commit 4fe6e705254050782c4594b74132b70a902c6cff Author: workashrafi77-web Date: Sun Jan 18 14:32:49 2026 +0330 push rasad front on new repo diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..cab3b7e --- /dev/null +++ b/.dockerignore @@ -0,0 +1,4 @@ +node_modules; +npm - debug.log.git.gitignore; +README.md.env.nyc_output; +coverage.DS_Store; diff --git a/.eslintignore b/.eslintignore new file mode 100644 index 0000000..e33378b --- /dev/null +++ b/.eslintignore @@ -0,0 +1,13 @@ +node_modules +build +dist +*.config.js +vite.config.js +serviceWorkerRegistration.js +service-worker.js +reportWebVitals.js +setupTests.js +public +.cursor +coverage + diff --git a/.eslintrc.json b/.eslintrc.json new file mode 100644 index 0000000..647873a --- /dev/null +++ b/.eslintrc.json @@ -0,0 +1,37 @@ +{ + "env": { + "browser": true, + "es2021": true, + "node": true + }, + "extends": [ + "eslint:recommended", + "plugin:react/recommended", + "plugin:react-hooks/recommended", + "plugin:prettier/recommended" + ], + "parserOptions": { + "ecmaVersion": "latest", + "sourceType": "module", + "ecmaFeatures": { + "jsx": true + } + }, + "settings": { + "react": { + "version": "detect" + } + }, + "rules": { + "react/react-in-jsx-scope": "off", + "react-hooks/exhaustive-deps": "off", + "react/prop-types": "off", + "react-hooks/set-state-in-effect": "off", + "react-hooks/immutability": "off", + "no-unused-vars": "error", + "no-console": "off", + "eqeqeq": ["error", "always"], + "prefer-const": "warn", + "no-var": "error" + } +} diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..c5e2e91 --- /dev/null +++ b/.gitignore @@ -0,0 +1,28 @@ +# See https://help.github.com/articles/ignoring-files/ for more about ignoring files. + +# dependencies +/node_modules +/.pnp +.pnp.js + +# testing +/coverage + +# production +/build +/dist + +# Vite +.vite + +# misc +.DS_Store +.env.local +.env.development.local +.env.test.local +.env.production.local + +npm-debug.log* +yarn-debug.log* +yarn-error.log* +/logs.txt \ No newline at end of file diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..e82b1ec --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,3 @@ +{ + "workbench.editor.enablePreviewFromCodeNavigation": true +} diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..27810cb --- /dev/null +++ b/Dockerfile @@ -0,0 +1,17 @@ +FROM node:18-alpine + +WORKDIR /app + +COPY package*.json ./ +RUN npm install --force + +COPY . . + +RUN npm run build + +RUN ls -la + +EXPOSE 3000 + +CMD ["npx", "vite", "preview", "--host", "0.0.0.0", "--port", "3000"] + diff --git a/README.md b/README.md new file mode 100644 index 0000000..d87df85 --- /dev/null +++ b/README.md @@ -0,0 +1 @@ +# Rasadyar_System diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..a61935e --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,9 @@ +version: "3.8" + +services: + rasaddam: + build: . + image: wixarm/rasadyar:latest + ports: + - "3000:3000" + restart: unless-stopped diff --git a/index.html b/index.html new file mode 100644 index 0000000..7c43c68 --- /dev/null +++ b/index.html @@ -0,0 +1,37 @@ + + + + + + + + + + + + + + + رصدیار، سامانه رصد و پایش کالای اساسی + + + + + + +
+ + + diff --git a/liara.json b/liara.json new file mode 100644 index 0000000..b1de3b0 --- /dev/null +++ b/liara.json @@ -0,0 +1,4 @@ +{ + "app": "rasadyaarapp", + "platform": "react" +} diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..9407d6e --- /dev/null +++ b/package-lock.json @@ -0,0 +1,11572 @@ +{ + "name": "my-app", + "version": "0.1.1", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "my-app", + "version": "0.1.1", + "dependencies": { + "@date-io/date-fns-jalali": "^2.15.0", + "@date-io/jalaali": "^2.15.0", + "@emotion/react": "^11.10.4", + "@emotion/styled": "^11.10.4", + "@mui/icons-material": "^5.10.3", + "@mui/lab": "^5.0.0-alpha.99", + "@mui/material": "^5.10.4", + "@mui/x-date-pickers": "^5.0.2", + "@reactour/tour": "^3.1.6", + "@reduxjs/toolkit": "^1.8.5", + "@testing-library/jest-dom": "^5.16.5", + "@testing-library/react": "^13.4.0", + "@testing-library/user-event": "^13.5.0", + "@vitejs/plugin-react": "^4.3.1", + "axios": "^0.27.2", + "camelize": "^1.0.0", + "chart.js": "^4.2.1", + "chartjs-plugin-annotation": "^3.1.0", + "chartjs-plugin-datalabels": "^2.2.0", + "date-fns": "^2.29.3", + "date-fns-jalali": "^2.29.2-0", + "echarts": "^5.6.0", + "echarts-for-react": "^3.0.2", + "eslint": "8.22.0", + "eslint-config-prettier": "^8.5.0", + "eslint-plugin-jest-dom": "^4.0.2", + "eslint-plugin-prettier": "^4.2.1", + "formik": "^2.2.9", + "framer-motion": "^7.3.5", + "html2canvas": "^1.4.1", + "lottie-react": "^2.3.1", + "material-react-table": "^2.1.0", + "moment": "^2.29.4", + "mui-datatables": "^4.2.2", + "num2persian": "^3.2.2", + "persian-date": "^1.1.0", + "prettier": "^2.7.1", + "react": "^18.2.0", + "react-chartjs-2": "^5.2.0", + "react-data-table-component": "^7.5.3", + "react-dom": "^18.2.0", + "react-error-boundary": "^3.1.4", + "react-icons": "^4.8.0", + "react-images-uploading": "^3.1.7", + "react-number-format": "^5.1.2", + "react-redux": "^8.0.2", + "react-router-dom": "^6.3.0", + "react-to-print": "^2.14.15", + "reactour": "^1.18.7", + "redux-persist": "^6.0.0", + "styled-components": "^4.0.0", + "stylis": "^4.1.2", + "stylis-plugin-rtl": "2.0.2", + "use-react-screenshot": "^3.0.0", + "vite": "^5.4.2", + "vite-plugin-pwa": "^0.20.1", + "vitest": "^2.0.5", + "web-vitals": "^2.1.4", + "workbox-background-sync": "^6.5.4", + "workbox-broadcast-update": "^6.5.4", + "workbox-cacheable-response": "^6.5.4", + "workbox-core": "^6.5.4", + "workbox-expiration": "^6.5.4", + "workbox-google-analytics": "^6.5.4", + "workbox-navigation-preload": "^6.5.4", + "workbox-precaching": "^6.5.4", + "workbox-range-requests": "^6.5.4", + "workbox-routing": "^6.5.4", + "workbox-strategies": "^6.5.4", + "workbox-streams": "^6.5.4", + "yup": "^0.32.11" + }, + "devDependencies": { + "eslint-plugin-react": "^7.37.5", + "eslint-plugin-react-hooks": "^7.0.0", + "eslint-plugin-testing-library": "^7.13.3" + } + }, + "node_modules/@adobe/css-tools": { + "version": "4.4.4", + "resolved": "https://registry.npmjs.org/@adobe/css-tools/-/css-tools-4.4.4.tgz", + "integrity": "sha512-Elp+iwUx5rN5+Y8xLt5/GRoG20WGoDCQ/1Fb+1LiGtvwbDavuSk0jhD/eZdckHAuzcDzccnkv+rEjyWfRx18gg==", + "license": "MIT" + }, + "node_modules/@babel/code-frame": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.27.1.tgz", + "integrity": "sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg==", + "license": "MIT", + "dependencies": { + "@babel/helper-validator-identifier": "^7.27.1", + "js-tokens": "^4.0.0", + "picocolors": "^1.1.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/compat-data": { + "version": "7.28.4", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.28.4.tgz", + "integrity": "sha512-YsmSKC29MJwf0gF8Rjjrg5LQCmyh+j/nD8/eP7f+BeoQTKYqs9RoWbjGOdy0+1Ekr68RJZMUOPVQaQisnIo4Rw==", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/core": { + "version": "7.28.4", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.28.4.tgz", + "integrity": "sha512-2BCOP7TN8M+gVDj7/ht3hsaO/B/n5oDbiAyyvnRlNOs+u1o+JWNYTQrmpuNp1/Wq2gcFrI01JAW+paEKDMx/CA==", + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.27.1", + "@babel/generator": "^7.28.3", + "@babel/helper-compilation-targets": "^7.27.2", + "@babel/helper-module-transforms": "^7.28.3", + "@babel/helpers": "^7.28.4", + "@babel/parser": "^7.28.4", + "@babel/template": "^7.27.2", + "@babel/traverse": "^7.28.4", + "@babel/types": "^7.28.4", + "@jridgewell/remapping": "^2.3.5", + "convert-source-map": "^2.0.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.2", + "json5": "^2.2.3", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/babel" + } + }, + "node_modules/@babel/core/node_modules/convert-source-map": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", + "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", + "license": "MIT" + }, + "node_modules/@babel/generator": { + "version": "7.28.3", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.28.3.tgz", + "integrity": "sha512-3lSpxGgvnmZznmBkCRnVREPUFJv2wrv9iAoFDvADJc0ypmdOxdUtcLeBgBJ6zE0PMeTKnxeQzyk0xTBq4Ep7zw==", + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.28.3", + "@babel/types": "^7.28.2", + "@jridgewell/gen-mapping": "^0.3.12", + "@jridgewell/trace-mapping": "^0.3.28", + "jsesc": "^3.0.2" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-annotate-as-pure": { + "version": "7.27.3", + "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.27.3.tgz", + "integrity": "sha512-fXSwMQqitTGeHLBC08Eq5yXz2m37E4pJX1qAU1+2cNedz/ifv/bVXft90VeSav5nFO61EcNgwr0aJxbyPaWBPg==", + "license": "MIT", + "dependencies": { + "@babel/types": "^7.27.3" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-compilation-targets": { + "version": "7.27.2", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.27.2.tgz", + "integrity": "sha512-2+1thGUUWWjLTYTHZWK1n8Yga0ijBz1XAhUXcKy81rd5g6yh7hGqMp45v7cadSbEHc9G3OTv45SyneRN3ps4DQ==", + "license": "MIT", + "dependencies": { + "@babel/compat-data": "^7.27.2", + "@babel/helper-validator-option": "^7.27.1", + "browserslist": "^4.24.0", + "lru-cache": "^5.1.1", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-create-class-features-plugin": { + "version": "7.28.3", + "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.28.3.tgz", + "integrity": "sha512-V9f6ZFIYSLNEbuGA/92uOvYsGCJNsuA8ESZ4ldc09bWk/j8H8TKiPw8Mk1eG6olpnO0ALHJmYfZvF4MEE4gajg==", + "license": "MIT", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.27.3", + "@babel/helper-member-expression-to-functions": "^7.27.1", + "@babel/helper-optimise-call-expression": "^7.27.1", + "@babel/helper-replace-supers": "^7.27.1", + "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1", + "@babel/traverse": "^7.28.3", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-create-regexp-features-plugin": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.27.1.tgz", + "integrity": "sha512-uVDC72XVf8UbrH5qQTc18Agb8emwjTiZrQE11Nv3CuBEZmVvTwwE9CBUEvHku06gQCAyYf8Nv6ja1IN+6LMbxQ==", + "license": "MIT", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.27.1", + "regexpu-core": "^6.2.0", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-define-polyfill-provider": { + "version": "0.6.5", + "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.6.5.tgz", + "integrity": "sha512-uJnGFcPsWQK8fvjgGP5LZUZZsYGIoPeRjSF5PGwrelYgq7Q15/Ft9NGFp1zglwgIv//W0uG4BevRuSJRyylZPg==", + "license": "MIT", + "dependencies": { + "@babel/helper-compilation-targets": "^7.27.2", + "@babel/helper-plugin-utils": "^7.27.1", + "debug": "^4.4.1", + "lodash.debounce": "^4.0.8", + "resolve": "^1.22.10" + }, + "peerDependencies": { + "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" + } + }, + "node_modules/@babel/helper-globals": { + "version": "7.28.0", + "resolved": "https://registry.npmjs.org/@babel/helper-globals/-/helper-globals-7.28.0.tgz", + "integrity": "sha512-+W6cISkXFa1jXsDEdYA8HeevQT/FULhxzR99pxphltZcVaugps53THCeiWA8SguxxpSp3gKPiuYfSWopkLQ4hw==", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-member-expression-to-functions": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.27.1.tgz", + "integrity": "sha512-E5chM8eWjTp/aNoVpcbfM7mLxu9XGLWYise2eBKGQomAk/Mb4XoxyqXTZbuTohbsl8EKqdlMhnDI2CCLfcs9wA==", + "license": "MIT", + "dependencies": { + "@babel/traverse": "^7.27.1", + "@babel/types": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-imports": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.27.1.tgz", + "integrity": "sha512-0gSFWUPNXNopqtIPQvlD5WgXYI5GY2kP2cCvoT8kczjbfcfuIljTbcWrulD1CIPIX2gt1wghbDy08yE1p+/r3w==", + "license": "MIT", + "dependencies": { + "@babel/traverse": "^7.27.1", + "@babel/types": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-transforms": { + "version": "7.28.3", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.28.3.tgz", + "integrity": "sha512-gytXUbs8k2sXS9PnQptz5o0QnpLL51SwASIORY6XaBKF88nsOT0Zw9szLqlSGQDP/4TljBAD5y98p2U1fqkdsw==", + "license": "MIT", + "dependencies": { + "@babel/helper-module-imports": "^7.27.1", + "@babel/helper-validator-identifier": "^7.27.1", + "@babel/traverse": "^7.28.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-optimise-call-expression": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.27.1.tgz", + "integrity": "sha512-URMGH08NzYFhubNSGJrpUEphGKQwMQYBySzat5cAByY1/YgIRkULnIy3tAMeszlL/so2HbeilYloUmSpd7GdVw==", + "license": "MIT", + "dependencies": { + "@babel/types": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-plugin-utils": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.27.1.tgz", + "integrity": "sha512-1gn1Up5YXka3YYAHGKpbideQ5Yjf1tDa9qYcgysz+cNCXukyLl6DjPXhD3VRwSb8c0J9tA4b2+rHEZtc6R0tlw==", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-remap-async-to-generator": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.27.1.tgz", + "integrity": "sha512-7fiA521aVw8lSPeI4ZOD3vRFkoqkJcS+z4hFo82bFSH/2tNd6eJ5qCVMS5OzDmZh/kaHQeBaeyxK6wljcPtveA==", + "license": "MIT", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.27.1", + "@babel/helper-wrap-function": "^7.27.1", + "@babel/traverse": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-replace-supers": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.27.1.tgz", + "integrity": "sha512-7EHz6qDZc8RYS5ElPoShMheWvEgERonFCs7IAonWLLUTXW59DP14bCZt89/GKyreYn8g3S83m21FelHKbeDCKA==", + "license": "MIT", + "dependencies": { + "@babel/helper-member-expression-to-functions": "^7.27.1", + "@babel/helper-optimise-call-expression": "^7.27.1", + "@babel/traverse": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-skip-transparent-expression-wrappers": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.27.1.tgz", + "integrity": "sha512-Tub4ZKEXqbPjXgWLl2+3JpQAYBJ8+ikpQ2Ocj/q/r0LwE3UhENh7EUabyHjz2kCEsrRY83ew2DQdHluuiDQFzg==", + "license": "MIT", + "dependencies": { + "@babel/traverse": "^7.27.1", + "@babel/types": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-string-parser": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.27.1.tgz", + "integrity": "sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.27.1.tgz", + "integrity": "sha512-D2hP9eA+Sqx1kBZgzxZh0y1trbuU+JoDkiEwqhQ36nodYqJwyEIhPSdMNd7lOm/4io72luTPWH20Yda0xOuUow==", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-option": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.27.1.tgz", + "integrity": "sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg==", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-wrap-function": { + "version": "7.28.3", + "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.28.3.tgz", + "integrity": "sha512-zdf983tNfLZFletc0RRXYrHrucBEg95NIFMkn6K9dbeMYnsgHaSBGcQqdsCSStG2PYwRre0Qc2NNSCXbG+xc6g==", + "license": "MIT", + "dependencies": { + "@babel/template": "^7.27.2", + "@babel/traverse": "^7.28.3", + "@babel/types": "^7.28.2" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helpers": { + "version": "7.28.4", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.28.4.tgz", + "integrity": "sha512-HFN59MmQXGHVyYadKLVumYsA9dBFun/ldYxipEjzA4196jpLZd8UjEEBLkbEkvfYreDqJhZxYAWFPtrfhNpj4w==", + "license": "MIT", + "dependencies": { + "@babel/template": "^7.27.2", + "@babel/types": "^7.28.4" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/parser": { + "version": "7.28.4", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.28.4.tgz", + "integrity": "sha512-yZbBqeM6TkpP9du/I2pUZnJsRMGGvOuIrhjzC1AwHwW+6he4mni6Bp/m8ijn0iOuZuPI2BfkCoSRunpyjnrQKg==", + "license": "MIT", + "dependencies": { + "@babel/types": "^7.28.4" + }, + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/plugin-bugfix-firefox-class-in-computed-class-key": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-firefox-class-in-computed-class-key/-/plugin-bugfix-firefox-class-in-computed-class-key-7.27.1.tgz", + "integrity": "sha512-QPG3C9cCVRQLxAVwmefEmwdTanECuUBMQZ/ym5kiw3XKCGA7qkuQLcjWWHcrD/GKbn/WmJwaezfuuAOcyKlRPA==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/traverse": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-bugfix-safari-class-field-initializer-scope": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-class-field-initializer-scope/-/plugin-bugfix-safari-class-field-initializer-scope-7.27.1.tgz", + "integrity": "sha512-qNeq3bCKnGgLkEXUuFry6dPlGfCdQNZbn7yUAPCInwAJHMU7THJfrBSozkcWq5sNM6RcF3S8XyQL2A52KNR9IA==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.27.1.tgz", + "integrity": "sha512-g4L7OYun04N1WyqMNjldFwlfPCLVkgB54A/YCXICZYBsvJJE3kByKv9c9+R/nAfmIfjl2rKYLNyMHboYbZaWaA==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.27.1.tgz", + "integrity": "sha512-oO02gcONcD5O1iTLi/6frMJBIwWEHceWGSGqrpCmEL8nogiS6J9PBlE48CaK20/Jx1LuRml9aDftLgdjXT8+Cw==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1", + "@babel/plugin-transform-optional-chaining": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.13.0" + } + }, + "node_modules/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": { + "version": "7.28.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly/-/plugin-bugfix-v8-static-class-fields-redefine-readonly-7.28.3.tgz", + "integrity": "sha512-b6YTX108evsvE4YgWyQ921ZAFFQm3Bn+CA3+ZXlNVnPhx+UfsVURoPjfGAPCjBgrqo30yX/C2nZGX96DxvR9Iw==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/traverse": "^7.28.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-proposal-private-property-in-object": { + "version": "7.21.0-placeholder-for-preset-env.2", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.21.0-placeholder-for-preset-env.2.tgz", + "integrity": "sha512-SOSkfJDddaM7mak6cPEpswyTRnuRltl429hMraQEglW+OkovnCzsiszTmsrlY//qLFjCpQDFRvjdm2wA5pPm9w==", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-import-assertions": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.27.1.tgz", + "integrity": "sha512-UT/Jrhw57xg4ILHLFnzFpPDlMbcdEicaAtjPQpbj9wa8T4r5KVWCimHcL/460g8Ht0DMxDyjsLgiWSkVjnwPFg==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-import-attributes": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.27.1.tgz", + "integrity": "sha512-oFT0FrKHgF53f4vOsZGi2Hh3I35PfSmVs4IBFLFj4dnafP+hIWDLg3VyKmUHfLoLHlyxY4C7DGtmHuJgn+IGww==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-jsx": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.27.1.tgz", + "integrity": "sha512-y8YTNIeKoyhGd9O0Jiyzyyqk8gdjnumGTQPsz0xOZOQ2RmkVJeZ1vmmfIvFEKqucBG6axJGBZDE/7iI5suUI/w==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-unicode-sets-regex": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-unicode-sets-regex/-/plugin-syntax-unicode-sets-regex-7.18.6.tgz", + "integrity": "sha512-727YkEAPwSIQTv5im8QHz3upqp92JTWhidIC81Tdx4VJYIte/VndKf1qKrfnnhPLiPghStWfvC/iFaMCQu7Nqg==", + "license": "MIT", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.18.6", + "@babel/helper-plugin-utils": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-transform-arrow-functions": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.27.1.tgz", + "integrity": "sha512-8Z4TGic6xW70FKThA5HYEKKyBpOOsucTOD1DjU3fZxDg+K3zBJcXMFnt/4yQiZnf5+MiOMSXQ9PaEK/Ilh1DeA==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-async-generator-functions": { + "version": "7.28.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-7.28.0.tgz", + "integrity": "sha512-BEOdvX4+M765icNPZeidyADIvQ1m1gmunXufXxvRESy/jNNyfovIqUyE7MVgGBjWktCoJlzvFA1To2O4ymIO3Q==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/helper-remap-async-to-generator": "^7.27.1", + "@babel/traverse": "^7.28.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-async-to-generator": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.27.1.tgz", + "integrity": "sha512-NREkZsZVJS4xmTr8qzE5y8AfIPqsdQfRuUiLRTEzb7Qii8iFWCyDKaUV2c0rCuh4ljDZ98ALHP/PetiBV2nddA==", + "license": "MIT", + "dependencies": { + "@babel/helper-module-imports": "^7.27.1", + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/helper-remap-async-to-generator": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-block-scoped-functions": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.27.1.tgz", + "integrity": "sha512-cnqkuOtZLapWYZUYM5rVIdv1nXYuFVIltZ6ZJ7nIj585QsjKM5dhL2Fu/lICXZ1OyIAFc7Qy+bvDAtTXqGrlhg==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-block-scoping": { + "version": "7.28.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.28.4.tgz", + "integrity": "sha512-1yxmvN0MJHOhPVmAsmoW5liWwoILobu/d/ShymZmj867bAdxGbehIrew1DuLpw2Ukv+qDSSPQdYW1dLNE7t11A==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-class-properties": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-properties/-/plugin-transform-class-properties-7.27.1.tgz", + "integrity": "sha512-D0VcalChDMtuRvJIu3U/fwWjf8ZMykz5iZsg77Nuj821vCKI3zCyRLwRdWbsuJ/uRwZhZ002QtCqIkwC/ZkvbA==", + "license": "MIT", + "dependencies": { + "@babel/helper-create-class-features-plugin": "^7.27.1", + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-class-static-block": { + "version": "7.28.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-static-block/-/plugin-transform-class-static-block-7.28.3.tgz", + "integrity": "sha512-LtPXlBbRoc4Njl/oh1CeD/3jC+atytbnf/UqLoqTDcEYGUPj022+rvfkbDYieUrSj3CaV4yHDByPE+T2HwfsJg==", + "license": "MIT", + "dependencies": { + "@babel/helper-create-class-features-plugin": "^7.28.3", + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.12.0" + } + }, + "node_modules/@babel/plugin-transform-classes": { + "version": "7.28.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.28.4.tgz", + "integrity": "sha512-cFOlhIYPBv/iBoc+KS3M6et2XPtbT2HiCRfBXWtfpc9OAyostldxIf9YAYB6ypURBBbx+Qv6nyrLzASfJe+hBA==", + "license": "MIT", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.27.3", + "@babel/helper-compilation-targets": "^7.27.2", + "@babel/helper-globals": "^7.28.0", + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/helper-replace-supers": "^7.27.1", + "@babel/traverse": "^7.28.4" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-computed-properties": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.27.1.tgz", + "integrity": "sha512-lj9PGWvMTVksbWiDT2tW68zGS/cyo4AkZ/QTp0sQT0mjPopCmrSkzxeXkznjqBxzDI6TclZhOJbBmbBLjuOZUw==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/template": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-destructuring": { + "version": "7.28.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.28.0.tgz", + "integrity": "sha512-v1nrSMBiKcodhsyJ4Gf+Z0U/yawmJDBOTpEB3mcQY52r9RIyPneGyAS/yM6seP/8I+mWI3elOMtT5dB8GJVs+A==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/traverse": "^7.28.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-dotall-regex": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.27.1.tgz", + "integrity": "sha512-gEbkDVGRvjj7+T1ivxrfgygpT7GUd4vmODtYpbs0gZATdkX8/iSnOtZSxiZnsgm1YjTgjI6VKBGSJJevkrclzw==", + "license": "MIT", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.27.1", + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-duplicate-keys": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.27.1.tgz", + "integrity": "sha512-MTyJk98sHvSs+cvZ4nOauwTTG1JeonDjSGvGGUNHreGQns+Mpt6WX/dVzWBHgg+dYZhkC4X+zTDfkTU+Vy9y7Q==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-duplicate-named-capturing-groups-regex": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-named-capturing-groups-regex/-/plugin-transform-duplicate-named-capturing-groups-regex-7.27.1.tgz", + "integrity": "sha512-hkGcueTEzuhB30B3eJCbCYeCaaEQOmQR0AdvzpD4LoN0GXMWzzGSuRrxR2xTnCrvNbVwK9N6/jQ92GSLfiZWoQ==", + "license": "MIT", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.27.1", + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-transform-dynamic-import": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dynamic-import/-/plugin-transform-dynamic-import-7.27.1.tgz", + "integrity": "sha512-MHzkWQcEmjzzVW9j2q8LGjwGWpG2mjwaaB0BNQwst3FIjqsg8Ct/mIZlvSPJvfi9y2AC8mi/ktxbFVL9pZ1I4A==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-explicit-resource-management": { + "version": "7.28.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-explicit-resource-management/-/plugin-transform-explicit-resource-management-7.28.0.tgz", + "integrity": "sha512-K8nhUcn3f6iB+P3gwCv/no7OdzOZQcKchW6N389V6PD8NUWKZHzndOd9sPDVbMoBsbmjMqlB4L9fm+fEFNVlwQ==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/plugin-transform-destructuring": "^7.28.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-exponentiation-operator": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.27.1.tgz", + "integrity": "sha512-uspvXnhHvGKf2r4VVtBpeFnuDWsJLQ6MF6lGJLC89jBR1uoVeqM416AZtTuhTezOfgHicpJQmoD5YUakO/YmXQ==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-export-namespace-from": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-export-namespace-from/-/plugin-transform-export-namespace-from-7.27.1.tgz", + "integrity": "sha512-tQvHWSZ3/jH2xuq/vZDy0jNn+ZdXJeM8gHvX4lnJmsc3+50yPlWdZXIc5ay+umX+2/tJIqHqiEqcJvxlmIvRvQ==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-for-of": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.27.1.tgz", + "integrity": "sha512-BfbWFFEJFQzLCQ5N8VocnCtA8J1CLkNTe2Ms2wocj75dd6VpiqS5Z5quTYcUoo4Yq+DN0rtikODccuv7RU81sw==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-function-name": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.27.1.tgz", + "integrity": "sha512-1bQeydJF9Nr1eBCMMbC+hdwmRlsv5XYOMu03YSWFwNs0HsAmtSxxF1fyuYPqemVldVyFmlCU7w8UE14LupUSZQ==", + "license": "MIT", + "dependencies": { + "@babel/helper-compilation-targets": "^7.27.1", + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/traverse": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-json-strings": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-json-strings/-/plugin-transform-json-strings-7.27.1.tgz", + "integrity": "sha512-6WVLVJiTjqcQauBhn1LkICsR2H+zm62I3h9faTDKt1qP4jn2o72tSvqMwtGFKGTpojce0gJs+76eZ2uCHRZh0Q==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-literals": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.27.1.tgz", + "integrity": "sha512-0HCFSepIpLTkLcsi86GG3mTUzxV5jpmbv97hTETW3yzrAij8aqlD36toB1D0daVFJM8NK6GvKO0gslVQmm+zZA==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-logical-assignment-operators": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-logical-assignment-operators/-/plugin-transform-logical-assignment-operators-7.27.1.tgz", + "integrity": "sha512-SJvDs5dXxiae4FbSL1aBJlG4wvl594N6YEVVn9e3JGulwioy6z3oPjx/sQBO3Y4NwUu5HNix6KJ3wBZoewcdbw==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-member-expression-literals": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.27.1.tgz", + "integrity": "sha512-hqoBX4dcZ1I33jCSWcXrP+1Ku7kdqXf1oeah7ooKOIiAdKQ+uqftgCFNOSzA5AMS2XIHEYeGFg4cKRCdpxzVOQ==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-modules-amd": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.27.1.tgz", + "integrity": "sha512-iCsytMg/N9/oFq6n+gFTvUYDZQOMK5kEdeYxmxt91fcJGycfxVP9CnrxoliM0oumFERba2i8ZtwRUCMhvP1LnA==", + "license": "MIT", + "dependencies": { + "@babel/helper-module-transforms": "^7.27.1", + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-modules-commonjs": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.27.1.tgz", + "integrity": "sha512-OJguuwlTYlN0gBZFRPqwOGNWssZjfIUdS7HMYtN8c1KmwpwHFBwTeFZrg9XZa+DFTitWOW5iTAG7tyCUPsCCyw==", + "license": "MIT", + "dependencies": { + "@babel/helper-module-transforms": "^7.27.1", + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-modules-systemjs": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.27.1.tgz", + "integrity": "sha512-w5N1XzsRbc0PQStASMksmUeqECuzKuTJer7kFagK8AXgpCMkeDMO5S+aaFb7A51ZYDF7XI34qsTX+fkHiIm5yA==", + "license": "MIT", + "dependencies": { + "@babel/helper-module-transforms": "^7.27.1", + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/helper-validator-identifier": "^7.27.1", + "@babel/traverse": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-modules-umd": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.27.1.tgz", + "integrity": "sha512-iQBE/xC5BV1OxJbp6WG7jq9IWiD+xxlZhLrdwpPkTX3ydmXdvoCpyfJN7acaIBZaOqTfr76pgzqBJflNbeRK+w==", + "license": "MIT", + "dependencies": { + "@babel/helper-module-transforms": "^7.27.1", + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-named-capturing-groups-regex": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.27.1.tgz", + "integrity": "sha512-SstR5JYy8ddZvD6MhV0tM/j16Qds4mIpJTOd1Yu9J9pJjH93bxHECF7pgtc28XvkzTD6Pxcm/0Z73Hvk7kb3Ng==", + "license": "MIT", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.27.1", + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-transform-new-target": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.27.1.tgz", + "integrity": "sha512-f6PiYeqXQ05lYq3TIfIDu/MtliKUbNwkGApPUvyo6+tc7uaR4cPjPe7DFPr15Uyycg2lZU6btZ575CuQoYh7MQ==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-nullish-coalescing-operator": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-nullish-coalescing-operator/-/plugin-transform-nullish-coalescing-operator-7.27.1.tgz", + "integrity": "sha512-aGZh6xMo6q9vq1JGcw58lZ1Z0+i0xB2x0XaauNIUXd6O1xXc3RwoWEBlsTQrY4KQ9Jf0s5rgD6SiNkaUdJegTA==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-numeric-separator": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-numeric-separator/-/plugin-transform-numeric-separator-7.27.1.tgz", + "integrity": "sha512-fdPKAcujuvEChxDBJ5c+0BTaS6revLV7CJL08e4m3de8qJfNIuCc2nc7XJYOjBoTMJeqSmwXJ0ypE14RCjLwaw==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-object-rest-spread": { + "version": "7.28.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-rest-spread/-/plugin-transform-object-rest-spread-7.28.4.tgz", + "integrity": "sha512-373KA2HQzKhQCYiRVIRr+3MjpCObqzDlyrM6u4I201wL8Mp2wHf7uB8GhDwis03k2ti8Zr65Zyyqs1xOxUF/Ew==", + "license": "MIT", + "dependencies": { + "@babel/helper-compilation-targets": "^7.27.2", + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/plugin-transform-destructuring": "^7.28.0", + "@babel/plugin-transform-parameters": "^7.27.7", + "@babel/traverse": "^7.28.4" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-object-super": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.27.1.tgz", + "integrity": "sha512-SFy8S9plRPbIcxlJ8A6mT/CxFdJx/c04JEctz4jf8YZaVS2px34j7NXRrlGlHkN/M2gnpL37ZpGRGVFLd3l8Ng==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/helper-replace-supers": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-optional-catch-binding": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-catch-binding/-/plugin-transform-optional-catch-binding-7.27.1.tgz", + "integrity": "sha512-txEAEKzYrHEX4xSZN4kJ+OfKXFVSWKB2ZxM9dpcE3wT7smwkNmXo5ORRlVzMVdJbD+Q8ILTgSD7959uj+3Dm3Q==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-optional-chaining": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-chaining/-/plugin-transform-optional-chaining-7.27.1.tgz", + "integrity": "sha512-BQmKPPIuc8EkZgNKsv0X4bPmOoayeu4F1YCwx2/CfmDSXDbp7GnzlUH+/ul5VGfRg1AoFPsrIThlEBj2xb4CAg==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-parameters": { + "version": "7.27.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.27.7.tgz", + "integrity": "sha512-qBkYTYCb76RRxUM6CcZA5KRu8K4SM8ajzVeUgVdMVO9NN9uI/GaVmBg/WKJJGnNokV9SY8FxNOVWGXzqzUidBg==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-private-methods": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-methods/-/plugin-transform-private-methods-7.27.1.tgz", + "integrity": "sha512-10FVt+X55AjRAYI9BrdISN9/AQWHqldOeZDUoLyif1Kn05a56xVBXb8ZouL8pZ9jem8QpXaOt8TS7RHUIS+GPA==", + "license": "MIT", + "dependencies": { + "@babel/helper-create-class-features-plugin": "^7.27.1", + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-private-property-in-object": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-property-in-object/-/plugin-transform-private-property-in-object-7.27.1.tgz", + "integrity": "sha512-5J+IhqTi1XPa0DXF83jYOaARrX+41gOewWbkPyjMNRDqgOCqdffGh8L3f/Ek5utaEBZExjSAzcyjmV9SSAWObQ==", + "license": "MIT", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.27.1", + "@babel/helper-create-class-features-plugin": "^7.27.1", + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-property-literals": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.27.1.tgz", + "integrity": "sha512-oThy3BCuCha8kDZ8ZkgOg2exvPYUlprMukKQXI1r1pJ47NCvxfkEy8vK+r/hT9nF0Aa4H1WUPZZjHTFtAhGfmQ==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-react-jsx-self": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-self/-/plugin-transform-react-jsx-self-7.27.1.tgz", + "integrity": "sha512-6UzkCs+ejGdZ5mFFC/OCUrv028ab2fp1znZmCZjAOBKiBK2jXD1O+BPSfX8X2qjJ75fZBMSnQn3Rq2mrBJK2mw==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-react-jsx-source": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.27.1.tgz", + "integrity": "sha512-zbwoTsBruTeKB9hSq73ha66iFeJHuaFkUbwvqElnygoNbj/jHRsSeokowZFN3CZ64IvEqcmmkVe89OPXc7ldAw==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-regenerator": { + "version": "7.28.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.28.4.tgz", + "integrity": "sha512-+ZEdQlBoRg9m2NnzvEeLgtvBMO4tkFBw5SQIUgLICgTrumLoU7lr+Oghi6km2PFj+dbUt2u1oby2w3BDO9YQnA==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-regexp-modifiers": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regexp-modifiers/-/plugin-transform-regexp-modifiers-7.27.1.tgz", + "integrity": "sha512-TtEciroaiODtXvLZv4rmfMhkCv8jx3wgKpL68PuiPh2M4fvz5jhsA7697N1gMvkvr/JTF13DrFYyEbY9U7cVPA==", + "license": "MIT", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.27.1", + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-transform-reserved-words": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.27.1.tgz", + "integrity": "sha512-V2ABPHIJX4kC7HegLkYoDpfg9PVmuWy/i6vUM5eGK22bx4YVFD3M5F0QQnWQoDs6AGsUWTVOopBiMFQgHaSkVw==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-shorthand-properties": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.27.1.tgz", + "integrity": "sha512-N/wH1vcn4oYawbJ13Y/FxcQrWk63jhfNa7jef0ih7PHSIHX2LB7GWE1rkPrOnka9kwMxb6hMl19p7lidA+EHmQ==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-spread": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.27.1.tgz", + "integrity": "sha512-kpb3HUqaILBJcRFVhFUs6Trdd4mkrzcGXss+6/mxUd273PfbWqSDHRzMT2234gIg2QYfAjvXLSquP1xECSg09Q==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-sticky-regex": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.27.1.tgz", + "integrity": "sha512-lhInBO5bi/Kowe2/aLdBAawijx+q1pQzicSgnkB6dUPc1+RC8QmJHKf2OjvU+NZWitguJHEaEmbV6VWEouT58g==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-template-literals": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.27.1.tgz", + "integrity": "sha512-fBJKiV7F2DxZUkg5EtHKXQdbsbURW3DZKQUWphDum0uRP6eHGGa/He9mc0mypL680pb+e/lDIthRohlv8NCHkg==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-typeof-symbol": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.27.1.tgz", + "integrity": "sha512-RiSILC+nRJM7FY5srIyc4/fGIwUhyDuuBSdWn4y6yT6gm652DpCHZjIipgn6B7MQ1ITOUnAKWixEUjQRIBIcLw==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-unicode-escapes": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.27.1.tgz", + "integrity": "sha512-Ysg4v6AmF26k9vpfFuTZg8HRfVWzsh1kVfowA23y9j/Gu6dOuahdUVhkLqpObp3JIv27MLSii6noRnuKN8H0Mg==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-unicode-property-regex": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-property-regex/-/plugin-transform-unicode-property-regex-7.27.1.tgz", + "integrity": "sha512-uW20S39PnaTImxp39O5qFlHLS9LJEmANjMG7SxIhap8rCHqu0Ik+tLEPX5DKmHn6CsWQ7j3lix2tFOa5YtL12Q==", + "license": "MIT", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.27.1", + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-unicode-regex": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.27.1.tgz", + "integrity": "sha512-xvINq24TRojDuyt6JGtHmkVkrfVV3FPT16uytxImLeBZqW3/H52yN+kM1MGuyPkIQxrzKwPHs5U/MP3qKyzkGw==", + "license": "MIT", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.27.1", + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-unicode-sets-regex": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-sets-regex/-/plugin-transform-unicode-sets-regex-7.27.1.tgz", + "integrity": "sha512-EtkOujbc4cgvb0mlpQefi4NTPBzhSIevblFevACNLUspmrALgmEBdL/XfnyyITfd8fKBZrZys92zOWcik7j9Tw==", + "license": "MIT", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.27.1", + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/preset-env": { + "version": "7.28.3", + "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.28.3.tgz", + "integrity": "sha512-ROiDcM+GbYVPYBOeCR6uBXKkQpBExLl8k9HO1ygXEyds39j+vCCsjmj7S8GOniZQlEs81QlkdJZe76IpLSiqpg==", + "license": "MIT", + "dependencies": { + "@babel/compat-data": "^7.28.0", + "@babel/helper-compilation-targets": "^7.27.2", + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/helper-validator-option": "^7.27.1", + "@babel/plugin-bugfix-firefox-class-in-computed-class-key": "^7.27.1", + "@babel/plugin-bugfix-safari-class-field-initializer-scope": "^7.27.1", + "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "^7.27.1", + "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.27.1", + "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": "^7.28.3", + "@babel/plugin-proposal-private-property-in-object": "7.21.0-placeholder-for-preset-env.2", + "@babel/plugin-syntax-import-assertions": "^7.27.1", + "@babel/plugin-syntax-import-attributes": "^7.27.1", + "@babel/plugin-syntax-unicode-sets-regex": "^7.18.6", + "@babel/plugin-transform-arrow-functions": "^7.27.1", + "@babel/plugin-transform-async-generator-functions": "^7.28.0", + "@babel/plugin-transform-async-to-generator": "^7.27.1", + "@babel/plugin-transform-block-scoped-functions": "^7.27.1", + "@babel/plugin-transform-block-scoping": "^7.28.0", + "@babel/plugin-transform-class-properties": "^7.27.1", + "@babel/plugin-transform-class-static-block": "^7.28.3", + "@babel/plugin-transform-classes": "^7.28.3", + "@babel/plugin-transform-computed-properties": "^7.27.1", + "@babel/plugin-transform-destructuring": "^7.28.0", + "@babel/plugin-transform-dotall-regex": "^7.27.1", + "@babel/plugin-transform-duplicate-keys": "^7.27.1", + "@babel/plugin-transform-duplicate-named-capturing-groups-regex": "^7.27.1", + "@babel/plugin-transform-dynamic-import": "^7.27.1", + "@babel/plugin-transform-explicit-resource-management": "^7.28.0", + "@babel/plugin-transform-exponentiation-operator": "^7.27.1", + "@babel/plugin-transform-export-namespace-from": "^7.27.1", + "@babel/plugin-transform-for-of": "^7.27.1", + "@babel/plugin-transform-function-name": "^7.27.1", + "@babel/plugin-transform-json-strings": "^7.27.1", + "@babel/plugin-transform-literals": "^7.27.1", + "@babel/plugin-transform-logical-assignment-operators": "^7.27.1", + "@babel/plugin-transform-member-expression-literals": "^7.27.1", + "@babel/plugin-transform-modules-amd": "^7.27.1", + "@babel/plugin-transform-modules-commonjs": "^7.27.1", + "@babel/plugin-transform-modules-systemjs": "^7.27.1", + "@babel/plugin-transform-modules-umd": "^7.27.1", + "@babel/plugin-transform-named-capturing-groups-regex": "^7.27.1", + "@babel/plugin-transform-new-target": "^7.27.1", + "@babel/plugin-transform-nullish-coalescing-operator": "^7.27.1", + "@babel/plugin-transform-numeric-separator": "^7.27.1", + "@babel/plugin-transform-object-rest-spread": "^7.28.0", + "@babel/plugin-transform-object-super": "^7.27.1", + "@babel/plugin-transform-optional-catch-binding": "^7.27.1", + "@babel/plugin-transform-optional-chaining": "^7.27.1", + "@babel/plugin-transform-parameters": "^7.27.7", + "@babel/plugin-transform-private-methods": "^7.27.1", + "@babel/plugin-transform-private-property-in-object": "^7.27.1", + "@babel/plugin-transform-property-literals": "^7.27.1", + "@babel/plugin-transform-regenerator": "^7.28.3", + "@babel/plugin-transform-regexp-modifiers": "^7.27.1", + "@babel/plugin-transform-reserved-words": "^7.27.1", + "@babel/plugin-transform-shorthand-properties": "^7.27.1", + "@babel/plugin-transform-spread": "^7.27.1", + "@babel/plugin-transform-sticky-regex": "^7.27.1", + "@babel/plugin-transform-template-literals": "^7.27.1", + "@babel/plugin-transform-typeof-symbol": "^7.27.1", + "@babel/plugin-transform-unicode-escapes": "^7.27.1", + "@babel/plugin-transform-unicode-property-regex": "^7.27.1", + "@babel/plugin-transform-unicode-regex": "^7.27.1", + "@babel/plugin-transform-unicode-sets-regex": "^7.27.1", + "@babel/preset-modules": "0.1.6-no-external-plugins", + "babel-plugin-polyfill-corejs2": "^0.4.14", + "babel-plugin-polyfill-corejs3": "^0.13.0", + "babel-plugin-polyfill-regenerator": "^0.6.5", + "core-js-compat": "^3.43.0", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/preset-modules": { + "version": "0.1.6-no-external-plugins", + "resolved": "https://registry.npmjs.org/@babel/preset-modules/-/preset-modules-0.1.6-no-external-plugins.tgz", + "integrity": "sha512-HrcgcIESLm9aIR842yhJ5RWan/gebQUJ6E/E5+rf0y9o6oj7w0Br+sWuL6kEQ/o/AdfvR1Je9jG18/gnpwjEyA==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/types": "^7.4.4", + "esutils": "^2.0.2" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0 || ^8.0.0-0 <8.0.0" + } + }, + "node_modules/@babel/runtime": { + "version": "7.28.4", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.28.4.tgz", + "integrity": "sha512-Q/N6JNWvIvPnLDvjlE1OUBLPQHH6l3CltCEsHIujp45zQUSSh8K+gHnaEX45yAT1nyngnINhvWtzN+Nb9D8RAQ==", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/runtime-corejs3": { + "version": "7.28.4", + "resolved": "https://registry.npmjs.org/@babel/runtime-corejs3/-/runtime-corejs3-7.28.4.tgz", + "integrity": "sha512-h7iEYiW4HebClDEhtvFObtPmIvrd1SSfpI9EhOeKk4CtIK/ngBWFpuhCzhdmRKtg71ylcue+9I6dv54XYO1epQ==", + "license": "MIT", + "dependencies": { + "core-js-pure": "^3.43.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/template": { + "version": "7.27.2", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.27.2.tgz", + "integrity": "sha512-LPDZ85aEJyYSd18/DkjNh4/y1ntkE5KwUHWTiqgRxruuZL2F1yuHligVHLvcHY2vMHXttKFpJn6LwfI7cw7ODw==", + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.27.1", + "@babel/parser": "^7.27.2", + "@babel/types": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/traverse": { + "version": "7.28.4", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.28.4.tgz", + "integrity": "sha512-YEzuboP2qvQavAcjgQNVgsvHIDv6ZpwXvcvjmyySP2DIMuByS/6ioU5G9pYrWHM6T2YDfc7xga9iNzYOs12CFQ==", + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.27.1", + "@babel/generator": "^7.28.3", + "@babel/helper-globals": "^7.28.0", + "@babel/parser": "^7.28.4", + "@babel/template": "^7.27.2", + "@babel/types": "^7.28.4", + "debug": "^4.3.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/types": { + "version": "7.28.4", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.28.4.tgz", + "integrity": "sha512-bkFqkLhh3pMBUQQkpVgWDWq/lqzc2678eUyDlTBhRqhCHFguYYGM0Efga7tYk4TogG/3x0EEl66/OQ+WGbWB/Q==", + "license": "MIT", + "dependencies": { + "@babel/helper-string-parser": "^7.27.1", + "@babel/helper-validator-identifier": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@date-io/core": { + "version": "2.17.0", + "resolved": "https://registry.npmjs.org/@date-io/core/-/core-2.17.0.tgz", + "integrity": "sha512-+EQE8xZhRM/hsY0CDTVyayMDDY5ihc4MqXCrPxooKw19yAzUIC6uUqsZeaOFNL9YKTNxYKrJP5DFgE8o5xRCOw==", + "license": "MIT" + }, + "node_modules/@date-io/date-fns": { + "version": "2.17.0", + "resolved": "https://registry.npmjs.org/@date-io/date-fns/-/date-fns-2.17.0.tgz", + "integrity": "sha512-L0hWZ/mTpy3Gx/xXJ5tq5CzHo0L7ry6KEO9/w/JWiFWFLZgiNVo3ex92gOl3zmzjHqY/3Ev+5sehAr8UnGLEng==", + "license": "MIT", + "dependencies": { + "@date-io/core": "^2.17.0" + }, + "peerDependencies": { + "date-fns": "^2.0.0" + }, + "peerDependenciesMeta": { + "date-fns": { + "optional": true + } + } + }, + "node_modules/@date-io/date-fns-jalali": { + "version": "2.17.0", + "resolved": "https://registry.npmjs.org/@date-io/date-fns-jalali/-/date-fns-jalali-2.17.0.tgz", + "integrity": "sha512-KpnYctxafW9lgILD6fE1qsacT3EnNkii9fIDiIAJ+9hXL0GcobQUB3KrTAsEQjMKSMP1WhsvwgJ0JNRdW5Zc8g==", + "license": "MIT", + "dependencies": { + "@date-io/core": "^2.17.0" + }, + "peerDependencies": { + "date-fns-jalali": "^2.13.0-0" + }, + "peerDependenciesMeta": { + "date-fns-jalali": { + "optional": true + } + } + }, + "node_modules/@date-io/dayjs": { + "version": "2.17.0", + "resolved": "https://registry.npmjs.org/@date-io/dayjs/-/dayjs-2.17.0.tgz", + "integrity": "sha512-Iq1wjY5XzBh0lheFA0it6Dsyv94e8mTiNR8vuTai+KopxDkreL3YjwTmZHxkgB7/vd0RMIACStzVgWvPATnDCA==", + "license": "MIT", + "dependencies": { + "@date-io/core": "^2.17.0" + }, + "peerDependencies": { + "dayjs": "^1.8.17" + }, + "peerDependenciesMeta": { + "dayjs": { + "optional": true + } + } + }, + "node_modules/@date-io/jalaali": { + "version": "2.17.0", + "resolved": "https://registry.npmjs.org/@date-io/jalaali/-/jalaali-2.17.0.tgz", + "integrity": "sha512-DPBJ6dfBQOmTVQOsbdkmR//zBZShCpeyEmxybDJJbZt+uj7bp3Vp3TXzgRdYqwhIPD/u3JC7llznBsbK9erFdA==", + "license": "MIT", + "dependencies": { + "@date-io/moment": "^2.17.0" + }, + "peerDependencies": { + "moment-jalaali": "^0.7.4 || ^0.8.0 || ^0.9.0" + }, + "peerDependenciesMeta": { + "moment-jalaali": { + "optional": true + } + } + }, + "node_modules/@date-io/luxon": { + "version": "2.17.0", + "resolved": "https://registry.npmjs.org/@date-io/luxon/-/luxon-2.17.0.tgz", + "integrity": "sha512-l712Vdm/uTddD2XWt9TlQloZUiTiRQtY5TCOG45MQ/8u0tu8M17BD6QYHar/3OrnkGybALAMPzCy1r5D7+0HBg==", + "license": "MIT", + "dependencies": { + "@date-io/core": "^2.17.0" + }, + "peerDependencies": { + "luxon": "^1.21.3 || ^2.x || ^3.x" + }, + "peerDependenciesMeta": { + "luxon": { + "optional": true + } + } + }, + "node_modules/@date-io/moment": { + "version": "2.17.0", + "resolved": "https://registry.npmjs.org/@date-io/moment/-/moment-2.17.0.tgz", + "integrity": "sha512-e4nb4CDZU4k0WRVhz1Wvl7d+hFsedObSauDHKtZwU9kt7gdYEAzKgnrSCTHsEaXrDumdrkCYTeZ0Tmyk7uV4tw==", + "license": "MIT", + "dependencies": { + "@date-io/core": "^2.17.0" + }, + "peerDependencies": { + "moment": "^2.24.0" + }, + "peerDependenciesMeta": { + "moment": { + "optional": true + } + } + }, + "node_modules/@emotion/babel-plugin": { + "version": "11.13.5", + "resolved": "https://registry.npmjs.org/@emotion/babel-plugin/-/babel-plugin-11.13.5.tgz", + "integrity": "sha512-pxHCpT2ex+0q+HH91/zsdHkw/lXd468DIN2zvfvLtPKLLMo6gQj7oLObq8PhkrxOZb/gGCq03S3Z7PDhS8pduQ==", + "license": "MIT", + "dependencies": { + "@babel/helper-module-imports": "^7.16.7", + "@babel/runtime": "^7.18.3", + "@emotion/hash": "^0.9.2", + "@emotion/memoize": "^0.9.0", + "@emotion/serialize": "^1.3.3", + "babel-plugin-macros": "^3.1.0", + "convert-source-map": "^1.5.0", + "escape-string-regexp": "^4.0.0", + "find-root": "^1.1.0", + "source-map": "^0.5.7", + "stylis": "4.2.0" + } + }, + "node_modules/@emotion/babel-plugin/node_modules/stylis": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/stylis/-/stylis-4.2.0.tgz", + "integrity": "sha512-Orov6g6BB1sDfYgzWfTHDOxamtX1bE/zo104Dh9e6fqJ3PooipYyfJ0pUmrZO2wAvO8YbEyeFrkV91XTsGMSrw==", + "license": "MIT" + }, + "node_modules/@emotion/cache": { + "version": "11.14.0", + "resolved": "https://registry.npmjs.org/@emotion/cache/-/cache-11.14.0.tgz", + "integrity": "sha512-L/B1lc/TViYk4DcpGxtAVbx0ZyiKM5ktoIyafGkH6zg/tj+mA+NE//aPYKG0k8kCHSHVJrpLpcAlOBEXQ3SavA==", + "license": "MIT", + "dependencies": { + "@emotion/memoize": "^0.9.0", + "@emotion/sheet": "^1.4.0", + "@emotion/utils": "^1.4.2", + "@emotion/weak-memoize": "^0.4.0", + "stylis": "4.2.0" + } + }, + "node_modules/@emotion/cache/node_modules/stylis": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/stylis/-/stylis-4.2.0.tgz", + "integrity": "sha512-Orov6g6BB1sDfYgzWfTHDOxamtX1bE/zo104Dh9e6fqJ3PooipYyfJ0pUmrZO2wAvO8YbEyeFrkV91XTsGMSrw==", + "license": "MIT" + }, + "node_modules/@emotion/hash": { + "version": "0.9.2", + "resolved": "https://registry.npmjs.org/@emotion/hash/-/hash-0.9.2.tgz", + "integrity": "sha512-MyqliTZGuOm3+5ZRSaaBGP3USLw6+EGykkwZns2EPC5g8jJ4z9OrdZY9apkl3+UP9+sdz76YYkwCKP5gh8iY3g==", + "license": "MIT" + }, + "node_modules/@emotion/is-prop-valid": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@emotion/is-prop-valid/-/is-prop-valid-1.4.0.tgz", + "integrity": "sha512-QgD4fyscGcbbKwJmqNvUMSE02OsHUa+lAWKdEUIJKgqe5IwRSKd7+KhibEWdaKwgjLj0DRSHA9biAIqGBk05lw==", + "license": "MIT", + "dependencies": { + "@emotion/memoize": "^0.9.0" + } + }, + "node_modules/@emotion/memoize": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.9.0.tgz", + "integrity": "sha512-30FAj7/EoJ5mwVPOWhAyCX+FPfMDrVecJAM+Iw9NRoSl4BBAQeqj4cApHHUXOVvIPgLVDsCFoz/hGD+5QQD1GQ==", + "license": "MIT" + }, + "node_modules/@emotion/react": { + "version": "11.14.0", + "resolved": "https://registry.npmjs.org/@emotion/react/-/react-11.14.0.tgz", + "integrity": "sha512-O000MLDBDdk/EohJPFUqvnp4qnHeYkVP5B0xEG0D/L7cOKP9kefu2DXn8dj74cQfsEzUqh+sr1RzFqiL1o+PpA==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.18.3", + "@emotion/babel-plugin": "^11.13.5", + "@emotion/cache": "^11.14.0", + "@emotion/serialize": "^1.3.3", + "@emotion/use-insertion-effect-with-fallbacks": "^1.2.0", + "@emotion/utils": "^1.4.2", + "@emotion/weak-memoize": "^0.4.0", + "hoist-non-react-statics": "^3.3.1" + }, + "peerDependencies": { + "react": ">=16.8.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@emotion/serialize": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/@emotion/serialize/-/serialize-1.3.3.tgz", + "integrity": "sha512-EISGqt7sSNWHGI76hC7x1CksiXPahbxEOrC5RjmFRJTqLyEK9/9hZvBbiYn70dw4wuwMKiEMCUlR6ZXTSWQqxA==", + "license": "MIT", + "dependencies": { + "@emotion/hash": "^0.9.2", + "@emotion/memoize": "^0.9.0", + "@emotion/unitless": "^0.10.0", + "@emotion/utils": "^1.4.2", + "csstype": "^3.0.2" + } + }, + "node_modules/@emotion/sheet": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@emotion/sheet/-/sheet-1.4.0.tgz", + "integrity": "sha512-fTBW9/8r2w3dXWYM4HCB1Rdp8NLibOw2+XELH5m5+AkWiL/KqYX6dc0kKYlaYyKjrQ6ds33MCdMPEwgs2z1rqg==", + "license": "MIT" + }, + "node_modules/@emotion/styled": { + "version": "11.14.1", + "resolved": "https://registry.npmjs.org/@emotion/styled/-/styled-11.14.1.tgz", + "integrity": "sha512-qEEJt42DuToa3gurlH4Qqc1kVpNq8wO8cJtDzU46TjlzWjDlsVyevtYCRijVq3SrHsROS+gVQ8Fnea108GnKzw==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.18.3", + "@emotion/babel-plugin": "^11.13.5", + "@emotion/is-prop-valid": "^1.3.0", + "@emotion/serialize": "^1.3.3", + "@emotion/use-insertion-effect-with-fallbacks": "^1.2.0", + "@emotion/utils": "^1.4.2" + }, + "peerDependencies": { + "@emotion/react": "^11.0.0-rc.0", + "react": ">=16.8.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@emotion/unitless": { + "version": "0.10.0", + "resolved": "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.10.0.tgz", + "integrity": "sha512-dFoMUuQA20zvtVTuxZww6OHoJYgrzfKM1t52mVySDJnMSEa08ruEvdYQbhvyu6soU+NeLVd3yKfTfT0NeV6qGg==", + "license": "MIT" + }, + "node_modules/@emotion/use-insertion-effect-with-fallbacks": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@emotion/use-insertion-effect-with-fallbacks/-/use-insertion-effect-with-fallbacks-1.2.0.tgz", + "integrity": "sha512-yJMtVdH59sxi/aVJBpk9FQq+OR8ll5GT8oWd57UpeaKEVGab41JWaCFA7FRLoMLloOZF/c/wsPoe+bfGmRKgDg==", + "license": "MIT", + "peerDependencies": { + "react": ">=16.8.0" + } + }, + "node_modules/@emotion/utils": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/@emotion/utils/-/utils-1.4.2.tgz", + "integrity": "sha512-3vLclRofFziIa3J2wDh9jjbkUz9qk5Vi3IZ/FSTKViB0k+ef0fPV7dYrUIugbgupYDx7v9ud/SjrtEP8Y4xLoA==", + "license": "MIT" + }, + "node_modules/@emotion/weak-memoize": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/@emotion/weak-memoize/-/weak-memoize-0.4.0.tgz", + "integrity": "sha512-snKqtPW01tN0ui7yu9rGv69aJXr/a/Ywvl11sUjNtEcRc+ng/mQriFL0wLXMef74iHa/EkftbDzU9F8iFbH+zg==", + "license": "MIT" + }, + "node_modules/@esbuild/aix-ppc64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.21.5.tgz", + "integrity": "sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==", + "cpu": [ + "ppc64" + ], + "license": "MIT", + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-arm": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.21.5.tgz", + "integrity": "sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==", + "cpu": [ + "arm" + ], + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.21.5.tgz", + "integrity": "sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.21.5.tgz", + "integrity": "sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/darwin-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.21.5.tgz", + "integrity": "sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/darwin-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.21.5.tgz", + "integrity": "sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.21.5.tgz", + "integrity": "sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/freebsd-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.21.5.tgz", + "integrity": "sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-arm": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.21.5.tgz", + "integrity": "sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==", + "cpu": [ + "arm" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.21.5.tgz", + "integrity": "sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-ia32": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.21.5.tgz", + "integrity": "sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==", + "cpu": [ + "ia32" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-loong64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.21.5.tgz", + "integrity": "sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==", + "cpu": [ + "loong64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-mips64el": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.21.5.tgz", + "integrity": "sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==", + "cpu": [ + "mips64el" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-ppc64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.21.5.tgz", + "integrity": "sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==", + "cpu": [ + "ppc64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-riscv64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.21.5.tgz", + "integrity": "sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==", + "cpu": [ + "riscv64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-s390x": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.21.5.tgz", + "integrity": "sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==", + "cpu": [ + "s390x" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.21.5.tgz", + "integrity": "sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/netbsd-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.21.5.tgz", + "integrity": "sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/openbsd-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.21.5.tgz", + "integrity": "sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/sunos-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.21.5.tgz", + "integrity": "sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.21.5.tgz", + "integrity": "sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-ia32": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.21.5.tgz", + "integrity": "sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==", + "cpu": [ + "ia32" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.21.5.tgz", + "integrity": "sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@eslint-community/eslint-utils": { + "version": "4.9.0", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.9.0.tgz", + "integrity": "sha512-ayVFHdtZ+hsq1t2Dy24wCmGXGe4q9Gu3smhLYALJrr473ZH27MsnSL+LKUlimp4BWJqMDMLmPpx/Q9R3OAlL4g==", + "dev": true, + "license": "MIT", + "dependencies": { + "eslint-visitor-keys": "^3.4.3" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" + } + }, + "node_modules/@eslint/eslintrc": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.4.1.tgz", + "integrity": "sha512-XXrH9Uarn0stsyldqDYq8r++mROmWRI1xKMXa640Bb//SY1+ECYX6VzT6Lcx5frD0V30XieqJ0oX9I2Xj5aoMA==", + "license": "MIT", + "dependencies": { + "ajv": "^6.12.4", + "debug": "^4.3.2", + "espree": "^9.4.0", + "globals": "^13.19.0", + "ignore": "^5.2.0", + "import-fresh": "^3.2.1", + "js-yaml": "^4.1.0", + "minimatch": "^3.1.2", + "strip-json-comments": "^3.1.1" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@floating-ui/core": { + "version": "1.7.3", + "resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.7.3.tgz", + "integrity": "sha512-sGnvb5dmrJaKEZ+LDIpguvdX3bDlEllmv4/ClQ9awcmCZrlx5jQyyMWFM5kBI+EyNOCDDiKk8il0zeuX3Zlg/w==", + "license": "MIT", + "dependencies": { + "@floating-ui/utils": "^0.2.10" + } + }, + "node_modules/@floating-ui/dom": { + "version": "1.7.4", + "resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.7.4.tgz", + "integrity": "sha512-OOchDgh4F2CchOX94cRVqhvy7b3AFb+/rQXyswmzmGakRfkMgoWVjfnLWkRirfLEfuD4ysVW16eXzwt3jHIzKA==", + "license": "MIT", + "dependencies": { + "@floating-ui/core": "^1.7.3", + "@floating-ui/utils": "^0.2.10" + } + }, + "node_modules/@floating-ui/react-dom": { + "version": "2.1.6", + "resolved": "https://registry.npmjs.org/@floating-ui/react-dom/-/react-dom-2.1.6.tgz", + "integrity": "sha512-4JX6rEatQEvlmgU80wZyq9RT96HZJa88q8hp0pBd+LrczeDI4o6uA2M+uvxngVHo4Ihr8uibXxH6+70zhAFrVw==", + "license": "MIT", + "dependencies": { + "@floating-ui/dom": "^1.7.4" + }, + "peerDependencies": { + "react": ">=16.8.0", + "react-dom": ">=16.8.0" + } + }, + "node_modules/@floating-ui/utils": { + "version": "0.2.10", + "resolved": "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.2.10.tgz", + "integrity": "sha512-aGTxbpbg8/b5JfU1HXSrbH3wXZuLPJcNEcZQFMxLs3oSzgtVu6nFPkbbGGUvBcUjKV2YyB9Wxxabo+HEH9tcRQ==", + "license": "MIT" + }, + "node_modules/@humanwhocodes/config-array": { + "version": "0.10.7", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.10.7.tgz", + "integrity": "sha512-MDl6D6sBsaV452/QSdX+4CXIjZhIcI0PELsxUjk4U828yd58vk3bTIvk/6w5FY+4hIy9sLW0sfrV7K7Kc++j/w==", + "deprecated": "Use @eslint/config-array instead", + "license": "Apache-2.0", + "dependencies": { + "@humanwhocodes/object-schema": "^1.2.1", + "debug": "^4.1.1", + "minimatch": "^3.0.4" + }, + "engines": { + "node": ">=10.10.0" + } + }, + "node_modules/@humanwhocodes/gitignore-to-minimatch": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@humanwhocodes/gitignore-to-minimatch/-/gitignore-to-minimatch-1.0.2.tgz", + "integrity": "sha512-rSqmMJDdLFUsyxR6FMtD00nfQKKLFb1kv+qBbOVKqErvloEIJLo5bDTJTQNTYgeyp78JsA7u/NPi5jT1GR/MuA==", + "license": "Apache-2.0", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "node_modules/@humanwhocodes/object-schema": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz", + "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==", + "deprecated": "Use @eslint/object-schema instead", + "license": "BSD-3-Clause" + }, + "node_modules/@jest/diff-sequences": { + "version": "30.0.1", + "resolved": "https://registry.npmjs.org/@jest/diff-sequences/-/diff-sequences-30.0.1.tgz", + "integrity": "sha512-n5H8QLDJ47QqbCNn5SuFjCRDrOLEZ0h8vAHCK5RL9Ls7Xa8AQLa/YxAc9UjFqoEDM48muwtBGjtMY5cr0PLDCw==", + "license": "MIT", + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/@jest/expect-utils": { + "version": "30.2.0", + "resolved": "https://registry.npmjs.org/@jest/expect-utils/-/expect-utils-30.2.0.tgz", + "integrity": "sha512-1JnRfhqpD8HGpOmQp180Fo9Zt69zNtC+9lR+kT7NVL05tNXIi+QC8Csz7lfidMoVLPD3FnOtcmp0CEFnxExGEA==", + "license": "MIT", + "dependencies": { + "@jest/get-type": "30.1.0" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/@jest/get-type": { + "version": "30.1.0", + "resolved": "https://registry.npmjs.org/@jest/get-type/-/get-type-30.1.0.tgz", + "integrity": "sha512-eMbZE2hUnx1WV0pmURZY9XoXPkUYjpc55mb0CrhtdWLtzMQPFvu/rZkTLZFTsdaVQa+Tr4eWAteqcUzoawq/uA==", + "license": "MIT", + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/@jest/pattern": { + "version": "30.0.1", + "resolved": "https://registry.npmjs.org/@jest/pattern/-/pattern-30.0.1.tgz", + "integrity": "sha512-gWp7NfQW27LaBQz3TITS8L7ZCQ0TLvtmI//4OwlQRx4rnWxcPNIYjxZpDcN4+UlGxgm3jS5QPz8IPTCkb59wZA==", + "license": "MIT", + "dependencies": { + "@types/node": "*", + "jest-regex-util": "30.0.1" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/@jest/schemas": { + "version": "30.0.5", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-30.0.5.tgz", + "integrity": "sha512-DmdYgtezMkh3cpU8/1uyXakv3tJRcmcXxBOcO0tbaozPwpmh4YMsnWrQm9ZmZMfa5ocbxzbFk6O4bDPEc/iAnA==", + "license": "MIT", + "dependencies": { + "@sinclair/typebox": "^0.34.0" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/@jest/types": { + "version": "30.2.0", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-30.2.0.tgz", + "integrity": "sha512-H9xg1/sfVvyfU7o3zMfBEjQ1gcsdeTMgqHoYdN79tuLqfTtuu7WckRA1R5whDwOzxaZAeMKTYWqP+WCAi0CHsg==", + "license": "MIT", + "dependencies": { + "@jest/pattern": "30.0.1", + "@jest/schemas": "30.0.5", + "@types/istanbul-lib-coverage": "^2.0.6", + "@types/istanbul-reports": "^3.0.4", + "@types/node": "*", + "@types/yargs": "^17.0.33", + "chalk": "^4.1.2" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/@jest/types/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.13", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz", + "integrity": "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==", + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.0", + "@jridgewell/trace-mapping": "^0.3.24" + } + }, + "node_modules/@jridgewell/remapping": { + "version": "2.3.5", + "resolved": "https://registry.npmjs.org/@jridgewell/remapping/-/remapping-2.3.5.tgz", + "integrity": "sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==", + "license": "MIT", + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.24" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", + "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", + "license": "MIT", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/source-map": { + "version": "0.3.11", + "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.11.tgz", + "integrity": "sha512-ZMp1V8ZFcPG5dIWnQLr3NSI1MiCU7UETdS/A0G8V/XWHvJv3ZsFqutJn1Y5RPmAPX6F3BiE397OqveU/9NCuIA==", + "license": "MIT", + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.25" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.5.5", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz", + "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==", + "license": "MIT" + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.31", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz", + "integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==", + "license": "MIT", + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, + "node_modules/@kurkle/color": { + "version": "0.3.4", + "resolved": "https://registry.npmjs.org/@kurkle/color/-/color-0.3.4.tgz", + "integrity": "sha512-M5UknZPHRu3DEDWoipU6sE8PdkZ6Z/S+v4dD+Ke8IaNlpdSQah50lz1KtcFBa2vsdOnwbbnxJwVM4wty6udA5w==", + "license": "MIT" + }, + "node_modules/@motionone/animation": { + "version": "10.18.0", + "resolved": "https://registry.npmjs.org/@motionone/animation/-/animation-10.18.0.tgz", + "integrity": "sha512-9z2p5GFGCm0gBsZbi8rVMOAJCtw1WqBTIPw3ozk06gDvZInBPIsQcHgYogEJ4yuHJ+akuW8g1SEIOpTOvYs8hw==", + "license": "MIT", + "dependencies": { + "@motionone/easing": "^10.18.0", + "@motionone/types": "^10.17.1", + "@motionone/utils": "^10.18.0", + "tslib": "^2.3.1" + } + }, + "node_modules/@motionone/animation/node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "license": "0BSD" + }, + "node_modules/@motionone/dom": { + "version": "10.18.0", + "resolved": "https://registry.npmjs.org/@motionone/dom/-/dom-10.18.0.tgz", + "integrity": "sha512-bKLP7E0eyO4B2UaHBBN55tnppwRnaE3KFfh3Ps9HhnAkar3Cb69kUCJY9as8LrccVYKgHA+JY5dOQqJLOPhF5A==", + "license": "MIT", + "dependencies": { + "@motionone/animation": "^10.18.0", + "@motionone/generators": "^10.18.0", + "@motionone/types": "^10.17.1", + "@motionone/utils": "^10.18.0", + "hey-listen": "^1.0.8", + "tslib": "^2.3.1" + } + }, + "node_modules/@motionone/dom/node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "license": "0BSD" + }, + "node_modules/@motionone/easing": { + "version": "10.18.0", + "resolved": "https://registry.npmjs.org/@motionone/easing/-/easing-10.18.0.tgz", + "integrity": "sha512-VcjByo7XpdLS4o9T8t99JtgxkdMcNWD3yHU/n6CLEz3bkmKDRZyYQ/wmSf6daum8ZXqfUAgFeCZSpJZIMxaCzg==", + "license": "MIT", + "dependencies": { + "@motionone/utils": "^10.18.0", + "tslib": "^2.3.1" + } + }, + "node_modules/@motionone/easing/node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "license": "0BSD" + }, + "node_modules/@motionone/generators": { + "version": "10.18.0", + "resolved": "https://registry.npmjs.org/@motionone/generators/-/generators-10.18.0.tgz", + "integrity": "sha512-+qfkC2DtkDj4tHPu+AFKVfR/C30O1vYdvsGYaR13W/1cczPrrcjdvYCj0VLFuRMN+lP1xvpNZHCRNM4fBzn1jg==", + "license": "MIT", + "dependencies": { + "@motionone/types": "^10.17.1", + "@motionone/utils": "^10.18.0", + "tslib": "^2.3.1" + } + }, + "node_modules/@motionone/generators/node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "license": "0BSD" + }, + "node_modules/@motionone/types": { + "version": "10.17.1", + "resolved": "https://registry.npmjs.org/@motionone/types/-/types-10.17.1.tgz", + "integrity": "sha512-KaC4kgiODDz8hswCrS0btrVrzyU2CSQKO7Ps90ibBVSQmjkrt2teqta6/sOG59v7+dPnKMAg13jyqtMKV2yJ7A==", + "license": "MIT" + }, + "node_modules/@motionone/utils": { + "version": "10.18.0", + "resolved": "https://registry.npmjs.org/@motionone/utils/-/utils-10.18.0.tgz", + "integrity": "sha512-3XVF7sgyTSI2KWvTf6uLlBJ5iAgRgmvp3bpuOiQJvInd4nZ19ET8lX5unn30SlmRH7hXbBbH+Gxd0m0klJ3Xtw==", + "license": "MIT", + "dependencies": { + "@motionone/types": "^10.17.1", + "hey-listen": "^1.0.8", + "tslib": "^2.3.1" + } + }, + "node_modules/@motionone/utils/node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "license": "0BSD" + }, + "node_modules/@mui/base": { + "version": "5.0.0-beta.40-1", + "resolved": "https://registry.npmjs.org/@mui/base/-/base-5.0.0-beta.40-1.tgz", + "integrity": "sha512-agKXuNNy0bHUmeU7pNmoZwNFr7Hiyhojkb9+2PVyDG5+6RafYuyMgbrav8CndsB7KUc/U51JAw9vKNDLYBzaUA==", + "deprecated": "This package has been replaced by @base-ui-components/react", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.23.9", + "@floating-ui/react-dom": "^2.0.8", + "@mui/types": "~7.2.15", + "@mui/utils": "^5.17.1", + "@popperjs/core": "^2.11.8", + "clsx": "^2.1.0", + "prop-types": "^15.8.1" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui-org" + }, + "peerDependencies": { + "@types/react": "^17.0.0 || ^18.0.0 || ^19.0.0", + "react": "^17.0.0 || ^18.0.0 || ^19.0.0", + "react-dom": "^17.0.0 || ^18.0.0 || ^19.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@mui/core-downloads-tracker": { + "version": "5.18.0", + "resolved": "https://registry.npmjs.org/@mui/core-downloads-tracker/-/core-downloads-tracker-5.18.0.tgz", + "integrity": "sha512-jbhwoQ1AY200PSSOrNXmrFCaSDSJWP7qk6urkTmIirvRXDROkqe+QwcLlUiw/PrREwsIF/vm3/dAXvjlMHF0RA==", + "license": "MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui-org" + } + }, + "node_modules/@mui/icons-material": { + "version": "5.18.0", + "resolved": "https://registry.npmjs.org/@mui/icons-material/-/icons-material-5.18.0.tgz", + "integrity": "sha512-1s0vEZj5XFXDMmz3Arl/R7IncFqJ+WQ95LDp1roHWGDE2oCO3IS4/hmiOv1/8SD9r6B7tv9GLiqVZYHo+6PkTg==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.23.9" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui-org" + }, + "peerDependencies": { + "@mui/material": "^5.0.0", + "@types/react": "^17.0.0 || ^18.0.0 || ^19.0.0", + "react": "^17.0.0 || ^18.0.0 || ^19.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@mui/lab": { + "version": "5.0.0-alpha.177", + "resolved": "https://registry.npmjs.org/@mui/lab/-/lab-5.0.0-alpha.177.tgz", + "integrity": "sha512-bdCxxtNjlWAgN9rtrwlmFydJ1qxA3IIbb6OlomGFsIXw0zGoHomLyjvh72q/R3yUAC0kvSef18cHY1UalLylyQ==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.23.9", + "@mui/base": "5.0.0-beta.40-1", + "@mui/system": "^5.18.0", + "@mui/types": "~7.2.15", + "@mui/utils": "^5.17.1", + "clsx": "^2.1.0", + "prop-types": "^15.8.1" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui-org" + }, + "peerDependencies": { + "@emotion/react": "^11.5.0", + "@emotion/styled": "^11.3.0", + "@mui/material": ">=5.15.0", + "@types/react": "^17.0.0 || ^18.0.0 || ^19.0.0", + "react": "^17.0.0 || ^18.0.0 || ^19.0.0", + "react-dom": "^17.0.0 || ^18.0.0 || ^19.0.0" + }, + "peerDependenciesMeta": { + "@emotion/react": { + "optional": true + }, + "@emotion/styled": { + "optional": true + }, + "@types/react": { + "optional": true + } + } + }, + "node_modules/@mui/material": { + "version": "5.18.0", + "resolved": "https://registry.npmjs.org/@mui/material/-/material-5.18.0.tgz", + "integrity": "sha512-bbH/HaJZpFtXGvWg3TsBWG4eyt3gah3E7nCNU8GLyRjVoWcA91Vm/T+sjHfUcwgJSw9iLtucfHBoq+qW/T30aA==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.23.9", + "@mui/core-downloads-tracker": "^5.18.0", + "@mui/system": "^5.18.0", + "@mui/types": "~7.2.15", + "@mui/utils": "^5.17.1", + "@popperjs/core": "^2.11.8", + "@types/react-transition-group": "^4.4.10", + "clsx": "^2.1.0", + "csstype": "^3.1.3", + "prop-types": "^15.8.1", + "react-is": "^19.0.0", + "react-transition-group": "^4.4.5" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui-org" + }, + "peerDependencies": { + "@emotion/react": "^11.5.0", + "@emotion/styled": "^11.3.0", + "@types/react": "^17.0.0 || ^18.0.0 || ^19.0.0", + "react": "^17.0.0 || ^18.0.0 || ^19.0.0", + "react-dom": "^17.0.0 || ^18.0.0 || ^19.0.0" + }, + "peerDependenciesMeta": { + "@emotion/react": { + "optional": true + }, + "@emotion/styled": { + "optional": true + }, + "@types/react": { + "optional": true + } + } + }, + "node_modules/@mui/material/node_modules/react-is": { + "version": "19.2.0", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-19.2.0.tgz", + "integrity": "sha512-x3Ax3kNSMIIkyVYhWPyO09bu0uttcAIoecO/um/rKGQ4EltYWVYtyiGkS/3xMynrbVQdS69Jhlv8FXUEZehlzA==", + "license": "MIT" + }, + "node_modules/@mui/private-theming": { + "version": "5.17.1", + "resolved": "https://registry.npmjs.org/@mui/private-theming/-/private-theming-5.17.1.tgz", + "integrity": "sha512-XMxU0NTYcKqdsG8LRmSoxERPXwMbp16sIXPcLVgLGII/bVNagX0xaheWAwFv8+zDK7tI3ajllkuD3GZZE++ICQ==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.23.9", + "@mui/utils": "^5.17.1", + "prop-types": "^15.8.1" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui-org" + }, + "peerDependencies": { + "@types/react": "^17.0.0 || ^18.0.0 || ^19.0.0", + "react": "^17.0.0 || ^18.0.0 || ^19.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@mui/styled-engine": { + "version": "5.18.0", + "resolved": "https://registry.npmjs.org/@mui/styled-engine/-/styled-engine-5.18.0.tgz", + "integrity": "sha512-BN/vKV/O6uaQh2z5rXV+MBlVrEkwoS/TK75rFQ2mjxA7+NBo8qtTAOA4UaM0XeJfn7kh2wZ+xQw2HAx0u+TiBg==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.23.9", + "@emotion/cache": "^11.13.5", + "@emotion/serialize": "^1.3.3", + "csstype": "^3.1.3", + "prop-types": "^15.8.1" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui-org" + }, + "peerDependencies": { + "@emotion/react": "^11.4.1", + "@emotion/styled": "^11.3.0", + "react": "^17.0.0 || ^18.0.0 || ^19.0.0" + }, + "peerDependenciesMeta": { + "@emotion/react": { + "optional": true + }, + "@emotion/styled": { + "optional": true + } + } + }, + "node_modules/@mui/system": { + "version": "5.18.0", + "resolved": "https://registry.npmjs.org/@mui/system/-/system-5.18.0.tgz", + "integrity": "sha512-ojZGVcRWqWhu557cdO3pWHloIGJdzVtxs3rk0F9L+x55LsUjcMUVkEhiF7E4TMxZoF9MmIHGGs0ZX3FDLAf0Xw==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.23.9", + "@mui/private-theming": "^5.17.1", + "@mui/styled-engine": "^5.18.0", + "@mui/types": "~7.2.15", + "@mui/utils": "^5.17.1", + "clsx": "^2.1.0", + "csstype": "^3.1.3", + "prop-types": "^15.8.1" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui-org" + }, + "peerDependencies": { + "@emotion/react": "^11.5.0", + "@emotion/styled": "^11.3.0", + "@types/react": "^17.0.0 || ^18.0.0 || ^19.0.0", + "react": "^17.0.0 || ^18.0.0 || ^19.0.0" + }, + "peerDependenciesMeta": { + "@emotion/react": { + "optional": true + }, + "@emotion/styled": { + "optional": true + }, + "@types/react": { + "optional": true + } + } + }, + "node_modules/@mui/types": { + "version": "7.2.24", + "resolved": "https://registry.npmjs.org/@mui/types/-/types-7.2.24.tgz", + "integrity": "sha512-3c8tRt/CbWZ+pEg7QpSwbdxOk36EfmhbKf6AGZsD1EcLDLTSZoxxJ86FVtcjxvjuhdyBiWKSTGZFaXCnidO2kw==", + "license": "MIT", + "peerDependencies": { + "@types/react": "^17.0.0 || ^18.0.0 || ^19.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@mui/utils": { + "version": "5.17.1", + "resolved": "https://registry.npmjs.org/@mui/utils/-/utils-5.17.1.tgz", + "integrity": "sha512-jEZ8FTqInt2WzxDV8bhImWBqeQRD99c/id/fq83H0ER9tFl+sfZlaAoCdznGvbSQQ9ividMxqSV2c7cC1vBcQg==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.23.9", + "@mui/types": "~7.2.15", + "@types/prop-types": "^15.7.12", + "clsx": "^2.1.1", + "prop-types": "^15.8.1", + "react-is": "^19.0.0" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui-org" + }, + "peerDependencies": { + "@types/react": "^17.0.0 || ^18.0.0 || ^19.0.0", + "react": "^17.0.0 || ^18.0.0 || ^19.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@mui/utils/node_modules/react-is": { + "version": "19.2.0", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-19.2.0.tgz", + "integrity": "sha512-x3Ax3kNSMIIkyVYhWPyO09bu0uttcAIoecO/um/rKGQ4EltYWVYtyiGkS/3xMynrbVQdS69Jhlv8FXUEZehlzA==", + "license": "MIT" + }, + "node_modules/@mui/x-date-pickers": { + "version": "5.0.20", + "resolved": "https://registry.npmjs.org/@mui/x-date-pickers/-/x-date-pickers-5.0.20.tgz", + "integrity": "sha512-ERukSeHIoNLbI1C2XRhF9wRhqfsr+Q4B1SAw2ZlU7CWgcG8UBOxgqRKDEOVAIoSWL+DWT6GRuQjOKvj6UXZceA==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.18.9", + "@date-io/core": "^2.15.0", + "@date-io/date-fns": "^2.15.0", + "@date-io/dayjs": "^2.15.0", + "@date-io/luxon": "^2.15.0", + "@date-io/moment": "^2.15.0", + "@mui/utils": "^5.10.3", + "@types/react-transition-group": "^4.4.5", + "clsx": "^1.2.1", + "prop-types": "^15.7.2", + "react-transition-group": "^4.4.5", + "rifm": "^0.12.1" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui" + }, + "peerDependencies": { + "@emotion/react": "^11.9.0", + "@emotion/styled": "^11.8.1", + "@mui/material": "^5.4.1", + "@mui/system": "^5.4.1", + "date-fns": "^2.25.0", + "dayjs": "^1.10.7", + "luxon": "^1.28.0 || ^2.0.0 || ^3.0.0", + "moment": "^2.29.1", + "react": "^17.0.2 || ^18.0.0", + "react-dom": "^17.0.2 || ^18.0.0" + }, + "peerDependenciesMeta": { + "@emotion/react": { + "optional": true + }, + "@emotion/styled": { + "optional": true + }, + "date-fns": { + "optional": true + }, + "dayjs": { + "optional": true + }, + "luxon": { + "optional": true + }, + "moment": { + "optional": true + } + } + }, + "node_modules/@mui/x-date-pickers/node_modules/clsx": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/clsx/-/clsx-1.2.1.tgz", + "integrity": "sha512-EcR6r5a8bj6pu3ycsa/E/cKVGuTgZJZdsyUYHOksG/UHIiKfjxzRxYJpyVBwYaQeOvghal9fcc4PidlgzugAQg==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "license": "MIT", + "dependencies": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "license": "MIT", + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "license": "MIT", + "dependencies": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@popperjs/core": { + "version": "2.11.8", + "resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.8.tgz", + "integrity": "sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A==", + "license": "MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/popperjs" + } + }, + "node_modules/@react-dnd/asap": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@react-dnd/asap/-/asap-4.0.1.tgz", + "integrity": "sha512-kLy0PJDDwvwwTXxqTFNAAllPHD73AycE9ypWeln/IguoGBEbvFcPDbCV03G52bEcC5E+YgupBE0VzHGdC8SIXg==", + "license": "MIT" + }, + "node_modules/@react-dnd/invariant": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@react-dnd/invariant/-/invariant-2.0.0.tgz", + "integrity": "sha512-xL4RCQBCBDJ+GRwKTFhGUW8GXa4yoDfJrPbLblc3U09ciS+9ZJXJ3Qrcs/x2IODOdIE5kQxvMmE2UKyqUictUw==", + "license": "MIT" + }, + "node_modules/@react-dnd/shallowequal": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@react-dnd/shallowequal/-/shallowequal-2.0.0.tgz", + "integrity": "sha512-Pc/AFTdwZwEKJxFJvlxrSmGe/di+aAOBn60sremrpLo6VI/6cmiUYNNwlI5KNYttg7uypzA3ILPMPgxB2GYZEg==", + "license": "MIT" + }, + "node_modules/@reactour/mask": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@reactour/mask/-/mask-1.2.0.tgz", + "integrity": "sha512-XLgBLWfKJybtZjNTSO5lt/SIvRlCZBadB6JfE/hO1ErqURRjYhnv+edC0Ki1haUCqMGFppWk3lwcPCjmK0xNog==", + "license": "MIT", + "dependencies": { + "@reactour/utils": "*" + }, + "peerDependencies": { + "react": "16.x || 17.x || 18.x || 19.x" + } + }, + "node_modules/@reactour/popover": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@reactour/popover/-/popover-1.3.0.tgz", + "integrity": "sha512-YdyjSmHPvEeQEcJM4gcGFa5pI/Yf4nZGqwG4JnT+rK1SyUJBIPnm4Gkl/h7/+1g0KCFMkwNwagS3ZiXvZB7ThA==", + "license": "MIT", + "dependencies": { + "@reactour/utils": "*" + }, + "peerDependencies": { + "react": "16.x || 17.x || 18.x || 19.x" + } + }, + "node_modules/@reactour/tour": { + "version": "3.8.0", + "resolved": "https://registry.npmjs.org/@reactour/tour/-/tour-3.8.0.tgz", + "integrity": "sha512-KZTFi1pAvoTVKKRdBN5+XCYxXBp4k4Ql/acZcXyPvec8VU24fkMSEeV+v8krfYQpoVcewxIu3gM6xWZZLjxi7w==", + "license": "MIT", + "dependencies": { + "@reactour/mask": "*", + "@reactour/popover": "*", + "@reactour/utils": "*" + }, + "peerDependencies": { + "react": "16.x || 17.x || 18.x || 19.x" + } + }, + "node_modules/@reactour/utils": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/@reactour/utils/-/utils-0.6.0.tgz", + "integrity": "sha512-GqaLjQi7MJsgtAKjdiw2Eak1toFkADoLRnm1+HZpaD+yl+DkaHpC1N7JAl+kVOO5I17bWInPA+OFbXjO9Co8Qg==", + "license": "MIT", + "dependencies": { + "@rooks/use-mutation-observer": "^4.11.2", + "resize-observer-polyfill": "^1.5.1" + }, + "peerDependencies": { + "react": "16.x || 17.x || 18.x || 19.x" + } + }, + "node_modules/@reduxjs/toolkit": { + "version": "1.9.7", + "resolved": "https://registry.npmjs.org/@reduxjs/toolkit/-/toolkit-1.9.7.tgz", + "integrity": "sha512-t7v8ZPxhhKgOKtU+uyJT13lu4vL7az5aFi4IdoDs/eS548edn2M8Ik9h8fxgvMjGoAUVFSt6ZC1P5cWmQ014QQ==", + "license": "MIT", + "dependencies": { + "immer": "^9.0.21", + "redux": "^4.2.1", + "redux-thunk": "^2.4.2", + "reselect": "^4.1.8" + }, + "peerDependencies": { + "react": "^16.9.0 || ^17.0.0 || ^18", + "react-redux": "^7.2.1 || ^8.0.2" + }, + "peerDependenciesMeta": { + "react": { + "optional": true + }, + "react-redux": { + "optional": true + } + } + }, + "node_modules/@remix-run/router": { + "version": "1.23.0", + "resolved": "https://registry.npmjs.org/@remix-run/router/-/router-1.23.0.tgz", + "integrity": "sha512-O3rHJzAQKamUz1fvE0Qaw0xSFqsA/yafi2iqeE0pvdFtCO1viYx8QL6f3Ln/aCCTLxs68SLf0KPM9eSeM8yBnA==", + "license": "MIT", + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@rolldown/pluginutils": { + "version": "1.0.0-beta.27", + "resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.0-beta.27.tgz", + "integrity": "sha512-+d0F4MKMCbeVUJwG96uQ4SgAznZNSq93I3V+9NHA4OpvqG8mRCpGdKmK8l/dl02h2CCDHwW2FqilnTyDcAnqjA==", + "license": "MIT" + }, + "node_modules/@rollup/plugin-node-resolve": { + "version": "15.3.1", + "resolved": "https://registry.npmjs.org/@rollup/plugin-node-resolve/-/plugin-node-resolve-15.3.1.tgz", + "integrity": "sha512-tgg6b91pAybXHJQMAAwW9VuWBO6Thi+q7BCNARLwSqlmsHz0XYURtGvh/AuwSADXSI4h/2uHbs7s4FzlZDGSGA==", + "license": "MIT", + "dependencies": { + "@rollup/pluginutils": "^5.0.1", + "@types/resolve": "1.20.2", + "deepmerge": "^4.2.2", + "is-module": "^1.0.0", + "resolve": "^1.22.1" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "rollup": "^2.78.0||^3.0.0||^4.0.0" + }, + "peerDependenciesMeta": { + "rollup": { + "optional": true + } + } + }, + "node_modules/@rollup/plugin-node-resolve/node_modules/deepmerge": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz", + "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/@rollup/plugin-terser": { + "version": "0.4.4", + "resolved": "https://registry.npmjs.org/@rollup/plugin-terser/-/plugin-terser-0.4.4.tgz", + "integrity": "sha512-XHeJC5Bgvs8LfukDwWZp7yeqin6ns8RTl2B9avbejt6tZqsqvVoWI7ZTQrcNsfKEDWBTnTxM8nMDkO2IFFbd0A==", + "license": "MIT", + "dependencies": { + "serialize-javascript": "^6.0.1", + "smob": "^1.0.0", + "terser": "^5.17.4" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "rollup": "^2.0.0||^3.0.0||^4.0.0" + }, + "peerDependenciesMeta": { + "rollup": { + "optional": true + } + } + }, + "node_modules/@rollup/pluginutils": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-5.3.0.tgz", + "integrity": "sha512-5EdhGZtnu3V88ces7s53hhfK5KSASnJZv8Lulpc04cWO3REESroJXg73DFsOmgbU2BhwV0E20bu2IDZb3VKW4Q==", + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0", + "estree-walker": "^2.0.2", + "picomatch": "^4.0.2" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "rollup": "^1.20.0||^2.0.0||^3.0.0||^4.0.0" + }, + "peerDependenciesMeta": { + "rollup": { + "optional": true + } + } + }, + "node_modules/@rollup/pluginutils/node_modules/estree-walker": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz", + "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==", + "license": "MIT" + }, + "node_modules/@rollup/rollup-android-arm-eabi": { + "version": "4.52.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.52.5.tgz", + "integrity": "sha512-8c1vW4ocv3UOMp9K+gToY5zL2XiiVw3k7f1ksf4yO1FlDFQ1C2u72iACFnSOceJFsWskc2WZNqeRhFRPzv+wtQ==", + "cpu": [ + "arm" + ], + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-android-arm64": { + "version": "4.52.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.52.5.tgz", + "integrity": "sha512-mQGfsIEFcu21mvqkEKKu2dYmtuSZOBMmAl5CFlPGLY94Vlcm+zWApK7F/eocsNzp8tKmbeBP8yXyAbx0XHsFNA==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-darwin-arm64": { + "version": "4.52.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.52.5.tgz", + "integrity": "sha512-takF3CR71mCAGA+v794QUZ0b6ZSrgJkArC+gUiG6LB6TQty9T0Mqh3m2ImRBOxS2IeYBo4lKWIieSvnEk2OQWA==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-darwin-x64": { + "version": "4.52.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.52.5.tgz", + "integrity": "sha512-W901Pla8Ya95WpxDn//VF9K9u2JbocwV/v75TE0YIHNTbhqUTv9w4VuQ9MaWlNOkkEfFwkdNhXgcLqPSmHy0fA==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-freebsd-arm64": { + "version": "4.52.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.52.5.tgz", + "integrity": "sha512-QofO7i7JycsYOWxe0GFqhLmF6l1TqBswJMvICnRUjqCx8b47MTo46W8AoeQwiokAx3zVryVnxtBMcGcnX12LvA==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@rollup/rollup-freebsd-x64": { + "version": "4.52.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.52.5.tgz", + "integrity": "sha512-jr21b/99ew8ujZubPo9skbrItHEIE50WdV86cdSoRkKtmWa+DDr6fu2c/xyRT0F/WazZpam6kk7IHBerSL7LDQ==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@rollup/rollup-linux-arm-gnueabihf": { + "version": "4.52.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.52.5.tgz", + "integrity": "sha512-PsNAbcyv9CcecAUagQefwX8fQn9LQ4nZkpDboBOttmyffnInRy8R8dSg6hxxl2Re5QhHBf6FYIDhIj5v982ATQ==", + "cpu": [ + "arm" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm-musleabihf": { + "version": "4.52.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.52.5.tgz", + "integrity": "sha512-Fw4tysRutyQc/wwkmcyoqFtJhh0u31K+Q6jYjeicsGJJ7bbEq8LwPWV/w0cnzOqR2m694/Af6hpFayLJZkG2VQ==", + "cpu": [ + "arm" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-gnu": { + "version": "4.52.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.52.5.tgz", + "integrity": "sha512-a+3wVnAYdQClOTlyapKmyI6BLPAFYs0JM8HRpgYZQO02rMR09ZcV9LbQB+NL6sljzG38869YqThrRnfPMCDtZg==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-musl": { + "version": "4.52.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.52.5.tgz", + "integrity": "sha512-AvttBOMwO9Pcuuf7m9PkC1PUIKsfaAJ4AYhy944qeTJgQOqJYJ9oVl2nYgY7Rk0mkbsuOpCAYSs6wLYB2Xiw0Q==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-loong64-gnu": { + "version": "4.52.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.52.5.tgz", + "integrity": "sha512-DkDk8pmXQV2wVrF6oq5tONK6UHLz/XcEVow4JTTerdeV1uqPeHxwcg7aFsfnSm9L+OO8WJsWotKM2JJPMWrQtA==", + "cpu": [ + "loong64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-ppc64-gnu": { + "version": "4.52.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.52.5.tgz", + "integrity": "sha512-W/b9ZN/U9+hPQVvlGwjzi+Wy4xdoH2I8EjaCkMvzpI7wJUs8sWJ03Rq96jRnHkSrcHTpQe8h5Tg3ZzUPGauvAw==", + "cpu": [ + "ppc64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-gnu": { + "version": "4.52.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.52.5.tgz", + "integrity": "sha512-sjQLr9BW7R/ZiXnQiWPkErNfLMkkWIoCz7YMn27HldKsADEKa5WYdobaa1hmN6slu9oWQbB6/jFpJ+P2IkVrmw==", + "cpu": [ + "riscv64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-musl": { + "version": "4.52.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.52.5.tgz", + "integrity": "sha512-hq3jU/kGyjXWTvAh2awn8oHroCbrPm8JqM7RUpKjalIRWWXE01CQOf/tUNWNHjmbMHg/hmNCwc/Pz3k1T/j/Lg==", + "cpu": [ + "riscv64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-s390x-gnu": { + "version": "4.52.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.52.5.tgz", + "integrity": "sha512-gn8kHOrku8D4NGHMK1Y7NA7INQTRdVOntt1OCYypZPRt6skGbddska44K8iocdpxHTMMNui5oH4elPH4QOLrFQ==", + "cpu": [ + "s390x" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-gnu": { + "version": "4.52.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.52.5.tgz", + "integrity": "sha512-hXGLYpdhiNElzN770+H2nlx+jRog8TyynpTVzdlc6bndktjKWyZyiCsuDAlpd+j+W+WNqfcyAWz9HxxIGfZm1Q==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-musl": { + "version": "4.52.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.52.5.tgz", + "integrity": "sha512-arCGIcuNKjBoKAXD+y7XomR9gY6Mw7HnFBv5Rw7wQRvwYLR7gBAgV7Mb2QTyjXfTveBNFAtPt46/36vV9STLNg==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-openharmony-arm64": { + "version": "4.52.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.52.5.tgz", + "integrity": "sha512-QoFqB6+/9Rly/RiPjaomPLmR/13cgkIGfA40LHly9zcH1S0bN2HVFYk3a1eAyHQyjs3ZJYlXvIGtcCs5tko9Cw==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ] + }, + "node_modules/@rollup/rollup-win32-arm64-msvc": { + "version": "4.52.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.52.5.tgz", + "integrity": "sha512-w0cDWVR6MlTstla1cIfOGyl8+qb93FlAVutcor14Gf5Md5ap5ySfQ7R9S/NjNaMLSFdUnKGEasmVnu3lCMqB7w==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-ia32-msvc": { + "version": "4.52.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.52.5.tgz", + "integrity": "sha512-Aufdpzp7DpOTULJCuvzqcItSGDH73pF3ko/f+ckJhxQyHtp67rHw3HMNxoIdDMUITJESNE6a8uh4Lo4SLouOUg==", + "cpu": [ + "ia32" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-x64-gnu": { + "version": "4.52.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.52.5.tgz", + "integrity": "sha512-UGBUGPFp1vkj6p8wCRraqNhqwX/4kNQPS57BCFc8wYh0g94iVIW33wJtQAx3G7vrjjNtRaxiMUylM0ktp/TRSQ==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-x64-msvc": { + "version": "4.52.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.52.5.tgz", + "integrity": "sha512-TAcgQh2sSkykPRWLrdyy2AiceMckNf5loITqXxFI5VuQjS5tSuw3WlwdN8qv8vzjLAUTvYaH/mVjSFpbkFbpTg==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rooks/use-mutation-observer": { + "version": "4.11.2", + "resolved": "https://registry.npmjs.org/@rooks/use-mutation-observer/-/use-mutation-observer-4.11.2.tgz", + "integrity": "sha512-vpsdrZdr6TkB1zZJcHx+fR1YC/pHs2BaqcuYiEGjBVbwY5xcC49+h0hAUtQKHth3oJqXfIX/Ng8S7s5HFHdM/A==", + "license": "MIT", + "peerDependencies": { + "react": ">=16.8.0" + } + }, + "node_modules/@sinclair/typebox": { + "version": "0.34.41", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.34.41.tgz", + "integrity": "sha512-6gS8pZzSXdyRHTIqoqSVknxolr1kzfy4/CeDnrzsVz8TTIWUbOBr6gnzOmTYJ3eXQNh4IYHIGi5aIL7sOZ2G/g==", + "license": "MIT" + }, + "node_modules/@surma/rollup-plugin-off-main-thread": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/@surma/rollup-plugin-off-main-thread/-/rollup-plugin-off-main-thread-2.2.3.tgz", + "integrity": "sha512-lR8q/9W7hZpMWweNiAKU7NQerBnzQQLvi8qnTDU/fxItPhtZVMbPV3lbCwjhIlNBe9Bbr5V+KHshvWmVSG9cxQ==", + "license": "Apache-2.0", + "dependencies": { + "ejs": "^3.1.6", + "json5": "^2.2.0", + "magic-string": "^0.25.0", + "string.prototype.matchall": "^4.0.6" + } + }, + "node_modules/@surma/rollup-plugin-off-main-thread/node_modules/magic-string": { + "version": "0.25.9", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.25.9.tgz", + "integrity": "sha512-RmF0AsMzgt25qzqqLc1+MbHmhdx0ojF2Fvs4XnOqz2ZOBXzzkEwc/dJQZCYHAn7v1jbVOjAZfK8msRn4BxO4VQ==", + "license": "MIT", + "dependencies": { + "sourcemap-codec": "^1.4.8" + } + }, + "node_modules/@tanstack/match-sorter-utils": { + "version": "8.19.4", + "resolved": "https://registry.npmjs.org/@tanstack/match-sorter-utils/-/match-sorter-utils-8.19.4.tgz", + "integrity": "sha512-Wo1iKt2b9OT7d+YGhvEPD3DXvPv2etTusIMhMUoG7fbhmxcXCtIjJDEygy91Y2JFlwGyjqiBPRozme7UD8hoqg==", + "license": "MIT", + "dependencies": { + "remove-accents": "0.5.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/tannerlinsley" + } + }, + "node_modules/@tanstack/react-table": { + "version": "8.20.5", + "resolved": "https://registry.npmjs.org/@tanstack/react-table/-/react-table-8.20.5.tgz", + "integrity": "sha512-WEHopKw3znbUZ61s9i0+i9g8drmDo6asTWbrQh8Us63DAk/M0FkmIqERew6P71HI75ksZ2Pxyuf4vvKh9rAkiA==", + "license": "MIT", + "dependencies": { + "@tanstack/table-core": "8.20.5" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/tannerlinsley" + }, + "peerDependencies": { + "react": ">=16.8", + "react-dom": ">=16.8" + } + }, + "node_modules/@tanstack/react-virtual": { + "version": "3.10.6", + "resolved": "https://registry.npmjs.org/@tanstack/react-virtual/-/react-virtual-3.10.6.tgz", + "integrity": "sha512-xaSy6uUxB92O8mngHZ6CvbhGuqxQ5lIZWCBy+FjhrbHmOwc6BnOnKkYm2FsB1/BpKw/+FVctlMbEtI+F6I1aJg==", + "license": "MIT", + "dependencies": { + "@tanstack/virtual-core": "3.10.6" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/tannerlinsley" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0", + "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0" + } + }, + "node_modules/@tanstack/table-core": { + "version": "8.20.5", + "resolved": "https://registry.npmjs.org/@tanstack/table-core/-/table-core-8.20.5.tgz", + "integrity": "sha512-P9dF7XbibHph2PFRz8gfBKEXEY/HJPOhym8CHmjF8y3q5mWpKx9xtZapXQUWCgkqvsK0R46Azuz+VaxD4Xl+Tg==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/tannerlinsley" + } + }, + "node_modules/@tanstack/virtual-core": { + "version": "3.10.6", + "resolved": "https://registry.npmjs.org/@tanstack/virtual-core/-/virtual-core-3.10.6.tgz", + "integrity": "sha512-1giLc4dzgEKLMx5pgKjL6HlG5fjZMgCjzlKAlpr7yoUtetVPELgER1NtephAI910nMwfPTHNyWKSFmJdHkz2Cw==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/tannerlinsley" + } + }, + "node_modules/@testing-library/dom": { + "version": "10.4.1", + "resolved": "https://registry.npmjs.org/@testing-library/dom/-/dom-10.4.1.tgz", + "integrity": "sha512-o4PXJQidqJl82ckFaXUeoAW+XysPLauYI43Abki5hABd853iMhitooc6znOnczgbTYmEP6U6/y1ZyKAIsvMKGg==", + "license": "MIT", + "peer": true, + "dependencies": { + "@babel/code-frame": "^7.10.4", + "@babel/runtime": "^7.12.5", + "@types/aria-query": "^5.0.1", + "aria-query": "5.3.0", + "dom-accessibility-api": "^0.5.9", + "lz-string": "^1.5.0", + "picocolors": "1.1.1", + "pretty-format": "^27.0.2" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@testing-library/jest-dom": { + "version": "5.17.0", + "resolved": "https://registry.npmjs.org/@testing-library/jest-dom/-/jest-dom-5.17.0.tgz", + "integrity": "sha512-ynmNeT7asXyH3aSVv4vvX4Rb+0qjOhdNHnO/3vuZNqPmhDpV/+rCSGwQ7bLcmU2cJ4dvoheIO85LQj0IbJHEtg==", + "license": "MIT", + "dependencies": { + "@adobe/css-tools": "^4.0.1", + "@babel/runtime": "^7.9.2", + "@types/testing-library__jest-dom": "^5.9.1", + "aria-query": "^5.0.0", + "chalk": "^3.0.0", + "css.escape": "^1.5.1", + "dom-accessibility-api": "^0.5.6", + "lodash": "^4.17.15", + "redent": "^3.0.0" + }, + "engines": { + "node": ">=8", + "npm": ">=6", + "yarn": ">=1" + } + }, + "node_modules/@testing-library/react": { + "version": "13.4.0", + "resolved": "https://registry.npmjs.org/@testing-library/react/-/react-13.4.0.tgz", + "integrity": "sha512-sXOGON+WNTh3MLE9rve97ftaZukN3oNf2KjDy7YTx6hcTO2uuLHuCGynMDhFwGw/jYf4OJ2Qk0i4i79qMNNkyw==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.12.5", + "@testing-library/dom": "^8.5.0", + "@types/react-dom": "^18.0.0" + }, + "engines": { + "node": ">=12" + }, + "peerDependencies": { + "react": "^18.0.0", + "react-dom": "^18.0.0" + } + }, + "node_modules/@testing-library/react/node_modules/@testing-library/dom": { + "version": "8.20.1", + "resolved": "https://registry.npmjs.org/@testing-library/dom/-/dom-8.20.1.tgz", + "integrity": "sha512-/DiOQ5xBxgdYRC8LNk7U+RWat0S3qRLeIw3ZIkMQ9kkVlRmwD/Eg8k8CqIpD6GW7u20JIUOfMKbxtiLutpjQ4g==", + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.10.4", + "@babel/runtime": "^7.12.5", + "@types/aria-query": "^5.0.1", + "aria-query": "5.1.3", + "chalk": "^4.1.0", + "dom-accessibility-api": "^0.5.9", + "lz-string": "^1.5.0", + "pretty-format": "^27.0.2" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@testing-library/react/node_modules/aria-query": { + "version": "5.1.3", + "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.1.3.tgz", + "integrity": "sha512-R5iJ5lkuHybztUfuOAznmboyjWq8O6sqNqtK7CLOqdydi54VNbORp49mb14KbWgG1QD3JFO9hJdZ+y4KutfdOQ==", + "license": "Apache-2.0", + "dependencies": { + "deep-equal": "^2.0.5" + } + }, + "node_modules/@testing-library/react/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/@testing-library/user-event": { + "version": "13.5.0", + "resolved": "https://registry.npmjs.org/@testing-library/user-event/-/user-event-13.5.0.tgz", + "integrity": "sha512-5Kwtbo3Y/NowpkbRuSepbyMFkZmHgD+vPzYB/RJ4oxt5Gj/avFFBYjhw27cqSVPVw/3a67NK1PbiIr9k4Gwmdg==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.12.5" + }, + "engines": { + "node": ">=10", + "npm": ">=6" + }, + "peerDependencies": { + "@testing-library/dom": ">=7.21.4" + } + }, + "node_modules/@types/aria-query": { + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/@types/aria-query/-/aria-query-5.0.4.tgz", + "integrity": "sha512-rfT93uj5s0PRL7EzccGMs3brplhcrghnDoV26NqKhCAS1hVo+WdNsPvE/yb6ilfr5hi2MEk6d5EWJTKdxg8jVw==", + "license": "MIT" + }, + "node_modules/@types/babel__core": { + "version": "7.20.5", + "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.5.tgz", + "integrity": "sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==", + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.20.7", + "@babel/types": "^7.20.7", + "@types/babel__generator": "*", + "@types/babel__template": "*", + "@types/babel__traverse": "*" + } + }, + "node_modules/@types/babel__generator": { + "version": "7.27.0", + "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.27.0.tgz", + "integrity": "sha512-ufFd2Xi92OAVPYsy+P4n7/U7e68fex0+Ee8gSG9KX7eo084CWiQ4sdxktvdl0bOPupXtVJPY19zk6EwWqUQ8lg==", + "license": "MIT", + "dependencies": { + "@babel/types": "^7.0.0" + } + }, + "node_modules/@types/babel__template": { + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.4.tgz", + "integrity": "sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==", + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.1.0", + "@babel/types": "^7.0.0" + } + }, + "node_modules/@types/babel__traverse": { + "version": "7.28.0", + "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.28.0.tgz", + "integrity": "sha512-8PvcXf70gTDZBgt9ptxJ8elBeBjcLOAcOtoO/mPJjtji1+CdGbHgm77om1GrsPxsiE+uXIpNSK64UYaIwQXd4Q==", + "license": "MIT", + "dependencies": { + "@babel/types": "^7.28.2" + } + }, + "node_modules/@types/estree": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz", + "integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==", + "license": "MIT" + }, + "node_modules/@types/hoist-non-react-statics": { + "version": "3.3.7", + "resolved": "https://registry.npmjs.org/@types/hoist-non-react-statics/-/hoist-non-react-statics-3.3.7.tgz", + "integrity": "sha512-PQTyIulDkIDro8P+IHbKCsw7U2xxBYflVzW/FgWdCAePD9xGSidgA76/GeJ6lBKoblyhf9pBY763gbrN+1dI8g==", + "license": "MIT", + "dependencies": { + "hoist-non-react-statics": "^3.3.0" + }, + "peerDependencies": { + "@types/react": "*" + } + }, + "node_modules/@types/istanbul-lib-coverage": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.6.tgz", + "integrity": "sha512-2QF/t/auWm0lsy8XtKVPG19v3sSOQlJe/YHZgfjb/KBBHOGSV+J2q/S671rcq9uTBrLAXmZpqJiaQbMT+zNU1w==", + "license": "MIT" + }, + "node_modules/@types/istanbul-lib-report": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.3.tgz", + "integrity": "sha512-NQn7AHQnk/RSLOxrBbGyJM/aVQ+pjj5HCgasFxc0K/KhoATfQ/47AyUl15I2yBUpihjmas+a+VJBOqecrFH+uA==", + "license": "MIT", + "dependencies": { + "@types/istanbul-lib-coverage": "*" + } + }, + "node_modules/@types/istanbul-reports": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.4.tgz", + "integrity": "sha512-pk2B1NWalF9toCRu6gjBzR69syFjP4Od8WRAX+0mmf9lAjCRicLOWc+ZrxZHx/0XRjotgkF9t6iaMJ+aXcOdZQ==", + "license": "MIT", + "dependencies": { + "@types/istanbul-lib-report": "*" + } + }, + "node_modules/@types/jest": { + "version": "30.0.0", + "resolved": "https://registry.npmjs.org/@types/jest/-/jest-30.0.0.tgz", + "integrity": "sha512-XTYugzhuwqWjws0CVz8QpM36+T+Dz5mTEBKhNs/esGLnCIlGdRy+Dq78NRjd7ls7r8BC8ZRMOrKlkO1hU0JOwA==", + "license": "MIT", + "dependencies": { + "expect": "^30.0.0", + "pretty-format": "^30.0.0" + } + }, + "node_modules/@types/jest/node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/@types/jest/node_modules/pretty-format": { + "version": "30.2.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-30.2.0.tgz", + "integrity": "sha512-9uBdv/B4EefsuAL+pWqueZyZS2Ba+LxfFeQ9DN14HU4bN8bhaxKdkpjpB6fs9+pSjIBu+FXQHImEg8j/Lw0+vA==", + "license": "MIT", + "dependencies": { + "@jest/schemas": "30.0.5", + "ansi-styles": "^5.2.0", + "react-is": "^18.3.1" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/@types/lodash": { + "version": "4.17.20", + "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.17.20.tgz", + "integrity": "sha512-H3MHACvFUEiujabxhaI/ImO6gUrd8oOurg7LQtS7mbwIXA/cUqWrvBsaeJ23aZEPk1TAYkurjfMbSELfoCXlGA==", + "license": "MIT" + }, + "node_modules/@types/node": { + "version": "24.8.1", + "resolved": "https://registry.npmjs.org/@types/node/-/node-24.8.1.tgz", + "integrity": "sha512-alv65KGRadQVfVcG69MuB4IzdYVpRwMG/mq8KWOaoOdyY617P5ivaDiMCGOFDWD2sAn5Q0mR3mRtUOgm99hL9Q==", + "license": "MIT", + "dependencies": { + "undici-types": "~7.14.0" + } + }, + "node_modules/@types/parse-json": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.2.tgz", + "integrity": "sha512-dISoDXWWQwUquiKsyZ4Ng+HX2KsPL7LyHKHQwgGFEA3IaKac4Obd+h2a/a6waisAoepJlBcx9paWqjA8/HVjCw==", + "license": "MIT" + }, + "node_modules/@types/prop-types": { + "version": "15.7.15", + "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.15.tgz", + "integrity": "sha512-F6bEyamV9jKGAFBEmlQnesRPGOQqS2+Uwi0Em15xenOxHaf2hv6L8YCVn3rPdPJOiJfPiCnLIRyvwVaqMY3MIw==", + "license": "MIT" + }, + "node_modules/@types/react": { + "version": "18.3.27", + "resolved": "https://registry.npmjs.org/@types/react/-/react-18.3.27.tgz", + "integrity": "sha512-cisd7gxkzjBKU2GgdYrTdtQx1SORymWyaAFhaxQPK9bYO9ot3Y5OikQRvY0VYQtvwjeQnizCINJAenh/V7MK2w==", + "license": "MIT", + "peer": true, + "dependencies": { + "@types/prop-types": "*", + "csstype": "^3.2.2" + } + }, + "node_modules/@types/react-dom": { + "version": "18.3.7", + "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.3.7.tgz", + "integrity": "sha512-MEe3UeoENYVFXzoXEWsvcpg6ZvlrFNlOQ7EOsvhI3CfAXwzPfO8Qwuxd40nepsYKqyyVQnTdEfv68q91yLcKrQ==", + "license": "MIT", + "peerDependencies": { + "@types/react": "^18.0.0" + } + }, + "node_modules/@types/react-transition-group": { + "version": "4.4.12", + "resolved": "https://registry.npmjs.org/@types/react-transition-group/-/react-transition-group-4.4.12.tgz", + "integrity": "sha512-8TV6R3h2j7a91c+1DXdJi3Syo69zzIZbz7Lg5tORM5LEJG7X/E6a1V3drRyBRZq7/utz7A+c4OgYLiLcYGHG6w==", + "license": "MIT", + "peerDependencies": { + "@types/react": "*" + } + }, + "node_modules/@types/resolve": { + "version": "1.20.2", + "resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-1.20.2.tgz", + "integrity": "sha512-60BCwRFOZCQhDncwQdxxeOEEkbc5dIMccYLwbxsS4TUNeVECQ/pBJ0j09mrHOl/JJvpRPGwO9SvE4nR2Nb/a4Q==", + "license": "MIT" + }, + "node_modules/@types/stack-utils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.3.tgz", + "integrity": "sha512-9aEbYZ3TbYMznPdcdr3SmIrLXwC/AKZXQeCf9Pgao5CKb8CyHuEX5jzWPTkvregvhRJHcpRO6BFoGW9ycaOkYw==", + "license": "MIT" + }, + "node_modules/@types/testing-library__jest-dom": { + "version": "5.14.9", + "resolved": "https://registry.npmjs.org/@types/testing-library__jest-dom/-/testing-library__jest-dom-5.14.9.tgz", + "integrity": "sha512-FSYhIjFlfOpGSRyVoMBMuS3ws5ehFQODymf3vlI7U1K8c7PHwWwFY7VREfmsuzHSOnoKs/9/Y983ayOs7eRzqw==", + "license": "MIT", + "dependencies": { + "@types/jest": "*" + } + }, + "node_modules/@types/trusted-types": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/@types/trusted-types/-/trusted-types-2.0.7.tgz", + "integrity": "sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw==", + "license": "MIT" + }, + "node_modules/@types/use-sync-external-store": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/@types/use-sync-external-store/-/use-sync-external-store-0.0.3.tgz", + "integrity": "sha512-EwmlvuaxPNej9+T4v5AuBPJa2x2UOJVdjCtDHgcDqitUeOtjnJKJ+apYjVcAoBEMjKW1VVFGZLUb5+qqa09XFA==", + "license": "MIT" + }, + "node_modules/@types/yargs": { + "version": "17.0.33", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.33.tgz", + "integrity": "sha512-WpxBCKWPLr4xSsHgz511rFJAM+wS28w2zEO1QDNY5zM/S8ok70NNfztH0xwhqKyaK0OHCbN98LDAZuy1ctxDkA==", + "license": "MIT", + "dependencies": { + "@types/yargs-parser": "*" + } + }, + "node_modules/@types/yargs-parser": { + "version": "21.0.3", + "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-21.0.3.tgz", + "integrity": "sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ==", + "license": "MIT" + }, + "node_modules/@typescript-eslint/project-service": { + "version": "8.46.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.46.1.tgz", + "integrity": "sha512-FOIaFVMHzRskXr5J4Jp8lFVV0gz5ngv3RHmn+E4HYxSJ3DgDzU7fVI1/M7Ijh1zf6S7HIoaIOtln1H5y8V+9Zg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/tsconfig-utils": "^8.46.1", + "@typescript-eslint/types": "^8.46.1", + "debug": "^4.3.4" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "typescript": ">=4.8.4 <6.0.0" + } + }, + "node_modules/@typescript-eslint/scope-manager": { + "version": "8.46.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.46.1.tgz", + "integrity": "sha512-weL9Gg3/5F0pVQKiF8eOXFZp8emqWzZsOJuWRUNtHT+UNV2xSJegmpCNQHy37aEQIbToTq7RHKhWvOsmbM680A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "8.46.1", + "@typescript-eslint/visitor-keys": "8.46.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/tsconfig-utils": { + "version": "8.46.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.46.1.tgz", + "integrity": "sha512-X88+J/CwFvlJB+mK09VFqx5FE4H5cXD+H/Bdza2aEWkSb8hnWIQorNcscRl4IEo1Cz9VI/+/r/jnGWkbWPx54g==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "typescript": ">=4.8.4 <6.0.0" + } + }, + "node_modules/@typescript-eslint/types": { + "version": "8.46.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.46.1.tgz", + "integrity": "sha512-C+soprGBHwWBdkDpbaRC4paGBrkIXxVlNohadL5o0kfhsXqOC6GYH2S/Obmig+I0HTDl8wMaRySwrfrXVP8/pQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/typescript-estree": { + "version": "8.46.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.46.1.tgz", + "integrity": "sha512-uIifjT4s8cQKFQ8ZBXXyoUODtRoAd7F7+G8MKmtzj17+1UbdzFl52AzRyZRyKqPHhgzvXunnSckVu36flGy8cg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/project-service": "8.46.1", + "@typescript-eslint/tsconfig-utils": "8.46.1", + "@typescript-eslint/types": "8.46.1", + "@typescript-eslint/visitor-keys": "8.46.1", + "debug": "^4.3.4", + "fast-glob": "^3.3.2", + "is-glob": "^4.0.3", + "minimatch": "^9.0.4", + "semver": "^7.6.0", + "ts-api-utils": "^2.1.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "typescript": ">=4.8.4 <6.0.0" + } + }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/brace-expansion": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", + "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/minimatch": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/semver": { + "version": "7.7.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.3.tgz", + "integrity": "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@typescript-eslint/utils": { + "version": "8.46.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.46.1.tgz", + "integrity": "sha512-vkYUy6LdZS7q1v/Gxb2Zs7zziuXN0wxqsetJdeZdRe/f5dwJFglmuvZBfTUivCtjH725C1jWCDfpadadD95EDQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/eslint-utils": "^4.7.0", + "@typescript-eslint/scope-manager": "8.46.1", + "@typescript-eslint/types": "8.46.1", + "@typescript-eslint/typescript-estree": "8.46.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0", + "typescript": ">=4.8.4 <6.0.0" + } + }, + "node_modules/@typescript-eslint/visitor-keys": { + "version": "8.46.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.46.1.tgz", + "integrity": "sha512-ptkmIf2iDkNUjdeu2bQqhFPV1m6qTnFFjg7PPDjxKWaMaP0Z6I9l30Jr3g5QqbZGdw8YdYvLp+XnqnWWZOg/NA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "8.46.1", + "eslint-visitor-keys": "^4.2.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/visitor-keys/node_modules/eslint-visitor-keys": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.1.tgz", + "integrity": "sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@vitejs/plugin-react": { + "version": "4.7.0", + "resolved": "https://registry.npmjs.org/@vitejs/plugin-react/-/plugin-react-4.7.0.tgz", + "integrity": "sha512-gUu9hwfWvvEDBBmgtAowQCojwZmJ5mcLn3aufeCsitijs3+f2NsrPtlAWIR6OPiqljl96GVCUbLe0HyqIpVaoA==", + "license": "MIT", + "dependencies": { + "@babel/core": "^7.28.0", + "@babel/plugin-transform-react-jsx-self": "^7.27.1", + "@babel/plugin-transform-react-jsx-source": "^7.27.1", + "@rolldown/pluginutils": "1.0.0-beta.27", + "@types/babel__core": "^7.20.5", + "react-refresh": "^0.17.0" + }, + "engines": { + "node": "^14.18.0 || >=16.0.0" + }, + "peerDependencies": { + "vite": "^4.2.0 || ^5.0.0 || ^6.0.0 || ^7.0.0" + } + }, + "node_modules/@vitest/expect": { + "version": "2.1.9", + "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-2.1.9.tgz", + "integrity": "sha512-UJCIkTBenHeKT1TTlKMJWy1laZewsRIzYighyYiJKZreqtdxSos/S1t+ktRMQWu2CKqaarrkeszJx1cgC5tGZw==", + "license": "MIT", + "dependencies": { + "@vitest/spy": "2.1.9", + "@vitest/utils": "2.1.9", + "chai": "^5.1.2", + "tinyrainbow": "^1.2.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/mocker": { + "version": "2.1.9", + "resolved": "https://registry.npmjs.org/@vitest/mocker/-/mocker-2.1.9.tgz", + "integrity": "sha512-tVL6uJgoUdi6icpxmdrn5YNo3g3Dxv+IHJBr0GXHaEdTcw3F+cPKnsXFhli6nO+f/6SDKPHEK1UN+k+TQv0Ehg==", + "license": "MIT", + "dependencies": { + "@vitest/spy": "2.1.9", + "estree-walker": "^3.0.3", + "magic-string": "^0.30.12" + }, + "funding": { + "url": "https://opencollective.com/vitest" + }, + "peerDependencies": { + "msw": "^2.4.9", + "vite": "^5.0.0" + }, + "peerDependenciesMeta": { + "msw": { + "optional": true + }, + "vite": { + "optional": true + } + } + }, + "node_modules/@vitest/pretty-format": { + "version": "2.1.9", + "resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-2.1.9.tgz", + "integrity": "sha512-KhRIdGV2U9HOUzxfiHmY8IFHTdqtOhIzCpd8WRdJiE7D/HUcZVD0EgQCVjm+Q9gkUXWgBvMmTtZgIG48wq7sOQ==", + "license": "MIT", + "dependencies": { + "tinyrainbow": "^1.2.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/runner": { + "version": "2.1.9", + "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-2.1.9.tgz", + "integrity": "sha512-ZXSSqTFIrzduD63btIfEyOmNcBmQvgOVsPNPe0jYtESiXkhd8u2erDLnMxmGrDCwHCCHE7hxwRDCT3pt0esT4g==", + "license": "MIT", + "dependencies": { + "@vitest/utils": "2.1.9", + "pathe": "^1.1.2" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/snapshot": { + "version": "2.1.9", + "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-2.1.9.tgz", + "integrity": "sha512-oBO82rEjsxLNJincVhLhaxxZdEtV0EFHMK5Kmx5sJ6H9L183dHECjiefOAdnqpIgT5eZwT04PoggUnW88vOBNQ==", + "license": "MIT", + "dependencies": { + "@vitest/pretty-format": "2.1.9", + "magic-string": "^0.30.12", + "pathe": "^1.1.2" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/spy": { + "version": "2.1.9", + "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-2.1.9.tgz", + "integrity": "sha512-E1B35FwzXXTs9FHNK6bDszs7mtydNi5MIfUWpceJ8Xbfb1gBMscAnwLbEu+B44ed6W3XjL9/ehLPHR1fkf1KLQ==", + "license": "MIT", + "dependencies": { + "tinyspy": "^3.0.2" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/utils": { + "version": "2.1.9", + "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-2.1.9.tgz", + "integrity": "sha512-v0psaMSkNJ3A2NMrUEHFRzJtDPFn+/VWZ5WxImB21T9fjucJRmS7xCS3ppEnARb9y11OAzaD+P2Ps+b+BGX5iQ==", + "license": "MIT", + "dependencies": { + "@vitest/pretty-format": "2.1.9", + "loupe": "^3.1.2", + "tinyrainbow": "^1.2.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/acorn": { + "version": "8.15.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz", + "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==", + "license": "MIT", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-jsx": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", + "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", + "license": "MIT", + "peerDependencies": { + "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" + } + }, + "node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "license": "Python-2.0" + }, + "node_modules/aria-query": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.3.0.tgz", + "integrity": "sha512-b0P0sZPKtyu8HkeRAfCq0IfURZK+SuwMjY1UXGBU27wpAiTwQAIlq56IbIO+ytk/JjS1fMR14ee5WBBfKi5J6A==", + "license": "Apache-2.0", + "dependencies": { + "dequal": "^2.0.3" + } + }, + "node_modules/array-buffer-byte-length": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.2.tgz", + "integrity": "sha512-LHE+8BuR7RYGDKvnrmcuSq3tDcKv9OFEXQt/HpbZhY7V6h0zlUXutnAD82GiFx9rdieCMjkvtcsPqBwgUl1Iiw==", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "is-array-buffer": "^3.0.5" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array-includes": { + "version": "3.1.9", + "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.9.tgz", + "integrity": "sha512-FmeCCAenzH0KH381SPT5FZmiA/TmpndpcaShhfgEN9eCVjnFBqq3l1xrI42y8+PPLI6hypzou4GXw00WHmPBLQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.4", + "define-properties": "^1.2.1", + "es-abstract": "^1.24.0", + "es-object-atoms": "^1.1.1", + "get-intrinsic": "^1.3.0", + "is-string": "^1.1.1", + "math-intrinsics": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array-union": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", + "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/array.prototype.findlast": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/array.prototype.findlast/-/array.prototype.findlast-1.2.5.tgz", + "integrity": "sha512-CVvd6FHg1Z3POpBLxO6E6zr+rSKEQ9L6rZHAaY7lLfhKsWYUBBOuMs0e9o24oopj6H+geRCX0YJ+TJLBK2eHyQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0", + "es-shim-unscopables": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array.prototype.flat": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.3.3.tgz", + "integrity": "sha512-rwG/ja1neyLqCuGZ5YYrznA62D4mZXg0i1cIskIUKSiqF3Cje9/wXAls9B9s1Wa2fomMsIv8czB8jZcPmxCXFg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.5", + "es-shim-unscopables": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array.prototype.flatmap": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.3.3.tgz", + "integrity": "sha512-Y7Wt51eKJSyi80hFrJCePGGNo5ktJCslFuboqJsbf57CCPcm5zztluPlc4/aD8sWsKvlwatezpV4U1efk8kpjg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.5", + "es-shim-unscopables": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array.prototype.tosorted": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/array.prototype.tosorted/-/array.prototype.tosorted-1.1.4.tgz", + "integrity": "sha512-p6Fx8B7b7ZhL/gmUsAy0D15WhvDccw3mnGNbZpi3pmeJdxtWsj2jEaI4Y6oo3XiHfzuSgPwKc04MYt6KgvC/wA==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.3", + "es-errors": "^1.3.0", + "es-shim-unscopables": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/arraybuffer.prototype.slice": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.4.tgz", + "integrity": "sha512-BNoCY6SXXPQ7gF2opIP4GBE+Xw7U+pHMYKuzjgCN3GwiaIR09UUeKfheyIry77QtrCBlC0KK0q5/TER/tYh3PQ==", + "license": "MIT", + "dependencies": { + "array-buffer-byte-length": "^1.0.1", + "call-bind": "^1.0.8", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.5", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.6", + "is-array-buffer": "^3.0.4" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/assertion-error": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-2.0.1.tgz", + "integrity": "sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==", + "license": "MIT", + "engines": { + "node": ">=12" + } + }, + "node_modules/async": { + "version": "3.2.6", + "resolved": "https://registry.npmjs.org/async/-/async-3.2.6.tgz", + "integrity": "sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA==", + "license": "MIT" + }, + "node_modules/async-function": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/async-function/-/async-function-1.0.0.tgz", + "integrity": "sha512-hsU18Ae8CDTR6Kgu9DYf0EbCr/a5iGL0rytQDobUcdpYOKokk8LEjVphnXkDkgpi0wYVsqrXuP0bZxJaTqdgoA==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", + "license": "MIT" + }, + "node_modules/at-least-node": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz", + "integrity": "sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==", + "license": "ISC", + "engines": { + "node": ">= 4.0.0" + } + }, + "node_modules/available-typed-arrays": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz", + "integrity": "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==", + "license": "MIT", + "dependencies": { + "possible-typed-array-names": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/axios": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/axios/-/axios-0.27.2.tgz", + "integrity": "sha512-t+yRIyySRTp/wua5xEr+z1q60QmLq8ABsS5O9Me1AsE5dfKqgnCFzwiCZZ/cGNd1lq4/7akDWMxdhVlucjmnOQ==", + "license": "MIT", + "dependencies": { + "follow-redirects": "^1.14.9", + "form-data": "^4.0.0" + } + }, + "node_modules/babel-plugin-macros": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/babel-plugin-macros/-/babel-plugin-macros-3.1.0.tgz", + "integrity": "sha512-Cg7TFGpIr01vOQNODXOOaGz2NpCU5gl8x1qJFbb6hbZxR7XrcE2vtbAsTAbJ7/xwJtUuJEw8K8Zr/AE0LHlesg==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.12.5", + "cosmiconfig": "^7.0.0", + "resolve": "^1.19.0" + }, + "engines": { + "node": ">=10", + "npm": ">=6" + } + }, + "node_modules/babel-plugin-polyfill-corejs2": { + "version": "0.4.14", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.14.tgz", + "integrity": "sha512-Co2Y9wX854ts6U8gAAPXfn0GmAyctHuK8n0Yhfjd6t30g7yvKjspvvOo9yG+z52PZRgFErt7Ka2pYnXCjLKEpg==", + "license": "MIT", + "dependencies": { + "@babel/compat-data": "^7.27.7", + "@babel/helper-define-polyfill-provider": "^0.6.5", + "semver": "^6.3.1" + }, + "peerDependencies": { + "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" + } + }, + "node_modules/babel-plugin-polyfill-corejs3": { + "version": "0.13.0", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.13.0.tgz", + "integrity": "sha512-U+GNwMdSFgzVmfhNm8GJUX88AadB3uo9KpJqS3FaqNIPKgySuvMb+bHPsOmmuWyIcuqZj/pzt1RUIUZns4y2+A==", + "license": "MIT", + "dependencies": { + "@babel/helper-define-polyfill-provider": "^0.6.5", + "core-js-compat": "^3.43.0" + }, + "peerDependencies": { + "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" + } + }, + "node_modules/babel-plugin-polyfill-regenerator": { + "version": "0.6.5", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.6.5.tgz", + "integrity": "sha512-ISqQ2frbiNU9vIJkzg7dlPpznPZ4jOiUQ1uSmB0fEHeowtN3COYRsXr/xexn64NpU13P06jc/L5TgiJXOgrbEg==", + "license": "MIT", + "dependencies": { + "@babel/helper-define-polyfill-provider": "^0.6.5" + }, + "peerDependencies": { + "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" + } + }, + "node_modules/babel-plugin-styled-components": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/babel-plugin-styled-components/-/babel-plugin-styled-components-2.1.4.tgz", + "integrity": "sha512-Xgp9g+A/cG47sUyRwwYxGM4bR/jDRg5N6it/8+HxCnbT5XNKSKDT9xm4oag/osgqjC2It/vH0yXsomOG6k558g==", + "license": "MIT", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.22.5", + "@babel/helper-module-imports": "^7.22.5", + "@babel/plugin-syntax-jsx": "^7.22.5", + "lodash": "^4.17.21", + "picomatch": "^2.3.1" + }, + "peerDependencies": { + "styled-components": ">= 2" + } + }, + "node_modules/babel-plugin-styled-components/node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "license": "MIT", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "license": "MIT" + }, + "node_modules/base64-arraybuffer": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/base64-arraybuffer/-/base64-arraybuffer-1.0.2.tgz", + "integrity": "sha512-I3yl4r9QB5ZRY3XuJVEPfc2XhZO6YweFPI+UovAzn+8/hb3oJ6lnysaFcjVpkCPfVWFUDvoZ8kmVDP7WyRtYtQ==", + "license": "MIT", + "engines": { + "node": ">= 0.6.0" + } + }, + "node_modules/baseline-browser-mapping": { + "version": "2.8.18", + "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.8.18.tgz", + "integrity": "sha512-UYmTpOBwgPScZpS4A+YbapwWuBwasxvO/2IOHArSsAhL/+ZdmATBXTex3t+l2hXwLVYK382ibr/nKoY9GKe86w==", + "license": "Apache-2.0", + "bin": { + "baseline-browser-mapping": "dist/cli.js" + } + }, + "node_modules/brace-expansion": { + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", + "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/braces": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", + "license": "MIT", + "dependencies": { + "fill-range": "^7.1.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/browserslist": { + "version": "4.26.3", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.26.3.tgz", + "integrity": "sha512-lAUU+02RFBuCKQPj/P6NgjlbCnLBMp4UtgTx7vNHd3XSIJF87s9a5rA3aH2yw3GS9DqZAUbOtZdCCiZeVRqt0w==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "baseline-browser-mapping": "^2.8.9", + "caniuse-lite": "^1.0.30001746", + "electron-to-chromium": "^1.5.227", + "node-releases": "^2.0.21", + "update-browserslist-db": "^1.1.3" + }, + "bin": { + "browserslist": "cli.js" + }, + "engines": { + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" + } + }, + "node_modules/buffer-from": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", + "license": "MIT" + }, + "node_modules/cac": { + "version": "6.7.14", + "resolved": "https://registry.npmjs.org/cac/-/cac-6.7.14.tgz", + "integrity": "sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/call-bind": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.8.tgz", + "integrity": "sha512-oKlSFMcMwpUg2ednkhQ454wfWiU/ul3CkJe/PEHcTKuiX6RpbehUiFMXu13HalGZxfUwCQzZG747YXBn1im9ww==", + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.0", + "es-define-property": "^1.0.0", + "get-intrinsic": "^1.2.4", + "set-function-length": "^1.2.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/call-bind-apply-helpers": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", + "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/call-bound": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.4.tgz", + "integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==", + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "get-intrinsic": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/camelize": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/camelize/-/camelize-1.0.1.tgz", + "integrity": "sha512-dU+Tx2fsypxTgtLoE36npi3UqcjSSMNYfkqgmoEhtZrraP5VWq0K7FkWVTYa8eMPtnU/G2txVsfdCJTn9uzpuQ==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/caniuse-lite": { + "version": "1.0.30001751", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001751.tgz", + "integrity": "sha512-A0QJhug0Ly64Ii3eIqHu5X51ebln3k4yTUkY1j8drqpWHVreg/VLijN48cZ1bYPiqOQuqpkIKnzr/Ul8V+p6Cw==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/caniuse-lite" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "CC-BY-4.0" + }, + "node_modules/chai": { + "version": "5.3.3", + "resolved": "https://registry.npmjs.org/chai/-/chai-5.3.3.tgz", + "integrity": "sha512-4zNhdJD/iOjSH0A05ea+Ke6MU5mmpQcbQsSOkgdaUMJ9zTlDTD/GYlwohmIE2u0gaxHYiVHEn1Fw9mZ/ktJWgw==", + "license": "MIT", + "dependencies": { + "assertion-error": "^2.0.1", + "check-error": "^2.1.1", + "deep-eql": "^5.0.1", + "loupe": "^3.1.0", + "pathval": "^2.0.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/chalk": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", + "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/chart.js": { + "version": "4.5.1", + "resolved": "https://registry.npmjs.org/chart.js/-/chart.js-4.5.1.tgz", + "integrity": "sha512-GIjfiT9dbmHRiYi6Nl2yFCq7kkwdkp1W/lp2J99rX0yo9tgJGn3lKQATztIjb5tVtevcBtIdICNWqlq5+E8/Pw==", + "license": "MIT", + "dependencies": { + "@kurkle/color": "^0.3.0" + }, + "engines": { + "pnpm": ">=8" + } + }, + "node_modules/chartjs-plugin-annotation": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/chartjs-plugin-annotation/-/chartjs-plugin-annotation-3.1.0.tgz", + "integrity": "sha512-EkAed6/ycXD/7n0ShrlT1T2Hm3acnbFhgkIEJLa0X+M6S16x0zwj1Fv4suv/2bwayCT3jGPdAtI9uLcAMToaQQ==", + "license": "MIT", + "peerDependencies": { + "chart.js": ">=4.0.0" + } + }, + "node_modules/chartjs-plugin-datalabels": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/chartjs-plugin-datalabels/-/chartjs-plugin-datalabels-2.2.0.tgz", + "integrity": "sha512-14ZU30lH7n89oq+A4bWaJPnAG8a7ZTk7dKf48YAzMvJjQtjrgg5Dpk9f+LbjCF6bpx3RAGTeL13IXpKQYyRvlw==", + "license": "MIT", + "peerDependencies": { + "chart.js": ">=3.0.0" + } + }, + "node_modules/check-error": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/check-error/-/check-error-2.1.1.tgz", + "integrity": "sha512-OAlb+T7V4Op9OwdkjmguYRqncdlx5JiofwOAUkmTF+jNdHwzTaTs4sRAGpzLF3oOz5xAyDGrPgeIDFQmDOTiJw==", + "license": "MIT", + "engines": { + "node": ">= 16" + } + }, + "node_modules/ci-info": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-4.3.1.tgz", + "integrity": "sha512-Wdy2Igu8OcBpI2pZePZ5oWjPC38tmDVx5WKUXKwlLYkA0ozo85sLsLvkBbBn/sZaSCMFOGZJ14fvW9t5/d7kdA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/sibiraj-s" + } + ], + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/classnames": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/classnames/-/classnames-2.3.1.tgz", + "integrity": "sha512-OlQdbZ7gLfGarSqxesMesDa5uz7KFbID8Kpq/SxIoNGDqY8lSYs0D+hhtBXhcdB3rcbXArFr7vlHheLk1voeNA==", + "license": "MIT" + }, + "node_modules/clsx": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.1.1.tgz", + "integrity": "sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "license": "MIT" + }, + "node_modules/combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "license": "MIT", + "dependencies": { + "delayed-stream": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", + "license": "MIT" + }, + "node_modules/common-tags": { + "version": "1.8.2", + "resolved": "https://registry.npmjs.org/common-tags/-/common-tags-1.8.2.tgz", + "integrity": "sha512-gk/Z852D2Wtb//0I+kRFNKKE9dIIVirjoqPoA1wJU+XePVXZfGeBpk45+A1rKO4Q43prqWBNY/MiIeRLbPWUaA==", + "license": "MIT", + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "license": "MIT" + }, + "node_modules/convert-source-map": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz", + "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==", + "license": "MIT" + }, + "node_modules/core-js-compat": { + "version": "3.46.0", + "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.46.0.tgz", + "integrity": "sha512-p9hObIIEENxSV8xIu+V68JjSeARg6UVMG5mR+JEUguG3sI6MsiS1njz2jHmyJDvA+8jX/sytkBHup6kxhM9law==", + "license": "MIT", + "dependencies": { + "browserslist": "^4.26.3" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/core-js" + } + }, + "node_modules/core-js-pure": { + "version": "3.46.0", + "resolved": "https://registry.npmjs.org/core-js-pure/-/core-js-pure-3.46.0.tgz", + "integrity": "sha512-NMCW30bHNofuhwLhYPt66OLOKTMbOhgTTatKVbaQC3KRHpTCiRIBYvtshr+NBYSnBxwAFhjW/RfJ0XbIjS16rw==", + "hasInstallScript": true, + "license": "MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/core-js" + } + }, + "node_modules/cosmiconfig": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.1.0.tgz", + "integrity": "sha512-AdmX6xUzdNASswsFtmwSt7Vj8po9IuqXm0UXz7QKPuEUmPB4XyjGfaAr2PSuELMwkRMVH1EpIkX5bTZGRB3eCA==", + "license": "MIT", + "dependencies": { + "@types/parse-json": "^4.0.0", + "import-fresh": "^3.2.1", + "parse-json": "^5.0.0", + "path-type": "^4.0.0", + "yaml": "^1.10.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/cross-spawn": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", + "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", + "license": "MIT", + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/crypto-random-string": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-2.0.0.tgz", + "integrity": "sha512-v1plID3y9r/lPhviJ1wrXpLeyUIGAZ2SHNYTEapm7/8A9nLPoyvVp3RK/EPFqn5kEznyWgYZNsRtYYIWbuG8KA==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/css-color-keywords": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/css-color-keywords/-/css-color-keywords-1.0.0.tgz", + "integrity": "sha512-FyyrDHZKEjXDpNJYvVsV960FiqQyXc/LlYmsxl2BcdMb2WPx0OGRVgTg55rPSyLSNMqP52R9r8geSp7apN3Ofg==", + "license": "ISC", + "engines": { + "node": ">=4" + } + }, + "node_modules/css-line-break": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/css-line-break/-/css-line-break-2.1.0.tgz", + "integrity": "sha512-FHcKFCZcAha3LwfVBhCQbW2nCNbkZXn7KVUJcsT5/P8YmfsVja0FMPJr0B903j/E69HUphKiV9iQArX8SDYA4w==", + "license": "MIT", + "dependencies": { + "utrie": "^1.0.2" + } + }, + "node_modules/css-to-react-native": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/css-to-react-native/-/css-to-react-native-2.3.2.tgz", + "integrity": "sha512-VOFaeZA053BqvvvqIA8c9n0+9vFppVBAHCp6JgFTtTMU3Mzi+XnelJ9XC9ul3BqFzZyQ5N+H0SnwsWT2Ebchxw==", + "license": "MIT", + "dependencies": { + "camelize": "^1.0.0", + "css-color-keywords": "^1.0.0", + "postcss-value-parser": "^3.3.0" + } + }, + "node_modules/css.escape": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/css.escape/-/css.escape-1.5.1.tgz", + "integrity": "sha512-YUifsXXuknHlUsmlgyY0PKzgPOr7/FjCePfHNt0jxm83wHZi44VDMQ7/fGNkjY3/jV1MC+1CmZbaHzugyeRtpg==", + "license": "MIT" + }, + "node_modules/cssjanus": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/cssjanus/-/cssjanus-2.3.0.tgz", + "integrity": "sha512-ZZXXn51SnxRxAZ6fdY7mBDPmA4OZd83q/J9Gdqz3YmE9TUq+9tZl+tdOnCi7PpNygI6PEkehj9rgifv5+W8a5A==", + "license": "Apache-2.0", + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/csstype": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.2.3.tgz", + "integrity": "sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==", + "license": "MIT" + }, + "node_modules/data-view-buffer": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/data-view-buffer/-/data-view-buffer-1.0.2.tgz", + "integrity": "sha512-EmKO5V3OLXh1rtK2wgXRansaK1/mtVdTUEiEI0W8RkvgT05kfxaH29PliLnpLP73yYO6142Q72QNa8Wx/A5CqQ==", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "es-errors": "^1.3.0", + "is-data-view": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/data-view-byte-length": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/data-view-byte-length/-/data-view-byte-length-1.0.2.tgz", + "integrity": "sha512-tuhGbE6CfTM9+5ANGf+oQb72Ky/0+s3xKUpHvShfiz2RxMFgFPjsXuRLBVMtvMs15awe45SRb83D6wH4ew6wlQ==", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "es-errors": "^1.3.0", + "is-data-view": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/inspect-js" + } + }, + "node_modules/data-view-byte-offset": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/data-view-byte-offset/-/data-view-byte-offset-1.0.1.tgz", + "integrity": "sha512-BS8PfmtDGnrgYdOonGZQdLZslWIeCGFP9tpan0hi1Co2Zr2NKADsvGYA8XxuG/4UWgJ6Cjtv+YJnB6MM69QGlQ==", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "is-data-view": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/date-fns": { + "version": "2.30.0", + "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-2.30.0.tgz", + "integrity": "sha512-fnULvOpxnC5/Vg3NCiWelDsLiUc9bRwAPs/+LfTLNvetFCtCTN+yQz15C/fs4AwX1R9K5GLtLfn8QW+dWisaAw==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.21.0" + }, + "engines": { + "node": ">=0.11" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/date-fns" + } + }, + "node_modules/date-fns-jalali": { + "version": "2.29.2-0", + "resolved": "https://registry.npmjs.org/date-fns-jalali/-/date-fns-jalali-2.29.2-0.tgz", + "integrity": "sha512-wNjKHcRJzgyTSG1bxB5A3PZFWf+TfzRWRixIqHIgM+nZXHF/TRQ7X8IYGXecaqMatUXxekR1kDEuFhuwyPFrew==", + "license": "MIT", + "engines": { + "node": ">=0.11" + } + }, + "node_modules/debug": { + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", + "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/deep-eql": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-5.0.2.tgz", + "integrity": "sha512-h5k/5U50IJJFpzfL6nO9jaaumfjO/f2NjK/oYB2Djzm4p9L+3T9qWpZqZ2hAbLPuuYq9wrU08WQyBTL5GbPk5Q==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/deep-equal": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-2.2.3.tgz", + "integrity": "sha512-ZIwpnevOurS8bpT4192sqAowWM76JDKSHYzMLty3BZGSswgq6pBaH3DhCSW5xVAZICZyKdOBPjwww5wfgT/6PA==", + "license": "MIT", + "dependencies": { + "array-buffer-byte-length": "^1.0.0", + "call-bind": "^1.0.5", + "es-get-iterator": "^1.1.3", + "get-intrinsic": "^1.2.2", + "is-arguments": "^1.1.1", + "is-array-buffer": "^3.0.2", + "is-date-object": "^1.0.5", + "is-regex": "^1.1.4", + "is-shared-array-buffer": "^1.0.2", + "isarray": "^2.0.5", + "object-is": "^1.1.5", + "object-keys": "^1.1.1", + "object.assign": "^4.1.4", + "regexp.prototype.flags": "^1.5.1", + "side-channel": "^1.0.4", + "which-boxed-primitive": "^1.0.2", + "which-collection": "^1.0.1", + "which-typed-array": "^1.1.13" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/deep-is": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", + "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", + "license": "MIT" + }, + "node_modules/deepmerge": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-2.2.1.tgz", + "integrity": "sha512-R9hc1Xa/NOBi9WRVUWg19rl1UB7Tt4kuPd+thNJgFZoxXsTz7ncaPaeIm+40oSGuP33DfMb4sZt1QIGiJzC4EA==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/define-data-property": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", + "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", + "license": "MIT", + "dependencies": { + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "gopd": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/define-properties": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz", + "integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==", + "license": "MIT", + "dependencies": { + "define-data-property": "^1.0.1", + "has-property-descriptors": "^1.0.0", + "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", + "license": "MIT", + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/dequal": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz", + "integrity": "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/detect-node-es": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/detect-node-es/-/detect-node-es-1.1.0.tgz", + "integrity": "sha512-ypdmJU/TbBby2Dxibuv7ZLW3Bs1QEmM7nHjEANfohJLvE0XVujisn1qPJcZxg+qDucsr+bP6fLD1rPS3AhJ7EQ==", + "license": "MIT" + }, + "node_modules/dir-glob": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", + "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", + "license": "MIT", + "dependencies": { + "path-type": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/dnd-core": { + "version": "11.1.3", + "resolved": "https://registry.npmjs.org/dnd-core/-/dnd-core-11.1.3.tgz", + "integrity": "sha512-QugF55dNW+h+vzxVJ/LSJeTeUw9MCJ2cllhmVThVPEtF16ooBkxj0WBE5RB+AceFxMFo1rO6bJKXtqKl+JNnyA==", + "license": "MIT", + "dependencies": { + "@react-dnd/asap": "^4.0.0", + "@react-dnd/invariant": "^2.0.0", + "redux": "^4.0.4" + } + }, + "node_modules/doctrine": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", + "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", + "license": "Apache-2.0", + "dependencies": { + "esutils": "^2.0.2" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/dom-accessibility-api": { + "version": "0.5.16", + "resolved": "https://registry.npmjs.org/dom-accessibility-api/-/dom-accessibility-api-0.5.16.tgz", + "integrity": "sha512-X7BJ2yElsnOJ30pZF4uIIDfBEVgF4XEBxL9Bxhy6dnrm5hkzqmsWHGTiHqRiITNhMyFLyAiWndIJP7Z1NTteDg==", + "license": "MIT" + }, + "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": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", + "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.1", + "es-errors": "^1.3.0", + "gopd": "^1.2.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/echarts": { + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/echarts/-/echarts-5.6.0.tgz", + "integrity": "sha512-oTbVTsXfKuEhxftHqL5xprgLoc0k7uScAwtryCgWF6hPYFLRwOUHiFmHGCBKP5NPFNkDVopOieyUqYGH8Fa3kA==", + "license": "Apache-2.0", + "dependencies": { + "tslib": "2.3.0", + "zrender": "5.6.1" + } + }, + "node_modules/echarts-for-react": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/echarts-for-react/-/echarts-for-react-3.0.2.tgz", + "integrity": "sha512-DRwIiTzx8JfwPOVgGttDytBqdp5VzCSyMRIxubgU/g2n9y3VLUmF2FK7Icmg/sNVkv4+rktmrLN9w22U2yy3fA==", + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.3", + "size-sensor": "^1.0.1" + }, + "peerDependencies": { + "echarts": "^3.0.0 || ^4.0.0 || ^5.0.0", + "react": "^15.0.0 || >=16.0.0" + } + }, + "node_modules/ejs": { + "version": "3.1.10", + "resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.10.tgz", + "integrity": "sha512-UeJmFfOrAQS8OJWPZ4qtgHyWExa088/MtK5UEyoJGFH67cDEXkZSviOiKRCZ4Xij0zxI3JECgYs3oKx+AizQBA==", + "license": "Apache-2.0", + "dependencies": { + "jake": "^10.8.5" + }, + "bin": { + "ejs": "bin/cli.js" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/electron-to-chromium": { + "version": "1.5.237", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.237.tgz", + "integrity": "sha512-icUt1NvfhGLar5lSWH3tHNzablaA5js3HVHacQimfP8ViEBOQv+L7DKEuHdbTZ0SKCO1ogTJTIL1Gwk9S6Qvcg==", + "license": "ISC" + }, + "node_modules/error-ex": { + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.4.tgz", + "integrity": "sha512-sqQamAnR14VgCr1A618A3sGrygcpK+HEbenA/HiEAkkUwcZIIB/tgWqHFxWgOyDh4nB4JCRimh79dR5Ywc9MDQ==", + "license": "MIT", + "dependencies": { + "is-arrayish": "^0.2.1" + } + }, + "node_modules/es-abstract": { + "version": "1.24.0", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.24.0.tgz", + "integrity": "sha512-WSzPgsdLtTcQwm4CROfS5ju2Wa1QQcVeT37jFjYzdFz1r9ahadC8B8/a4qxJxM+09F18iumCdRmlr96ZYkQvEg==", + "license": "MIT", + "dependencies": { + "array-buffer-byte-length": "^1.0.2", + "arraybuffer.prototype.slice": "^1.0.4", + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.8", + "call-bound": "^1.0.4", + "data-view-buffer": "^1.0.2", + "data-view-byte-length": "^1.0.2", + "data-view-byte-offset": "^1.0.1", + "es-define-property": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.1.1", + "es-set-tostringtag": "^2.1.0", + "es-to-primitive": "^1.3.0", + "function.prototype.name": "^1.1.8", + "get-intrinsic": "^1.3.0", + "get-proto": "^1.0.1", + "get-symbol-description": "^1.1.0", + "globalthis": "^1.0.4", + "gopd": "^1.2.0", + "has-property-descriptors": "^1.0.2", + "has-proto": "^1.2.0", + "has-symbols": "^1.1.0", + "hasown": "^2.0.2", + "internal-slot": "^1.1.0", + "is-array-buffer": "^3.0.5", + "is-callable": "^1.2.7", + "is-data-view": "^1.0.2", + "is-negative-zero": "^2.0.3", + "is-regex": "^1.2.1", + "is-set": "^2.0.3", + "is-shared-array-buffer": "^1.0.4", + "is-string": "^1.1.1", + "is-typed-array": "^1.1.15", + "is-weakref": "^1.1.1", + "math-intrinsics": "^1.1.0", + "object-inspect": "^1.13.4", + "object-keys": "^1.1.1", + "object.assign": "^4.1.7", + "own-keys": "^1.0.1", + "regexp.prototype.flags": "^1.5.4", + "safe-array-concat": "^1.1.3", + "safe-push-apply": "^1.0.0", + "safe-regex-test": "^1.1.0", + "set-proto": "^1.0.0", + "stop-iteration-iterator": "^1.1.0", + "string.prototype.trim": "^1.2.10", + "string.prototype.trimend": "^1.0.9", + "string.prototype.trimstart": "^1.0.8", + "typed-array-buffer": "^1.0.3", + "typed-array-byte-length": "^1.0.3", + "typed-array-byte-offset": "^1.0.4", + "typed-array-length": "^1.0.7", + "unbox-primitive": "^1.1.0", + "which-typed-array": "^1.1.19" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/es-define-property": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", + "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-get-iterator": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/es-get-iterator/-/es-get-iterator-1.1.3.tgz", + "integrity": "sha512-sPZmqHBe6JIiTfN5q2pEi//TwxmAFHwj/XEuYjTuse78i8KxaqMTTzxPoFKuzRpDpTJ+0NAbpfenkmH2rePtuw==", + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.2", + "get-intrinsic": "^1.1.3", + "has-symbols": "^1.0.3", + "is-arguments": "^1.1.1", + "is-map": "^2.0.2", + "is-set": "^2.0.2", + "is-string": "^1.0.7", + "isarray": "^2.0.5", + "stop-iteration-iterator": "^1.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/es-iterator-helpers": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/es-iterator-helpers/-/es-iterator-helpers-1.2.1.tgz", + "integrity": "sha512-uDn+FE1yrDzyC0pCo961B2IHbdM8y/ACZsKD4dG6WqrjV53BADjwa7D+1aom2rsNVfLyDgU/eigvlJGJ08OQ4w==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.6", + "es-errors": "^1.3.0", + "es-set-tostringtag": "^2.0.3", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.6", + "globalthis": "^1.0.4", + "gopd": "^1.2.0", + "has-property-descriptors": "^1.0.2", + "has-proto": "^1.2.0", + "has-symbols": "^1.1.0", + "internal-slot": "^1.1.0", + "iterator.prototype": "^1.1.4", + "safe-array-concat": "^1.1.3" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-module-lexer": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.7.0.tgz", + "integrity": "sha512-jEQoCwk8hyb2AZziIOLhDqpm5+2ww5uIE6lkO/6jcOCusfk6LhMHpXXfBLXTZ7Ydyt0j4VoUQv6uGNYbdW+kBA==", + "license": "MIT" + }, + "node_modules/es-object-atoms": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz", + "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-set-tostringtag": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz", + "integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.6", + "has-tostringtag": "^1.0.2", + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-shim-unscopables": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/es-shim-unscopables/-/es-shim-unscopables-1.1.0.tgz", + "integrity": "sha512-d9T8ucsEhh8Bi1woXCf+TIKDIROLG5WCkxg8geBCbvk22kzwC5G2OnXVMO6FUsvQlgUUXQ2itephWDLqDzbeCw==", + "dev": true, + "license": "MIT", + "dependencies": { + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-to-primitive": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.3.0.tgz", + "integrity": "sha512-w+5mJ3GuFL+NjVtJlvydShqE1eN3h3PbI7/5LAsYJP/2qtuMXjfL2LpHSRqo4b4eSF5K/DH1JXKUAHSB2UW50g==", + "license": "MIT", + "dependencies": { + "is-callable": "^1.2.7", + "is-date-object": "^1.0.5", + "is-symbol": "^1.0.4" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/esbuild": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.21.5.tgz", + "integrity": "sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==", + "hasInstallScript": true, + "license": "MIT", + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=12" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.21.5", + "@esbuild/android-arm": "0.21.5", + "@esbuild/android-arm64": "0.21.5", + "@esbuild/android-x64": "0.21.5", + "@esbuild/darwin-arm64": "0.21.5", + "@esbuild/darwin-x64": "0.21.5", + "@esbuild/freebsd-arm64": "0.21.5", + "@esbuild/freebsd-x64": "0.21.5", + "@esbuild/linux-arm": "0.21.5", + "@esbuild/linux-arm64": "0.21.5", + "@esbuild/linux-ia32": "0.21.5", + "@esbuild/linux-loong64": "0.21.5", + "@esbuild/linux-mips64el": "0.21.5", + "@esbuild/linux-ppc64": "0.21.5", + "@esbuild/linux-riscv64": "0.21.5", + "@esbuild/linux-s390x": "0.21.5", + "@esbuild/linux-x64": "0.21.5", + "@esbuild/netbsd-x64": "0.21.5", + "@esbuild/openbsd-x64": "0.21.5", + "@esbuild/sunos-x64": "0.21.5", + "@esbuild/win32-arm64": "0.21.5", + "@esbuild/win32-ia32": "0.21.5", + "@esbuild/win32-x64": "0.21.5" + } + }, + "node_modules/escalade": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", + "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint": { + "version": "8.22.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.22.0.tgz", + "integrity": "sha512-ci4t0sz6vSRKdmkOGmprBo6fmI4PrphDFMy5JEq/fNS0gQkJM3rLmrqcp8ipMcdobH3KtUP40KniAE9W19S4wA==", + "deprecated": "This version is no longer supported. Please see https://eslint.org/version-support for other options.", + "license": "MIT", + "dependencies": { + "@eslint/eslintrc": "^1.3.0", + "@humanwhocodes/config-array": "^0.10.4", + "@humanwhocodes/gitignore-to-minimatch": "^1.0.2", + "ajv": "^6.10.0", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.2", + "debug": "^4.3.2", + "doctrine": "^3.0.0", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^7.1.1", + "eslint-utils": "^3.0.0", + "eslint-visitor-keys": "^3.3.0", + "espree": "^9.3.3", + "esquery": "^1.4.0", + "esutils": "^2.0.2", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^6.0.1", + "find-up": "^5.0.0", + "functional-red-black-tree": "^1.0.1", + "glob-parent": "^6.0.1", + "globals": "^13.15.0", + "globby": "^11.1.0", + "grapheme-splitter": "^1.0.4", + "ignore": "^5.2.0", + "import-fresh": "^3.0.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "js-yaml": "^4.1.0", + "json-stable-stringify-without-jsonify": "^1.0.1", + "levn": "^0.4.1", + "lodash.merge": "^4.6.2", + "minimatch": "^3.1.2", + "natural-compare": "^1.4.0", + "optionator": "^0.9.1", + "regexpp": "^3.2.0", + "strip-ansi": "^6.0.1", + "strip-json-comments": "^3.1.0", + "text-table": "^0.2.0", + "v8-compile-cache": "^2.0.3" + }, + "bin": { + "eslint": "bin/eslint.js" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint-config-prettier": { + "version": "8.10.2", + "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-8.10.2.tgz", + "integrity": "sha512-/IGJ6+Dka158JnP5n5YFMOszjDWrXggGz1LaK/guZq9vZTmniaKlHcsscvkAhn9y4U+BU3JuUdYvtAMcv30y4A==", + "license": "MIT", + "bin": { + "eslint-config-prettier": "bin/cli.js" + }, + "peerDependencies": { + "eslint": ">=7.0.0" + } + }, + "node_modules/eslint-plugin-jest-dom": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/eslint-plugin-jest-dom/-/eslint-plugin-jest-dom-4.0.3.tgz", + "integrity": "sha512-9j+n8uj0+V0tmsoS7bYC7fLhQmIvjRqRYEcbDSi+TKPsTThLLXCyj5swMSSf/hTleeMktACnn+HFqXBr5gbcbA==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.16.3", + "@testing-library/dom": "^8.11.1", + "requireindex": "^1.2.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0", + "npm": ">=6", + "yarn": ">=1" + }, + "peerDependencies": { + "eslint": "^6.8.0 || ^7.0.0 || ^8.0.0" + } + }, + "node_modules/eslint-plugin-jest-dom/node_modules/@testing-library/dom": { + "version": "8.20.1", + "resolved": "https://registry.npmjs.org/@testing-library/dom/-/dom-8.20.1.tgz", + "integrity": "sha512-/DiOQ5xBxgdYRC8LNk7U+RWat0S3qRLeIw3ZIkMQ9kkVlRmwD/Eg8k8CqIpD6GW7u20JIUOfMKbxtiLutpjQ4g==", + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.10.4", + "@babel/runtime": "^7.12.5", + "@types/aria-query": "^5.0.1", + "aria-query": "5.1.3", + "chalk": "^4.1.0", + "dom-accessibility-api": "^0.5.9", + "lz-string": "^1.5.0", + "pretty-format": "^27.0.2" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/eslint-plugin-jest-dom/node_modules/aria-query": { + "version": "5.1.3", + "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.1.3.tgz", + "integrity": "sha512-R5iJ5lkuHybztUfuOAznmboyjWq8O6sqNqtK7CLOqdydi54VNbORp49mb14KbWgG1QD3JFO9hJdZ+y4KutfdOQ==", + "license": "Apache-2.0", + "dependencies": { + "deep-equal": "^2.0.5" + } + }, + "node_modules/eslint-plugin-jest-dom/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/eslint-plugin-prettier": { + "version": "4.2.5", + "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-4.2.5.tgz", + "integrity": "sha512-9Ni+xgemM2IWLq6aXEpP2+V/V30GeA/46Ar629vcMqVPodFFWC9skHu/D1phvuqtS8bJCFnNf01/qcmqYEwNfg==", + "license": "MIT", + "dependencies": { + "prettier-linter-helpers": "^1.0.0" + }, + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "eslint": ">=7.28.0", + "prettier": ">=2.0.0" + }, + "peerDependenciesMeta": { + "eslint-config-prettier": { + "optional": true + } + } + }, + "node_modules/eslint-plugin-react": { + "version": "7.37.5", + "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.37.5.tgz", + "integrity": "sha512-Qteup0SqU15kdocexFNAJMvCJEfa2xUKNV4CC1xsVMrIIqEy3SQ/rqyxCWNzfrd3/ldy6HMlD2e0JDVpDg2qIA==", + "dev": true, + "license": "MIT", + "dependencies": { + "array-includes": "^3.1.8", + "array.prototype.findlast": "^1.2.5", + "array.prototype.flatmap": "^1.3.3", + "array.prototype.tosorted": "^1.1.4", + "doctrine": "^2.1.0", + "es-iterator-helpers": "^1.2.1", + "estraverse": "^5.3.0", + "hasown": "^2.0.2", + "jsx-ast-utils": "^2.4.1 || ^3.0.0", + "minimatch": "^3.1.2", + "object.entries": "^1.1.9", + "object.fromentries": "^2.0.8", + "object.values": "^1.2.1", + "prop-types": "^15.8.1", + "resolve": "^2.0.0-next.5", + "semver": "^6.3.1", + "string.prototype.matchall": "^4.0.12", + "string.prototype.repeat": "^1.0.0" + }, + "engines": { + "node": ">=4" + }, + "peerDependencies": { + "eslint": "^3 || ^4 || ^5 || ^6 || ^7 || ^8 || ^9.7" + } + }, + "node_modules/eslint-plugin-react-hooks": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-7.0.0.tgz", + "integrity": "sha512-fNXaOwvKwq2+pXiRpXc825Vd63+KM4DLL40Rtlycb8m7fYpp6efrTp1sa6ZbP/Ap58K2bEKFXRmhURE+CJAQWw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/core": "^7.24.4", + "@babel/parser": "^7.24.4", + "hermes-parser": "^0.25.1", + "zod": "^3.22.4 || ^4.0.0", + "zod-validation-error": "^3.0.3 || ^4.0.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "eslint": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0 || ^9.0.0" + } + }, + "node_modules/eslint-plugin-react/node_modules/doctrine": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", + "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "esutils": "^2.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/eslint-plugin-react/node_modules/resolve": { + "version": "2.0.0-next.5", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-2.0.0-next.5.tgz", + "integrity": "sha512-U7WjGVG9sH8tvjW5SmGbQuui75FiyjAX72HX15DwBBwF9dNiQZRQAg9nnPhYy+TUnE0+VcrttuvNI8oSxZcocA==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-core-module": "^2.13.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/eslint-plugin-testing-library": { + "version": "7.13.3", + "resolved": "https://registry.npmjs.org/eslint-plugin-testing-library/-/eslint-plugin-testing-library-7.13.3.tgz", + "integrity": "sha512-STwyXN7GnHulgsfdXVd5iC8fFCJVRQj2AcKtMmQOsA8G4oMnSCOX1p3MjbrDQ9fmwVf5wZy6vboTOTFobWuxOA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/scope-manager": "^8.15.0", + "@typescript-eslint/utils": "^8.15.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0", + "pnpm": "^9.14.0" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0" + } + }, + "node_modules/eslint-scope": { + "version": "7.2.2", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz", + "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==", + "license": "BSD-2-Clause", + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint-utils": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-3.0.0.tgz", + "integrity": "sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==", + "license": "MIT", + "dependencies": { + "eslint-visitor-keys": "^2.0.0" + }, + "engines": { + "node": "^10.0.0 || ^12.0.0 || >= 14.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/mysticatea" + }, + "peerDependencies": { + "eslint": ">=5" + } + }, + "node_modules/eslint-utils/node_modules/eslint-visitor-keys": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz", + "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==", + "license": "Apache-2.0", + "engines": { + "node": ">=10" + } + }, + "node_modules/eslint-visitor-keys": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", + "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", + "license": "Apache-2.0", + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/espree": { + "version": "9.6.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz", + "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==", + "license": "BSD-2-Clause", + "dependencies": { + "acorn": "^8.9.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^3.4.1" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/esquery": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.6.0.tgz", + "integrity": "sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==", + "license": "BSD-3-Clause", + "dependencies": { + "estraverse": "^5.1.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/esrecurse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "license": "BSD-2-Clause", + "dependencies": { + "estraverse": "^5.2.0" + }, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "license": "BSD-2-Clause", + "engines": { + "node": ">=4.0" + } + }, + "node_modules/estree-walker": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz", + "integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==", + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0" + } + }, + "node_modules/esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/expect": { + "version": "30.2.0", + "resolved": "https://registry.npmjs.org/expect/-/expect-30.2.0.tgz", + "integrity": "sha512-u/feCi0GPsI+988gU2FLcsHyAHTU0MX1Wg68NhAnN7z/+C5wqG+CY8J53N9ioe8RXgaoz0nBR/TYMf3AycUuPw==", + "license": "MIT", + "dependencies": { + "@jest/expect-utils": "30.2.0", + "@jest/get-type": "30.1.0", + "jest-matcher-utils": "30.2.0", + "jest-message-util": "30.2.0", + "jest-mock": "30.2.0", + "jest-util": "30.2.0" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/expect-type": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/expect-type/-/expect-type-1.2.2.tgz", + "integrity": "sha512-JhFGDVJ7tmDJItKhYgJCGLOWjuK9vPxiXoUFLwLDc99NlmklilbiQJwoctZtt13+xMw91MCk/REan6MWHqDjyA==", + "license": "Apache-2.0", + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "license": "MIT" + }, + "node_modules/fast-diff": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.3.0.tgz", + "integrity": "sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw==", + "license": "Apache-2.0" + }, + "node_modules/fast-glob": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.3.tgz", + "integrity": "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==", + "license": "MIT", + "dependencies": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.8" + }, + "engines": { + "node": ">=8.6.0" + } + }, + "node_modules/fast-glob/node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "license": "MIT" + }, + "node_modules/fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", + "license": "MIT" + }, + "node_modules/fast-uri": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.1.0.tgz", + "integrity": "sha512-iPeeDKJSWf4IEOasVVrknXpaBV0IApz/gp7S2bb7Z4Lljbl2MGJRqInZiUrQwV16cpzw/D3S5j5Julj/gT52AA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fastify" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fastify" + } + ], + "license": "BSD-3-Clause" + }, + "node_modules/fastq": { + "version": "1.19.1", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.19.1.tgz", + "integrity": "sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ==", + "license": "ISC", + "dependencies": { + "reusify": "^1.0.4" + } + }, + "node_modules/fdir": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", + "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==", + "license": "MIT", + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "picomatch": "^3 || ^4" + }, + "peerDependenciesMeta": { + "picomatch": { + "optional": true + } + } + }, + "node_modules/file-entry-cache": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", + "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", + "license": "MIT", + "dependencies": { + "flat-cache": "^3.0.4" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + } + }, + "node_modules/filelist": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/filelist/-/filelist-1.0.4.tgz", + "integrity": "sha512-w1cEuf3S+DrLCQL7ET6kz+gmlJdbq9J7yXCSjK/OZCPA+qEN1WyF4ZAf0YYJa4/shHJra2t/d/r8SV4Ji+x+8Q==", + "license": "Apache-2.0", + "dependencies": { + "minimatch": "^5.0.1" + } + }, + "node_modules/filelist/node_modules/brace-expansion": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", + "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/filelist/node_modules/minimatch": { + "version": "5.1.6", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", + "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/fill-range": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", + "license": "MIT", + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/find-root": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/find-root/-/find-root-1.1.0.tgz", + "integrity": "sha512-NKfW6bec6GfKc0SGx1e07QZY9PE99u0Bft/0rzSD5k3sO/vwkVUpDUKVm5Gpp5Ue3YfShPFTX2070tDs5kB9Ng==", + "license": "MIT" + }, + "node_modules/find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "license": "MIT", + "dependencies": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/flat-cache": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.2.0.tgz", + "integrity": "sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==", + "license": "MIT", + "dependencies": { + "flatted": "^3.2.9", + "keyv": "^4.5.3", + "rimraf": "^3.0.2" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + } + }, + "node_modules/flatted": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.3.tgz", + "integrity": "sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg==", + "license": "ISC" + }, + "node_modules/focus-lock": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/focus-lock/-/focus-lock-1.3.6.tgz", + "integrity": "sha512-Ik/6OCk9RQQ0T5Xw+hKNLWrjSMtv51dD4GRmJjbD5a58TIEpI5a5iXagKVl3Z5UuyslMCA8Xwnu76jQob62Yhg==", + "license": "MIT", + "dependencies": { + "tslib": "^2.0.3" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/focus-outline-manager": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/focus-outline-manager/-/focus-outline-manager-1.0.2.tgz", + "integrity": "sha512-bHWEmjLsTjGP9gVs7P3Hyl+oY5NlMW8aTSPdTJ+X2GKt6glDctt9fUCLbRV+d/l8NDC40+FxMjp9WlTQXaQALw==", + "license": "BSD-3-Clause" + }, + "node_modules/follow-redirects": { + "version": "1.15.11", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.11.tgz", + "integrity": "sha512-deG2P0JfjrTxl50XGCDyfI97ZGVCxIpfKYmfyrQ54n5FO/0gfIES8C/Psl6kWVDolizcaaxZJnTS0QSMxvnsBQ==", + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/RubenVerborgh" + } + ], + "license": "MIT", + "engines": { + "node": ">=4.0" + }, + "peerDependenciesMeta": { + "debug": { + "optional": true + } + } + }, + "node_modules/for-each": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.5.tgz", + "integrity": "sha512-dKx12eRCVIzqCxFGplyFKJMPvLEWgmNtUrpTiJIR5u97zEhRG8ySrtboPHZXx7daLxQVrl643cTzbab2tkQjxg==", + "license": "MIT", + "dependencies": { + "is-callable": "^1.2.7" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/form-data": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.4.tgz", + "integrity": "sha512-KrGhL9Q4zjj0kiUt5OO4Mr/A/jlI2jDYs5eHBpYHPcBEVSiipAvn2Ko2HnPe20rmcuuvMHNdZFp+4IlGTMF0Ow==", + "license": "MIT", + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "es-set-tostringtag": "^2.1.0", + "hasown": "^2.0.2", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/formik": { + "version": "2.4.6", + "resolved": "https://registry.npmjs.org/formik/-/formik-2.4.6.tgz", + "integrity": "sha512-A+2EI7U7aG296q2TLGvNapDNTZp1khVt5Vk0Q/fyfSROss0V/V6+txt2aJnwEos44IxTCW/LYAi/zgWzlevj+g==", + "funding": [ + { + "type": "individual", + "url": "https://opencollective.com/formik" + } + ], + "license": "Apache-2.0", + "dependencies": { + "@types/hoist-non-react-statics": "^3.3.1", + "deepmerge": "^2.1.1", + "hoist-non-react-statics": "^3.3.0", + "lodash": "^4.17.21", + "lodash-es": "^4.17.21", + "react-fast-compare": "^2.0.1", + "tiny-warning": "^1.0.2", + "tslib": "^2.0.0" + }, + "peerDependencies": { + "react": ">=16.8.0" + } + }, + "node_modules/framer-motion": { + "version": "7.10.3", + "resolved": "https://registry.npmjs.org/framer-motion/-/framer-motion-7.10.3.tgz", + "integrity": "sha512-k2ccYeZNSpPg//HTaqrU+4pRq9f9ZpaaN7rr0+Rx5zA4wZLbk547wtDzge2db1sB+1mnJ6r59P4xb+aEIi/W+w==", + "license": "MIT", + "dependencies": { + "@motionone/dom": "^10.15.3", + "hey-listen": "^1.0.8", + "tslib": "2.4.0" + }, + "optionalDependencies": { + "@emotion/is-prop-valid": "^0.8.2" + }, + "peerDependencies": { + "react": "^18.0.0", + "react-dom": "^18.0.0" + } + }, + "node_modules/framer-motion/node_modules/@emotion/is-prop-valid": { + "version": "0.8.8", + "resolved": "https://registry.npmjs.org/@emotion/is-prop-valid/-/is-prop-valid-0.8.8.tgz", + "integrity": "sha512-u5WtneEAr5IDG2Wv65yhunPSMLIpuKsbuOktRojfrEiEvRyC85LgPMZI63cr7NUqT8ZIGdSVg8ZKGxIug4lXcA==", + "license": "MIT", + "optional": true, + "dependencies": { + "@emotion/memoize": "0.7.4" + } + }, + "node_modules/framer-motion/node_modules/@emotion/memoize": { + "version": "0.7.4", + "resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.7.4.tgz", + "integrity": "sha512-Ja/Vfqe3HpuzRsG1oBtWTHk2PGZ7GR+2Vz5iYGelAw8dx32K0y7PjVuxK6z1nMpZOqAFsRUPCkK1YjJ56qJlgw==", + "license": "MIT", + "optional": true + }, + "node_modules/framer-motion/node_modules/tslib": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.0.tgz", + "integrity": "sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ==", + "license": "0BSD" + }, + "node_modules/fs-extra": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", + "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", + "license": "MIT", + "dependencies": { + "at-least-node": "^1.0.0", + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", + "license": "ISC" + }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/function.prototype.name": { + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.8.tgz", + "integrity": "sha512-e5iwyodOHhbMr/yNrc7fDYG4qlbIvI5gajyzPnb5TCwyhjApznQh1BMFou9b30SevY43gCJKXycoCBjMbsuW0Q==", + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", + "define-properties": "^1.2.1", + "functions-have-names": "^1.2.3", + "hasown": "^2.0.2", + "is-callable": "^1.2.7" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/functional-red-black-tree": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", + "integrity": "sha512-dsKNQNdj6xA3T+QlADDA7mOSlX0qiMINjn0cgr+eGHGsbSHzTabcIogz2+p/iqP1Xs6EP/sS2SbqH+brGTbq0g==", + "license": "MIT" + }, + "node_modules/functions-have-names": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz", + "integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/generator-function": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/generator-function/-/generator-function-2.0.1.tgz", + "integrity": "sha512-SFdFmIJi+ybC0vjlHN0ZGVGHc3lgE0DxPAT0djjVg+kjOnSqclqmj0KQ7ykTOLP6YxoqOvuAODGdcHJn+43q3g==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/gensync": { + "version": "1.0.0-beta.2", + "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", + "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/get-intrinsic": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", + "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "es-define-property": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.1.1", + "function-bind": "^1.1.2", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "has-symbols": "^1.1.0", + "hasown": "^2.0.2", + "math-intrinsics": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-own-enumerable-property-symbols": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/get-own-enumerable-property-symbols/-/get-own-enumerable-property-symbols-3.0.2.tgz", + "integrity": "sha512-I0UBV/XOz1XkIJHEUDMZAbzCThU/H8DxmSfmdGcKPnVhu2VfFqr34jr9777IyaTYvxjedWhqVIilEDsCdP5G6g==", + "license": "ISC" + }, + "node_modules/get-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", + "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", + "license": "MIT", + "dependencies": { + "dunder-proto": "^1.0.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/get-symbol-description": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.1.0.tgz", + "integrity": "sha512-w9UMqWwJxHNOvoNzSJ2oPF5wvYcvP7jUvYzhp67yEhTi17ZDBBC1z9pTdGuzjD+EFIqLSYRweZjqfiPzQ06Ebg==", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.6" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "deprecated": "Glob versions prior to v9 are no longer supported", + "license": "ISC", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/glob-parent": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.3" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/globals": { + "version": "13.24.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", + "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", + "license": "MIT", + "dependencies": { + "type-fest": "^0.20.2" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/globalthis": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.4.tgz", + "integrity": "sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ==", + "license": "MIT", + "dependencies": { + "define-properties": "^1.2.1", + "gopd": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/globby": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", + "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", + "license": "MIT", + "dependencies": { + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.2.9", + "ignore": "^5.2.0", + "merge2": "^1.4.1", + "slash": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/gopd": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", + "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/graceful-fs": { + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", + "license": "ISC" + }, + "node_modules/grapheme-splitter": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/grapheme-splitter/-/grapheme-splitter-1.0.4.tgz", + "integrity": "sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ==", + "license": "MIT" + }, + "node_modules/has-bigints": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.1.0.tgz", + "integrity": "sha512-R3pbpkcIqv2Pm3dUwgjclDRVmWpTJW2DcMzcIhEXEx1oh/CEMObMm3KLmRJOdvhM7o4uQBnwr8pzRK2sJWIqfg==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/has-property-descriptors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", + "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", + "license": "MIT", + "dependencies": { + "es-define-property": "^1.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-proto": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.2.0.tgz", + "integrity": "sha512-KIL7eQPfHQRC8+XluaIw7BHUwwqL19bQn4hzNgdr+1wXoU0KKj6rufu47lhY7KbJR2C6T6+PfyN0Ea7wkSS+qQ==", + "license": "MIT", + "dependencies": { + "dunder-proto": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-symbols": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", + "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-tostringtag": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", + "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", + "license": "MIT", + "dependencies": { + "has-symbols": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/hasown": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "license": "MIT", + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/hermes-estree": { + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/hermes-estree/-/hermes-estree-0.25.1.tgz", + "integrity": "sha512-0wUoCcLp+5Ev5pDW2OriHC2MJCbwLwuRx+gAqMTOkGKJJiBCLjtrvy4PWUGn6MIVefecRpzoOZ/UV6iGdOr+Cw==", + "dev": true, + "license": "MIT" + }, + "node_modules/hermes-parser": { + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/hermes-parser/-/hermes-parser-0.25.1.tgz", + "integrity": "sha512-6pEjquH3rqaI6cYAXYPcz9MS4rY6R4ngRgrgfDshRptUZIc3lw0MCIJIGDj9++mfySOuPTHB4nrSW99BCvOPIA==", + "dev": true, + "license": "MIT", + "dependencies": { + "hermes-estree": "0.25.1" + } + }, + "node_modules/hey-listen": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/hey-listen/-/hey-listen-1.0.8.tgz", + "integrity": "sha512-COpmrF2NOg4TBWUJ5UVyaCU2A88wEMkUPK4hNqyCkqHbxT92BbvfjoSozkAIIm6XhicGlJHhFdullInrdhwU8Q==", + "license": "MIT" + }, + "node_modules/highlight-words": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/highlight-words/-/highlight-words-1.2.2.tgz", + "integrity": "sha512-Mf4xfPXYm8Ay1wTibCrHpNWeR2nUMynMVFkXCi4mbl+TEgmNOe+I4hV7W3OCZcSvzGL6kupaqpfHOemliMTGxQ==", + "license": "MIT", + "engines": { + "node": ">= 16", + "npm": ">= 8" + } + }, + "node_modules/hoist-non-react-statics": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz", + "integrity": "sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==", + "license": "BSD-3-Clause", + "dependencies": { + "react-is": "^16.7.0" + } + }, + "node_modules/hoist-non-react-statics/node_modules/react-is": { + "version": "16.13.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", + "license": "MIT" + }, + "node_modules/html2canvas": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/html2canvas/-/html2canvas-1.4.1.tgz", + "integrity": "sha512-fPU6BHNpsyIhr8yyMpTLLxAbkaK8ArIBcmZIRiBLiDhjeqvXolaEmDGmELFuX9I4xDcaKKcJl+TKZLqruBbmWA==", + "license": "MIT", + "dependencies": { + "css-line-break": "^2.1.0", + "text-segmentation": "^1.0.3" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/idb": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/idb/-/idb-7.1.1.tgz", + "integrity": "sha512-gchesWBzyvGHRO9W8tzUWFDycow5gwjvFKfyV9FF32Y7F50yZMp7mP+T2mJIWFx49zicqyC4uefHM17o6xKIVQ==", + "license": "ISC" + }, + "node_modules/ignore": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", + "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, + "node_modules/immer": { + "version": "9.0.21", + "resolved": "https://registry.npmjs.org/immer/-/immer-9.0.21.tgz", + "integrity": "sha512-bc4NBHqOqSfRW7POMkHd51LvClaeMXpm8dx0e8oE2GORbq5aRK7Bxl4FyzVLdGtLmvLKL7BTDBG5ACQm4HWjTA==", + "license": "MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/immer" + } + }, + "node_modules/import-fresh": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.1.tgz", + "integrity": "sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==", + "license": "MIT", + "dependencies": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", + "license": "MIT", + "engines": { + "node": ">=0.8.19" + } + }, + "node_modules/indent-string": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", + "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.", + "license": "ISC", + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "license": "ISC" + }, + "node_modules/internal-slot": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.1.0.tgz", + "integrity": "sha512-4gd7VpWNQNB4UKKCFFVcp1AVv+FMOgs9NKzjHKusc8jTMhd5eL1NqQqOpE0KzMds804/yHlglp3uxgluOqAPLw==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "hasown": "^2.0.2", + "side-channel": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/is-arguments": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.2.0.tgz", + "integrity": "sha512-7bVbi0huj/wrIAOzb8U1aszg9kdi3KN/CyU19CTI7tAoZYEZoL9yCDXpbXN+uPsuWnP02cyug1gleqq+TU+YCA==", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-array-buffer": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.5.tgz", + "integrity": "sha512-DDfANUiiG2wC1qawP66qlTugJeL5HyzMpfr8lLK+jMQirGzNod0B12cFB/9q838Ru27sBwfw78/rdoU7RERz6A==", + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", + "get-intrinsic": "^1.2.6" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", + "license": "MIT" + }, + "node_modules/is-async-function": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-async-function/-/is-async-function-2.1.1.tgz", + "integrity": "sha512-9dgM/cZBnNvjzaMYHVoxxfPj2QXt22Ev7SuuPrs+xav0ukGB0S6d4ydZdEiM48kLx5kDV+QBPrpVnFyefL8kkQ==", + "license": "MIT", + "dependencies": { + "async-function": "^1.0.0", + "call-bound": "^1.0.3", + "get-proto": "^1.0.1", + "has-tostringtag": "^1.0.2", + "safe-regex-test": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-bigint": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.1.0.tgz", + "integrity": "sha512-n4ZT37wG78iz03xPRKJrHTdZbe3IicyucEtdRsV5yglwc3GyUfbAfpSeD0FJ41NbUNSt5wbhqfp1fS+BgnvDFQ==", + "license": "MIT", + "dependencies": { + "has-bigints": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-boolean-object": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.2.2.tgz", + "integrity": "sha512-wa56o2/ElJMYqjCjGkXri7it5FbebW5usLw/nPmCMs5DeZ7eziSYZhSmPRn0txqeW4LnAmQQU7FgqLpsEFKM4A==", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-callable": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", + "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-core-module": { + "version": "2.16.1", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.1.tgz", + "integrity": "sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==", + "license": "MIT", + "dependencies": { + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-data-view": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-data-view/-/is-data-view-1.0.2.tgz", + "integrity": "sha512-RKtWF8pGmS87i2D6gqQu/l7EYRlVdfzemCJN/P3UOs//x1QE7mfhvzHIApBTRf7axvT6DMGwSwBXYCT0nfB9xw==", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "get-intrinsic": "^1.2.6", + "is-typed-array": "^1.1.13" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-date-object": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.1.0.tgz", + "integrity": "sha512-PwwhEakHVKTdRNVOw+/Gyh0+MzlCl4R6qKvkhuvLtPMggI1WAHt9sOwZxQLSGpUaDnrdyDsomoRgNnCfKNSXXg==", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-finalizationregistry": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-finalizationregistry/-/is-finalizationregistry-1.1.1.tgz", + "integrity": "sha512-1pC6N8qWJbWoPtEjgcL2xyhQOP491EQjeUo3qTKcmV8YSDDJrOepfG8pcC7h/QgnQHYSv0mJ3Z/ZWxmatVrysg==", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-generator-function": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.1.2.tgz", + "integrity": "sha512-upqt1SkGkODW9tsGNG5mtXTXtECizwtS2kA161M+gJPc1xdb/Ax629af6YrTwcOeQHbewrPNlE5Dx7kzvXTizA==", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.4", + "generator-function": "^2.0.0", + "get-proto": "^1.0.1", + "has-tostringtag": "^1.0.2", + "safe-regex-test": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "license": "MIT", + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-map": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/is-map/-/is-map-2.0.3.tgz", + "integrity": "sha512-1Qed0/Hr2m+YqxnM09CjA2d/i6YZNfF6R2oRAOj36eUdS6qIV/huPJNSEpKbupewFs+ZsJlxsjjPbc0/afW6Lw==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-module": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-module/-/is-module-1.0.0.tgz", + "integrity": "sha512-51ypPSPCoTEIN9dy5Oy+h4pShgJmPCygKfyRCISBI+JoWT/2oJvK8QPxmwv7b/p239jXrm9M1mlQbyKJ5A152g==", + "license": "MIT" + }, + "node_modules/is-negative-zero": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.3.tgz", + "integrity": "sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "license": "MIT", + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/is-number-object": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.1.1.tgz", + "integrity": "sha512-lZhclumE1G6VYD8VHe35wFaIif+CTy5SJIi5+3y4psDgWu4wPDoBhF8NxUOinEc7pHgiTsT6MaBb92rKhhD+Xw==", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-obj": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-1.0.1.tgz", + "integrity": "sha512-l4RyHgRqGN4Y3+9JHVrNqO+tN0rV5My76uW5/nuO4K1b6vw5G8d/cmFjP9tRfEsdhZNt0IFdZuK/c2Vr4Nb+Qg==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-regex": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.2.1.tgz", + "integrity": "sha512-MjYsKHO5O7mCsmRGxWcLWheFqN9DJ/2TmngvjKXihe6efViPqc274+Fx/4fYj/r03+ESvBdTXK0V6tA3rgez1g==", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "gopd": "^1.2.0", + "has-tostringtag": "^1.0.2", + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-regexp": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-regexp/-/is-regexp-1.0.0.tgz", + "integrity": "sha512-7zjFAPO4/gwyQAAgRRmqeEeyIICSdmCqa3tsVHMdBzaXXRiqopZL4Cyghg/XulGWrtABTpbnYYzzIRffLkP4oA==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-set": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/is-set/-/is-set-2.0.3.tgz", + "integrity": "sha512-iPAjerrse27/ygGLxw+EBR9agv9Y6uLeYVJMu+QNCoouJ1/1ri0mGrcWpfCqFZuzzx3WjtwxG098X+n4OuRkPg==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-shared-array-buffer": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.4.tgz", + "integrity": "sha512-ISWac8drv4ZGfwKl5slpHG9OwPNty4jOWPRIhBpxOoD+hqITiwuipOQ2bNthAzwA3B4fIjO4Nln74N0S9byq8A==", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-stream": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", + "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-string": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.1.1.tgz", + "integrity": "sha512-BtEeSsoaQjlSPBemMQIrY1MY0uM6vnS1g5fmufYOtnxLGUZM2178PKbhsk7Ffv58IX+ZtcvoGwccYsh0PglkAA==", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-symbol": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.1.1.tgz", + "integrity": "sha512-9gGx6GTtCQM73BgmHQXfDmLtfjjTUDSyoxTCbp5WtoixAhfgsDirWIcVQ/IHpvI5Vgd5i/J5F7B9cN/WlVbC/w==", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "has-symbols": "^1.1.0", + "safe-regex-test": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-typed-array": { + "version": "1.1.15", + "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.15.tgz", + "integrity": "sha512-p3EcsicXjit7SaskXHs1hA91QxgTw46Fv6EFKKGS5DRFLD8yKnohjF3hxoju94b/OcMZoQukzpPpBE9uLVKzgQ==", + "license": "MIT", + "dependencies": { + "which-typed-array": "^1.1.16" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-weakmap": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/is-weakmap/-/is-weakmap-2.0.2.tgz", + "integrity": "sha512-K5pXYOm9wqY1RgjpL3YTkF39tni1XajUIkawTLUo9EZEVUFga5gSQJF8nNS7ZwJQ02y+1YCNYcMh+HIf1ZqE+w==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-weakref": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.1.1.tgz", + "integrity": "sha512-6i9mGWSlqzNMEqpCp93KwRS1uUOodk2OJ6b+sq7ZPDSy2WuI5NFIxp/254TytR8ftefexkWn5xNiHUNpPOfSew==", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-weakset": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/is-weakset/-/is-weakset-2.0.4.tgz", + "integrity": "sha512-mfcwb6IzQyOKTs84CQMrOwW4gQcaTOAWJ0zzJCl2WSPDrWk/OzDaImWFH3djXhb24g4eudZfLRozAvPGw4d9hQ==", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "get-intrinsic": "^1.2.6" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-what": { + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/is-what/-/is-what-3.14.1.tgz", + "integrity": "sha512-sNxgpk9793nzSs7bA6JQJGeIuRBQhAaNGG77kzYQgMkrID+lS6SlK07K5LaptscDlSaIgH+GPFzf+d75FVxozA==", + "license": "MIT" + }, + "node_modules/isarray": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", + "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==", + "license": "MIT" + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "license": "ISC" + }, + "node_modules/iterator.prototype": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/iterator.prototype/-/iterator.prototype-1.1.5.tgz", + "integrity": "sha512-H0dkQoCa3b2VEeKQBOxFph+JAbcrQdE7KC0UkqwpLmv2EC4P41QXP+rqo9wYodACiG5/WM5s9oDApTU8utwj9g==", + "dev": true, + "license": "MIT", + "dependencies": { + "define-data-property": "^1.1.4", + "es-object-atoms": "^1.0.0", + "get-intrinsic": "^1.2.6", + "get-proto": "^1.0.0", + "has-symbols": "^1.1.0", + "set-function-name": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/jake": { + "version": "10.9.4", + "resolved": "https://registry.npmjs.org/jake/-/jake-10.9.4.tgz", + "integrity": "sha512-wpHYzhxiVQL+IV05BLE2Xn34zW1S223hvjtqk0+gsPrwd/8JNLXJgZZM/iPFsYc1xyphF+6M6EvdE5E9MBGkDA==", + "license": "Apache-2.0", + "dependencies": { + "async": "^3.2.6", + "filelist": "^1.0.4", + "picocolors": "^1.1.1" + }, + "bin": { + "jake": "bin/cli.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/jest-diff": { + "version": "30.2.0", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-30.2.0.tgz", + "integrity": "sha512-dQHFo3Pt4/NLlG5z4PxZ/3yZTZ1C7s9hveiOj+GCN+uT109NC2QgsoVZsVOAvbJ3RgKkvyLGXZV9+piDpWbm6A==", + "license": "MIT", + "dependencies": { + "@jest/diff-sequences": "30.0.1", + "@jest/get-type": "30.1.0", + "chalk": "^4.1.2", + "pretty-format": "30.2.0" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/jest-diff/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/jest-diff/node_modules/pretty-format": { + "version": "30.2.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-30.2.0.tgz", + "integrity": "sha512-9uBdv/B4EefsuAL+pWqueZyZS2Ba+LxfFeQ9DN14HU4bN8bhaxKdkpjpB6fs9+pSjIBu+FXQHImEg8j/Lw0+vA==", + "license": "MIT", + "dependencies": { + "@jest/schemas": "30.0.5", + "ansi-styles": "^5.2.0", + "react-is": "^18.3.1" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/jest-diff/node_modules/pretty-format/node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-matcher-utils": { + "version": "30.2.0", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-30.2.0.tgz", + "integrity": "sha512-dQ94Nq4dbzmUWkQ0ANAWS9tBRfqCrn0bV9AMYdOi/MHW726xn7eQmMeRTpX2ViC00bpNaWXq+7o4lIQ3AX13Hg==", + "license": "MIT", + "dependencies": { + "@jest/get-type": "30.1.0", + "chalk": "^4.1.2", + "jest-diff": "30.2.0", + "pretty-format": "30.2.0" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/jest-matcher-utils/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/jest-matcher-utils/node_modules/pretty-format": { + "version": "30.2.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-30.2.0.tgz", + "integrity": "sha512-9uBdv/B4EefsuAL+pWqueZyZS2Ba+LxfFeQ9DN14HU4bN8bhaxKdkpjpB6fs9+pSjIBu+FXQHImEg8j/Lw0+vA==", + "license": "MIT", + "dependencies": { + "@jest/schemas": "30.0.5", + "ansi-styles": "^5.2.0", + "react-is": "^18.3.1" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/jest-matcher-utils/node_modules/pretty-format/node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-message-util": { + "version": "30.2.0", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-30.2.0.tgz", + "integrity": "sha512-y4DKFLZ2y6DxTWD4cDe07RglV88ZiNEdlRfGtqahfbIjfsw1nMCPx49Uev4IA/hWn3sDKyAnSPwoYSsAEdcimw==", + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.27.1", + "@jest/types": "30.2.0", + "@types/stack-utils": "^2.0.3", + "chalk": "^4.1.2", + "graceful-fs": "^4.2.11", + "micromatch": "^4.0.8", + "pretty-format": "30.2.0", + "slash": "^3.0.0", + "stack-utils": "^2.0.6" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/jest-message-util/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/jest-message-util/node_modules/pretty-format": { + "version": "30.2.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-30.2.0.tgz", + "integrity": "sha512-9uBdv/B4EefsuAL+pWqueZyZS2Ba+LxfFeQ9DN14HU4bN8bhaxKdkpjpB6fs9+pSjIBu+FXQHImEg8j/Lw0+vA==", + "license": "MIT", + "dependencies": { + "@jest/schemas": "30.0.5", + "ansi-styles": "^5.2.0", + "react-is": "^18.3.1" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/jest-message-util/node_modules/pretty-format/node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-mock": { + "version": "30.2.0", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-30.2.0.tgz", + "integrity": "sha512-JNNNl2rj4b5ICpmAcq+WbLH83XswjPbjH4T7yvGzfAGCPh1rw+xVNbtk+FnRslvt9lkCcdn9i1oAoKUuFsOxRw==", + "license": "MIT", + "dependencies": { + "@jest/types": "30.2.0", + "@types/node": "*", + "jest-util": "30.2.0" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/jest-regex-util": { + "version": "30.0.1", + "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-30.0.1.tgz", + "integrity": "sha512-jHEQgBXAgc+Gh4g0p3bCevgRCVRkB4VB70zhoAE48gxeSr1hfUOsM/C2WoJgVL7Eyg//hudYENbm3Ne+/dRVVA==", + "license": "MIT", + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/jest-util": { + "version": "30.2.0", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-30.2.0.tgz", + "integrity": "sha512-QKNsM0o3Xe6ISQU869e+DhG+4CK/48aHYdJZGlFQVTjnbvgpcKyxpzk29fGiO7i/J8VENZ+d2iGnSsvmuHywlA==", + "license": "MIT", + "dependencies": { + "@jest/types": "30.2.0", + "@types/node": "*", + "chalk": "^4.1.2", + "ci-info": "^4.2.0", + "graceful-fs": "^4.2.11", + "picomatch": "^4.0.2" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/jest-util/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "license": "MIT" + }, + "node_modules/js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "license": "MIT", + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/jsesc": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz", + "integrity": "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==", + "license": "MIT", + "bin": { + "jsesc": "bin/jsesc" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/json-buffer": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", + "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", + "license": "MIT" + }, + "node_modules/json-parse-even-better-errors": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", + "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", + "license": "MIT" + }, + "node_modules/json-schema": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.4.0.tgz", + "integrity": "sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==", + "license": "(AFL-2.1 OR BSD-3-Clause)" + }, + "node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "license": "MIT" + }, + "node_modules/json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", + "license": "MIT" + }, + "node_modules/json5": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", + "license": "MIT", + "bin": { + "json5": "lib/cli.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/jsonfile": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.2.0.tgz", + "integrity": "sha512-FGuPw30AdOIUTRMC2OMRtQV+jkVj2cfPqSeWXv1NEAJ1qZ5zb1X6z1mFhbfOB/iy3ssJCD+3KuZ8r8C3uVFlAg==", + "license": "MIT", + "dependencies": { + "universalify": "^2.0.0" + }, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/jsonpointer": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/jsonpointer/-/jsonpointer-5.0.1.tgz", + "integrity": "sha512-p/nXbhSEcu3pZRdkW1OfJhpsVtW1gd4Wa1fnQc9YLiTfAjn0312eMKimbdIQzuZl9aa9xUGaRlP9T/CJE/ditQ==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/jsx-ast-utils": { + "version": "3.3.5", + "resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-3.3.5.tgz", + "integrity": "sha512-ZZow9HBI5O6EPgSJLUb8n2NKgmVWTwCvHGwFuJlMjvLFqlGG6pjirPhtdsseaLZjSibD8eegzmYpUZwoIlj2cQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "array-includes": "^3.1.6", + "array.prototype.flat": "^1.3.1", + "object.assign": "^4.1.4", + "object.values": "^1.1.6" + }, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/keyv": { + "version": "4.5.4", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", + "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", + "license": "MIT", + "dependencies": { + "json-buffer": "3.0.1" + } + }, + "node_modules/leven": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", + "integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/levn": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", + "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", + "license": "MIT", + "dependencies": { + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/lines-and-columns": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", + "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", + "license": "MIT" + }, + "node_modules/locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "license": "MIT", + "dependencies": { + "p-locate": "^5.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "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-es": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash-es/-/lodash-es-4.17.21.tgz", + "integrity": "sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==", + "license": "MIT" + }, + "node_modules/lodash.assignwith": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/lodash.assignwith/-/lodash.assignwith-4.2.0.tgz", + "integrity": "sha512-ZznplvbvtjK2gMvnQ1BR/zqPFZmS6jbK4p+6Up4xcRYA7yMIwxHCfbTcrYxXKzzqLsQ05eJPVznEW3tuwV7k1g==", + "license": "MIT" + }, + "node_modules/lodash.clonedeep": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz", + "integrity": "sha512-H5ZhCF25riFd9uB5UCkVKo61m3S/xZk1x4wA6yp/L3RFP6Z/eHH1ymQcGLo7J3GMPfm0V/7m1tryHuGVxpqEBQ==", + "license": "MIT" + }, + "node_modules/lodash.debounce": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", + "integrity": "sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==", + "license": "MIT" + }, + "node_modules/lodash.find": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/lodash.find/-/lodash.find-4.6.0.tgz", + "integrity": "sha512-yaRZoAV3Xq28F1iafWN1+a0rflOej93l1DQUejs3SZ41h2O9UJBoS9aueGjPDgAl4B6tPC0NuuchLKaDQQ3Isg==", + "license": "MIT" + }, + "node_modules/lodash.get": { + "version": "4.4.2", + "resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz", + "integrity": "sha512-z+Uw/vLuy6gQe8cfaFWD7p0wVv8fJl3mbzXh33RS+0oW2wvUqiRXiQ69gLWSLpgB5/6sU+r6BlQR0MBILadqTQ==", + "deprecated": "This package is deprecated. Use the optional chaining (?.) operator instead.", + "license": "MIT" + }, + "node_modules/lodash.isequal": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.isequal/-/lodash.isequal-4.5.0.tgz", + "integrity": "sha512-pDo3lu8Jhfjqls6GkMgpahsF9kCyayhgykjyLMNFTKWrpVdAQtYyB4muAMWozBB4ig/dtWAmsMxLEI8wuz+DYQ==", + "deprecated": "This package is deprecated. Use require('node:util').isDeepStrictEqual instead.", + "license": "MIT" + }, + "node_modules/lodash.isundefined": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/lodash.isundefined/-/lodash.isundefined-3.0.1.tgz", + "integrity": "sha512-MXB1is3s899/cD8jheYYE2V9qTHwKvt+npCwpD+1Sxm3Q3cECXCiYHjeHWXNwr6Q0SOBPrYUDxendrO6goVTEA==", + "license": "MIT" + }, + "node_modules/lodash.memoize": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz", + "integrity": "sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag==", + "license": "MIT" + }, + "node_modules/lodash.merge": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", + "license": "MIT" + }, + "node_modules/lodash.sortby": { + "version": "4.7.0", + "resolved": "https://registry.npmjs.org/lodash.sortby/-/lodash.sortby-4.7.0.tgz", + "integrity": "sha512-HDWXG8isMntAyRF5vZ7xKuEvOhT4AhlRt/3czTSjvGUxjYCBVRQY48ViDHyfYz9VIoBkW4TMGQNapx+l3RUwdA==", + "license": "MIT" + }, + "node_modules/lodash.throttle": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/lodash.throttle/-/lodash.throttle-4.1.1.tgz", + "integrity": "sha512-wIkUCfVKpVsWo3JSZlc+8MB5it+2AN5W8J7YVMST30UrvcQNZ1Okbj+rbVniijTWE6FGYy4XJq/rHkas8qJMLQ==", + "license": "MIT" + }, + "node_modules/loose-envify": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", + "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", + "license": "MIT", + "dependencies": { + "js-tokens": "^3.0.0 || ^4.0.0" + }, + "bin": { + "loose-envify": "cli.js" + } + }, + "node_modules/lottie-react": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/lottie-react/-/lottie-react-2.4.1.tgz", + "integrity": "sha512-LQrH7jlkigIIv++wIyrOYFLHSKQpEY4zehPicL9bQsrt1rnoKRYCYgpCUe5maqylNtacy58/sQDZTkwMcTRxZw==", + "license": "MIT", + "dependencies": { + "lottie-web": "^5.10.2" + }, + "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/lottie-web": { + "version": "5.13.0", + "resolved": "https://registry.npmjs.org/lottie-web/-/lottie-web-5.13.0.tgz", + "integrity": "sha512-+gfBXl6sxXMPe8tKQm7qzLnUy5DUPJPKIyRHwtpCpyUEYjHYRJC/5gjUvdkuO2c3JllrPtHXH5UJJK8LRYl5yQ==", + "license": "MIT" + }, + "node_modules/loupe": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/loupe/-/loupe-3.2.1.tgz", + "integrity": "sha512-CdzqowRJCeLU72bHvWqwRBBlLcMEtIvGrlvef74kMnV2AolS9Y8xUv1I0U/MNAWMhBlKIoyuEgoJ0t/bbwHbLQ==", + "license": "MIT" + }, + "node_modules/lru-cache": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", + "license": "ISC", + "dependencies": { + "yallist": "^3.0.2" + } + }, + "node_modules/lz-string": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/lz-string/-/lz-string-1.5.0.tgz", + "integrity": "sha512-h5bgJWpxJNswbU7qCrV0tIKQCaS3blPDrqKWx+QxzuzL1zGUzij9XCWLrSLsJPu5t+eWA/ycetzYAO5IOMcWAQ==", + "license": "MIT", + "bin": { + "lz-string": "bin/bin.js" + } + }, + "node_modules/magic-string": { + "version": "0.30.19", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.19.tgz", + "integrity": "sha512-2N21sPY9Ws53PZvsEpVtNuSW+ScYbQdp4b9qUaL+9QkHUrGFKo56Lg9Emg5s9V/qrtNBmiR01sYhUOwu3H+VOw==", + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.5" + } + }, + "node_modules/material-react-table": { + "version": "2.13.3", + "resolved": "https://registry.npmjs.org/material-react-table/-/material-react-table-2.13.3.tgz", + "integrity": "sha512-xeyAEG6UYG3qgBIo17epAP5zsWT1pH0uCEkaUxvhki9sGcP35OqfOMSZJNhISvmqEqXKYHdqKbZI6iOwsg1sYA==", + "license": "MIT", + "dependencies": { + "@tanstack/match-sorter-utils": "8.19.4", + "@tanstack/react-table": "8.20.5", + "@tanstack/react-virtual": "3.10.6", + "highlight-words": "1.2.2" + }, + "engines": { + "node": ">=16" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/kevinvandy" + }, + "peerDependencies": { + "@emotion/react": ">=11.11", + "@emotion/styled": ">=11.11", + "@mui/icons-material": ">=5.11", + "@mui/material": ">=5.13", + "@mui/x-date-pickers": ">=6.15.0", + "react": ">=17.0", + "react-dom": ">=17.0" + } + }, + "node_modules/math-intrinsics": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", + "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/memoize-one": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/memoize-one/-/memoize-one-5.2.1.tgz", + "integrity": "sha512-zYiwtZUcYyXKo/np96AGZAckk+FWWsUdJ3cHGGmld7+AhvcWmQyGCYUh1hc4Q/pkOhb65dQR/pqCyK0cOaHz4Q==", + "license": "MIT" + }, + "node_modules/merge-anything": { + "version": "2.4.4", + "resolved": "https://registry.npmjs.org/merge-anything/-/merge-anything-2.4.4.tgz", + "integrity": "sha512-l5XlriUDJKQT12bH+rVhAHjwIuXWdAIecGwsYjv2LJo+dA1AeRTmeQS+3QBpO6lEthBMDi2IUMpLC1yyRvGlwQ==", + "license": "MIT", + "dependencies": { + "is-what": "^3.3.1" + } + }, + "node_modules/merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "license": "MIT", + "engines": { + "node": ">= 8" + } + }, + "node_modules/micromatch": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", + "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", + "license": "MIT", + "dependencies": { + "braces": "^3.0.3", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/micromatch/node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "license": "MIT", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "license": "MIT", + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/min-indent": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz", + "integrity": "sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/moment": { + "version": "2.30.1", + "resolved": "https://registry.npmjs.org/moment/-/moment-2.30.1.tgz", + "integrity": "sha512-uEmtNhbDOrWPFS+hdjFCBfy9f2YoyzRpwcl+DqpC6taX21FzsTLQVbMV/W7PzNSX6x/bhC1zA3c2UQ5NzH6how==", + "license": "MIT", + "engines": { + "node": "*" + } + }, + "node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "license": "MIT" + }, + "node_modules/mui-datatables": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/mui-datatables/-/mui-datatables-4.3.0.tgz", + "integrity": "sha512-LFliQwNnnxW03IO+V3q/ORxZsOHkzl53iGogLbjUJzme47hNEN106dM0ie8oMSc0heYJY0J07oZmKm7Xn3X7IQ==", + "license": "MIT", + "dependencies": { + "@babel/runtime-corejs3": "^7.12.1", + "@emotion/cache": "^11.7.1", + "clsx": "^1.1.1", + "lodash.assignwith": "^4.2.0", + "lodash.clonedeep": "^4.5.0", + "lodash.debounce": "^4.0.8", + "lodash.find": "^4.6.0", + "lodash.get": "^4.4.2", + "lodash.isequal": "^4.5.0", + "lodash.isundefined": "^3.0.1", + "lodash.memoize": "^4.1.2", + "lodash.merge": "^4.6.2", + "prop-types": "^15.7.2", + "react-dnd": "^11.1.3", + "react-dnd-html5-backend": "^11.1.3", + "react-sortable-tree-patch-react-17": "^2.9.0", + "react-to-print": "^2.8.0", + "tss-react": "^3.6.0" + }, + "peerDependencies": { + "@emotion/react": "^11.10.5", + "@mui/icons-material": "^5.11.0", + "@mui/material": "^5.11.0", + "react": "^16.8.0 || ^17.0.2 || ^18.2.0", + "react-dom": "^16.8.0 || ^17.0.2 || ^18.2.0" + } + }, + "node_modules/mui-datatables/node_modules/clsx": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/clsx/-/clsx-1.2.1.tgz", + "integrity": "sha512-EcR6r5a8bj6pu3ycsa/E/cKVGuTgZJZdsyUYHOksG/UHIiKfjxzRxYJpyVBwYaQeOvghal9fcc4PidlgzugAQg==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/nanoclone": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/nanoclone/-/nanoclone-0.2.1.tgz", + "integrity": "sha512-wynEP02LmIbLpcYw8uBKpcfF6dmg2vcpKqxeH5UcoKEYdExslsdUA4ugFauuaeYdTB76ez6gJW8XAZ6CgkXYxA==", + "license": "MIT" + }, + "node_modules/natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", + "license": "MIT" + }, + "node_modules/node-releases": { + "version": "2.0.25", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.25.tgz", + "integrity": "sha512-4auku8B/vw5psvTiiN9j1dAOsXvMoGqJuKJcR+dTdqiXEK20mMTk1UEo3HS16LeGQsVG6+qKTPM9u/qQ2LqATA==", + "license": "MIT" + }, + "node_modules/num2persian": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/num2persian/-/num2persian-3.2.2.tgz", + "integrity": "sha512-xwT+fAiVWq6Nde+JWf5/PlW3qAGRNa0TJEUJwoJmaXjmLp1dewOFiX2+jUSreAsTrX2qi/rzgk3diSt36f6ouQ==", + "license": "GPL-2.0", + "engines": { + "node": ">=6.9.0", + "npm": ">= 3" + } + }, + "node_modules/object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-inspect": { + "version": "1.13.4", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz", + "integrity": "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object-is": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/object-is/-/object-is-1.1.6.tgz", + "integrity": "sha512-F8cZ+KfGlSGi09lJT7/Nd6KJZ9ygtvYC0/UYYLI9nmQKLMnydpB9yvbv9K1uSkEu7FU9vYPmVwLg328tX+ot3Q==", + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/object.assign": { + "version": "4.1.7", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.7.tgz", + "integrity": "sha512-nK28WOo+QIjBkDduTINE4JkF/UJJKyf2EJxvJKfblDpyg0Q+pkOHNTL0Qwy6NP6FhE/EnzV73BxxqcJaXY9anw==", + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0", + "has-symbols": "^1.1.0", + "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object.entries": { + "version": "1.1.9", + "resolved": "https://registry.npmjs.org/object.entries/-/object.entries-1.1.9.tgz", + "integrity": "sha512-8u/hfXFRBD1O0hPUjioLhoWFHRmt6tKA4/vZPyckBr18l1KE9uHrFaFaUi8MDRTpi4uak2goyPTSNJLXX2k2Hw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.4", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/object.fromentries": { + "version": "2.0.8", + "resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.8.tgz", + "integrity": "sha512-k6E21FzySsSK5a21KRADBd/NGneRegFO5pLHfdQLpRDETUNJueLXs3WCzyQ3tFRDYgbq3KHGXfTbi2bs8WQ6rQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object.values": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.2.1.tgz", + "integrity": "sha512-gXah6aZrcUxjWg2zR2MwouP2eHlCBzdV4pygudehaKXSGW4v2AsRQUK+lwwXhii6KFZcunEnmSUoYp5CXibxtA==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "license": "ISC", + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/optionator": { + "version": "0.9.4", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", + "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==", + "license": "MIT", + "dependencies": { + "deep-is": "^0.1.3", + "fast-levenshtein": "^2.0.6", + "levn": "^0.4.1", + "prelude-ls": "^1.2.1", + "type-check": "^0.4.0", + "word-wrap": "^1.2.5" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/own-keys": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/own-keys/-/own-keys-1.0.1.tgz", + "integrity": "sha512-qFOyK5PjiWZd+QQIh+1jhdb9LpxTF0qs7Pm8o5QHYZ0M3vKqSqzsZaEB6oWlxZ+q2sJBMI/Ktgd2N5ZwQoRHfg==", + "license": "MIT", + "dependencies": { + "get-intrinsic": "^1.2.6", + "object-keys": "^1.1.1", + "safe-push-apply": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "license": "MIT", + "dependencies": { + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "license": "MIT", + "dependencies": { + "p-limit": "^3.0.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/parent-module": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "license": "MIT", + "dependencies": { + "callsites": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/parse-json": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", + "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-even-better-errors": "^2.3.0", + "lines-and-columns": "^1.1.6" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "license": "MIT" + }, + "node_modules/path-type": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/pathe": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/pathe/-/pathe-1.1.2.tgz", + "integrity": "sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ==", + "license": "MIT" + }, + "node_modules/pathval": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/pathval/-/pathval-2.0.1.tgz", + "integrity": "sha512-//nshmD55c46FuFw26xV/xFAaB5HF9Xdap7HJBBnrKdAd6/GxDBaNA1870O79+9ueg61cZLSVc+OaFlfmObYVQ==", + "license": "MIT", + "engines": { + "node": ">= 14.16" + } + }, + "node_modules/performance-now": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", + "integrity": "sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow==", + "license": "MIT" + }, + "node_modules/persian-date": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/persian-date/-/persian-date-1.1.0.tgz", + "integrity": "sha512-YwV3703jLTTJFFQfP3RvMfvKZc5Z1yE++Deywox+hkVLuVN81VsTaZFma9k5P9SgfSUvXjiylbQVuf4YYLGOow==", + "license": "MIT" + }, + "node_modules/picocolors": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", + "license": "ISC" + }, + "node_modules/picomatch": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", + "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/possible-typed-array-names": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.1.0.tgz", + "integrity": "sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/postcss": { + "version": "8.5.6", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.6.tgz", + "integrity": "sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "nanoid": "^3.3.11", + "picocolors": "^1.1.1", + "source-map-js": "^1.2.1" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/postcss-value-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", + "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==", + "license": "MIT" + }, + "node_modules/postcss/node_modules/nanoid": { + "version": "3.3.11", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz", + "integrity": "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "node_modules/prelude-ls": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", + "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", + "license": "MIT", + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/prettier": { + "version": "2.8.8", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.8.tgz", + "integrity": "sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==", + "license": "MIT", + "bin": { + "prettier": "bin-prettier.js" + }, + "engines": { + "node": ">=10.13.0" + }, + "funding": { + "url": "https://github.com/prettier/prettier?sponsor=1" + } + }, + "node_modules/prettier-linter-helpers": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/prettier-linter-helpers/-/prettier-linter-helpers-1.0.0.tgz", + "integrity": "sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w==", + "license": "MIT", + "dependencies": { + "fast-diff": "^1.1.2" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/pretty-bytes": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/pretty-bytes/-/pretty-bytes-6.1.1.tgz", + "integrity": "sha512-mQUvGU6aUFQ+rNvTIAcZuWGRT9a6f6Yrg9bHs4ImKF+HZCEK+plBvnAZYSIQztknZF2qnzNtr6F8s0+IuptdlQ==", + "license": "MIT", + "engines": { + "node": "^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/pretty-format": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.5.1.tgz", + "integrity": "sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ==", + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1", + "ansi-styles": "^5.0.0", + "react-is": "^17.0.1" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/pretty-format/node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/pretty-format/node_modules/react-is": { + "version": "17.0.2", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", + "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", + "license": "MIT" + }, + "node_modules/prop-types": { + "version": "15.8.1", + "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz", + "integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==", + "license": "MIT", + "dependencies": { + "loose-envify": "^1.4.0", + "object-assign": "^4.1.1", + "react-is": "^16.13.1" + } + }, + "node_modules/prop-types/node_modules/react-is": { + "version": "16.13.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", + "license": "MIT" + }, + "node_modules/property-expr": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/property-expr/-/property-expr-2.0.6.tgz", + "integrity": "sha512-SVtmxhRE/CGkn3eZY1T6pC8Nln6Fr/lu1mKSgRud0eC73whjGfoAogbn78LkD8aFL0zz3bAFerKSnOl7NlErBA==", + "license": "MIT" + }, + "node_modules/punycode": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/raf": { + "version": "3.4.1", + "resolved": "https://registry.npmjs.org/raf/-/raf-3.4.1.tgz", + "integrity": "sha512-Sq4CW4QhwOHE8ucn6J34MqtZCeWFP2aQSmrlroYgqAV1PjStIhJXxYuTgUIfkEk7zTLjmIjLmU5q+fbD1NnOJA==", + "license": "MIT", + "dependencies": { + "performance-now": "^2.1.0" + } + }, + "node_modules/randombytes": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", + "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", + "license": "MIT", + "dependencies": { + "safe-buffer": "^5.1.0" + } + }, + "node_modules/react": { + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react/-/react-18.3.1.tgz", + "integrity": "sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==", + "license": "MIT", + "dependencies": { + "loose-envify": "^1.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/react-chartjs-2": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/react-chartjs-2/-/react-chartjs-2-5.3.0.tgz", + "integrity": "sha512-UfZZFnDsERI3c3CZGxzvNJd02SHjaSJ8kgW1djn65H1KK8rehwTjyrRKOG3VTMG8wtHZ5rgAO5oTHtHi9GCCmw==", + "license": "MIT", + "peerDependencies": { + "chart.js": "^4.1.1", + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" + } + }, + "node_modules/react-clientside-effect": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/react-clientside-effect/-/react-clientside-effect-1.2.8.tgz", + "integrity": "sha512-ma2FePH0z3px2+WOu6h+YycZcEvFmmxIlAb62cF52bG86eMySciO/EQZeQMXd07kPCYB0a1dWDT5J+KE9mCDUw==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.12.13" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc" + } + }, + "node_modules/react-data-table-component": { + "version": "7.7.0", + "resolved": "https://registry.npmjs.org/react-data-table-component/-/react-data-table-component-7.7.0.tgz", + "integrity": "sha512-5knL6zMSKlbvzu9P04KM5Lx8/EyQujb4I9z3rWeoVX++IDJadQ7aR4X5J6EeS90wjK0Xoa6btaVeglnCAqD2ag==", + "license": "Apache-2.0", + "dependencies": { + "deepmerge": "^4.3.1" + }, + "peerDependencies": { + "react": ">= 17.0.0", + "styled-components": ">= 5.0.0" + }, + "peerDependenciesMeta": { + "styled-components": { + "optional": false + } + } + }, + "node_modules/react-data-table-component/node_modules/deepmerge": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz", + "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/react-display-name": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/react-display-name/-/react-display-name-0.2.5.tgz", + "integrity": "sha512-I+vcaK9t4+kypiSgaiVWAipqHRXYmZIuAiS8vzFvXHHXVigg/sMKwlRgLy6LH2i3rmP+0Vzfl5lFsFRwF1r3pg==", + "license": "MIT" + }, + "node_modules/react-dnd": { + "version": "11.1.3", + "resolved": "https://registry.npmjs.org/react-dnd/-/react-dnd-11.1.3.tgz", + "integrity": "sha512-8rtzzT8iwHgdSC89VktwhqdKKtfXaAyC4wiqp0SywpHG12TTLvfOoL6xNEIUWXwIEWu+CFfDn4GZJyynCEuHIQ==", + "license": "MIT", + "dependencies": { + "@react-dnd/shallowequal": "^2.0.0", + "@types/hoist-non-react-statics": "^3.3.1", + "dnd-core": "^11.1.3", + "hoist-non-react-statics": "^3.3.0" + }, + "peerDependencies": { + "react": ">= 16.9.0", + "react-dom": ">= 16.9.0" + } + }, + "node_modules/react-dnd-html5-backend": { + "version": "11.1.3", + "resolved": "https://registry.npmjs.org/react-dnd-html5-backend/-/react-dnd-html5-backend-11.1.3.tgz", + "integrity": "sha512-/1FjNlJbW/ivkUxlxQd7o3trA5DE33QiRZgxent3zKme8DwF4Nbw3OFVhTRFGaYhHFNL1rZt6Rdj1D78BjnNLw==", + "license": "MIT", + "dependencies": { + "dnd-core": "^11.1.3" + } + }, + "node_modules/react-dom": { + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.3.1.tgz", + "integrity": "sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw==", + "license": "MIT", + "dependencies": { + "loose-envify": "^1.1.0", + "scheduler": "^0.23.2" + }, + "peerDependencies": { + "react": "^18.3.1" + } + }, + "node_modules/react-error-boundary": { + "version": "3.1.4", + "resolved": "https://registry.npmjs.org/react-error-boundary/-/react-error-boundary-3.1.4.tgz", + "integrity": "sha512-uM9uPzZJTF6wRQORmSrvOIgt4lJ9MC1sNgEOj2XGsDTRE4kmpWxg7ENK9EWNKJRMAOY9z0MuF4yIfl6gp4sotA==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.12.5" + }, + "engines": { + "node": ">=10", + "npm": ">=6" + }, + "peerDependencies": { + "react": ">=16.13.1" + } + }, + "node_modules/react-fast-compare": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/react-fast-compare/-/react-fast-compare-2.0.4.tgz", + "integrity": "sha512-suNP+J1VU1MWFKcyt7RtjiSWUjvidmQSlqu+eHslq+342xCbGTYmC0mEhPCOHxlW0CywylOC1u2DFAT+bv4dBw==", + "license": "MIT" + }, + "node_modules/react-focus-lock": { + "version": "2.13.6", + "resolved": "https://registry.npmjs.org/react-focus-lock/-/react-focus-lock-2.13.6.tgz", + "integrity": "sha512-ehylFFWyYtBKXjAO9+3v8d0i+cnc1trGS0vlTGhzFW1vbFXVUTmR8s2tt/ZQG8x5hElg6rhENlLG1H3EZK0Llg==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.0.0", + "focus-lock": "^1.3.6", + "prop-types": "^15.6.2", + "react-clientside-effect": "^1.2.7", + "use-callback-ref": "^1.3.3", + "use-sidecar": "^1.1.3" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/react-icons": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/react-icons/-/react-icons-4.12.0.tgz", + "integrity": "sha512-IBaDuHiShdZqmfc/TwHu6+d6k2ltNCf3AszxNmjJc1KUfXdEeRJOKyNvLmAHaarhzGmTSVygNdyu8/opXv2gaw==", + "license": "MIT", + "peerDependencies": { + "react": "*" + } + }, + "node_modules/react-images-uploading": { + "version": "3.1.7", + "resolved": "https://registry.npmjs.org/react-images-uploading/-/react-images-uploading-3.1.7.tgz", + "integrity": "sha512-woET50eCezm645iIeP4gCoN7HjdR3T64UXC5l53yd+2vHFp+pwABH8Z/aAO5IXDeC1aP6doQ+K738L701zswAw==", + "license": "MIT", + "engines": { + "node": ">=8", + "npm": ">=5" + }, + "peerDependencies": { + "react": ">=16.8.0", + "react-dom": ">=16.8.0" + } + }, + "node_modules/react-is": { + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz", + "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==", + "license": "MIT" + }, + "node_modules/react-lifecycles-compat": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/react-lifecycles-compat/-/react-lifecycles-compat-3.0.4.tgz", + "integrity": "sha512-fBASbA6LnOU9dOU2eW7aQ8xmYBSXUIWr+UmF9b1efZBazGNO+rcXT/icdKnYm2pTwcRylVUYwW7H1PHfLekVzA==", + "license": "MIT" + }, + "node_modules/react-number-format": { + "version": "5.4.4", + "resolved": "https://registry.npmjs.org/react-number-format/-/react-number-format-5.4.4.tgz", + "integrity": "sha512-wOmoNZoOpvMminhifQYiYSTCLUDOiUbBunrMrMjA+dV52sY+vck1S4UhR6PkgnoCquvvMSeJjErXZ4qSaWCliA==", + "license": "MIT", + "peerDependencies": { + "react": "^0.14 || ^15.0.0 || ^16.0.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", + "react-dom": "^0.14 || ^15.0.0 || ^16.0.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" + } + }, + "node_modules/react-redux": { + "version": "8.1.3", + "resolved": "https://registry.npmjs.org/react-redux/-/react-redux-8.1.3.tgz", + "integrity": "sha512-n0ZrutD7DaX/j9VscF+uTALI3oUPa/pO4Z3soOBIjuRn/FzVu6aehhysxZCLi6y7duMf52WNZGMl7CtuK5EnRw==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.12.1", + "@types/hoist-non-react-statics": "^3.3.1", + "@types/use-sync-external-store": "^0.0.3", + "hoist-non-react-statics": "^3.3.2", + "react-is": "^18.0.0", + "use-sync-external-store": "^1.0.0" + }, + "peerDependencies": { + "@types/react": "^16.8 || ^17.0 || ^18.0", + "@types/react-dom": "^16.8 || ^17.0 || ^18.0", + "react": "^16.8 || ^17.0 || ^18.0", + "react-dom": "^16.8 || ^17.0 || ^18.0", + "react-native": ">=0.59", + "redux": "^4 || ^5.0.0-beta.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + }, + "react-dom": { + "optional": true + }, + "react-native": { + "optional": true + }, + "redux": { + "optional": true + } + } + }, + "node_modules/react-refresh": { + "version": "0.17.0", + "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.17.0.tgz", + "integrity": "sha512-z6F7K9bV85EfseRCp2bzrpyQ0Gkw1uLoCel9XBVWPg/TjRj94SkJzUTGfOa4bs7iJvBWtQG0Wq7wnI0syw3EBQ==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/react-router": { + "version": "6.30.1", + "resolved": "https://registry.npmjs.org/react-router/-/react-router-6.30.1.tgz", + "integrity": "sha512-X1m21aEmxGXqENEPG3T6u0Th7g0aS4ZmoNynhbs+Cn+q+QGTLt+d5IQ2bHAXKzKcxGJjxACpVbnYQSCRcfxHlQ==", + "license": "MIT", + "dependencies": { + "@remix-run/router": "1.23.0" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "react": ">=16.8" + } + }, + "node_modules/react-router-dom": { + "version": "6.30.1", + "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-6.30.1.tgz", + "integrity": "sha512-llKsgOkZdbPU1Eg3zK8lCn+sjD9wMRZZPuzmdWWX5SUs8OFkN5HnFVC0u5KMeMaC9aoancFI/KoLuKPqN+hxHw==", + "license": "MIT", + "dependencies": { + "@remix-run/router": "1.23.0", + "react-router": "6.30.1" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "react": ">=16.8", + "react-dom": ">=16.8" + } + }, + "node_modules/react-sortable-tree-patch-react-17": { + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/react-sortable-tree-patch-react-17/-/react-sortable-tree-patch-react-17-2.9.0.tgz", + "integrity": "sha512-Ngtdbf78OfjqCxLj7+N+K4zM9d1mQ/tfnUsOfICFDzNa5JHg6AjixAj69ijvz0ykEiA9lYop+0Fm4KCOqCdlKA==", + "deprecated": "Package no longer supported. Contact Support at https://www.npmjs.com/support for more info.", + "license": "MIT", + "dependencies": { + "lodash.isequal": "^4.5.0", + "prop-types": "^15.6.1", + "react": "^17.0.0", + "react-dnd": "^11.1.3", + "react-dnd-html5-backend": "^11.1.3", + "react-dnd-scrollzone-patch-react-17": "^1.0.2", + "react-dom": "^17.0.0", + "react-lifecycles-compat": "^3.0.4", + "react-virtualized": "^9.21.2" + }, + "peerDependencies": { + "react": "^17.0.0", + "react-dnd": "^11.1.3", + "react-dom": "^17.0.0" + } + }, + "node_modules/react-sortable-tree-patch-react-17/node_modules/react": { + "version": "17.0.2", + "resolved": "https://registry.npmjs.org/react/-/react-17.0.2.tgz", + "integrity": "sha512-gnhPt75i/dq/z3/6q/0asP78D0u592D5L1pd7M8P+dck6Fu/jJeL6iVVK23fptSUZj8Vjf++7wXA8UNclGQcbA==", + "license": "MIT", + "dependencies": { + "loose-envify": "^1.1.0", + "object-assign": "^4.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/react-sortable-tree-patch-react-17/node_modules/react-dnd-scrollzone-patch-react-17": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/react-dnd-scrollzone-patch-react-17/-/react-dnd-scrollzone-patch-react-17-1.0.2.tgz", + "integrity": "sha512-Wfhyc/Y/Veim29REBYm8nMmtDB5IwSmPPhXIuabBgsEa1MrVsuOwK9+7LmuP+mGbDOEP/S6G8+5XvDqPlRFK2g==", + "deprecated": "Package no longer supported. Contact Support at https://www.npmjs.com/support for more info.", + "license": "MIT", + "dependencies": { + "hoist-non-react-statics": "^3.1.0", + "lodash.throttle": "^4.0.1", + "prop-types": "^15.5.9", + "raf": "^3.2.0", + "react-display-name": "^0.2.0" + }, + "peerDependencies": { + "react": "^17.0.1", + "react-dnd": "^11.1.3", + "react-dom": "^17.0.1" + } + }, + "node_modules/react-sortable-tree-patch-react-17/node_modules/react-dom": { + "version": "17.0.2", + "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-17.0.2.tgz", + "integrity": "sha512-s4h96KtLDUQlsENhMn1ar8t2bEa+q/YAtj8pPPdIjPDGBDIVNsrD9aXNWqspUe6AzKCIG0C1HZZLqLV7qpOBGA==", + "license": "MIT", + "dependencies": { + "loose-envify": "^1.1.0", + "object-assign": "^4.1.1", + "scheduler": "^0.20.2" + }, + "peerDependencies": { + "react": "17.0.2" + } + }, + "node_modules/react-sortable-tree-patch-react-17/node_modules/scheduler": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.20.2.tgz", + "integrity": "sha512-2eWfGgAqqWFGqtdMmcL5zCMK1U8KlXv8SQFGglL3CEtd0aDVDWgeF/YoCmvln55m5zSk3J/20hTaSBeSObsQDQ==", + "license": "MIT", + "dependencies": { + "loose-envify": "^1.1.0", + "object-assign": "^4.1.1" + } + }, + "node_modules/react-to-print": { + "version": "2.15.1", + "resolved": "https://registry.npmjs.org/react-to-print/-/react-to-print-2.15.1.tgz", + "integrity": "sha512-1foogIFbCpzAVxydkhBiDfMiFYhIMphiagDOfcG4X/EcQ+fBPqJ0rby9Wv/emzY1YLkIQy/rEgOrWQT+rBKhjw==", + "license": "MIT", + "peerDependencies": { + "react": "^15.0.0 || ^16.0.0 || ^17.0.0 || ^18.0.0", + "react-dom": "^15.0.0 || ^16.0.0 || ^17.0.0 || ^18.0.0" + } + }, + "node_modules/react-transition-group": { + "version": "4.4.5", + "resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-4.4.5.tgz", + "integrity": "sha512-pZcd1MCJoiKiBR2NRxeCRg13uCXbydPnmB4EOeRrY7480qNWO8IIgQG6zlDkm6uRMsURXPuKq0GWtiM59a5Q6g==", + "license": "BSD-3-Clause", + "dependencies": { + "@babel/runtime": "^7.5.5", + "dom-helpers": "^5.0.1", + "loose-envify": "^1.4.0", + "prop-types": "^15.6.2" + }, + "peerDependencies": { + "react": ">=16.6.0", + "react-dom": ">=16.6.0" + } + }, + "node_modules/react-virtualized": { + "version": "9.22.6", + "resolved": "https://registry.npmjs.org/react-virtualized/-/react-virtualized-9.22.6.tgz", + "integrity": "sha512-U5j7KuUQt3AaMatlMJ0UJddqSiX+Km0YJxSqbAzIiGw5EmNz0khMyqP2hzgu4+QUtm+QPIrxzUX4raJxmVJnHg==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.7.2", + "clsx": "^1.0.4", + "dom-helpers": "^5.1.3", + "loose-envify": "^1.4.0", + "prop-types": "^15.7.2", + "react-lifecycles-compat": "^3.0.4" + }, + "peerDependencies": { + "react": "^16.3.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", + "react-dom": "^16.3.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" + } + }, + "node_modules/react-virtualized/node_modules/clsx": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/clsx/-/clsx-1.2.1.tgz", + "integrity": "sha512-EcR6r5a8bj6pu3ycsa/E/cKVGuTgZJZdsyUYHOksG/UHIiKfjxzRxYJpyVBwYaQeOvghal9fcc4PidlgzugAQg==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/reactour": { + "version": "1.19.4", + "resolved": "https://registry.npmjs.org/reactour/-/reactour-1.19.4.tgz", + "integrity": "sha512-cMIaUQazGkdXt03m7AXAYXrCdyQl+uvH4nQBGP/oEjIaeSTZqj92C3W3y6doPakIIu21WeoGh1b0hBRKOxIViA==", + "license": "MIT", + "dependencies": { + "@rooks/use-mutation-observer": "4.11.2", + "classnames": "2.3.1", + "focus-outline-manager": "^1.0.2", + "lodash.debounce": "4.0.8", + "prop-types": "15.7.2", + "react-focus-lock": "^2.12.1", + "scroll-smooth": "1.1.1", + "scrollparent": "2.0.1" + }, + "peerDependencies": { + "react": "^16.3.0 || ^17.0.0-0 || ^18.0.0-0", + "react-dom": "^16.3.0 || ^17.0.0-0 || ^18.0.0-0", + "react-is": "^16.8 || ^17.0.0-0 || ^18.0.0-0", + "styled-components": "^4.0.0 || ^5.0.0" + } + }, + "node_modules/reactour/node_modules/prop-types": { + "version": "15.7.2", + "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.7.2.tgz", + "integrity": "sha512-8QQikdH7//R2vurIJSutZ1smHYTcLpRWEOlHnzcWHmBYrOGUysKwSsrC89BCiFj3CbrfJ/nXFdJepOVrY1GCHQ==", + "license": "MIT", + "dependencies": { + "loose-envify": "^1.4.0", + "object-assign": "^4.1.1", + "react-is": "^16.8.1" + } + }, + "node_modules/reactour/node_modules/prop-types/node_modules/react-is": { + "version": "16.13.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", + "license": "MIT" + }, + "node_modules/redent": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/redent/-/redent-3.0.0.tgz", + "integrity": "sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg==", + "license": "MIT", + "dependencies": { + "indent-string": "^4.0.0", + "strip-indent": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/redux": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/redux/-/redux-4.2.1.tgz", + "integrity": "sha512-LAUYz4lc+Do8/g7aeRa8JkyDErK6ekstQaqWQrNRW//MY1TvCEpMtpTWvlQ+FPbWCx+Xixu/6SHt5N0HR+SB4w==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.9.2" + } + }, + "node_modules/redux-persist": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/redux-persist/-/redux-persist-6.0.0.tgz", + "integrity": "sha512-71LLMbUq2r02ng2We9S215LtPu3fY0KgaGE0k8WRgl6RkqxtGfl7HUozz1Dftwsb0D/5mZ8dwAaPbtnzfvbEwQ==", + "license": "MIT", + "peerDependencies": { + "redux": ">4.0.0" + } + }, + "node_modules/redux-thunk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/redux-thunk/-/redux-thunk-2.4.2.tgz", + "integrity": "sha512-+P3TjtnP0k/FEjcBL5FZpoovtvrTNT/UXd4/sluaSyrURlSlhLSzEdfsTBW7WsKB6yPvgd7q/iZPICFjW4o57Q==", + "license": "MIT", + "peerDependencies": { + "redux": "^4" + } + }, + "node_modules/reflect.getprototypeof": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/reflect.getprototypeof/-/reflect.getprototypeof-1.0.10.tgz", + "integrity": "sha512-00o4I+DVrefhv+nX0ulyi3biSHCPDe+yLv5o/p6d/UVlirijB8E16FtfwSAi4g3tcqrQ4lRAqQSoFEZJehYEcw==", + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.9", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0", + "get-intrinsic": "^1.2.7", + "get-proto": "^1.0.1", + "which-builtin-type": "^1.2.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/regenerate": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.2.tgz", + "integrity": "sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A==", + "license": "MIT" + }, + "node_modules/regenerate-unicode-properties": { + "version": "10.2.2", + "resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-10.2.2.tgz", + "integrity": "sha512-m03P+zhBeQd1RGnYxrGyDAPpWX/epKirLrp8e3qevZdVkKtnCrjjWczIbYc8+xd6vcTStVlqfycTx1KR4LOr0g==", + "license": "MIT", + "dependencies": { + "regenerate": "^1.4.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/regexp.prototype.flags": { + "version": "1.5.4", + "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.4.tgz", + "integrity": "sha512-dYqgNSZbDwkaJ2ceRd9ojCGjBq+mOm9LmtXnAnEGyHhN/5R7iDW2TRw3h+o/jCFxus3P2LfWIIiwowAjANm7IA==", + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "define-properties": "^1.2.1", + "es-errors": "^1.3.0", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "set-function-name": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/regexpp": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz", + "integrity": "sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==", + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/mysticatea" + } + }, + "node_modules/regexpu-core": { + "version": "6.4.0", + "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-6.4.0.tgz", + "integrity": "sha512-0ghuzq67LI9bLXpOX/ISfve/Mq33a4aFRzoQYhnnok1JOFpmE/A2TBGkNVenOGEeSBCjIiWcc6MVOG5HEQv0sA==", + "license": "MIT", + "dependencies": { + "regenerate": "^1.4.2", + "regenerate-unicode-properties": "^10.2.2", + "regjsgen": "^0.8.0", + "regjsparser": "^0.13.0", + "unicode-match-property-ecmascript": "^2.0.0", + "unicode-match-property-value-ecmascript": "^2.2.1" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/regjsgen": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.8.0.tgz", + "integrity": "sha512-RvwtGe3d7LvWiDQXeQw8p5asZUmfU1G/l6WbUXeHta7Y2PEIvBTwH6E2EfmYUK8pxcxEdEmaomqyp0vZZ7C+3Q==", + "license": "MIT" + }, + "node_modules/regjsparser": { + "version": "0.13.0", + "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.13.0.tgz", + "integrity": "sha512-NZQZdC5wOE/H3UT28fVGL+ikOZcEzfMGk/c3iN9UGxzWHMa1op7274oyiUVrAG4B2EuFhus8SvkaYnhvW92p9Q==", + "license": "BSD-2-Clause", + "dependencies": { + "jsesc": "~3.1.0" + }, + "bin": { + "regjsparser": "bin/parser" + } + }, + "node_modules/remove-accents": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/remove-accents/-/remove-accents-0.5.0.tgz", + "integrity": "sha512-8g3/Otx1eJaVD12e31UbJj1YzdtVvzH85HV7t+9MJYk/u3XmkOUJ5Ys9wQrf9PCPK8+xn4ymzqYCiZl6QWKn+A==", + "license": "MIT" + }, + "node_modules/require-from-string": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/requireindex": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/requireindex/-/requireindex-1.2.0.tgz", + "integrity": "sha512-L9jEkOi3ASd9PYit2cwRfyppc9NoABujTP8/5gFcbERmo5jUoAKovIC3fsF17pkTnGsrByysqX+Kxd2OTNI1ww==", + "license": "MIT", + "engines": { + "node": ">=0.10.5" + } + }, + "node_modules/reselect": { + "version": "4.1.8", + "resolved": "https://registry.npmjs.org/reselect/-/reselect-4.1.8.tgz", + "integrity": "sha512-ab9EmR80F/zQTMNeneUr4cv+jSwPJgIlvEmVwLerwrWVbpLlBuls9XHzIeTFy4cegU2NHBp3va0LKOzU5qFEYQ==", + "license": "MIT" + }, + "node_modules/resize-observer-polyfill": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/resize-observer-polyfill/-/resize-observer-polyfill-1.5.1.tgz", + "integrity": "sha512-LwZrotdHOo12nQuZlHEmtuXdqGoOD0OhaxopaNFxWzInpEgaLWoVuAMbTzixuosCx2nEG58ngzW3vxdWoxIgdg==", + "license": "MIT" + }, + "node_modules/resolve": { + "version": "1.22.10", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.10.tgz", + "integrity": "sha512-NPRy+/ncIMeDlTAsuqwKIiferiawhefFJtkNSW0qZJEqMEb+qBt/77B/jGeeek+F0uOeN05CDa6HXbbIgtVX4w==", + "license": "MIT", + "dependencies": { + "is-core-module": "^2.16.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/reusify": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.1.0.tgz", + "integrity": "sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==", + "license": "MIT", + "engines": { + "iojs": ">=1.0.0", + "node": ">=0.10.0" + } + }, + "node_modules/rifm": { + "version": "0.12.1", + "resolved": "https://registry.npmjs.org/rifm/-/rifm-0.12.1.tgz", + "integrity": "sha512-OGA1Bitg/dSJtI/c4dh90svzaUPt228kzFsUkJbtA2c964IqEAwWXeL9ZJi86xWv3j5SMqRvGULl7bA6cK0Bvg==", + "license": "MIT", + "peerDependencies": { + "react": ">=16.8" + } + }, + "node_modules/rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "deprecated": "Rimraf versions prior to v4 are no longer supported", + "license": "ISC", + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/rollup": { + "version": "4.52.5", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.52.5.tgz", + "integrity": "sha512-3GuObel8h7Kqdjt0gxkEzaifHTqLVW56Y/bjN7PSQtkKr0w3V/QYSdt6QWYtd7A1xUtYQigtdUfgj1RvWVtorw==", + "license": "MIT", + "dependencies": { + "@types/estree": "1.0.8" + }, + "bin": { + "rollup": "dist/bin/rollup" + }, + "engines": { + "node": ">=18.0.0", + "npm": ">=8.0.0" + }, + "optionalDependencies": { + "@rollup/rollup-android-arm-eabi": "4.52.5", + "@rollup/rollup-android-arm64": "4.52.5", + "@rollup/rollup-darwin-arm64": "4.52.5", + "@rollup/rollup-darwin-x64": "4.52.5", + "@rollup/rollup-freebsd-arm64": "4.52.5", + "@rollup/rollup-freebsd-x64": "4.52.5", + "@rollup/rollup-linux-arm-gnueabihf": "4.52.5", + "@rollup/rollup-linux-arm-musleabihf": "4.52.5", + "@rollup/rollup-linux-arm64-gnu": "4.52.5", + "@rollup/rollup-linux-arm64-musl": "4.52.5", + "@rollup/rollup-linux-loong64-gnu": "4.52.5", + "@rollup/rollup-linux-ppc64-gnu": "4.52.5", + "@rollup/rollup-linux-riscv64-gnu": "4.52.5", + "@rollup/rollup-linux-riscv64-musl": "4.52.5", + "@rollup/rollup-linux-s390x-gnu": "4.52.5", + "@rollup/rollup-linux-x64-gnu": "4.52.5", + "@rollup/rollup-linux-x64-musl": "4.52.5", + "@rollup/rollup-openharmony-arm64": "4.52.5", + "@rollup/rollup-win32-arm64-msvc": "4.52.5", + "@rollup/rollup-win32-ia32-msvc": "4.52.5", + "@rollup/rollup-win32-x64-gnu": "4.52.5", + "@rollup/rollup-win32-x64-msvc": "4.52.5", + "fsevents": "~2.3.2" + } + }, + "node_modules/run-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "dependencies": { + "queue-microtask": "^1.2.2" + } + }, + "node_modules/safe-array-concat": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.1.3.tgz", + "integrity": "sha512-AURm5f0jYEOydBj7VQlVvDrjeFgthDdEF5H1dP+6mNpoXOMo1quQqJ4wvJDyRZ9+pO3kGWoOdmV08cSv2aJV6Q==", + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.2", + "get-intrinsic": "^1.2.6", + "has-symbols": "^1.1.0", + "isarray": "^2.0.5" + }, + "engines": { + "node": ">=0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/safe-push-apply": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/safe-push-apply/-/safe-push-apply-1.0.0.tgz", + "integrity": "sha512-iKE9w/Z7xCzUMIZqdBsp6pEQvwuEebH4vdpjcDWnyzaI6yl6O9FHvVpmGelvEHNsoY6wGblkxR6Zty/h00WiSA==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "isarray": "^2.0.5" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/safe-regex-test": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.1.0.tgz", + "integrity": "sha512-x/+Cz4YrimQxQccJf5mKEbIa1NzeCRNI5Ecl/ekmlYaampdNLPalVyIcCZNNH3MvmqBugV5TMYZXv0ljslUlaw==", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "is-regex": "^1.2.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/scheduler": { + "version": "0.23.2", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.2.tgz", + "integrity": "sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ==", + "license": "MIT", + "dependencies": { + "loose-envify": "^1.1.0" + } + }, + "node_modules/scroll-smooth": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/scroll-smooth/-/scroll-smooth-1.1.1.tgz", + "integrity": "sha512-i9e/hJf0ODPEsy+AubE0zES6xdOuIvtebe5MvdSI1lB4t91k+O+8kV15CYfPN0yPH4j4hZUoKM3rVaPVcmiOoQ==", + "license": "MIT" + }, + "node_modules/scrollparent": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/scrollparent/-/scrollparent-2.0.1.tgz", + "integrity": "sha512-HSdN78VMvFCSGCkh0oYX/tY4R3P1DW61f8+TeZZ4j2VLgfwvw0bpRSOv4PCVKisktIwbzHCfZsx+rLbbDBqIBA==", + "license": "ISC" + }, + "node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/serialize-javascript": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.2.tgz", + "integrity": "sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==", + "license": "BSD-3-Clause", + "dependencies": { + "randombytes": "^2.1.0" + } + }, + "node_modules/set-function-length": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", + "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==", + "license": "MIT", + "dependencies": { + "define-data-property": "^1.1.4", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/set-function-name": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/set-function-name/-/set-function-name-2.0.2.tgz", + "integrity": "sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==", + "license": "MIT", + "dependencies": { + "define-data-property": "^1.1.4", + "es-errors": "^1.3.0", + "functions-have-names": "^1.2.3", + "has-property-descriptors": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/set-proto": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/set-proto/-/set-proto-1.0.0.tgz", + "integrity": "sha512-RJRdvCo6IAnPdsvP/7m6bsQqNnn1FCBX5ZNtFL98MmFF/4xAIJTIg1YbHW5DC2W5SKZanrC6i4HsJqlajw/dZw==", + "license": "MIT", + "dependencies": { + "dunder-proto": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "license": "MIT", + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/side-channel": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz", + "integrity": "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "object-inspect": "^1.13.3", + "side-channel-list": "^1.0.0", + "side-channel-map": "^1.0.1", + "side-channel-weakmap": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-list": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.0.tgz", + "integrity": "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "object-inspect": "^1.13.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-map": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/side-channel-map/-/side-channel-map-1.0.1.tgz", + "integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.5", + "object-inspect": "^1.13.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-weakmap": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz", + "integrity": "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.5", + "object-inspect": "^1.13.3", + "side-channel-map": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/siginfo": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/siginfo/-/siginfo-2.0.0.tgz", + "integrity": "sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==", + "license": "ISC" + }, + "node_modules/size-sensor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/size-sensor/-/size-sensor-1.0.2.tgz", + "integrity": "sha512-2NCmWxY7A9pYKGXNBfteo4hy14gWu47rg5692peVMst6lQLPKrVjhY+UTEsPI5ceFRJSl3gVgMYaUi/hKuaiKw==", + "license": "ISC" + }, + "node_modules/slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/smob": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/smob/-/smob-1.5.0.tgz", + "integrity": "sha512-g6T+p7QO8npa+/hNx9ohv1E5pVCmWrVCUzUXJyLdMmftX6ER0oiWY/w9knEonLpnOp6b6FenKnMfR8gqwWdwig==", + "license": "MIT" + }, + "node_modules/source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==", + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/source-map-js": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", + "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/source-map-support": { + "version": "0.5.21", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", + "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", + "license": "MIT", + "dependencies": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, + "node_modules/source-map-support/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/sourcemap-codec": { + "version": "1.4.8", + "resolved": "https://registry.npmjs.org/sourcemap-codec/-/sourcemap-codec-1.4.8.tgz", + "integrity": "sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==", + "deprecated": "Please use @jridgewell/sourcemap-codec instead", + "license": "MIT" + }, + "node_modules/stack-utils": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.6.tgz", + "integrity": "sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ==", + "license": "MIT", + "dependencies": { + "escape-string-regexp": "^2.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/stack-utils/node_modules/escape-string-regexp": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", + "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/stackback": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/stackback/-/stackback-0.0.2.tgz", + "integrity": "sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==", + "license": "MIT" + }, + "node_modules/std-env": { + "version": "3.10.0", + "resolved": "https://registry.npmjs.org/std-env/-/std-env-3.10.0.tgz", + "integrity": "sha512-5GS12FdOZNliM5mAOxFRg7Ir0pWz8MdpYm6AY6VPkGpbA7ZzmbzNcBJQ0GPvvyWgcY7QAhCgf9Uy89I03faLkg==", + "license": "MIT" + }, + "node_modules/stop-iteration-iterator": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/stop-iteration-iterator/-/stop-iteration-iterator-1.1.0.tgz", + "integrity": "sha512-eLoXW/DHyl62zxY4SCaIgnRhuMr6ri4juEYARS8E6sCEqzKpOiE521Ucofdx+KnDZl5xmvGYaaKCk5FEOxJCoQ==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "internal-slot": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/string.prototype.matchall": { + "version": "4.0.12", + "resolved": "https://registry.npmjs.org/string.prototype.matchall/-/string.prototype.matchall-4.0.12.tgz", + "integrity": "sha512-6CC9uyBL+/48dYizRf7H7VAYCMCNTBeM78x/VTUe9bFEaxBepPJDa1Ow99LqI/1yF7kuy7Q3cQsYMrcjGUcskA==", + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.6", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0", + "get-intrinsic": "^1.2.6", + "gopd": "^1.2.0", + "has-symbols": "^1.1.0", + "internal-slot": "^1.1.0", + "regexp.prototype.flags": "^1.5.3", + "set-function-name": "^2.0.2", + "side-channel": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/string.prototype.repeat": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/string.prototype.repeat/-/string.prototype.repeat-1.0.0.tgz", + "integrity": "sha512-0u/TldDbKD8bFCQ/4f5+mNRrXwZ8hg2w7ZR8wa16e8z9XpePWl3eGEcUD0OXpEH/VJH/2G3gjUtR3ZOiBe2S/w==", + "dev": true, + "license": "MIT", + "dependencies": { + "define-properties": "^1.1.3", + "es-abstract": "^1.17.5" + } + }, + "node_modules/string.prototype.trim": { + "version": "1.2.10", + "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.10.tgz", + "integrity": "sha512-Rs66F0P/1kedk5lyYyH9uBzuiI/kNRmwJAR9quK6VOtIpZ2G+hMZd+HQbbv25MgCA6gEffoMZYxlTod4WcdrKA==", + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.2", + "define-data-property": "^1.1.4", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.5", + "es-object-atoms": "^1.0.0", + "has-property-descriptors": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/string.prototype.trimend": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.9.tgz", + "integrity": "sha512-G7Ok5C6E/j4SGfyLCloXTrngQIQU3PWtXGst3yM7Bea9FRURf1S42ZHlZZtsNque2FN2PoUhfZXYLNWwEr4dLQ==", + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.2", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/string.prototype.trimstart": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.8.tgz", + "integrity": "sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg==", + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/stringify-object": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/stringify-object/-/stringify-object-3.3.0.tgz", + "integrity": "sha512-rHqiFh1elqCQ9WPLIC8I0Q/g/wj5J1eMkyoiD6eoQApWHP0FtlK7rqnhmabL5VUY9JQCcqwwvlOaSuutekgyrw==", + "license": "BSD-2-Clause", + "dependencies": { + "get-own-enumerable-property-symbols": "^3.0.0", + "is-obj": "^1.0.1", + "is-regexp": "^1.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-comments": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/strip-comments/-/strip-comments-2.0.1.tgz", + "integrity": "sha512-ZprKx+bBLXv067WTCALv8SSz5l2+XhpYCsVtSqlMnkAXMWDq+/ekVbl1ghqP9rUHTzv6sm/DwCOiYutU/yp1fw==", + "license": "MIT", + "engines": { + "node": ">=10" + } + }, + "node_modules/strip-indent": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-3.0.0.tgz", + "integrity": "sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==", + "license": "MIT", + "dependencies": { + "min-indent": "^1.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/styled-components": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/styled-components/-/styled-components-4.4.1.tgz", + "integrity": "sha512-RNqj14kYzw++6Sr38n7197xG33ipEOktGElty4I70IKzQF1jzaD1U4xQ+Ny/i03UUhHlC5NWEO+d8olRCDji6g==", + "hasInstallScript": true, + "license": "MIT", + "dependencies": { + "@babel/helper-module-imports": "^7.0.0", + "@babel/traverse": "^7.0.0", + "@emotion/is-prop-valid": "^0.8.1", + "@emotion/unitless": "^0.7.0", + "babel-plugin-styled-components": ">= 1", + "css-to-react-native": "^2.2.2", + "memoize-one": "^5.0.0", + "merge-anything": "^2.2.4", + "prop-types": "^15.5.4", + "react-is": "^16.6.0", + "stylis": "^3.5.0", + "stylis-rule-sheet": "^0.0.10", + "supports-color": "^5.5.0" + }, + "peerDependencies": { + "react": ">= 16.3.0", + "react-dom": ">= 16.3.0" + } + }, + "node_modules/styled-components/node_modules/@emotion/is-prop-valid": { + "version": "0.8.8", + "resolved": "https://registry.npmjs.org/@emotion/is-prop-valid/-/is-prop-valid-0.8.8.tgz", + "integrity": "sha512-u5WtneEAr5IDG2Wv65yhunPSMLIpuKsbuOktRojfrEiEvRyC85LgPMZI63cr7NUqT8ZIGdSVg8ZKGxIug4lXcA==", + "license": "MIT", + "dependencies": { + "@emotion/memoize": "0.7.4" + } + }, + "node_modules/styled-components/node_modules/@emotion/memoize": { + "version": "0.7.4", + "resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.7.4.tgz", + "integrity": "sha512-Ja/Vfqe3HpuzRsG1oBtWTHk2PGZ7GR+2Vz5iYGelAw8dx32K0y7PjVuxK6z1nMpZOqAFsRUPCkK1YjJ56qJlgw==", + "license": "MIT" + }, + "node_modules/styled-components/node_modules/@emotion/unitless": { + "version": "0.7.5", + "resolved": "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.7.5.tgz", + "integrity": "sha512-OWORNpfjMsSSUBVrRBVGECkhWcULOAJz9ZW8uK9qgxD+87M7jHRcvh/A96XXNhXTLmKcoYSQtBEX7lHMO7YRwg==", + "license": "MIT" + }, + "node_modules/styled-components/node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/styled-components/node_modules/react-is": { + "version": "16.13.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", + "license": "MIT" + }, + "node_modules/styled-components/node_modules/stylis": { + "version": "3.5.4", + "resolved": "https://registry.npmjs.org/stylis/-/stylis-3.5.4.tgz", + "integrity": "sha512-8/3pSmthWM7lsPBKv7NXkzn2Uc9W7NotcwGNpJaa3k7WMM1XDCA4MgT5k/8BIexd5ydZdboXtU90XH9Ec4Bv/Q==", + "license": "MIT" + }, + "node_modules/styled-components/node_modules/stylis-rule-sheet": { + "version": "0.0.10", + "resolved": "https://registry.npmjs.org/stylis-rule-sheet/-/stylis-rule-sheet-0.0.10.tgz", + "integrity": "sha512-nTbZoaqoBnmK+ptANthb10ZRZOGC+EmTLLUxeYIuHNkEKcmKgXX1XWKkUBT2Ac4es3NybooPe0SmvKdhKJZAuw==", + "license": "MIT", + "peerDependencies": { + "stylis": "^3.5.0" + } + }, + "node_modules/styled-components/node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "license": "MIT", + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/stylis": { + "version": "4.3.6", + "resolved": "https://registry.npmjs.org/stylis/-/stylis-4.3.6.tgz", + "integrity": "sha512-yQ3rwFWRfwNUY7H5vpU0wfdkNSnvnJinhF9830Swlaxl03zsOjCfmX0ugac+3LtK0lYSgwL/KXc8oYL3mG4YFQ==", + "license": "MIT" + }, + "node_modules/stylis-plugin-rtl": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/stylis-plugin-rtl/-/stylis-plugin-rtl-2.0.2.tgz", + "integrity": "sha512-3xKsCTUs/Ab6Kp/NjwTEvcS6eI2ZbIORJssvw2S+H20DlUIp8ZC3drQ/0V3G5P559A4xGwA+XV6ZSJHhEoRvhw==", + "license": "MIT", + "dependencies": { + "cssjanus": "^2.0.1" + }, + "peerDependencies": { + "stylis": "4.x" + } + }, + "node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/temp-dir": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/temp-dir/-/temp-dir-2.0.0.tgz", + "integrity": "sha512-aoBAniQmmwtcKp/7BzsH8Cxzv8OL736p7v1ihGb5e9DJ9kTwGWHrQrVB5+lfVDzfGrdRzXch+ig7LHaY1JTOrg==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/tempy": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/tempy/-/tempy-0.6.0.tgz", + "integrity": "sha512-G13vtMYPT/J8A4X2SjdtBTphZlrp1gKv6hZiOjw14RCWg6GbHuQBGtjlx75xLbYV/wEc0D7G5K4rxKP/cXk8Bw==", + "license": "MIT", + "dependencies": { + "is-stream": "^2.0.0", + "temp-dir": "^2.0.0", + "type-fest": "^0.16.0", + "unique-string": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/tempy/node_modules/type-fest": { + "version": "0.16.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.16.0.tgz", + "integrity": "sha512-eaBzG6MxNzEn9kiwvtre90cXaNLkmadMWa1zQMs3XORCXNbsH/OewwbxC5ia9dCxIxnTAsSxXJaa/p5y8DlvJg==", + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/terser": { + "version": "5.44.0", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.44.0.tgz", + "integrity": "sha512-nIVck8DK+GM/0Frwd+nIhZ84pR/BX7rmXMfYwyg+Sri5oGVE99/E3KvXqpC2xHFxyqXyGHTKBSioxxplrO4I4w==", + "license": "BSD-2-Clause", + "dependencies": { + "@jridgewell/source-map": "^0.3.3", + "acorn": "^8.15.0", + "commander": "^2.20.0", + "source-map-support": "~0.5.20" + }, + "bin": { + "terser": "bin/terser" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/text-segmentation": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/text-segmentation/-/text-segmentation-1.0.3.tgz", + "integrity": "sha512-iOiPUo/BGnZ6+54OsWxZidGCsdU8YbE4PSpdPinp7DeMtUJNJBoJ/ouUSTJjHkh1KntHaltHl/gDs2FC4i5+Nw==", + "license": "MIT", + "dependencies": { + "utrie": "^1.0.2" + } + }, + "node_modules/text-table": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", + "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", + "license": "MIT" + }, + "node_modules/tiny-warning": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/tiny-warning/-/tiny-warning-1.0.3.tgz", + "integrity": "sha512-lBN9zLN/oAf68o3zNXYrdCt1kP8WsiGW8Oo2ka41b2IM5JL/S1CTyX1rW0mb/zSuJun0ZUrDxx4sqvYS2FWzPA==", + "license": "MIT" + }, + "node_modules/tinybench": { + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/tinybench/-/tinybench-2.9.0.tgz", + "integrity": "sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==", + "license": "MIT" + }, + "node_modules/tinyexec": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/tinyexec/-/tinyexec-0.3.2.tgz", + "integrity": "sha512-KQQR9yN7R5+OSwaK0XQoj22pwHoTlgYqmUscPYoknOoWCWfj/5/ABTMRi69FrKU5ffPVh5QcFikpWJI/P1ocHA==", + "license": "MIT" + }, + "node_modules/tinyglobby": { + "version": "0.2.15", + "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.15.tgz", + "integrity": "sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==", + "license": "MIT", + "dependencies": { + "fdir": "^6.5.0", + "picomatch": "^4.0.3" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/SuperchupuDev" + } + }, + "node_modules/tinypool": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/tinypool/-/tinypool-1.1.1.tgz", + "integrity": "sha512-Zba82s87IFq9A9XmjiX5uZA/ARWDrB03OHlq+Vw1fSdt0I+4/Kutwy8BP4Y/y/aORMo61FQ0vIb5j44vSo5Pkg==", + "license": "MIT", + "engines": { + "node": "^18.0.0 || >=20.0.0" + } + }, + "node_modules/tinyrainbow": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/tinyrainbow/-/tinyrainbow-1.2.0.tgz", + "integrity": "sha512-weEDEq7Z5eTHPDh4xjX789+fHfF+P8boiFB+0vbWzpbnbsEr/GRaohi/uMKxg8RZMXnl1ItAi/IUHWMsjDV7kQ==", + "license": "MIT", + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/tinyspy": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/tinyspy/-/tinyspy-3.0.2.tgz", + "integrity": "sha512-n1cw8k1k0x4pgA2+9XrOkFydTerNcJ1zWCO5Nn9scWHTD+5tp8dghT2x1uduQePZTZgd3Tupf+x9BxJjeJi77Q==", + "license": "MIT", + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "license": "MIT", + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/toposort": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/toposort/-/toposort-2.0.2.tgz", + "integrity": "sha512-0a5EOkAUp8D4moMi2W8ZF8jcga7BgZd91O/yabJCFY8az+XSzeGyTKs0Aoo897iV1Nj6guFq8orWDS96z91oGg==", + "license": "MIT" + }, + "node_modules/tr46": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-1.0.1.tgz", + "integrity": "sha512-dTpowEjclQ7Kgx5SdBkqRzVhERQXov8/l9Ft9dVM9fmg0W0KQSVaXX9T4i6twCPNtYiZM53lpSSUAwJbFPOHxA==", + "license": "MIT", + "dependencies": { + "punycode": "^2.1.0" + } + }, + "node_modules/ts-api-utils": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-2.1.0.tgz", + "integrity": "sha512-CUgTZL1irw8u29bzrOD/nH85jqyc74D6SshFgujOIA7osm2Rz7dYH77agkx7H4FBNxDq7Cjf+IjaX/8zwFW+ZQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18.12" + }, + "peerDependencies": { + "typescript": ">=4.8.4" + } + }, + "node_modules/tslib": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.0.tgz", + "integrity": "sha512-N82ooyxVNm6h1riLCoyS9e3fuJ3AMG2zIZs2Gd1ATcSFjSA23Q0fzjjZeh0jbJvWVDZ0cJT8yaNNaaXHzueNjg==", + "license": "0BSD" + }, + "node_modules/tss-react": { + "version": "3.7.1", + "resolved": "https://registry.npmjs.org/tss-react/-/tss-react-3.7.1.tgz", + "integrity": "sha512-dfWUoxBlKZfIG9UC1A2h02OmcE/Ni0itCmmZu94E9g+KyBhKMHKcsKvUm0bNlRqTmYjXiCgPJDmj5fyc8CSrLg==", + "license": "MIT", + "dependencies": { + "@emotion/cache": "*", + "@emotion/serialize": "*", + "@emotion/utils": "*" + }, + "peerDependencies": { + "@emotion/react": "^11.4.1", + "@emotion/server": "^11.4.0", + "react": "^16.8.0 || ^17.0.2 || ^18.0.0" + }, + "peerDependenciesMeta": { + "@emotion/server": { + "optional": true + } + } + }, + "node_modules/type-check": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", + "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", + "license": "MIT", + "dependencies": { + "prelude-ls": "^1.2.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/type-fest": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/typed-array-buffer": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.3.tgz", + "integrity": "sha512-nAYYwfY3qnzX30IkA6AQZjVbtK6duGontcQm1WSG1MD94YLqK0515GNApXkoxKOWMusVssAHWLh9SeaoefYFGw==", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "es-errors": "^1.3.0", + "is-typed-array": "^1.1.14" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/typed-array-byte-length": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/typed-array-byte-length/-/typed-array-byte-length-1.0.3.tgz", + "integrity": "sha512-BaXgOuIxz8n8pIq3e7Atg/7s+DpiYrxn4vdot3w9KbnBhcRQq6o3xemQdIfynqSeXeDrF32x+WvfzmOjPiY9lg==", + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "for-each": "^0.3.3", + "gopd": "^1.2.0", + "has-proto": "^1.2.0", + "is-typed-array": "^1.1.14" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/typed-array-byte-offset": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/typed-array-byte-offset/-/typed-array-byte-offset-1.0.4.tgz", + "integrity": "sha512-bTlAFB/FBYMcuX81gbL4OcpH5PmlFHqlCCpAl8AlEzMz5k53oNDvN8p1PNOWLEmI2x4orp3raOFB51tv9X+MFQ==", + "license": "MIT", + "dependencies": { + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.8", + "for-each": "^0.3.3", + "gopd": "^1.2.0", + "has-proto": "^1.2.0", + "is-typed-array": "^1.1.15", + "reflect.getprototypeof": "^1.0.9" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/typed-array-length": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.7.tgz", + "integrity": "sha512-3KS2b+kL7fsuk/eJZ7EQdnEmQoaho/r6KUef7hxvltNA5DR8NAUM+8wJMbJyZ4G9/7i3v5zPBIMN5aybAh2/Jg==", + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "for-each": "^0.3.3", + "gopd": "^1.0.1", + "is-typed-array": "^1.1.13", + "possible-typed-array-names": "^1.0.0", + "reflect.getprototypeof": "^1.0.6" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/typescript": { + "version": "5.9.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz", + "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==", + "dev": true, + "license": "Apache-2.0", + "peer": true, + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/unbox-primitive": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.1.0.tgz", + "integrity": "sha512-nWJ91DjeOkej/TA8pXQ3myruKpKEYgqvpw9lz4OPHj/NWFNluYrjbz9j01CJ8yKQd2g4jFoOkINCTW2I5LEEyw==", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "has-bigints": "^1.0.2", + "has-symbols": "^1.1.0", + "which-boxed-primitive": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/undici-types": { + "version": "7.14.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.14.0.tgz", + "integrity": "sha512-QQiYxHuyZ9gQUIrmPo3IA+hUl4KYk8uSA7cHrcKd/l3p1OTpZcM0Tbp9x7FAtXdAYhlasd60ncPpgu6ihG6TOA==", + "license": "MIT" + }, + "node_modules/unicode-canonical-property-names-ecmascript": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-2.0.1.tgz", + "integrity": "sha512-dA8WbNeb2a6oQzAQ55YlT5vQAWGV9WXOsi3SskE3bcCdM0P4SDd+24zS/OCacdRq5BkdsRj9q3Pg6YyQoxIGqg==", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/unicode-match-property-ecmascript": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-2.0.0.tgz", + "integrity": "sha512-5kaZCrbp5mmbz5ulBkDkbY0SsPOjKqVS35VpL9ulMPfSl0J0Xsm+9Evphv9CoIZFwre7aJoa94AY6seMKGVN5Q==", + "license": "MIT", + "dependencies": { + "unicode-canonical-property-names-ecmascript": "^2.0.0", + "unicode-property-aliases-ecmascript": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/unicode-match-property-value-ecmascript": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-2.2.1.tgz", + "integrity": "sha512-JQ84qTuMg4nVkx8ga4A16a1epI9H6uTXAknqxkGF/aFfRLw1xC/Bp24HNLaZhHSkWd3+84t8iXnp1J0kYcZHhg==", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/unicode-property-aliases-ecmascript": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-2.2.0.tgz", + "integrity": "sha512-hpbDzxUY9BFwX+UeBnxv3Sh1q7HFxj48DTmXchNgRa46lO8uj3/1iEn3MiNUYTg1g9ctIqXCCERn8gYZhHC5lQ==", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/unique-string": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unique-string/-/unique-string-2.0.0.tgz", + "integrity": "sha512-uNaeirEPvpZWSgzwsPGtU2zVSTrn/8L5q/IexZmH0eH6SA73CmAA5U4GwORTxQAZs95TAXLNqeLoPPNO5gZfWg==", + "license": "MIT", + "dependencies": { + "crypto-random-string": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/universalify": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", + "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", + "license": "MIT", + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/upath": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/upath/-/upath-1.2.0.tgz", + "integrity": "sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg==", + "license": "MIT", + "engines": { + "node": ">=4", + "yarn": "*" + } + }, + "node_modules/update-browserslist-db": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.3.tgz", + "integrity": "sha512-UxhIZQ+QInVdunkDAaiazvvT/+fXL5Osr0JZlJulepYu6Jd7qJtDZjlur0emRlT71EN3ScPoE7gvsuIKKNavKw==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "escalade": "^3.2.0", + "picocolors": "^1.1.1" + }, + "bin": { + "update-browserslist-db": "cli.js" + }, + "peerDependencies": { + "browserslist": ">= 4.21.0" + } + }, + "node_modules/uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "license": "BSD-2-Clause", + "dependencies": { + "punycode": "^2.1.0" + } + }, + "node_modules/use-callback-ref": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/use-callback-ref/-/use-callback-ref-1.3.3.tgz", + "integrity": "sha512-jQL3lRnocaFtu3V00JToYz/4QkNWswxijDaCVNZRiRTO3HQDLsdu1ZtmIUvV4yPp+rvWm5j0y0TG/S61cuijTg==", + "license": "MIT", + "dependencies": { + "tslib": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/use-react-screenshot": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/use-react-screenshot/-/use-react-screenshot-3.0.0.tgz", + "integrity": "sha512-82+zsJgNWEUsUR7lslLIXMw9BW+xic+epn5Dl2ziedgsP9bz0HM0hfx3E71Kkv1U7F6Hyi4E/jMxuxJPLdpHcg==", + "license": "MIT", + "engines": { + "node": ">=8", + "npm": ">=5" + }, + "peerDependencies": { + "html2canvas": "^1.3.3", + "react": "^17.0.2" + } + }, + "node_modules/use-sidecar": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/use-sidecar/-/use-sidecar-1.1.3.tgz", + "integrity": "sha512-Fedw0aZvkhynoPYlA5WXrMCAMm+nSWdZt6lzJQ7Ok8S6Q+VsHmHpRWndVRJ8Be0ZbkfPc5LRYH+5XrzXcEeLRQ==", + "license": "MIT", + "dependencies": { + "detect-node-es": "^1.1.0", + "tslib": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/use-sync-external-store": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.6.0.tgz", + "integrity": "sha512-Pp6GSwGP/NrPIrxVFAIkOQeyw8lFenOHijQWkUTrDvrF4ALqylP2C/KCkeS9dpUM3KvYRQhna5vt7IL95+ZQ9w==", + "license": "MIT", + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" + } + }, + "node_modules/utrie": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/utrie/-/utrie-1.0.2.tgz", + "integrity": "sha512-1MLa5ouZiOmQzUbjbu9VmjLzn1QLXBhwpUa7kdLUQK+KQ5KA9I1vk5U4YHe/X2Ch7PYnJfWuWT+VbuxbGwljhw==", + "license": "MIT", + "dependencies": { + "base64-arraybuffer": "^1.0.2" + } + }, + "node_modules/v8-compile-cache": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.4.0.tgz", + "integrity": "sha512-ocyWc3bAHBB/guyqJQVI5o4BZkPhznPYUG2ea80Gond/BgNWpap8TOmLSeeQG7bnh2KMISxskdADG59j7zruhw==", + "license": "MIT" + }, + "node_modules/vite": { + "version": "5.4.20", + "resolved": "https://registry.npmjs.org/vite/-/vite-5.4.20.tgz", + "integrity": "sha512-j3lYzGC3P+B5Yfy/pfKNgVEg4+UtcIJcVRt2cDjIOmhLourAqPqf8P7acgxeiSgUB7E3p2P8/3gNIgDLpwzs4g==", + "license": "MIT", + "dependencies": { + "esbuild": "^0.21.3", + "postcss": "^8.4.43", + "rollup": "^4.20.0" + }, + "bin": { + "vite": "bin/vite.js" + }, + "engines": { + "node": "^18.0.0 || >=20.0.0" + }, + "funding": { + "url": "https://github.com/vitejs/vite?sponsor=1" + }, + "optionalDependencies": { + "fsevents": "~2.3.3" + }, + "peerDependencies": { + "@types/node": "^18.0.0 || >=20.0.0", + "less": "*", + "lightningcss": "^1.21.0", + "sass": "*", + "sass-embedded": "*", + "stylus": "*", + "sugarss": "*", + "terser": "^5.4.0" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, + "less": { + "optional": true + }, + "lightningcss": { + "optional": true + }, + "sass": { + "optional": true + }, + "sass-embedded": { + "optional": true + }, + "stylus": { + "optional": true + }, + "sugarss": { + "optional": true + }, + "terser": { + "optional": true + } + } + }, + "node_modules/vite-node": { + "version": "2.1.9", + "resolved": "https://registry.npmjs.org/vite-node/-/vite-node-2.1.9.tgz", + "integrity": "sha512-AM9aQ/IPrW/6ENLQg3AGY4K1N2TGZdR5e4gu/MmmR2xR3Ll1+dib+nook92g4TV3PXVyeyxdWwtaCAiUL0hMxA==", + "license": "MIT", + "dependencies": { + "cac": "^6.7.14", + "debug": "^4.3.7", + "es-module-lexer": "^1.5.4", + "pathe": "^1.1.2", + "vite": "^5.0.0" + }, + "bin": { + "vite-node": "vite-node.mjs" + }, + "engines": { + "node": "^18.0.0 || >=20.0.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/vite-plugin-pwa": { + "version": "0.20.5", + "resolved": "https://registry.npmjs.org/vite-plugin-pwa/-/vite-plugin-pwa-0.20.5.tgz", + "integrity": "sha512-aweuI/6G6n4C5Inn0vwHumElU/UEpNuO+9iZzwPZGTCH87TeZ6YFMrEY6ZUBQdIHHlhTsbMDryFARcSuOdsz9Q==", + "license": "MIT", + "dependencies": { + "debug": "^4.3.6", + "pretty-bytes": "^6.1.1", + "tinyglobby": "^0.2.0", + "workbox-build": "^7.1.0", + "workbox-window": "^7.1.0" + }, + "engines": { + "node": ">=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + }, + "peerDependencies": { + "@vite-pwa/assets-generator": "^0.2.6", + "vite": "^3.1.0 || ^4.0.0 || ^5.0.0", + "workbox-build": "^7.1.0", + "workbox-window": "^7.1.0" + }, + "peerDependenciesMeta": { + "@vite-pwa/assets-generator": { + "optional": true + } + } + }, + "node_modules/vitest": { + "version": "2.1.9", + "resolved": "https://registry.npmjs.org/vitest/-/vitest-2.1.9.tgz", + "integrity": "sha512-MSmPM9REYqDGBI8439mA4mWhV5sKmDlBKWIYbA3lRb2PTHACE0mgKwA8yQ2xq9vxDTuk4iPrECBAEW2aoFXY0Q==", + "license": "MIT", + "dependencies": { + "@vitest/expect": "2.1.9", + "@vitest/mocker": "2.1.9", + "@vitest/pretty-format": "^2.1.9", + "@vitest/runner": "2.1.9", + "@vitest/snapshot": "2.1.9", + "@vitest/spy": "2.1.9", + "@vitest/utils": "2.1.9", + "chai": "^5.1.2", + "debug": "^4.3.7", + "expect-type": "^1.1.0", + "magic-string": "^0.30.12", + "pathe": "^1.1.2", + "std-env": "^3.8.0", + "tinybench": "^2.9.0", + "tinyexec": "^0.3.1", + "tinypool": "^1.0.1", + "tinyrainbow": "^1.2.0", + "vite": "^5.0.0", + "vite-node": "2.1.9", + "why-is-node-running": "^2.3.0" + }, + "bin": { + "vitest": "vitest.mjs" + }, + "engines": { + "node": "^18.0.0 || >=20.0.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + }, + "peerDependencies": { + "@edge-runtime/vm": "*", + "@types/node": "^18.0.0 || >=20.0.0", + "@vitest/browser": "2.1.9", + "@vitest/ui": "2.1.9", + "happy-dom": "*", + "jsdom": "*" + }, + "peerDependenciesMeta": { + "@edge-runtime/vm": { + "optional": true + }, + "@types/node": { + "optional": true + }, + "@vitest/browser": { + "optional": true + }, + "@vitest/ui": { + "optional": true + }, + "happy-dom": { + "optional": true + }, + "jsdom": { + "optional": true + } + } + }, + "node_modules/web-vitals": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/web-vitals/-/web-vitals-2.1.4.tgz", + "integrity": "sha512-sVWcwhU5mX6crfI5Vd2dC4qchyTqxV8URinzt25XqVh+bHEPGH4C3NPrNionCP7Obx59wrYEbNlw4Z8sjALzZg==", + "license": "Apache-2.0" + }, + "node_modules/webidl-conversions": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-4.0.2.tgz", + "integrity": "sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg==", + "license": "BSD-2-Clause" + }, + "node_modules/whatwg-url": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-7.1.0.tgz", + "integrity": "sha512-WUu7Rg1DroM7oQvGWfOiAK21n74Gg+T4elXEQYkOhtyLeWiJFoOGLXPKI/9gzIie9CtwVLm8wtw6YJdKyxSjeg==", + "license": "MIT", + "dependencies": { + "lodash.sortby": "^4.7.0", + "tr46": "^1.0.1", + "webidl-conversions": "^4.0.2" + } + }, + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "license": "ISC", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/which-boxed-primitive": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.1.1.tgz", + "integrity": "sha512-TbX3mj8n0odCBFVlY8AxkqcHASw3L60jIuF8jFP78az3C2YhmGvqbHBpAjTRH2/xqYunrJ9g1jSyjCjpoWzIAA==", + "license": "MIT", + "dependencies": { + "is-bigint": "^1.1.0", + "is-boolean-object": "^1.2.1", + "is-number-object": "^1.1.1", + "is-string": "^1.1.1", + "is-symbol": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/which-builtin-type": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/which-builtin-type/-/which-builtin-type-1.2.1.tgz", + "integrity": "sha512-6iBczoX+kDQ7a3+YJBnh3T+KZRxM/iYNPXicqk66/Qfm1b93iu+yOImkg0zHbj5LNOcNv1TEADiZ0xa34B4q6Q==", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "function.prototype.name": "^1.1.6", + "has-tostringtag": "^1.0.2", + "is-async-function": "^2.0.0", + "is-date-object": "^1.1.0", + "is-finalizationregistry": "^1.1.0", + "is-generator-function": "^1.0.10", + "is-regex": "^1.2.1", + "is-weakref": "^1.0.2", + "isarray": "^2.0.5", + "which-boxed-primitive": "^1.1.0", + "which-collection": "^1.0.2", + "which-typed-array": "^1.1.16" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/which-collection": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/which-collection/-/which-collection-1.0.2.tgz", + "integrity": "sha512-K4jVyjnBdgvc86Y6BkaLZEN933SwYOuBFkdmBu9ZfkcAbdVbpITnDmjvZ/aQjRXQrv5EPkTnD1s39GiiqbngCw==", + "license": "MIT", + "dependencies": { + "is-map": "^2.0.3", + "is-set": "^2.0.3", + "is-weakmap": "^2.0.2", + "is-weakset": "^2.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/which-typed-array": { + "version": "1.1.19", + "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.19.tgz", + "integrity": "sha512-rEvr90Bck4WZt9HHFC4DJMsjvu7x+r6bImz0/BrbWb7A2djJ8hnZMrWnHo9F8ssv0OMErasDhftrfROTyqSDrw==", + "license": "MIT", + "dependencies": { + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.8", + "call-bound": "^1.0.4", + "for-each": "^0.3.5", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/why-is-node-running": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/why-is-node-running/-/why-is-node-running-2.3.0.tgz", + "integrity": "sha512-hUrmaWBdVDcxvYqnyh09zunKzROWjbZTiNy8dBEjkS7ehEDQibXJ7XvlmtbwuTclUiIyN+CyXQD4Vmko8fNm8w==", + "license": "MIT", + "dependencies": { + "siginfo": "^2.0.0", + "stackback": "0.0.2" + }, + "bin": { + "why-is-node-running": "cli.js" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/word-wrap": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", + "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/workbox-background-sync": { + "version": "6.6.1", + "resolved": "https://registry.npmjs.org/workbox-background-sync/-/workbox-background-sync-6.6.1.tgz", + "integrity": "sha512-trJd3ovpWCvzu4sW0E8rV3FUyIcC0W8G+AZ+VcqzzA890AsWZlUGOTSxIMmIHVusUw/FDq1HFWfy/kC/WTRqSg==", + "deprecated": "this package has been deprecated", + "license": "MIT", + "dependencies": { + "idb": "^7.0.1", + "workbox-core": "6.6.1" + } + }, + "node_modules/workbox-background-sync/node_modules/workbox-core": { + "version": "6.6.1", + "resolved": "https://registry.npmjs.org/workbox-core/-/workbox-core-6.6.1.tgz", + "integrity": "sha512-ZrGBXjjaJLqzVothoE12qTbVnOAjFrHDXpZe7coCb6q65qI/59rDLwuFMO4PcZ7jcbxY+0+NhUVztzR/CbjEFw==", + "deprecated": "this package has been deprecated", + "license": "MIT" + }, + "node_modules/workbox-broadcast-update": { + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/workbox-broadcast-update/-/workbox-broadcast-update-6.6.0.tgz", + "integrity": "sha512-nm+v6QmrIFaB/yokJmQ/93qIJ7n72NICxIwQwe5xsZiV2aI93MGGyEyzOzDPVz5THEr5rC3FJSsO3346cId64Q==", + "license": "MIT", + "dependencies": { + "workbox-core": "6.6.0" + } + }, + "node_modules/workbox-build": { + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/workbox-build/-/workbox-build-7.3.0.tgz", + "integrity": "sha512-JGL6vZTPlxnlqZRhR/K/msqg3wKP+m0wfEUVosK7gsYzSgeIxvZLi1ViJJzVL7CEeI8r7rGFV973RiEqkP3lWQ==", + "license": "MIT", + "dependencies": { + "@apideck/better-ajv-errors": "^0.3.1", + "@babel/core": "^7.24.4", + "@babel/preset-env": "^7.11.0", + "@babel/runtime": "^7.11.2", + "@rollup/plugin-babel": "^5.2.0", + "@rollup/plugin-node-resolve": "^15.2.3", + "@rollup/plugin-replace": "^2.4.1", + "@rollup/plugin-terser": "^0.4.3", + "@surma/rollup-plugin-off-main-thread": "^2.2.3", + "ajv": "^8.6.0", + "common-tags": "^1.8.0", + "fast-json-stable-stringify": "^2.1.0", + "fs-extra": "^9.0.1", + "glob": "^7.1.6", + "lodash": "^4.17.20", + "pretty-bytes": "^5.3.0", + "rollup": "^2.43.1", + "source-map": "^0.8.0-beta.0", + "stringify-object": "^3.3.0", + "strip-comments": "^2.0.1", + "tempy": "^0.6.0", + "upath": "^1.2.0", + "workbox-background-sync": "7.3.0", + "workbox-broadcast-update": "7.3.0", + "workbox-cacheable-response": "7.3.0", + "workbox-core": "7.3.0", + "workbox-expiration": "7.3.0", + "workbox-google-analytics": "7.3.0", + "workbox-navigation-preload": "7.3.0", + "workbox-precaching": "7.3.0", + "workbox-range-requests": "7.3.0", + "workbox-recipes": "7.3.0", + "workbox-routing": "7.3.0", + "workbox-strategies": "7.3.0", + "workbox-streams": "7.3.0", + "workbox-sw": "7.3.0", + "workbox-window": "7.3.0" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/workbox-build/node_modules/@apideck/better-ajv-errors": { + "version": "0.3.6", + "resolved": "https://registry.npmjs.org/@apideck/better-ajv-errors/-/better-ajv-errors-0.3.6.tgz", + "integrity": "sha512-P+ZygBLZtkp0qqOAJJVX4oX/sFo5JR3eBWwwuqHHhK0GIgQOKWrAfiAaWX0aArHkRWHMuggFEgAZNxVPwPZYaA==", + "license": "MIT", + "dependencies": { + "json-schema": "^0.4.0", + "jsonpointer": "^5.0.0", + "leven": "^3.1.0" + }, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "ajv": ">=8" + } + }, + "node_modules/workbox-build/node_modules/@rollup/plugin-babel": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/@rollup/plugin-babel/-/plugin-babel-5.3.1.tgz", + "integrity": "sha512-WFfdLWU/xVWKeRQnKmIAQULUI7Il0gZnBIH/ZFO069wYIfPu+8zrfp/KMW0atmELoRDq8FbiP3VCss9MhCut7Q==", + "license": "MIT", + "dependencies": { + "@babel/helper-module-imports": "^7.10.4", + "@rollup/pluginutils": "^3.1.0" + }, + "engines": { + "node": ">= 10.0.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0", + "@types/babel__core": "^7.1.9", + "rollup": "^1.20.0||^2.0.0" + }, + "peerDependenciesMeta": { + "@types/babel__core": { + "optional": true + } + } + }, + "node_modules/workbox-build/node_modules/@rollup/plugin-replace": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/@rollup/plugin-replace/-/plugin-replace-2.4.2.tgz", + "integrity": "sha512-IGcu+cydlUMZ5En85jxHH4qj2hta/11BHq95iHEyb2sbgiN0eCdzvUcHw5gt9pBL5lTi4JDYJ1acCoMGpTvEZg==", + "license": "MIT", + "dependencies": { + "@rollup/pluginutils": "^3.1.0", + "magic-string": "^0.25.7" + }, + "peerDependencies": { + "rollup": "^1.20.0 || ^2.0.0" + } + }, + "node_modules/workbox-build/node_modules/@rollup/pluginutils": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-3.1.0.tgz", + "integrity": "sha512-GksZ6pr6TpIjHm8h9lSQ8pi8BE9VeubNT0OMJ3B5uZJ8pz73NPiqOtCog/x2/QzM1ENChPKxMDhiQuRHsqc+lg==", + "license": "MIT", + "dependencies": { + "@types/estree": "0.0.39", + "estree-walker": "^1.0.1", + "picomatch": "^2.2.2" + }, + "engines": { + "node": ">= 8.0.0" + }, + "peerDependencies": { + "rollup": "^1.20.0||^2.0.0" + } + }, + "node_modules/workbox-build/node_modules/@types/estree": { + "version": "0.0.39", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.39.tgz", + "integrity": "sha512-EYNwp3bU+98cpU4lAWYYL7Zz+2gryWH1qbdDTidVd6hkiR6weksdbMadyXKXNPEkQFhXM+hVO9ZygomHXp+AIw==", + "license": "MIT" + }, + "node_modules/workbox-build/node_modules/ajv": { + "version": "8.17.1", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", + "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.3", + "fast-uri": "^3.0.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/workbox-build/node_modules/estree-walker": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-1.0.1.tgz", + "integrity": "sha512-1fMXF3YP4pZZVozF8j/ZLfvnR8NSIljt56UhbZ5PeeDmmGHpgpdwQt7ITlGvYaQukCvuBRMLEiKiYC+oeIg4cg==", + "license": "MIT" + }, + "node_modules/workbox-build/node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "license": "MIT" + }, + "node_modules/workbox-build/node_modules/magic-string": { + "version": "0.25.9", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.25.9.tgz", + "integrity": "sha512-RmF0AsMzgt25qzqqLc1+MbHmhdx0ojF2Fvs4XnOqz2ZOBXzzkEwc/dJQZCYHAn7v1jbVOjAZfK8msRn4BxO4VQ==", + "license": "MIT", + "dependencies": { + "sourcemap-codec": "^1.4.8" + } + }, + "node_modules/workbox-build/node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "license": "MIT", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/workbox-build/node_modules/pretty-bytes": { + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/pretty-bytes/-/pretty-bytes-5.6.0.tgz", + "integrity": "sha512-FFw039TmrBqFK8ma/7OL3sDz/VytdtJr044/QUJtH0wK9lb9jLq9tJyIxUwtQJHwar2BqtiA4iCWSwo9JLkzFg==", + "license": "MIT", + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/workbox-build/node_modules/rollup": { + "version": "2.79.2", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.79.2.tgz", + "integrity": "sha512-fS6iqSPZDs3dr/y7Od6y5nha8dW1YnbgtsyotCVvoFGKbERG++CVRFv1meyGDE1SNItQA8BrnCw7ScdAhRJ3XQ==", + "license": "MIT", + "bin": { + "rollup": "dist/bin/rollup" + }, + "engines": { + "node": ">=10.0.0" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, + "node_modules/workbox-build/node_modules/source-map": { + "version": "0.8.0-beta.0", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.8.0-beta.0.tgz", + "integrity": "sha512-2ymg6oRBpebeZi9UUNsgQ89bhx01TcTkmNTGnNO88imTmbSgy4nfujrgVEFKWpMTEGA11EDkTt7mqObTPdigIA==", + "deprecated": "The work that was done in this beta branch won't be included in future versions", + "license": "BSD-3-Clause", + "dependencies": { + "whatwg-url": "^7.0.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/workbox-build/node_modules/workbox-background-sync": { + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/workbox-background-sync/-/workbox-background-sync-7.3.0.tgz", + "integrity": "sha512-PCSk3eK7Mxeuyatb22pcSx9dlgWNv3+M8PqPaYDokks8Y5/FX4soaOqj3yhAZr5k6Q5JWTOMYgaJBpbw11G9Eg==", + "license": "MIT", + "dependencies": { + "idb": "^7.0.1", + "workbox-core": "7.3.0" + } + }, + "node_modules/workbox-build/node_modules/workbox-broadcast-update": { + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/workbox-broadcast-update/-/workbox-broadcast-update-7.3.0.tgz", + "integrity": "sha512-T9/F5VEdJVhwmrIAE+E/kq5at2OY6+OXXgOWQevnubal6sO92Gjo24v6dCVwQiclAF5NS3hlmsifRrpQzZCdUA==", + "license": "MIT", + "dependencies": { + "workbox-core": "7.3.0" + } + }, + "node_modules/workbox-build/node_modules/workbox-cacheable-response": { + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/workbox-cacheable-response/-/workbox-cacheable-response-7.3.0.tgz", + "integrity": "sha512-eAFERIg6J2LuyELhLlmeRcJFa5e16Mj8kL2yCDbhWE+HUun9skRQrGIFVUagqWj4DMaaPSMWfAolM7XZZxNmxA==", + "license": "MIT", + "dependencies": { + "workbox-core": "7.3.0" + } + }, + "node_modules/workbox-build/node_modules/workbox-core": { + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/workbox-core/-/workbox-core-7.3.0.tgz", + "integrity": "sha512-Z+mYrErfh4t3zi7NVTvOuACB0A/jA3bgxUN3PwtAVHvfEsZxV9Iju580VEETug3zYJRc0Dmii/aixI/Uxj8fmw==", + "license": "MIT" + }, + "node_modules/workbox-build/node_modules/workbox-expiration": { + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/workbox-expiration/-/workbox-expiration-7.3.0.tgz", + "integrity": "sha512-lpnSSLp2BM+K6bgFCWc5bS1LR5pAwDWbcKt1iL87/eTSJRdLdAwGQznZE+1czLgn/X05YChsrEegTNxjM067vQ==", + "license": "MIT", + "dependencies": { + "idb": "^7.0.1", + "workbox-core": "7.3.0" + } + }, + "node_modules/workbox-build/node_modules/workbox-google-analytics": { + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/workbox-google-analytics/-/workbox-google-analytics-7.3.0.tgz", + "integrity": "sha512-ii/tSfFdhjLHZ2BrYgFNTrb/yk04pw2hasgbM70jpZfLk0vdJAXgaiMAWsoE+wfJDNWoZmBYY0hMVI0v5wWDbg==", + "license": "MIT", + "dependencies": { + "workbox-background-sync": "7.3.0", + "workbox-core": "7.3.0", + "workbox-routing": "7.3.0", + "workbox-strategies": "7.3.0" + } + }, + "node_modules/workbox-build/node_modules/workbox-navigation-preload": { + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/workbox-navigation-preload/-/workbox-navigation-preload-7.3.0.tgz", + "integrity": "sha512-fTJzogmFaTv4bShZ6aA7Bfj4Cewaq5rp30qcxl2iYM45YD79rKIhvzNHiFj1P+u5ZZldroqhASXwwoyusnr2cg==", + "license": "MIT", + "dependencies": { + "workbox-core": "7.3.0" + } + }, + "node_modules/workbox-build/node_modules/workbox-precaching": { + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/workbox-precaching/-/workbox-precaching-7.3.0.tgz", + "integrity": "sha512-ckp/3t0msgXclVAYaNndAGeAoWQUv7Rwc4fdhWL69CCAb2UHo3Cef0KIUctqfQj1p8h6aGyz3w8Cy3Ihq9OmIw==", + "license": "MIT", + "dependencies": { + "workbox-core": "7.3.0", + "workbox-routing": "7.3.0", + "workbox-strategies": "7.3.0" + } + }, + "node_modules/workbox-build/node_modules/workbox-range-requests": { + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/workbox-range-requests/-/workbox-range-requests-7.3.0.tgz", + "integrity": "sha512-EyFmM1KpDzzAouNF3+EWa15yDEenwxoeXu9bgxOEYnFfCxns7eAxA9WSSaVd8kujFFt3eIbShNqa4hLQNFvmVQ==", + "license": "MIT", + "dependencies": { + "workbox-core": "7.3.0" + } + }, + "node_modules/workbox-build/node_modules/workbox-routing": { + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/workbox-routing/-/workbox-routing-7.3.0.tgz", + "integrity": "sha512-ZUlysUVn5ZUzMOmQN3bqu+gK98vNfgX/gSTZ127izJg/pMMy4LryAthnYtjuqcjkN4HEAx1mdgxNiKJMZQM76A==", + "license": "MIT", + "dependencies": { + "workbox-core": "7.3.0" + } + }, + "node_modules/workbox-build/node_modules/workbox-strategies": { + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/workbox-strategies/-/workbox-strategies-7.3.0.tgz", + "integrity": "sha512-tmZydug+qzDFATwX7QiEL5Hdf7FrkhjaF9db1CbB39sDmEZJg3l9ayDvPxy8Y18C3Y66Nrr9kkN1f/RlkDgllg==", + "license": "MIT", + "dependencies": { + "workbox-core": "7.3.0" + } + }, + "node_modules/workbox-build/node_modules/workbox-streams": { + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/workbox-streams/-/workbox-streams-7.3.0.tgz", + "integrity": "sha512-SZnXucyg8x2Y61VGtDjKPO5EgPUG5NDn/v86WYHX+9ZqvAsGOytP0Jxp1bl663YUuMoXSAtsGLL+byHzEuMRpw==", + "license": "MIT", + "dependencies": { + "workbox-core": "7.3.0", + "workbox-routing": "7.3.0" + } + }, + "node_modules/workbox-cacheable-response": { + "version": "6.5.4", + "resolved": "https://registry.npmjs.org/workbox-cacheable-response/-/workbox-cacheable-response-6.5.4.tgz", + "integrity": "sha512-DCR9uD0Fqj8oB2TSWQEm1hbFs/85hXXoayVwFKLVuIuxwJaihBsLsp4y7J9bvZbqtPJ1KlCkmYVGQKrBU4KAug==", + "license": "MIT", + "dependencies": { + "workbox-core": "6.5.4" + } + }, + "node_modules/workbox-cacheable-response/node_modules/workbox-core": { + "version": "6.5.4", + "resolved": "https://registry.npmjs.org/workbox-core/-/workbox-core-6.5.4.tgz", + "integrity": "sha512-OXYb+m9wZm8GrORlV2vBbE5EC1FKu71GGp0H4rjmxmF4/HLbMCoTFws87M3dFwgpmg0v00K++PImpNQ6J5NQ6Q==", + "license": "MIT" + }, + "node_modules/workbox-core": { + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/workbox-core/-/workbox-core-6.6.0.tgz", + "integrity": "sha512-GDtFRF7Yg3DD859PMbPAYPeJyg5gJYXuBQAC+wyrWuuXgpfoOrIQIvFRZnQ7+czTIQjIr1DhLEGFzZanAT/3bQ==", + "license": "MIT" + }, + "node_modules/workbox-expiration": { + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/workbox-expiration/-/workbox-expiration-6.6.0.tgz", + "integrity": "sha512-baplYXcDHbe8vAo7GYvyAmlS4f6998Jff513L4XvlzAOxcl8F620O91guoJ5EOf5qeXG4cGdNZHkkVAPouFCpw==", + "license": "MIT", + "dependencies": { + "idb": "^7.0.1", + "workbox-core": "6.6.0" + } + }, + "node_modules/workbox-google-analytics": { + "version": "6.6.1", + "resolved": "https://registry.npmjs.org/workbox-google-analytics/-/workbox-google-analytics-6.6.1.tgz", + "integrity": "sha512-1TjSvbFSLmkpqLcBsF7FuGqqeDsf+uAXO/pjiINQKg3b1GN0nBngnxLcXDYo1n/XxK4N7RaRrpRlkwjY/3ocuA==", + "deprecated": "It is not compatible with newer versions of GA starting with v4, as long as you are using GAv3 it should be ok, but the package is not longer being maintained", + "license": "MIT", + "dependencies": { + "workbox-background-sync": "6.6.1", + "workbox-core": "6.6.1", + "workbox-routing": "6.6.1", + "workbox-strategies": "6.6.1" + } + }, + "node_modules/workbox-google-analytics/node_modules/workbox-core": { + "version": "6.6.1", + "resolved": "https://registry.npmjs.org/workbox-core/-/workbox-core-6.6.1.tgz", + "integrity": "sha512-ZrGBXjjaJLqzVothoE12qTbVnOAjFrHDXpZe7coCb6q65qI/59rDLwuFMO4PcZ7jcbxY+0+NhUVztzR/CbjEFw==", + "deprecated": "this package has been deprecated", + "license": "MIT" + }, + "node_modules/workbox-google-analytics/node_modules/workbox-routing": { + "version": "6.6.1", + "resolved": "https://registry.npmjs.org/workbox-routing/-/workbox-routing-6.6.1.tgz", + "integrity": "sha512-j4ohlQvfpVdoR8vDYxTY9rA9VvxTHogkIDwGdJ+rb2VRZQ5vt1CWwUUZBeD/WGFAni12jD1HlMXvJ8JS7aBWTg==", + "deprecated": "this package has been deprecated", + "license": "MIT", + "dependencies": { + "workbox-core": "6.6.1" + } + }, + "node_modules/workbox-google-analytics/node_modules/workbox-strategies": { + "version": "6.6.1", + "resolved": "https://registry.npmjs.org/workbox-strategies/-/workbox-strategies-6.6.1.tgz", + "integrity": "sha512-WQLXkRnsk4L81fVPkkgon1rZNxnpdO5LsO+ws7tYBC6QQQFJVI6v98klrJEjFtZwzw/mB/HT5yVp7CcX0O+mrw==", + "deprecated": "this package has been deprecated", + "license": "MIT", + "dependencies": { + "workbox-core": "6.6.1" + } + }, + "node_modules/workbox-navigation-preload": { + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/workbox-navigation-preload/-/workbox-navigation-preload-6.6.0.tgz", + "integrity": "sha512-utNEWG+uOfXdaZmvhshrh7KzhDu/1iMHyQOV6Aqup8Mm78D286ugu5k9MFD9SzBT5TcwgwSORVvInaXWbvKz9Q==", + "license": "MIT", + "dependencies": { + "workbox-core": "6.6.0" + } + }, + "node_modules/workbox-precaching": { + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/workbox-precaching/-/workbox-precaching-6.6.0.tgz", + "integrity": "sha512-eYu/7MqtRZN1IDttl/UQcSZFkHP7dnvr/X3Vn6Iw6OsPMruQHiVjjomDFCNtd8k2RdjLs0xiz9nq+t3YVBcWPw==", + "license": "MIT", + "dependencies": { + "workbox-core": "6.6.0", + "workbox-routing": "6.6.0", + "workbox-strategies": "6.6.0" + } + }, + "node_modules/workbox-range-requests": { + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/workbox-range-requests/-/workbox-range-requests-6.6.0.tgz", + "integrity": "sha512-V3aICz5fLGq5DpSYEU8LxeXvsT//mRWzKrfBOIxzIdQnV/Wj7R+LyJVTczi4CQ4NwKhAaBVaSujI1cEjXW+hTw==", + "license": "MIT", + "dependencies": { + "workbox-core": "6.6.0" + } + }, + "node_modules/workbox-recipes": { + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/workbox-recipes/-/workbox-recipes-7.3.0.tgz", + "integrity": "sha512-BJro/MpuW35I/zjZQBcoxsctgeB+kyb2JAP5EB3EYzePg8wDGoQuUdyYQS+CheTb+GhqJeWmVs3QxLI8EBP1sg==", + "license": "MIT", + "dependencies": { + "workbox-cacheable-response": "7.3.0", + "workbox-core": "7.3.0", + "workbox-expiration": "7.3.0", + "workbox-precaching": "7.3.0", + "workbox-routing": "7.3.0", + "workbox-strategies": "7.3.0" + } + }, + "node_modules/workbox-recipes/node_modules/workbox-cacheable-response": { + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/workbox-cacheable-response/-/workbox-cacheable-response-7.3.0.tgz", + "integrity": "sha512-eAFERIg6J2LuyELhLlmeRcJFa5e16Mj8kL2yCDbhWE+HUun9skRQrGIFVUagqWj4DMaaPSMWfAolM7XZZxNmxA==", + "license": "MIT", + "dependencies": { + "workbox-core": "7.3.0" + } + }, + "node_modules/workbox-recipes/node_modules/workbox-core": { + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/workbox-core/-/workbox-core-7.3.0.tgz", + "integrity": "sha512-Z+mYrErfh4t3zi7NVTvOuACB0A/jA3bgxUN3PwtAVHvfEsZxV9Iju580VEETug3zYJRc0Dmii/aixI/Uxj8fmw==", + "license": "MIT" + }, + "node_modules/workbox-recipes/node_modules/workbox-expiration": { + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/workbox-expiration/-/workbox-expiration-7.3.0.tgz", + "integrity": "sha512-lpnSSLp2BM+K6bgFCWc5bS1LR5pAwDWbcKt1iL87/eTSJRdLdAwGQznZE+1czLgn/X05YChsrEegTNxjM067vQ==", + "license": "MIT", + "dependencies": { + "idb": "^7.0.1", + "workbox-core": "7.3.0" + } + }, + "node_modules/workbox-recipes/node_modules/workbox-precaching": { + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/workbox-precaching/-/workbox-precaching-7.3.0.tgz", + "integrity": "sha512-ckp/3t0msgXclVAYaNndAGeAoWQUv7Rwc4fdhWL69CCAb2UHo3Cef0KIUctqfQj1p8h6aGyz3w8Cy3Ihq9OmIw==", + "license": "MIT", + "dependencies": { + "workbox-core": "7.3.0", + "workbox-routing": "7.3.0", + "workbox-strategies": "7.3.0" + } + }, + "node_modules/workbox-recipes/node_modules/workbox-routing": { + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/workbox-routing/-/workbox-routing-7.3.0.tgz", + "integrity": "sha512-ZUlysUVn5ZUzMOmQN3bqu+gK98vNfgX/gSTZ127izJg/pMMy4LryAthnYtjuqcjkN4HEAx1mdgxNiKJMZQM76A==", + "license": "MIT", + "dependencies": { + "workbox-core": "7.3.0" + } + }, + "node_modules/workbox-recipes/node_modules/workbox-strategies": { + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/workbox-strategies/-/workbox-strategies-7.3.0.tgz", + "integrity": "sha512-tmZydug+qzDFATwX7QiEL5Hdf7FrkhjaF9db1CbB39sDmEZJg3l9ayDvPxy8Y18C3Y66Nrr9kkN1f/RlkDgllg==", + "license": "MIT", + "dependencies": { + "workbox-core": "7.3.0" + } + }, + "node_modules/workbox-routing": { + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/workbox-routing/-/workbox-routing-6.6.0.tgz", + "integrity": "sha512-x8gdN7VDBiLC03izAZRfU+WKUXJnbqt6PG9Uh0XuPRzJPpZGLKce/FkOX95dWHRpOHWLEq8RXzjW0O+POSkKvw==", + "license": "MIT", + "dependencies": { + "workbox-core": "6.6.0" + } + }, + "node_modules/workbox-strategies": { + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/workbox-strategies/-/workbox-strategies-6.6.0.tgz", + "integrity": "sha512-eC07XGuINAKUWDnZeIPdRdVja4JQtTuc35TZ8SwMb1ztjp7Ddq2CJ4yqLvWzFWGlYI7CG/YGqaETntTxBGdKgQ==", + "license": "MIT", + "dependencies": { + "workbox-core": "6.6.0" + } + }, + "node_modules/workbox-streams": { + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/workbox-streams/-/workbox-streams-6.6.0.tgz", + "integrity": "sha512-rfMJLVvwuED09CnH1RnIep7L9+mj4ufkTyDPVaXPKlhi9+0czCu+SJggWCIFbPpJaAZmp2iyVGLqS3RUmY3fxg==", + "license": "MIT", + "dependencies": { + "workbox-core": "6.6.0", + "workbox-routing": "6.6.0" + } + }, + "node_modules/workbox-sw": { + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/workbox-sw/-/workbox-sw-7.3.0.tgz", + "integrity": "sha512-aCUyoAZU9IZtH05mn0ACUpyHzPs0lMeJimAYkQkBsOWiqaJLgusfDCR+yllkPkFRxWpZKF8vSvgHYeG7LwhlmA==", + "license": "MIT" + }, + "node_modules/workbox-window": { + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/workbox-window/-/workbox-window-7.3.0.tgz", + "integrity": "sha512-qW8PDy16OV1UBaUNGlTVcepzrlzyzNW/ZJvFQQs2j2TzGsg6IKjcpZC1RSquqQnTOafl5pCj5bGfAHlCjOOjdA==", + "license": "MIT", + "dependencies": { + "@types/trusted-types": "^2.0.2", + "workbox-core": "7.3.0" + } + }, + "node_modules/workbox-window/node_modules/workbox-core": { + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/workbox-core/-/workbox-core-7.3.0.tgz", + "integrity": "sha512-Z+mYrErfh4t3zi7NVTvOuACB0A/jA3bgxUN3PwtAVHvfEsZxV9Iju580VEETug3zYJRc0Dmii/aixI/Uxj8fmw==", + "license": "MIT" + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", + "license": "ISC" + }, + "node_modules/yallist": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", + "license": "ISC" + }, + "node_modules/yaml": { + "version": "1.10.2", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz", + "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==", + "license": "ISC", + "engines": { + "node": ">= 6" + } + }, + "node_modules/yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/yup": { + "version": "0.32.11", + "resolved": "https://registry.npmjs.org/yup/-/yup-0.32.11.tgz", + "integrity": "sha512-Z2Fe1bn+eLstG8DRR6FTavGD+MeAwyfmouhHsIUgaADz8jvFKbO/fXc2trJKZg+5EBjh4gGm3iU/t3onKlXHIg==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.15.4", + "@types/lodash": "^4.14.175", + "lodash": "^4.17.21", + "lodash-es": "^4.17.21", + "nanoclone": "^0.2.1", + "property-expr": "^2.0.4", + "toposort": "^2.0.2" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/zod": { + "version": "4.1.12", + "resolved": "https://registry.npmjs.org/zod/-/zod-4.1.12.tgz", + "integrity": "sha512-JInaHOamG8pt5+Ey8kGmdcAcg3OL9reK8ltczgHTAwNhMys/6ThXHityHxVV2p3fkw/c+MAvBHFVYHFZDmjMCQ==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/colinhacks" + } + }, + "node_modules/zod-validation-error": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/zod-validation-error/-/zod-validation-error-4.0.2.tgz", + "integrity": "sha512-Q6/nZLe6jxuU80qb/4uJ4t5v2VEZ44lzQjPDhYJNztRQ4wyWc6VF3D3Kb/fAuPetZQnhS3hnajCf9CsWesghLQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18.0.0" + }, + "peerDependencies": { + "zod": "^3.25.0 || ^4.0.0" + } + }, + "node_modules/zrender": { + "version": "5.6.1", + "resolved": "https://registry.npmjs.org/zrender/-/zrender-5.6.1.tgz", + "integrity": "sha512-OFXkDJKcrlx5su2XbzJvj/34Q3m6PvyCZkVPHGYpcCJ52ek4U/ymZyfuV1nKE23AyBJ51E/6Yr0mhZ7xGTO4ag==", + "license": "BSD-3-Clause", + "dependencies": { + "tslib": "2.3.0" + } + } + } +} diff --git a/package.json b/package.json new file mode 100644 index 0000000..bda027b --- /dev/null +++ b/package.json @@ -0,0 +1,105 @@ +{ + "name": "my-app", + "version": "0.1.1", + "private": true, + "type": "module", + "dependencies": { + "@date-io/date-fns-jalali": "^2.15.0", + "@date-io/jalaali": "^2.15.0", + "@emotion/react": "^11.10.4", + "@emotion/styled": "^11.10.4", + "@mui/icons-material": "^5.10.3", + "@mui/lab": "^5.0.0-alpha.99", + "@mui/material": "^5.10.4", + "@mui/x-date-pickers": "^5.0.2", + "@reactour/tour": "^3.1.6", + "@reduxjs/toolkit": "^1.8.5", + "@testing-library/jest-dom": "^5.16.5", + "@testing-library/react": "^13.4.0", + "@testing-library/user-event": "^13.5.0", + "@vitejs/plugin-react": "^4.3.1", + "axios": "^0.27.2", + "camelize": "^1.0.0", + "chart.js": "^4.2.1", + "chartjs-plugin-annotation": "^3.1.0", + "chartjs-plugin-datalabels": "^2.2.0", + "date-fns": "^2.29.3", + "date-fns-jalali": "^2.29.2-0", + "echarts": "^5.6.0", + "echarts-for-react": "^3.0.2", + "eslint": "8.22.0", + "eslint-config-prettier": "^8.5.0", + "eslint-plugin-jest-dom": "^4.0.2", + "eslint-plugin-prettier": "^4.2.1", + "formik": "^2.2.9", + "framer-motion": "^7.3.5", + "html2canvas": "^1.4.1", + "lottie-react": "^2.3.1", + "material-react-table": "^2.1.0", + "moment": "^2.29.4", + "mui-datatables": "^4.2.2", + "num2persian": "^3.2.2", + "persian-date": "^1.1.0", + "prettier": "^2.7.1", + "react": "^18.2.0", + "react-chartjs-2": "^5.2.0", + "react-data-table-component": "^7.5.3", + "react-dom": "^18.2.0", + "react-error-boundary": "^3.1.4", + "react-icons": "^4.8.0", + "react-images-uploading": "^3.1.7", + "react-number-format": "^5.1.2", + "react-redux": "^8.0.2", + "react-router-dom": "^6.3.0", + "react-to-print": "^2.14.15", + "reactour": "^1.18.7", + "redux-persist": "^6.0.0", + "styled-components": "^4.0.0", + "stylis": "^4.1.2", + "stylis-plugin-rtl": "2.0.2", + "use-react-screenshot": "^3.0.0", + "vite": "^5.4.2", + "vite-plugin-pwa": "^0.20.1", + "vitest": "^2.0.5", + "web-vitals": "^2.1.4", + "workbox-background-sync": "^6.5.4", + "workbox-broadcast-update": "^6.5.4", + "workbox-cacheable-response": "^6.5.4", + "workbox-core": "^6.5.4", + "workbox-expiration": "^6.5.4", + "workbox-google-analytics": "^6.5.4", + "workbox-navigation-preload": "^6.5.4", + "workbox-precaching": "^6.5.4", + "workbox-range-requests": "^6.5.4", + "workbox-routing": "^6.5.4", + "workbox-strategies": "^6.5.4", + "workbox-streams": "^6.5.4", + "yup": "^0.32.11" + }, + "scripts": { + "dev": "vite", + "start": "vite", + "build": "vite build", + "preview": "vite preview", + "test": "vitest", + "lint": "eslint src --ext .js,.jsx", + "lint:fix": "eslint src --ext .js,.jsx --fix" + }, + "browserslist": { + "production": [ + ">0.2%", + "not dead", + "not op_mini all" + ], + "development": [ + "last 1 chrome version", + "last 1 firefox version", + "last 1 safari version" + ] + }, + "devDependencies": { + "eslint-plugin-react": "^7.37.5", + "eslint-plugin-react-hooks": "^7.0.0", + "eslint-plugin-testing-library": "^7.13.3" + } +} diff --git a/public/OIG e(1).png b/public/OIG e(1).png new file mode 100644 index 0000000..84e4ed0 Binary files /dev/null and b/public/OIG e(1).png differ diff --git a/public/android-chrome-192x192.png b/public/android-chrome-192x192.png new file mode 100644 index 0000000..8686518 Binary files /dev/null and b/public/android-chrome-192x192.png differ diff --git a/public/android-chrome-512x512.png b/public/android-chrome-512x512.png new file mode 100644 index 0000000..e9d92f7 Binary files /dev/null and b/public/android-chrome-512x512.png differ diff --git a/public/apple-touch-icon.png b/public/apple-touch-icon.png new file mode 100644 index 0000000..e5d1d9b Binary files /dev/null and b/public/apple-touch-icon.png differ diff --git a/public/favicon-16x16.png b/public/favicon-16x16.png new file mode 100644 index 0000000..77b35e5 Binary files /dev/null and b/public/favicon-16x16.png differ diff --git a/public/favicon-32x32.png b/public/favicon-32x32.png new file mode 100644 index 0000000..0a7bb18 Binary files /dev/null and b/public/favicon-32x32.png differ diff --git a/public/favicon.ico b/public/favicon.ico new file mode 100644 index 0000000..1bc6fa9 Binary files /dev/null and b/public/favicon.ico differ diff --git a/public/logo192.png b/public/logo192.png new file mode 100644 index 0000000..e2a711d Binary files /dev/null and b/public/logo192.png differ diff --git a/public/logo512.png b/public/logo512.png new file mode 100644 index 0000000..f4aa482 Binary files /dev/null and b/public/logo512.png differ diff --git a/public/manifest.json b/public/manifest.json new file mode 100644 index 0000000..a10163b --- /dev/null +++ b/public/manifest.json @@ -0,0 +1,20 @@ +{ + "short_name": "سامانه رصدیار", + "name": "سامانه رصدیار", + "icons": [ + { + "src": "/android-chrome-192x192.png", + "sizes": "192x192", + "type": "image/png" + }, + { + "src": "/android-chrome-512x512.png", + "sizes": "512x512", + "type": "image/png" + } + ], + "start_url": ".", + "display": "standalone", + "theme_color": "#000000", + "background_color": "#ffffff" +} diff --git a/public/robots.txt b/public/robots.txt new file mode 100644 index 0000000..e9e57dc --- /dev/null +++ b/public/robots.txt @@ -0,0 +1,3 @@ +# https://www.robotstxt.org/robotstxt.html +User-agent: * +Disallow: diff --git a/src/App-oldd.js b/src/App-oldd.js new file mode 100644 index 0000000..c514aa1 --- /dev/null +++ b/src/App-oldd.js @@ -0,0 +1,44 @@ +import React from "react"; + +const App = () => { + const containerStyle = { + backgroundColor: "#f0f0f0", + fontFamily: "Arial, sans-serif", + textAlign: "center", + }; + + const headerStyle = { + backgroundColor: "#3498db", + color: "#fff", + padding: "20px", + }; + + const addressStyle = { + fontSize: "24px", + fontWeight: "bold", + color: "#3498db", + }; + + const textStyle = { + fontSize: "18px", + }; + + return ( +
+
+

سامانه رصدیار به آدرس زیر انتقال یافت!

+
+
+

آدرس جدید سامانه:

+

+ sha.rasadyaar.ir +

+
+
+

برای انتقال بر روی لینک کلیک کنید.

+
+
+ ); +}; + +export default App; diff --git a/src/App.css b/src/App.css new file mode 100644 index 0000000..7328e2e --- /dev/null +++ b/src/App.css @@ -0,0 +1,158 @@ +a { + text-decoration: none; +} + +.App { + text-align: center; +} + +html::-webkit-scrollbar { + width: 10px; +} + +html::-webkit-scrollbar-thumb { + background: linear-gradient(to bottom, #eaefff, #2247bf); + border-radius: 0px 0px 4px 4px; +} + +html::-webkit-scrollbar-track { + background-color: white; +} + +.App-logo { + height: 40vmin; + pointer-events: none; +} + +.svg-icon-color path { + stroke: #4285f4; +} + +@media (prefers-reduced-motion: no-preference) { + .App-logo { + animation: App-logo-spin infinite 20s linear; + } +} + +.App-header { + background-color: #282c34; + min-height: 100vh; + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + font-size: calc(10px + 2vmin); + color: white; +} + +.App-link { + color: #61dafb; +} + +@keyframes App-logo-spin { + from { + transform: rotate(0deg); + } + to { + transform: rotate(360deg); + } +} + +.bluehover { + will-change: filter; + transition: filter 300ms; +} +.bluehover:hover { + filter: drop-shadow(0 0 0.5em #cc0a95aa); +} + +.marquee { + width: 100%; + line-height: 30px; + color: white; + white-space: nowrap; + overflow: hidden; + box-sizing: border-box; + direction: rtl; + margin-top: -10px !important; +} + +.marquee p { + font-size: 15px; + margin: 0; + display: inline-block; + animation: marquee 60s linear infinite; + color: #f9f947; +} + +@keyframes marquee { + 0% { + transform: translate(-100%, 0); + } + 100% { + transform: translate(100%, 0); + } +} + +/* .MuiOutlinedInput-notchedOutline, +.MuiButtonBase-root { + border-radius: 15px !important; +} */ + +.MuiOutlinedInput-notchedOutline { + border-radius: 8px !important; +} + +/* .MuiButtonBase-root { + border-radius: 5px !important; +} */ + +/* .muirtl-1ujnqem-MuiTabs-root { + border-style: solid; + padding: 2px; + border-radius: 15px 15px 0px 0px; + border-width: 1px 0px 0px 0px; + border-color: #a1f1c2; + filter: drop-shadow(0 0 0.75rem crimson); +} */ + +.insidetabs { + border-style: none !important; + padding: 0px !important; + color: pink !important; + font-size: 10px !important; +} + +.header-menu { + font-weight: 800 !important; +} + +.muirtl-rpxd6p-MuiButtonBase-root-MuiTab-root.Mui-selected { + background: #eaefff; + font-weight: 800; +} + +.path-city { + stroke: #fff; +} +.path-city:hover { + fill: #db5f5f; +} + +@media only screen and (max-width: 600px) { + .MuiButtonBase-root-MuiTab-root { + font-size: 0.75rem !important; + } + .muirtl-1sbhvmq { + padding: 12px 16px !important; + } + .muirtl-162ovef { + padding: 4px 8px !important; + } + .MuiChip-root { + height: 24px !important; + } + .MuiChip-label { + padding: 0 6px !important; + } +} diff --git a/src/App.js b/src/App.js new file mode 100644 index 0000000..de57323 --- /dev/null +++ b/src/App.js @@ -0,0 +1,497 @@ +import React, { Suspense, useEffect, useState } from "react"; +import "./App.css"; +import { Routes, Route, Navigate, useLocation } from "react-router-dom"; +import { guestRouting } from "./routes/guestRouting"; +import { getManagerRouting } from "./routes/managerRouting"; +import { Box, ThemeProvider } from "@mui/material"; +import createCache from "@emotion/cache"; +import { prefixer } from "stylis"; +import rtlPlugin from "stylis-plugin-rtl"; +import { CacheProvider } from "@emotion/react"; +import { theme } from "./data/theme"; +import axios from "axios"; +import { store } from "./lib/redux/store"; +import { Loading } from "./components/loading/Loading"; +import { useDispatch, useSelector } from "react-redux"; +import { avicultureRouting } from "./routes/avicultureRouting"; +import { Header } from "./layouts/header/Header"; +import AdapterJalali from "@date-io/date-fns-jalali"; +import { LocalizationProvider } from "@mui/x-date-pickers"; +import { cityRouting } from "./routes/cityRouting"; +import { slaughterRouting } from "./routes/slaughterRouting"; +import { Modal } from "./components/modal/Modal"; +import { provinceFinancialRouting } from "./routes/provinceFinancialRouting"; +import { vetFarmRouting } from "./routes/vetFarmRouting"; +import Drawer from "./components/drawer/Drawer"; +import { generalRouting } from "./routes/generalRouting"; +import { StrictModal } from "./components/strict-modal/StrictModal"; +import { StrictMissingHallNumber } from "./features/aviculture/components/strict-missing-hall-number/StrictMissingHallNumber"; +import { driverRouting } from "./routes/driverRouting"; +import { SidebarContextProvider } from "./contexts/SidebarContext"; +import { BackDrop } from "./components/backdrop/BackDrop"; +import { AppContextProvider } from "./contexts/AppContext"; +import { Notif } from "./components/notif/Notif"; +import { inspectorRouting } from "./routes/inspectorRouting"; +// import bg from "./assets/images/bg.jpg"; +import { Fallback } from "./layouts/fallback/Fallback"; +import { slaughterHouseVetRouting } from "./routes/slaughterHouseVet"; +import { ErrorBoundary } from "react-error-boundary"; +import { ErrorFallback } from "./components/error-fallback/ErrorFallback"; +import { LOG_OUT } from "./lib/redux/slices/userSlice"; +import { adminRouting } from "./routes/adminRouting"; +import { SetupAxios } from "./lib/axios/axios"; +import { vetSupervisorRouting } from "./routes/vetSupervisorRouting"; +import { jahadRouting } from "./routes/jahadRouting"; +import { commerceRouting } from "./routes/commerceRouting"; +import { cityCommerceRouting } from "./routes/cityCommerceRouting"; +import { cityVetRouting } from "./routes/cityVetRouting"; +import { cityJihadRouting } from "./routes/cityJihadRouting"; +import { observatoryRouting } from "./routes/observatoryRouting"; +import { provinceSupervisorRouting } from "./routes/provinceSupervisorRouting"; +import { senfRouting } from "./routes/senfRouting"; +import versionNumber from "./version.txt"; +import { guildRoomRouting } from "./routes/guildRoomRouting"; +import { posCompanyRouting } from "./routes/posCompanyRouting"; +import { liveStockSupportRouting } from "./routes/liveStockSupportRouting"; +import { chainCompanyRouting } from "./routes/chainCompanyRouting"; +// import ChatButton from "./components/chat-system/ChatSystem"; +import { supporterRouting } from "./routes/supporterRouting"; +import { dispenserRouting } from "./routes/dispenserRouting"; +import { cityPoultryRouting } from "./routes/cityPoultryRouting"; +import { SiteMap } from "./layouts/site-map/SiteMap"; +import { getRoleFromUrl } from "./utils/getRoleFromUrl"; +import { parentCompanyRouting } from "./routes/parentCompanyRouting"; +import { coldHouseStewardRouting } from "./routes/coldHouseStewardRouting"; +import { cityGuildRouting } from "./routes/cityGuildRouting"; +import { liveStockProvinceJahadRouting } from "./routes/LiveStockProvinceJahadRouting"; +import { unionRouting } from "./routes/unionRouting"; +import { cooperativeRouting } from "./routes/cooperativeRouting"; +import { rancherRouting } from "./routes/rancherRouting"; +import { barSquareRouting } from "./routes/barSquareRouting"; +import { stewardRouting } from "./routes/stewardRouting"; + +const AppRouter = () => { + const authToken = useSelector((state) => state.userSlice.authToken); + const role = useSelector((state) => state.userSlice.role); + + let routes = [...guestRouting]; + let defaultRoute = "/"; + + // const authToken = true; + // const role = "Poultry"; + + if (authToken) { + routes = [...generalRouting, ...barSquareRouting]; + for (const singleRoleIndex in role) { + if (Object.hasOwnProperty.call(role, singleRoleIndex)) { + const element = role[singleRoleIndex]; + switch (element) { + case "Admin": + routes = [...routes, ...adminRouting, ...inspectorRouting]; + break; + case "Poultry": + routes = [...routes, ...avicultureRouting]; + break; + case "CityOperator": + routes = [...routes, ...cityRouting]; + break; + case "KillHouse": + routes = [...routes, ...slaughterRouting]; + break; + case "ProvinceOperator": + routes = [...routes, ...getManagerRouting("provinceOperator")]; + break; + case "ProvinceFinancial": + routes = [...routes, ...provinceFinancialRouting]; + break; + case "ProvinceInspector": + routes = [...routes, ...inspectorRouting]; + break; + case "KillHouseVet": + routes = [...routes, ...slaughterHouseVetRouting]; + break; + case "VetFarm": + routes = [...routes, ...vetFarmRouting]; + break; + case "Driver": + routes = [...routes, ...driverRouting]; + break; + case "VetSupervisor": + routes = [...routes, ...vetSupervisorRouting]; + break; + case "Jahad": + routes = [...routes, ...jahadRouting]; + break; + case "Guilds": + routes = [...routes, ...senfRouting]; + break; + case "Steward": + routes = [...routes, ...stewardRouting]; + break; + case "Commerce": + routes = [...routes, ...commerceRouting]; + break; + case "ProvinceSupervisor": + routes = [...routes, ...provinceSupervisorRouting]; + break; + case "CityCommerce": + routes = [...routes, ...cityCommerceRouting]; + break; + case "CityVet": + routes = [...routes, ...cityVetRouting]; + break; + case "CityJahad": + routes = [...routes, ...cityJihadRouting]; + break; + case "Observatory": + routes = [...routes, ...observatoryRouting]; + break; + case "GuildRoom": + routes = [...routes, ...guildRoomRouting]; + break; + case "PosCompany": + routes = [...routes, ...posCompanyRouting]; + break; + case "LiveStockSupport": + routes = [...routes, ...liveStockSupportRouting]; + break; + case "SuperAdmin": + routes = [...routes, ...getManagerRouting("SuperAdmin")]; + break; + case "ChainCompany": + routes = [...routes, ...chainCompanyRouting]; + break; + case "AdminX": + routes = [...routes, ...getManagerRouting("AdminX")]; + break; + case "Supporter": + routes = [...routes, ...supporterRouting]; + break; + case "Dispenser": + routes = [...routes, ...dispenserRouting]; + break; + case "CityPoultry": + routes = [...routes, ...cityPoultryRouting]; + break; + case "ParentCompany": + routes = [...routes, ...parentCompanyRouting]; + break; + case "ColdHouseSteward": + routes = [...routes, ...coldHouseStewardRouting]; + break; + case "cityGuildRouting": + routes = [...routes, ...cityGuildRouting]; + break; + case "LiveStockProvinceJahad": + routes = [...routes, ...liveStockProvinceJahadRouting]; + break; + case "Union": + routes = [...routes, ...unionRouting]; + break; + case "Cooperative": + routes = [...routes, ...cooperativeRouting]; + break; + case "Rancher": + routes = [...routes, ...rancherRouting]; + break; + default: + } + } + } + } + + return ( + + {routes?.map((route) => { + const { exact, Page, props } = route; + return route.path.map((path) => ( + }> + + + + + } + /> + )); + })} + } + /> + + ); +}; + +const cacheRtl = createCache({ + key: "muirtl", + stylisPlugins: [prefixer, rtlPlugin], +}); + +const App = () => { + const dispatch = useDispatch(); + const authToken = useSelector((state) => state.userSlice.authToken); + const { pathname } = useLocation(); + // useEffect(() => { + // (function () { + // var cache = window.caches; + // cache.keys().then(function (keys) { + // keys.forEach(function (key) { + // cache.delete(key); + // }); + // }); + // })(); + // }, []); + + // check for necessary infos + const { profile } = useSelector((state) => state.avicultureSlice); + const [neededInfoMissingHall, setNeededInfoMissingHall] = useState([]); + + // const { selectedRoles } = useSelector((state) => state.fileSlice); + + // useEffect(() => { + // if (authToken) { + // dispatch(avicultureGetProfile()); + // if (!selectedRoles?.length) { + // dispatch(CHANGE_SELECTED_ROLES(role)); + // } + // if (isFirstLogin) { + // switch (role[0]) { + // case "Admin": + // break; + // case "Poultry": + // navigate(ROUTE_AVICULTURE_REQUESTS); + // break; + // case "CityOperator": + // navigate(ROUTE_CITY_REQUESTS); + // break; + // case "KillHouse": + // navigate(ROUTE_SLAUGHTER_REQUESTS); + // break; + // case "ProvinceOperator": + // navigate(ROUTE_PROVINCE_REQUESTS); + // break; + // case "ProvinceFinancial": + // navigate(ROUTE_PROVINCE_FINANCIAL_REQUESTS); + // break; + // case "ProvinceInspector": + // break; + // case "KillHouseVet": + // navigate(ROUTE_SLAUGHTER_HOUSE_VET_REQUESTS); + // break; + // case "VetFarm": + // navigate(ROUTE_VETFARM_ROUTE_ALLOCATIONS); + // break; + // case "Driver": + // break; + // case "VetSupervisor": + // navigate(ROUTE_VETـSUPERVISOR_ALLOCATIONS); + // break; + // case "CityVet": + // navigate(ROUTE_CITYVET_ROUTE_ALLOCATIONS); + // break; + // case "Observatory": + // navigate(ROUTE_OBSERVATORY_STATICS); + // break; + // case "Jahad": + // break; + // } + // dispatch(IS_FIRST_LOGIN(false)); + // } + // } + // }, [authToken]); + + useEffect(() => { + setOpen(false); + if (authToken && profile) { + for (const iterator of profile.aviculture) { + if (!iterator.numberOfHalls) { + setOpen(true); + setNeededInfoMissingHall([ + { + title: "NUMBER_OF_HALLS", + data: { + ...iterator, + }, + }, + ]); + } + } + } + }, [authToken, profile]); + + useEffect(() => { + if (!authToken || profile === null) { + setOpen(false); + } + }, [authToken, profile]); + + // useEffect(() => { + // if (authToken) { + // dispatch(provinceGetPolicyAvicultureCommitService()); + // } + // }, []); + + //buildchange + // useEffect(() => { + // let name = "Arta-System"; + // let version = "7"; + + // const last_version = localStorage.getItem(`${name}-Version`); + // if (last_version !== version) { + // localStorage.setItem(`${name}-Version`, version); + // dispatch(LOG_OUT()); + // // window.location.reload(true); + // } + // }, []); + + const [visibleSiteMap, setVisibleSiteMap] = useState(false); + + useEffect(() => { + setVisibleSiteMap(authToken && getRoleFromUrl()); + }, [window.location.href, window.location.pathname, pathname]); + + useEffect(() => { + if ( + window.location.search.includes("refresh") && + !window.location.search.includes("finalAmount") + ) { + window.location.href = window.location.pathname; + } + }, []); + + const hardRefresh = () => { + const currentUrl = window.location.href; + const newUrl = `${currentUrl}?refresh=${new Date().getTime()}`; + window.location.href = newUrl; + }; + + useEffect(() => { + const uniqueQueryParam = `?v=${new Date().getTime()}`; + fetch(`${versionNumber}${uniqueQueryParam}`) + .then((response) => response.text()) + .then((numberText) => { + const numberFromTxt = numberText.toString(); + const lastVersion = localStorage.getItem("AppVersion"); + console.log("compare versions", numberFromTxt, lastVersion); + if ( + !lastVersion || + lastVersion.toString() !== numberFromTxt.toString() + ) { + localStorage.setItem("AppVersion", numberFromTxt.toString()); + + if ("caches" in window) { + caches.keys().then((names) => { + names.forEach((name) => { + caches.delete(name); + }); + }); + hardRefresh(); + + // dispatch( + // OPEN_MODAL({ + // title: "ورژن جدید در دسترس است", + // content: ( + // <> + // + // + // جهت بهره مندی از امکانات جدید لطفا مرورگر خود را با زدن + // کلیدهای CTRL و F5 مجددا بارگزاری کنید. + // + // + // + // + // ), + // }) + // ); + } + } + }) + .catch((error) => { + console.error("Error:", error); + }); + }, [window.location.pathname]); + + const [open, setOpen] = React.useState(false); + // const handleOpen = () => setOpen(true); + const handleClose = () => setOpen(false); + + return ( + + + + { + dispatch(LOG_OUT()); + }} + > + }> + +
+ + {authToken &&
} + {visibleSiteMap && } + + {/* {authToken && } */} + + + + +
+ {neededInfoMissingHall.map((item, i) => { + let modalTitle = ""; + const modalContent = ( + + ); + if (item.title === "NUMBER_OF_HALLS") { + modalTitle = "ثبت تعداد سالن ها"; + } + return ( + + ); + })} + + + +
+
+
+
+
+
+ ); +}; + +SetupAxios(axios, store); + +export default App; diff --git a/src/App.test.js b/src/App.test.js new file mode 100644 index 0000000..d76787e --- /dev/null +++ b/src/App.test.js @@ -0,0 +1,9 @@ +import React from "react"; +import { render, screen } from "@testing-library/react"; +import App from "./App"; + +test("renders learn react link", () => { + render(); + const linkElement = screen.getByText(/learn react/i); + expect(linkElement).toBeInTheDocument(); +}); diff --git a/src/assets/fonts-old/eot/IRANSansWeb.eot b/src/assets/fonts-old/eot/IRANSansWeb.eot new file mode 100644 index 0000000..5a6fdd0 Binary files /dev/null and b/src/assets/fonts-old/eot/IRANSansWeb.eot differ diff --git a/src/assets/fonts-old/eot/IRANSansWeb_Black.eot b/src/assets/fonts-old/eot/IRANSansWeb_Black.eot new file mode 100644 index 0000000..a012bc6 Binary files /dev/null and b/src/assets/fonts-old/eot/IRANSansWeb_Black.eot differ diff --git a/src/assets/fonts-old/eot/IRANSansWeb_Bold.eot b/src/assets/fonts-old/eot/IRANSansWeb_Bold.eot new file mode 100644 index 0000000..82525e5 Binary files /dev/null and b/src/assets/fonts-old/eot/IRANSansWeb_Bold.eot differ diff --git a/src/assets/fonts-old/eot/IRANSansWeb_Light.eot b/src/assets/fonts-old/eot/IRANSansWeb_Light.eot new file mode 100644 index 0000000..f899008 Binary files /dev/null and b/src/assets/fonts-old/eot/IRANSansWeb_Light.eot differ diff --git a/src/assets/fonts-old/eot/IRANSansWeb_Medium.eot b/src/assets/fonts-old/eot/IRANSansWeb_Medium.eot new file mode 100644 index 0000000..117c2c8 Binary files /dev/null and b/src/assets/fonts-old/eot/IRANSansWeb_Medium.eot differ diff --git a/src/assets/fonts-old/eot/IRANSansWeb_UltraLight.eot b/src/assets/fonts-old/eot/IRANSansWeb_UltraLight.eot new file mode 100644 index 0000000..9cd9b66 Binary files /dev/null and b/src/assets/fonts-old/eot/IRANSansWeb_UltraLight.eot differ diff --git a/src/assets/fonts-old/fonts.css b/src/assets/fonts-old/fonts.css new file mode 100644 index 0000000..5b661a1 --- /dev/null +++ b/src/assets/fonts-old/fonts.css @@ -0,0 +1,78 @@ +@font-face { + font-family: IRANSans; + font-style: normal; + font-weight: 900; + src: url("../fonts/eot/IRANSansWeb_Black.eot"); + src: url("../fonts/eot/IRANSansWeb_Black.eot?#iefix") + format("embedded-opentype"), + /* IE6-8 */ url("../fonts/woff2/IRANSansWeb_Black.woff2") format("woff2"), + /* FF39+,Chrome36+, Opera24+*/ url("../fonts/woff/IRANSansWeb_Black.woff") + format("woff"), + /* FF3.6+, IE9, Chrome6+, Saf5.1+*/ + url("../fonts/ttf/IRANSansWeb_Black.ttf") format("truetype"); +} +@font-face { + font-family: IRANSans; + font-style: normal; + font-weight: bold; + src: url("../fonts/eot/IRANSansWeb_Bold.eot"); + src: url("../fonts/eot/IRANSansWeb_Bold.eot?#iefix") + format("embedded-opentype"), + /* IE6-8 */ url("../fonts/woff2/IRANSansWeb_Bold.woff2") format("woff2"), + /* FF39+,Chrome36+, Opera24+*/ url("../fonts/woff/IRANSansWeb_Bold.woff") + format("woff"), + /* FF3.6+, IE9, Chrome6+, Saf5.1+*/ url("../fonts/ttf/IRANSansWeb_Bold.ttf") + format("truetype"); +} +@font-face { + font-family: IRANSans; + font-style: normal; + font-weight: 500; + src: url("../fonts/eot/IRANSansWeb_Medium.eot"); + src: url("../fonts/eot/IRANSansWeb_Medium.eot?#iefix") + format("embedded-opentype"), + /* IE6-8 */ url("../fonts/woff2/IRANSansWeb_Medium.woff2") format("woff2"), + /* FF39+,Chrome36+, Opera24+*/ url("../fonts/woff/IRANSansWeb_Medium.woff") + format("woff"), + /* FF3.6+, IE9, Chrome6+, Saf5.1+*/ + url("../fonts/ttf/IRANSansWeb_Medium.ttf") format("truetype"); +} +@font-face { + font-family: IRANSans; + font-style: normal; + font-weight: 300; + src: url("../fonts/eot/IRANSansWeb_Light.eot"); + src: url("../fonts/eot/IRANSansWeb_Light.eot?#iefix") + format("embedded-opentype"), + /* IE6-8 */ url("../fonts/woff2/IRANSansWeb_Light.woff2") format("woff2"), + /* FF39+,Chrome36+, Opera24+*/ url("../fonts/woff/IRANSansWeb_Light.woff") + format("woff"), + /* FF3.6+, IE9, Chrome6+, Saf5.1+*/ + url("../fonts/ttf/IRANSansWeb_Light.ttf") format("truetype"); +} +@font-face { + font-family: IRANSans; + font-style: normal; + font-weight: 200; + src: url("../fonts/eot/IRANSansWeb_UltraLight.eot"); + src: url("../fonts/eot/IRANSansWeb_UltraLight.eot?#iefix") + format("embedded-opentype"), + /* IE6-8 */ url("../fonts/woff2/IRANSansWeb_UltraLight.woff2") + format("woff2"), + /* FF39+,Chrome36+, Opera24+*/ + url("../fonts/woff/IRANSansWeb_UltraLight.woff") format("woff"), + /* FF3.6+, IE9, Chrome6+, Saf5.1+*/ + url("../fonts/ttf/IRANSansWeb_UltraLight.ttf") format("truetype"); +} +@font-face { + font-family: IRANSans; + font-style: normal; + font-weight: normal; + src: url("../fonts/eot/IRANSansWeb.eot"); + src: url("../fonts/eot/IRANSansWeb.eot?#iefix") format("embedded-opentype"), + /* IE6-8 */ url("../fonts/woff2/IRANSansWeb.woff2") format("woff2"), + /* FF39+,Chrome36+, Opera24+*/ url("../fonts/woff/IRANSansWeb.woff") + format("woff"), + /* FF3.6+, IE9, Chrome6+, Saf5.1+*/ url("../fonts/ttf/IRANSansWeb.ttf") + format("truetype"); +} diff --git a/src/assets/fonts-old/ttf/IRANSansWeb.ttf b/src/assets/fonts-old/ttf/IRANSansWeb.ttf new file mode 100644 index 0000000..cd74265 Binary files /dev/null and b/src/assets/fonts-old/ttf/IRANSansWeb.ttf differ diff --git a/src/assets/fonts-old/ttf/IRANSansWeb_Black.ttf b/src/assets/fonts-old/ttf/IRANSansWeb_Black.ttf new file mode 100644 index 0000000..0f84dbf Binary files /dev/null and b/src/assets/fonts-old/ttf/IRANSansWeb_Black.ttf differ diff --git a/src/assets/fonts-old/ttf/IRANSansWeb_Bold.ttf b/src/assets/fonts-old/ttf/IRANSansWeb_Bold.ttf new file mode 100644 index 0000000..6fa2412 Binary files /dev/null and b/src/assets/fonts-old/ttf/IRANSansWeb_Bold.ttf differ diff --git a/src/assets/fonts-old/ttf/IRANSansWeb_Light.ttf b/src/assets/fonts-old/ttf/IRANSansWeb_Light.ttf new file mode 100644 index 0000000..d9000c9 Binary files /dev/null and b/src/assets/fonts-old/ttf/IRANSansWeb_Light.ttf differ diff --git a/src/assets/fonts-old/ttf/IRANSansWeb_Medium.ttf b/src/assets/fonts-old/ttf/IRANSansWeb_Medium.ttf new file mode 100644 index 0000000..e20001c Binary files /dev/null and b/src/assets/fonts-old/ttf/IRANSansWeb_Medium.ttf differ diff --git a/src/assets/fonts-old/ttf/IRANSansWeb_UltraLight.ttf b/src/assets/fonts-old/ttf/IRANSansWeb_UltraLight.ttf new file mode 100644 index 0000000..0072606 Binary files /dev/null and b/src/assets/fonts-old/ttf/IRANSansWeb_UltraLight.ttf differ diff --git a/src/assets/fonts-old/woff/IRANSansWeb.woff b/src/assets/fonts-old/woff/IRANSansWeb.woff new file mode 100644 index 0000000..e34dfc4 Binary files /dev/null and b/src/assets/fonts-old/woff/IRANSansWeb.woff differ diff --git a/src/assets/fonts-old/woff/IRANSansWeb_Black.woff b/src/assets/fonts-old/woff/IRANSansWeb_Black.woff new file mode 100644 index 0000000..bbbca77 Binary files /dev/null and b/src/assets/fonts-old/woff/IRANSansWeb_Black.woff differ diff --git a/src/assets/fonts-old/woff/IRANSansWeb_Bold.woff b/src/assets/fonts-old/woff/IRANSansWeb_Bold.woff new file mode 100644 index 0000000..05d933e Binary files /dev/null and b/src/assets/fonts-old/woff/IRANSansWeb_Bold.woff differ diff --git a/src/assets/fonts-old/woff/IRANSansWeb_Light.woff b/src/assets/fonts-old/woff/IRANSansWeb_Light.woff new file mode 100644 index 0000000..fe80d47 Binary files /dev/null and b/src/assets/fonts-old/woff/IRANSansWeb_Light.woff differ diff --git a/src/assets/fonts-old/woff/IRANSansWeb_Medium.woff b/src/assets/fonts-old/woff/IRANSansWeb_Medium.woff new file mode 100644 index 0000000..f13a870 Binary files /dev/null and b/src/assets/fonts-old/woff/IRANSansWeb_Medium.woff differ diff --git a/src/assets/fonts-old/woff/IRANSansWeb_UltraLight.woff b/src/assets/fonts-old/woff/IRANSansWeb_UltraLight.woff new file mode 100644 index 0000000..9c653a4 Binary files /dev/null and b/src/assets/fonts-old/woff/IRANSansWeb_UltraLight.woff differ diff --git a/src/assets/fonts-old/woff2/IRANSansWeb.woff2 b/src/assets/fonts-old/woff2/IRANSansWeb.woff2 new file mode 100644 index 0000000..30a377d Binary files /dev/null and b/src/assets/fonts-old/woff2/IRANSansWeb.woff2 differ diff --git a/src/assets/fonts-old/woff2/IRANSansWeb_Black.woff2 b/src/assets/fonts-old/woff2/IRANSansWeb_Black.woff2 new file mode 100644 index 0000000..0b15441 Binary files /dev/null and b/src/assets/fonts-old/woff2/IRANSansWeb_Black.woff2 differ diff --git a/src/assets/fonts-old/woff2/IRANSansWeb_Bold.woff2 b/src/assets/fonts-old/woff2/IRANSansWeb_Bold.woff2 new file mode 100644 index 0000000..f2353b2 Binary files /dev/null and b/src/assets/fonts-old/woff2/IRANSansWeb_Bold.woff2 differ diff --git a/src/assets/fonts-old/woff2/IRANSansWeb_Light.woff2 b/src/assets/fonts-old/woff2/IRANSansWeb_Light.woff2 new file mode 100644 index 0000000..562d663 Binary files /dev/null and b/src/assets/fonts-old/woff2/IRANSansWeb_Light.woff2 differ diff --git a/src/assets/fonts-old/woff2/IRANSansWeb_Medium.woff2 b/src/assets/fonts-old/woff2/IRANSansWeb_Medium.woff2 new file mode 100644 index 0000000..a69f4d0 Binary files /dev/null and b/src/assets/fonts-old/woff2/IRANSansWeb_Medium.woff2 differ diff --git a/src/assets/fonts-old/woff2/IRANSansWeb_UltraLight.woff2 b/src/assets/fonts-old/woff2/IRANSansWeb_UltraLight.woff2 new file mode 100644 index 0000000..1114f71 Binary files /dev/null and b/src/assets/fonts-old/woff2/IRANSansWeb_UltraLight.woff2 differ diff --git a/src/assets/fonts/eot/iranyekanwebblackfanum.eot b/src/assets/fonts/eot/iranyekanwebblackfanum.eot new file mode 100644 index 0000000..c3ee485 Binary files /dev/null and b/src/assets/fonts/eot/iranyekanwebblackfanum.eot differ diff --git a/src/assets/fonts/eot/iranyekanwebboldfanum.eot b/src/assets/fonts/eot/iranyekanwebboldfanum.eot new file mode 100644 index 0000000..e50057b Binary files /dev/null and b/src/assets/fonts/eot/iranyekanwebboldfanum.eot differ diff --git a/src/assets/fonts/eot/iranyekanwebextrablackfanum.eot b/src/assets/fonts/eot/iranyekanwebextrablackfanum.eot new file mode 100644 index 0000000..e393149 Binary files /dev/null and b/src/assets/fonts/eot/iranyekanwebextrablackfanum.eot differ diff --git a/src/assets/fonts/eot/iranyekanwebextraboldfanum.eot b/src/assets/fonts/eot/iranyekanwebextraboldfanum.eot new file mode 100644 index 0000000..bf5a180 Binary files /dev/null and b/src/assets/fonts/eot/iranyekanwebextraboldfanum.eot differ diff --git a/src/assets/fonts/eot/iranyekanweblightfanum.eot b/src/assets/fonts/eot/iranyekanweblightfanum.eot new file mode 100644 index 0000000..05181ba Binary files /dev/null and b/src/assets/fonts/eot/iranyekanweblightfanum.eot differ diff --git a/src/assets/fonts/eot/iranyekanwebmediumfanum.eot b/src/assets/fonts/eot/iranyekanwebmediumfanum.eot new file mode 100644 index 0000000..f162420 Binary files /dev/null and b/src/assets/fonts/eot/iranyekanwebmediumfanum.eot differ diff --git a/src/assets/fonts/eot/iranyekanwebregularfanum.eot b/src/assets/fonts/eot/iranyekanwebregularfanum.eot new file mode 100644 index 0000000..9c0463b Binary files /dev/null and b/src/assets/fonts/eot/iranyekanwebregularfanum.eot differ diff --git a/src/assets/fonts/eot/iranyekanwebthinfanum.eot b/src/assets/fonts/eot/iranyekanwebthinfanum.eot new file mode 100644 index 0000000..302b1df Binary files /dev/null and b/src/assets/fonts/eot/iranyekanwebthinfanum.eot differ diff --git a/src/assets/fonts/fonts.css b/src/assets/fonts/fonts.css new file mode 100644 index 0000000..4a6c7fc --- /dev/null +++ b/src/assets/fonts/fonts.css @@ -0,0 +1,147 @@ +/** +* +* Name: IRANYekan Font +* Version: 3.0 +* Author: Moslem Ebrahimi (moslemebrahimi.com) +* Created on: Dec 20, 2018 +* Updated on: Dec 20, 2018 +* Website: http://fontiran.com +* Copyright: Commercial/Proprietary Software +-------------------------------------------------------------------------------------- +فونت ایران یکان یک نرم افزار مالکیتی محسوب می شود. جهت آگاهی از قوانین استفاده از این فونت ها لطفا به وب سایت (فونت ایران دات کام) مراجعه نمایید +-------------------------------------------------------------------------------------- +IRANYekan fonts are considered a proprietary software. To gain information about the laws regarding the use of these fonts, please visit www.fontiran.com +-------------------------------------------------------------------------------------- +This set of fonts are used in this project under the license: (.....) +-------------------------------------------------------------------------------------- +* +**/ +@font-face { + font-family: iranyekan; + font-style: normal; + font-weight: bold; + src: url("./eot/iranyekanwebboldfanum.eot"); + src: url("./eot/iranyekanwebboldfanum.eot?#iefix") format("embedded-opentype"), + /* IE6-8 */ url("./woff/iranyekanwebboldfanum.woff") format("woff"), + /* FF3.6+, IE9, Chrome6+, Saf5.1+*/ url("./ttf/iranyekanwebboldfanum.ttf") + format("truetype"); +} + +@font-face { + font-family: iranyekan; + font-style: normal; + font-weight: 100; + src: url("./eot/iranyekanwebthinfanum.eot"); + src: url("./eot/iranyekanwebthinfanum.eot?#iefix") format("embedded-opentype"), + /* IE6-8 */ url("./woff/iranyekanwebthinfanum.woff") format("woff"), + /* FF3.6+, IE9, Chrome6+, Saf5.1+*/ url("./ttf/iranyekanwebthinfanum.ttf") + format("truetype"); +} + +@font-face { + font-family: iranyekan; + font-style: normal; + font-weight: 300; + src: url("./eot/iranyekanweblightfanum.eot"); + src: url("./eot/iranyekanweblightfanum.eot?#iefix") + format("embedded-opentype"), + /* IE6-8 */ url("./woff/iranyekanweblightfanum.woff") format("woff"), + /* FF3.6+, IE9, Chrome6+, Saf5.1+*/ url("./ttf/iranyekanweblightfanum.ttf") + format("truetype"); +} + +@font-face { + font-family: iranyekan; + font-style: normal; + font-weight: normal; + src: url("./eot/iranyekanwebregularfanum.eot"); + src: url("./eot/iranyekanwebregularfanum.eot?#iefix") + format("embedded-opentype"), + /* IE6-8 */ url("./woff/iranyekanwebregularfanum.woff") format("woff"), + /* FF3.6+, IE9, Chrome6+, Saf5.1+*/ + url("./ttf/iranyekanwebregularfanum.ttf") format("truetype"); +} + +@font-face { + font-family: iranyekan; + font-style: normal; + font-weight: 500; + src: url("./eot/iranyekanwebmediumfanum.eot"); + src: url("./eot/iranyekanwebmediumfanum.eot?#iefix") + format("embedded-opentype"), + /* IE6-8 */ url("./woff/iranyekanwebmediumfanum.woff") format("woff"), + /* FF3.6+, IE9, Chrome6+, Saf5.1+*/ url("./ttf/iranyekanwebmediumfanum.ttf") + format("truetype"); +} + +@font-face { + font-family: iranyekan; + font-style: normal; + font-weight: 800; + src: url("./eot/iranyekanwebextraboldfanum.eot"); + src: url("./eot/iranyekanwebextraboldfanum.eot?#iefix") + format("embedded-opentype"), + /* IE6-8 */ url("./woff/iranyekanwebextraboldfanum.woff") format("woff"), + /* FF3.6+, IE9, Chrome6+, Saf5.1+*/ + url("./ttf/iranyekanwebextraboldfanum.ttf") format("truetype"); +} + +@font-face { + font-family: iranyekan; + font-style: normal; + font-weight: 850; + src: url("./eot/iranyekanwebblackfanum.eot"); + src: url("./eot/iranyekanwebblackfanum.eot?#iefix") + format("embedded-opentype"), + /* IE6-8 */ url("./woff/iranyekanwebblackfanum.woff") format("woff"), + /* FF3.6+, IE9, Chrome6+, Saf5.1+*/ url("./ttf/iranyekanwebblackfanum.ttf") + format("truetype"); +} + +@font-face { + font-family: iranyekan; + font-style: normal; + font-weight: 900; + src: url("./eot/iranyekanwebextrablackfanum.eot"); + src: url("./eot/iranyekanwebextrablackfanum.eot?#iefix") + format("embedded-opentype"), + /* IE6-8 */ url("./woff/iranyekanwebextrablackfanum.woff") format("woff"), + /* FF3.6+, IE9, Chrome6+, Saf5.1+*/ + url("./ttf/iranyekanwebextrablackfanum.ttf") format("truetype"); +} + +@font-face { + font-family: "nazanin"; + src: local("nazanin"), url("./ttf/B-NAZANIN.TTF") format("truetype"); + font-weight: bold; +} + +@font-face { + font-family: "titr"; + src: local("titr"), url("./ttf/Titr.ttf") format("truetype"); + font-weight: bold; +} + +/* @font-face { + font-family: "vazir"; + src: local("vazir"), url("./ttf/Vazir-Medium.ttf") format("truetype"); + font-weight: bold; +} + +@font-face { + font-family: "nima"; + src: local("vazir"), url("./ttf/Nima.ttf") format("truetype"); + font-weight: bold; +} + +@font-face { + font-family: "sharif"; + src: local("vazir"), url("./ttf/Sharif.ttf") format("truetype"); + font-weight: bold; +} + +@font-face { + font-family: "azar"; + src: local("vazir"), url("./ttf/AzarMehr.ttf") format("truetype"); + font-weight: bold; +} */ diff --git a/src/assets/fonts/svg/iranyekanwebblackfanum.svg b/src/assets/fonts/svg/iranyekanwebblackfanum.svg new file mode 100644 index 0000000..c791c06 --- /dev/null +++ b/src/assets/fonts/svg/iranyekanwebblackfanum.svg @@ -0,0 +1,1475 @@ + + + + +Created by FontForge 20161003 at Mon Dec 17 00:05:28 2018 + By www-data +Copyright (c) 2019 by fontiran.com. All rights reserved. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/assets/fonts/svg/iranyekanwebboldfanum.svg b/src/assets/fonts/svg/iranyekanwebboldfanum.svg new file mode 100644 index 0000000..fe47d8d --- /dev/null +++ b/src/assets/fonts/svg/iranyekanwebboldfanum.svg @@ -0,0 +1,1578 @@ + + + + +Created by FontForge 20161003 at Mon Dec 17 00:05:43 2018 + By www-data +Copyright (c) 2019 by fontiran.com. All rights reserved. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/assets/fonts/svg/iranyekanwebextrablackfanum.svg b/src/assets/fonts/svg/iranyekanwebextrablackfanum.svg new file mode 100644 index 0000000..cab035f --- /dev/null +++ b/src/assets/fonts/svg/iranyekanwebextrablackfanum.svg @@ -0,0 +1,1489 @@ + + + + +Created by FontForge 20161003 at Mon Dec 17 00:05:52 2018 + By www-data +Copyright (c) 2019 by fontiran.com. All rights reserved. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/assets/fonts/svg/iranyekanwebextraboldfanum.svg b/src/assets/fonts/svg/iranyekanwebextraboldfanum.svg new file mode 100644 index 0000000..62749a2 --- /dev/null +++ b/src/assets/fonts/svg/iranyekanwebextraboldfanum.svg @@ -0,0 +1,1478 @@ + + + + +Created by FontForge 20161003 at Mon Dec 17 00:06:01 2018 + By www-data +Copyright (c) 2018 by fontiran.com. All rights reserved. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/assets/fonts/svg/iranyekanweblightfanum.svg b/src/assets/fonts/svg/iranyekanweblightfanum.svg new file mode 100644 index 0000000..2034329 --- /dev/null +++ b/src/assets/fonts/svg/iranyekanweblightfanum.svg @@ -0,0 +1,1628 @@ + + + + +Created by FontForge 20161003 at Mon Dec 17 00:06:12 2018 + By www-data +Copyright (c) 2019 by fontiran.com. All rights reserved. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/assets/fonts/svg/iranyekanwebmediumfanum.svg b/src/assets/fonts/svg/iranyekanwebmediumfanum.svg new file mode 100644 index 0000000..58a320f --- /dev/null +++ b/src/assets/fonts/svg/iranyekanwebmediumfanum.svg @@ -0,0 +1,1584 @@ + + + + +Created by FontForge 20161003 at Mon Dec 17 00:06:27 2018 + By www-data +Copyright (c) 2019 by fontiran.com. All rights reserved. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/assets/fonts/svg/iranyekanwebregularfanum.svg b/src/assets/fonts/svg/iranyekanwebregularfanum.svg new file mode 100644 index 0000000..39b11b5 --- /dev/null +++ b/src/assets/fonts/svg/iranyekanwebregularfanum.svg @@ -0,0 +1,1560 @@ + + + + +Created by FontForge 20161003 at Mon Dec 17 00:06:43 2018 + By www-data +Copyright (c) 2019 by www.fontiran.com (Moslem Ebrahimi). All rights reserved. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/assets/fonts/svg/iranyekanwebthinfanum.svg b/src/assets/fonts/svg/iranyekanwebthinfanum.svg new file mode 100644 index 0000000..8ad9b7d --- /dev/null +++ b/src/assets/fonts/svg/iranyekanwebthinfanum.svg @@ -0,0 +1,1651 @@ + + + + +Created by FontForge 20161003 at Mon Dec 17 00:06:54 2018 + By www-data +Copyright (c) 2019 by fontiran.com. All rights reserved. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/assets/fonts/ttf/AzarMehr.ttf b/src/assets/fonts/ttf/AzarMehr.ttf new file mode 100644 index 0000000..df7d900 Binary files /dev/null and b/src/assets/fonts/ttf/AzarMehr.ttf differ diff --git a/src/assets/fonts/ttf/B-NAZANIN.TTF b/src/assets/fonts/ttf/B-NAZANIN.TTF new file mode 100644 index 0000000..72bbfc3 Binary files /dev/null and b/src/assets/fonts/ttf/B-NAZANIN.TTF differ diff --git a/src/assets/fonts/ttf/Nima.ttf b/src/assets/fonts/ttf/Nima.ttf new file mode 100644 index 0000000..820564d Binary files /dev/null and b/src/assets/fonts/ttf/Nima.ttf differ diff --git a/src/assets/fonts/ttf/Sharif.ttf b/src/assets/fonts/ttf/Sharif.ttf new file mode 100644 index 0000000..e88fc26 Binary files /dev/null and b/src/assets/fonts/ttf/Sharif.ttf differ diff --git a/src/assets/fonts/ttf/Titr.ttf b/src/assets/fonts/ttf/Titr.ttf new file mode 100644 index 0000000..1cb9034 Binary files /dev/null and b/src/assets/fonts/ttf/Titr.ttf differ diff --git a/src/assets/fonts/ttf/Vazir-Medium.ttf b/src/assets/fonts/ttf/Vazir-Medium.ttf new file mode 100644 index 0000000..1e08dd5 Binary files /dev/null and b/src/assets/fonts/ttf/Vazir-Medium.ttf differ diff --git a/src/assets/fonts/ttf/iranyekanwebblackfanum.ttf b/src/assets/fonts/ttf/iranyekanwebblackfanum.ttf new file mode 100644 index 0000000..39ece30 Binary files /dev/null and b/src/assets/fonts/ttf/iranyekanwebblackfanum.ttf differ diff --git a/src/assets/fonts/ttf/iranyekanwebboldfanum.ttf b/src/assets/fonts/ttf/iranyekanwebboldfanum.ttf new file mode 100644 index 0000000..a68e403 Binary files /dev/null and b/src/assets/fonts/ttf/iranyekanwebboldfanum.ttf differ diff --git a/src/assets/fonts/ttf/iranyekanwebextrablackfanum.ttf b/src/assets/fonts/ttf/iranyekanwebextrablackfanum.ttf new file mode 100644 index 0000000..6218901 Binary files /dev/null and b/src/assets/fonts/ttf/iranyekanwebextrablackfanum.ttf differ diff --git a/src/assets/fonts/ttf/iranyekanwebextraboldfanum.ttf b/src/assets/fonts/ttf/iranyekanwebextraboldfanum.ttf new file mode 100644 index 0000000..ec35796 Binary files /dev/null and b/src/assets/fonts/ttf/iranyekanwebextraboldfanum.ttf differ diff --git a/src/assets/fonts/ttf/iranyekanweblightfanum.ttf b/src/assets/fonts/ttf/iranyekanweblightfanum.ttf new file mode 100644 index 0000000..7a89cfa Binary files /dev/null and b/src/assets/fonts/ttf/iranyekanweblightfanum.ttf differ diff --git a/src/assets/fonts/ttf/iranyekanwebmediumfanum.ttf b/src/assets/fonts/ttf/iranyekanwebmediumfanum.ttf new file mode 100644 index 0000000..551a67f Binary files /dev/null and b/src/assets/fonts/ttf/iranyekanwebmediumfanum.ttf differ diff --git a/src/assets/fonts/ttf/iranyekanwebregularfanum.ttf b/src/assets/fonts/ttf/iranyekanwebregularfanum.ttf new file mode 100644 index 0000000..72d5808 Binary files /dev/null and b/src/assets/fonts/ttf/iranyekanwebregularfanum.ttf differ diff --git a/src/assets/fonts/ttf/iranyekanwebthinfanum.ttf b/src/assets/fonts/ttf/iranyekanwebthinfanum.ttf new file mode 100644 index 0000000..ab55482 Binary files /dev/null and b/src/assets/fonts/ttf/iranyekanwebthinfanum.ttf differ diff --git a/src/assets/fonts/woff/iranyekanwebblackfanum.woff b/src/assets/fonts/woff/iranyekanwebblackfanum.woff new file mode 100644 index 0000000..760df99 Binary files /dev/null and b/src/assets/fonts/woff/iranyekanwebblackfanum.woff differ diff --git a/src/assets/fonts/woff/iranyekanwebboldfanum.woff b/src/assets/fonts/woff/iranyekanwebboldfanum.woff new file mode 100644 index 0000000..07f9756 Binary files /dev/null and b/src/assets/fonts/woff/iranyekanwebboldfanum.woff differ diff --git a/src/assets/fonts/woff/iranyekanwebextrablackfanum.woff b/src/assets/fonts/woff/iranyekanwebextrablackfanum.woff new file mode 100644 index 0000000..6b4943d Binary files /dev/null and b/src/assets/fonts/woff/iranyekanwebextrablackfanum.woff differ diff --git a/src/assets/fonts/woff/iranyekanwebextraboldfanum.woff b/src/assets/fonts/woff/iranyekanwebextraboldfanum.woff new file mode 100644 index 0000000..c04651a Binary files /dev/null and b/src/assets/fonts/woff/iranyekanwebextraboldfanum.woff differ diff --git a/src/assets/fonts/woff/iranyekanweblightfanum.woff b/src/assets/fonts/woff/iranyekanweblightfanum.woff new file mode 100644 index 0000000..9e6d42c Binary files /dev/null and b/src/assets/fonts/woff/iranyekanweblightfanum.woff differ diff --git a/src/assets/fonts/woff/iranyekanwebmediumfanum.woff b/src/assets/fonts/woff/iranyekanwebmediumfanum.woff new file mode 100644 index 0000000..8fe8e40 Binary files /dev/null and b/src/assets/fonts/woff/iranyekanwebmediumfanum.woff differ diff --git a/src/assets/fonts/woff/iranyekanwebregularfanum.woff b/src/assets/fonts/woff/iranyekanwebregularfanum.woff new file mode 100644 index 0000000..3a07dcc Binary files /dev/null and b/src/assets/fonts/woff/iranyekanwebregularfanum.woff differ diff --git a/src/assets/fonts/woff/iranyekanwebthinfanum.woff b/src/assets/fonts/woff/iranyekanwebthinfanum.woff new file mode 100644 index 0000000..2c3b845 Binary files /dev/null and b/src/assets/fonts/woff/iranyekanwebthinfanum.woff differ diff --git a/src/assets/images/ChickenLogo.png b/src/assets/images/ChickenLogo.png new file mode 100644 index 0000000..2fdd234 Binary files /dev/null and b/src/assets/images/ChickenLogo.png differ diff --git a/src/assets/images/ClosedTicketImage.png b/src/assets/images/ClosedTicketImage.png new file mode 100644 index 0000000..c07763b Binary files /dev/null and b/src/assets/images/ClosedTicketImage.png differ diff --git a/src/assets/images/IranOutlined.png b/src/assets/images/IranOutlined.png new file mode 100644 index 0000000..cd8bab8 Binary files /dev/null and b/src/assets/images/IranOutlined.png differ diff --git a/src/assets/images/IranOutlined2.png b/src/assets/images/IranOutlined2.png new file mode 100644 index 0000000..6502089 Binary files /dev/null and b/src/assets/images/IranOutlined2.png differ diff --git a/src/assets/images/Ticket1.png b/src/assets/images/Ticket1.png new file mode 100644 index 0000000..def7b1f Binary files /dev/null and b/src/assets/images/Ticket1.png differ diff --git a/src/assets/images/arrow.png b/src/assets/images/arrow.png new file mode 100644 index 0000000..9a230ae Binary files /dev/null and b/src/assets/images/arrow.png differ diff --git a/src/assets/images/barSquare.png b/src/assets/images/barSquare.png new file mode 100644 index 0000000..7d92caf Binary files /dev/null and b/src/assets/images/barSquare.png differ diff --git a/src/assets/images/barSquareColor.png b/src/assets/images/barSquareColor.png new file mode 100644 index 0000000..ed8d53e Binary files /dev/null and b/src/assets/images/barSquareColor.png differ diff --git a/src/assets/images/bg.jpg b/src/assets/images/bg.jpg new file mode 100644 index 0000000..d3c49cc Binary files /dev/null and b/src/assets/images/bg.jpg differ diff --git a/src/assets/images/check-icon-small.png b/src/assets/images/check-icon-small.png new file mode 100644 index 0000000..163a3ff Binary files /dev/null and b/src/assets/images/check-icon-small.png differ diff --git a/src/assets/images/chicken.png b/src/assets/images/chicken.png new file mode 100644 index 0000000..2f946b3 Binary files /dev/null and b/src/assets/images/chicken.png differ diff --git a/src/assets/images/chicken.svg b/src/assets/images/chicken.svg new file mode 100644 index 0000000..abab00a --- /dev/null +++ b/src/assets/images/chicken.svg @@ -0,0 +1,178 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/assets/images/chickenprice.jpg b/src/assets/images/chickenprice.jpg new file mode 100644 index 0000000..a6d1a82 Binary files /dev/null and b/src/assets/images/chickenprice.jpg differ diff --git a/src/assets/images/dashboard/buyerPerformanceIcon.png b/src/assets/images/dashboard/buyerPerformanceIcon.png new file mode 100644 index 0000000..ac41c65 Binary files /dev/null and b/src/assets/images/dashboard/buyerPerformanceIcon.png differ diff --git a/src/assets/images/dashboard/farmIcon1.png b/src/assets/images/dashboard/farmIcon1.png new file mode 100644 index 0000000..44b558d Binary files /dev/null and b/src/assets/images/dashboard/farmIcon1.png differ diff --git a/src/assets/images/dashboard/farmIcon2.png b/src/assets/images/dashboard/farmIcon2.png new file mode 100644 index 0000000..ae7e8b3 Binary files /dev/null and b/src/assets/images/dashboard/farmIcon2.png differ diff --git a/src/assets/images/dashboard/farmIcon3.png b/src/assets/images/dashboard/farmIcon3.png new file mode 100644 index 0000000..86f6de5 Binary files /dev/null and b/src/assets/images/dashboard/farmIcon3.png differ diff --git a/src/assets/images/dashboard/farmIcon4.png b/src/assets/images/dashboard/farmIcon4.png new file mode 100644 index 0000000..6de21b3 Binary files /dev/null and b/src/assets/images/dashboard/farmIcon4.png differ diff --git a/src/assets/images/dashboard/farmIcon5.png b/src/assets/images/dashboard/farmIcon5.png new file mode 100644 index 0000000..18c0e71 Binary files /dev/null and b/src/assets/images/dashboard/farmIcon5.png differ diff --git a/src/assets/images/dashboard/farmIcon6.png b/src/assets/images/dashboard/farmIcon6.png new file mode 100644 index 0000000..f85d83c Binary files /dev/null and b/src/assets/images/dashboard/farmIcon6.png differ diff --git a/src/assets/images/dashboard/farmIcon7.png b/src/assets/images/dashboard/farmIcon7.png new file mode 100644 index 0000000..6743ff3 Binary files /dev/null and b/src/assets/images/dashboard/farmIcon7.png differ diff --git a/src/assets/images/dashboard/farmIcon8.png b/src/assets/images/dashboard/farmIcon8.png new file mode 100644 index 0000000..1a7ab7b Binary files /dev/null and b/src/assets/images/dashboard/farmIcon8.png differ diff --git a/src/assets/images/dashboard/iconLeft.png b/src/assets/images/dashboard/iconLeft.png new file mode 100644 index 0000000..6a9514d Binary files /dev/null and b/src/assets/images/dashboard/iconLeft.png differ diff --git a/src/assets/images/dashboard/iconRight.png b/src/assets/images/dashboard/iconRight.png new file mode 100644 index 0000000..17e03a5 Binary files /dev/null and b/src/assets/images/dashboard/iconRight.png differ diff --git a/src/assets/images/dashboard/killedInProvinceIcon1.png b/src/assets/images/dashboard/killedInProvinceIcon1.png new file mode 100644 index 0000000..a6d4500 Binary files /dev/null and b/src/assets/images/dashboard/killedInProvinceIcon1.png differ diff --git a/src/assets/images/dashboard/killedInProvinceIcon2.png b/src/assets/images/dashboard/killedInProvinceIcon2.png new file mode 100644 index 0000000..60036cc Binary files /dev/null and b/src/assets/images/dashboard/killedInProvinceIcon2.png differ diff --git a/src/assets/images/dashboard/killedInProvinceIcon3.png b/src/assets/images/dashboard/killedInProvinceIcon3.png new file mode 100644 index 0000000..58360f1 Binary files /dev/null and b/src/assets/images/dashboard/killedInProvinceIcon3.png differ diff --git a/src/assets/images/dashboard/warningIcon.png b/src/assets/images/dashboard/warningIcon.png new file mode 100644 index 0000000..4eef66a Binary files /dev/null and b/src/assets/images/dashboard/warningIcon.png differ diff --git a/src/assets/images/document.jpg b/src/assets/images/document.jpg new file mode 100644 index 0000000..09c0507 Binary files /dev/null and b/src/assets/images/document.jpg differ diff --git a/src/assets/images/dollar-circle.svg b/src/assets/images/dollar-circle.svg new file mode 100644 index 0000000..f79e383 --- /dev/null +++ b/src/assets/images/dollar-circle.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/src/assets/images/eita.png b/src/assets/images/eita.png new file mode 100644 index 0000000..dd50b93 Binary files /dev/null and b/src/assets/images/eita.png differ diff --git a/src/assets/images/enamad-logo.png b/src/assets/images/enamad-logo.png new file mode 100644 index 0000000..17d0448 Binary files /dev/null and b/src/assets/images/enamad-logo.png differ diff --git a/src/assets/images/glass.jpg b/src/assets/images/glass.jpg new file mode 100644 index 0000000..6e7af0b Binary files /dev/null and b/src/assets/images/glass.jpg differ diff --git a/src/assets/images/landingImage.jpg b/src/assets/images/landingImage.jpg new file mode 100644 index 0000000..53793ff Binary files /dev/null and b/src/assets/images/landingImage.jpg differ diff --git a/src/assets/images/landingImage.png b/src/assets/images/landingImage.png new file mode 100644 index 0000000..349bbea Binary files /dev/null and b/src/assets/images/landingImage.png differ diff --git a/src/assets/images/livestock.png b/src/assets/images/livestock.png new file mode 100644 index 0000000..40b9707 Binary files /dev/null and b/src/assets/images/livestock.png differ diff --git a/src/assets/images/livestockColor.png b/src/assets/images/livestockColor.png new file mode 100644 index 0000000..30a7bb8 Binary files /dev/null and b/src/assets/images/livestockColor.png differ diff --git a/src/assets/images/lock-anbar.svg b/src/assets/images/lock-anbar.svg new file mode 100644 index 0000000..39bd5b5 --- /dev/null +++ b/src/assets/images/lock-anbar.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/src/assets/images/lock-dollar.svg b/src/assets/images/lock-dollar.svg new file mode 100644 index 0000000..12c3e90 --- /dev/null +++ b/src/assets/images/lock-dollar.svg @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/src/assets/images/login-bg.png b/src/assets/images/login-bg.png new file mode 100644 index 0000000..10b03de Binary files /dev/null and b/src/assets/images/login-bg.png differ diff --git a/src/assets/images/login-logo.png b/src/assets/images/login-logo.png new file mode 100644 index 0000000..bc5d2ac Binary files /dev/null and b/src/assets/images/login-logo.png differ diff --git a/src/assets/images/login-rasadyar.png b/src/assets/images/login-rasadyar.png new file mode 100644 index 0000000..093a5b3 Binary files /dev/null and b/src/assets/images/login-rasadyar.png differ diff --git a/src/assets/images/login.png b/src/assets/images/login.png new file mode 100644 index 0000000..772c50c Binary files /dev/null and b/src/assets/images/login.png differ diff --git a/src/assets/images/logo.png b/src/assets/images/logo.png new file mode 100644 index 0000000..b2cae35 Binary files /dev/null and b/src/assets/images/logo.png differ diff --git a/src/assets/images/pelak.jpg b/src/assets/images/pelak.jpg new file mode 100644 index 0000000..a0cd6cb Binary files /dev/null and b/src/assets/images/pelak.jpg differ diff --git a/src/assets/images/poultry.png b/src/assets/images/poultry.png new file mode 100644 index 0000000..475df8d Binary files /dev/null and b/src/assets/images/poultry.png differ diff --git a/src/assets/images/poultryColor.png b/src/assets/images/poultryColor.png new file mode 100644 index 0000000..d84258b Binary files /dev/null and b/src/assets/images/poultryColor.png differ diff --git a/src/assets/images/price.jpg b/src/assets/images/price.jpg new file mode 100644 index 0000000..71995df Binary files /dev/null and b/src/assets/images/price.jpg differ diff --git a/src/assets/images/reportFooter.png b/src/assets/images/reportFooter.png new file mode 100644 index 0000000..4606f24 Binary files /dev/null and b/src/assets/images/reportFooter.png differ diff --git a/src/assets/images/reportHeader.png b/src/assets/images/reportHeader.png new file mode 100644 index 0000000..2a2dd0c Binary files /dev/null and b/src/assets/images/reportHeader.png differ diff --git a/src/assets/images/signature.png b/src/assets/images/signature.png new file mode 100644 index 0000000..ae3d4cc Binary files /dev/null and b/src/assets/images/signature.png differ diff --git a/src/assets/images/ticket2.png b/src/assets/images/ticket2.png new file mode 100644 index 0000000..9c5dc12 Binary files /dev/null and b/src/assets/images/ticket2.png differ diff --git a/src/assets/images/ticket3.png b/src/assets/images/ticket3.png new file mode 100644 index 0000000..def7b1f Binary files /dev/null and b/src/assets/images/ticket3.png differ diff --git a/src/assets/images/users.jpg b/src/assets/images/users.jpg new file mode 100644 index 0000000..852e1ab Binary files /dev/null and b/src/assets/images/users.jpg differ diff --git a/src/assets/images/waiting-icon.png b/src/assets/images/waiting-icon.png new file mode 100644 index 0000000..5398930 Binary files /dev/null and b/src/assets/images/waiting-icon.png differ diff --git a/src/assets/lottie/Empty.json b/src/assets/lottie/Empty.json new file mode 100644 index 0000000..a02fa2b --- /dev/null +++ b/src/assets/lottie/Empty.json @@ -0,0 +1 @@ +{"v":"5.7.4","fr":29.9700012207031,"ip":0,"op":75.0000030548126,"w":266,"h":266,"nm":"Comp 1","ddd":0,"assets":[{"id":"image_0","w":38,"h":38,"u":"","p":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACYAAAAmBAMAAABaE/SdAAAAJHpUWHRDcmVhdG9yAAAImXNMyU9KVXBMK0ktUnBNS0tNLikGAEF6Bs5qehXFAAAACXBIWXMAAAABAAAAAQBPJcTWAAAALVBMVEVHcEzzXHTyWnLzWXDzWXLyWnLyWnLxW3LyWnL//v781dv1g5X0dYn5t8L2jp5j9zpmAAAACHRSTlMAQWAroOTGcMVbXa4AAACPSURBVCjPY2DACtgzOhAgxQAkxBzRgQxaQGIWHajAASgWgSbWCDQNTaijlYGBDV2sw4CBA8a8A2MIwMW6Zw2MWA8WsY4XWMQ6KBA7gcXeuVjU3cFnngGmGDCcMcSasIg5YIqB4hdNrEUAJqaAmlo4IMZiiClgiqErA4kpYIphKAOKYShjYMVUxsBswEAMAADsu/0qA5pP3wAAAABJRU5ErkJggg==","e":1},{"id":"image_1","w":73,"h":71,"u":"","p":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEkAAABHCAMAAAB8p5qeAAAAJHpUWHRDcmVhdG9yAAAImXNMyU9KVXBMK0ktUnBNS0tNLikGAEF6Bs5qehXFAAAACXBIWXMAAAABAAAAAQBPJcTWAAAAdVBMVEVHcExTVWxNUGVcYXZjaH5VWW1HSV7a7P9BQ1dqcIVCRFhLTWJHSV5ER1tQUmlNT2WHkaVMTF9vdYqlscVNTmRISl/O3/JcYHZJTGGWobVMTmS2xdhGR1xDRVpNT2RGSF1XWnB6gZXQ4/VNUGVPUmfF1ehdYHci4ka3AAAAJ3RSTlMAvPjy7/X8sv7r9tzm78XQ2A/pySZht9uP0FDBOb52qufftummu82Kdd2xAAADHklEQVRYw9XY23qjIBAA4IgieCZ4iKdoTLTv/4id0bZrthXQ9GJ3bvt9fwZmkKGn038S57orxwRjLPP2BWaM4zj5jCAIyvqQ0wETXy4OhI1xAyq4due9To6M8xH2Ytn0Ada+vLLRii+e5zhSpM2dMTY11WBTm9JHGPY70sot682DqCa2jnSgEGEYGO99Z1nAyOrO/o4JLUgrN4UwIfHdwWg8SoghNUMyZRtRDISSKDKg6hma2HZUBLPKtFWDPZJKaKaiKNBU8DzqIcYEUqWu/m/SS5kuJFLKXjhblvSEFmIFdV3/qqmblHe9xCrXjfxWnZKsmEl46qRq05Tg5IDkb3dCCYUzS4kxClKn3O/JUBKq5bWwuMEQYg0ub7uZzBfHGHF93m5vk0FXfobDOe82Jek1xpLgPt86Mbjh9x0SV0ieNIZYCtJVkdNvSd4OqdLkNP3KPmEXmNduUEjdrn6yQao3e/xi8pn7CIA2ezyDa0XuKd3muTvFsflGSUXpYKNi4+UVLkjb12cNkjMZ94CvuPLG2HGEcUq96rrD6asxbCbeKq9gSGq4GxWOR5ZqNqjjxGB9BUHpEscqqsT1VbobGCHqXBIVdY4ToFI9RISDlGJ+zZLk5tiVDnIbBtQtSRRUDZRtb257Sjl2AGY9U4GW+nmFxeC6CC05i3ner5UFDGCO/z5rFoLMjvv5l3SmOtWImASQFnVE8zSOkyUh8qdNgKLwnlE9WuCNgmM8taWAZ0IlBg8ZuMC5f/NWxzyFh0MYqibFdgTrMWMwgGO4cH1D9BZ8D58oqqEWK3w8yIPgVAnh+1Gf4XT8RDU2UurHTJb34UcgFPb5edlFPAdrCn/pqnsXtXlX9n3fdXW2KshMfXVcQ42on2uLlHym/IMUnE57RTlYjmt2hIrxHMjiq2dt7JCoPUx5TxR82Q9RPVB0TXHNJbF9Dnrs3BV144r73YByitUUxPmRTZ+p8ItaoPx0OkiFISV2Mz+JXoGAuoYhIbR5GZqpCA64cN0XIaSiaP5yvQot1PwFfBXCyxY+XL5y3DCn8FP6O/86a9v29G/HO1j/Y1S5TQboAAAAAElFTkSuQmCC","e":1},{"id":"image_2","w":135,"h":111,"u":"","p":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAIcAAABvCAMAAADxLiPXAAAAJHpUWHRDcmVhdG9yAAAImXNMyU9KVXBMK0ktUnBNS0tNLikGAEF6Bs5qehXFAAAACXBIWXMAAAABAAAAAQBPJcTWAAAATlBMVEVHcEyRmKeRl6Z0fo5weoplcYJUY3R+h5eJkaFtd4SMlqNpdIVsd4d6g5OOlaSQl6deanyPlqWRmKft7e3m5+ikqbWYn63FyM/Y2d20uML3wTkVAAAAEnRSTlMA7l/ZwXA97f0aMpuvhJu7VtIT1ptLAAAEqElEQVRo3uWbi5KjIBBFo5k8MDEPn5P//9FFwAjaQDeCbu1aU1NTU4oHuFwabA6Hf+a6/ZR/AcXpUlXV5bQzxXmgGK7jeUcKdhwQrj9X8ZvthSHff+c88q/bLhTl8O5KtYJsmR1kIuSpq+Il/nHZVibFBaj+STTQkW0tz6Uc7lKwG1HIt92herMfQVhuJ8+z01CSC1aq8fiiKHgjeQITTlpfU51/x9yZztfYg1LLZL4m5Uno9SS+lstCXzTLje1rSp707o7qa6M8Wfiz5dbyTOZrqo9fa4pY72t5nMqs9DX2DpRnVF9jz3B5xvM1Jc+Igz/I1/L18ozga8U10eRA87VcyjPFtC197Y1rjaxKFu9KuVYPPMYQ+8VvjaFfOhQI4xht03dV/EBG2FnVNz3/nSO8q23quu5Fk1zjaVXa+2csO/didMOtdd18qoiBjJzu2l9RdP3xgXAP7dS9nKSNJVg5TKaSfSAP4+a6/hUyqe4xbKPqtYIFSOHAMO/mXdmtlom00U9jFszbOivs/jXDUOScJFQmclppm3mxjRUExpgEy4J9q/2FirWADBifGrxGwQb6Vm8vNWOQjVowJsHe6L7V9Y2t0IYX+mZLjLZ2XGRf03zLVTsTRLp57bxIvmb6Fhbk6+bOSwkW4WsL33KBPCE39zzWonzt7pLnrER98n2i2DXBOhdosG+5dPeA3dz/oMPXbL7lB7H5l0+wBc23nCC5mlU+DeVJm6+5fcvV0/m4YKI+3AK+NsZbpCqJxn3KIZhntC7VJuKS4ltLCiG2aZaRa0hak5iCxfkWVJfMiIdkk9CKmQSL9q1l3z4YEAQRm3UU7OVKb04ljMKycCHWaZyI6cJYdom2NxnQJEomIcKwm3LxJg9h1TWU0WYRxmGp14aKQXjGLgyzSUiuJmI7PnjxIE5hHAKHsIx1+YDJkSBS1siQm2VIf1YhNy/4gAIZOxG7kSC/UXuH8Bj5DxwIECmMd0niuPuH8HcBIji8IKMwTiSOsxjCLluY1kGSww0ihVFyYRA5fK6mLccUhwNEn93JHM7ARF8Vjhw2EHN2p3M4XM1YnH45YJCZY4Rw2AITc408cQAgCxMP4oBdbbZU1zjmIICJB3IAgcl8x0DnMEDk7P42TTyYYx6YLDYuDA4NBJ7dwznMIbzcPzE5RhDb7L6GQwtMgG2cGYcEsc7uqzi+QxjaTZpzyA8Fttl9JYcKTDpgU2vBIUCyEp7d13KoJgH21pYch/xhDfsIHHyx/LJ9sgO2+AAO17YEnoOviiz7YEUOVHMHDvD6HzhuyThuJA7K93gKh9gXwH6/YLTv8XgOlYaB3qmnfY9HcwSkpVC+xyM5AtN08N/jURwr0pawFUBwrEzjwnWol2N9Whsqz8jHESXND5Fn5OaIlvboLcjFETUN1NOwdo7YabFuoVk5EqQJuwaehSNR2rTdiECOhGnktgoCHInT6uEOX3CkP2YADoA5x22LYxeAIZgcG6RrW16kc2yUvg42/MSxYTo/IMQvx6bHG5YDU3FsftxjblSCY5fjL6avDRv3ex0H0gXBf3Y8HqUNkGrf42KaYex7fO7ra7sfJ/z3rj/8USnvgCbE4wAAAABJRU5ErkJggg==","e":1}],"layers":[{"ddd":0,"ind":1,"ty":4,"nm":"Shape Layer 1","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":32,"s":[100]},{"t":41.0000016699642,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[125.5,135.5,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":1,"k":[{"i":{"x":[0.667,0.667],"y":[1,1]},"o":{"x":[0.333,0.333],"y":[0,0]},"t":0,"s":[55,11]},{"i":{"x":[0.667,0.667],"y":[1,1]},"o":{"x":[0.333,0.333],"y":[0,0]},"t":15,"s":[45,7]},{"i":{"x":[0.667,0.667],"y":[1,1]},"o":{"x":[0.333,0.333],"y":[0,0]},"t":30,"s":[55,11]},{"i":{"x":[0.667,0.667],"y":[1,1]},"o":{"x":[0.333,0.333],"y":[0,0]},"t":45,"s":[45,7]},{"t":60.0000024438501,"s":[59,14]}],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"st","c":{"a":0,"k":[1,1,1,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":0,"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[0.827450980392,0.827450980392,0.827450980392,1],"ix":4},"o":{"a":0,"k":50,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[83,60],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":75.0000030548126,"st":0,"bm":0},{"ddd":0,"ind":2,"ty":2,"nm":"Error Icon","refId":"image_0","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":33,"s":[0]},{"t":48.0000019550801,"s":[100]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"t":33,"s":[168.234,106.021,0],"to":[1.833,-5.333,0],"ti":[-1.833,5.333,0]},{"t":48.0000019550801,"s":[179.234,74.021,0]}],"ix":2,"l":2},"a":{"a":0,"k":[18.707,18.707,0],"ix":1,"l":2},"s":{"a":1,"k":[{"i":{"x":[0.667,0.667,0.667],"y":[1,1,1]},"o":{"x":[0.333,0.333,0.333],"y":[0,0,0]},"t":33,"s":[20,20,100]},{"t":48.0000019550801,"s":[100,100,100]}],"ix":6,"l":2}},"ao":0,"ip":31.0000012626559,"op":75.0000030548126,"st":31.0000012626559,"bm":0},{"ddd":0,"ind":3,"ty":2,"nm":"Search Icon","refId":"image_1","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":32,"s":[100]},{"t":41.0000016699642,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"t":0,"s":[180.298,138.638,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"t":15,"s":[181.298,106.263,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"t":30,"s":[180.298,147.638,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"t":45,"s":[181.298,106.263,0],"to":[0,0,0],"ti":[0,0,0]},{"t":60.0000024438501,"s":[180.298,147.638,0]}],"ix":2,"l":2},"a":{"a":0,"k":[36.205,35.348,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"ip":0,"op":75.0000030548126,"st":0,"bm":0},{"ddd":0,"ind":4,"ty":2,"nm":"Box Icon","refId":"image_2","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.833],"y":[1]},"o":{"x":[0.167],"y":[0]},"t":0,"s":[0]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":3,"s":[2]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":6,"s":[0]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":9,"s":[-2]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":12,"s":[0]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":15,"s":[2]},{"i":{"x":[0.833],"y":[1]},"o":{"x":[0.167],"y":[0]},"t":18,"s":[0]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":21,"s":[-2]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":24,"s":[0]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":27,"s":[2]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":30,"s":[0]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":33,"s":[-2]},{"t":36.0000014663101,"s":[0]}],"ix":10},"p":{"a":0,"k":[133,139,0],"ix":2,"l":2},"a":{"a":0,"k":[67.471,55.221,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"ip":0,"op":75.0000030548126,"st":0,"bm":0}],"markers":[]} \ No newline at end of file diff --git a/src/assets/lottie/error.json b/src/assets/lottie/error.json new file mode 100644 index 0000000..4eaf3d3 --- /dev/null +++ b/src/assets/lottie/error.json @@ -0,0 +1 @@ +{"v":"5.8.1","fr":29.9700012207031,"ip":0,"op":301.000012259981,"w":1080,"h":1080,"nm":"Composition 1","ddd":0,"assets":[{"id":"comp_0","nm":"Nuage","fr":29.9700012207031,"layers":[{"ddd":0,"ind":1,"ty":4,"nm":"Calque de forme 11","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[540,540,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[54,54],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Tracé d'ellipse 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.901960784314,0.901960784314,0.901960784314,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fond 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-22,-239],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transformer "}],"nm":"Ellipse 1","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":630.000025660426,"st":0,"bm":0},{"ddd":0,"ind":2,"ty":4,"nm":"Calque de forme 12","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[544.675,315.475,0],"ix":2,"l":2},"a":{"a":0,"k":[-54.5,-226.5,0],"ix":1,"l":2},"s":{"a":0,"k":[80,80,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[31,31],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Tracé d'ellipse 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.901960784314,0.901960784314,0.901960784314,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fond 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-54.5,-226.5],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transformer "}],"nm":"Ellipse 1","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":630.000025660426,"st":0,"bm":0},{"ddd":0,"ind":3,"ty":4,"nm":"Calque de forme 10","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[540,540,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[31,31],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Tracé d'ellipse 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.901960784314,0.901960784314,0.901960784314,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fond 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-54.5,-226.5],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transformer "}],"nm":"Ellipse 1","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":630.000025660426,"st":0,"bm":0},{"ddd":0,"ind":4,"ty":4,"nm":"Calque de forme 9","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[540,540,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"rc","d":1,"s":{"a":0,"k":[100,20],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"r":{"a":0,"k":20,"ix":4},"nm":"Tracé rectangulaire 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"fl","c":{"a":0,"k":[0.901960784314,0.901960784314,0.901960784314,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fond 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-26,-216],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transformer "}],"nm":"Rectangle 1","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":630.000025660426,"st":0,"bm":0}]},{"id":"comp_1","nm":"éolienne","fr":29.9700012207031,"layers":[{"ddd":0,"ind":1,"ty":0,"nm":"Hélices","refId":"comp_2","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.137],"y":[1]},"o":{"x":[0.567],"y":[0]},"t":1,"s":[0]},{"t":300.00001221925,"s":[1440]}],"ix":10},"p":{"a":0,"k":[800,440,0],"ix":2,"l":2},"a":{"a":0,"k":[800,440,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"w":1080,"h":1080,"ip":0,"op":630.000025660426,"st":0,"bm":0},{"ddd":0,"ind":2,"ty":4,"nm":"Socle eolienne","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[540,540,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[264.75,-95],[257,-95],[242,252],[288,251]],"c":true},"ix":2},"nm":"Tracé 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.901960784314,0.901960784314,0.901960784314,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fond 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transformer "}],"nm":"Forme 1","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":630.000025660426,"st":0,"bm":0}]},{"id":"comp_2","nm":"Hélices","fr":29.9700012207031,"layers":[{"ddd":0,"ind":1,"ty":4,"nm":"Calque de forme 11","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":-239.6,"ix":10},"p":{"a":0,"k":[803,442,0],"ix":2,"l":2},"a":{"a":0,"k":[263,-98,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0]],"v":[[310,-98],[284,-92],[263,-96],[439,10],[423,-17]],"c":true},"ix":2},"nm":"Tracé 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.901960784314,0.901960784314,0.901960784314,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fond 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transformer "}],"nm":"Forme 1","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":630.000025660426,"st":0,"bm":0},{"ddd":0,"ind":2,"ty":4,"nm":"Calque de forme 10","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":-122.747,"ix":10},"p":{"a":0,"k":[803,442,0],"ix":2,"l":2},"a":{"a":0,"k":[263,-98,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0]],"v":[[310,-98],[284,-92],[263,-96],[439,10],[423,-17]],"c":true},"ix":2},"nm":"Tracé 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.901960784314,0.901960784314,0.901960784314,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fond 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transformer "}],"nm":"Forme 1","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":630.000025660426,"st":0,"bm":0},{"ddd":0,"ind":3,"ty":4,"nm":"Calque de forme 9","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[803,442,0],"ix":2,"l":2},"a":{"a":0,"k":[263,-98,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0]],"v":[[310,-98],[284,-92],[263,-96],[439,10],[423,-17]],"c":true},"ix":2},"nm":"Tracé 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.901960784314,0.901960784314,0.901960784314,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fond 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transformer "}],"nm":"Forme 1","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":630.000025660426,"st":0,"bm":0},{"ddd":0,"ind":4,"ty":4,"nm":"Calque de forme 8","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[800.5,439.5,0],"ix":2,"l":2},"a":{"a":0,"k":[266.5,-94.5,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[27,27],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Tracé d'ellipse 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.901960784314,0.901960784314,0.901960784314,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fond 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[266.5,-94.5],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transformer "}],"nm":"Ellipse 1","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":630.000025660426,"st":0,"bm":0}]},{"id":"comp_3","nm":"plot base","fr":29.9700012207031,"layers":[{"ddd":0,"ind":1,"ty":4,"nm":"Calque de forme 8","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[541,387.5,0],"ix":2,"l":2},"a":{"a":0,"k":[1,-152.5,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[13,-223],[-13,-223],[-52,-82],[54,-82]],"c":true},"ix":2},"nm":"Tracé 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.9019607843137255,0.3764705882352941,0.27058823529411763,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fond 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transformer "}],"nm":"Forme 1","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":630.000025660426,"st":0,"bm":0},{"ddd":0,"ind":2,"ty":4,"nm":"Calque de forme 7","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[540,502,0],"ix":2,"l":2},"a":{"a":0,"k":[0,-38,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[58,-56],[-59,-56],[-70,-20],[70,-20]],"c":true},"ix":2},"nm":"Tracé 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.9019607843137255,0.3764705882352941,0.27058823529411763,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fond 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transformer "}],"nm":"Forme 1","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":630.000025660426,"st":0,"bm":0},{"ddd":0,"ind":3,"ty":4,"nm":"Calque de forme 5","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[539.75,606.25,0],"ix":2,"l":2},"a":{"a":0,"k":[-0.25,66.25,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"rc","d":1,"s":{"a":0,"k":[256.5,28.5],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"r":{"a":0,"k":0,"ix":4},"nm":"Tracé rectangulaire 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"fl","c":{"a":0,"k":[0.7647058823529411,0.3215686274509804,0.23137254901960785,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fond 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-0.25,66.25],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transformer "}],"nm":"Rectangle 1","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":630.000025660426,"st":0,"bm":0},{"ddd":0,"ind":4,"ty":4,"nm":"Calque de forme 6","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[540,572,0],"ix":2,"l":2},"a":{"a":0,"k":[0,32,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[78,3],[-76,3],[-93,60],[93,61]],"c":true},"ix":2},"nm":"Tracé 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.9019607843137255,0.3764705882352941,0.27058823529411763,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fond 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transformer "}],"nm":"Forme 1","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":630.000025660426,"st":0,"bm":0}]},{"id":"comp_4","nm":"Tree","fr":29.9700012207031,"layers":[{"ddd":0,"ind":1,"ty":4,"nm":"Calque de forme 10","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[540,540,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-171.5,-79.5],[-152.5,-45]],"c":false},"ix":2},"nm":"Tracé 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.850980451995,0.84313731474,0.84313731474,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":7,"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"Contour 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transformer "}],"nm":"Forme 1","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":630.000025660426,"st":0,"bm":0},{"ddd":0,"ind":2,"ty":4,"nm":"Calque de forme 9","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[540,540,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-154.5,-23.5],[-137.5,-48.5]],"c":false},"ix":2},"nm":"Tracé 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.850980451995,0.84313731474,0.84313731474,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":7,"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"Contour 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transformer "}],"nm":"Forme 1","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":630.000025660426,"st":0,"bm":0},{"ddd":0,"ind":3,"ty":4,"nm":"Calque de forme 7","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[386,620,0],"ix":2,"l":2},"a":{"a":0,"k":[-154,80,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-154,256],[-154,-96]],"c":false},"ix":2},"nm":"Tracé 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.850980392157,0.844306078144,0.844306078144,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":10,"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"Contour 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transformer "}],"nm":"Forme 1","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":630.000025660426,"st":0,"bm":0},{"ddd":0,"ind":4,"ty":4,"nm":"Calque de forme 8","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[384,475,0],"ix":2,"l":2},"a":{"a":0,"k":[-156,-65,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"rc","d":1,"s":{"a":0,"k":[96,222],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"r":{"a":0,"k":62,"ix":4},"nm":"Tracé rectangulaire 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"fl","c":{"a":0,"k":[0.949019667682,0.949019667682,0.949019667682,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fond 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-156,-65],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transformer "}],"nm":"Rectangle 1","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":630.000025660426,"st":0,"bm":0}]},{"id":"comp_5","nm":"ground","fr":29.9700012207031,"layers":[{"ddd":0,"ind":1,"ty":4,"nm":"Calque de forme 2","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[515,795.5,0],"ix":2,"l":2},"a":{"a":0,"k":[-273.5,78,0],"ix":1,"l":2},"s":{"a":0,"k":[662,317,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"rc","d":1,"s":{"a":0,"k":[59,2],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"r":{"a":0,"k":2371,"ix":4},"nm":"Tracé rectangulaire 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"fl","c":{"a":0,"k":[0.133333333333,0.145098039216,0.235294132607,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fond 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-273.5,78],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transformer "}],"nm":"Rectangle 1","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":630.000025660426,"st":0,"bm":0},{"ddd":0,"ind":2,"ty":4,"nm":"Calque de forme 4","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[817,795.5,0],"ix":2,"l":2},"a":{"a":0,"k":[-273.5,78,0],"ix":1,"l":2},"s":{"a":0,"k":[78,317,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"rc","d":1,"s":{"a":0,"k":[59,2],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"r":{"a":0,"k":2371,"ix":4},"nm":"Tracé rectangulaire 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"fl","c":{"a":0,"k":[0.133333333333,0.145098039216,0.235294132607,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fond 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-273.5,78],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transformer "}],"nm":"Rectangle 1","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":630.000025660426,"st":0,"bm":0},{"ddd":0,"ind":3,"ty":4,"nm":"Calque de forme 3","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[752,795.5,0],"ix":2,"l":2},"a":{"a":0,"k":[-273.5,78,0],"ix":1,"l":2},"s":{"a":0,"k":[89,317,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"rc","d":1,"s":{"a":0,"k":[59,2],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"r":{"a":0,"k":2371,"ix":4},"nm":"Tracé rectangulaire 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"fl","c":{"a":0,"k":[0.133333333333,0.145098039216,0.235294132607,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fond 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-273.5,78],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transformer "}],"nm":"Rectangle 1","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":630.000025660426,"st":0,"bm":0},{"ddd":0,"ind":4,"ty":4,"nm":"Calque de forme 1","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[270,795.5,0],"ix":2,"l":2},"a":{"a":0,"k":[-273.5,78,0],"ix":1,"l":2},"s":{"a":0,"k":[102,317,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"rc","d":1,"s":{"a":0,"k":[59,2],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"r":{"a":0,"k":2371,"ix":4},"nm":"Tracé rectangulaire 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"fl","c":{"a":0,"k":[0.133333333333,0.145098039216,0.235294132607,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fond 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-273.5,78],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transformer "}],"nm":"Rectangle 1","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":630.000025660426,"st":0,"bm":0}]}],"layers":[{"ddd":0,"ind":1,"ty":0,"nm":"Nuage","refId":"comp_0","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":0,"s":[0]},{"i":{"x":[0.833],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":51,"s":[100]},{"i":{"x":[0.833],"y":[1]},"o":{"x":[0.167],"y":[0]},"t":234,"s":[100]},{"t":299.00001217852,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.284,"y":1},"o":{"x":0.387,"y":0},"t":0,"s":[704,380,0],"to":[-36.667,0,0],"ti":[36.667,0,0]},{"t":299.00001217852,"s":[484,380,0]}],"ix":2,"l":2},"a":{"a":0,"k":[514,308,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"w":1080,"h":1080,"ip":0,"op":630.000025660426,"st":0,"bm":0},{"ddd":0,"ind":2,"ty":4,"nm":"Calque de forme 7","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[540,540,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.5,-0.5],[0,0.5],[0,-1],[0,-0.5],[0,0],[0.5,-0.5],[0,0],[0.5,-0.5],[-0.5,-0.5]],"o":[[-19,-5],[-34,-13],[-18.5,1.5],[-17,10.5],[0,0],[17,-19.5],[6.5,-4],[-3.5,-13],[11.5,-19.5]],"v":[[263.5,176],[242.5,196],[218,213],[209.5,232.5],[215,254.5],[297,253.5],[289.5,225],[294,210],[271.5,204]],"c":true},"ix":2},"nm":"Tracé 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.83137254902,0.821591725069,0.821591725069,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fond 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transformer "}],"nm":"Forme 1","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":630.000025660426,"st":0,"bm":0},{"ddd":0,"ind":3,"ty":0,"nm":"éolienne","refId":"comp_1","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[804,796,0],"ix":2,"l":2},"a":{"a":0,"k":[804,796,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"w":1080,"h":1080,"ip":0,"op":630.000025660426,"st":0,"bm":0},{"ddd":0,"ind":4,"ty":0,"nm":"plot base","refId":"comp_3","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":0,"s":[0]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":7.368,"s":[6]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":14.736,"s":[-5]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":22.264,"s":[4]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":29.633,"s":[-2]},{"t":37.0000015070409,"s":[0]}],"ix":10},"p":{"a":1,"k":[{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"t":0,"s":[540,792,0],"to":[0,-2.667,0],"ti":[0,2,0]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"t":7.368,"s":[540,776,0],"to":[0,-2,0],"ti":[0,-1.333,0]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"t":14.736,"s":[540,780,0],"to":[0,1.333,0],"ti":[0,-1.333,0]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"t":22.264,"s":[540,784,0],"to":[0,1.333,0],"ti":[0,-2,0]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"t":29.633,"s":[540,788,0],"to":[0,2,0],"ti":[0,-1.333,0]},{"t":37.0000015070409,"s":[540,796,0]}],"ix":2,"l":2},"a":{"a":0,"k":[540,616,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"w":1080,"h":1080,"ip":0,"op":630.000025660426,"st":0,"bm":0},{"ddd":0,"ind":5,"ty":0,"nm":"éolienne","refId":"comp_1","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[670,796,0],"ix":2,"l":2},"a":{"a":0,"k":[804,796,0],"ix":1,"l":2},"s":{"a":0,"k":[63,63,100],"ix":6,"l":2}},"ao":0,"w":1080,"h":1080,"ip":0,"op":630.000025660426,"st":0,"bm":0},{"ddd":0,"ind":6,"ty":0,"nm":"Tree","refId":"comp_4","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[280,790,0],"ix":2,"l":2},"a":{"a":0,"k":[384,790,0],"ix":1,"l":2},"s":{"a":0,"k":[82,82,100],"ix":6,"l":2}},"ao":0,"w":1080,"h":1080,"ip":0,"op":630.000025660426,"st":0,"bm":0},{"ddd":0,"ind":7,"ty":0,"nm":"Tree","refId":"comp_4","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[540,540,0],"ix":2,"l":2},"a":{"a":0,"k":[540,540,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"w":1080,"h":1080,"ip":0,"op":630.000025660426,"st":0,"bm":0},{"ddd":0,"ind":8,"ty":4,"nm":"Arbuste","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[68,540,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.5,-0.5],[0,0.5],[0,-1],[0,-0.5],[0,0],[0.5,-0.5],[0,0],[0.5,-0.5],[-0.5,-0.5]],"o":[[-19,-5],[-34,-13],[-18.5,1.5],[-17,10.5],[0,0],[17,-19.5],[6.5,-4],[-3.5,-13],[11.5,-19.5]],"v":[[263.5,176],[242.5,196],[218,213],[209.5,232.5],[215,254.5],[297,253.5],[289.5,225],[294,210],[271.5,204]],"c":true},"ix":2},"nm":"Tracé 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.901960784314,0.901960784314,0.901960784314,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fond 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transformer "}],"nm":"Forme 1","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":630.000025660426,"st":0,"bm":0},{"ddd":0,"ind":9,"ty":0,"nm":"ground","refId":"comp_5","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[540,540,0],"ix":2,"l":2},"a":{"a":0,"k":[540,540,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"w":1080,"h":1080,"ip":0,"op":630.000025660426,"st":0,"bm":0},{"ddd":0,"ind":10,"ty":0,"nm":"Nuage","refId":"comp_0","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":0,"s":[0]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":51,"s":[100]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":234,"s":[100]},{"t":299.00001217852,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"t":0,"s":[193,606,0],"to":[56.5,0,0],"ti":[-56.5,0,0]},{"t":299.00001217852,"s":[532,606,0]}],"ix":2,"l":2},"a":{"a":0,"k":[514,308,0],"ix":1,"l":2},"s":{"a":0,"k":[60,60,100],"ix":6,"l":2}},"ao":0,"w":1080,"h":1080,"ip":0,"op":630.000025660426,"st":0,"bm":0},{"ddd":0,"ind":11,"ty":4,"nm":"Calque de forme 6","td":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[572,712,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"rc","d":1,"s":{"a":0,"k":[784,628],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"r":{"a":0,"k":0,"ix":4},"nm":"Tracé rectangulaire 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"fl","c":{"a":0,"k":[0.909803921569,0.909803921569,0.909803921569,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fond 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-36,-234],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transformer "}],"nm":"Rectangle 1","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":630.000025660426,"st":0,"bm":0},{"ddd":0,"ind":12,"ty":4,"nm":"Calque de forme 5","tt":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[540,716,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[728,728],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Tracé d'ellipse 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.976470588235,0.976470588235,0.976470588235,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fond 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[8,-140],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transformer "}],"nm":"Ellipse 1","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":630.000025660426,"st":0,"bm":0},{"ddd":0,"ind":14,"ty":1,"nm":"Blanc uni 1","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[540,540,0],"ix":2,"l":2},"a":{"a":0,"k":[540,540,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"sw":1080,"sh":1080,"sc":"#ffffff00","ip":0,"op":630.000025660426,"st":0,"bm":0}],"markers":[]} \ No newline at end of file diff --git a/src/assets/lottie/loading.json b/src/assets/lottie/loading.json new file mode 100644 index 0000000..96181b3 --- /dev/null +++ b/src/assets/lottie/loading.json @@ -0,0 +1 @@ +{"assets":[],"layers":[{"ddd":0,"ind":0,"ty":4,"nm":"形状图层 5","ks":{"o":{"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.333],"y":[0]},"n":["0p833_0p833_0p333_0"],"t":8,"s":[100],"e":[30]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.333],"y":[0]},"n":["0p833_0p833_0p333_0"],"t":24,"s":[30],"e":[100]},{"t":40}]},"r":{"k":0},"p":{"k":[187.875,77.125,0]},"a":{"k":[-76.375,-2.875,0]},"s":{"k":[{"i":{"x":[0.833,0.833,0.833],"y":[0.833,0.833,0.833]},"o":{"x":[0.333,0.333,0.333],"y":[0,0,0.333]},"n":["0p833_0p833_0p333_0","0p833_0p833_0p333_0","0p833_0p833_0p333_0p333"],"t":8,"s":[100,100,100],"e":[200,200,100]},{"i":{"x":[0.833,0.833,0.833],"y":[0.833,0.833,0.833]},"o":{"x":[0.333,0.333,0.333],"y":[0,0,0.333]},"n":["0p833_0p833_0p333_0","0p833_0p833_0p333_0","0p833_0p833_0p333_0p333"],"t":24,"s":[200,200,100],"e":[100,100,100]},{"t":40}]}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"k":[18,18]},"p":{"k":[0,0]},"nm":"椭圆路径 1","mn":"ADBE Vector Shape - Ellipse"},{"ty":"st","c":{"k":[1,1,1,1]},"o":{"k":100},"w":{"k":0},"lc":1,"lj":1,"ml":4,"nm":"描边 1","mn":"ADBE Vector Graphic - Stroke"},{"ty":"fl","c":{"k":[0.87,0.42,0.56,1]},"o":{"k":100},"nm":"填充 1","mn":"ADBE Vector Graphic - Fill"},{"ty":"tr","p":{"k":[-76.482,-3.482],"ix":2},"a":{"k":[0,0],"ix":1},"s":{"k":[100,100],"ix":3},"r":{"k":0,"ix":6},"o":{"k":100,"ix":7},"sk":{"k":0,"ix":4},"sa":{"k":0,"ix":5},"nm":"变换"}],"nm":"椭圆 1","np":3,"mn":"ADBE Vector Group"}],"ip":0,"op":40,"st":0,"bm":0,"sr":1},{"ddd":0,"ind":1,"ty":4,"nm":"形状图层 4","ks":{"o":{"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.333],"y":[0]},"n":["0p833_0p833_0p333_0"],"t":6,"s":[100],"e":[30]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.333],"y":[0]},"n":["0p833_0p833_0p333_0"],"t":22,"s":[30],"e":[100]},{"t":36}]},"r":{"k":0},"p":{"k":[162.125,76.625,0]},"a":{"k":[-76.375,-2.875,0]},"s":{"k":[{"i":{"x":[0.833,0.833,0.833],"y":[0.833,0.833,0.833]},"o":{"x":[0.333,0.333,0.333],"y":[0,0,0.333]},"n":["0p833_0p833_0p333_0","0p833_0p833_0p333_0","0p833_0p833_0p333_0p333"],"t":6,"s":[100,100,100],"e":[200,200,100]},{"i":{"x":[0.833,0.833,0.833],"y":[0.833,0.833,0.833]},"o":{"x":[0.333,0.333,0.333],"y":[0,0,0.333]},"n":["0p833_0p833_0p333_0","0p833_0p833_0p333_0","0p833_0p833_0p333_0p333"],"t":22,"s":[200,200,100],"e":[100,100,100]},{"t":36}]}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"k":[18,18]},"p":{"k":[0,0]},"nm":"椭圆路径 1","mn":"ADBE Vector Shape - Ellipse"},{"ty":"st","c":{"k":[1,1,1,1]},"o":{"k":100},"w":{"k":0},"lc":1,"lj":1,"ml":4,"nm":"描边 1","mn":"ADBE Vector Graphic - Stroke"},{"ty":"fl","c":{"k":[0.81,0.55,0.82,1]},"o":{"k":100},"nm":"填充 1","mn":"ADBE Vector Graphic - Fill"},{"ty":"tr","p":{"k":[-76.482,-3.482],"ix":2},"a":{"k":[0,0],"ix":1},"s":{"k":[100,100],"ix":3},"r":{"k":0,"ix":6},"o":{"k":100,"ix":7},"sk":{"k":0,"ix":4},"sa":{"k":0,"ix":5},"nm":"变换"}],"nm":"椭圆 1","np":3,"mn":"ADBE Vector Group"}],"ip":0,"op":40,"st":0,"bm":0,"sr":1},{"ddd":0,"ind":2,"ty":4,"nm":"形状图层 3","ks":{"o":{"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.333],"y":[0]},"n":["0p833_0p833_0p333_0"],"t":4,"s":[100],"e":[30]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.333],"y":[0]},"n":["0p833_0p833_0p333_0"],"t":20,"s":[30],"e":[100]},{"t":32}]},"r":{"k":0},"p":{"k":[135.625,76.625,0]},"a":{"k":[-76.375,-2.875,0]},"s":{"k":[{"i":{"x":[0.833,0.833,0.833],"y":[0.833,0.833,0.833]},"o":{"x":[0.333,0.333,0.333],"y":[0,0,0.333]},"n":["0p833_0p833_0p333_0","0p833_0p833_0p333_0","0p833_0p833_0p333_0p333"],"t":4,"s":[100,100,100],"e":[200,200,100]},{"i":{"x":[0.833,0.833,0.833],"y":[0.833,0.833,0.833]},"o":{"x":[0.333,0.333,0.333],"y":[0,0,0.333]},"n":["0p833_0p833_0p333_0","0p833_0p833_0p333_0","0p833_0p833_0p333_0p333"],"t":20,"s":[200,200,100],"e":[100,100,100]},{"t":32}]}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"k":[18,18]},"p":{"k":[0,0]},"nm":"椭圆路径 1","mn":"ADBE Vector Shape - Ellipse"},{"ty":"st","c":{"k":[1,1,1,1]},"o":{"k":100},"w":{"k":0},"lc":1,"lj":1,"ml":4,"nm":"描边 1","mn":"ADBE Vector Graphic - Stroke"},{"ty":"fl","c":{"k":[0.47,0.31,0.62,1]},"o":{"k":100},"nm":"填充 1","mn":"ADBE Vector Graphic - Fill"},{"ty":"tr","p":{"k":[-76.482,-3.482],"ix":2},"a":{"k":[0,0],"ix":1},"s":{"k":[100,100],"ix":3},"r":{"k":0,"ix":6},"o":{"k":100,"ix":7},"sk":{"k":0,"ix":4},"sa":{"k":0,"ix":5},"nm":"变换"}],"nm":"椭圆 1","np":3,"mn":"ADBE Vector Group"}],"ip":0,"op":40,"st":0,"bm":0,"sr":1},{"ddd":0,"ind":3,"ty":4,"nm":"形状图层 2","ks":{"o":{"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.333],"y":[0]},"n":["0p833_0p833_0p333_0"],"t":2,"s":[100],"e":[30]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.333],"y":[0]},"n":["0p833_0p833_0p333_0"],"t":16,"s":[30],"e":[100]},{"t":28}]},"r":{"k":0},"p":{"k":[109.375,76.625,0]},"a":{"k":[-76.625,-3.125,0]},"s":{"k":[{"i":{"x":[0.833,0.833,0.833],"y":[0.833,0.833,0.833]},"o":{"x":[0.333,0.333,0.333],"y":[0,0,0.333]},"n":["0p833_0p833_0p333_0","0p833_0p833_0p333_0","0p833_0p833_0p333_0p333"],"t":2,"s":[100,100,100],"e":[200,200,100]},{"i":{"x":[0.833,0.833,0.833],"y":[0.833,0.833,0.833]},"o":{"x":[0.333,0.333,0.333],"y":[0,0,0.333]},"n":["0p833_0p833_0p333_0","0p833_0p833_0p333_0","0p833_0p833_0p333_0p333"],"t":16,"s":[200,200,100],"e":[100,100,100]},{"t":28}]}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"k":[18,18]},"p":{"k":[0,0]},"nm":"椭圆路径 1","mn":"ADBE Vector Shape - Ellipse"},{"ty":"st","c":{"k":[1,1,1,1]},"o":{"k":100},"w":{"k":0},"lc":1,"lj":1,"ml":4,"nm":"描边 1","mn":"ADBE Vector Graphic - Stroke"},{"ty":"fl","c":{"k":[0.54,0.81,0.89,1]},"o":{"k":100},"nm":"填充 1","mn":"ADBE Vector Graphic - Fill"},{"ty":"tr","p":{"k":[-76.482,-3.482],"ix":2},"a":{"k":[0,0],"ix":1},"s":{"k":[100,100],"ix":3},"r":{"k":0,"ix":6},"o":{"k":100,"ix":7},"sk":{"k":0,"ix":4},"sa":{"k":0,"ix":5},"nm":"变换"}],"nm":"椭圆 1","np":3,"mn":"ADBE Vector Group"}],"ip":0,"op":40,"st":0,"bm":0,"sr":1},{"ddd":0,"ind":4,"ty":4,"nm":"形状图层 1","ks":{"o":{"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.333],"y":[0]},"n":["0p833_0p833_0p333_0"],"t":0,"s":[100],"e":[30]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.333],"y":[0]},"n":["0p833_0p833_0p333_0"],"t":12,"s":[30],"e":[100]},{"t":24}]},"r":{"k":0},"p":{"k":[82.625,76.625,0]},"a":{"k":[-76.625,-3.375,0]},"s":{"k":[{"i":{"x":[0.833,0.833,0.833],"y":[0.833,0.833,0.833]},"o":{"x":[0.333,0.333,0.333],"y":[0,0,0.333]},"n":["0p833_0p833_0p333_0","0p833_0p833_0p333_0","0p833_0p833_0p333_0p333"],"t":0,"s":[100,100,100],"e":[200,200,100]},{"i":{"x":[0.833,0.833,0.833],"y":[0.833,0.833,0.833]},"o":{"x":[0.333,0.333,0.333],"y":[0,0,0.333]},"n":["0p833_0p833_0p333_0","0p833_0p833_0p333_0","0p833_0p833_0p333_0p333"],"t":12,"s":[200,200,100],"e":[100,100,100]},{"t":24}]}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"k":[18,18]},"p":{"k":[0,0]},"nm":"椭圆路径 1","mn":"ADBE Vector Shape - Ellipse"},{"ty":"st","c":{"k":[1,1,1,1]},"o":{"k":100},"w":{"k":0},"lc":1,"lj":1,"ml":4,"nm":"描边 1","mn":"ADBE Vector Graphic - Stroke"},{"ty":"fl","c":{"k":[0.34,0.45,0.78,1]},"o":{"k":100},"nm":"填充 1","mn":"ADBE Vector Graphic - Fill"},{"ty":"tr","p":{"k":[-76.482,-3.482],"ix":2},"a":{"k":[0,0],"ix":1},"s":{"k":[100,100],"ix":3},"r":{"k":0,"ix":6},"o":{"k":100,"ix":7},"sk":{"k":0,"ix":4},"sa":{"k":0,"ix":5},"nm":"变换"}],"nm":"椭圆 1","np":3,"mn":"ADBE Vector Group"}],"ip":0,"op":40,"st":0,"bm":0,"sr":1}],"v":"4.5.4","ddd":0,"ip":0,"op":40,"fr":24,"w":280,"h":160} \ No newline at end of file diff --git a/src/assets/message.mp3 b/src/assets/message.mp3 new file mode 100644 index 0000000..73d30d3 Binary files /dev/null and b/src/assets/message.mp3 differ diff --git a/src/components/advanced-chart/AdvancedChart.js b/src/components/advanced-chart/AdvancedChart.js new file mode 100644 index 0000000..36a1fff --- /dev/null +++ b/src/components/advanced-chart/AdvancedChart.js @@ -0,0 +1,218 @@ +import React, { useState, useRef } from "react"; +import ReactEcharts from "echarts-for-react"; +import { Grid } from "../grid/Grid"; +import * as echarts from "echarts"; + +export const AdvancedChart = ({ info, title, seperator, type, group }) => { + const [isGroup, setIsGroup] = useState(group); + const chartRef = useRef(null); + + const PALETTE = [ + "#1105f5", + "#f50505", + "#f5056d", + "#f505f5", + "#05a5f5", + "#05f5bd", + "#05f57d", + "#1f4f33", + "#95DFD3", + "#AEC7ED", + "#92BFFF", + "#B1B1E0", + "#fdcb6e", + "#636e72", + "#d63031", + "#7f8fa6", + "#40739e", + ]; + + const colorByIndex = (i) => PALETTE[i % PALETTE.length]; + + const createGradient = (startColor, endColor) => ({ + type: "linear", + x: 0, + y: 0, + x2: 0, + y2: 1, + colorStops: [ + { offset: 0, color: startColor }, + { offset: 1, color: endColor }, + ], + }); + + const onChartReady = (echart) => { + chartRef.current = echart; + }; + + const handleGroupToggle = () => { + setIsGroup((prev) => !prev); + if (chartRef.current) { + chartRef.current.setOption(getOption()); + } + }; + + const getOption = () => { + if (type === "pie") { + return { + title: { + text: title, + textStyle: { + fontWeight: "bold", + fontSize: 16, + fontFamily: "iranyekan", + }, + left: "center", + padding: 10, + }, + tooltip: { trigger: "item", formatter: "{a}
{b}: {c} ({d}%)" }, + legend: { + orient: "vertical", + right: 10, + top: "center", + data: info?.map((item) => item?.name), + textStyle: { + fontFamily: "iranyekan", + width: 100, + overflow: "truncate", + ellipsis: "...", + }, + }, + color: info?.map((_, i) => colorByIndex(i)), + series: [ + { + name: title, + type: "pie", + radius: ["40%", "70%"], + avoidLabelOverlap: false, + itemStyle: { + borderRadius: 10, + borderColor: "#fff", + borderWidth: 2, + }, + label: { show: false, position: "center" }, + emphasis: { + label: { show: true, fontSize: "18", fontWeight: "bold" }, + }, + labelLine: { show: false }, + data: info?.map((item, i) => ({ + value: item.data[0], + name: item.name, + itemStyle: { + color: colorByIndex(i), + }, + })), + }, + ], + textStyle: { fontFamily: "iranyekan" }, + }; + } + + return { + title: { + text: title, + textStyle: { + fontWeight: "bold", + fontSize: 16, + fontFamily: "iranyekan", + }, + left: "center", + padding: 10, + }, + xAxis: { + type: "category", + data: seperator, + axisLabel: { + rotate: 30, + interval: 0, + width: 60, + overflow: "truncate", + fontSize: 10, + }, + }, + yAxis: isGroup + ? [ + { + type: "value", + axisLabel: { + formatter: function (a) { + a = +a; + return isFinite(a) ? echarts.format.addCommas(+a / 1000) : ""; + }, + }, + }, + ] + : { type: "value" }, + dataZoom: [ + { show: false, start: 0, end: 100 }, + { type: "inside", start: 94, end: 100 }, + ], + toolbox: { + show: true, + feature: { + mark: { + show: true, + title: { + mark: "علامت گذاری", + markUndo: "حذف علامت", + markClear: "پاک کردن همه علامت‌ها", + }, + }, + magicType: { + show: true, + type: ["line", "bar"], + title: { line: "خطی", bar: "میله‌ای", pie: "دایره ای" }, + }, + saveAsImage: { show: true, title: "ذخیره به عنوان تصویر" }, + myCustomButton: { + show: true, + title: isGroup ? "نمایش گروهی" : "نمایش جداگانه", + icon: "path://M19 13h-6v6h-2v-6H5v-2h6V5h2v6h6v2z", + onclick: handleGroupToggle, + }, + }, + }, + grid: { top: "20%", left: "1%", right: "1%", containLabel: true }, + textStyle: { fontFamily: "iranyekan" }, + + color: info?.map((_, i) => colorByIndex(i)), + + series: info?.map((item, i) => { + const base = colorByIndex(i); + const next = colorByIndex(i + 1); + return { + ...item, + smooth: true, + type, + itemStyle: { + color: base, + }, + areaStyle: { + color: createGradient(base, next), + }, + emphasis: { focus: "series" }, + stack: isGroup ? false : "stack", + }; + }), + tooltip: { trigger: "axis", axisPointer: { type: "cross" } }, + legend: { + data: info?.map((item) => item?.name), + itemGap: 10, + top: "10%", + type: "scroll", + padding: [5, 50], + textStyle: { width: 100, overflow: "truncate", ellipsis: "..." }, + }, + }; + }; + + return ( + + + + ); +}; diff --git a/src/components/advanced-table-page/AdvancedTablePage.js b/src/components/advanced-table-page/AdvancedTablePage.js new file mode 100644 index 0000000..099553a --- /dev/null +++ b/src/components/advanced-table-page/AdvancedTablePage.js @@ -0,0 +1,164 @@ +import Table from "@mui/material/Table"; +import TableBody from "@mui/material/TableBody"; +import TableCell from "@mui/material/TableCell"; +import TableContainer from "@mui/material/TableContainer"; +import TableHead from "@mui/material/TableHead"; +import TableRow from "@mui/material/TableRow"; +import Paper from "@mui/material/Paper"; +import Pagination from "@mui/material/Pagination"; +import Box from "@mui/material/Box"; +import axios from "axios"; +import { useEffect, useState } from "react"; +import { NativeSelect } from "@mui/material"; + +const tableStyles = { + tableContainer: { + marginBottom: "16px", + maxHeight: "70vh", + overflow: "auto", + }, + selectButton: { + marginRight: "8px", + }, +}; + +function AdvancedTablePage({ columns, list, api }) { + const [page, setPage] = useState(0); + const [rowsPerPage, setRowsPerPage] = useState(5); + const [tableData, setTableData] = useState([]); + const [tableRows, setTableRows] = useState([]); + const [totalRows, setTotalRows] = useState(0); + + const handleChangePage = (event, newPage) => { + setPage(newPage); + }; + + const handleChangeRowsPerPage = (event) => { + setRowsPerPage(parseInt(event.target.value, 10)); + setPage(0); + }; + + const codeList = eval(list); + + function replacePlaceholders(inputHTML, item) { + const replacedHTML = inputHTML.replace( + /{(.*?)}/g, + (match, propertyName) => { + return item[propertyName] !== undefined ? item[propertyName] : "-"; + } + ); + return
; + } + + useEffect(() => { + const apiUrl = `${api}&page=${page + 1}&page_size=${rowsPerPage}`; + axios.get(apiUrl).then((response) => { + setTableData(response?.data?.results); + setTotalRows(response?.data?.count); + }); + }, [api, page, rowsPerPage]); + + useEffect(() => { + const d = tableData?.map((item) => { + const result = codeList.map((option) => { + const properties = option.split("."); + let value = item; + for (const property of properties) { + if (property.includes("<")) { + value = replacePlaceholders(option, item); + } else { + value = value[property]; + } + } + return value; + }); + return result; + }); + + setTableRows(d); + }, [tableData, codeList]); + + return ( + + + + + + {columns.map((column, index) => ( + {column} + ))} + + + + {tableRows.map((row, rowIndex) => ( + + {row.map((cell, cellIndex) => ( + {cell} + ))} + + ))} + +
+
+ + + + + + + + + { + handleChangePage(event, newPage - 1); + }} + /> + +
+ ); +} + +export default AdvancedTablePage; + +// sample usage +// diff --git a/src/components/advanced-table/AdvancedTable.js b/src/components/advanced-table/AdvancedTable.js new file mode 100644 index 0000000..b25244e --- /dev/null +++ b/src/components/advanced-table/AdvancedTable.js @@ -0,0 +1,97 @@ +import { + // Paper, + // Table, + // TableCell, + // TableContainer, + // TableRow, + Typography, +} from "@mui/material"; +import MUIDataTable from "mui-datatables"; +import { useEffect, useState } from "react"; +import { PropTypes } from "prop-types"; +// import moment from "moment"; + +export const AdvancedTable = ({ columns, data, name, pagination }) => { + const [rows, setRows] = useState(data); + + useEffect(() => { + setRows(data); + }, [data]); + + useEffect(() => { + const d = data?.map((item) => { + return item?.map((row) => { + if (!row && row !== 0) { + return ""; + } else { + return row; + } + }); + }); + setRows(d); + }, [data]); + + const options = { + viewColumns: false, + filter: true, + print: false, + download: false, + selectableRowsHeader: false, + selectableRowsHideCheckboxes: true, + responsive: "vertical", + pagination: pagination ? pagination : true, + fixedHeader: true, + tableBodyMaxHeight: "70vh", + // localization + textLabels: { + body: { + noMatch: "داده ای جهت نمایش موجود نیست!", + toolTip: "مرتب سازی", + columnHeaderTooltip: (column) => `مرتب سازی بر اساس ${column.label}`, + }, + pagination: { + next: "صفحه بعد", + previous: "صفحه قبل", + rowsPerPage: "تعداد سطر در هر صفحه:", + displayRows: "تعداد کل نتایج: ", + }, + toolbar: { + search: "جستجو", + downloadCsv: "دانلود CSV", + print: "پرینت", + viewColumns: "نمایش سطون ها", + filterTable: "فیلتر جدول", + }, + filter: { + all: "همه", + title: "فیلترها", + reset: "پاکسازی", + }, + viewColumns: { + title: "نمایش ستون ها", + titleAria: "نمایش/بستن ستون های جدول", + }, + selectedRows: { + text: "سطر انتخاب شده است", + delete: "پاک کردن", + deleteAria: "پاک کردن سطرهای انتخاب شده", + }, + }, + }; + + return ( + {name}} + data={rows} + columns={columns} + options={options} + /> + ); +}; + +AdvancedTable.propTypes = { + columns: PropTypes.any, + data: PropTypes.any, + name: PropTypes.any, + expandable: PropTypes.bool, +}; diff --git a/src/components/autocomplete-select/AutocompleteSelect.js b/src/components/autocomplete-select/AutocompleteSelect.js new file mode 100644 index 0000000..ff415b7 --- /dev/null +++ b/src/components/autocomplete-select/AutocompleteSelect.js @@ -0,0 +1,239 @@ +import * as React from "react"; +import PropTypes from "prop-types"; +import CheckIcon from "@mui/icons-material/Check"; +import CloseIcon from "@mui/icons-material/Close"; +import { styled } from "@mui/material/styles"; +import { autocompleteClasses } from "@mui/material/Autocomplete"; +import { Typography, useAutocomplete } from "@mui/material"; +import { Grid } from "../grid/Grid"; + +const Root = styled("div")( + ({ theme }) => ` + color: ${ + theme.palette.mode === "dark" ? "rgba(255,255,255,0.65)" : "rgba(0,0,0,.85)" + }; + font-size: 14px; +` +); + +const Label = styled("label")` + padding: 0 0 4px; + line-height: 1.5; + display: block; +`; + +const InputWrapper = styled("div")( + ({ theme }) => ` + width: 300px; + border: 1px solid ${theme.palette.mode === "dark" ? "#434343" : "#d9d9d9"}; + background-color: ${theme.palette.mode === "dark" ? "#141414" : "#fff"}; + border-radius: 4px; + padding: 1px; + display: flex; + flex-wrap: wrap; + + &:hover { + border-color: ${theme.palette.mode === "dark" ? "#177ddc" : "#40a9ff"}; + } + + &.focused { + border-color: ${theme.palette.mode === "dark" ? "#177ddc" : "#40a9ff"}; + box-shadow: 0 0 0 2px rgba(24, 144, 255, 0.2); + } + + & input { + background-color: ${theme.palette.mode === "dark" ? "#141414" : "#fff"}; + color: ${ + theme.palette.mode === "dark" + ? "rgba(255,255,255,0.65)" + : "rgba(0,0,0,.85)" + }; + height: 30px; + box-sizing: border-box; + padding: 4px 6px; + width: 0; + min-width: 30px; + flex-grow: 1; + border: 0; + margin: 0; + outline: 0; + } +` +); + +function Tag(props) { + const { label, onDelete, ...other } = props; + return ( +
+ {label} + +
+ ); +} + +Tag.propTypes = { + label: PropTypes.string.isRequired, + onDelete: PropTypes.func.isRequired, +}; + +const StyledTag = styled(Tag)( + ({ theme }) => ` + display: flex; + align-items: center; + height: 24px; + margin: 2px; + line-height: 22px; + background-color: ${ + theme.palette.mode === "dark" ? "rgba(255,255,255,0.08)" : "#fafafa" + }; + border: 1px solid ${theme.palette.mode === "dark" ? "#303030" : "#e8e8e8"}; + border-radius: 2px; + box-sizing: content-box; + padding: 0 4px 0 10px; + outline: 0; + overflow: hidden; + + &:focus { + border-color: ${theme.palette.mode === "dark" ? "#177ddc" : "#40a9ff"}; + background-color: ${theme.palette.mode === "dark" ? "#003b57" : "#e6f7ff"}; + } + + & span { + overflow: hidden; + white-space: nowrap; + text-overflow: ellipsis; + } + + & svg { + font-size: 12px; + cursor: pointer; + padding: 4px; + } +` +); + +const Listbox = styled("ul")( + ({ theme }) => ` + width: 300px; + margin: 2px 0 0; + padding: 0; + position: absolute; + list-style: none; + background-color: ${theme.palette.mode === "dark" ? "#141414" : "#fff"}; + overflow: auto; + max-height: 250px; + border-radius: 4px; + box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15); + z-index: 1; + + & li { + padding: 5px 12px; + display: flex; + + & span { + flex-grow: 1; + } + + & svg { + color: transparent; + } + } + + & li[aria-selected='true'] { + background-color: ${theme.palette.mode === "dark" ? "#2b2b2b" : "#fafafa"}; + font-weight: 600; + + & svg { + color: #1890ff; + } + } + + & li.${autocompleteClasses.focused} { + background-color: ${theme.palette.mode === "dark" ? "#003b57" : "#e6f7ff"}; + cursor: pointer; + + & svg { + color: currentColor; + } + } +` +); + +export function AutocompleteSelect({ + title, + options, + defualtValueIndex, + onChange, +}) { + const { + getInputLabelProps, + getInputProps, + getTagProps, + getListboxProps, + getOptionProps, + groupedOptions, + value, + focused, + setAnchorEl, + } = useAutocomplete({ + id: "customized-hook-demo", + // defaultValue: [options[defualtValueIndex]], + multiple: true, + options: options, + getOptionLabel: (option) => option.title, + }); + + React.useEffect(() => { + onChange(value); + }, [value]); + + return ( + + + + + {value.map((option, index) => { + return ( + + + + ); + })} + + + + {groupedOptions.length > 0 ? ( + + {groupedOptions.map((option, index) => ( +
  • + + {option.title} + + +
  • + ))} +
    + ) : null} +
    +
    + ); +} + +AutocompleteSelect.propTypes = { + title: PropTypes.string, + defualtValueIndex: PropTypes.any, + options: PropTypes.any, + onChange: PropTypes.any, +}; diff --git a/src/components/back-button/BackButton.js b/src/components/back-button/BackButton.js new file mode 100644 index 0000000..c0d67af --- /dev/null +++ b/src/components/back-button/BackButton.js @@ -0,0 +1,21 @@ +import { IconButton, Typography } from "@mui/material"; +import { useNavigate } from "react-router-dom"; +import { Grid } from "../grid/Grid"; +import { SPACING } from "../../data/spacing"; +import StartIcon from "@mui/icons-material/Start"; + +export const BackButton = () => { + const navigate = useNavigate(); + return ( + + navigate(-1)} + > + + بازگشت + + + ); +}; diff --git a/src/components/backdrop/BackDrop.js b/src/components/backdrop/BackDrop.js new file mode 100644 index 0000000..e81f414 --- /dev/null +++ b/src/components/backdrop/BackDrop.js @@ -0,0 +1,26 @@ +import { Backdrop } from "@mui/material"; +import { useContext, useEffect } from "react"; +import { useDispatch, useSelector } from "react-redux"; +import { SidebarContext } from "../../contexts/SidebarContext"; +import { BACKDROP_HIDE } from "../../lib/redux/slices/appSlice"; + +export const BackDrop = () => { + const backdropState = useSelector((state) => state.appSlice.backdrop); + const [, setSidebarMobileState] = useContext(SidebarContext); + const dispatch = useDispatch(); + + useEffect(() => { + dispatch(BACKDROP_HIDE()); + }, []); + + return ( + theme.zIndex.drawer + 1, + }} + open={backdropState} + onClick={() => setSidebarMobileState(false)} + > + ); +}; diff --git a/src/components/bank-card/BankCard.js b/src/components/bank-card/BankCard.js new file mode 100644 index 0000000..4d85600 --- /dev/null +++ b/src/components/bank-card/BankCard.js @@ -0,0 +1,61 @@ +import React from "react"; +import PropTypes from "prop-types"; +import { Typography } from "@mui/material"; + +const BankCard = ({ cardNumber, expirationDate, bankName, bankUser }) => ( +
    +
    +
    + اطلاعات بانکی جهت واریز مبلغ + + {bankName} + +
    + +
    + Visa +
    +
    + +
    + شماره کارت {cardNumber} +
    +
    + +
    {bankUser}
    +
    {expirationDate}
    +
    +
    +
    +); + +BankCard.propTypes = { + cardNumber: PropTypes.string.isRequired, + expirationDate: PropTypes.string.isRequired, +}; + +export default BankCard; diff --git a/src/components/box-list/BoxList.js b/src/components/box-list/BoxList.js new file mode 100644 index 0000000..abf3d1e --- /dev/null +++ b/src/components/box-list/BoxList.js @@ -0,0 +1,118 @@ +import React, { useState } from "react"; +import PropTypes from "prop-types"; +import Box from "@mui/material/Box"; +import Typography from "@mui/material/Typography"; +import { Pagination } from "@mui/material"; +import { SPACING } from "../../data/spacing"; +import { Grid } from "../grid/Grid"; + +const BoxList = ({ columns, data, ignore, paginated, name }) => { + const itemsPerPage = 2; + const totalPages = Math.ceil(data?.length / itemsPerPage); + const [currentPage, setCurrentPage] = useState(1); + + function isInIgnoreList(number) { + return ignore?.includes(number); + } + + const startIndex = (currentPage - 1) * itemsPerPage; + const endIndex = startIndex + itemsPerPage; + + const slicedData = paginated ? data.slice(startIndex, endIndex) : data; + + return ( + <> + + {name && ( + + {name} + + )} + {!data.length && ( + + + موردی وجود ندارد! + + + )} + + {slicedData.map((row, rowIndex) => { + let visibleCellIndex = 0; + + return ( + + + {row.map( + (cell, cellIndex) => + !isInIgnoreList(cellIndex) && ( + + + {`${columns[cellIndex]}`} + + + + {cell} + + + ) + )} + + + ); + })} + + + {paginated && ( + + setCurrentPage(page)} + /> + + )} + + ); +}; + +BoxList.propTypes = { + columns: PropTypes.any, + data: PropTypes.any, + ignore: PropTypes.array, + paginated: PropTypes.any, +}; + +export default BoxList; diff --git a/src/components/button-with-icon/ButtonWithIcon.js b/src/components/button-with-icon/ButtonWithIcon.js new file mode 100644 index 0000000..c8a430a --- /dev/null +++ b/src/components/button-with-icon/ButtonWithIcon.js @@ -0,0 +1,42 @@ +import { Paper, Typography } from "@mui/material"; +import { PropTypes } from "prop-types"; +import { SPACING } from "../../data/spacing"; +import { Grid } from "../grid/Grid"; + +export const ButtonWithIcon = ({ Icon, onClick, title }) => { + return ( + + + + + + {title} + + + + + ); +}; + +ButtonWithIcon.propTypes = { + Icon: PropTypes.any, + onClick: PropTypes.func, + title: PropTypes.string, +}; diff --git a/src/components/captcha/Captcha.js b/src/components/captcha/Captcha.js new file mode 100644 index 0000000..908243f --- /dev/null +++ b/src/components/captcha/Captcha.js @@ -0,0 +1,143 @@ +import { TextField } from "@mui/material"; +import PropTypes from "prop-types"; +import React, { Component } from "react"; +// import "./captcha.css"; + +function getRandomInt(min, max) { + min = Math.ceil(min); + max = Math.floor(max); + return Math.floor(Math.random() * (max - min)) + min; +} + +class Captcha extends Component { + state = { + solution: getRandomInt(111111, 999999), + input: "", + }; + + componentDidMount = () => { + this.drawCaptcha(); + // this.props.captchaSolution(this.state.solution.toString()); + }; + + drawCaptcha = () => { + const { solution } = this.state; + const { width, height } = this.canvas; + const ctx = this.canvas.getContext("2d"); + ctx.clearRect(0, 0, width, height); + ctx.font = "40px serif"; + ctx.textAlign = "center"; + ctx.textBaseline = "middle"; + ctx.fillText(solution, width / 2, height / 2 + 3); + ctx.strokeStyle = "#000000"; + ctx.beginPath(); + ctx.moveTo(getRandomInt(5, 20), getRandomInt(5, 20)); + ctx.lineTo(width - getRandomInt(5, 20), height - getRandomInt(5, 20)); + ctx.stroke(); + ctx.moveTo(getRandomInt(5, 20), height - getRandomInt(5, 20)); + ctx.lineTo(width - getRandomInt(5, 20), getRandomInt(5, 20)); + ctx.stroke(); + ctx.closePath(); + this.canvas.style.backgroundColor = "transparent"; + }; + + refresh = () => { + this.setState( + { + solution: getRandomInt(111111, 999999), + input: "", + }, + this.drawCaptcha + ); + }; + + playAudio = () => { + const { solution } = this.state; + let audio = new SpeechSynthesisUtterance( + solution.toString().split("").join(" ") + ); + audio.rate = 0.25; + window.speechSynthesis.speak(audio); + }; + + handleChange = (e) => { + const { onChange } = this.props; + const { solution } = this.state; + this.setState({ input: e.target.value }); + onChange(e.target.value === solution.toString()); + }; + + render() { + const { input } = this.state; + return ( +
    +
    + (this.canvas = el)} + width={200} + height={50} + className="rnc-canvas" + data-testid="captcha-canvas" + /> +
    + + +
    +
    + +
    + ); + } +} + +Captcha.defaultProps = { + placeholder: "کد امنیتی را وارد کنید...", +}; + +Captcha.propTypes = { + onChange: PropTypes.func.isRequired, + placeholder: PropTypes.string, +}; + +export default Captcha; diff --git a/src/components/car-pelak/CarPelak.js b/src/components/car-pelak/CarPelak.js new file mode 100644 index 0000000..5cdd250 --- /dev/null +++ b/src/components/car-pelak/CarPelak.js @@ -0,0 +1,250 @@ +import { Grid } from "../grid/Grid"; +import pelakImg from "../../assets/images/pelak.jpg"; +import { FormControl, MenuItem, Select, TextField } from "@mui/material"; +import { SPACING } from "../../data/spacing"; +import { useFormik } from "formik"; +import { Yup } from "../../lib/yup/yup"; +import { PropTypes } from "prop-types"; +import { useEffect, useState } from "react"; + +export const CarPelak = ({ handleChange, pelakState, pelakInitial }) => { + const formik = useFormik({ + initialValues: { + driver_name: "", + driver_mobile: "", + type_car: "ایسوزو", + type_weight: "سنگین", + capocity: "", + pelak1: pelakInitial?.split(" ")[0] ? pelakInitial?.split(" ")[0] : "", + pelak2: pelakInitial?.split(" ")[1] ? pelakInitial?.split(" ")[1] : "", + pelak3: pelakInitial?.split(" ")[2] ? pelakInitial?.split(" ")[2] : "", + pelak4: pelakInitial?.split(" ")[3] ? pelakInitial?.split(" ")[3] : "", + // name: "", + }, + validationSchema: Yup.object({ + driver_name: Yup.string() + .matches( + /^[ض‌ص‌ث‌ق‌ف‌غ‌ع‌ه‌خ‌خ‌ح‌ج‌چ‌ش‌س‌ی‌ب‌ل‌ا‌ت‌ن‌ن‌م‌ک‌گ‌ظ‌ط‌ز‌ر‌ذ‌د‌و‌پ‌آ‌ژ ]+$/, + "فقط حروف فارسی وارد کنید" + ) + .required("این فیلد اجباری است!") + .typeError("لطفا فیلد را به درستی وارد کنید!"), + driver_mobile: Yup.string() + .test("len", "شماره تلفن باید با 0 شروع شود", (val, context) => { + return context.originalValue && context.originalValue.startsWith("0"); + }) + .test("len", "شماره تماس 11 رقم باید باشد", (val, context) => { + if (context.originalValue) { + return context.originalValue.length === 11; + } + }) + .required("این فیلد اجباری است!") + .typeError("لطفا عدد وارد کنید!"), + type_weight: Yup.string() + .required("این فیلد اجباری است!") + .typeError("لطفا فیلد را به درستی وارد کنید!"), + capocity: Yup.string() + .required("این فیلد اجباری است!") + .typeError("لطفا فیلد را به درستی وارد کنید!"), + pelak1: Yup.number() + .required("این فیلد اجباری است!") + .typeError("لطفا عدد وارد کنید!"), + pelak2: Yup.string() + .required("این فیلد اجباری است!") + .typeError("لطفا فیلد را به درستی وارد کنید!"), + pelak3: Yup.number() + .required("این فیلد اجباری است!") + .typeError("لطفا عدد وارد کنید!"), + pelak4: Yup.number() + .required("این فیلد اجباری است!") + .typeError("لطفا عدد وارد کنید!"), + name: Yup.string().typeError("لطفا فیلد را به درستی وارد کنید!"), + }), + }); + + const [flag, setFlag] = useState(true); + useEffect(() => { + if (pelakState?.length && flag) { + setFlag(false); + const [pelak1, pelak2, pelak3, pelak4] = pelakState; + formik.setFieldValue("pelak1", pelak1); + formik.setFieldValue("pelak2", pelak2); + formik.setFieldValue("pelak3", pelak3); + formik.setFieldValue("pelak4", pelak4); + } + }, [pelakState]); + + useEffect(() => { + handleChange( + formik.values.pelak1 ? formik.values.pelak1 : "", + formik.values.pelak2 ? formik.values.pelak2 : "", + formik.values.pelak3 ? formik.values.pelak3 : "", + formik.values.pelak4 ? formik.values.pelak4 : "" + ); + }, [ + formik.values.pelak1, + formik.values.pelak2, + formik.values.pelak3, + formik.values.pelak4, + ]); + + return ( + + + + + + + + + + + + {/* */} + + + + + + + + + + + + ); +}; + +CarPelak.propTypes = { + pelak1: PropTypes.number, + pelak2: PropTypes.number, + pelak3: PropTypes.number, + pelak4: PropTypes.number, + handleChange: PropTypes.any, +}; diff --git a/src/components/chart-bar/ChartBar.js b/src/components/chart-bar/ChartBar.js new file mode 100644 index 0000000..fdf150a --- /dev/null +++ b/src/components/chart-bar/ChartBar.js @@ -0,0 +1,19 @@ +import React from "react"; +import { Bar } from "react-chartjs-2"; +import { Chart as ChartJs } from "chart.js/auto"; +import { PropTypes } from "prop-types"; +import { defaults } from "chart.js"; + +defaults.font.family = "iranyekan"; + +const ChartBar = ({ chartData, options }) => { + console.log(ChartJs); + return ; +}; + +export default ChartBar; + +ChartBar.propTypes = { + chartData: PropTypes.any, + options: PropTypes.any, +}; diff --git a/src/components/chart-bar/hot it works.txt b/src/components/chart-bar/hot it works.txt new file mode 100644 index 0000000..b769191 --- /dev/null +++ b/src/components/chart-bar/hot it works.txt @@ -0,0 +1,133 @@ +const AdminStatics = () => { + const UserDataBase = [ + { id: 1, year: 1401, userGain: 6400, userLost: 400 }, + { id: 2, year: 1401, userGain: 7100, userLost: 250 }, + { id: 3, year: 1402, userGain: 10000, userLost: 500 }, + { id: 3, year: 1399, userGain: 3500, userLost: 110 }, + ]; + const [userData] = useState({ + labels: UserDataBase.map((data) => data.year), + datasets: [ + { + label: "Users Gained", + data: UserDataBase.map((data) => data.userGain), + backgroundColor: [ + "rgba(255, 29, 255, 0.5)", + "rgba(0, 255, 0, 0.5)", + "rgba(0, 172, 62, 0.5)", + "rgba(255, 0, 0, 0.5)", + "rgba(255, 121, 189, 0.5)", + ], + hoverBackgroundColor: "rgba(119, 222, 227, 0.5)", + opacity: "10%", + borderColor: "green", + borderWidth: 1, + }, + ], + }); + + const [userBarData] = useState({ + labels: UserDataBase.map((data) => data.year), + datasets: [ + { + label: "تعداد", + fillColor: "blue", + data: [3, 7, 4], + }, + { + label: "تلفات", + fillColor: "red", + data: [4, 3, 5], + }, + { + label: "کشتار شده", + fillColor: "green", + data: [7, 2, 6], + }, + ], + }); + + const myUserDataBase = [ + { id: 1, year: 15, userGain: 20, userLost: 10 }, + { id: 2, year: 10, userGain: 2, userLost: 10 }, + { id: 2, year: 30, userGain: 15, userLost: 10 }, + { id: 2, year: 20, userGain: 20, userLost: 13 }, + ]; + + let mydata = myUserDataBase.map((data) => { + return { x: data.userGain, y: data.userLost, r: data.year }; + }); + + console.log(mydata); + + const [bubbleData] = useState({ + datasets: [ + { + label: "Users Gained", + data: mydata, + backgroundColor: [ + "rgba(255, 29, 255, 0.8)", + "rgba(0, 255, 0, 0.9)", + "rgba(0, 172, 62, 0.6)", + "rgba(255, 0, 0, 0.5)", + "rgba(255, 121, 189, 0.2)", + ], + opacity: "10%", + borderColor: "green", + borderWidth: 1, + }, + ], + }); + + return ( + + + + + + + + + + + + {" "} + + + + + + + ); +}; + +export default AdminStatics; diff --git a/src/components/chart-bubble/ChartBubble.js b/src/components/chart-bubble/ChartBubble.js new file mode 100644 index 0000000..d7e465d --- /dev/null +++ b/src/components/chart-bubble/ChartBubble.js @@ -0,0 +1,18 @@ +import React from "react"; +import { Bubble } from "react-chartjs-2"; +import { Chart as ChartJs } from "chart.js/auto"; +import { PropTypes } from "prop-types"; +import { defaults } from "chart.js"; + +defaults.font.family = "iranyekan"; + +const ChartBubble = ({ chartData }) => { + console.log(ChartJs); + return ; +}; + +export default ChartBubble; + +ChartBubble.propTypes = { + chartData: PropTypes.any, +}; diff --git a/src/components/chart-doughnut/ChartDoughnut.js b/src/components/chart-doughnut/ChartDoughnut.js new file mode 100644 index 0000000..8b8ee28 --- /dev/null +++ b/src/components/chart-doughnut/ChartDoughnut.js @@ -0,0 +1,18 @@ +import React from "react"; +import { Doughnut } from "react-chartjs-2"; +import { Chart as ChartJs } from "chart.js/auto"; +import { PropTypes } from "prop-types"; +import { defaults } from "chart.js"; + +defaults.font.family = "iranyekan"; + +const ChartDoughnut = ({ chartData }) => { + console.log(ChartJs); + return ; +}; + +export default ChartDoughnut; + +ChartDoughnut.propTypes = { + chartData: PropTypes.any, +}; diff --git a/src/components/chart-linear/ChartLenear.js b/src/components/chart-linear/ChartLenear.js new file mode 100644 index 0000000..ba52be0 --- /dev/null +++ b/src/components/chart-linear/ChartLenear.js @@ -0,0 +1,19 @@ +import React from "react"; +import { Line } from "react-chartjs-2"; +import { Chart as ChartJs } from "chart.js/auto"; +import { PropTypes } from "prop-types"; +import { defaults } from "chart.js"; + +console.log(ChartJs); + +defaults.font.family = "iranyekan"; + +const ChartLinear = ({ chartData }) => { + return ; +}; + +export default ChartLinear; + +ChartLinear.propTypes = { + chartData: PropTypes.any, +}; diff --git a/src/components/chart-pie/ChartPie.js b/src/components/chart-pie/ChartPie.js new file mode 100644 index 0000000..fb90dd7 --- /dev/null +++ b/src/components/chart-pie/ChartPie.js @@ -0,0 +1,18 @@ +import React from "react"; +import { Pie } from "react-chartjs-2"; +import { Chart as ChartJs } from "chart.js/auto"; +import { PropTypes } from "prop-types"; +import { defaults } from "chart.js"; + +defaults.font.family = "iranyekan"; + +const ChartPie = ({ chartData }) => { + console.log(ChartJs); + return ; +}; + +export default ChartPie; + +ChartPie.propTypes = { + chartData: PropTypes.any, +}; diff --git a/src/components/chart-polar-area/ChartPolarArea.js b/src/components/chart-polar-area/ChartPolarArea.js new file mode 100644 index 0000000..f9c28e0 --- /dev/null +++ b/src/components/chart-polar-area/ChartPolarArea.js @@ -0,0 +1,18 @@ +import React from "react"; +import { PolarArea } from "react-chartjs-2"; +import { Chart as ChartJs } from "chart.js/auto"; +import { PropTypes } from "prop-types"; +import { defaults } from "chart.js"; + +defaults.font.family = "iranyekan"; + +const ChartPolarArea = ({ chartData }) => { + console.log(ChartJs); + return ; +}; + +export default ChartPolarArea; + +ChartPolarArea.propTypes = { + chartData: PropTypes.any, +}; diff --git a/src/components/chart-radar/ChartRadar.js b/src/components/chart-radar/ChartRadar.js new file mode 100644 index 0000000..28758bf --- /dev/null +++ b/src/components/chart-radar/ChartRadar.js @@ -0,0 +1,18 @@ +import React from "react"; +import { Radar } from "react-chartjs-2"; +import { Chart as ChartJs } from "chart.js/auto"; +import { PropTypes } from "prop-types"; +import { defaults } from "chart.js"; + +defaults.font.family = "iranyekan"; + +const ChartRadar = ({ chartData }) => { + console.log(ChartJs); + return ; +}; + +export default ChartRadar; + +ChartRadar.propTypes = { + chartData: PropTypes.any, +}; diff --git a/src/components/chart-scatter/ChartScatter.js b/src/components/chart-scatter/ChartScatter.js new file mode 100644 index 0000000..d456d30 --- /dev/null +++ b/src/components/chart-scatter/ChartScatter.js @@ -0,0 +1,18 @@ +import React from "react"; +import { Scatter } from "react-chartjs-2"; +import { Chart as ChartJs } from "chart.js/auto"; +import { PropTypes } from "prop-types"; +import { defaults } from "chart.js"; + +defaults.font.family = "iranyekan"; + +const ChartScatter = ({ chartData }) => { + console.log(ChartJs); + return ; +}; + +export default ChartScatter; + +ChartScatter.propTypes = { + chartData: PropTypes.any, +}; diff --git a/src/components/chat-system/ChatSystem.js b/src/components/chat-system/ChatSystem.js new file mode 100644 index 0000000..f65e77a --- /dev/null +++ b/src/components/chat-system/ChatSystem.js @@ -0,0 +1,546 @@ +import React, { useContext, useEffect, useRef, useState } from "react"; +import { + Fab, + Box, + Paper, + Typography, + IconButton, + TextField, + Button, + Avatar, + Tooltip, +} from "@mui/material"; +import ChatIcon from "@mui/icons-material/Chat"; +import CloseIcon from "@mui/icons-material/Close"; +// import SendIcon from "@mui/icons-material/Send"; +import { motion, AnimatePresence } from "framer-motion"; +import { Formik, Form, Field } from "formik"; +import * as Yup from "yup"; +import { useDispatch, useSelector } from "react-redux"; +import { getTickets } from "./services/getTickets"; +import ArrowBackIosIcon from "@mui/icons-material/ArrowBackIos"; +import ContactSupportIcon from "@mui/icons-material/ContactSupport"; +import { getMessages } from "./services/getMessages"; +import { submitTicket } from "./services/submitTicket"; +import { AppContext } from "../../contexts/AppContext"; +import DoDisturbOffIcon from "@mui/icons-material/DoDisturbOff"; +import { closeTicket } from "./services/closeTicket"; +import messageSound from "../../assets/message.mp3"; +import { submitMessage } from "./services/submitMessage"; + +const ChatButton = () => { + const dispatch = useDispatch(); + const [showChat, setShowChat] = useState(false); + const [tickets, setTickets] = useState([]); + const [single, setSingle] = useState(false); + const [singleId, setSingleId] = useState(); + const [openNotif] = useContext(AppContext); + const { role } = useSelector((item) => item.userSlice); + + const [messages, setMessages] = useState([]); + + const toggleChat = () => { + setShowChat(!showChat); + }; + + const getTicketsFunction = () => { + if (showChat === true) { + dispatch(getTickets()).then((r) => { + setTickets(r.payload.data); + }); + } + }; + const prevLengthRef = useRef(messages.length); + + const getMessagesFunction = (id) => { + const mlength = prevLengthRef.current; + const audio = new Audio(messageSound); + + dispatch(getMessages({ ticketId: id })).then((r) => { + const d = r.payload.data.map((item) => { + return { + text: item?.message, + sender: item?.sender, + }; + }); + setMessages(d); + if (prevLengthRef === 0) { + prevLengthRef.current = d.length; + } else if ( + d.length > mlength && + !role.includes("SuperAdmin") && + d[d.length - 1].sender === "admin" + ) { + prevLengthRef.current = d.length; + + audio.play(); + } + }); + }; + useEffect(() => { + if (singleId) { + getMessagesFunction(singleId, true); + const intervalId = setInterval(() => { + getMessagesFunction(singleId, true); + }, 5000); + + return () => clearInterval(intervalId); + } + }, [singleId]); + + useEffect(() => { + getTicketsFunction(); + }, [showChat]); + + const handleSendMessage = (values, { resetForm }) => { + if (!single) { + dispatch( + submitTicket({ + title: values.ticket, + userlocation: window.location.pathname, + picture: null, + text: null, + }) + ).then((r) => { + if (r.payload.error) { + openNotif({ + vertical: "top", + horizontal: "center", + msg: r.payload.error, + severity: "error", + }); + } else { + openNotif({ + vertical: "top", + horizontal: "center", + msg: "عملیات با موفقیت انجام شد.", + severity: "success", + }); + } + getTicketsFunction(); + }); + resetForm(); + } else { + setMessages([ + ...messages, + { + text: values.message, + sender: role.includes("SuperAdmin") ? "admin" : "user", + }, + ]); + resetForm(); + dispatch( + submitMessage({ + message: values.message, + sender: role.includes("SuperAdmin") ? "admin" : "user", + user_location: window.location.pathname, + ticket: singleId, + }) + ).then((r) => { + if (r.payload.error) { + openNotif({ + vertical: "top", + horizontal: "center", + msg: r.payload.error, + severity: "error", + }); + } else { + openNotif({ + vertical: "top", + horizontal: "center", + msg: "عملیات با موفقیت انجام شد.", + severity: "success", + }); + } + getMessagesFunction(singleId); + }); + } + }; + + return ( +
    + + {!showChat && ( + + + + + + )} + + + + {showChat && ( + <> + {!single ? ( + + + + گفتگو با پشتیبان + + + + + + {tickets?.map((item) => { + return ( + + { + setSingle(true); + setSingleId(item?.id); + }} + style={{ color: "gray", cursor: "pointer" }} + > + {item?.title} + + + {item?.status === "open" ? ( + + { + dispatch( + closeTicket({ ticket: item.id }) + ).then(() => { + getTicketsFunction(); + }); + }} + className="bluehover" + style={{ cursor: "pointer" }} + > + + + + ) : ( + + + + + + )} + + ); + })} + + {!role?.includes("SuperAdmin") && ( + + + {({ errors, touched }) => ( +
    + + // + // + // + // + // ), + // }} + sx={{ + flex: 1, + marginRight: "8px", + }} + /> + + + )} +
    +
    + )} +
    +
    + ) : ( + + + + + گفتگو با{" "} + {role.includes("SuperAdmin") ? "کاربر" : "پشتیبان"} + + { + setSingle(false); + setSingleId(""); + getTicketsFunction(); + }} + > + + + + + {messages.length ? ( + + {messages.map((message, index) => ( + + ))} + + ) : ( + + پیامی موجود نیست! + + )} + + + + {({ errors, touched }) => ( +
    + + // + // + // + // + // ), + // }} + sx={{ + flex: 1, + marginRight: "8px", + }} + /> + + + )} +
    +
    +
    +
    + )} + + )} +
    +
    + ); +}; + +const Message = ({ message, sender }) => { + const isUser = sender === "user"; + const [tooltipTitle, setTooltipTitle] = useState("جهت کپی محل کلیک کنید"); + + const handleClickMessage = () => { + navigator.clipboard + .writeText(message?.userLocation) + .then(() => { + setTooltipTitle("کپی شد"); + setTimeout(() => { + setTooltipTitle("جهت کپی محل کلیک کنید"); + }, 1000); + }) + .catch((err) => { + console.error(err); + console.error("مشکلی بوجود آمد!!"); + }); + }; + + return ( + + {" "} + {isUser ? ( + + + {message.text} + + + ) : ( + + {message.text} + + )} + + ); +}; + +export default ChatButton; diff --git a/src/components/chat-system/services/closeTicket.js b/src/components/chat-system/services/closeTicket.js new file mode 100644 index 0000000..0418880 --- /dev/null +++ b/src/components/chat-system/services/closeTicket.js @@ -0,0 +1,11 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; + +export const closeTicket = createAsyncThunk("CLOSE_TICKET", async (d) => { + try { + const { data, status } = await axios.put("ticket/0/", d); + return { data, status }; + } catch (e) { + return { error: e.response.data.result }; + } +}); diff --git a/src/components/chat-system/services/getMessages.js b/src/components/chat-system/services/getMessages.js new file mode 100644 index 0000000..c28b4ef --- /dev/null +++ b/src/components/chat-system/services/getMessages.js @@ -0,0 +1,9 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; + +export const getMessages = createAsyncThunk("GET_Messages", async (d) => { + const { data, status } = await axios.get("message/", { + params: { ticket: d.ticketId }, + }); + return { data, status }; +}); diff --git a/src/components/chat-system/services/getTickets.js b/src/components/chat-system/services/getTickets.js new file mode 100644 index 0000000..7d2cb74 --- /dev/null +++ b/src/components/chat-system/services/getTickets.js @@ -0,0 +1,7 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; + +export const getTickets = createAsyncThunk("GET_Tickets", async (d) => { + const { data, status } = await axios.get("ticket/"); + return { data, status }; +}); diff --git a/src/components/chat-system/services/submitMessage.js b/src/components/chat-system/services/submitMessage.js new file mode 100644 index 0000000..fd03b92 --- /dev/null +++ b/src/components/chat-system/services/submitMessage.js @@ -0,0 +1,11 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; + +export const submitMessage = createAsyncThunk("SUBMIT_MESSAGE", async (d) => { + try { + const { data, status } = await axios.post("message/", d); + return { data, status }; + } catch (e) { + return { error: e.response.data.result }; + } +}); diff --git a/src/components/chat-system/services/submitTicket.js b/src/components/chat-system/services/submitTicket.js new file mode 100644 index 0000000..776a9e4 --- /dev/null +++ b/src/components/chat-system/services/submitTicket.js @@ -0,0 +1,11 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; + +export const submitTicket = createAsyncThunk("SUBMIT_TICKET", async (d) => { + try { + const { data, status } = await axios.post("ticket/", d); + return { data, status }; + } catch (e) { + return { error: e.response.data.result }; + } +}); diff --git a/src/components/check-clearance-code/ChechClearanceCode.js b/src/components/check-clearance-code/ChechClearanceCode.js new file mode 100644 index 0000000..38d41a8 --- /dev/null +++ b/src/components/check-clearance-code/ChechClearanceCode.js @@ -0,0 +1,227 @@ +import React, { useState, useRef } from "react"; +import { + Button, + Dialog, + DialogActions, + DialogContent, + DialogTitle, + Grid, + IconButton, + TextField, + Tooltip, + Typography, +} from "@mui/material"; +import PageviewIcon from "@mui/icons-material/Pageview"; +import EditIcon from "@mui/icons-material/Edit"; +import AddCircleOutlineIcon from "@mui/icons-material/AddCircleOutline"; +import { PropTypes } from "prop-types"; + +import { editBarClearanceBar } from "../../features/slaughter-house/services/edit_bar_clearance_code"; +import { AppContext } from "../../contexts/AppContext"; +import { useDispatch } from "react-redux"; +import { Yup } from "../../lib/yup/yup"; +import { useFormik } from "formik"; + +export const CheckCleanceCode = ({ + clearanceCode, + onSave, + bar_key, + register_type, +}) => { + const dispatch = useDispatch(); + const { openNotif } = React.useContext(AppContext); + const [isEditing, setIsEditing] = useState(false); + const [isSaving, setIsSaving] = useState(false); + const inputRef = useRef(null); + + const formik = useFormik({ + initialValues: { + clearanceCode: clearanceCode || "", + }, + validationSchema: Yup.object({ + clearanceCode: Yup.string() + .required("این فیلد اجباری است!") + .matches(/^[A-Z0-9]+$/, "فقط حروف بزرگ و عدد مجاز است!"), + }), + + onSubmit: async (values) => { + setIsSaving(true); + + try { + const result = await dispatch( + editBarClearanceBar({ + key: bar_key, + bar_clearance_code: values.clearanceCode, + }) + ); + + if (result.error) { + openNotif({ + vertical: "top", + horizontal: "center", + msg: result.error.message || "خطا در ذخیره سازی", + severity: "error", + }); + } else { + openNotif({ + vertical: "top", + horizontal: "center", + msg: "کد با موفقیت ذخیره شد", + severity: "success", + }); + if (onSave) onSave(values.clearanceCode); + setIsEditing(false); + } + } catch (error) { + openNotif({ + vertical: "top", + horizontal: "center", + msg: "خطا در ارتباط با سرور", + severity: "error", + }); + } finally { + setIsSaving(false); + } + }, + }); + + const handleOpenModal = () => { + setIsEditing(true); + }; + + const canEdit = register_type === "manual"; + + return ( + + {formik.values.clearanceCode ? ( + + ) : null} + {canEdit && ( + + + {formik.values.clearanceCode ? ( + + ) : ( + + )} + + + )} + {isEditing && ( + { + formik.resetForm(); + setIsEditing(false); + }} + > + ویرایش کد گواهی + + + + + + + + + )} + + ); +}; + +const ViewCodeComponent = ({ clearanceCode }) => { + const formRef = useRef(null); + + const handleImageClick = () => { + if (formRef.current) { + formRef.current.submit(); + } + }; + return ( + + +
    + + + +
    + + {clearanceCode} + +
    + ); +}; + +CheckCleanceCode.propTypes = { + clearanceCode: PropTypes.any, + onSave: PropTypes.func, + bar_key: PropTypes.oneOfType([PropTypes.string, PropTypes.number]), + register_type: PropTypes.string, +}; + +ViewCodeComponent.propTypes = { + clearanceCode: PropTypes.any, +}; diff --git a/src/components/custom-card/CustomCard.js b/src/components/custom-card/CustomCard.js new file mode 100644 index 0000000..c34a2ad --- /dev/null +++ b/src/components/custom-card/CustomCard.js @@ -0,0 +1,55 @@ +import React from "react"; +import { Card, Typography } from "@mui/material"; + +function CustomCard(props) { + const { title, value, imageUrl } = props; + + return ( + + {/* This content will be po sitioned on top of the image */} + + {title} + + + {value} + + + ); +} + +export default CustomCard; diff --git a/src/components/date-picker/CustomDatePicker.js b/src/components/date-picker/CustomDatePicker.js new file mode 100644 index 0000000..6a2ec9a --- /dev/null +++ b/src/components/date-picker/CustomDatePicker.js @@ -0,0 +1,158 @@ +import React, { useState, useEffect, useRef } from "react"; +import "./TimePicker.css"; +import { Typography } from "@mui/material"; + +const TimePicker = ({ + value = "", + onChange, + label = "زمان", + disabled = false, + className = "", +}) => { + const [time, setTime] = useState(value); + const [isOpen, setIsOpen] = useState(false); + const timePickerRef = useRef(null); + + const hours = Array.from({ length: 24 }, (_, i) => + i.toString().padStart(2, "0") + ); + const minutes = Array.from({ length: 12 }, (_, i) => + (i * 5).toString().padStart(2, "0") + ); + + useEffect(() => { + setTime(value); + }, [value]); + + const [currentHour, currentMinute] = time ? time.split(":") : ""; + const selectedHour = currentHour || "00"; + const selectedMinute = currentMinute || "00"; + + useEffect(() => { + const handleClickOutside = (event) => { + if ( + timePickerRef.current && + !timePickerRef.current.contains(event.target) + ) { + setIsOpen(false); + } + }; + + document.addEventListener("mousedown", handleClickOutside); + return () => document.removeEventListener("mousedown", handleClickOutside); + }, []); + + const handleHourChange = (hour) => { + const newTime = `${hour}:${selectedMinute}:00`; + setTime(newTime); + onChange(newTime); + }; + + const handleMinuteChange = (minute) => { + const newTime = `${selectedHour}:${minute}:00`; + setTime(newTime); + onChange(newTime); + setIsOpen(false); + }; + + const handleInputChange = (e) => { + const value = e.target.value; + if (/^([0-1]?[0-9]|2[0-3]):[0-5][0-9]$/.test(value) || value === "") { + setTime(value); + if (value.includes(":") && value.length === 5) { + const formatted = `${value}:00`; + onChange(formatted); + } + } + }; + const handleInputBlur = () => { + if (!time.includes(":") || time.length !== 5) { + setTime(selectedHour + ":" + selectedMinute); + } + }; + + return ( +
    + + {label && } + +
    + {/* eslint-disable-next-line */} + setIsOpen(true)} + placeholder="hh:mm" + className="time-picker-input" + disabled={disabled} + aria-haspopup="listbox" + aria-expanded={isOpen} + /> + +
    + + {isOpen && ( +
    +
    +
    دقیقه
    +
    + {minutes.map((minute) => ( + + ))} +
    +
    +
    +
    ساعت
    +
    + {hours.map((hour) => ( + + ))} +
    +
    +
    + )} +
    + ); +}; + +export default TimePicker; diff --git a/src/components/date-picker/MonthlyDataCalendar.js b/src/components/date-picker/MonthlyDataCalendar.js new file mode 100644 index 0000000..e7b0f24 --- /dev/null +++ b/src/components/date-picker/MonthlyDataCalendar.js @@ -0,0 +1,401 @@ +import React, { useState, useEffect, useRef } from "react"; +import { + Box, + Typography, + Card, + Grid, + IconButton, + Popover, + TextField, +} from "@mui/material"; +import { + ChevronLeft, + ChevronRight, + CalendarMonthOutlined, +} from "@mui/icons-material"; +import PersianDate from "persian-date"; +import moment from "moment"; + +const MonthlyDataCalendar = ({ + onDateSelect, + dayData = {}, + selectedDate = null, + label = "انتخاب تاریخ", + className = "", + disableToday = false, + maxGregorianDate = null, + customDateFilter = null, +}) => { + const [currentMonth, setCurrentMonth] = useState(new PersianDate()); + const [calendarDays, setCalendarDays] = useState([]); + const [anchorEl, setAnchorEl] = useState(null); + const inputRef = useRef(null); + + const open = Boolean(anchorEl); + + const handleClick = () => { + setAnchorEl(inputRef.current); + }; + + const handleClose = () => { + setAnchorEl(null); + }; + + // Get Persian month names + const monthNames = [ + "فروردین", + "اردیبهشت", + "خرداد", + "تیر", + "مرداد", + "شهریور", + "مهر", + "آبان", + "آذر", + "دی", + "بهمن", + "اسفند", + ]; + + const dayNames = ["ش", "ی", "د", "س", "چ", "پ", "ج"]; + + const getDayData = (formattedDate) => { + return dayData[formattedDate] || null; + }; + + const isDateEnabled = (date) => { + const dateStr = date.format("YYYY/MM/DD"); + + if (customDateFilter) { + return customDateFilter(date, dateStr, dayData); + } + + const today = new PersianDate(); + const twoDaysAgo = new PersianDate().subtract("day", 2); + const oneDayAgo = new PersianDate().subtract("day", 1); + + const todayStr = today.format("YYYY/MM/DD"); + const twoDaysAgoStr = twoDaysAgo.format("YYYY/MM/DD"); + const oneDayAgoStr = oneDayAgo.format("YYYY/MM/DD"); + + const isTodayAllowed = disableToday ? false : dateStr === todayStr; + + let isAfterMax = false; + if (maxGregorianDate) { + const gregorianOfCell = date.toDate ? date.toDate() : new Date(); + isAfterMax = moment(gregorianOfCell).isAfter( + moment(maxGregorianDate), + "day" + ); + } + + const hasData = dayData[dateStr] !== undefined; + const isActive = + hasData && + (dayData[dateStr].active === undefined || + dayData[dateStr].active === true); + + return ( + !isAfterMax && + (isTodayAllowed || + dateStr === twoDaysAgoStr || + dateStr === oneDayAgoStr || + isActive) + ); + }; + + useEffect(() => { + const generateCalendar = () => { + const days = []; + const year = currentMonth.year(); + const month = currentMonth.month(); + const daysInMonth = currentMonth.daysInMonth(); + + const firstDayOfMonth = new PersianDate([year, month, 1]); + let dayOfWeek = firstDayOfMonth.day(); + if (dayOfWeek >= 1 && dayOfWeek <= 7) { + dayOfWeek = dayOfWeek - 1; + } + dayOfWeek = dayOfWeek % 7; + + for (let i = 0; i < dayOfWeek; i++) { + days.push(null); + } + + for (let day = 1; day <= daysInMonth; day++) { + const date = new PersianDate([year, month, day]); + const today = new PersianDate(); + const isEnabled = isDateEnabled(date); + const formattedDate = date.format("YYYY/MM/DD"); + const data = getDayData(formattedDate); + const hasZeroValue = isEnabled && data && data.value1 === 0; + + days.push({ + date: date, + day: day, + formattedDate: formattedDate, + isToday: + date.year() === today.year() && + date.month() === today.month() && + date.date() === today.date(), + isEnabled: isEnabled, + hasZeroValue: hasZeroValue, + }); + } + + setCalendarDays(days); + }; + + generateCalendar(); + }, [currentMonth, dayData]); + + const handleDayClick = (dayInfo) => { + if (dayInfo && dayInfo.isEnabled && !dayInfo.hasZeroValue && onDateSelect) { + onDateSelect(dayInfo); + handleClose(); + } + }; + + const handleNextMonth = () => { + const nextMonth = new PersianDate([ + currentMonth.year(), + currentMonth.month() + 1, + 1, + ]); + setCurrentMonth(nextMonth); + }; + + const handlePrevMonth = () => { + const prevMonth = new PersianDate([ + currentMonth.year(), + currentMonth.month() - 1, + 1, + ]); + setCurrentMonth(prevMonth); + }; + + const isSelected = (formattedDate) => { + return selectedDate && selectedDate === formattedDate; + }; + + const formatNumber = (num) => { + if (num === null || num === undefined) return ""; + return num.toLocaleString("fa-IR"); + }; + + const getDisplayValue = () => { + if (!selectedDate) return ""; + const dayInfo = calendarDays.find( + (d) => d && d.formattedDate === selectedDate + ); + return dayInfo + ? `${dayInfo.day.toLocaleString("fa-IR")} ${ + monthNames[dayInfo.date.month() - 1] + }` + : selectedDate; + }; + + return ( + + + + + ), + }} + sx={{ + cursor: "pointer", + width: "100%", + fontSize: { xs: "13px", sm: "16px" }, + }} + /> + + + + + + + + + + {monthNames[currentMonth.month() - 1]} {currentMonth.year()} + + + + + + + + + {dayNames.map((dayName, index) => ( + + + {dayName} + + + ))} + + + + {calendarDays.map((dayInfo, index) => { + if (!dayInfo) { + // Empty cell + return ( + + + + ); + } + + const data = getDayData(dayInfo.formattedDate); + const isSelectedDay = isSelected(dayInfo.formattedDate); + + let bgColor = "#fff"; + let borderColor = "#e0e0e0"; + let opacity = 1; + let cursorStyle = "pointer"; + + if (!dayInfo.isEnabled || dayInfo.hasZeroValue) { + bgColor = "#f5f5f5"; + borderColor = "#d0d0d0"; + opacity = dayInfo.hasZeroValue ? 0.4 : 0.25; + cursorStyle = "not-allowed"; + } else if (isSelectedDay) { + bgColor = "#e3f2fd"; + borderColor = "#1976d2"; + } + + if ( + dayInfo.isToday && + dayInfo.isEnabled && + !dayInfo.hasZeroValue + ) { + borderColor = "#ff9800"; + } + + return ( + + handleDayClick(dayInfo)} + sx={{ + aspectRatio: "1/1", + cursor: cursorStyle, + transition: "all 0.2s ease", + backgroundColor: bgColor, + border: { + xs: `1.5px solid ${borderColor}`, + sm: `2px solid ${borderColor}`, + }, + display: "flex", + flexDirection: "column", + alignItems: "center", + justifyContent: "center", + p: { xs: 0.5, sm: 1 }, + gap: { xs: 0.25, sm: 0.5 }, + opacity: opacity, + "&:hover": + dayInfo.isEnabled && !dayInfo.hasZeroValue + ? { + transform: "scale(1.05)", + boxShadow: "0 4px 12px rgba(0,0,0,0.15)", + backgroundColor: "#f5f5f5", + } + : {}, + }} + > + + {dayInfo.day.toLocaleString("fa-IR")} + + + {data && data.value1 !== undefined && ( + + {formatNumber(data.value1)} + + )} + + + ); + })} + + + + + ); +}; + +export default MonthlyDataCalendar; diff --git a/src/components/date-picker/TimePicker.css b/src/components/date-picker/TimePicker.css new file mode 100644 index 0000000..2a7fa98 --- /dev/null +++ b/src/components/date-picker/TimePicker.css @@ -0,0 +1,121 @@ +.time-picker { + position: relative; + font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen, + Ubuntu, Cantarell, sans-serif; + width: 100%; + max-width: 100px; +} + +.time-picker-label { + display: block; + margin-bottom: 8px; + font-size: 14px; + color: #333; + font-weight: 500; +} + +.time-picker-input-container { + position: relative; + display: flex; + align-items: center; +} + +.time-picker-input { + width: 100%; + padding: 10px 40px 10px 12px; + border: 1px solid #ddd; + border-radius: 6px; + font-size: 14px; + transition: border-color 0.2s; + box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05); +} + +.time-picker-input:focus { + outline: none; + border-color: #4a90e2; + box-shadow: 0 0 0 3px rgba(74, 144, 226, 0.2); +} + +.time-picker-input:disabled { + background-color: #f5f5f5; + cursor: not-allowed; +} + +.time-picker-toggle { + position: absolute; + right: 8px; + background: none; + border: none; + cursor: pointer; + color: #666; + padding: 4px; + display: flex; + align-items: center; + justify-content: center; +} + +.time-picker-toggle:disabled { + color: #ccc; + cursor: not-allowed; +} + +.time-picker-toggle:hover:not(:disabled) { + color: #333; +} + +.time-picker-dropdown { + position: absolute; + top: 0; + transform: translateY(-100%); + left: 0; + margin-bottom: 4px; + background: white; + border: 1px solid #ddd; + border-radius: 6px; + box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1); + z-index: 1000; + display: flex; + max-height: 300px; + overflow-y: auto; +} + +.time-picker-column { + flex: 1; + min-width: 60px; +} + +.time-picker-header { + padding: 8px 12px; + font-size: 12px; + font-weight: 600; + color: #666; + background-color: #f9f9f9; + border-bottom: 1px solid #eee; + text-align: center; +} + +.time-picker-list { + overflow-y: auto; + max-height: 250px; +} + +.time-picker-item { + display: block; + width: 100%; + padding: 8px 12px; + border: none; + background: none; + text-align: center; + cursor: pointer; + font-size: 14px; + color: #333; +} + +.time-picker-item:hover { + background-color: #f0f7ff; +} + +.time-picker-item.selected { + background-color: #4a90e2; + color: white; +} diff --git a/src/components/dialog-alert/DialogAlert.js b/src/components/dialog-alert/DialogAlert.js new file mode 100644 index 0000000..5fe2aeb --- /dev/null +++ b/src/components/dialog-alert/DialogAlert.js @@ -0,0 +1,72 @@ +import * as React from "react"; +import Dialog from "@mui/material/Dialog"; +import DialogActions from "@mui/material/DialogActions"; +import DialogContent from "@mui/material/DialogContent"; +import DialogContentText from "@mui/material/DialogContentText"; +import DialogTitle from "@mui/material/DialogTitle"; +import Slide from "@mui/material/Slide"; +import { PropTypes } from "prop-types"; +import { Checkbox, Typography } from "@mui/material"; +import { Grid } from "../grid/Grid"; +import { SPACING } from "../../data/spacing"; + +const Transition = React.forwardRef(function Transition(props, ref) { + return ; +}); + +export function DialogAlert({ title, content, actions, btnTitle, isAccepted }) { + const [open, setOpen] = React.useState(false); + + const handleClickOpen = () => { + setOpen(true); + }; + + const handleClose = () => { + setOpen(false); + }; + + return ( +
    + + + + + {btnTitle} + + + + + + {title} + + + {content} + + + {actions} + +
    + ); +} + +DialogAlert.propTypes = { + title: PropTypes.string, + content: PropTypes.string, + btnTitle: PropTypes.string, + isAccepted: PropTypes.bool, + actions: PropTypes.array, +}; diff --git a/src/components/drawer/Drawer.js b/src/components/drawer/Drawer.js new file mode 100644 index 0000000..746ea84 --- /dev/null +++ b/src/components/drawer/Drawer.js @@ -0,0 +1,145 @@ +import * as React from "react"; +import Drawer from "@mui/material/Drawer"; +import { useDispatch, useSelector } from "react-redux"; +import { useEffect } from "react"; +import { DRAWER } from "../../lib/redux/slices/appSlice"; +import { Grid } from "../grid/Grid"; +import { Box, Button, Typography } from "@mui/material"; +import { SPACING } from "../../data/spacing"; + +export default function TemporaryDrawer() { + const { drawer } = useSelector((state) => state.appSlice); + const dispatch = useDispatch(); + + const [state, setState] = React.useState({ + top: false, + left: false, + bottom: false, + right: false, + size: false, + content: false, + }); + + useEffect(() => { + dispatch( + DRAWER({ + top: false, + left: false, + bottom: false, + right: false, + title: null, + content: null, + size: 310, + }) + ); + }, []); + + useEffect(() => { + if (!drawer) { + setState({ + top: false, + left: false, + bottom: false, + right: false, + size: null, + content: null, + }); + } else { + setState(drawer); + } + }, [drawer]); + + const toggleDrawer = (anchor, open) => (event) => { + if ( + event.type === "keydown" && + (event.key === "Tab" || event.key === "Shift") + ) { + return; + } + dispatch( + DRAWER({ + [anchor]: open, + }) + ); + // setState({ ...state, [anchor]: open }); + }; + const list = (anchor) => ( + + + + + {drawer.title} + + + + + + {drawer?.content} + + ); + + return ( +
    + {["left", "right", "top", "bottom"].map((anchor) => ( + + + {list(anchor)} + + + ))} +
    + ); +} diff --git a/src/components/error-fallback/ErrorFallback.js b/src/components/error-fallback/ErrorFallback.js new file mode 100644 index 0000000..f4b7e57 --- /dev/null +++ b/src/components/error-fallback/ErrorFallback.js @@ -0,0 +1,200 @@ +import { Button, Typography } from "@mui/material"; +// import { LottiePlayer } from "lottie-react"; +import { PropTypes } from "prop-types"; +import { Grid } from "../grid/Grid"; +import groovyWalkAnimation from "../../assets/lottie/error.json"; +import Lottie from "lottie-react"; +import useUserProfile from "../../features/authentication/hooks/useUserProfile"; +import { useEffect } from "react"; + +export function ErrorFallback({ error, resetErrorBoundary }) { + useEffect(() => { + const body = document.body; + body.style.background = "#341f97"; + + return () => { + body.style.background = ""; + }; + }, []); + + const nVer = navigator.appVersion; + const nAgt = navigator.userAgent; + let browserName = navigator.appName; + let fullVersion = "" + parseFloat(navigator.appVersion); + let majorVersion = parseInt(navigator.appVersion, 10); + let nameOffset, verOffset, ix; + + // In Opera, the true version is after "OPR" or after "Version" + if ((verOffset = nAgt.indexOf("OPR")) !== -1) { + browserName = "Opera"; + fullVersion = nAgt.substring(verOffset + 4); + if ((verOffset = nAgt.indexOf("Version")) !== -1) + fullVersion = nAgt.substring(verOffset + 8); + } + // In MS Edge, the true version is after "Edg" in userAgent + else if ((verOffset = nAgt.indexOf("Edg")) !== -1) { + browserName = "Microsoft Edge"; + fullVersion = nAgt.substring(verOffset + 4); + } + // In MSIE, the true version is after "MSIE" in userAgent + else if ((verOffset = nAgt.indexOf("MSIE")) !== -1) { + browserName = "Microsoft Internet Explorer"; + fullVersion = nAgt.substring(verOffset + 5); + } + // In Chrome, the true version is after "Chrome" + else if ((verOffset = nAgt.indexOf("Chrome")) !== -1) { + browserName = "Chrome"; + fullVersion = nAgt.substring(verOffset + 7); + } + // In Safari, the true version is after "Safari" or after "Version" + else if ((verOffset = nAgt.indexOf("Safari")) !== -1) { + browserName = "Safari"; + fullVersion = nAgt.substring(verOffset + 7); + if ((verOffset = nAgt.indexOf("Version")) !== -1) + fullVersion = nAgt.substring(verOffset + 8); + } + // In Firefox, the true version is after "Firefox" + else if ((verOffset = nAgt.indexOf("Firefox")) !== -1) { + browserName = "Firefox"; + fullVersion = nAgt.substring(verOffset + 8); + } + // In most other browsers, "name/version" is at the end of userAgent + else if ( + (nameOffset = nAgt.lastIndexOf(" ") + 1) < + (verOffset = nAgt.lastIndexOf("/")) + ) { + browserName = nAgt.substring(nameOffset, verOffset); + fullVersion = nAgt.substring(verOffset + 1); + if (browserName.toLowerCase() === browserName.toUpperCase()) { + browserName = navigator.appName; + } + } + // trim the fullVersion string at semicolon/space if present + if ((ix = fullVersion.indexOf(";")) !== -1) + fullVersion = fullVersion.substring(0, ix); + if ((ix = fullVersion.indexOf(" ")) !== -1) + fullVersion = fullVersion.substring(0, ix); + + majorVersion = parseInt("" + fullVersion, 10); + if (isNaN(majorVersion)) { + fullVersion = "" + parseFloat(navigator.appVersion); + majorVersion = parseInt(navigator.appVersion, 10); + } + + let OSName = "Unknown OS"; + if (navigator.appVersion.indexOf("Win") !== -1) OSName = "Windows"; + if (navigator.appVersion.indexOf("Mac") !== -1) OSName = "MacOS"; + if (navigator.appVersion.indexOf("X11") !== -1) OSName = "UNIX"; + if (navigator.appVersion.indexOf("Linux") !== -1) OSName = "Linux"; + + const [, userProfile] = useUserProfile(); + + const reportObj = { + error: { + stack: error?.stack || "No stack trace available", + msg: error?.message || "Unknown error", + }, + url: window.location?.href || window.location, + userProfile: userProfile || null, + date: new Date(), + os: OSName, + browserName, + browserVersion: fullVersion + "-" + majorVersion, + navigatorAppName: navigator.appName, + navigatorAppVersion: nVer, + navigatorUserAgent: nAgt, + }; + + useEffect(() => { + console.log( + { error, reportObj }, + JSON.stringify(error, null, 2), + "Current Error" + ); + }, [error]); + useEffect(() => { + if (error) { + // if (window.location.hostname !== "localhost") { + // fetch("https://core-inventory.iran.liara.run/crashes/rasadyar/", { + // method: "POST", // or 'PUT' + // headers: { + // "Content-Type": "application/json", + // }, + // body: JSON.stringify(reportObj), + // }) + // .then((response) => response.json()) + // .then((data) => { + // }) + // .catch((error) => { + // console.error("Error:", error); + // }); + // } + } + }, [error]); + + return ( + + + + {groovyWalkAnimation ? ( + + ) : ( + + ⚠️ + + )} + + + + متاسفیم، این بخش در دست توسعه است! + + + + + مشکل شما به بخش فنی گزارش داده شد و در حال رفع مشکل هستیم، لطفا چند + لحظه دیگر تلاش کنید. + + + + + در صورت رفع نشدن مشکل با شماره 02128421237 تماس حاصل فرمایید. + + + + + + + + + ); +} + +ErrorFallback.propTypes = { + error: PropTypes.any, + resetErrorBoundary: PropTypes.any, +}; diff --git a/src/components/error-fallback/style.css b/src/components/error-fallback/style.css new file mode 100644 index 0000000..e69de29 diff --git a/src/components/excel-link/ExcelLink.js b/src/components/excel-link/ExcelLink.js new file mode 100644 index 0000000..6fbe0a6 --- /dev/null +++ b/src/components/excel-link/ExcelLink.js @@ -0,0 +1,58 @@ +import { Tooltip } from "@mui/material"; +import axios from "axios"; +import React, { useContext } from "react"; +import { getRoleFromUrl } from "../../utils/getRoleFromUrl"; +import { useSelector } from "react-redux"; +import "./styles.css"; +import { AppContext } from "../../contexts/AppContext"; + +export const ExcelLink = ({ link, text, fontSize, role, token, fColor }) => { + const authToken = useSelector((state) => state.userSlice.authToken); + const [openNotif] = useContext(AppContext); + + return ( + <> + {" "} + {getRoleFromUrl() === "ProvinceOperator" || + getRoleFromUrl() === "SuperAdmin" ? ( + + { + openNotif({ + vertical: "top", + horizontal: "center", + msg: "فایل اکسل در حال دانلود می باشد، این علمیات ممکن است زمان بر باشد لطفا صبر کنید.", + severity: "success", + }); + }} + className="cell" + style={{ + textDecoration: "none", + fontSize: fontSize ? fontSize : "12px", + color: fColor ? fColor : "white", + }} + href={ + link + ? `${axios.defaults.baseURL}${link}${ + role ? `&role=${getRoleFromUrl()}` : "" + }${token ? `&token=${authToken}` : ""}` + : "#" + } + > + {text} + + + ) : ( + + {text} + + )} + + ); +}; diff --git a/src/components/excel-link/styles.css b/src/components/excel-link/styles.css new file mode 100644 index 0000000..60211d3 --- /dev/null +++ b/src/components/excel-link/styles.css @@ -0,0 +1,3 @@ +.cell:hover { + color: white !important; +} diff --git a/src/components/file-uploader/FileUploader.js b/src/components/file-uploader/FileUploader.js new file mode 100644 index 0000000..56b86d7 --- /dev/null +++ b/src/components/file-uploader/FileUploader.js @@ -0,0 +1,185 @@ +import React, { useContext, useEffect, useState } from "react"; +import CloudUploadIcon from "@mui/icons-material/CloudUpload"; +import { styled } from "@mui/material/styles"; +import { + Button, + IconButton, + Typography, + Box, + LinearProgress, + Chip, +} from "@mui/material"; +import CloseIcon from "@mui/icons-material/Close"; +import CheckCircleIcon from "@mui/icons-material/CheckCircle"; +import { AppContext } from "../../contexts/AppContext"; +import { motion, AnimatePresence } from "framer-motion"; + +const VisuallyHiddenInput = styled("input")({ + clip: "rect(0 0 0 0)", + clipPath: "inset(50%)", + height: 1, + overflow: "hidden", + position: "absolute", + bottom: 0, + left: 0, + whiteSpace: "nowrap", + width: 1, +}); + +const CompactFileItem = styled(motion.div)(({ theme }) => ({ + display: "flex", + alignItems: "center", + justifyContent: "space-between", + padding: theme.spacing(0.5), + margin: theme.spacing(0.25, 0), + borderRadius: theme.shape.borderRadius, + "&:hover": { + backgroundColor: theme.palette.action.hover, + }, +})); + +export const FileUploader = ({ onChange }) => { + const [filesList, setFilesList] = useState([]); + const [isUploading, setIsUploading] = useState(false); + const [uploadProgress, setUploadProgress] = useState(0); + const [openNotif] = useContext(AppContext); + + const handleFileUpload = (event) => { + const file = event.target.files[0]; + if (!file) return; + + if (file.size > 5000000) { + openNotif({ + vertical: "top", + horizontal: "center", + msg: "حجم فایل بیش از حد مجاز است!", + severity: "error", + }); + return; + } + + setIsUploading(true); + setUploadProgress(0); + + const interval = setInterval(() => { + setUploadProgress((prev) => { + if (prev >= 100) { + clearInterval(interval); + setIsUploading(false); + return 100; + } + return prev + 10; + }); + }, 100); + + setFilesList((prev) => [...prev, file]); + }; + + const handleRemoveFile = (index) => { + setFilesList((prevFiles) => prevFiles.filter((_, i) => i !== index)); + }; + + useEffect(() => { + if (onChange) { + onChange(filesList); + } + }, [filesList, onChange]); + + return ( + + + + + {!!filesList.length && ( + + + {isUploading && ( + + )} + + {filesList.map((item, i) => ( + + + + + {item.name} + + + + handleRemoveFile(i)} + size="small" + sx={{ p: 0.5 }} + > + + + + ))} + + + )} + + + ); +}; diff --git a/src/components/flex-table/ColsListItems.js b/src/components/flex-table/ColsListItems.js new file mode 100644 index 0000000..9ed1e58 --- /dev/null +++ b/src/components/flex-table/ColsListItems.js @@ -0,0 +1,42 @@ +// Import necessary dependencies from Material-UI +import React, { useEffect, useState } from "react"; +import List from "@mui/material/List"; +import ListItem from "@mui/material/ListItem"; +import Checkbox from "@mui/material/Checkbox"; +import Typography from "@mui/material/Typography"; + +// Define your CompactList component +const ColsListItems = ({ items, changeColsHandler }) => { + // State to manage the checked items + const [checkedItems, setCheckedItems] = useState(items); + + // Function to handle checkbox state changes + const handleCheckboxChange = (item) => { + const prevItems = checkedItems.filter((it) => it.name !== item.name); + let newItem = { ...item }; + newItem.hide = !newItem.hide; + + const arrayOfObjects = [...prevItems, newItem]; + setCheckedItems(arrayOfObjects); + }; + + useEffect(() => { + changeColsHandler(checkedItems); + }, [checkedItems]); + + return ( + + {checkedItems.map((item) => ( + + handleCheckboxChange(item)} + /> + {item.name} + + ))} + + ); +}; + +export default ColsListItems; diff --git a/src/components/flex-table/FlexTable.js b/src/components/flex-table/FlexTable.js new file mode 100644 index 0000000..7fe84fc --- /dev/null +++ b/src/components/flex-table/FlexTable.js @@ -0,0 +1,194 @@ +import { useEffect, useMemo, useState } from "react"; +import { + MaterialReactTable, + useMaterialReactTable, +} from "material-react-table"; +import { MRT_Localization_FA } from "material-react-table/locales/fa"; +import { Grid } from "../grid/Grid"; +import { useSelector } from "react-redux"; +import { formatJustDate } from "../../utils/formatTime"; +import axios from "axios"; +import { Box } from "@mui/material"; +import { RowItemCity } from "./RowItemCity"; + +export const FlexTable = () => { + const { authToken } = useSelector((state) => state.userSlice); + const [data, setData] = useState([]); + const [isError, setIsError] = useState(false); + const [isLoading, setIsLoading] = useState(false); + const [isRefetching, setIsRefetching] = useState(false); + const [rowCount, setRowCount] = useState(0); + + const [columnFilters, setColumnFilters] = useState([]); + const [globalFilter, setGlobalFilter] = useState(""); + const [sorting, setSorting] = useState([]); + const [pagination, setPagination] = useState({ + pageIndex: 0, + pageSize: 10, + }); + + useEffect(() => { + const fetchData = async () => { + if (!data.length) { + setIsLoading(true); + } else { + setIsRefetching(true); + } + const url = new URL( + `${axios.defaults.baseURL}poultry_requests_for_total_information_in_table/?date1=2023-12-24&date2=2023-12-26&search=filter&value=` + ); + // url.searchParams.set( + // "page", + // `${pagination.pageIndex * pagination.pageSize}` + // ); + + url.searchParams.set("page", `${pagination.pageIndex + 1}`); + url.searchParams.set("size", `${pagination.pageSize}`); + url.searchParams.set("filters", JSON.stringify(columnFilters ?? [])); + url.searchParams.set("globalFilter", globalFilter ?? ""); + url.searchParams.set("sorting", JSON.stringify(sorting ?? [])); + + try { + const response = await fetch(url.href, { + headers: { + Authorization: `Bearer ${authToken}`, + }, + }); + const json = await response.json(); + const refineData = json.results.map((item) => { + let sellType = ""; + + if (item.directBuying) { + sellType = "خرید مستقیم"; + } else if (item.union) { + sellType = "خرید خارج از استان"; + } else { + sellType = "اتحادیه"; + } + return { + shomarehParvande: item?.order_code, + tarikhKoshtar: formatJustDate(item?.send_date), + noeForoosh: sellType, + farmMorghdar: item?.poultry?.unit_name, + tedad: item?.quantity?.toLocaleString(), + vaznTotal: (item?.quantity * item?.Index_weight)?.toLocaleString(), + ghimatMorghdar: item?.amount?.toLocaleString() + " ریال", + item, + }; + }); + setData(refineData); + setRowCount(json.count); + } catch (error) { + setIsError(true); + console.error(error); + return; + } + setIsError(false); + setIsLoading(false); + setIsRefetching(false); + }; + fetchData(); + }, [ + columnFilters, + globalFilter, + pagination.pageIndex, + pagination.pageSize, + sorting, + ]); + + const columns = useMemo( + () => [ + { + accessorKey: "shomarehParvande", + header: "شماره پرونده", + }, + { + accessorKey: "tarikhKoshtar", + header: "تاریخ کشتار", + }, + { + accessorKey: "noeForoosh", + header: "نوع فروش", + }, + { + accessorKey: "farmMorghdar", + header: "فارم (مرغدار)", + }, + { + accessorKey: "tedad", + header: "تعداد", + }, + { + accessorKey: "vaznTotal", + header: "وزن کل (کیلوگرم)", + }, + { + accessorKey: "ghimatMorghdar", + header: "قیمت مرغدار", + }, + ], + [] + ); + + const table = useMaterialReactTable({ + columns, + data, + renderDetailPanel: ({ row }) => { + return ( + + + {/* Address */} + {/* City: {row.original.city} + State: {row.original.state} + Country: {row.original.country} */} + + ); + }, + enableRowSelection: true, + getRowId: (row) => row.key, + initialState: { + showColumnFilters: true, + density: "compact", + enableRowOrdering: false, + }, + manualFiltering: true, + manualPagination: true, + enableStickyHeader: true, + manualSorting: true, + muiToolbarAlertBannerProps: isError + ? { + color: "error", + children: "مشکلی پیش آمده است.", + } + : undefined, + onColumnFiltersChange: setColumnFilters, + onGlobalFilterChange: setGlobalFilter, + onPaginationChange: setPagination, + onSortingChange: setSorting, + rowCount, + state: { + columnFilters, + globalFilter, + isLoading, + pagination, + showAlertBanner: isError, + showProgressBars: isRefetching, + sorting, + }, + enableColumnOrdering: true, + localization: MRT_Localization_FA, + }); + + return ( + + + + ); +}; diff --git a/src/components/flex-table/RowItemCity.js b/src/components/flex-table/RowItemCity.js new file mode 100644 index 0000000..ac3b59d --- /dev/null +++ b/src/components/flex-table/RowItemCity.js @@ -0,0 +1,181 @@ +import { + Accordion, + AccordionDetails, + AccordionSummary, + Typography, +} from "@mui/material"; +import ExpandMoreIcon from "@mui/icons-material/ExpandMore"; +import { Grid } from "../grid/Grid"; +import { SPACING } from "../../data/spacing"; + +const styles = { + tableInNewPage: { + pageBreakAfter: "always", + paddingLeft: "40px", + paddingRight: "40px", + direction: "rtl", + fontFamily: "titr", + fontWeight: "bold", + }, + container: { + width: "95%", + alignSelf: "center", + pageBreakInside: "avoid", + }, + + invoiceTable: { + width: "100%", + borderCollapse: "collapse", + alignSelf: "center", + fontFamily: "titr", + marginBottom: "5px", + marginTop: "15px", + borderRadius: "10px", + }, + tableCell: { + border: "1px solid #000", + pAlign: "left", + textAlign: "center", + fontSize: 12, + fontWeight: "bolder", + color: "#403e3e", + }, + tableCellGreen: { + border: "1px solid #000", + pAlign: "left", + textAlign: "center", + fontSize: 12, + color: "white", + fontWeight: "bolder", + backgroundColor: "rgba(26, 188, 156, 0.7)", + }, + tableCellMobile: { + border: "1px solid #000", + pAlign: "left", + textAlign: "center", + fontSize: 12, + }, + tableInnerCell: { + border: "1px solid #000", + pAlign: "left", + textAlign: "center", + fontSize: 9, + whiteSpace: "nowrap", + }, + tableHeader: { + backgroundColor: "rgba(211, 211, 211, 0.3)", + pageBreakAfter: "auto", + }, + headerRow: { + background: "linear-gradient(to right, #E684AE, #79CBCA, #77A1D3)", + backgroundColor: "rgba(232, 67, 147, 0.4)", + color: "#422020", + pageBreakInside: "avoid", + pageBreakAfter: "auto", + }, + + tableHeaderCell: { + fontSize: 14, + border: "1px solid #000", + padding: "4px", + textAlign: "center", + fontWeight: "bolder", + }, + tableHeaderCellGreen: { + backgroundColor: "rgba(26, 188, 156, 0.7)", + fontSize: 12, + border: "1px solid #000", + padding: "4px", + textAlign: "center", + fontWeight: "bolder", + color: "white", + }, + footer: { + left: 0, + bottom: 0, + width: "100%", + position: "absolute", + }, + footerContainer: { + alignItems: "center", + display: "flex", + }, + + tableRowEven: { + backgroundColor: "rgba(170, 183, 255, 0.3)", + }, + titleOfTable: { + marginRight: "20px", + fontSize: "15px", + }, + tableCellAlert: { + border: "1px solid #000", + pAlign: "left", + textAlign: "center", + fontSize: 12, + color: "red", + }, + levelDetails: { + color: "red", + fontSize: 12, + }, +}; + +export const RowItemCity = ({ item }) => { + return ( + + } + aria-controls="panel1a-content" + className="row-item-table-accordion" + > + مرحله شهرستان + + + + مرحله شهرستان + + + + + + + + + + + + {item?.city_state?.date ? ( + + + + + + + + + + + ) : ( + + )} +
    اپراتورسمتتلفنتعاونی مرغدارآدرسوضعیت
    + {item?.city_state?.city_operator_fullname} + اپراتور شهرستان + {item?.city_state?.city_operator_mobile} + {item?.city_state?.poultry} + {item?.city_state?.province + + " - " + + item?.city_state?.city} + + {item?.city_state?.state === "accept" + ? "تایید شده" + : "رد شده"} +
    + هنوز شهرستان پرونده را تائید نکرده است +
    +
    +
    +
    + ); +}; diff --git a/src/components/grid/Grid.js b/src/components/grid/Grid.js new file mode 100644 index 0000000..7a0fbcc --- /dev/null +++ b/src/components/grid/Grid.js @@ -0,0 +1,130 @@ +import React, { useState, useRef, useEffect } from "react"; +import Grid2 from "@mui/material/Unstable_Grid2"; +import { PropTypes } from "prop-types"; +import { styled } from "@mui/material/styles"; +import Button from "@mui/material/Button"; +import ExpandMoreIcon from "@mui/icons-material/ExpandMore"; +import ExpandLessIcon from "@mui/icons-material/ExpandLess"; + +const ToggleButton = styled(Button)({ + position: "absolute", + opacity: "50%", + bottom: 0, + right: 0, + transform: "translateX(-50%)", + minWidth: "auto", + padding: "2px 8px", + backgroundColor: "white", + border: "1px solid #B0B0B0", + borderRadius: "10px 10px 0 0", + "&:hover": { + backgroundColor: "#f5f5f5", + }, + zIndex: 100, +}); + +const StyledGrid = styled(Grid2)( + ({ theme, isDashboard, isPolicy, isLocked, isExpanded }) => ({ + ...(isDashboard + ? { + position: "relative", + overflow: "hidden", + "&::before": { + content: '""', + position: "absolute", + top: 0, + left: 0, + right: 0, + pointerEvents: "none", + zIndex: -1, + }, + padding: theme.spacing(2), + background: theme.palette.background.paper, + boxShadow: "rgba(100, 100, 111, 0.2) 2px 6px 6px 2px", + borderRadius: "2px 2px 10px 10px", + zIndex: 0, + } + : isPolicy && { + padding: "10px", + color: "#727272", + borderStyle: "solid", + borderColor: "#B0B0B0", + borderWidth: "1px", + borderRadius: "8px", + width: "270px", + background: isLocked ? "#EAEFFF" : "white", + height: isExpanded ? "auto" : "100px", + overflow: isExpanded ? "unset" : "hidden", + position: "relative", + "&:hover": { + backgroundColor: isLocked ? "#EAEFFF" : "#f5f5f5", + }, + }), + }) +); + +export const Grid = (props) => { + const { children, isDashboard, isPolicy, ...rest } = props; + const [isExpanded, setIsExpanded] = useState(false); + const [showToggle, setShowToggle] = useState(false); + const [isFirstRender, setIsFirstRender] = useState(true); + const contentRef = useRef(null); + + useEffect(() => { + if (isPolicy && contentRef.current) { + const contentHeight = contentRef.current.scrollHeight; + setShowToggle(contentHeight > 120); + } + }, [children, isPolicy]); + + setTimeout(() => { + setIsFirstRender(false); + }, 3000); + + const toggleExpand = () => { + setIsExpanded(!isExpanded); + }; + + useEffect(() => { + if (contentRef.current) { + const contentHeight = contentRef.current.scrollHeight; + if (contentHeight > 120) { + if (!isFirstRender) { + setIsExpanded(true); + } + } else { + setIsExpanded(false); + } + } + }, [contentRef?.current?.scrollHeight]); + + return ( + + {children} + {isPolicy && showToggle && ( + + {isExpanded ? : } + + )} + + ); +}; + +Grid.propTypes = { + children: PropTypes.any, + isDashboard: PropTypes.bool, + isPolicy: PropTypes.bool, + isLocked: PropTypes.bool, +}; + +Grid.defaultProps = { + isDashboard: false, + isPolicy: false, + isLocked: false, +}; diff --git a/src/components/image-upload/ImageUpload.js b/src/components/image-upload/ImageUpload.js new file mode 100644 index 0000000..d2dea61 --- /dev/null +++ b/src/components/image-upload/ImageUpload.js @@ -0,0 +1,137 @@ +import ReactImageUploading from "react-images-uploading"; +import { Grid } from "../grid/Grid"; +import { Button, IconButton, Tooltip } from "@mui/material"; +import UploadIcon from "@mui/icons-material/Upload"; +import { SPACING } from "../../data/spacing"; +import React from "react"; +import { PropTypes } from "prop-types"; +import PublishedWithChangesIcon from "@mui/icons-material/PublishedWithChanges"; +import DeleteIcon from "@mui/icons-material/Delete"; + +export const ImageUpload = ({ + images, + onChange, + maxNumber, + title, + disabled, + showImages, + size, +}) => { + let showImagesList; + if (showImages === undefined || showImages === true) { + showImagesList = true; + } else { + showImagesList = false; + } + + return ( + + {({ + imageList, + onImageUpload, + onImageRemoveAll, + onImageUpdate, + onImageRemove, + isDragging, + dragProps, + }) => ( + // write your building UI + + {showImagesList && ( + <> + {imageList.map((image, index) => ( + + profile + + + + onImageUpdate(index)} + > + + + + + + + onImageRemove(index)} + > + + + + + + + ))} + + )} + + {imageList?.length !== maxNumber && ( + + + + )} + + )} + + ); +}; + +ImageUpload.propTypes = { + images: PropTypes.array, + onChange: PropTypes.func, + maxNumber: PropTypes.number, + title: PropTypes.string, + disabled: PropTypes.any, +}; diff --git a/src/components/img-uploader/ImgUploader.js b/src/components/img-uploader/ImgUploader.js new file mode 100644 index 0000000..f6428ab --- /dev/null +++ b/src/components/img-uploader/ImgUploader.js @@ -0,0 +1,38 @@ +import React, { useState } from "react"; +import { Box, Input, Typography } from "@mui/material"; + +const ImgUploader = () => { + const [selectedImage, setSelectedImage] = useState(null); + const [imageUrl, setImageUrl] = useState(null); + + const handleFileChange = (event) => { + const selectedFile = event.target.files[0]; + if (selectedFile) { + const reader = new FileReader(); + reader.onload = () => { + setSelectedImage(selectedFile); + setImageUrl(reader.result); + }; + reader.readAsDataURL(selectedFile); + } + }; + + return ( + + سند: + + {selectedImage && ( + + img + + )} + + ); +}; + +export default ImgUploader; diff --git a/src/components/inspection-details-modal/InspectionDetailsModal.js b/src/components/inspection-details-modal/InspectionDetailsModal.js new file mode 100644 index 0000000..bf854e9 --- /dev/null +++ b/src/components/inspection-details-modal/InspectionDetailsModal.js @@ -0,0 +1,551 @@ +import React, { useState } from "react"; +import { Box, Typography, Tab, Tabs, IconButton, Divider } from "@mui/material"; +import { Grid } from "../grid/Grid"; +import { SPACING } from "../../data/spacing"; +import { LabelField } from "../label-field/LabelField"; +import CloseIcon from "@mui/icons-material/Close"; +import PictureAsPdfIcon from "@mui/icons-material/PictureAsPdf"; +import axios from "axios"; + +export const InspectionDetailsModal = ({ item }) => { + const [statusTab, setStatusTab] = useState(0); + const [fullscreenMedia, setFullscreenMedia] = useState(null); + + const handleStatusTabChange = (newValue) => { + setStatusTab(newValue); + }; + + const handleOpenFullscreen = (mediaUrl) => { + setFullscreenMedia(mediaUrl); + }; + + const handleCloseFullscreen = () => { + setFullscreenMedia(null); + }; + + const handleDownloadPdf = () => { + const baseUrl = axios.defaults.baseURL || ""; + const url = `${baseUrl}poultry_science_report_pdf/?key=${item?.key}`; + window.open(url, "_blank"); + }; + + const formatDate = (dateString) => { + if (!dateString) return "---"; + try { + const date = new Date(dateString); + return date.toLocaleDateString("fa-IR"); + } catch { + return dateString; + } + }; + + const formatDateTime = (dateString) => { + if (!dateString) return "---"; + try { + const date = new Date(dateString); + return `${date.toLocaleDateString("fa-IR")} (${date.toLocaleTimeString( + "fa-IR", + { hour: "2-digit", minute: "2-digit" } + )})`; + } catch { + return dateString; + } + }; + + const poultry = item?.hatching?.poultry || {}; + const hatching = item?.hatching || {}; + const reportInfo = item?.reportInformation || {}; + + const informationData = { + "نام واحد مرغداری": poultry?.unitName || "---", + "کد یکتا / شناسه واحد": poultry?.breedingUniqueId || "---", + "پروانه بهداشتی": poultry?.healthCertificateNumber || "---", + "مجوز جوجه ریزی": hatching?.licenceNumber || "---", + "کد اپیدمیولوژیک": poultry?.epidemiologicalCode || "---", + "اعتبار پروانه بهره برداری": poultry?.operatingLicenceCapacity + ? `${poultry.operatingLicenceCapacity}` + : "---", + "وضعیت مستاجر": hatching?.hasTenant + ? hatching?.InteractTypeName || "دارد" + : "ندارد", + "نام مالک / بهره بردار": poultry?.user?.fullname || "---", + "نوع مالکیت": hatching?.InteractTypeName || "---", + "کد ملی بهره بردار": + poultry?.user?.nationalId || poultry?.user?.nationalCode || "---", + استان: poultry?.address?.province?.name || poultry?.provinceName || "---", + شهر: poultry?.address?.city?.name || poultry?.cityName || "---", + "مختصات جغرافیایی": + poultry?.Lat && poultry?.Long + ? `${poultry.Lat}, ${poultry.Long}` + : item?.lat && item?.log + ? `${item.lat}, ${item.log}` + : "---", + "شماره تماس بهره بردار": poultry?.user?.mobile || "---", + "ظرفیت اسمی واحدها": poultry?.totalCapacity + ? `${poultry.totalCapacity.toLocaleString()}` + : "---", + + "تاریخ جوجه ریزی": formatDateTime(hatching?.date), + "تاریخ بازدید": formatDateTime(item?.date), + "تعداد جوجه ریزی اولیه": hatching?.quantity + ? `${hatching.quantity.toLocaleString()}` + : "---", + "تعداد جوجه ریزی توسط دامپزشکی": hatching?.quantity + ? `${hatching.quantity.toLocaleString()}` + : "---", + "تعداد جوجه طبق خود اظهاری مرغدار": hatching?.quantity + ? `${hatching.quantity.toLocaleString()}` + : "---", + "منبع تهیه جوجه": reportInfo?.casualties?.sourceOfHatching || "---", + "سن جوجه در زمان بازدید": hatching?.chickenAge + ? `${hatching.chickenAge} روز` + : hatching?.nowAge + ? `${hatching.nowAge} روز` + : "---", + "نوع نژاد": hatching?.chickenBreed || "---", + }; + + const generalCondition = reportInfo?.generalConditionHall || {}; + const casualties = reportInfo?.casualties || {}; + const technicalOfficer = reportInfo?.technicalOfficer || {}; + + const healthMonitoringData = { + "وضعیت بهداشتی سالن": generalCondition?.healthStatus || "---", + "وضعیت تهویه": generalCondition?.ventilationStatus || "---", + "وضعیت بستر": generalCondition?.bedCondition || "---", + "دما و رطوبت سالن با توجه به سن جوجه": generalCondition?.temperature + ? `${generalCondition.temperature} درجه` + : "---", + "کیفیت آب مصرفی": generalCondition?.drinkingWaterQuality || "---", + "منبع آب مصرفی": generalCondition?.drinkingWaterSource || "---", + "تعداد تلفات عادی دوره": casualties?.normalLosses + ? `${casualties.normalLosses}` + : "---", + "تلفات غیر عادی": casualties?.abnormalLosses + ? `${casualties.abnormalLosses}` + : "---", + "علت تلفات غیر عادی": casualties?.causeAbnormalLosses || "---", + "نوع بیماری تشخیصی": casualties?.typeDisease || "---", + "نمونه برداری انجام شده": casualties?.samplingDone ? "بله" : "خیر", + "نوع نمونه": casualties?.typeSampling || "---", + "نام مسئول فنی بهداشتی": technicalOfficer?.technicalHealthOfficer || "---", + "نام مسئول فنی نظام مهندسی": + technicalOfficer?.technicalEngineeringOfficer || "---", + }; + + const inputStatus = reportInfo?.inputStatus || {}; + const infrastructureEnergy = reportInfo?.infrastructureEnergy || {}; + const facilities = reportInfo?.facilities || {}; + const hr = reportInfo?.hr || {}; + + const infrastructureData = { + "وضعیت نهاده": inputStatus?.inputStatus || "---", + "نوع دان": inputStatus?.typeOfGrain || "---", + "کیفیت دانه": inputStatus?.gradeGrain || "---", + "موجودی تا روز بازدید": inputStatus?.inventoryUntilVisit || "---", + "موجودی در انبار": inputStatus?.inventoryInWarehouse || "---", + "کد رهگیری": inputStatus?.trackingCode || "---", + "نام شرکت": inputStatus?.companyName || "---", + "نوع ژنراتور": infrastructureEnergy?.generatorType || "---", + "مدل ژنراتور": infrastructureEnergy?.generatorModel || "---", + "تعداد ژنراتور": infrastructureEnergy?.generatorCount || "---", + "نوع سوخت": infrastructureEnergy?.fuelType || "---", + "ظرفیت ژنراتور": infrastructureEnergy?.generatorCapacity + ? `${infrastructureEnergy.generatorCapacity.toLocaleString()}` + : "---", + "میزان موجودی سوخت اضطراری (لیتر)": + infrastructureEnergy?.emergencyFuelInventory + ? `${infrastructureEnergy.emergencyFuelInventory.toLocaleString()}` + : "---", + "سابقه قطعی برق دوره جاری": infrastructureEnergy?.hasPowerCutHistory + ? "بله" + : "خیر", + "مدت زمان قطعی": infrastructureEnergy?.powerCutDuration + ? `${infrastructureEnergy.powerCutDuration} ساعت` + : "---", + "ساعت قطعی": infrastructureEnergy?.powerCutHour || "---", + "عملکرد ژنراتور": infrastructureEnergy?.generatorPerformance || "---", + "توضیحات تکمیلی": infrastructureEnergy?.additionalNotes || "---", + "تعداد افراد شاغل": hr?.numberEmployed ? `${hr.numberEmployed}` : "---", + "تعداد افراد بومی": hr?.numberIndigenous ? `${hr.numberIndigenous}` : "---", + "تعداد افراد غیر بومی": hr?.numberNonIndigenous + ? `${hr.numberNonIndigenous}` + : "---", + "وضعیت قرارداد کارگران": hr?.contractStatus || "---", + "آموزش دیده در حوزه بهداشت و امنیت زیستی": hr?.trained ? "بله" : "خیر", + "تسهیلات دریافتی فعال": facilities?.hasFacilities ? "بله" : "خیر", + "نوع تسهیلات": facilities?.typeOfFacility || "---", + "مبلغ تسهیلات": facilities?.amount + ? `${facilities.amount.toLocaleString()}` + : "---", + "وضعیت بازپرداخت": facilities?.repaymentStatus || "---", + "درخواست جدید بهره بردار": facilities?.requestFacilities || "---", + "تاریخ تسهیلات": formatDate(facilities?.date), + }; + + const renderInformationTab = () => ( + + {Object.entries(informationData).map(([label, value]) => ( + + + + {value || "---"} + + + + ))} + + ); + + const renderHealthMonitoringTab = () => ( + + {Object.entries(healthMonitoringData).map(([label, value]) => ( + + + + {value || "---"} + + + + ))} + + ); + + const renderInfrastructureTab = () => ( + + {Object.entries(infrastructureData).map(([label, value]) => ( + + + + {value || "---"} + + + + ))} + + ); + + const ImageThumbnail = ({ src, onClick }) => { + const isVideo = src?.toLowerCase().match(/\.(mp4|webm|ogg|mov)$/i); + + return ( + onClick && onClick(src)} + sx={{ + position: "relative", + width: "70px", + height: "70px", + borderRadius: 1.5, + overflow: "hidden", + border: "1px solid #e0e0e0", + cursor: "pointer", + "&:hover": { + opacity: 0.8, + }, + }} + > + {isVideo ? ( + + ) : ( + + )} + + ); + }; + + const ImageGallerySection = ({ title, description, images = [] }) => ( + + + {title} + + {description && ( + + {description} + + )} + {images && images.length > 0 ? ( + + {images.map((imageUrl, index) => ( + + ))} + + ) : ( + + تصویری موجود نیست + + )} + + ); + + const renderDocumentsTab = () => { + const generalConditionImages = generalCondition?.images || []; + const inputStatusImages = inputStatus?.images || []; + const casualtiesImages = casualties?.images || []; + const violationImages = hatching?.violationImage || []; + + return ( + + + + + + + + + + + handleStatusTabChange(newValue)} + sx={{ + "& .MuiTabs-indicator": { + display: "none", + }, + "& .MuiTab-root": { + minHeight: "auto", + px: 3, + py: 1, + borderRadius: 2, + fontWeight: "bold", + textTransform: "none", + "&.Mui-selected": { + bgcolor: "#4caf50", + color: "white", + }, + "&:not(.Mui-selected)": { + bgcolor: "#f5f5f5", + color: "text.primary", + }, + }, + }} + > + + + + + + + {reportInfo?.inspectionNotes || "---"} + + + + + + احراز مسئول سالن + + + + + + {hatching?.vetFarm?.vetFarmFullName ? "بله" : "خیر"} + + + + + + + {hatching?.vetFarm?.vetFarmFullName || "---"} + + + + + + + {hatching?.vetFarm?.vetFarmMobile || "---"} + + + + + + ); + }; + + return ( + + + + اطلاعات + + + + + + + {renderInformationTab()} + + + پایش سلامت + + + {renderHealthMonitoringTab()} + + + زیرساخت + + + {renderInfrastructureTab()} + + + مستندات + + + {renderDocumentsTab()} + + {fullscreenMedia && ( + + { + e.stopPropagation(); + handleCloseFullscreen(); + }} + sx={{ + position: "absolute", + top: 16, + right: 16, + backgroundColor: "rgba(255, 255, 255, 0.2)", + color: "white", + "&:hover": { + backgroundColor: "rgba(255, 255, 255, 0.3)", + }, + zIndex: 10000, + }} + > + + + e.stopPropagation()} + sx={{ + maxWidth: "90vw", + maxHeight: "90vh", + display: "flex", + alignItems: "center", + justifyContent: "center", + }} + > + {fullscreenMedia?.toLowerCase().match(/\.(mp4|webm|ogg|mov)$/i) ? ( + + ) : ( + + )} + + + )} + + ); +}; diff --git a/src/components/label-field/LabelField.js b/src/components/label-field/LabelField.js new file mode 100644 index 0000000..368d18a --- /dev/null +++ b/src/components/label-field/LabelField.js @@ -0,0 +1,43 @@ +import { Box, Grid, Typography } from "@mui/material"; +import { SPACING } from "../../data/spacing"; + +export const LabelField = ({ label, children }) => { + return ( + + + {label && ( + + {label} + + )} + {children} + + + ); +}; diff --git a/src/components/line-with-text/LineWithText.js b/src/components/line-with-text/LineWithText.js new file mode 100644 index 0000000..76bae63 --- /dev/null +++ b/src/components/line-with-text/LineWithText.js @@ -0,0 +1,47 @@ +import { Divider, Typography } from "@mui/material"; +import React from "react"; + +export const LineWithText = ({ text }) => { + return ( +
    + + + {text} + + +
    + ); +}; diff --git a/src/components/link-item/LinkItem.js b/src/components/link-item/LinkItem.js new file mode 100644 index 0000000..c474cc6 --- /dev/null +++ b/src/components/link-item/LinkItem.js @@ -0,0 +1,79 @@ +import React, { useEffect } from "react"; +import { Typography, Box, Badge, useTheme } from "@mui/material"; +import { styled } from "@mui/system"; +import { Grid } from "../grid/Grid"; +import { motion } from "framer-motion"; +import { useDispatch } from "react-redux"; +import { + SET_MEDIATOR_TEXT, + SET_SUBMENU_TEXT, +} from "../../lib/redux/slices/userSlice"; +import { useLocation } from "react-router-dom"; + +const CircleWrapper = styled(motion.div)(({ theme }) => ({ + display: "flex", + alignItems: "center", + justifyContent: "center", + flexDirection: "column", + gap: "10px", + width: window.innerWidth <= 600 ? "40vw" : "180px", + height: window.innerWidth <= 600 ? "40vw" : "180px", + borderRadius: "16px", + background: theme.palette.mode === "dark" ? "#1e272e" : "#ffffff", + borderStyle: "solid", + borderWidth: "1px", + borderColor: theme.palette.primary.main, + boxShadow: + theme.palette.mode === "dark" + ? "5px 5px 15px rgba(0, 0, 0, 0.5)" + : "5px 5px 15px rgba(0, 0, 0, 0.1)", + transition: "transform 0.2s ease, background 0.4s ease", + "&:hover": { + transform: "translateY(-10px)", + background: theme.palette.mode === "dark" ? "#2f3640" : "#f5f6fa", + }, + padding: 2, +})); + +const LinkItem = ({ icon, title, badgeContent, ...props }) => { + const theme = useTheme(); + const dispatch = useDispatch(); + + const { pathname } = useLocation(); + + useEffect(() => { + dispatch(SET_MEDIATOR_TEXT(pathname)); + }, [dispatch]); + + return ( + { + dispatch(SET_SUBMENU_TEXT(title)); + }} + > + + + {icon} + + + {title} + + + + ); +}; + +export default LinkItem; diff --git a/src/components/loading/Loading.js b/src/components/loading/Loading.js new file mode 100644 index 0000000..859d93a --- /dev/null +++ b/src/components/loading/Loading.js @@ -0,0 +1,44 @@ +import { Backdrop, Typography, styled } from "@mui/material"; +import { useEffect } from "react"; +import { useDispatch, useSelector } from "react-redux"; +import { LOADING_END } from "../../lib/redux/slices/appSlice"; +import { Grid } from "../grid/Grid"; +import loading from "../../assets/lottie/loading.json"; +import Lottie from "lottie-react"; + +const LoadingText = styled(Typography)(({ theme }) => ({ + color: "#fdfdff", + fontSize: "1.2rem", + fontWeight: 600, + textShadow: "0 0 8px rgba(255, 255, 255, 0.7)", +})); + +export const Loading = () => { + const dispatch = useDispatch(); + const loadingState = useSelector((state) => state.appSlice.loading); + + useEffect(() => { + dispatch(LOADING_END()); + }, []); + + return ( + theme.zIndex.drawer + 999999 }} + open={loadingState} + > + + + + + + لطفاً صبر کنید + + + + ); +}; diff --git a/src/components/modal/Modal.js b/src/components/modal/Modal.js new file mode 100644 index 0000000..be408cb --- /dev/null +++ b/src/components/modal/Modal.js @@ -0,0 +1,126 @@ +import * as React from "react"; +import Box from "@mui/material/Box"; +import ModalBox from "@mui/material/Modal"; +import { useDispatch, useSelector } from "react-redux"; +import { CLOSE_MODAL } from "../../lib/redux/slices/appSlice"; +import { Typography } from "@mui/material"; +import { SPACING } from "../../data/spacing"; +import CancelIcon from "@mui/icons-material/Cancel"; +const isMobile = window.innerWidth <= 600; + +export const Modal = () => { + const { modalState, modalContent, modalTitle, modalOnClose, modalSize } = + useSelector((state) => state.appSlice.modal); + + const size = modalSize || 500; + const style = { + position: "absolute", + top: "50%", + left: "50%", + transform: "translate(-50%, -50%)", + width: isMobile ? "90%" : size, + bgcolor: "background.paper", + // border: "2px solid #000", + boxShadow: 24, + display: "flex", + alignItems: "center", + justifyContent: "center", + flexDirection: "column", + gap: SPACING.SMALL, + borderRadius: 2, + p: 2, + }; + + const dispatch = useDispatch(); + + React.useEffect(() => { + dispatch(CLOSE_MODAL()); + }, []); + + const handleClose = () => { + dispatch(CLOSE_MODAL()); + if (modalOnClose) { + modalOnClose(); + } + }; + + const successModal = ( + + + theme.palette.success.main, + }} + > + عملیات با موفقیت انجام شد! + + + ); + const errorModal = ( + + + theme.palette.error.main, + }} + > + مشکلی پیش آمده است! + + + ); + + return ( + + + {modalTitle === "success" && successModal} + {modalTitle === "error" && errorModal} + {modalTitle !== "success" && modalTitle !== "error" && ( + <> + + + + {modalTitle} + + + {modalContent} + + )} + + + ); +}; diff --git a/src/components/modern-table/ModernTable.js b/src/components/modern-table/ModernTable.js new file mode 100644 index 0000000..aa6dfea --- /dev/null +++ b/src/components/modern-table/ModernTable.js @@ -0,0 +1,43 @@ +import React from "react"; +import PropTypes from "prop-types"; +import { + Table, + TableBody, + TableCell, + TableContainer, + TableHead, + TableRow, + Paper, +} from "@mui/material"; + +const ModernTable = ({ columns, data }) => { + return ( + + + + + {columns.map((column, index) => ( + {column} + ))} + + + + {data.map((row, rowIndex) => ( + + {row.map((cell, cellIndex) => ( + {cell} + ))} + + ))} + +
    +
    + ); +}; + +ModernTable.propTypes = { + columns: PropTypes.arrayOf(PropTypes.string).isRequired, + data: PropTypes.arrayOf(PropTypes.arrayOf(PropTypes.string)).isRequired, +}; + +export default ModernTable; diff --git a/src/components/mui-table/MuiTable.js b/src/components/mui-table/MuiTable.js new file mode 100644 index 0000000..c70dac5 --- /dev/null +++ b/src/components/mui-table/MuiTable.js @@ -0,0 +1,117 @@ +import { + Table, + TableBody, + TableCell, + TableContainer, + TableHead, + TableRow, +} from "@mui/material"; +import { Grid } from "../grid/Grid"; + +function createData(name, calories, fat, carbs, protein) { + return { + name, + calories, + fat, + carbs, + protein, + name2: name, + calories2: calories, + fat2: fat, + carbs2: carbs, + protein2: protein, + }; +} + +const rows = [ + createData("Frozen yoghurt", 159, 6.0, 24, 4.0), + // createData("Ice cream sandwich", 237, 9.0, 37, 4.3), + // createData("Eclair", 262, 16.0, 24, 6.0), + // createData("Cupcake", 305, 3.7, 67, 4.3), + // createData("Gingerbread", 356, 16.0, 49, 3.9), +]; + +export const MuiTable = ({ data }) => { + return ( + <> + + + + + + Dessert (100g serving) + Calories + Fat (g) + Carbs (g) + Protein (g) + Calories + Fat (g) + Carbs (g) + Protein (g) + Protein (g) + + + + {rows?.map((row) => ( + + {row.name} + {row.calories} + {row.fat} + {row.carbs} + {row.protein} + {row.name2} + {row.calories2} + {row.fat2} + {row.carbs2} + {row.protein2} + + ))} + +
    +
    +
    + + + + + + Dessert (100g serving) + Calories + Fat (g) + Carbs (g) + Protein (g) + Calories + Fat (g) + Carbs (g) + Protein (g) + Protein (g) + + + + {rows?.map((row) => ( + + {row.name} + {row.calories} + {row.fat} + {row.carbs} + {row.protein} + {row.name2} + {row.calories2} + {row.fat2} + {row.carbs2} + {row.protein2} + + ))} + +
    +
    +
    + + ); +}; diff --git a/src/components/my-table/MyTable.js b/src/components/my-table/MyTable.js new file mode 100644 index 0000000..1fd8843 --- /dev/null +++ b/src/components/my-table/MyTable.js @@ -0,0 +1,42 @@ +import { + Paper, + Table, + TableBody, + TableCell, + TableContainer, + TableHead, + TableRow, +} from "@mui/material"; +import React from "react"; + +const MyTable = ({ children }) => { + return ( + + + + + خریدار + اطلاعات خریدار + میانگین وزن 4 کشتار قبلی + {/* اولویت وزن + اولویت شهر + بدهی قبلی + مبلغ پیش فاکتور اولیه + پرداخت اولیه */} + کل سهمیه خریدار + مانده از سهمیه + تعداد تخصیص به کل سفارشات + قابل تخصیص + اقدام + + + {children} +
    +
    + ); +}; + +export default MyTable; diff --git a/src/components/nav-link/NavLink.js b/src/components/nav-link/NavLink.js new file mode 100644 index 0000000..49ba67a --- /dev/null +++ b/src/components/nav-link/NavLink.js @@ -0,0 +1,10 @@ +import styled from "@emotion/styled"; +import { Link } from "react-router-dom"; + +export const NavLink = styled(Link)` + text-decoration: none !important; + color: ${(props) => + props.active + ? props.theme.palette.primary.main + : props.theme.palette.grey.A400}; +`; diff --git a/src/components/notif/Notif.js b/src/components/notif/Notif.js new file mode 100644 index 0000000..e5ff3f2 --- /dev/null +++ b/src/components/notif/Notif.js @@ -0,0 +1,44 @@ +import { Snackbar } from "@mui/material"; +import React, { useContext } from "react"; +import { AppContext } from "../../contexts/AppContext"; +import MuiAlert from "@mui/material/Alert"; + +export const Notif = () => { + const Alert = React.forwardRef(function Alert(props, ref) { + return ; + }); + const [handleNotif, notifState] = useContext(AppContext); + + const { vertical, horizontal, open, severity, msg } = notifState; + + // const handleClick = (newState) => () => { + // setNotifState({ open: true, ...newState }); + // }; + + // HOW TO USE IT? + // const [openNotif] = useContext(AppContext); + // openNotif({ + // vertical: "top", + // horizontal: "center", + // msg: "سلام تست", + // severity: "error", + // }); + + const handleClose = () => { + handleNotif({ ...notifState, open: false }); + }; + + return ( + + + {msg} + + + ); +}; diff --git a/src/components/number-format-custom/NumberFormatCustom.js b/src/components/number-format-custom/NumberFormatCustom.js new file mode 100644 index 0000000..1bdc97f --- /dev/null +++ b/src/components/number-format-custom/NumberFormatCustom.js @@ -0,0 +1,40 @@ +import React from "react"; +import PropTypes from "prop-types"; +import { NumberFormatBase, useNumericFormat } from "react-number-format"; +import { TextField } from "@mui/material"; + +export const NumberInput = (props) => { + const { format, removeFormatting, ...rest } = useNumericFormat(props); + const _format = (val) => { + const _val = format(val); + return _val; + }; + + delete rest.onChange; + + const _removeFormatting = (val) => { + const _val = val.toLowerCase().replace(/[ ,]/g, ""); + return removeFormatting(_val); + }; + return ( + { + props.onChange({ + target: { + name: props.id, + value: values.floatValue, + }, + }); + }} + /> + ); +}; + +NumberInput.propTypes = { + id: PropTypes.any.isRequired, + onChange: PropTypes.func.isRequired, +}; diff --git a/src/components/page-table-api/PageTableApi.js b/src/components/page-table-api/PageTableApi.js new file mode 100644 index 0000000..882c9c4 --- /dev/null +++ b/src/components/page-table-api/PageTableApi.js @@ -0,0 +1,5 @@ +import { Grid } from "../grid/Grid"; + +export const PageTableApi = (props) => { + return ; +}; diff --git a/src/components/page-table/PageTable.js b/src/components/page-table/PageTable.js new file mode 100644 index 0000000..ed4b986 --- /dev/null +++ b/src/components/page-table/PageTable.js @@ -0,0 +1,131 @@ +import { CircularProgress, Typography } from "@mui/material"; +import { useEffect, useState } from "react"; +import DataTable from "react-data-table-component"; +import { Grid } from "../grid/Grid"; + +const customStyles = { + rows: { + style: { + minHeight: "72px", // override the row height + }, + }, + headCells: { + style: { + paddingLeft: "0px", // override the cell padding for head cells + paddingRight: "0px", + backgroundColor: "#ddd", + }, + }, + cells: { + style: { + paddingLeft: "0px", // override the cell padding for data cells + paddingRight: "0px", + }, + }, +}; + +export const PageTable = (props) => { + const titleJsx = props.title; + + useEffect(() => { + if (!props.progressPending) { + const spanElement = document.querySelector(".rdt_Pagination span"); + + const pagination = document.querySelector(".rdt_Pagination"); + const lastSpan = + pagination?.querySelectorAll("span")[ + pagination?.querySelectorAll("span").length - 1 + ]; + + if (lastSpan) { + lastSpan.textContent = lastSpan.textContent.replace("of", "از"); + spanElement.textContent = "سطر در صفحه:"; + } + } + }, [props.progressPending]); + + const [zoomLevel, setZoomLevel] = useState(window.devicePixelRatio); + + const handleZoomChange = () => { + const newZoomLevel = window.devicePixelRatio; + setZoomLevel(newZoomLevel); + }; + + useEffect(() => { + window.addEventListener("resize", handleZoomChange); + return () => { + window.removeEventListener("resize", handleZoomChange); + }; + }, [zoomLevel]); + + useEffect(() => { + const divElements = document.querySelectorAll(".rdt_Table"); + + // Text to search for and replace + const searchText = "There are no records to display"; + const replacementText = "داده ای جهت نمایش وجود ندارد"; + divElements?.forEach((div) => { + // Get the text content of the div + const content = div?.textContent; + if (content.includes(searchText)) { + // Replace the search text with replacement text + // const updatedContent = content.replace( + // new RegExp(searchText, "g"), + // replacementText + // ); + + // // Update the content of the div + div.textContent = replacementText; + } + }); + }, []); + + const isMobile = window.innerWidth <= 600; + + return ( + + + {titleJsx} + + {Boolean(props?.data?.length) && ( + = 1 + ? window.screen.width - 200 + : window.screen.width * (10 / (zoomLevel * 10)) - 250 + } + > + + + )} + {!props?.data?.length && !props.progressPending && ( + + داده ای جهت نمایش وجود ندارد! + + )} + {props.progressPending && ( + + )} + + ); +}; diff --git a/src/components/requests-awaiting-inspections/RequestsAwaitingInspections.js b/src/components/requests-awaiting-inspections/RequestsAwaitingInspections.js new file mode 100644 index 0000000..cde839a --- /dev/null +++ b/src/components/requests-awaiting-inspections/RequestsAwaitingInspections.js @@ -0,0 +1,82 @@ +import { Card, IconButton } from "@mui/material"; +import { useEffect, useState } from "react"; +import { useNavigate } from "react-router-dom"; +import { AdvancedTable } from "../advanced-table/AdvancedTable"; +import PlagiarismIcon from "@mui/icons-material/Plagiarism"; +import { getRoleFromUrl } from "../../utils/getRoleFromUrl"; +import { useDispatch, useSelector } from "react-redux"; +import { getRequestsAwaitingInspection } from "./service"; +import { format } from "date-fns-jalali"; + +export const RequestsAwaitingInspections = () => { + const { awaitingInspectionRequests } = useSelector( + (state) => state.generalSlice + ); + + const navigate = useNavigate(); + const [dataTable, setDataTable] = useState([]); + const urlRole = window.location.pathname.split("/")[1]; + + const dispatch = useDispatch(); + + const role = getRoleFromUrl(); + + useEffect(() => { + dispatch(getRequestsAwaitingInspection(role + "&inspector")); + }, []); + + useEffect(() => { + const fileUrl = "/" + urlRole + "/file/"; + + const d = awaitingInspectionRequests?.map((item, i) => { + return [ + i + 1, + item.orderCode, + format(new Date(item.createDate), "yyyy/MM/dd"), + format(new Date(item.sendDate), "yyyy/MM/dd"), + item?.process?.poultry?.poultryName, + item?.process?.poultry?.poultryMobile, + item?.process?.poultry?.poultryCity, + item?.process?.poultry?.poultryProvince, + item?.process?.poultry?.age, + item?.process?.poultry?.poultryQuantity, + + navigate(fileUrl + item?.process?.poultry?.poultryRequestId) + } + > + + , + ]; + }); + + setDataTable(d); + }, [awaitingInspectionRequests]); + + const [tableDataCol] = useState([ + "ردیف", + "کد سفارش", + "تاریخ ثبت درخواست", + "تاریخ درخواست", + "مرغدار", + "تلفن مرغدار", + "شهر", + "استان", + "سن مرغ", + "تعداد", + "مشاهده", + ]); + return ( + + + + ); +}; diff --git a/src/components/requests-awaiting-inspections/service.js b/src/components/requests-awaiting-inspections/service.js new file mode 100644 index 0000000..52cbdb2 --- /dev/null +++ b/src/components/requests-awaiting-inspections/service.js @@ -0,0 +1,10 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; + +export const getRequestsAwaitingInspection = createAsyncThunk( + "GET_REQUESTS_AWAITING_INSPECTION", + async (d) => { + const { data, status } = await axios.get("Poultry_Request/?role=" + d); + return { data, status }; + } +); diff --git a/src/components/requests-awaiting-payment/RequestsAwaitingPayment.js b/src/components/requests-awaiting-payment/RequestsAwaitingPayment.js new file mode 100644 index 0000000..6978fbb --- /dev/null +++ b/src/components/requests-awaiting-payment/RequestsAwaitingPayment.js @@ -0,0 +1,126 @@ +import { Card, IconButton, TextField, Typography } from "@mui/material"; +import { useContext, useEffect, useState } from "react"; +import { useNavigate } from "react-router-dom"; +import { AdvancedTable } from "../advanced-table/AdvancedTable"; +import PlagiarismIcon from "@mui/icons-material/Plagiarism"; +import { useDispatch, useSelector } from "react-redux"; +import { getRequestsAwaitingPayment } from "./service"; +import { format } from "date-fns-jalali"; +import { SPACING } from "../../data/spacing"; +import { DatePicker } from "@mui/x-date-pickers"; +import moment from "moment/moment"; +import { AppContext } from "../../contexts/AppContext"; +import { Grid } from "../grid/Grid"; + +export const RequestsAwaitingPayment = () => { + const { awaitingPaymentRequests } = useSelector( + (state) => state.generalSlice + ); + + const navigate = useNavigate(); + const [dataTable, setDataTable] = useState([]); + const urlRole = window.location.pathname.split("/")[1]; + + const [, , selectedDate1, setSelectedDate1, selectedDate2, setSelectedDate2] = + useContext(AppContext); + + useEffect(() => { + const currentDate = moment(new Date()).format("YYYY-MM-DD"); + setSelectedDate1(currentDate); + setSelectedDate2(currentDate); + }, []); + + const dispatch = useDispatch(); + + useEffect(() => { + dispatch(getRequestsAwaitingPayment({ selectedDate1, selectedDate2 })); + }, [selectedDate1, selectedDate2]); + + useEffect(() => { + const fileUrl = "/" + urlRole + "/file/"; + + const d = awaitingPaymentRequests?.map((item, i) => { + return [ + i + 1, + item.provinceCheckInfo?.killHouseAssignment?.killHouseRequest?.barCode, + format(new Date(item?.poultryRequest?.sendDate), "yyyy/MM/dd"), + format(new Date(item?.factorDate), "yyyy/MM/dd"), + item?.poultryRequest?.poultryName, + item.provinceCheckInfo?.killHouseAssignment?.killHouseRequest + ?.killRequest?.killHouse.name, + item.provinceCheckInfo.killHouseAssignment.netWeight.toLocaleString() + + " کیلوگرم", + item.provinceCheckInfo?.killHouseAssignment?.realQuantity.toLocaleString() + + " قطعه", + item.totalPrice.toLocaleString() + " ﷼", + + navigate(fileUrl + item?.poultryRequest?.poultryRequestId) + } + > + + , + ]; + }); + + setDataTable(d); + }, [awaitingPaymentRequests]); + + return ( + + + + درخواست های در انتظار پرداخت + + + + ( + + )} + value={selectedDate1} + onChange={(e) => { + setSelectedDate1(moment(e).format("YYYY-MM-DD")); + }} + /> + + + ( + + )} + value={selectedDate2} + onChange={(e) => { + setSelectedDate2(moment(e).format("YYYY-MM-DD")); + }} + /> + + + + } + columns={[ + "ردیف", + "بارکد", + "تاریخ کشتار", + "تاریخ صدور فاکتور", + "مرغدار", + "کشتارگاه", + "وزن", + "تعداد", + "مبلغ کل فاکتور", + "مشاهده", + ]} + data={dataTable} + /> + + ); +}; diff --git a/src/components/requests-awaiting-payment/service.js b/src/components/requests-awaiting-payment/service.js new file mode 100644 index 0000000..ac349ea --- /dev/null +++ b/src/components/requests-awaiting-payment/service.js @@ -0,0 +1,16 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../lib/redux/slices/appSlice"; +import { getRoleFromUrl } from "../../utils/getRoleFromUrl"; + +export const getRequestsAwaitingPayment = createAsyncThunk( + "GET_REQUESTS_AWAITING_PAYMENT", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + const { data, status } = await axios.get("province_factor_to_kill_house/", { + params: { role: getRoleFromUrl() }, + }); + dispatch(LOADING_END()); + return { data, status }; + } +); diff --git a/src/components/responsive-table/BoxShowTable.js b/src/components/responsive-table/BoxShowTable.js new file mode 100644 index 0000000..bbc3f38 --- /dev/null +++ b/src/components/responsive-table/BoxShowTable.js @@ -0,0 +1,258 @@ +import React, { useState } from "react"; +import PropTypes from "prop-types"; +import Box from "@mui/material/Box"; +import Typography from "@mui/material/Typography"; +import IconButton from "@mui/material/IconButton"; +import ExpandMoreIcon from "@mui/icons-material/ExpandMore"; +import { Grid } from "../grid/Grid"; + +const BoxShowTable = ({ + columns, + data, + isDashboard, + allColors, + customColors, +}) => { + const [expandedRows, setExpandedRows] = useState([]); + + const getColumnColor = (column) => { + if (allColors) { + return allColors.color; + } else { + const c = customColors?.find((item) => item.name === column?.name) + ? customColors?.find((item) => item.name === column?.name) + : customColors?.find((item) => item.rest === true); + if (c) { + return c.color; + } else { + if (isDashboard) { + return "#f4c3c3"; + } else if (customColors?.length) { + return "#f6e58d"; + } else { + return null; + } + } + } + }; + + const handleExpandClick = (rowIndex) => { + setExpandedRows((prev) => + prev.includes(rowIndex) + ? prev.filter((index) => index !== rowIndex) + : [...prev, rowIndex] + ); + }; + + function isPositiveNumber(str) { + const data = String(str); + const sanitizedStr = data?.replace(/,/g, ""); + const num = Number(sanitizedStr); + + if (!isNaN(num)) { + return num >= 0; + } else { + return true; + } + } + + const getTextColor = (column) => { + if (allColors?.text) return allColors.text; + const bgColor = getColumnColor(column); + + if (!bgColor) return "white"; + if ( + bgColor === "black" || + bgColor === "blue" || + bgColor === "red" || + bgColor === "brown" || + bgColor === "green" + ) { + return "white"; + } + return "black"; + }; + + return ( + + + {data?.map((row, rowIndex) => { + let visibleCellIndex = 0; + const isExpanded = expandedRows.includes(rowIndex); + + return ( + + + {row + .slice( + 0, + 8 + + columns.filter((item) => item?.visible === false)?.length + ) + .map( + (cell, cellIndex) => + columns[cellIndex]?.visible && ( + + + {`${columns[cellIndex]?.name}`} + + + + {!isPositiveNumber(cell) + ? String(cell).replace("-", "") + "-‌ ‌" + : cell} + + + ) + )} + {isExpanded && + row.slice(8)?.map( + (cell, cellIndex) => + columns[cellIndex + 8]?.visible && ( + + + {`${columns[cellIndex + 8]?.name}`} + + + + {!isPositiveNumber(cell) + ? String(cell).replace("-", "") + "-‌ ‌" + : cell} + + + ) + )} + {row.length > 8 && ( + handleExpandClick(rowIndex)}> + + + )} + + + ); + })} + + + ); +}; + +BoxShowTable.propTypes = { + columns: PropTypes.any, + data: PropTypes.any, + ignore: PropTypes.array, +}; + +export default BoxShowTable; diff --git a/src/components/responsive-table/ResponsiveTable.js b/src/components/responsive-table/ResponsiveTable.js new file mode 100644 index 0000000..98fef92 --- /dev/null +++ b/src/components/responsive-table/ResponsiveTable.js @@ -0,0 +1,762 @@ +import React, { useState, useEffect } from "react"; +import PropTypes from "prop-types"; +import { + Typography, + Table, + TableBody, + TableCell, + TableContainer, + TableHead, + TableRow, + Paper, + Grid, + Checkbox, + FormControlLabel, + IconButton, + Popover, + Divider, + Button, + Pagination, + FormControl, + InputLabel, + Select, + MenuItem, + TextField, + Tooltip, +} from "@mui/material"; +import TableViewIcon from "@mui/icons-material/TableView"; +import FilterAltIcon from "@mui/icons-material/FilterAlt"; +import styled from "styled-components"; +import Lottie from "lottie-react"; +import EmptyAnimation from "../../assets/lottie/Empty.json"; +import FilterAltOffIcon from "@mui/icons-material/FilterAltOff"; +import GridViewIcon from "@mui/icons-material/GridView"; +import AdsClickIcon from "@mui/icons-material/AdsClick"; +import BoxShowTable from "./BoxShowTable"; +import Zoom from "@mui/material/Zoom"; +import { motion } from "framer-motion"; + +const ResponsiveTable = ({ + columns: initialColumns, + data, + title, + paginated = false, + handlePageChange, + handlePerRowsChange, + totalRows, + page, + perPage, + customColors, + noPagination, + changed, + isDashboard, + noSearch, + operation, + allColors, + activeRows, + customWidth, + ignoreTextsLength, + CustomColumnsColor, + hasSum, + hasSumColumn, +}) => { + const pathname = window.location.pathname; + const storageKey = `${pathname}_${ + initialColumns.length + }_columnsVisibility${title}${initialColumns.join(" ")}`; + + const getInitialColumns = () => { + const savedColumns = localStorage.getItem(storageKey); + + if ( + savedColumns && + JSON.parse(savedColumns)?.length === initialColumns?.length && + !changed + ) { + return JSON.parse(savedColumns); + } + return initialColumns.map((col) => ({ name: col, visible: true })); + }; + + useEffect(() => { + setColumns(getInitialColumns()); + }, [initialColumns]); + + function isPositiveNumber(str) { + const data = String(str); + const sanitizedStr = data?.replace(/,/g, ""); + const num = Number(sanitizedStr); + + if (!isNaN(num)) { + return num >= 0; + } else { + return true; + } + } + + const [itemsPerPage, setItemsPerPage] = useState(10); + const [currentPage, setCurrentPage] = useState(1); + const [searchQuery, setSearchQuery] = useState(""); + const [searchPageIndex, setSearchPageIndex] = useState(null); + const [columns, setColumns] = useState(getInitialColumns()); + const [sortConfig, setSortConfig] = useState({ key: null, direction: "asc" }); + + useEffect(() => { + localStorage.setItem(storageKey, JSON.stringify(columns)); + }, [columns]); + + const handleSort = (columnIndex) => { + const newDirection = + sortConfig.key === columnIndex && sortConfig.direction === "asc" + ? "desc" + : "asc"; + setSortConfig({ key: columnIndex, direction: newDirection }); + }; + + const sortedData = [...(data || [])].sort((a, b) => { + if (sortConfig.key === null) return 0; + + const itemA = String(a[sortConfig.key]); + const itemB = String(b[sortConfig.key]); + + const isNumericA = !isNaN(itemA.replace(/,/g, "")); + const isNumericB = !isNaN(itemB.replace(/,/g, "")); + + if (isNumericA && isNumericB) { + const valueA = parseFloat(itemA.replace(/,/g, "")); + const valueB = parseFloat(itemB.replace(/,/g, "")); + return sortConfig.direction === "asc" ? valueA - valueB : valueB - valueA; + } + + if (typeof itemA === "string" && typeof itemB === "string") { + return sortConfig.direction === "asc" + ? itemA.localeCompare(itemB, "fa", { sensitivity: "base" }) + : itemB.localeCompare(itemA, "fa", { sensitivity: "base" }); + } + + if (isNumericA) return sortConfig.direction === "asc" ? -1 : 1; + if (isNumericB) return sortConfig.direction === "asc" ? 1 : -1; + + return 0; + }); + + const filteredData = sortedData.filter((row) => + row.some((cell) => + cell?.toString()?.toLowerCase()?.includes(searchQuery.toLowerCase()) + ) + ); + + useEffect(() => { + setCurrentPage(1); + }, [searchQuery]); + + const totalPages = Math.ceil(filteredData?.length / itemsPerPage); + + const startIndex = (currentPage - 1) * itemsPerPage; + const endIndex = startIndex + itemsPerPage; + + const slicedData = paginated + ? filteredData.slice(startIndex, endIndex) + : filteredData; + + const toggleColumnVisibility = (index) => { + const updatedColumns = [...columns]; + updatedColumns[index].visible = !updatedColumns[index].visible; + setColumns(updatedColumns); + }; + + const [anchorEl, setAnchorEl] = useState(null); + + const handleClick = (event) => { + setAnchorEl(event.currentTarget); + }; + + const handleClose = () => { + setAnchorEl(null); + }; + + const open = Boolean(anchorEl); + const id = open ? "simple-popover" : undefined; + + const [openS, setOpenS] = useState(false); + + const handleChange = (event) => { + setItemsPerPage(event.target.value, setCurrentPage(1)); + }; + + const handleCloseS = () => { + setOpenS(false); + }; + + const handleOpenS = () => { + setOpenS(true); + }; + const dotVariants = { + hidden: { opacity: 0 }, + visible: { opacity: 1 }, + }; + + const AnimatedEllipsis = () => { + return ( + + {[".", ".", "."].map((dot, index) => ( + + {dot} + + ))} + + ); + }; + + const tableTitle = ( + + + + {isDashboard ? ( + + ) : ( + + )} + + {title} + + + + + + + {operation} + {paginated && !noSearch && ( + + setSearchQuery(e.target.value)} + /> + + )} + + {!isDashboard && ( + item?.visible === false).length + ? "error" + : "primary" + } + > + {columns.filter((item) => item?.visible === false).length ? ( + + ) : ( + + )} + + )} + + + + + + + فیلتر ستون ها + + + + + {columns.map((column, index) => ( + + toggleColumnVisibility(index)} + /> + } + label={column.name} + /> + + ))} + + + + + + + ); + + const CustomTableCell = styled(TableCell)` + font-weight: bold; + background: ${({ bgColor }) => `${bgColor} !important`}; + color: ${({ bgColor, textColor }) => + `${ + textColor + ? textColor + : isDashboard + ? "white" + : allColors + ? allColors?.text + : bgColor === "black" || + bgColor === "blue" || + bgColor === "red" || + bgColor === "brown" || + bgColor === "green" + ? "white" + : "black" + } !important`}; + `; + + const getColumnColor = (column) => { + if (CustomColumnsColor) { + const c = CustomColumnsColor?.find((item) => + column?.name.includes(item.key) + ); + if (c) { + return c.color; + } + } + const c = customColors?.find((item) => item.name === column?.name) + ? customColors?.find((item) => item.name === column?.name) + : customColors?.find((item) => item.rest === true); + if (c) { + return c.color; + } else if (allColors) { + return allColors.color; + } else { + if (isDashboard) { + return "#c23616"; + } else if (customColors?.length) { + return "#f6e58d"; + } else { + return null; + } + } + }; + + const parseNumber = (value) => { + const dateRegex = /^\d{4}\/\d{2}\/\d{2}$/; + const isLargeNumber = + typeof value === "string" && value.replace(/,/g, "").length > 14; + + if (typeof value === "string" && (dateRegex.test(value) || isLargeNumber)) { + return 0; + } + + if (typeof value === "string") { + const parsed = parseFloat(value.replace(/,/g, "")); + return isNaN(parsed) ? 0 : parsed; + } + + return typeof value === "number" ? value : 0; + }; + const calculateColumnSum = (colIndex) => { + let hasNumericData = false; + const sum = slicedData.reduce((total, row) => { + const value = parseNumber(row[colIndex]); + if (value !== null) { + hasNumericData = true; + return total + value; + } + return total; + }, 0); + return hasNumericData ? sum : null; + }; + + const AnimatedTableRow = motion(TableRow); + + const rowAnimation = { + active: { + backgroundColor: hasSum + ? [ + "rgba(176, 84, 237, 0.8)", + "rgba(176, 84, 237, 0.6)", + "rgba(176, 84, 237, 0.8)", + ] + : [ + "rgb(234, 137, 130, 0.6)", + "rgb(234, 137, 130, 0.4)", + "rgb(234, 137, 130, 0.6)", + ], + transition: { + duration: 3, + repeat: Infinity, + ease: "easeInOut", + }, + }, + }; + + return ( + <> + {tableTitle} + + + + + + {columns + .filter((d) => d.visible) + .map((column, index) => { + const columnSum = calculateColumnSum(index); + return ( + + + column?.name.includes(item.key) + )?.text || null + } + onClick={() => handleSort(index)} + style={{ cursor: "pointer" }} + > + {column?.name} + {sortConfig.key === index && + !isDashboard && + (sortConfig.direction === "asc" ? " 🔻" : " 🔺")} + + + ); + })} + + + + {slicedData?.map((row, rowIndex) => ( + + {row?.map( + (cell, cellIndex) => + columns[cellIndex]?.visible && ( + + + + {!isPositiveNumber(cell) ? ( + String(cell).replace("-", "") + "-‌ ‌" + ) : typeof cell === "string" && + !ignoreTextsLength && + cell.length > 30 ? ( + + {cell.slice(0, 30) + " ... "} + + + ) : (cell?.toString() === "NaN" || !cell) && + cell !== 0 ? ( + "-" + ) : ( + cell + )} + + + + ) + )} + + ))} + {hasSum && ( + + {columns + .filter((d) => d.visible) + .map((column, index) => { + const columnSum = calculateColumnSum(index); + return ( + + + + {column?.name === "ردیف" + ? slicedData?.length + 1 + : column?.name === hasSumColumn + ? "مجموع" + : !isPositiveNumber(columnSum) + ? String(columnSum).replace("-", "") + "-‌ ‌" + : columnSum?.toLocaleString()} + + + + ); + })} + + )} + +
    +
    +
    + {!slicedData?.length && ( + + {!isDashboard && !noPagination && ( + + + + )} + + + {isDashboard ? ( + <> + در حال دریافت اطلاعات {"‌‌"} + + + ) : ( + "داده ای دریافت نشد!" + )} + + + + )} + + + + + {!noPagination && ( + + {paginated ? ( + + + + تعداد + + + + {itemsPerPage !== 1000 && ( + setCurrentPage(page)} + /> + )} + + ) : ( + + + + تعداد + + + + handlePageChange(page)} + /> + + setSearchPageIndex(e.target.value)} + onKeyDown={(e) => { + if ( + e.key === "Enter" && + parseInt(searchPageIndex) <= + Math.ceil(totalRows / perPage) && + parseInt(searchPageIndex) > 0 + ) { + handlePageChange(parseInt(searchPageIndex)); + } + }} + /> + + + )} + + )} + + ); +}; + +ResponsiveTable.propTypes = { + columns: PropTypes.arrayOf(PropTypes.string).isRequired, + data: PropTypes.arrayOf(PropTypes.arrayOf(PropTypes.any)).isRequired, + title: PropTypes.string.isRequired, + paginated: PropTypes.bool, +}; + +export default ResponsiveTable; diff --git a/src/components/select-check/SelectCheck.js b/src/components/select-check/SelectCheck.js new file mode 100644 index 0000000..c840218 --- /dev/null +++ b/src/components/select-check/SelectCheck.js @@ -0,0 +1,127 @@ +import * as React from "react"; +import OutlinedInput from "@mui/material/OutlinedInput"; +import InputLabel from "@mui/material/InputLabel"; +import MenuItem from "@mui/material/MenuItem"; +import FormControl from "@mui/material/FormControl"; +// import ListItemText from "@mui/material/ListItemText"; +import Select from "@mui/material/Select"; +// import Checkbox from "@mui/material/Checkbox"; +import { PropTypes } from "prop-types"; +import { ListItemText } from "@mui/material"; + +const ITEM_HEIGHT = 48; +const ITEM_PADDING_TOP = 8; +const MenuProps = { + PaperProps: { + style: { + maxHeight: ITEM_HEIGHT * 4.5 + ITEM_PADDING_TOP, + width: 280, + }, + }, +}; + +export const SelectCheck = ({ + label, + id, + options, + error, + onBlur, + onChange, + size, + value, + width, + defaultValue, +}) => { + defaultValue = defaultValue || []; + const [myValue, setMyValue] = React.useState(defaultValue); + width = width || 280; + // React.useEffect(() => { + // if (Array.isArray(value) && !myValue?.length) { + // setMyValue(value); + // } + // }, [value]); + + const handleChange = (event) => { + const { + target: { value }, + } = event; + setMyValue( + // On autofill we get a stringified value. + typeof value === "string" ? value.split(",") : value + ); + }; + + React.useEffect(() => { + onChange(myValue); + }, [myValue]); + + React.useEffect(() => { + if (defaultValue?.length) { + setMyValue(myValue); + } + }, [defaultValue]); + + const optionValues = options?.map((item) => item.value); + const optionLabels = options?.map((item) => item.label); + + return ( +
    + + {label} + + +
    + ); +}; + +SelectCheck.propTypes = { + label: PropTypes.string, + id: PropTypes.string, + options: PropTypes.array, + error: PropTypes.any, + onBlur: PropTypes.any, + onChange: PropTypes.any, + size: PropTypes.any, +}; diff --git a/src/components/show-image/ShowImage.js b/src/components/show-image/ShowImage.js new file mode 100644 index 0000000..95767ee --- /dev/null +++ b/src/components/show-image/ShowImage.js @@ -0,0 +1,196 @@ +import React, { useState } from "react"; +import { Box, IconButton, Modal, Tooltip, Button } from "@mui/material"; +import { motion } from "framer-motion"; +import DownloadIcon from "@mui/icons-material/Download"; +import CloseIcon from "@mui/icons-material/Close"; +import RotateRightIcon from "@mui/icons-material/RotateRight"; + +const imageExtensions = [ + ".jpg", + ".jpeg", + ".png", + ".gif", + ".bmp", + ".webp", + ".svg", +]; + +const ShowImage = ({ src, size }) => { + const [open, setOpen] = useState(false); + const [rotation, setRotation] = useState(0); + + const handleOpen = () => setOpen(true); + const handleClose = () => setOpen(false); + + const handleDownload = () => { + if (!src || typeof src !== "string") return; + try { + const link = document.createElement("a"); + link.href = src; + const filename = src.split("/").pop() || "document"; + link.download = filename; + link.click(); + } catch (error) { + console.error("Error downloading file:", error); + } + }; + + const handleRotate = () => { + setRotation((prevRotation) => prevRotation + 90); + }; + + const getFileExtension = () => { + if (!src || typeof src !== "string") return ""; + try { + const filename = src.split("/").pop(); + if (!filename || typeof filename !== "string") return ""; + const lastDotIndex = filename.lastIndexOf("."); + if (lastDotIndex === -1) return ""; + return filename.substring(lastDotIndex + 1).toLowerCase(); + } catch (error) { + console.error("Error getting file extension:", error); + return ""; + } + }; + + const isImage = () => { + if (!src || typeof src !== "string") return false; + const extension = getFileExtension(); + return imageExtensions.includes(`.${extension}`); + }; + + if (!src || typeof src !== "string") { + return "-"; + } + + if (!isImage()) { + const fileExtension = getFileExtension(); + const buttonText = fileExtension + ? `دانلود سند ${fileExtension}` + : "دانلود سند"; + + return ( + + ); + } + + return ( +
    + + + + + + + + + + + + + + + + + + + + + + + +
    + ); +}; + +export default ShowImage; diff --git a/src/components/simple-table/SimpleTable.js b/src/components/simple-table/SimpleTable.js new file mode 100644 index 0000000..232a515 --- /dev/null +++ b/src/components/simple-table/SimpleTable.js @@ -0,0 +1,147 @@ +import MUIDataTable from "mui-datatables"; +import { useEffect, useState } from "react"; +import { PropTypes } from "prop-types"; +import { Box } from "@mui/system"; +import { Tooltip } from "@mui/material"; +export const SimpleTable = ({ + columns, + data, + name, + responsive, + cssClass, + headerColor, + rowColors, +}) => { + const [rows, setRows] = useState(data); + + useEffect(() => { + setRows(data); + }, [data]); + + useEffect(() => { + const d = data?.map((item) => { + return item?.map((row) => { + if (!row && row !== 0) { + return ""; + } else { + return row; + } + }); + }); + setRows(d); + }, [data]); + const options = { + viewColumns: false, + search: false, + sort: false, + pagination: false, + filter: false, + print: false, + download: false, + selectableRowsHeader: false, + selectableRowsHideCheckboxes: true, + responsive: responsive || "vertical", + fixedHeader: true, + tableBodyMaxHeight: { xs: "auto", md: "70vh" }, + setRowProps: (row, dataIndex) => ({ + style: rowColors + ? { backgroundColor: rowColors[dataIndex % rowColors.length] } + : {}, + }), + + // localization + textLabels: { + body: { + noMatch: "داده ای جهت نمایش موجود نیست!", + toolTip: "مرتب سازی", + columnHeaderTooltip: (column) => `مرتب سازی بر اساس ${column.label}`, + }, + pagination: { + next: "صفحه بعد", + previous: "صفحه قبل", + rowsPerPage: "تعداد سطر در هر صفحه:", + displayRows: "تعداد کل نتایج: ", + }, + toolbar: { + search: "جستجو", + downloadCsv: "دانلود CSV", + print: "پرینت", + viewColumns: "نمایش سطون ها", + filterTable: "فیلتر جدول", + }, + filter: { + all: "همه", + title: "فیلترها", + reset: "پاکسازی", + }, + viewColumns: { + title: "نمایش ستون ها", + titleAria: "نمایش/بستن ستون های جدول", + }, + selectedRows: { + text: "سطر انتخاب شده است", + delete: "پاک کردن", + deleteAria: "پاک کردن سطرهای انتخاب شده", + }, + }, + }; + const columnsWithHeaderColor = columns.map((col, colIndex) => ({ + name: col, + options: { + customHeadRender: (columnMeta) => { + let sumValue = 0; + rows?.forEach((row) => { + let value = row[colIndex]; + if (typeof value === "string") { + const cleaned = value.replace(/,/g, ""); + value = parseFloat(cleaned); + } + if (!isNaN(value)) sumValue += value; + }); + + const tooltipTitle = + sumValue && !isNaN(sumValue) + ? `مجموع: ${sumValue.toLocaleString()}` + : ""; + + return ( + + + {columnMeta.name} + + + ); + }, + }, + })); + + return ( + + + + ); +}; + +SimpleTable.propTypes = { + columns: PropTypes.any, + data: PropTypes.any, + name: PropTypes.any, + expandable: PropTypes.bool, + responsive: PropTypes.any, + headerColor: PropTypes.string, + rowColors: PropTypes.string, +}; diff --git a/src/components/state-stepper/StateStepper.js b/src/components/state-stepper/StateStepper.js new file mode 100644 index 0000000..2c6c995 --- /dev/null +++ b/src/components/state-stepper/StateStepper.js @@ -0,0 +1,47 @@ +import { Grid } from "../grid/Grid"; +import TaskAltIcon from "@mui/icons-material/TaskAlt"; +import { PropTypes } from "prop-types"; +import MoreHorizIcon from "@mui/icons-material/MoreHoriz"; +import LockIcon from "@mui/icons-material/Lock"; + +export const StateStepper = ({ state, children }) => { + const completedJSX = ( + + + + + {children} + + ); + + const pendingJSX = ( + + + + + {children} + + ); + + const lockedJSX = ( + + + + + {children} + + ); + + return ( + <> + {state === "completed" && completedJSX} + {state === "pending" && pendingJSX} + {state === "locked" && lockedJSX} + + ); +}; + +StateStepper.propTypes = { + state: PropTypes.any, + children: PropTypes.any, +}; diff --git a/src/components/strict-modal/StrictModal.js b/src/components/strict-modal/StrictModal.js new file mode 100644 index 0000000..c9c44b5 --- /dev/null +++ b/src/components/strict-modal/StrictModal.js @@ -0,0 +1,59 @@ +import * as React from "react"; +import Box from "@mui/material/Box"; +import ModalBox from "@mui/material/Modal"; +import { Typography } from "@mui/material"; +import { SPACING } from "../../data/spacing"; +import { PropTypes } from "prop-types"; + +export const StrictModal = ({ content, title, open }) => { + const style = { + position: "absolute", + top: "50%", + left: "50%", + transform: "translate(-50%, -50%)", + width: 400, + bgcolor: "background.paper", + // border: "2px solid #000", + boxShadow: 24, + display: "flex", + alignItems: "center", + justifyContent: "center", + flexDirection: "column", + gap: SPACING.SMALL, + borderRadius: 2, + p: 3, + }; + + return ( + + + <> + + + {title} + + + {content} + + + + ); +}; + +StrictModal.propTypes = { + title: PropTypes.any, + content: PropTypes.any, + open: PropTypes.any, +}; diff --git a/src/components/text-input/TextInput.js b/src/components/text-input/TextInput.js new file mode 100644 index 0000000..edae763 --- /dev/null +++ b/src/components/text-input/TextInput.js @@ -0,0 +1,17 @@ +import { TextField } from "@mui/material"; +import { PropTypes } from "prop-types"; + +export const TextInput = (props) => { + return ( + + ); +}; + +TextInput.propTypes = { + formik: PropTypes.any, +}; diff --git a/src/components/time-to-logout/TimeToLogOut.js b/src/components/time-to-logout/TimeToLogOut.js new file mode 100644 index 0000000..0cc0fa1 --- /dev/null +++ b/src/components/time-to-logout/TimeToLogOut.js @@ -0,0 +1,46 @@ +import { Typography } from "@mui/material"; +import React, { useEffect, useState } from "react"; +import { useSelector } from "react-redux"; +// import { RESET_TIME_TO_LOGOUT } from "../../lib/redux/slices/appSlice"; +// import { LOG_OUT } from "../../lib/redux/slices/userSlice"; +import { toHHMMSS } from "../../utils/toHHMMSS"; +import { Grid } from "../grid/Grid"; + +export const TimeToLogOut = () => { + const { inActiveTime } = useSelector((state) => state.appSlice); + const [remainTime, setRemainTime] = useState(inActiveTime); + // const dispatch = useDispatch(); + + useEffect(() => { + // dispatch(RESET_TIME_TO_LOGOUT()); + setRemainTime(inActiveTime); + }, [window.location.pathname]); + + // useEffect(() => { + // if (remainTime < 1) { + // dispatch(LOG_OUT()); + // } + // }, [remainTime]); + + const timer = () => { + setRemainTime((prevState) => prevState - 1); + }; + + useEffect(() => { + if (remainTime <= 0) { + return; + } + const id = setInterval(timer, 1000); + return () => clearInterval(id); + }, []); + + const auctionTimer = remainTime <= 0 ? "پایان یافته!" : toHHMMSS(remainTime); + + return ( + + زمان تا خروج + {auctionTimer} + {/* */} + + ); +}; diff --git a/src/components/timer/Timer.js b/src/components/timer/Timer.js new file mode 100644 index 0000000..a741a01 --- /dev/null +++ b/src/components/timer/Timer.js @@ -0,0 +1,53 @@ +import { Typography } from "@mui/material"; +import { useEffect, useState } from "react"; +import { PropTypes } from "prop-types"; +import { toHHMMSS } from "../../utils/toHHMMSS"; +import { toDDHHMMSS } from "../../utils/toDDHHMMSS"; +import FiberManualRecordIcon from "@mui/icons-material/FiberManualRecord"; +import { Grid } from "../grid/Grid"; + +export const Timer = ({ seconds, isFilePaymentTime }) => { + isFilePaymentTime = isFilePaymentTime || false; + const [currentCount, setCount] = useState(Math.round(seconds)); + const timer = () => { + setCount((prevState) => prevState - 1); + }; + + useEffect(() => { + setCount(seconds); + return () => setCount(0); + }, [seconds]); + + useEffect(() => { + if (currentCount <= 0) { + return; + } + const id = setInterval(timer, 1000); + return () => clearInterval(id); + }, []); + + const auctionTimer = + currentCount <= 0 ? "پایان یافته!" : toHHMMSS(currentCount); + + const fileTimer = + currentCount <= 0 ? "پایان یافته!" : toDDHHMMSS(currentCount); + + return ( + + + + {!isFilePaymentTime && auctionTimer} + {isFilePaymentTime && fileTimer} + + + ); +}; + +Timer.propTypes = { + seconds: PropTypes.any, + isFilePaymentTime: PropTypes.any, +}; diff --git a/src/contexts/AppContext.js b/src/contexts/AppContext.js new file mode 100644 index 0000000..71e64db --- /dev/null +++ b/src/contexts/AppContext.js @@ -0,0 +1,45 @@ +import { createContext, useState } from "react"; +import { PropTypes } from "prop-types"; +import moment from "moment/moment"; + +export const AppContext = createContext(); + +export const AppContextProvider = (props) => { + const [notifState, setNotifState] = useState({ + open: false, + vertical: "top", + horizontal: "center", + severity: "success", + msg: "", + }); + + const [selectedDate1, setSelectedDate1] = useState( + moment(new Date()).format("YYYY-MM-DD") + ); + const [selectedDate2, setSelectedDate2] = useState( + moment(new Date()).format("YYYY-MM-DD") + ); + + const openNotif = (newState) => { + setNotifState({ open: true, ...newState }); + }; + + return ( + + {props.children} + + ); +}; + +AppContextProvider.propTypes = { + children: PropTypes.any, +}; diff --git a/src/contexts/SidebarContext.js b/src/contexts/SidebarContext.js new file mode 100644 index 0000000..7a6bd1c --- /dev/null +++ b/src/contexts/SidebarContext.js @@ -0,0 +1,24 @@ +import { createContext, useState } from "react"; +import { PropTypes } from "prop-types"; + +export const SidebarContext = createContext(); + +export const sidebarContextValues = { + sidebarState: false, +}; + +export const SidebarContextProvider = (props) => { + const [sideBarMobileState, setSidebarMobileState] = useState(false); + + return ( + + {props.children} + + ); +}; + +SidebarContextProvider.propTypes = { + children: PropTypes.any, +}; diff --git a/src/data/columnsName.js b/src/data/columnsName.js new file mode 100644 index 0000000..f03cf8d --- /dev/null +++ b/src/data/columnsName.js @@ -0,0 +1,16 @@ +export const columnsName = [ + "ردیف", + "کد سفارش", + "کدکاربری", + "تاریخ ثبت درخواست", + "تاریخ کشتار", + "مرغدار", + "تلفن مرغدار", + "شهر", + "استان", + "تاریخ جوجه ریزی", + "سن مرغ", + "تعداد", + "عملیات", + "مشاهده", +]; diff --git a/src/data/download-file.js b/src/data/download-file.js new file mode 100644 index 0000000..90810dd --- /dev/null +++ b/src/data/download-file.js @@ -0,0 +1,26 @@ +import axios from "axios"; + +export const downloadFile = (fileUrl) => { + axios({ + url: fileUrl, + method: "GET", + responseType: "blob", + }) + .then((response) => { + const blob = new Blob([response.data], { + type: response.headers["content-type"], + }); + const url = window.URL.createObjectURL(blob); + + const a = document.createElement("a"); + a.href = url; + a.download = "filename.xlsx"; + document.body.appendChild(a); + a.click(); + + window.URL.revokeObjectURL(url); + }) + .catch((error) => { + console.error("Error downloading the file:", error); + }); +}; diff --git a/src/data/roles.js b/src/data/roles.js new file mode 100644 index 0000000..191dcb5 --- /dev/null +++ b/src/data/roles.js @@ -0,0 +1,15 @@ +export const ROLES = [ + "Admin", + "CityOperator", + "Poultry", + "ProvinceOperator", + "ProvinceFinancial", + "KillHouse", + "KillHouseVet", + "VetFarm", + "Driver", + "ProvinceInspector", + "VetSupervisor", + "Jahad", + "ProvincialGovernment", +]; diff --git a/src/data/spacing.js b/src/data/spacing.js new file mode 100644 index 0000000..9ecb551 --- /dev/null +++ b/src/data/spacing.js @@ -0,0 +1,7 @@ +const SPACING = { + TINY: 1, + SMALL: 2, + MEDIUM: 4, + LARGE: 8, +}; +export { SPACING }; diff --git a/src/data/theme.js b/src/data/theme.js new file mode 100644 index 0000000..251edb7 --- /dev/null +++ b/src/data/theme.js @@ -0,0 +1,259 @@ +import { createTheme } from "@mui/material"; +import { faIR } from "@mui/material/locale"; + +export const theme = createTheme( + { + direction: "rtl", + typography: { + fontFamily: [ + "iranyekan", + "-apple-system", + "BlinkMacSystemFont", + '"Segoe UI"', + "Roboto", + '"Helvetica Neue"', + "sans-serif", + "Arial", + '"Apple Color Emoji"', + '"Segoe UI Emoji"', + '"Segoe UI Symbol"', + ].join(","), + }, + palette: { + primary: { + light: "#E0E7FF", + main: "#244CCC", + dark: "#102159", + contrastText: "#fff", + }, + secondary: { + light: "#E6FAF5", + main: "#00CC99", + dark: "#ab003c", + contrastText: "#000", + }, + error: { + light: "#EB5757", + main: "#EB5757", + dark: "#EB5757", + contrastText: "#fff", + }, + info: { + light: "#17A2B8", + main: "#17A2B8", + dark: "#17A2B8", + contrastText: "#fff", + }, + }, + breakpoints: { + values: { + xs: 0, + sm: 600, + md: 900, + lg: 1200, + nlg: 1400, + xl: 1536, + nxl: 1700, + xxl: 1920, + xxxl: 2400, + }, + }, + components: { + MUIDataTableBodyRow: { + styleOverrides: { + root: { + borderBottom: "1px solid #e3e3e3", + }, + }, + }, + MuiFormControl: { + styleOverrides: { + root: { + width: "100%", + }, + }, + }, + MuiFormControlLabel: { + styleOverrides: { + label: { + fontSize: "14px", + }, + }, + }, + MuiOutlinedInput: { + styleOverrides: { + root: { + backgroundColor: "transparent", + "&.Mui-focused": { + backgroundColor: "transparent", + }, + }, + input: { + backgroundColor: "transparent", + "&:-webkit-autofill": { + WebkitBoxShadow: "0 0 0 100px white inset", + WebkitTextFillColor: "inherit", + }, + }, + notchedOutline: { + borderColor: "#e6e6e6", + }, + }, + }, + MuiInputLabel: { + styleOverrides: { + asterisk: { + color: "#EB5757", + }, + }, + }, + MuiButton: { + styleOverrides: { + root: ({ theme }) => ({ + borderRadius: "8px", + fontWeight: 600, + "&.Mui-disabled": { + backgroundColor: "rgba(36, 76, 204, 0.3)", + color: "rgba(255, 255, 255, 0.7)", + }, + fontSize: "17px", + [theme.breakpoints.down("sm")]: { + fontSize: "13px", + }, + }), + outlined: { + borderWidth: "2px", + "&:hover": { + borderWidth: "2px", + }, + "&.Mui-disabled": { + borderColor: "rgba(36, 76, 204, 0.3)", + color: "rgba(36, 76, 204, 0.5)", + backgroundColor: "transparent", + }, + }, + }, + }, + MUIDataTable: { + styleOverrides: { + responsiveBase: { + overflow: "hidden", + }, + root: { + boxShadow: "none !important", + width: "100%", + }, + }, + }, + MUIDataTableSearch: { + styleOverrides: { + searchIcon: { + display: "none", + }, + main: { + justifyContent: "flex-end", + }, + searchText: { + flex: "unset", + }, + }, + }, + MUIDataTablePagination: { + styleOverrides: { + navContainer: { + width: "100%", + display: "inline-block", + }, + }, + }, + MUIDataTableToolbar: { + styleOverrides: { + root: { + alignItems: "center", + }, + actions: { + display: "flex", + justifyContent: "flex-end", + flex: "unset", + }, + titleText: { + textAlign: "right", + fontSize: "16px", + color: "rgba(0, 0, 0, 0.54)", + }, + }, + }, + MUIDataTableHeadCell: { + styleOverrides: { + toolButton: { + padding: "0px !important", + marginRight: "0px !important", + justifyContent: "center !important", + }, + data: ({ theme }) => ({ + fontSize: "14px", + [theme.breakpoints.down("sm")]: { + fontSize: "12px", + }, + }), + contentWrapper: { + justifyContent: "center", + }, + }, + }, + MuiTableCell: { + styleOverrides: { + head: { + backgroundColor: "#e3e3e3 !important", + textAlign: "center", + }, + root: { + justifyContent: "center", + padding: "5px !important", + }, + }, + }, + MuiToolbar: { + styleOverrides: { + root: {}, + }, + }, + MUIDataTableBodyCell: { + styleOverrides: { + root: { + textAlign: "center", + fontSize: "12px", + }, + }, + }, + MuiTablePagination: { + styleOverrides: { + root: { + justifyContent: "center", + display: "flex", + }, + toolbar: { + marginTop: "0px", + alignItems: "center", + }, + }, + }, + MuiDrawer: { + styleOverrides: { + paperAnchorBottom: { + borderTopRightRadius: "25px", + borderTopLeftRadius: "25px", + }, + }, + }, + MuiTimeline: { + styleOverrides: { + root: { + gap: "0px !important", + }, + }, + }, + }, + }, + faIR +); diff --git a/src/features/admin/components/admin-hatching-by-period/AdminHatchingByPeriod.js b/src/features/admin/components/admin-hatching-by-period/AdminHatchingByPeriod.js new file mode 100644 index 0000000..630814a --- /dev/null +++ b/src/features/admin/components/admin-hatching-by-period/AdminHatchingByPeriod.js @@ -0,0 +1,297 @@ +import { Button, Chip, Divider, TextField, Typography } from "@mui/material"; +import { DatePicker } from "@mui/x-date-pickers"; +import React, { useEffect, useState } from "react"; +import ChartBar from "../../../../components/chart-bar/ChartBar"; +import { Grid } from "../../../../components/grid/Grid"; +import { SPACING } from "../../../../data/spacing"; +import { useFormik } from "formik"; +import { Yup } from "../../../../lib/yup/yup"; +import { useDispatch, useSelector } from "react-redux"; +import { adminGetHatchingByPeriod } from "../../services/admin-get-hatching-by-period"; +import { + LOADING_END, + LOADING_START, +} from "../../../../lib/redux/slices/appSlice"; +import moment from "moment"; +import { EMPTY_HATCHING } from "../../../../lib/redux/slices/adminSlice"; +import { formatJustDate } from "../../../../utils/formatTime"; + +export const AdminHatchingByPeriod = () => { + const dispatch = useDispatch(); + + const { hatchingByPeriod } = useSelector((state) => state.adminSlice); + + useEffect(() => { + dispatch(EMPTY_HATCHING()); + }, []); + + useEffect(() => { + if (hatchingByPeriod && Array.isArray(hatchingByPeriod)) { + setHatchingByPeriodData({ + labels: hatchingByPeriod.map((data) => formatJustDate(data?.date)), + datasets: [ + { + label: "تعداد", + backgroundColor: ["rgba(33, 72, 214, 0.7)"], + data: hatchingByPeriod.map((data) => data?.quantity || 0), + borderRadius: 5, + }, + { + label: "تلفات", + backgroundColor: ["rgba(100, 130, 160, 0.7)"], + data: hatchingByPeriod.map((data) => data?.losses || 0), + borderRadius: 5, + }, + // { + // type: "line", + // label: "مقدار استاندارد", + // backgroundColor: ["rgba(0, 120, 10, 0.7)"], + // data: [ + // 2500, 2500, 2500, 2500, 2500, 2500, 2500, 2500, 2500, 2500, 2500, + // 2500, + // ], + // }, + ], + }); + } + }, [hatchingByPeriod?.length]); + + const [hatchingByPeriodData, setHatchingByPeriodData] = useState({ + datasets: [], + }); + + const formik = useFormik({ + initialValues: { + periodfrom: moment(Date()).format("YYYY-MM-DD"), + periodto: moment(Date()).format("YYYY-MM-DD"), + chickenAge: "5", + }, + validationSchema: Yup.object({ + periodfrom: Yup.string() + .typeError("لطفا فیلد را به درستی وارد کنید.!") + .required("این فیلد اجباری است!"), + periodto: Yup.string() + .typeError("لطفا فیلد را به درستی وارد کنید.!") + .required("این فیلد اجباری است!"), + chickenAge: Yup.number() + .typeError("لطفا فیلد را به صورت عددی وارد کنید.!") + .required("این فیلد اجباری است!") + .test("len", "سن مرغ را در بازه 45 روزه وارد کنید", (val, context) => { + if (context.originalValue) { + return context.originalValue <= 45 && context.originalValue > 0; + } + }), + }), + }); + + const chartTooltipData = (data) => { + if (!data || !data.parsed || typeof data.parsed.x === "undefined") { + return ""; + } + + const index = data.parsed.x; + + if (!data?.dataset?.label) { + return ""; + } + + if (data.dataset.label === "تلفات") { + return "مرغداری صداقت با مقدار 2000 در تاریخ 1400/02/03"; + } else if (data.dataset.label === "مقدار استاندارد") { + return `میزان استاندارد جوجه ریزی در روز ${ + data?.formattedValue || "" + } عدد میباشد`; + } else { + const hatchingItem = hatchingByPeriod?.[index]; + if (!hatchingItem || !Array.isArray(hatchingItem?.poultry)) { + return ""; + } + return hatchingItem.poultry + .map( + (poultryData, i) => + i + + 1 + + "- مرغداری " + + (poultryData?.unitname || "") + + " از استان " + + (poultryData?.province || "") + + " شهر " + + (poultryData?.city || "") + ) + .join(", "); + } + }; + + const chartTooltipTitle = (data) => { + if (!data?.dataset?.label) { + return ""; + } + + if (data.dataset.label === "تلفات") { + return "تلفات برای این مرغداری ها ثبت شده است"; + } else if (data.dataset.label === "مقدار استاندارد") { + return "لاین کنترلی"; + } else { + return "جوجه ریزی ها توسط این مرغداری ها ثبت شده است"; + } + }; + + const [dataObject, setDataObject] = useState({ + date1: "", + date2: "", + age: "", + }); + + useEffect(() => { + setDataObject({ + date1: formik.values.periodfrom, + date2: formik.values.periodto, + age: formik.values.chickenAge, + }); + }, [formik.values]); + + const options = { + plugins: { + tooltip: { + callbacks: { + title: (data) => { + if (!data || !Array.isArray(data) || !data[0]) { + return ""; + } + return chartTooltipTitle(data[0]); + }, + label: (data) => { + if (!data) { + return ""; + } + return chartTooltipData(data); + }, + }, + }, + }, + }; + + useEffect(() => { + formik.validateForm(); + }, []); + + const isFormvalid = (formik) => { + const date = + (new Date(formik.values.periodto) - new Date(formik.values.periodfrom)) / + (1000 * 60 * 60 * 24); + if (date > 0 && date <= 30) { + return false; + } else { + return true; + } + }; + + return ( + + + + + + + + دریافت بر اساس بازه دلخواه : + + } + value={formik.values.periodfrom} + error={ + formik.touched.periodfrom + ? Boolean(formik.errors.periodfrom) + : null + } + onChange={(e) => { + formik.setFieldValue( + "periodfrom", + moment(e).format("YYYY-MM-DD") + ); + }} + onBlur={formik.handleBlur} + helperText={ + formik.touched.periodfrom && Boolean(formik.errors.periodfrom) + ? formik.errors.periodfrom + : null + } + /> + + } + value={formik.values.periodto} + error={ + formik.touched.periodto ? Boolean(formik.errors.periodto) : null + } + onChange={(e) => { + formik.setFieldValue("periodto", moment(e).format("YYYY-MM-DD")); + }} + onBlur={formik.handleBlur} + helperText={ + formik.touched.periodto && Boolean(formik.errors.periodto) + ? formik.errors.periodto + : null + } + /> + + + + + + + + ); +}; diff --git a/src/features/admin/components/admin-hatching/AdminHatching.js b/src/features/admin/components/admin-hatching/AdminHatching.js new file mode 100644 index 0000000..ef2a988 --- /dev/null +++ b/src/features/admin/components/admin-hatching/AdminHatching.js @@ -0,0 +1,296 @@ +import { Button, IconButton, Tooltip } from "@mui/material"; +import { SPACING } from "../../../../data/spacing"; +import { useEffect } from "react"; +import { useDispatch, useSelector } from "react-redux"; +import { useFormik } from "formik"; +import moment from "moment"; +import { useState } from "react"; +import DeleteIcon from "@mui/icons-material/Delete"; +import { useContext } from "react"; +import Tour from "reactour"; +import { AvicultureNewHatching } from "../../../aviculture/components/aviculture-new-hatching/AvicultureNewHatching"; +import { AdvancedTable } from "../../../../components/advanced-table/AdvancedTable"; +import { + DRAWER, + LOADING_END, + LOADING_START, +} from "../../../../lib/redux/slices/appSlice"; +import { Grid } from "../../../../components/grid/Grid"; +import { AppContext } from "../../../../contexts/AppContext"; +import { avicultureGetHatchings } from "../../../aviculture/services/aviculture-get-hatchings"; +import { Yup } from "../../../../lib/yup/yup"; +import { avicultureDeleteHatching } from "../../../aviculture/services/aviculture-delete-hatching"; +import { formatJustDate } from "../../../../utils/formatTime"; + +const steps = [ + { + selector: ".first-step", + content: () =>
    برای ثبت جوجه ریزی اینجا کلیک کنید!
    , + }, + { + selector: ".second", + content: () => ( +
    در این قسمت جوجه ریزی های ثبت شده توسط شما نمایش داده می شود.
    + ), + }, +]; + +export const AdminHatching = () => { + const dispatch = useDispatch(); + const [openNotif] = useContext(AppContext); + const { avicultureHatchings } = useSelector((state) => state.avicultureSlice); + const [isTourOpen, setIsTourOpen] = useState(false); + const [dataTable, setDataTable] = useState([]); + const [dataTableArchived, setDataTableArchuved] = useState([]); + + useEffect(() => { + dispatch(avicultureGetHatchings()); + }, []); + + useEffect(() => { + const filteredData = avicultureHatchings?.filter( + (item) => item.allowHatching === "pending" + ); + + const filteredDataArchived = avicultureHatchings?.filter( + (item) => item.allowHatching === "True" + ); + + const d = filteredData?.map((item, i) => { + const quantity = item?.quantity || 0; + const losses = item?.losses || 0; + const leftOver = item?.leftOver || 0; + const killedNumber = quantity - losses - leftOver; + const percentage = + quantity > 0 + ? (value) => ((value * 100) / quantity).toFixed(0) + : () => "0"; + + return [ + i + 1, + item?.poultry?.unitName || "", + item?.hall || "", + item?.period || "", + formatJustDate(item?.createDate), + formatJustDate(item?.date), + item?.chickenBreed || "", + item?.age || "", + quantity, + `${losses} (%${percentage(losses)})`, + killedNumber + ` (%${percentage(killedNumber)})`, + `${leftOver} (%${percentage(leftOver)})`, + + { + dispatch(LOADING_START()); + dispatch(avicultureDeleteHatching(item?.key)).then((r) => { + dispatch(LOADING_END()); + if (r?.error) { + const errorMessage = r.error?.message || ""; + if (errorMessage.includes("403")) { + openNotif({ + vertical: "top", + horizontal: "center", + msg: "برای این جوجه ریزی درخواست کشتار ثبت شده است!", + severity: "error", + }); + } else if (errorMessage.includes("400")) { + openNotif({ + vertical: "top", + horizontal: "center", + msg: "برای این جوجه ریزی بازرسی ثبت شده است!", + severity: "error", + }); + } else { + openNotif({ + vertical: "top", + horizontal: "center", + msg: "مشکلی پیش آمده است!", + severity: "error", + }); + } + } else { + dispatch(avicultureGetHatchings()); + openNotif({ + vertical: "top", + horizontal: "center", + msg: "عملیات با موفقیت انجام شد.", + severity: "success", + }); + } + }); + }} + > + + + , + ]; + }); + + setDataTable(d); + + const b = filteredDataArchived?.map((item, i) => { + const quantity = item?.quantity || 0; + const losses = item?.losses || 0; + const leftOver = item?.leftOver || 0; + const killedNumber = quantity - losses - leftOver; + const percentage = + quantity > 0 + ? (value) => ((value * 100) / quantity).toFixed(0) + : () => "0"; + + return [ + i + 1, + item?.poultry?.unitName || "", + item?.hall || "", + item?.period || "", + formatJustDate(item?.createDate), + formatJustDate(item?.date), + item?.chickenBreed || "", + item?.age || "", + quantity, + `${losses} (%${percentage(losses)})`, + killedNumber + ` (%${percentage(killedNumber)})`, + `${leftOver} (%${percentage(leftOver)})`, + ]; + }); + + setDataTableArchuved(b); + }, [avicultureHatchings]); + + const formik = useFormik({ + initialValues: { + noChicken: "", + slaughterDate: moment(Date()).format("YYYY-MM-DD hh:mm:ss"), + race: "آرین", + weight: "", + }, + validationSchema: Yup.object({ + noChicken: Yup.number() + .required("این فیلد اجباری است!") + .typeError("لطفا عدد وارد کنید!"), + weight: Yup.number() + .required("این فیلد اجباری است!") + .typeError("لطفا وزن را وارد کنید!"), + }), + }); + + useEffect(() => { + formik.validateForm(); + }, []); + + return ( + + + + + + + + + + {/* */} + + + setIsTourOpen(false)} + styles={{ + popover: (base) => ({ + ...base, + borderRadius: "10px", + "--reactor-accent": "red", + }), + }} + /> + + + + + + + + + + + ); +}; diff --git a/src/features/admin/components/admin-static-info-in-box/AdminStaticInfoInBox.js b/src/features/admin/components/admin-static-info-in-box/AdminStaticInfoInBox.js new file mode 100644 index 0000000..f8c6307 --- /dev/null +++ b/src/features/admin/components/admin-static-info-in-box/AdminStaticInfoInBox.js @@ -0,0 +1,247 @@ +import { + Card, + CardActionArea, + CardContent, + CardMedia, + Typography, +} from "@mui/material"; +import React from "react"; +import { Grid } from "../../../../components/grid/Grid"; +import { SPACING } from "../../../../data/spacing"; +import { PropTypes } from "prop-types"; + +import img1 from "../../../../assets/images/document.jpg"; +import img2 from "../../../../assets/images/chicken.svg"; +import img3 from "../../../../assets/images/users.jpg"; +import img4 from "../../../../assets/images/price.jpg"; + +export default function AdminStaticInfoInBox({ infoData }) { + return ( + + + + + + + + پرونده ها + + + prop.palette.grey["A700"]} + > + فعال: + + + {infoData?.numberOfActiveFiles} + + + + + prop.palette.grey["A700"]} + > + رد شده: + + + {infoData?.numberOfRejectedFiles} + + + + + prop.palette.grey["A700"]} + > + بایگانی شده: + + + {infoData?.numberOfArchiveFiles} + + + + + + + + + + + جوجه ریزی + + + prop.palette.grey["A700"]} + > + جوجه ریزی: + + + {infoData?.realHatching} + + + + + prop.palette.grey["A700"]} + > + تلفات: + + + {infoData?.totalLossess} + + + + + prop.palette.grey["A700"]} + > + مجموع: + + + {infoData?.totalHatching} + + + + + + + + + + + کاربران + + + prop.palette.grey["A700"]} + > + کل: + + + {infoData?.totalUsers} + + + + + prop.palette.grey["A700"]} + > + کاربر: + + + {infoData?.numberOfUsers} + + + + + prop.palette.grey["A700"]} + > + اپراتور: + + + {infoData?.numberOfOperators} + + + + + + + + + + + + نرخ مرغ + + + prop.palette.grey["A700"]} + > + قیمت روز: + + + {infoData?.price} ریال + + + + + prop.palette.grey["A700"]} + > + کف قیمت: + + + {infoData?.floorPrice} ریال + + + + + prop.palette.grey["A700"]} + > + سقف قیمت: + + + {infoData?.cellingPrice} ریال + + + + + + + + ); +} + +AdminStaticInfoInBox.propTypes = { + infoData: PropTypes.any, +}; diff --git a/src/features/admin/components/requests-operations/AdminRequestsOperations.js b/src/features/admin/components/requests-operations/AdminRequestsOperations.js new file mode 100644 index 0000000..6c50226 --- /dev/null +++ b/src/features/admin/components/requests-operations/AdminRequestsOperations.js @@ -0,0 +1,80 @@ +import { useLocation } from "react-router-dom"; +import { Button } from "@mui/material"; +import { + ROUTE_ADMIN_ARCHIVED_REQUESTS, + ROUTE_ADMIN_AWAITING_INSPECTION_REQUESTS, + ROUTE_ADMIN_AWAITING_PAYMENT_REQUESTS, + ROUTE_ADMIN_HATCHING, + ROUTE_ADMIN_REJECTED_REQUESTS, + ROUTE_ADMIN_REQUESTS, +} from "../../../../routes/routes"; +import { Grid } from "../../../../components/grid/Grid"; +import { SPACING } from "../../../../data/spacing"; +import { NavLink } from "../../../../components/nav-link/NavLink"; + +export const AdminRequestsOperations = () => { + const { pathname } = useLocation(); + + return ( + + + + + + + + + + + + + + + + + + + + + + ); +}; diff --git a/src/features/admin/services/admin-get-charts.js b/src/features/admin/services/admin-get-charts.js new file mode 100644 index 0000000..44219cb --- /dev/null +++ b/src/features/admin/services/admin-get-charts.js @@ -0,0 +1,7 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; + +export const adminGetCharts = createAsyncThunk("ADMIN_GET_CHARTS", async () => { + const { data, status } = await axios.get("chart"); + return { data, status }; +}); diff --git a/src/features/admin/services/admin-get-hatching-by-period.js b/src/features/admin/services/admin-get-hatching-by-period.js new file mode 100644 index 0000000..ebdf832 --- /dev/null +++ b/src/features/admin/services/admin-get-hatching-by-period.js @@ -0,0 +1,17 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; + +export const adminGetHatchingByPeriod = createAsyncThunk( + "ADMIN_GET_HATCHING_BY_PERIOD", + async (dataObject) => { + const { data, status } = await axios.get( + "forcast_hatching/?date1=" + + dataObject.date1 + + "&date2=" + + dataObject.date2 + + "&day=" + + dataObject.age + ); + return { data, status }; + } +); diff --git a/src/features/admix-x/components/admin-x-excel-status/AdminCExcelStatus.js b/src/features/admix-x/components/admin-x-excel-status/AdminCExcelStatus.js new file mode 100644 index 0000000..f3e02f5 --- /dev/null +++ b/src/features/admix-x/components/admin-x-excel-status/AdminCExcelStatus.js @@ -0,0 +1,222 @@ +import React, { useContext, useEffect, useState } from "react"; +import { Grid } from "../../../../components/grid/Grid"; +import ResponsiveTable from "../../../../components/responsive-table/ResponsiveTable"; +import { reportsList } from "./reportList"; +import { AppContext } from "../../../../contexts/AppContext"; +import moment from "moment"; +import { DatePicker } from "@mui/x-date-pickers"; +import { Button, IconButton, TextField, Typography } from "@mui/material"; +import { SPACING } from "../../../../data/spacing"; +import { useDispatch, useSelector } from "react-redux"; +import { adminXGetReportStatusService } from "../../services/admin-x-get-report-status-service"; +import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl"; +import ManageSearchIcon from "@mui/icons-material/ManageSearch"; + +export const AdminCExcelStatus = () => { + const [tableData, setTableData] = useState([]); + const userKey = useSelector((state) => state.userSlice?.userProfile?.key); + const authToken = useSelector((state) => state.userSlice?.authToken); + const [loadingIndex, setLoadingIndex] = useState(null); + const [allReports, setAllReports] = useState([]); + const [update, setUpdate] = useState(false); + + const [, , selectedDate1, setSelectedDate1, selectedDate2, setSelectedDate2] = + useContext(AppContext); + + const dispatch = useDispatch(); + + useEffect(() => { + const currentDate = moment(new Date()).format("YYYY-MM-DD"); + setSelectedDate1(currentDate); + setSelectedDate2(currentDate); + }, [setSelectedDate1, setSelectedDate2]); + + useEffect(() => { + const newData = reportsList.map((report) => ({ + ...report, + status: "", + })); + setAllReports(newData); + }, []); + + function replaceUrlParams(url, date1, date2, role, key, token) { + if (!url || typeof url !== "string") { + return url || ""; + } + + const [baseUrl, queryString] = url.split("?"); + + if (!queryString) { + return url; + } + + const params = new URLSearchParams(queryString); + + if (params.has("date1")) { + params.set("date1", date1); + } + if (params.has("date2")) { + params.set("date2", date2); + } + + if (params.has("start")) { + params.set("start", date1); + } + if (params.has("end")) { + params.set("end", date2); + } + + if (params.has("role")) { + params.set("role", role); + } + + if (params.has("token")) { + params.set("token", token); + } + + if (params.has("key")) { + params.set("key", key); + } + + return `${baseUrl}?${params.toString()}`; + } + + const handleCheckAll = async () => { + const updatedData = [...allReports]; + for (let i = 0; i < allReports.length; i++) { + setLoadingIndex(i); + try { + const response = await dispatch( + adminXGetReportStatusService({ + url: replaceUrlParams( + allReports[i]?.url, + selectedDate1, + selectedDate2, + getRoleFromUrl(), + userKey, + authToken + ), + }) + ); + + if (response?.payload?.data?.status) { + updatedData[i].status = response.payload.data.status; + } + } catch (error) { + console.error("Error fetching report status:", error); + } + } + setLoadingIndex(null); + setAllReports(updatedData); + setUpdate((prevUpdate) => !prevUpdate); + }; + + const handleSingleCheck = async (index) => { + setLoadingIndex(index); + try { + const response = await dispatch( + adminXGetReportStatusService({ + url: replaceUrlParams( + allReports[index]?.url, + selectedDate1, + selectedDate2, + getRoleFromUrl(), + userKey, + authToken + ), + }) + ); + + const newData = [...allReports]; + if (response?.payload?.data?.status) { + newData[index].status = response.payload.data.status; + } + setAllReports(newData); + } catch (error) { + console.error("Error fetching report status:", error); + } finally { + setLoadingIndex(null); + } + }; + + useEffect(() => { + const d = allReports.map((item, i) => [ + i + 1, + item?.title || "", + item?.url ? item.url.split("/")[0] : "", + handleSingleCheck(i)} + disabled={loadingIndex === i} + > + + , + item?.status ? ( + + ({item.status}){" "} + {parseInt(item.status) === 200 || item.status === "200" + ? "سالم" + : "مشکل دارد"} + + ) : ( + "-" + ), + ]); + + setTableData(d); + }, [allReports, loadingIndex, update]); + + return ( + + + + ( + + )} + value={selectedDate1} + onChange={(e) => { + setSelectedDate1(moment(e).format("YYYY-MM-DD")); + }} + /> + + + ( + + )} + value={selectedDate2} + onChange={(e) => { + setSelectedDate2(moment(e).format("YYYY-MM-DD")); + }} + /> + + + + + + + + ); +}; diff --git a/src/features/admix-x/components/admin-x-excel-status/reportList.js b/src/features/admix-x/components/admin-x-excel-status/reportList.js new file mode 100644 index 0000000..d508d3c --- /dev/null +++ b/src/features/admix-x/components/admin-x-excel-status/reportList.js @@ -0,0 +1,219 @@ +export const reportsList = [ + { + title: "مدیریت بار", + url: "bar_excel/?start=2024-08-03&end=2024-08-03&key=fde6fff6-7f4c-4e10-5604-0d45f8b41904&role=ProvinceOperator&search=filter&value=", + }, + { + title: "گزارش جزییات کشتار", + url: "detail_of_killing_excel/?date1=2024-08-03&date2=2024-08-03&role=ProvinceOperator&key=fde6fff6-7f4c-4e10-5604-0d45f8b41904", + }, + { + title: "گزارش جامع کشتارگاه", + url: "comprehensive_report_of_the_slaughterhouse_excel/?date1=2024-08-03&date2=2024-08-03", + }, + { + title: "پایش کلی بارها", + url: "monitor_loads_excel/?role=ProvinceOperator&key=fde6fff6-7f4c-4e10-5604-0d45f8b41904&date1=2024-08-03&date2=2024-08-03", + }, + { + title: "مدیریت بارهای تکمیل نشده", + url: "bar_excel/?start=2024-05-21&end=2024-08-03&role=ProvinceOperator&state=bar_pending&key=fde6fff6-7f4c-4e10-5604-0d45f8b41904&search=filter&value=", + }, + { + title: "مدیریت بارهای تکمیل شده", + url: "bar_excel/?start=2024-07-22&end=2024-08-03&state=completed&role=ProvinceOperator&key=fde6fff6-7f4c-4e10-5604-0d45f8b41904&search=filter&value=", + }, + { + title: "بارهای حذف شده", + url: "bar_excel_trash_true/?start=2024-08-03&end=2024-08-03&key=fde6fff6-7f4c-4e10-5604-0d45f8b41904&role=ProvinceOperator&search=filter&value=", + }, + { + title: "فروش خارج از استان", + url: "bar_free_excel/?date1=2024-08-03&date2=2024-08-03&state=accepted&role=ProvinceOperator&key=fde6fff6-7f4c-4e10-5604-0d45f8b41904", + }, + { + title: "مدیریت بارهای زنجیره", + url: "bar_chain_excel/?key=fde6fff6-7f4c-4e10-5604-0d45f8b41904&role=ProvinceOperator&search=filter&value=&state=accepted&date1=2024-08-03&date2=2024-08-03", + }, + { + title: "خرید خارج از استان زنده", + url: "kill_house_free_bar_excel/?role=ProvinceOperator&key=fde6fff6-7f4c-4e10-5604-0d45f8b41904&date1=2024-08-03&date2=2024-08-03&type=live", + }, + { + title: "خرید خارج از استان لاشه", + url: "kill_house_free_bar_excel/?role=ProvinceOperator&key=fde6fff6-7f4c-4e10-5604-0d45f8b41904&date1=2024-08-03&date2=2024-08-03&type=carcass", + }, + { + title: "درخواست مرغدار", + url: "poultry_kill_request_excel/?start=2024-08-03&end=2024-08-03&role=ProvinceOperator&token=vamptUktoL9b1htBgvjE14XTZg7Bg4", + }, + { + title: "درخواست کشتارگاه", + url: "kill_house_excel/?start=2024-08-03&end=2024-08-03", + }, + { + title: "جوجه ریزی", + url: "0/hatching_excel/?role=ProvinceOperator&key=fde6fff6-7f4c-4e10-5604-0d45f8b41904&search=filter&value=", + }, + { + title: "بایگانی جوجه ریزی", + url: "archive_hatching_excel/?search=filter&value=&key=fde6fff6-7f4c-4e10-5604-0d45f8b41904&role=ProvinceOperator", + }, + { + title: "جوجه ریزی در بازه تاریخی", + url: "hatching_date_range_excel/?date1=2024-08-03&date2=2024-08-03", + }, + { + title: "وضعیت پرونده", + url: "poultry_request_report_excel/?start=2024-08-03&end=2024-08-03&role=ProvinceOperator&key=fde6fff6-7f4c-4e10-5604-0d45f8b41904", + }, + { + title: "گزارش مغایرت اطلاعات کشتار و عدم فعالیت نقش ها", + url: "discrepancy_report_excel/?date1=2024-08-02&date2=2024-08-03&key=fde6fff6-7f4c-4e10-5604-0d45f8b41904&role=ProvinceOperator", + }, + { + title: + "گزارش کلی فارم های فعال مرغ گوشتی دارای مانده در سالن بیشتر از 10 درصد و بازه سنی 55 تا 90 روزه", + url: "poultry_hatching_between_50age_70age_excel/", + }, + { + title: "گزارش کشتار روزانه", + url: "daily_process_klling_proccess_excel/?date=2024-08-03&key=fde6fff6-7f4c-4e10-5604-0d45f8b41904", + }, + { + title: "گزارش پخش روزانه", + url: "daily_process_excel/?date=2024-08-03&key=fde6fff6-7f4c-4e10-5604-0d45f8b41904", + }, + { + title: "تراکنش های موفق", + url: "successful_transactions_excel/?date1=2024-08-03&date2=2024-08-03&key=fde6fff6-7f4c-4e10-5604-0d45f8b41904", + }, + { + title: "تراکنش های ناموفق", + url: "unsuccessful_transactions_excel/?date1=2024-08-03&date2=2024-08-03&key=fde6fff6-7f4c-4e10-5604-0d45f8b41904", + }, + { + title: "مدیریت اصناف", + url: "guilds_excel/?key=fde6fff6-7f4c-4e10-5604-0d45f8b41904&search=filter&value=&role=ProvinceOperator", + }, + { + title: "مدیریت مباشرین", + url: "stewards_excel/", + }, + { + title: "خودروها", + url: "car_province_excel/?key=fde6fff6-7f4c-4e10-5604-0d45f8b41904&role=Province", + }, + { + title: "مدیریت کاربران", + url: "get_all_user_excel/", + }, + { + title: "مدیریت مرغداران", + url: "management_poultry/?key=fde6fff6-7f4c-4e10-5604-0d45f8b41904&role=ProvinceOperator", + }, + { + title: "مدیریت خریداران", + url: "kill_house_user_excel/", + }, + { + title: "گزارش پخش لاشه مرغ گرم", + url: "all_inventory_excel/?date1=2024-07-22&date2=2024-08-03", + }, + { + title: "گزارش پخش لاشه مرغ گرم از مباشر به صنف", + url: "steward_ware_house_total_report_daily_excel/?date1=2024-06-21&date2=2024-08-03", + }, + { + title: "کارمزد پرداخت شده کشتارگاه", + url: "kill_house_total_transactions_wage_payid_excel/?key=fde6fff6-7f4c-4e10-5604-0d45f8b41904&search=filter&value=&role=ProvinceOperator", + }, + { + title: "پرداختی زنجیره ها", + url: "chain-company-total-transactions_not_payid_excel/?token=vamptUktoL9b1htBgvjE14XTZg7Bg4", + }, + { + title: "ریز تراکنش ها", + url: "payment_transactions_province_excel/?role=ProvinceOperator&key=fde6fff6-7f4c-4e10-5604-0d45f8b41904", + }, + { + title: "اطلاعات تعرفه بارهای روزانه", + url: "kill_house_total_wage_excel/?token=vamptUktoL9b1htBgvjE14XTZg7Bg4&date1=2024-08-03&date2=2024-08-03", + }, + { + title: "پایش تعرفه برای استان", + url: "kill_house_total_transactions_wage_payid_super_admin_excel/?key=fde6fff6-7f4c-4e10-5604-0d45f8b41904&role=AdminX", + }, + { + title: "پایش تعرفه برای ادمین ایکس", + url: "kill_house_total_transactions_wage_payid_admin_x_excel/?role=AdminX&key=fde6fff6-7f4c-4e10-5604-0d45f8b41904", + }, + { + title: "خرید مستقیم", + url: "direct_purchase_excel/?date1=2024-08-03&date2=2024-08-03&role=ProvinceOperator&key=fde6fff6-7f4c-4e10-5604-0d45f8b41904", + }, + { + title: "بایگانی خرید مستقیم", + url: "direct_purchase_archive_excel/?date1=2024-08-03&date2=2024-08-03&role=ProvinceOperator&key=fde6fff6-7f4c-4e10-5604-0d45f8b41904", + }, + { + title: "بایگانی صادرات", + url: "export_kill_house_excel/?date1=2024-08-03&date2=2024-08-03&role=AdminX&key=fde6fff6-7f4c-4e10-5604-0d45f8b41904", + }, + { + title: "گزارش کلی بار خارج از استان", + url: "general_free_bar_excel/?date1=2024-08-03&date2=2024-08-03&role=AdminX&key=fde6fff6-7f4c-4e10-5604-0d45f8b41904&search=filter&value=", + }, + { + title: "بار خارج از استان", + url: "bar_free_excel/?date1=2024-08-03&date2=2024-08-03&state=pending&role=AdminX&key=fde6fff6-7f4c-4e10-5604-0d45f8b41904", + }, + { + title: "بارهای تایید شده خارج از استان", + url: "bar_free_excel/?date1=2024-08-03&date2=2024-08-03&state=accepted&role=AdminX&key=fde6fff6-7f4c-4e10-5604-0d45f8b41904", + }, + { + title: "بارهای رد شده خارج از استان", + url: "bar_free_excel/?date1=2024-08-03&date2=2024-08-03&state=rejected&role=AdminX&key=fde6fff6-7f4c-4e10-5604-0d45f8b41904", + }, + { + title: "خریداران خارج از استان", + url: "out_province_poultry_request_buyers_excel/?key=fde6fff6-7f4c-4e10-5604-0d45f8b41904&role=AdminX&search=filter&value=", + }, + { + title: "جوجه ریزی زنجیره", + url: "0/hatching_excel/?role=AdminX&key=fde6fff6-7f4c-4e10-5604-0d45f8b41904&chain=true", + }, + { + title: "مدیریت بار زنجیره ها", + url: "bar_chain_excel/?key=fde6fff6-7f4c-4e10-5604-0d45f8b41904&role=AdminX&search=filter&value=&state=accepted&date1=2024-08-03&date2=2024-08-03", + }, + { + title: "شرکت زنجیره", + url: "chain_company_buyers_excel/?role=AdminX&key=fde6fff6-7f4c-4e10-5604-0d45f8b41904&search=filter&value=", + }, + { + title: "جوجه ریزی بایگانی شرکت زنجیره", + url: "archive_hatching_excel/?chain=true", + }, + { + title: "مدیریت تخصیصات", + url: "allocated_excel/?start=2024-08-03&end=2024-08-03", + }, + { + title: "گزارش کشتار روزانه", + url: "daily_process_klling_proccess_excel/?date=2024-08-03&key=fde6fff6-7f4c-4e10-5604-0d45f8b41904", + }, + { + title: "گزارش پخش روزانه", + url: "daily_process_excel/?date=2024-08-03&key=fde6fff6-7f4c-4e10-5604-0d45f8b41904", + }, + { + title: "تراکنش های موفق", + url: "successful_transactions_excel/?date1=2024-08-03&date2=2024-08-03&key=fde6fff6-7f4c-4e10-5604-0d45f8b41904", + }, + { + title: "تراکنش های ناموفق", + url: "unsuccessful_transactions_excel/?date1=2024-08-03&date2=2024-08-03&key=fde6fff6-7f4c-4e10-5604-0d45f8b41904", + }, +]; diff --git a/src/features/admix-x/services/admin-x-get-report-status-service.js b/src/features/admix-x/services/admin-x-get-report-status-service.js new file mode 100644 index 0000000..b1e1771 --- /dev/null +++ b/src/features/admix-x/services/admin-x-get-report-status-service.js @@ -0,0 +1,12 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; + +export const adminXGetReportStatusService = createAsyncThunk( + "ADMINX_REPORT_STATUS", + async (d, { dispatch }) => { + const { data, status } = await axios.get("check_excel/", { + params: { url: d.url }, + }); + return { data, status }; + } +); diff --git a/src/features/auction/components/auction-bids/AuctionBids.js b/src/features/auction/components/auction-bids/AuctionBids.js new file mode 100644 index 0000000..fb36628 --- /dev/null +++ b/src/features/auction/components/auction-bids/AuctionBids.js @@ -0,0 +1,111 @@ +import { Button } from "@mui/material"; +// import moment from "moment"; +import { useEffect, useState } from "react"; +import { useDispatch, useSelector } from "react-redux"; +import { useNavigate } from "react-router-dom"; +import { AdvancedTable } from "../../../../components/advanced-table/AdvancedTable"; +import { Grid } from "../../../../components/grid/Grid"; +// import { Timer } from "../../../../components/timer/Timer"; +import { SPACING } from "../../../../data/spacing"; +import { ROUTE_SLAUGHTER_FILE } from "../../../../routes/routes"; +import { formatTime } from "../../../../utils/formatTime"; +import { auctionSlaughterRequests } from "../../services/auction-slaughter-requests"; + +export const AuctionsBids = () => { + const [tableRows, setTableRows] = useState([]); + const dispatch = useDispatch(); + const navigate = useNavigate(); + const { auctionSlaughterRequestsData } = useSelector( + (state) => state.auctionSlice + ); + + useEffect(() => { + dispatch(auctionSlaughterRequests()); + }, []); + + useEffect(() => { + if ( + !auctionSlaughterRequestsData || + !Array.isArray(auctionSlaughterRequestsData) + ) { + setTableRows([]); + return; + } + + setTableRows( + auctionSlaughterRequestsData.map((item) => { + // const auctionFinishDate = moment(new Date(item.date)); + // const currentDate = moment(); + // const diff = auctionFinishDate.diff(currentDate); + // let auctionRemainedSeconds = moment.duration(diff).asSeconds(); + const auctionState = + item?.state === "accepted" + ? "برنده شده اید!" + : item?.state === "pending" + ? "در حال انجام مزایده" + : "درخواست شما پذیرفته نشد."; + return [ + item?.poultryRequest?.id || "", + item?.poultryRequest?.orderCode || "", + (item?.fee || 0) + " ﷼", + (item?.poultryRequest?.quantity || 0) + " قطعه", + item?.poultryRequest?.hatching?.date || "", + (item?.poultryRequest?.chickenBreed || "") + + (item?.poultryRequest?.chickenBreed && + item?.poultryRequest?.process?.poultry?.age + ? " - " + : "") + + (item?.poultryRequest?.process?.poultry?.age || ""), + (item?.poultryRequest?.IndexWeight || 0) + " کیلوگرم", + item?.poultryRequest?.poultry?.address?.province?.name || "", + item?.poultryRequest?.poultry?.address?.city?.name || "", + item?.date ? formatTime(item.date) : "", + auctionState === "برنده شده اید!" ? ( + + {auctionState} + + + ) : ( + auctionState + ), + ]; + }) + ); + }, [auctionSlaughterRequestsData]); + + return ( + <> + {auctionSlaughterRequestsData && + Array.isArray(auctionSlaughterRequestsData) && + auctionSlaughterRequestsData.length > 0 && ( + + + + )} + + ); +}; diff --git a/src/features/auction/components/auction-filter-request-advance/AuctionFilterRequestAdvance.js b/src/features/auction/components/auction-filter-request-advance/AuctionFilterRequestAdvance.js new file mode 100644 index 0000000..aadba11 --- /dev/null +++ b/src/features/auction/components/auction-filter-request-advance/AuctionFilterRequestAdvance.js @@ -0,0 +1,221 @@ +import { SPACING } from "../../../../data/spacing"; +import { Grid } from "../../../../components/grid/Grid"; +import { + Button, + FormControl, + FormHelperText, + InputLabel, + MenuItem, + Select, + Slider, +} from "@mui/material"; +import { useState } from "react"; +import { Yup } from "../../../../lib/yup/yup"; +import { useFormik } from "formik"; +import { useDispatch, useSelector } from "react-redux"; +import { PropTypes } from "prop-types"; +import { + auctionFilterByAge, + auctionFilterByPrice, + auctionFilterByQuantity, + auctionFilterByRace, + auctionFilterByWeight, +} from "../../../../lib/redux/slices/auctionSlice"; +import { + DRAWER, + LOADING_END, + LOADING_START, +} from "../../../../lib/redux/slices/appSlice"; +import { useEffect } from "react"; +import { avicultureGetChickenPrice } from "../../../aviculture/services/aviculture-get-chicken-price"; + +export const AuctionFilterRequestAdvance = ({ + minQuantity = 0, + maxQuantity = 1000, +}) => { + const dispatch = useDispatch(); + const { avicultureChickenPrice } = useSelector( + (state) => state.avicultureSlice + ); + + useEffect(() => { + dispatch(LOADING_START()); + dispatch(avicultureGetChickenPrice()); + dispatch(LOADING_END()); + }, []); + + const formik = useFormik({ + initialValues: { + age: "", + race: "همه", + }, + validationSchema: Yup.object({ + age: Yup.number().typeError("لطفا سن مرغ را وارد کنید."), + }), + }); + + const [number, setNumber] = useState([minQuantity || 0, maxQuantity || 1000]); + const [weight, setWeight] = useState([1, 5]); + const [age, setAge] = useState([30, 70]); + const [price, setPrice] = useState([ + avicultureChickenPrice?.floorPrice || 0, + avicultureChickenPrice?.ceilingPrice || 100000, + ]); + + useEffect(() => { + if ( + avicultureChickenPrice?.floorPrice && + avicultureChickenPrice?.ceilingPrice + ) { + setPrice([ + avicultureChickenPrice.floorPrice, + avicultureChickenPrice.ceilingPrice, + ]); + } + }, [avicultureChickenPrice]); + + const handleChangeNumber = (event, newNumber) => { + setNumber(newNumber); + }; + + const handleChangeWeight = (event, newWeight) => { + setWeight(newWeight); + }; + + const handleChangeAge = (event, newAge) => { + setAge(newAge); + }; + + const handleChangePrice = (event, newPrice) => { + setPrice(newPrice); + }; + + return ( + + + + + نژاد مرغ + + + {formik.touched.race && Boolean(formik.errors.race) + ? formik.errors.race + : null} + + + + {number && + Array.isArray(number) && + number[0] !== undefined && + number[0] !== Infinity && + minQuantity !== undefined && + maxQuantity !== undefined ? ( + + تعداد: + "تعداد"} + value={number} + min={minQuantity || 0} + max={maxQuantity || 1000} + step={100} + onChange={handleChangeNumber} + valueLabelDisplay="auto" + /> + + ) : ( + "" + )} + + + سن: + + + + + وزن: + "Temperature range"} + value={weight} + min={1} + max={5} + onChange={handleChangeWeight} + valueLabelDisplay="auto" + /> + + + + قیمت: + "سقف و کف قیمت امروز"} + value={price} + step={5000} + min={avicultureChickenPrice?.floorPrice || 0} + max={avicultureChickenPrice?.ceilingPrice || 100000} + onChange={handleChangePrice} + valueLabelDisplay="auto" + /> + + + + + + + + ); +}; + +AuctionFilterRequestAdvance.propTypes = { + minQuantity: PropTypes.number, + maxQuantity: PropTypes.number, +}; diff --git a/src/features/auction/components/auction-filter-request-date/AuctionFilterRequestDate.js b/src/features/auction/components/auction-filter-request-date/AuctionFilterRequestDate.js new file mode 100644 index 0000000..551470e --- /dev/null +++ b/src/features/auction/components/auction-filter-request-date/AuctionFilterRequestDate.js @@ -0,0 +1,173 @@ +import { SPACING } from "../../../../data/spacing"; +import { Grid } from "../../../../components/grid/Grid"; +import { + Button, + Checkbox, + FormControl, + FormControlLabel, + InputLabel, + ListItemText, + MenuItem, + OutlinedInput, + Radio, + RadioGroup, + Select, + Typography, +} from "@mui/material"; +import { useSelector } from "react-redux"; +import { useEffect, useState } from "react"; +import { format } from "date-fns-jalali"; +import { useDispatch } from "react-redux"; +import { auctionFilterByDate } from "../../../../lib/redux/slices/auctionSlice"; +import { DRAWER } from "../../../../lib/redux/slices/appSlice"; + +export const AuctionFilterRequestDate = () => { + const dispatch = useDispatch(); + + const ITEM_HEIGHT = 48; + const ITEM_PADDING_TOP = 8; + + const { auctions } = useSelector((state) => state.auctionSlice || {}); + const [selectedDates, setSelectedDates] = useState([]); + const [availableDates, setAvailableDates] = useState([]); + const [value, setValue] = useState("all"); + + const handleChangeRadioButton = (event) => { + setValue(event.target.value); + }; + + const handleChange = (event) => { + const { + target: { value }, + } = event; + setSelectedDates( + // On autofill we get a stringified value. + typeof value === "string" ? value.split(",") : value + ); + }; + + const MenuProps = { + PaperProps: { + style: { + maxHeight: ITEM_HEIGHT * 4.5 + ITEM_PADDING_TOP, + width: 250, + }, + }, + }; + + useEffect(() => { + if (auctions && Array.isArray(auctions)) { + const data = auctions + .filter((item) => item?.sendDate) + .map((item) => { + try { + return format(new Date(item.sendDate), "yyyy/MM/dd"); + } catch (error) { + console.error("Error formatting date:", error); + return null; + } + }) + .filter((date) => date !== null); + setAvailableDates(data); + } else { + setAvailableDates([]); + } + }, [auctions]); + + return ( + + + + + + } + label="بدون فیلتر" + /> + } + label="انتخاب تاریخ" + /> + + + + {value === "filter" && ( + <> + + + تاریخ هایی که مایل به رویت مناقصات آنها هستید را انتخاب کنید. + + + + + + تاریخ های انتخاب شده + + + + + + )} + + + + + + + ); +}; diff --git a/src/features/auction/components/auction-filter-request-zone/AuctionFilterRequestZone.js b/src/features/auction/components/auction-filter-request-zone/AuctionFilterRequestZone.js new file mode 100644 index 0000000..def4acd --- /dev/null +++ b/src/features/auction/components/auction-filter-request-zone/AuctionFilterRequestZone.js @@ -0,0 +1,149 @@ +import { SPACING } from "../../../../data/spacing"; +import { Grid } from "../../../../components/grid/Grid"; +import { Autocomplete, Button, TextField } from "@mui/material"; +import { useState } from "react"; +import { + DRAWER, + LOADING_END, + LOADING_START, +} from "../../../../lib/redux/slices/appSlice"; +import { useDispatch } from "react-redux"; +import { cityGetProvinces } from "../../../city/services/CityGetProvinces"; +import { useEffect } from "react"; +import { cityGetCity } from "../../../city/services/city-get-city"; +import { + auctionFilterByCity, + auctionFilterByProvince, +} from "../../../../lib/redux/slices/auctionSlice"; + +export const AuctionFilterRequestZone = () => { + const [provinceData, setProvinceData] = useState(); + const [cityData, setCityData] = useState(); + const [provinceKey, setProvinceKey] = useState(); + + const [selectedProvince, setSelectedProvince] = useState(); + const [selectedCity, setSelectedCity] = useState(); + + const [, setCityKey] = useState(); + const [isExistProvince, setIsExistProvince] = useState(true); + + const dispatch = useDispatch(); + + useEffect(() => { + dispatch(LOADING_START()); + dispatch(cityGetProvinces()) + ?.then((r) => { + if (r?.payload?.data) { + setProvinceData(r.payload.data); + } + }) + .catch((error) => { + console.error("Error fetching provinces:", error); + }) + .finally(() => { + dispatch(LOADING_END()); + }); + }, []); + + useEffect(() => { + if (provinceKey) { + dispatch(LOADING_START()); + dispatch(cityGetCity(provinceKey)) + .then((r) => { + if (r?.payload?.data) { + setCityData(r.payload.data); + setIsExistProvince(false); + } + }) + .catch((error) => { + console.error("Error fetching cities:", error); + }) + .finally(() => { + dispatch(LOADING_END()); + }); + } else { + setCityData([]); + setIsExistProvince(true); + } + }, [provinceKey]); + + return ( + + + + i?.key && i?.name) + .map((i) => ({ id: i.key, label: i.name })) + : [] + } + onChange={(e, value) => { + if (value) { + setProvinceKey(value.id); + setSelectedProvince(value.label); + } else { + setProvinceKey(undefined); + setSelectedProvince(undefined); + } + }} + renderInput={(params) => ( + + )} + /> + + + + i?.key && i?.name) + .map((i) => ({ id: i.key, label: i.name })) + : [] + } + onChange={(e, value) => { + if (value) { + setCityKey(value.id); + setSelectedCity(value.label); + } else { + setCityKey(undefined); + setSelectedCity(undefined); + } + }} + renderInput={(params) => ( + + )} + /> + + + + + + + ); +}; diff --git a/src/features/auction/components/auction-offer-price-form/AuctionOfferPriceForm.js b/src/features/auction/components/auction-offer-price-form/AuctionOfferPriceForm.js new file mode 100644 index 0000000..0b43a2f --- /dev/null +++ b/src/features/auction/components/auction-offer-price-form/AuctionOfferPriceForm.js @@ -0,0 +1,314 @@ +import { SPACING } from "../../../../data/spacing"; +import { Grid } from "../../../../components/grid/Grid"; +import { + Button, + Divider, + InputAdornment, + TextField, + Typography, +} from "@mui/material"; +import { useFormik } from "formik"; +import { Yup } from "../../../../lib/yup/yup"; +import { PropTypes } from "prop-types"; +import { Timer } from "../../../../components/timer/Timer"; +import { + DRAWER, + LOADING_END, + LOADING_START, +} from "../../../../lib/redux/slices/appSlice"; +import { useDispatch } from "react-redux"; +import { AuctionOfferPrice } from "../../services/auction-offer-price"; +import { useContext } from "react"; +import { AppContext } from "../../../../contexts/AppContext"; +import { auctionGetAuctions } from "../../services/auction-get-auctions"; +import { auctionSlaughterRequests } from "../../services/auction-slaughter-requests"; + +export const AuctionOfferPriceForm = ({ + data, + floorPrice, + ceilingPrice, + highestBidedPrice, + auctionRemainedSeconds, +}) => { + const dispatch = useDispatch(); + + const [openNotif] = useContext(AppContext); + + const formik = useFormik({ + initialValues: { + offer: "", + }, + validationSchema: Yup.object({ + offer: Yup.number() + .required("این فیلد اجباری است!") + .typeError("لطفا عدد وارد کنید!"), + }), + }); + + return ( + + + + prop.palette.grey["A700"]} + > + مانده تا پایان مناقصه : + + + + + prop.palette.grey["A700"]} + > + استان : + + + {data?.poultry?.address?.province?.name || ""} + + + + prop.palette.grey["A700"]} + > + شهر : + + + {data?.poultry?.address?.city?.name || ""} + + + + prop.palette.grey["A700"]} + > + مرغدار : + + + {data?.poultry?.userprofile?.fullName || ""} + + + + prop.palette.grey["A700"]} + > + محل پرورش : + + + {data?.poultry?.address?.address || ""} + + + + prop.palette.grey["A700"]} + > + نژاد : + + {data?.chickenBreed || ""} + + + prop.palette.grey["A700"]} + > + تعداد : + + + {data?.quantity || 0} + + قطعه + + + prop.palette.grey["A700"]} + > + سن : + + + {data?.process?.poultry?.age || 0} روز + + + + prop.palette.grey["A700"]} + > + وزن : + + + {data?.IndexWeight || 0} کیلوگرم + + + + + + prop.palette.grey["A700"]} + > + قیمت پایه : + + + {floorPrice || 0} + + ریال + + + + prop.palette.grey["A700"]} + > + بالاترین قیمت پیشنهادی : + + + {highestBidedPrice || "پیشنهادی وجود ندارد!"} + + {highestBidedPrice === "پیشنهادی وجود ندارد!" || !highestBidedPrice + ? "" + : "ریال"} + + + + + ریال + ), + }} + variant="outlined" + sx={{ width: "100%" }} + value={formik.values.offer} + error={formik.touched.offer ? Boolean(formik.errors.offer) : null} + onChange={formik.handleChange} + onBlur={formik.handleBlur} + helperText={ + formik.touched.offer && Boolean(formik.errors.offer) + ? formik.errors.offer + : null + } + /> + + + + + + + ); +}; + +AuctionOfferPriceForm.propTypes = { + data: PropTypes.any, + floorPrice: PropTypes.string, + ceilingPrice: PropTypes.string, + highestBidedPrice: PropTypes.string, + auctionRemainedSeconds: PropTypes.string, +}; diff --git a/src/features/auction/components/auction-operations/AuctionOperations.js b/src/features/auction/components/auction-operations/AuctionOperations.js new file mode 100644 index 0000000..bed4e2d --- /dev/null +++ b/src/features/auction/components/auction-operations/AuctionOperations.js @@ -0,0 +1,21 @@ +import { Grid } from "../../../../components/grid/Grid"; +import { SPACING } from "../../../../data/spacing"; +import { NavLink } from "../../../../components/nav-link/NavLink"; +import { Button } from "@mui/material"; + +export const AuctionOperations = () => { + return ( + + + + + + ); +}; diff --git a/src/features/auction/components/auctions-view/AuctionsView.js b/src/features/auction/components/auctions-view/AuctionsView.js new file mode 100644 index 0000000..a2058cc --- /dev/null +++ b/src/features/auction/components/auctions-view/AuctionsView.js @@ -0,0 +1,314 @@ +import { useEffect, useState } from "react"; +import { useDispatch, useSelector } from "react-redux"; +import { AdvancedTable } from "../../../../components/advanced-table/AdvancedTable"; +import { Grid } from "../../../../components/grid/Grid"; +import { SPACING } from "../../../../data/spacing"; +import { auctionGetAuctions } from "../../services/auction-get-auctions"; +import { Button, ButtonGroup, Typography } from "@mui/material"; +import { AuctionFilterRequestDate } from "../auction-filter-request-date/AuctionFilterRequestDate"; +import { AuctionFilterRequestAdvance } from "../auction-filter-request-advance/AuctionFilterRequestAdvance"; +import { + DRAWER, + LOADING_END, + LOADING_START, +} from "../../../../lib/redux/slices/appSlice"; +import { getAuctionItemForTable } from "../../utils/get-auction-item-for-table"; +import { format } from "date-fns-jalali"; +import { AuctionFilterRequestZone } from "../auction-filter-request-zone/AuctionFilterRequestZone"; +import { + auctionFilterByAge, + auctionFilterByCity, + auctionFilterByDate, + auctionFilterByPrice, + auctionFilterByProvince, + auctionFilterByQuantity, + auctionFilterByRace, + auctionFilterByWeight, +} from "../../../../lib/redux/slices/auctionSlice"; +import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl"; + +export const AuctionsView = () => { + const dispatch = useDispatch(); + const { auctions } = useSelector((state) => state.auctionSlice || {}); + const { filterByDate } = useSelector((state) => state.auctionSlice || {}); + const { filterByCity } = useSelector((state) => state.auctionSlice || {}); + const { filterByProvince } = useSelector((state) => state.auctionSlice || {}); + const { + filterByQuantity, + filterByAge, + filterByRace, + filterByWeight, + filterByPrice, + } = useSelector((state) => state.auctionSlice || {}); + const [tableRows, setTableRows] = useState([]); + const [minQuantity, setMinQuantity] = useState(0); + const [maxQuantity, setMaxQuantity] = useState(0); + + // useEffect(() => { + // setInterval(() => { + // dispatch(auctionGetAuctions()); + // }, 60000); + // }, []); + + useEffect(() => { + dispatch(auctionGetAuctions()); + }, [ + filterByDate, + filterByCity, + filterByQuantity, + filterByPrice, + filterByWeight, + filterByAge, + filterByRace, + ]); + useEffect(() => { + if (auctions && Array.isArray(auctions) && auctions.length > 0) { + const quantities = auctions + .map((object) => object?.quantity) + .filter((qty) => qty !== undefined && qty !== null); + if (quantities.length > 0) { + setMinQuantity(Math.min(...quantities)); + setMaxQuantity(Math.max(...quantities)); + } + } + }, [auctions]); + + useEffect(() => { + if (auctions && Array.isArray(auctions)) { + let data = []; + const dateFilterCallback = (item) => { + if (!filterByDate || !Array.isArray(filterByDate)) { + return true; + } + if (!item?.sendDate) { + return false; + } + try { + const formattedDate = format(new Date(item.sendDate), "yyyy/MM/dd"); + return filterByDate.includes(formattedDate); + } catch (error) { + console.error("Error formatting date:", error); + return false; + } + }; + const provinceCityFilterCallback = (item) => { + if (filterByCity || filterByProvince) { + if (filterByCity) { + return item?.process?.city?.cityOperatorCity === filterByCity; + } else if (filterByProvince) { + return ( + item?.process?.city?.cityOperatorProvince === filterByProvince + ); + } + } + return true; + }; + const advanceFilterCallback = (item) => { + if (filterByRace) { + return item?.chickenBreed === filterByRace; + } + if (filterByQuantity && Array.isArray(filterByQuantity)) { + const quantity = item?.quantity; + if (quantity === undefined || quantity === null) { + return false; + } + return ( + quantity >= (filterByQuantity[0] || 0) && + quantity <= (filterByQuantity[1] || Infinity) + ); + } + if (filterByPrice && Array.isArray(filterByPrice)) { + if (item?.process?.killHouseAuctionsList) { + const auctionsList = item.process.killHouseAuctionsList; + if (Array.isArray(auctionsList) && auctionsList.length > 0) { + const lastAuction = auctionsList[auctionsList.length - 1]; + const fee = lastAuction?.fee; + if (fee === undefined || fee === null) { + return false; + } + return ( + fee >= (filterByPrice[0] || 0) && + fee <= (filterByPrice[1] || Infinity) + ); + } + } + return false; + } + if (filterByWeight && Array.isArray(filterByWeight)) { + const weight = item?.IndexWeight; + if (weight === undefined || weight === null) { + return false; + } + return ( + weight >= (filterByWeight[0] || 0) && + weight <= (filterByWeight[1] || Infinity) + ); + } + if (filterByAge !== undefined && filterByAge !== null) { + const age = item?.process?.poultry?.age; + if (age === undefined || age === null) { + return false; + } + return age <= filterByAge; + } + return true; + }; + if ( + filterByDate || + filterByCity || + filterByProvince || + filterByQuantity || + filterByPrice || + filterByWeight || + filterByAge !== undefined || + filterByRace + ) { + data = auctions + .filter(dateFilterCallback) + .filter(provinceCityFilterCallback) + .filter(advanceFilterCallback) + .map((item, i) => { + return getAuctionItemForTable(item, i, dispatch); + }); + } else { + data = auctions.map((item, i) => { + return getAuctionItemForTable(item, i, dispatch); + }); + } + setTableRows(data); + } else { + setTableRows([]); + } + }, [ + auctions, + filterByDate, + filterByCity, + filterByProvince, + filterByQuantity, + filterByPrice, + filterByWeight, + filterByAge, + filterByRace, + dispatch, + ]); + + const columns = + getRoleFromUrl() === "KillHouse" + ? [ + "شماره مزایده", + "کدسفارش", + // "فروشنده", + "قیمت کف", + "قیمت سقف", + "بالاترین قیمت پیشنهادی", + "تعداد", + "تاریخ درخواست کشتار", + "نژاد و سن به روز", + "وزن", + "استان", + "شهرستان", + "زمان تا پایان", + "عملیات", + ] + : [ + "شماره مزایده", + "کدسفارش", + // "فروشنده", + "قیمت کف", + "قیمت سقف", + + "بالاترین قیمت پیشنهادی", + "تعداد", + "تاریخ درخواست کشتار", + "نژاد و سن به روز", + "وزن", + "استان", + "شهرستان", + "زمان تا پایان", + ]; + + return ( + + + + prop.palette.grey["A700"]}> + فیلتر کردن مزایده ها + + + + + + + + + + + + + + ); +}; diff --git a/src/features/auction/services/auction-get-auctions.js b/src/features/auction/services/auction-get-auctions.js new file mode 100644 index 0000000..b368cdc --- /dev/null +++ b/src/features/auction/services/auction-get-auctions.js @@ -0,0 +1,13 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const auctionGetAuctions = createAsyncThunk( + "AUCTION_GET_AUCTIONS", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + const { data, status } = await axios.get(`Poultry_Request/?type=auction`); + dispatch(LOADING_END()); + return { data, status }; + } +); diff --git a/src/features/auction/services/auction-offer-price.js b/src/features/auction/services/auction-offer-price.js new file mode 100644 index 0000000..ccc7320 --- /dev/null +++ b/src/features/auction/services/auction-offer-price.js @@ -0,0 +1,16 @@ +// { +// "key":"3175f8ee-ec0d-4865-b568-b0ab7880151c", +// "fee":"620000" + +// } + +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; + +export const AuctionOfferPrice = createAsyncThunk( + "AuctionOfferPrice", + async (d) => { + const { data, status } = await axios.post("kill_house_Request_auction/", d); + return { data, status }; + } +); diff --git a/src/features/auction/services/auction-slaughter-requests.js b/src/features/auction/services/auction-slaughter-requests.js new file mode 100644 index 0000000..bc0f300 --- /dev/null +++ b/src/features/auction/services/auction-slaughter-requests.js @@ -0,0 +1,13 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const auctionSlaughterRequests = createAsyncThunk( + "AUCTION_SLAUGHTER_REQUESTS", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + const { data, status } = await axios.get(`kill_house_Request_auction/`); + dispatch(LOADING_END()); + return { data, status }; + } +); diff --git a/src/features/auction/utils/get-auction-item-for-table.js b/src/features/auction/utils/get-auction-item-for-table.js new file mode 100644 index 0000000..5373c12 --- /dev/null +++ b/src/features/auction/utils/get-auction-item-for-table.js @@ -0,0 +1,64 @@ +import { Button } from "@mui/material"; +import moment from "moment"; +import { Timer } from "../../../components/timer/Timer"; +import GavelIcon from "@mui/icons-material/Gavel"; +import { AuctionOfferPriceForm } from "../components/auction-offer-price-form/AuctionOfferPriceForm"; +import { DRAWER } from "../../../lib/redux/slices/appSlice"; +import { getRoleFromUrl } from "../../../utils/getRoleFromUrl"; + +export function getAuctionItemForTable(item, i, dispatch) { + const auctionFinishDate = moment( + new Date(item?.process?.auctionsList[0]?.date) + ); + const currentDate = moment(); + const diff = auctionFinishDate.diff(currentDate); + const auctionRemainedSeconds = moment.duration(diff).asSeconds(); + const highestBidedPrice = item.process?.killHouseAuctionsList + ? item?.process?.killHouseAuctionsList[ + item?.process?.killHouseAuctionsList.length - 1 + ].fee + : "پیشنهادی وجود ندارد!"; + + return [ + item.id, + item.orderCode, + // item?.process?.provinceRequestAuctionList ? "استان" : "مرغدار", + item?.process?.auctionsList[0]?.floorPrice, + item?.process?.auctionsList[0]?.ceilingPrice, + highestBidedPrice, + item.quantity, + item.sendDate, + item.chickenBreed + " - " + item?.process?.poultry?.age, + item.IndexWeight, + item?.process?.city.cityOperatorProvince, + item?.process?.city.cityOperatorCity, + , + getRoleFromUrl() === "KillHouse" && ( + + ), + ]; +} diff --git a/src/features/authentication/components/auth-privacy-text/AuthProvacyText.js b/src/features/authentication/components/auth-privacy-text/AuthProvacyText.js new file mode 100644 index 0000000..d9b8e46 --- /dev/null +++ b/src/features/authentication/components/auth-privacy-text/AuthProvacyText.js @@ -0,0 +1,118 @@ +import React from "react"; +import { Grid, Divider } from "@mui/material"; +import { Typography } from "@mui/material"; +import { PrivacyTip, Security, Info } from "@mui/icons-material"; // Import icons + +export const AuthPrivacyText = () => { + return ( + + + + + + بيانيه حريم خصوصی + + + اطلاعات مربوط به هر شخص، حریم خصوصی وی محسوب می‌شود. حفاظت و حراست + از اطلاعات شخصی در سامانه رصد یار، نه تنها موجب حفظ امنیت کاربران + می‌شود، بلکه باعث اعتماد بیشتر و مشارکت آنها در فعالیت‌های جاری + می‌گردد. هدف از این بیانیه، آگاه ساختن شما درباره ی نوع و نحوه ی + استفاده از اطلاعاتی است که در هنگام استفاده از سامانه رصد یار ، از + جانب شما دریافت می‌گردد. شرکت هوشمند سازان خود را ملزم به رعایت حریم + خصوصی همه شهروندان و کاربران سامانه دانسته و آن دسته از اطلاعات + کاربران را که فقط به منظور ارائه خدمات کفایت می‌کند، دریافت کرده و + از انتشار آن یا در اختیار قرار دادن آن به دیگران خودداری مینماید. + + + + + + + + + + + چگونگی جمع آوری و استفاده از اطلاعات کاربران: + + + الف: اطلاعاتی که شما خود در اختيار این سامانه قرار + می‌دهيد، شامل موارد زيرهستند: + + + اقلام اطلاعاتی شامل شماره تلفن همراه، تاریخ تولد، کد پستی و کد ملی + کاربران را دریافت مینماییم که از این اقلام، صرفا جهت احراز هویت + کاربران استفاده خواهد شد. + + + + ب: برخی اطلاعات ديگر که به صورت خودکار از شما + دريافت میشود شامل موارد زير می‌باشد: + + + ⦁ دستگاهی که از طریق آن سامانه رصد یار را مشاهده می‌نمایید( تلفن + همراه، تبلت، رایانه).
    + ⦁ نام و نسخه سیستم عامل و browser کامپیوتر شما.
    + ⦁ اطلاعات صفحات بازدید شده.
    + ⦁ تعداد بازدیدهای روزانه در درگاه.
    ⦁ هدف ما از دریافت این + اطلاعات استفاده از آنها در تحلیل عملکرد کاربران درگاه می باشد تا + بتوانیم در خدمت رسانی بهتر عمل کنیم. +
    +
    + + + + + + + + + امنیت اطلاعات + + + متعهدیم که امنیت اطلاعات شما را تضمین نماییم و برای جلوگیری از هر + نوع دسترسی غیرمجاز و افشای اطلاعات شما از همه شیوه‌‌های لازم استفاده + می‌کنیم تا امنیت اطلاعاتی را که به صورت آنلاین گردآوری می‌کنیم، حفظ + شود. لازم به ذکر است در سامانه ما، ممکن است به سایت های دیگری لینک + شوید، وقتی که شما از طریق این لینک‌ها از سامانه ما خارج می‌شوید، + توجه داشته باشید که ما بر دیگر سایت ها کنترل نداریم و سازمان تعهدی + بر حفظ حریم شخصی آنان در سایت مقصد نخواهد داشت و مراجعه کنندگان + میبایست به بیانیه حریم شخصی آن سایت ها مراجعه نمایند. + + +
    +
    + ); +}; diff --git a/src/features/authentication/components/basic-profile-information/BasicProfileInformation.js b/src/features/authentication/components/basic-profile-information/BasicProfileInformation.js new file mode 100644 index 0000000..5931e15 --- /dev/null +++ b/src/features/authentication/components/basic-profile-information/BasicProfileInformation.js @@ -0,0 +1,519 @@ +import React, { useContext, useEffect, useState } from "react"; +import { + Typography, + Box, + Paper, + Divider, + IconButton, + Grid, + useTheme, + Button, + TextField, + Autocomplete, +} from "@mui/material"; +import EditIcon from "@mui/icons-material/Edit"; +import PersonIcon from "@mui/icons-material/Person"; +import PhoneIcon from "@mui/icons-material/Phone"; +import BadgeIcon from "@mui/icons-material/Badge"; +import CakeIcon from "@mui/icons-material/Cake"; +import LocationCityIcon from "@mui/icons-material/LocationCity"; +import LockIcon from "@mui/icons-material/Lock"; +import { useDispatch, useSelector } from "react-redux"; +import { + DRAWER, + LOADING_END, + LOADING_START, +} from "../../../../lib/redux/slices/appSlice"; +import { formatJustDate } from "../../../../utils/formatTime"; +import { getUserProfile } from "../../services/getUserProfile"; +import { ChangeProfile } from "../change-profile/ChangeProfile"; +import { motion } from "framer-motion"; +import { ChangePasswordForm } from "../change-password-form/ChangePasswordForm"; +import { useFormik } from "formik"; +import { Yup } from "../../../../lib/yup/yup"; +import { changeProfileFactorInfo } from "../../services/changeProfileInfo"; +import { AppContext } from "../../../../contexts/AppContext"; +import { + slaughterGetCitiesService, + slaughterGetProvinceService, +} from "../../../slaughter-house/services/slaughter-get-provinces"; + +const fadeInVariant = { + hidden: { opacity: 0, y: 20 }, + visible: { opacity: 1, y: 0, transition: { duration: 0.5 } }, +}; + +export const BasicProfileInformation = () => { + const { userProfile } = useSelector((state) => state.userSlice); + const dispatch = useDispatch(); + const theme = useTheme(); + const [provinceData, setProvinceData] = useState([]); + const [cityData, setCityData] = useState([]); + const [openNotif] = useContext(AppContext); + + const getProfile = () => { + dispatch(getUserProfile()); + }; + + useEffect(() => { + getProfile(); + }, [dispatch]); + + const validationSchema = Yup.object({ + nationalId: Yup.string().required("شناسه ملی الزامی است"), + registrationNumber: Yup.string().required("شماره ثبت الزامی است"), + economicalCode: Yup.string().required("کد اقتصادی الزامی است"), + address: Yup.string().required("نشانی الزامی است"), + unitName: Yup.string().required("نام واحد الزامی است"), + postalCode: Yup.string() + .matches(/^[0-9]{10}$/, "کد پستی باید 10 رقم باشد") + .required("کد پستی الزامی است"), + province: Yup.string() + .required("این فیلد اجباری است!") + .typeError("لطفا فیلد را به درستی وارد کنید!"), + city: Yup.string() + .required("این فیلد اجباری است!") + .typeError("لطفا فیلد را به درستی وارد کنید!"), + }); + + const formik = useFormik({ + initialValues: { + nationalId: userProfile?.unitNationalId || "", + registrationNumber: userProfile?.unitRegistrationNumber || "", + address: userProfile?.unitAddress || "", + postalCode: userProfile?.unitPostalCode || "", + economicalCode: userProfile?.unitEconomicalNumber || "", + unitName: userProfile?.unitName || "", + province: userProfile?.unitProvince || "", + city: userProfile?.unitCity || "", + }, + validationSchema, + onSubmit: (values) => { + dispatch(LOADING_START()); + dispatch( + changeProfileFactorInfo({ + userprofile_key: userProfile?.key, + unit_name: values.unitName, + unit_national_id: values.nationalId, + unit_registration_number: values.registrationNumber, + unit_province: values.province, + unit_city: values.city, + unit_postal_code: values.postalCode, + unit_address: values.address, + unit_economical_number: values.economicalCode, + }) + ).then((r) => { + if (r.error) { + openNotif({ + vertical: "top", + horizontal: "center", + msg: "مشکلی پیش آمده است!", + severity: "error", + }); + } else { + dispatch(getUserProfile()); + dispatch(LOADING_END()); + + openNotif({ + vertical: "top", + horizontal: "center", + msg: "عملیات با موفقیت انجام شد.", + severity: "success", + }); + } + dispatch(LOADING_END()); + }); + }, + }); + + useEffect(() => { + dispatch(slaughterGetProvinceService()).then((r) => { + setProvinceData(r.payload.data); + }); + }, []); + + useEffect(() => { + if (formik.values.province) { + setCityData( + [], + dispatch(slaughterGetCitiesService(formik.values.province)).then( + (r) => { + setCityData(r.payload.data); + } + ) + ); + } + }, [formik.values.province]); + + useEffect(() => { + formik.validateForm(); + }, [dispatch, userProfile]); + + const userData = [ + { + icon: , + label: "نام و نام خانوادگی", + value: userProfile?.fullname || "نامشخص", + }, + { + icon: , + label: "موبایل", + value: userProfile?.mobile || "نامشخص", + }, + { + icon: , + label: "کدملی", + value: userProfile?.nationalId || "نامشخص", + }, + { + icon: , + label: "شماره شناسنامه", + value: userProfile?.nationalCode || "نامشخص", + }, + { + icon: , + label: "تاریخ تولد", + value: userProfile?.birthday + ? formatJustDate(userProfile?.birthday) + : "نامشخص", + }, + { + icon: , + label: "استان", + value: userProfile?.province || "نامشخص", + }, + { + icon: , + label: "شهر", + value: userProfile?.city || "نامشخص", + }, + ]; + + return ( + + + + + + + + اطلاعات کاربری + + + { + dispatch( + DRAWER({ + right: !(window.innerWidth <= 600), + bottom: window.innerWidth <= 600, + content: , + title: "ویرایش اطلاعات کاربری", + }) + ); + }} + > + + + + + + {userData.map((item, index) => ( + + + {item.icon} + + + {item.label} + + + {item.value} + + + + + ))} + + + + + {(userProfile?.role?.includes("ProvinceOperator") || + userProfile?.role?.includes("KillHouse")) && ( + <> + + + + + اطلاعات صدور فاکتور + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + ({ + id: i.name, + label: i.name, + })) + : [] + } + onChange={(e, value) => { + formik.setFieldValue("province", value ? value.id : ""); + formik.setFieldValue("city", ""); + }} + renderInput={(params) => ( + + )} + /> + + + + ({ id: i.name, label: i.name })) + : [] + } + onChange={(e, value) => { + formik.setFieldValue("city", value ? value.id : ""); + }} + renderInput={(params) => ( + + )} + /> + + + + + + +
    + + )} + + + + + + تغییر رمز عبور + + + { + dispatch( + DRAWER({ + right: !(window.innerWidth <= 600), + bottom: window.innerWidth <= 600, + title: "تغییر رمز عبور", + content: , + }) + ); + }} + > + + + +
    +
    +
    + ); +}; diff --git a/src/features/authentication/components/change-bank-form/ChangeBankForm.js b/src/features/authentication/components/change-bank-form/ChangeBankForm.js new file mode 100644 index 0000000..180e2e3 --- /dev/null +++ b/src/features/authentication/components/change-bank-form/ChangeBankForm.js @@ -0,0 +1,296 @@ +import { + Button, + FormControl, + InputAdornment, + InputLabel, + MenuItem, + Select, + TextField, +} from "@mui/material"; +import { useFormik } from "formik"; +import { Grid } from "../../../../components/grid/Grid"; +import { SPACING } from "../../../../data/spacing"; +import { Yup } from "../../../../lib/yup/yup"; +import SaveIcon from "@mui/icons-material/Save"; +import { PropTypes } from "prop-types"; +import { changeBankForm } from "../../services/change-bank-form"; +import { useDispatch } from "react-redux"; +import { + DRAWER, + LOADING_END, + LOADING_START, +} from "../../../../lib/redux/slices/appSlice"; +import { useContext } from "react"; +import { AppContext } from "../../../../contexts/AppContext"; +import { updateBankForm } from "../../services/update-bank-form"; +import { avicultureGetProfile } from "../../../aviculture/services/aviculture-get-profile"; +import { slaughterGetProfile } from "../../../slaughter-house/services/slaughter-get-profile"; +import { provinceGetProfile } from "../../../province/services/province-get-profile"; +import { cityGetProfile } from "../../../city/services/city-get-profile"; +import { slaughterHouseVetGetProfile } from "../../../slaughter-house-vet/services/slaughter-house-vet-get-profile"; +import { vatFarmGetProfile } from "../../../vet-farm/services/vet-farm-get-profile"; + +export const ChangeBankForm = ({ item }) => { + const [openNotif] = useContext(AppContext); + const dispatch = useDispatch(); + const formik = useFormik({ + initialValues: { + bankName: item?.userBankInfo?.bankName, + cardNumber: item?.userBankInfo?.card, + accountNumber: item?.userBankInfo?.account, + shabaNumber: item?.userBankInfo?.shaba, + accountHolder: item?.userBankInfo?.nameOfBankUser, + }, + validationSchema: Yup.object({ + cardNumber: Yup.number() + .required("این فیلد اجباری است!") + .typeError("لطفا شماره کارتتان را وارد کنید!"), + accountNumber: Yup.number() + .required("این فیلد اجباری است!") + .typeError("لطفا شماره حسابتان را وارد کنید!"), + shabaNumber: Yup.number() + .required("این فیلد اجباری است!") + .typeError("لطفا شماره شبا را وارد کنید!"), + accountHolder: Yup.string() + .required("این فیلد اجباری است!") + .typeError("لطفا نام صاحب حساب را وارد کنید!"), + }), + }); + + return ( + + + + + بانک + + + + + + + + + + + + + IR, + }} + onChange={formik.handleChange} + onBlur={formik.handleBlur} + helperText={ + formik.touched.shabaNumber && Boolean(formik.errors.shabaNumber) + ? formik.errors.shabaNumber + : null + } + autoComplete="current-password" + variant="outlined" + /> + + + + + + + + + + ); +}; + +ChangeBankForm.propTypes = { + item: PropTypes.object, +}; diff --git a/src/features/authentication/components/change-card-info/ChangeCardInfo.js b/src/features/authentication/components/change-card-info/ChangeCardInfo.js new file mode 100644 index 0000000..09c3cbc --- /dev/null +++ b/src/features/authentication/components/change-card-info/ChangeCardInfo.js @@ -0,0 +1,67 @@ +import { Button, Chip, Divider, Typography } from "@mui/material"; +import { Grid } from "../../../../components/grid/Grid"; +import { useDispatch } from "react-redux"; +import { DRAWER } from "../../../../lib/redux/slices/appSlice"; +import { ChangeBankForm } from "../change-bank-form/ChangeBankForm"; +import { SimpleTable } from "../../../../components/simple-table/SimpleTable"; +import { SPACING } from "../../../../data/spacing"; +import { PropTypes } from "prop-types"; + +export const ChangeCardInfo = ({ item }) => { + const dispatch = useDispatch(); + return ( + + + + + اطلاعات بانکی + + + } + /> +
    + + + + + + ); +}; + +ChangeCardInfo.propTypes = { + item: PropTypes.object, +}; diff --git a/src/features/authentication/components/change-password-form/ChangePasswordForm.js b/src/features/authentication/components/change-password-form/ChangePasswordForm.js new file mode 100644 index 0000000..9a2a72d --- /dev/null +++ b/src/features/authentication/components/change-password-form/ChangePasswordForm.js @@ -0,0 +1,154 @@ +import { Button, TextField } from "@mui/material"; +import { useFormik } from "formik"; +import { Grid } from "../../../../components/grid/Grid"; +import { SPACING } from "../../../../data/spacing"; +import { Yup } from "../../../../lib/yup/yup"; +import SaveIcon from "@mui/icons-material/Save"; +import { changePassword } from "../../services/login"; +import { useDispatch, useSelector } from "react-redux"; +import { useContext } from "react"; +import { AppContext } from "../../../../contexts/AppContext"; +import { DRAWER } from "../../../../lib/redux/slices/appSlice"; + +export const ChangePasswordForm = () => { + const [openNotif] = useContext(AppContext); + const { userProfile } = useSelector((state) => state.userSlice); + const dispatch = useDispatch(); + const formik = useFormik({ + initialValues: { + lastPassword: "", + newPassword: "", + renewPassword: "", + }, + validationSchema: Yup.object({ + lastPassword: Yup.string() + .required("این فیلد اجباری است!") + .typeError("لطفا رمز را وارد کنید!"), + newPassword: Yup.string() + .required("این فیلد اجباری است!") + .typeError("لطفا رمز را وارد کنید!"), + renewPassword: Yup.string() + .required("این فیلد اجباری است!") + .typeError("لطفا رمز را وارد کنید!"), + }), + }); + return ( + + + + + + + + + + + + + + + + + ); +}; diff --git a/src/features/authentication/components/change-password/ChangePassword.js b/src/features/authentication/components/change-password/ChangePassword.js new file mode 100644 index 0000000..206f093 --- /dev/null +++ b/src/features/authentication/components/change-password/ChangePassword.js @@ -0,0 +1,64 @@ +import React from "react"; +import { Button, Typography, Box, Paper } from "@mui/material"; +import { useDispatch } from "react-redux"; +import { DRAWER } from "../../../../lib/redux/slices/appSlice"; +import { ChangePasswordForm } from "../change-password-form/ChangePasswordForm"; +import { SPACING } from "../../../../data/spacing"; +import { motion } from "framer-motion"; + +const fadeInVariant = { + hidden: { opacity: 0, y: 20 }, + visible: { opacity: 1, y: 0, transition: { duration: 0.5 } }, +}; + +export const ChangePassword = () => { + const dispatch = useDispatch(); + + return ( + + + + + + تغییر رمز عبور + + + + + + + ); +}; diff --git a/src/features/authentication/components/change-profile/ChangeProfile.js b/src/features/authentication/components/change-profile/ChangeProfile.js new file mode 100644 index 0000000..01c242c --- /dev/null +++ b/src/features/authentication/components/change-profile/ChangeProfile.js @@ -0,0 +1,266 @@ +import { Button, TextField } from "@mui/material"; +import { Grid } from "../../../../components/grid/Grid"; +import { SPACING } from "../../../../data/spacing"; +import React, { useEffect } from "react"; +import { Yup } from "../../../../lib/yup/yup"; +import { useFormik } from "formik"; +import { PropTypes } from "prop-types"; + +import { + DRAWER, + LOADING_END, + LOADING_START, +} from "../../../../lib/redux/slices/appSlice"; +import { changeProfileInfo } from "../../services/changeProfileInfo"; +import { useDispatch } from "react-redux"; +import moment from "moment"; +import { DatePicker } from "@mui/x-date-pickers"; +import { ImageUpload } from "../../../../components/image-upload/ImageUpload"; +import { fixBase64 } from "../../../../utils/toBase64"; +import { useContext } from "react"; +import { AppContext } from "../../../../contexts/AppContext"; +import { getUserProfile } from "../../services/getUserProfile"; + +export const ChangeProfile = ({ user }) => { + const [profileImages, setProfileImages] = React.useState([]); + const [profileImg, setProfileImg] = React.useState(); + const [openNotif] = useContext(AppContext); + + const factorPaymentHandler = (imageList) => { + if (imageList[0]) { + setProfileImg(fixBase64(imageList[0]?.data_url)); + } + setProfileImages(imageList); + }; + + const dispatch = useDispatch(); + + const formik = useFormik({ + initialValues: { + firstname: user.firstName ? user.firstName : "", + lastname: user.lastName ? user.lastName : "", + natioanlId: user.nationalId ? user.nationalId : "", + natioanlCode: user.nationalCode ? user.nationalCode : "", + birthday: user.birthday ? new Date(user.birthday) : Date(), + }, + validationSchema: Yup.object({ + firstname: Yup.string().typeError("لطفا فیلد را به درستی وارد کنید.!"), + lastname: Yup.string().typeError("لطفا فیلد را به درستی وارد کنید.!"), + natioanlId: Yup.number().typeError( + "لطفا فیلد را به صورت عددی وارد کنید!" + ), + natioanlCode: Yup.number().typeError( + "لطفا فیلد را به صورت عددی وارد کنید!" + ), + }), + }); + + useEffect(() => { + formik.validateForm(); + }, []); + + return ( + + + + + + + + + + + + + + + + + + + + } + value={formik.values.birthday} + error={ + formik.touched.birthday ? Boolean(formik.errors.birthday) : null + } + onChange={(e) => { + const selectedDate = new Date(e); + // moment(e).format("YYYY-MM-DD hh:mm:ss") + formik.setFieldValue("birthday", selectedDate); + }} + onBlur={formik.handleBlur} + helperText={ + formik.touched.birthday && Boolean(formik.errors.birthday) + ? formik.errors.birthday + : null + } + /> + + + + + + + + + + ); +}; + +ChangeProfile.propTypes = { + user: PropTypes.any, +}; diff --git a/src/features/authentication/components/enter-password/EnterPassword.js b/src/features/authentication/components/enter-password/EnterPassword.js new file mode 100644 index 0000000..8daa7fd --- /dev/null +++ b/src/features/authentication/components/enter-password/EnterPassword.js @@ -0,0 +1,507 @@ +import { + Button, + IconButton, + InputAdornment, + TextField, + Typography, +} from "@mui/material"; +import { useFormik } from "formik"; +import { useDispatch } from "react-redux"; +import { Grid } from "../../../../components/grid/Grid"; +import { SPACING } from "../../../../data/spacing"; +import { + forgetPassword, + forgetPasswordChangePassword, + forgetPasswordSendOpt, + loginWithPassword, +} from "../../services/login"; +import { PropTypes } from "prop-types"; +import { Yup } from "../../../../lib/yup/yup"; +import { useContext, useEffect } from "react"; +import { + CLOSE_MODAL, + LOADING_END, + LOADING_START, + OPEN_MODAL, +} from "../../../../lib/redux/slices/appSlice"; +import { useState } from "react"; +import Visibility from "@mui/icons-material/Visibility"; +import VisibilityOff from "@mui/icons-material/VisibilityOff"; +import { AppContext } from "../../../../contexts/AppContext"; +import { slaughterGetPermisionState } from "../../../slaughter-house/services/slaughter-get-permision"; +import { getUserAnnouncement } from "../../services/get-announcement"; +import { getUserMovingTextsService } from "../../services/getUserMovingTexts"; + +const modalContentStyle = { + backgroundColor: "#ffffff", + padding: "20px", + borderRadius: "4px", + outline: "none", + minWidth: "300px", + maxWidth: "600px", + textAlign: "center", +}; + +const descriptionStyle = { + marginBottom: "10px", +}; + +const buttonStyle = { + marginTop: "10px", +}; + +export const EnterPassword = ({ mobile, isUserHandler }) => { + const dispatch = useDispatch(); + const [openNotif] = useContext(AppContext); + const formikMain = useFormik({ + initialValues: { + password: "", + }, + validationSchema: Yup.object({ + password: Yup.mixed().required("این فیلد اجباری است!"), + }), + }); + + const getUserMovingTexts = () => { + dispatch(getUserMovingTextsService()); + }; + + const getSlaughterState = (role) => { + dispatch(slaughterGetPermisionState()); + dispatch(getUserAnnouncement(role)).then((r) => { + if (r.payload.data?.active) { + dispatch( + OPEN_MODAL({ + title: "اطلاعیه سیستم", + content: ( + + + {r.payload.data?.description} + + + + + + + + ), + }) + ); + } + }); + }; + + const formik = useFormik({ + initialValues: { + forgetOtp: "", + newPassword: "", + newPasswordRepeat: "", + }, + validationSchema: Yup.object({ + forgetOtp: Yup.mixed().required("این فیلد اجباری است!"), + newPassword: Yup.mixed().required("این فیلد اجباری است!"), + newPasswordRepeat: Yup.mixed().required("این فیلد اجباری است!"), + }), + }); + + const [showPassword, setShowPassword] = useState(false); + const [forgetPasswordKey, setForgetPasswordKey] = useState(null); + const [isForgetOtpCodeCorrect, setIsForgetOtpCodeCorrect] = useState(false); + + const handleClickShowPassword = () => { + setShowPassword(!showPassword); + }; + + const handleMouseDownPassword = (event) => { + event.preventDefault(); + }; + + useEffect(() => { + formik.validateForm(); + formikMain.validateForm(); + }, []); + + return ( + <> + {forgetPasswordKey ? ( + <> + {isForgetOtpCodeCorrect ? ( + + + رمزعبور جدید خود را وارد کنید. + + + + + {showPassword ? : } + + + ), + }} + /> + + + {showPassword ? : } + + + ), + }} + /> + + + + + + + + ) : ( + + + کد یکبارمصرف دریافتی را وارد کنید. + + + + {showPassword ? : } + + + ), + }} + /> + + + + + + + )} + + ) : ( + <> + + رمز عبور را وارد کرده و بر روی ورود کلیک نمایید. + + { + if (e.key === "Enter") { + dispatch(LOADING_START()); + dispatch( + loginWithPassword({ + mobile, + password: formikMain.values.password, + }) + ).then((r) => { + if ( + r.payload?.data?.role?.includes("CityOperator") || + r.payload?.data?.role?.includes("KillHouse") || + r.payload?.data?.role?.includes("CityJahad") || + r.payload?.data?.role?.includes("ProvinceSupervisor") || + r.payload?.data?.role?.includes("ProvinceOperator") + ) { + getUserMovingTexts(); + } + + if (r.payload?.data?.role?.includes("KillHouse")) { + getSlaughterState("KillHouse"); + } else if (r.payload?.data?.role?.includes("CityOperator")) { + getSlaughterState("CityOperator"); + } + if (r.error) { + openNotif({ + vertical: "top", + horizontal: "center", + msg: "رمزعبور اشتباه است!", + severity: "error", + }); + } + dispatch(LOADING_END()); + }); + } + }} + error={ + formikMain.touched.password + ? Boolean(formikMain.errors.password) + : null + } + helperText={ + formikMain.touched.password && Boolean(formikMain.errors.password) + ? formikMain.errors.password + : null + } + fullWidth + InputProps={{ + endAdornment: ( + + + {showPassword ? : } + + + ), + }} + /> + + + + + + + + + + + + + + + + )} + + ); +}; + +EnterPassword.propTypes = { + mobile: PropTypes.any, + isUserHandler: PropTypes.any, +}; diff --git a/src/features/authentication/components/general-dashboard-operations/GeneralDashboardOperations.js b/src/features/authentication/components/general-dashboard-operations/GeneralDashboardOperations.js new file mode 100644 index 0000000..4f2895b --- /dev/null +++ b/src/features/authentication/components/general-dashboard-operations/GeneralDashboardOperations.js @@ -0,0 +1,190 @@ +import { Box, Button, Chip, Divider, Typography } from "@mui/material"; +import { SPACING } from "../../../../data/spacing"; +import { NavLink } from "../../../../components/nav-link/NavLink"; +import { useLocation } from "react-router-dom"; +import { + Home, + Business, + House, + LocalHospital, + DirectionsCar, + AccountBalance, + Public, +} from "@mui/icons-material"; // Example icons +import { motion } from "framer-motion"; +import useUserProfile from "../../hooks/useUserProfile"; +import { + DRIVER_USER_PROFILE, + ROUTE_AVICULTURE_USER_PROFILE, + ROUTE_CHAIN_COMPANY_USER_PROFILE, + ROUTE_CITYVET_USER_PROFILE, + ROUTE_CITY_USER_PROFILE, + ROUTE_GENERAL_USER_PROFILE, + ROUTE_STEWARD_USER_PROFILE, + ROUTE_INSPECTOR_USER_PROFILE, + ROUTE_LIVE_STOCK_USER_PROFILE, + ROUTE_PROVINCE_FINANCIAL_USER_PROFILE, + ROUTE_PROVINCE_USER_PROFILE, + ROUTE_SLAUGHTER_HOUSE_VET_USER_PROFILE, + ROUTE_SLAUGHTER_USER_PROFILE, + ROUTE_VETFARM_USER_PROFILE, +} from "../../../../routes/routes"; +import { Grid } from "../../../../components/grid/Grid"; + +const routesMap = { + General: { + path: ROUTE_GENERAL_USER_PROFILE, + label: "کاربری", + icon: , + }, + CityOperator: { + path: ROUTE_CITY_USER_PROFILE, + label: "شهرستان", + icon: , + }, + Poultry: { + path: ROUTE_AVICULTURE_USER_PROFILE, + label: "مرغداری", + icon: , + }, + ProvinceOperator: { + path: ROUTE_PROVINCE_USER_PROFILE, + label: "تخصیص استان", + icon: , + }, + KillHouse: { + path: ROUTE_SLAUGHTER_USER_PROFILE, + label: "کشتارگاه", + icon: , + }, + VetFarm: { + path: ROUTE_VETFARM_USER_PROFILE, + label: "دامپزشک فارم", + icon: , + }, + KillHouseVet: { + path: ROUTE_SLAUGHTER_HOUSE_VET_USER_PROFILE, + label: "دامپزشک کشتارگاه", + icon: , + }, + Driver: { + path: DRIVER_USER_PROFILE, + label: "راننده", + icon: , + }, + ProvinceFinancial: { + path: ROUTE_PROVINCE_FINANCIAL_USER_PROFILE, + label: "مالی", + icon: , + }, + ProvinceInspector: { + path: ROUTE_INSPECTOR_USER_PROFILE, + label: "بازرس", + icon: , + }, + Guilds: { + path: ROUTE_STEWARD_USER_PROFILE, + label: "صنف", + icon: , + }, + CityVet: { + path: ROUTE_CITYVET_USER_PROFILE, + label: "دامپزشک شهرستان", + icon: , + }, + LiveStockSupport: { + path: ROUTE_LIVE_STOCK_USER_PROFILE, + label: "پشتیبانی امور دام", + icon: , + }, + ChainCompany: { + path: ROUTE_CHAIN_COMPANY_USER_PROFILE, + label: "شرکت زنجیره", + icon: , + }, +}; + +export const GeneralDashboardOperations = () => { + const { pathname } = useLocation(); + const [roles] = useUserProfile(); + + return ( + + + + + نقش ها + + } + /> + + + + + + + + + {roles.map((role, i) => { + const route = routesMap[role]; + return route ? ( + + + + + + ) : null; + })} + + + ); +}; diff --git a/src/features/authentication/components/login/Login.js b/src/features/authentication/components/login/Login.js new file mode 100644 index 0000000..8b4c3c9 --- /dev/null +++ b/src/features/authentication/components/login/Login.js @@ -0,0 +1,163 @@ +import { Button, TextField, Typography } from "@mui/material"; +import { Grid } from "../../../../components/grid/Grid"; +import { SPACING } from "../../../../data/spacing"; +import { loginSendMobile } from "../../services/login"; +import { useDispatch } from "react-redux"; +import { useFormik } from "formik"; +import { Yup } from "../../../../lib/yup/yup"; +import Captcha from "../../../../components/captcha/Captcha"; +import { useEffect, useState } from "react"; +import { EnterPassword } from "../enter-password/EnterPassword"; +import { + LOADING_END, + LOADING_START, +} from "../../../../lib/redux/slices/appSlice"; +import { useContext } from "react"; +import { AppContext } from "../../../../contexts/AppContext"; + +export const Login = () => { + const [openNotif] = useContext(AppContext); + const [isValidCaptcha, setIsValidCaptcha] = useState(false); + const [isUser, setIsUser] = useState(false); + const dispatch = useDispatch(); + const formik = useFormik({ + initialValues: { + mobile: "", + captcha: "", + }, + validationSchema: Yup.object({ + mobile: Yup.number() + .required("این فیلد اجباری است!") + .typeError("لطفا اعداد انگلیسی وارد کنید!") + .test("len", "شماره تلفن باید 11 رقم باشد!", (val, context) => { + return context.originalValue && context.originalValue.length === 11; + }), + }), + }); + + useEffect(() => { + formik.validateForm(); + }, []); + + const isUserHandler = () => { + setIsUser(false); + setIsValidCaptcha(false); + }; + + const submitForm = (e) => { + e.preventDefault(); + dispatch(LOADING_START()); + dispatch( + loginSendMobile({ + mobile: formik.values.mobile, + state: "", + }) + ).then((r) => { + dispatch(LOADING_END()); + if (!r.payload.data.isUser) { + openNotif({ + vertical: "top", + horizontal: "center", + msg: "شماره تلفن شما در سامانه وجود ندارد!", + severity: "error", + }); + } + if (r.error) { + openNotif({ + vertical: "top", + horizontal: "center", + msg: "مشکلی به وجود آمده است!", + severity: "error", + }); + } else { + setIsUser(r.payload.data.isUser); + } + }); + }; + + return ( + + + + + {isUser ? ( + + ) : ( + <> + + سامانه رصدیار + + + شماره موبایل تان را وارد کنید. + +
    + + + + + setIsValidCaptcha(status)} /> + + + + + + +
    + + )} +
    +
    +
    +
    + ); +}; diff --git a/src/features/authentication/hooks/useSelectedSubUser.js b/src/features/authentication/hooks/useSelectedSubUser.js new file mode 100644 index 0000000..35d535a --- /dev/null +++ b/src/features/authentication/hooks/useSelectedSubUser.js @@ -0,0 +1,26 @@ +import { useSelector } from "react-redux"; + +/** + * Hook to get the currently selected sub user from Redux state + * @returns {Object|null} - The selected sub user object with { key, name, unit, mobile, fullname } or null + */ +export const useSelectedSubUser = () => { + const selectedSubUser = useSelector( + (state) => state.userSlice.selectedSubUser + ); + return selectedSubUser; +}; + +/** + * Hook to get only the selected sub user key + * @returns {string|null} - The sub user key or null + */ +export const useSelectedSubUserKey = () => { + const selectedSubUser = useSelector( + (state) => state.userSlice.selectedSubUser + ); + return selectedSubUser?.key || null; +}; + +export default useSelectedSubUser; + diff --git a/src/features/authentication/hooks/useUserProfile.js b/src/features/authentication/hooks/useUserProfile.js new file mode 100644 index 0000000..a200217 --- /dev/null +++ b/src/features/authentication/hooks/useUserProfile.js @@ -0,0 +1,18 @@ +import { useEffect } from "react"; +import { useDispatch, useSelector } from "react-redux"; +import { getUserProfile } from "../services/getUserProfile"; + +const useUserProfile = () => { + const dispatch = useDispatch(); + const { role, userProfile } = useSelector((state) => state.userSlice); + + useEffect(() => { + if (!userProfile) { + dispatch(getUserProfile()); + } + }, []); + + return [role, userProfile]; +}; + +export default useUserProfile; diff --git a/src/features/authentication/services/change-bank-form.js b/src/features/authentication/services/change-bank-form.js new file mode 100644 index 0000000..fed286c --- /dev/null +++ b/src/features/authentication/services/change-bank-form.js @@ -0,0 +1,15 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { getActualRoleFromRole } from "../../../utils/getRoleFromUrl"; + +export const changeBankForm = createAsyncThunk( + "CHANGE_BANK_FORM", + async (d) => { + const role = window.location.pathname.split("/")[3]; + const { data, status } = await axios.post( + `user-bank_card/?role=${getActualRoleFromRole(role)}`, + d + ); + return { data, status }; + } +); diff --git a/src/features/authentication/services/changeProfileInfo.js b/src/features/authentication/services/changeProfileInfo.js new file mode 100644 index 0000000..cd2fd8b --- /dev/null +++ b/src/features/authentication/services/changeProfileInfo.js @@ -0,0 +1,21 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; + +export const changeProfileInfo = createAsyncThunk( + "CHANGE_PROFILE_INFO", + async (d) => { + const { data, status } = await axios.put("system_user_profile/0/", d); + return { data, status }; + } +); + +export const changeProfileFactorInfo = createAsyncThunk( + "CHANGE_PROFILE_FACTOR_INFO", + async (d) => { + const { data, status } = await axios.put( + "system_user_profile-for-factor/0/", + d + ); + return { data, status }; + } +); diff --git a/src/features/authentication/services/get-announcement.js b/src/features/authentication/services/get-announcement.js new file mode 100644 index 0000000..9d4a07d --- /dev/null +++ b/src/features/authentication/services/get-announcement.js @@ -0,0 +1,23 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const getAnnouncement = createAsyncThunk( + "GET_ANNOUNCEMENT", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + const { data, status } = await axios.get("announcements/?total=true"); + dispatch(LOADING_END()); + return { data, status }; + } +); + +export const getUserAnnouncement = createAsyncThunk( + "GET_ANNOUNCEMENT", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + const { data, status } = await axios.get(`announcements/?role=${d}`); + dispatch(LOADING_END()); + return { data, status }; + } +); diff --git a/src/features/authentication/services/getUnseenMessage.js b/src/features/authentication/services/getUnseenMessage.js new file mode 100644 index 0000000..39cd25c --- /dev/null +++ b/src/features/authentication/services/getUnseenMessage.js @@ -0,0 +1,10 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; + +export const getUnseenMessages = createAsyncThunk( + "GET_UNSEEN_MESSAGES", + async (d, { dispatch }) => { + const { data, status } = await axios.get(`get_num_message/`); + return { data, status }; + } +); diff --git a/src/features/authentication/services/getUserMovingTexts.js b/src/features/authentication/services/getUserMovingTexts.js new file mode 100644 index 0000000..603700b --- /dev/null +++ b/src/features/authentication/services/getUserMovingTexts.js @@ -0,0 +1,13 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; +import axios from "axios"; + +export const getUserMovingTextsService = createAsyncThunk( + "GET_USER_MOVING_TEXTS", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + const { data, status } = await axios.get(`moving-text/?dashboard=true`); + dispatch(LOADING_END()); + return { data, status }; + } +); diff --git a/src/features/authentication/services/getUserProfile.js b/src/features/authentication/services/getUserProfile.js new file mode 100644 index 0000000..b6133d4 --- /dev/null +++ b/src/features/authentication/services/getUserProfile.js @@ -0,0 +1,7 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; + +export const getUserProfile = createAsyncThunk("GET_USER_PROFILE", async () => { + const { data, status } = await axios.get("system_user_profile/?self-profile"); + return { data, status }; +}); diff --git a/src/features/authentication/services/getUserRoleInfo.js b/src/features/authentication/services/getUserRoleInfo.js new file mode 100644 index 0000000..cb0fc59 --- /dev/null +++ b/src/features/authentication/services/getUserRoleInfo.js @@ -0,0 +1,23 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const getUserRoleInfo = createAsyncThunk( + "GET_USER_ROLE_INFO", + async ({ userKey, role }, { dispatch }) => { + try { + dispatch(LOADING_START()); + const { data, status } = await axios.get("user-role-info/", { + params: { + user_key: userKey, + role: role, + }, + }); + dispatch(LOADING_END()); + return { data, status }; + } catch (error) { + dispatch(LOADING_END()); + throw error; + } + } +); diff --git a/src/features/authentication/services/login.js b/src/features/authentication/services/login.js new file mode 100644 index 0000000..fd99601 --- /dev/null +++ b/src/features/authentication/services/login.js @@ -0,0 +1,98 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; + +export const loginSendMobile = createAsyncThunk( + "LOGIN_SEND_MOBILE", + async ({ mobile, state }) => { + const { data, status } = await axios.post("api/send/", { mobile, state }); + return { data, status }; + } +); +//buildchange +export const loginWithPassword = createAsyncThunk( + "LOGIN_WITH_PASSWORD", + async ({ mobile, password }) => { + const { data, status } = await axios.post("api/login/", { + username: mobile, + password, + // bushehr + // api_key: "44d89a44-bd44-2144-a02f-2cc2cbf4e2d4", + // kermanshah + // api_key: "4b124231-62c7-41c6-8081-66191536c0b7", + // test + // api_key: "11d89a11-bd11-2111-a02f-2cc1cbf4e1d4", + // markazi arak + // api_key: "44d89a99-bd12-4152-a02f-5cc5cbf7e5d5", + // hamedan + // api_key: "33374d79-e8ee-4947-b0b4-4a6d31935814", + // lorestan + // api_key: "2b773c7e-f6de-4dd2-af43-a012a8b78d04", + // test + // api_key: "11d89a11-bd11-2111-a02f-2cc1cbf4e1d4", + // ardebil (AR) + // api_key: "14d14a14-bd14-1414-a03f-2cc1cbf5e1d1", + // tabriz (sharghi) + // api_key: "23d23a32-bd23-2311-a03f-2cc1cbf3e1d4", + }); + return { data, status }; + } +); + +export const forgetPassword = createAsyncThunk( + "LOGIN_FORGET_PASSWORD", + async ({ mobile, state }) => { + const { data, status } = await axios.post("api/send/", { mobile, state }); + return { data, status }; + } +); + +export const checkUserPath = createAsyncThunk( + "CHECK_USER_PATH", + async ({ mobile, state }) => { + const { data, status } = await axios.post( + "https://userbackend.rasadyar.com/api/send_otp/", + { mobile, state } + ); + return { data, status }; + } +); + +export const checkActiveUsers = createAsyncThunk( + "CHECK_ACTIVE_USERS", + async () => { + const { data, status } = await axios.get( + "https://userbackend.rasadyar.com/api/active-users/" + ); + return { data, status }; + } +); + +export const forgetPasswordSendOpt = createAsyncThunk( + "LOGIN_FORGET_PASSWORD_SEND_OTP", + async ({ key, code }) => { + const { data, status } = await axios.post("api/check/", { key, code }); + return { data, status }; + } +); + +export const forgetPasswordChangePassword = createAsyncThunk( + "LOGIN_FORGET_PASSWORD_CHANGE_PASSWORD", + async ({ username, password }) => { + const { data, status } = await axios.post("api/forget/", { + username, + password, + }); + return { data, status }; + } +); + +export const changePassword = createAsyncThunk( + "LOGIN_CHANGE_PASSWORD", + async ({ username, password }) => { + const { data, status } = await axios.post("api/change_password/", { + username, + password, + }); + return { data, status }; + } +); diff --git a/src/features/authentication/services/token-verifiction.js b/src/features/authentication/services/token-verifiction.js new file mode 100644 index 0000000..3326814 --- /dev/null +++ b/src/features/authentication/services/token-verifiction.js @@ -0,0 +1,12 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; + +export const tokenVerifiction = createAsyncThunk( + "GET_USER_RAVANDNO_INFO", + async (d) => { + const { data, status } = await axios.post("token-verification/", { + token: d.token, + }); + return { data, status }; + } +); diff --git a/src/features/authentication/services/update-bank-form.js b/src/features/authentication/services/update-bank-form.js new file mode 100644 index 0000000..0af4f9f --- /dev/null +++ b/src/features/authentication/services/update-bank-form.js @@ -0,0 +1,10 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; + +export const updateBankForm = createAsyncThunk( + "UPDATE_BANK_FORM", + async (d) => { + const { data, status } = await axios.put(`user-bank_card/0/`, d); + return { data, status }; + } +); diff --git a/src/features/authentication/services/wage-payment-get-user-info.js b/src/features/authentication/services/wage-payment-get-user-info.js new file mode 100644 index 0000000..28dc846 --- /dev/null +++ b/src/features/authentication/services/wage-payment-get-user-info.js @@ -0,0 +1,15 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; +import axios from "axios"; + +export const wagePaymentGetUserInfo = createAsyncThunk( + "WAGE_PAYMENT_GET_USER_INFO", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + const { data, status } = await axios.get( + `https://${d.province}backend.rasadyar.com/get-payer-info/?${d.key}` + ); + dispatch(LOADING_END()); + return { data, status }; + } +); diff --git a/src/features/aviculture/components/aviculture-active-requests/AvicultureActiveRequests.js b/src/features/aviculture/components/aviculture-active-requests/AvicultureActiveRequests.js new file mode 100644 index 0000000..89bd86e --- /dev/null +++ b/src/features/aviculture/components/aviculture-active-requests/AvicultureActiveRequests.js @@ -0,0 +1,225 @@ +import { Button, IconButton, TextField } from "@mui/material"; +import { useContext, useEffect, useState } from "react"; +import { Grid } from "../../../../components/grid/Grid"; +import { useDispatch, useSelector } from "react-redux"; +import { SPACING } from "../../../../data/spacing"; +import { DRAWER } from "../../../../lib/redux/slices/appSlice"; +// import { AvicultureNewRequest } from "../aviculture-new-request/AvicultureNewRequest"; +// import HelpOutlineIcon from "@mui/icons-material/HelpOutline"; +import DeleteIcon from "@mui/icons-material/Delete"; +import { AppContext } from "../../../../contexts/AppContext"; +import { avicultureGetRequests } from "../../services/aviculture-requests"; +import { archiveDeleteKillRequestService } from "../../services/aviculture-delete-kill-request"; +import { formatJustDate } from "../../../../utils/formatTime"; +import { DatePicker } from "@mui/x-date-pickers"; +import moment from "moment/moment"; +import { CityNewKillRequest } from "../../../city/components/city-new-kill-request/CityNewKillRequest"; +import ResponsiveTable from "../../../../components/responsive-table/ResponsiveTable"; + +export const AvicultureActiveRequests = () => { + const [dataTable, setDataTable] = useState([]); + const dispatch = useDispatch(); + const [openNotif] = useContext(AppContext); + const { avicultureRequests } = useSelector((state) => state.avicultureSlice); + + const [, , selectedDate1, setSelectedDate1, selectedDate2, setSelectedDate2] = + useContext(AppContext); + + useEffect(() => { + const currentDate = moment(new Date()).format("YYYY-MM-DD"); + setSelectedDate1(currentDate); + setSelectedDate2(currentDate); + }, []); + + useEffect(() => { + dispatch(avicultureGetRequests({ selectedDate1, selectedDate2 })); + }, [selectedDate1, selectedDate2]); + + useEffect(() => { + const filteredData = + Array.isArray(avicultureRequests) && + avicultureRequests?.filter( + (item) => + (item.stateProcess === "accepted" || + item.stateProcess === "pending") && + item.finalState !== "archive" + ); + let d; + if (filteredData) { + d = filteredData?.map((item, i) => { + let sellType = ""; + if (item.directBuying) { + sellType = "خرید مستقیم"; + } else if (item.union) { + sellType = "خرید خارج از استان"; + } else { + sellType = "اتحادیه"; + } + return [ + i + 1, + item.orderCode, + sellType, + item?.freezing ? "انجماد" : item?.export ? "صادرات" : "عادی", + item?.directBuyingBuyerInfo + ? `${item?.directBuyingBuyerInfo?.buyerFullname} (${item?.directBuyingBuyerInfo?.buyerMobile})` + : "-", + item.directBuyingKillPlace ? item.directBuyingKillPlace : "-", + item?.createDate ? formatJustDate(item?.createDate) : "", + item?.sendDate ? formatJustDate(item?.sendDate) : "", + `${item.process?.poultry?.poultryName} (${item.process?.poultry?.poultryMobile})`, + `${item.process?.poultry?.poultryProvince}/${item.process?.poultry?.poultryCity}`, + formatJustDate(item.process?.poultryHatching?.date), + item.process?.poultry?.age, + item.IndexWeight, + item.process?.poultry?.poultryQuantity.toLocaleString(), + ( + item.IndexWeight * item.process?.poultry?.poultryQuantity + ).toLocaleString(), + + { + dispatch( + archiveDeleteKillRequestService( + item?.process?.poultry?.poultryRequestId + ) + ).then((r) => { + if (r.payload.error) { + openNotif({ + vertical: "top", + horizontal: "center", + msg: r.payload.error, + severity: "error", + }); + } else { + dispatch(avicultureGetRequests()); + dispatch( + DRAWER({ right: false, bottom: false, content: null }) + ); + openNotif({ + vertical: "top", + horizontal: "center", + msg: "عملیات با موفقیت انجام شد.", + severity: "success", + }); + } + }); + }} + > + + , + ]; + }); + } + + setDataTable(d); + }, [avicultureRequests]); + + return ( + <> + + + + + + + {/* */} + + + + + ( + + )} + value={selectedDate1} + onChange={(e) => { + setSelectedDate1(moment(e).format("YYYY-MM-DD")); + }} + /> + + + ( + + )} + value={selectedDate2} + onChange={(e) => { + setSelectedDate2(moment(e).format("YYYY-MM-DD")); + }} + /> + + + + + + + + + ); +}; diff --git a/src/features/aviculture/components/aviculture-archived-requests/AvicultureArchivedRequests.js b/src/features/aviculture/components/aviculture-archived-requests/AvicultureArchivedRequests.js new file mode 100644 index 0000000..d142a8c --- /dev/null +++ b/src/features/aviculture/components/aviculture-archived-requests/AvicultureArchivedRequests.js @@ -0,0 +1,72 @@ +import { Card, IconButton } from "@mui/material"; +import { useEffect, useState } from "react"; +import { AdvancedTable } from "../../../../components/advanced-table/AdvancedTable"; +import PlagiarismIcon from "@mui/icons-material/Plagiarism"; +import { useNavigate } from "react-router-dom"; +import useAvicultureRequests from "../../hooks/useAvicultureRequests"; +import { formatJustDate } from "../../../../utils/formatTime"; + +export const AvicultureArchivedRequests = () => { + const navigate = useNavigate(); + const [dataTable, setDataTable] = useState([]); + const avicultureRequests = useAvicultureRequests("Poultry"); + const urlRole = window.location.pathname.split("/")[1]; + + useEffect(() => { + const fileUrl = "/" + urlRole + "/file/"; + + const filteredData = avicultureRequests?.filter( + (item, i) => item.finalState === "archive" + ); + const d = filteredData?.map((item, i) => { + return [ + i + 1, + item.orderCode, + formatJustDate(item?.createDate), + formatJustDate(item?.sendDate), + item?.process?.poultry?.poultryName, + item?.process?.poultry?.poultryMobile, + item?.process?.poultry?.poultryCity, + item?.process?.poultry?.poultryProvince, + item?.process?.poultry?.age, + item?.process?.poultry?.poultryQuantity, + + navigate(fileUrl + item?.process?.poultry?.poultryRequestId) + } + > + + , + ]; + }); + + setDataTable(d); + }, []); + + const [tableDataCol] = useState([ + "ردیف", + "کد سفارش", + "تاریخ ثبت درخواست", + "تاریخ درخواست", + "مرغدار", + "تلفن مرغدار", + "شهر", + "استان", + "سن مرغ", + "تعداد", + "مشاهده", + ]); + return ( + + + + ); +}; diff --git a/src/features/aviculture/components/aviculture-free-sale-new-request/AvicultureFreeSaleNewRequest.js b/src/features/aviculture/components/aviculture-free-sale-new-request/AvicultureFreeSaleNewRequest.js new file mode 100644 index 0000000..2b6041c --- /dev/null +++ b/src/features/aviculture/components/aviculture-free-sale-new-request/AvicultureFreeSaleNewRequest.js @@ -0,0 +1,1197 @@ +import { + Autocomplete, + Button, + Checkbox, + Divider, + FormControl, + FormControlLabel, + // FormGroup, + // FormControlLabel, + FormHelperText, + FormLabel, + IconButton, + InputAdornment, + InputLabel, + ListItem, + ListItemIcon, + ListItemText, + MenuItem, + Radio, + // Radio, + RadioGroup, + Select, + TextField, + Typography, +} from "@mui/material"; +import { Grid } from "../../../../components/grid/Grid"; +import { SPACING } from "../../../../data/spacing"; +import { useEffect } from "react"; +import { DatePicker } from "@mui/x-date-pickers"; +import { useDispatch, useSelector } from "react-redux"; +import { avicultureNewRequest } from "../../services/aviculture-new-request"; +import { + DRAWER, + LOADING_END, + LOADING_START, +} from "../../../../lib/redux/slices/appSlice"; +import { useFormik } from "formik"; +import { Yup } from "../../../../lib/yup/yup"; +import moment from "moment"; +import { useState } from "react"; +import { avicultureGetHatchingData } from "../../services/aviculture-get-hatching-data"; +import { avicultureGetPoultry } from "../../services/aviculture-get-poultry"; +import { avicultureGetChickenPrice } from "../../services/aviculture-get-chicken-price"; +import DeleteIcon from "@mui/icons-material/Delete"; +import { avicultureGetRequests } from "../../services/aviculture-requests"; +import { useContext } from "react"; +import { AppContext } from "../../../../contexts/AppContext"; +import AddIcon from "@mui/icons-material/Add"; +// import { NumericFormat } from "react-number-format"; +import { NumberInput } from "../../../../components/number-format-custom/NumberFormatCustom"; +import { DialogAlert } from "../../../../components/dialog-alert/DialogAlert"; +import useUserProfile from "../../../authentication/hooks/useUserProfile"; +// import { NumberFormatCustom } from "../../../../components/number-format-custom/NumberFormatCustom"; +import DoneIcon from "@mui/icons-material/Done"; +// import { SelectCheck } from "../../../../components/select-check/SelectCheck"; +import { avicultureGetSlaughters } from "../../services/aviculture-get-slaughters"; +import { avicultureGetUnions } from "../../services/aviculture-get-unions"; +import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl"; +import { provinceGetFreeSalesRequestsService } from "../../../province/services/province-get-free-sales-requests"; + +export const AvicultureFreeSaleNewRequest = () => { + const [openNotif] = useContext(AppContext); + const [hatchingKey, sethatchingKey] = useState(""); + const [hatchingData, setHatchingData] = useState(""); + const [hatchingSelected, setHatchingSelected] = useState(""); + const [poultryData, setPoultryData] = useState(""); + const [poultryKey, setPolutryKey] = useState(""); + const [quantity, setQuantity] = useState(""); + const [losses, setlosses] = useState(""); + const [leftOvers, setLeftOvers] = useState(""); + const [isUnion] = useState(false); + const [isStockMarket, setIsStockMarket] = useState(false); + const [pricingKey, setPriceKey] = useState(); + const [chickenBreed, setChickenBreed] = useState(""); + const [chickenCanRequest, setChickenCanRequest] = useState(""); + + const [, userProfile] = useUserProfile(); + + const inputArr = [ + { + type: "text", + id: 1, + value: "", + }, + ]; + + const inputArrPrices = [ + { + type: "text", + id: 1, + value: "", + }, + ]; + const [arr, setArr] = useState(inputArr); + const [arrPrices, setArrPrices] = useState(inputArrPrices); + + const dispatch = useDispatch(); + + const { avicultureChickenPrice } = useSelector( + (state) => state.avicultureSlice + ); + + useEffect(() => { + dispatch(LOADING_START()); + dispatch(avicultureGetChickenPrice()); + dispatch(avicultureGetSlaughters()); + dispatch(LOADING_END()); + }, []); + + const [unions, setUnions] = useState(); + const [unionSelected, setUnionSelected] = useState(); + + useEffect(() => { + dispatch(LOADING_START()); + dispatch(avicultureGetUnions()).then((r) => { + setUnionSelected(r.payload.data[0]?.key); + setUnions(r.payload.data); + }); + dispatch(LOADING_END()); + }, []); + + const addInput = () => { + if (arr.length < 3) { + setArr((prevState) => { + return [ + ...prevState, + { + type: "text", + value: "", + }, + ]; + }); + + setArrPrices((prevState) => { + return [ + ...prevState, + { + type: "text", + value: "", + }, + ]; + }); + } + }; + + const removeInput = () => { + const number = arr.length - 1; + + if (number !== 0) { + const filteredArrayPrice = arr.filter((object, i) => i !== number); + const filteredArrayTime = arrPrices.filter((object, i) => i !== number); + + setArr(filteredArrayPrice); + setArrPrices(filteredArrayTime); + } + + // setArr((s) => { + // return s.splice(arr.findIndex((item) => item.id === number, 1)); + // }); + + // setArrPrices((s) => { + // return s.splice(arr.findIndex((item) => item.id === number, 1)); + // }); + }; + + const handleChange = (e) => { + e.preventDefault(); + + const index = e.target.id; + setArr((s) => { + const newArr = s.slice(); + newArr[index].value = e.target.value; + + return newArr; + }); + }; + + const handleChangeTime = (e) => { + e.preventDefault(); + + const index = e.target.id; + + setArrPrices((s) => { + const newArrPrice = s.slice(); + newArrPrice[index].value = e.target.dataset.value; + + return newArrPrice; + }); + }; + + useEffect(() => { + if (avicultureChickenPrice) { + setPriceKey(avicultureChickenPrice?.key); + } + }, [avicultureChickenPrice]); + const formik = useFormik({ + initialValues: { + noChicken: "", + sellType: { + cash: true, + haveTime: false, + }, + price1: "", + price2: "", + price3: "", + slaughterDate: moment(Date()).format("YYYY-MM-DD"), + period1: "4", + period2: "4", + period3: "4", + weight: "", + losses: "0", + isUnion, + isStockMarket, + isAccepted: false, + selectedSlaughters: [], + name: "", + lastname: "", + mobile: "", + province: "", + city: "", + buyerType: "", + }, + validationSchema: Yup.object({ + noChicken: Yup.string() + .required("این فیلد اجباری است!") + .typeError("لطفا عدد وارد کنید!") + .min(0, "تعداد وارد شده از حداقل ممکن کمتر است") + .max(chickenCanRequest, "تعداد وارد شده از کل موجودی بیشتر است"), + isAccepted: Yup.boolean() + .test("req", "باید تعهد نامه را بپذیرید!", (val, context) => { + return context.originalValue && context.originalValue === true; + }) + .required("این فیلد اجباری است!"), + price1: Yup.number() + .typeError("لطفا عدد وارد کنید!") + .min( + avicultureChickenPrice?.floorPrice, + "قیمت وارد شده از کف قیمت امروز کمتر است" + ) + .max( + avicultureChickenPrice?.ceilingPrice, + "قیمت وارد شده از سقف قیمت امروز بیشتر است" + ), + price2: Yup.number() + .typeError("لطفا عدد وارد کنید!") + .min( + avicultureChickenPrice?.floorPrice, + "قیمت وارد شده از کف قیمت امروز کمتر است" + ) + .max( + avicultureChickenPrice?.ceilingPrice, + "قیمت وارد شده از سقف قیمت امروز بیشتر است" + ), + price3: Yup.number() + .typeError("لطفا عدد وارد کنید!") + .min( + avicultureChickenPrice?.floorPrice, + "قیمت وارد شده از کف قیمت امروز کمتر است" + ) + .max( + avicultureChickenPrice?.ceilingPrice, + "قیمت وارد شده از سقف قیمت امروز بیشتر است" + ), + weight: Yup.number() + .test("weight", "وزن را تا دو رقم اعشار وارد کنید", (val, context) => { + return ( + context.originalValue && + context.originalValue.toString().length <= 4 + ); + }) + .required("این فیلد اجباری است!") + .typeError("لطفا وزن را وارد کنید!"), + losses: Yup.number() + .required("این فیلد اجباری است!") + .max(quantity, "تلفات وارد شده از باقیمانده بیشتر است!") + .typeError("لطفا تعداد تلفات را وارد کنید!"), + sellType: Yup.object() + .test("sellType", "نحوه فروش را انتخاب کنید!", (val, context) => { + return ( + context.originalValue && + Object.values(context.originalValue).some((item) => item === true) + ); + }) + .required("این فیلد اجباری است!"), + name: Yup.string().required("نام اجباری است"), + lastname: Yup.string().required("نام خانوادگی اجباری است"), + mobile: Yup.string().required("موبایل اجباری است"), + province: Yup.string().required("استان اجباری است"), + city: Yup.string().required("شهرستان اجباری است"), + buyerType: Yup.string().required("نوع خریدار اجباری است"), + }), + }); + + const penaltyPrice = formik.values.noChicken * 1000; + const dialogContent = ( + <> + + اینجانب {userProfile.fullname} موافقت خود را نسبت به موارد ذکر شده اعلام + می نمایم. + + + + + + + + + + ); + + useEffect(() => { + dispatch(LOADING_START()); + dispatch(avicultureGetPoultry()).then((r) => { + setPoultryData(r.payload.data); + dispatch(LOADING_END()); + }); + }, []); + + useEffect(() => { + let newVal = formik.values.weight; + const mystring = formik.values.weight.toString().split(".").join(""); + if (formik.values.weight) { + if (mystring.length <= 3) { + if (mystring.length === 2) { + newVal = mystring[0] + "." + mystring[1]; + } + if (mystring.length === 3) { + newVal = mystring[0] + "." + mystring[1] + mystring[2]; + } + } + } + if (isNaN(Number.parseFloat(newVal))) { + formik.setFieldValue("weight", ""); + } else { + formik.setFieldValue("weight", Number.parseFloat(newVal)); + } + }, [formik.values.weight]); + + useEffect(() => { + if (isStockMarket) { + dispatch(avicultureGetChickenPrice()).then((r) => { + if (Array.isArray(r.payload.data)) { + openNotif({ + vertical: "top", + horizontal: "center", + msg: "قیمت روز مرغ در سامانه ثبت نشده است.", + severity: "error", + }); + + dispatch(DRAWER({ right: false, bottom: false, content: null })); + } else { + dispatch(LOADING_END()); + } + }); + } + }, [isStockMarket]); + + useEffect(() => { + formik.validateForm(); + }, []); + + useEffect(() => { + if (poultryKey) { + dispatch(LOADING_START()); + dispatch(avicultureGetHatchingData({ key: poultryKey })).then((r) => { + if (r.payload.data) { + setHatchingData(r.payload.data); + + dispatch(LOADING_END()); + } else { + openNotif({ + vertical: "top", + horizontal: "center", + msg: "اطلاعات جوجه ریزی یافت نشد!", + severity: "error", + }); + } + dispatch(LOADING_END()); + }); + } + }, [poultryKey]); + + useEffect(() => { + setChickenCanRequest( + formik.values.noChicken <= Number(leftOvers) && + Number(formik.values.losses) <= Number(leftOvers) + ? Number(leftOvers) - Number(formik.values.losses) + : 0 + ); + }, [formik.values.losses, leftOvers, formik.values.noChicken]); + + useEffect(() => { + setQuantity(hatchingSelected.quantity); + setlosses(hatchingSelected.losses); + setLeftOvers(hatchingSelected.leftOver); + }, [hatchingSelected]); + + // const handleSellTypeChange = (event) => { + // formik.setFieldValue("sellType", { + // ...formik.values.sellType, + // [event.target.name]: event.target.checked, + // }); + // }; + + return ( + + + + ({ + id: i.key, + label: i.unitName, + })) + : [] + } + onChange={(event, value) => { + setPolutryKey(value.id); + }} + renderInput={(params) => ( + + )} + /> + + + {!poultryData[0]?.provinceAllowSellFree && ( + اجازه فروش خارج از استان ندارید! + )} + + {poultryData[0]?.provinceAllowSellFree && ( + + + { + return { + id: i.key, + race: i.chickenBreed, + selected: i, + label: `دوره ${i.period} سالن ${i.hall} نژاد ${i.chickenBreed} باقیمانده ${i.leftOver} قطعه`, + }; + }) + : [] + } + onChange={(event, value) => { + sethatchingKey(value.id); + setHatchingSelected(value.selected); + let race = value.race; + if (race.includes("-")) { + race = "ترکیبی"; + } + setChickenBreed(race); + }} + renderInput={(params) => ( + + )} + /> + + + + + + + + + + + + )} + + + {hatchingSelected && ( + + اطلاعات کشتار + {getRoleFromUrl() !== "Poultry" && ( + + + + + + )} + + {/* */} + + + + + + prop.palette.grey["A700"]} + variant={"caption"} + > + باقیمانده: + + + {formik.values.noChicken + ? formik.values.noChicken <= Number(leftOvers) && + Number(formik.values.losses) <= Number(leftOvers) && + Number(leftOvers) - + Number(formik.values.losses) - + Number(formik.values.noChicken) >= + 0 + ? Math.abs( + Number(leftOvers) - + Number(formik.values.losses) - + Number(formik.values.noChicken) + ) + : 0 + : Number(leftOvers)} + + + قطعه + + + + prop.palette.grey["A700"]} + variant={"caption"} + > + سن مرغ: + + + {hatchingSelected.age} + + روزه + + + + + + } + value={formik.values.slaughterDate} + error={ + formik.touched.slaughterDate + ? Boolean(formik.errors.slaughterDate) + : null + } + onChange={(e) => { + formik.setFieldValue( + "slaughterDate", + moment(e).format("YYYY-MM-DD") + ); + }} + onBlur={formik.handleBlur} + helperText={ + formik.touched.slaughterDate && + Boolean(formik.errors.slaughterDate) + ? formik.errors.slaughterDate + : null + } + /> + + + کیلوگرم + ), + }} + value={formik.values.weight} + error={ + formik.touched.weight ? Boolean(formik.errors.weight) : null + } + onChange={formik.handleChange} + onBlur={formik.handleBlur} + helperText={ + formik.touched.weight && Boolean(formik.errors.weight) + ? formik.errors.weight + : null + } + /> + + + {/* + نحوه فروش + */} + + + { + setIsStockMarket(event.currentTarget.value); + }} + > + {/* } + label="فروش اتحادیه" + /> */} + {/* + } + label="فروش مزایده ای" + /> */} + {isStockMarket === "فروش مزایده ای" && ( + + + prop.palette.grey["A700"]} + variant={"caption"} + > + کف قیمت امروز: + + + {avicultureChickenPrice?.floorPrice + ? avicultureChickenPrice?.floorPrice.toLocaleString() + : "نامشخص"}{" "} + {" "} + ریال + + + + prop.palette.grey["A700"]} + variant={"caption"} + > + سقف قیمت امروز: + + + {avicultureChickenPrice?.ceilingPrice + ? avicultureChickenPrice?.ceilingPrice.toLocaleString() + : "نامشخص"}{" "} + {" "} + ریال + + + + + + {arr.map((item, i) => { + return ( + + + پیشنهاد {i + 1} + + + + + + + بازه زمانی (ساعت) + + + + {formik.touched.period1 && + Boolean(formik.errors.period1) + ? formik.errors.period1 + : null} + + + {/* */} + + ); + })} + + + {arr.length > 1 && ( + + + + )} + {arr.length < 3 && ( + + + افزودن پیشنهاد جدید + + )} + + + + + در صورت عدم فروش در بورس، از طریق اتحادیه فروش برود + + + + + )} + + + + اطلاعات خریدار + + + + + + + نوع خریدار + + } + label="کشتارگاه" + /> + } + label="کشتارکن" + /> + } + label="انجماد" + /> + + {formik.touched.buyerType && formik.errors.buyerType ? ( +
    {formik.errors.buyerType}
    + ) : null} +
    + + {/* + + نحوه فروش + + + + } + label="نقدی" + /> + + } + label="زمان دار (تا یک ماه)" + /> + + + {formik.touched.sellType && Boolean(formik.errors.sellType) + ? formik.errors.sellType + : null} + + */} + + {unions?.length > 1 && ( + <> + + + + + انتخاب اتحادیه + + { + setUnionSelected(event.currentTarget.value); + }} + > + {unions.map((item) => { + return ( + <> + } + label={item.unitName} + /> + + ); + })} + + + + + )} + + + + + + } + btnTitle={"با تعهد نامه موافق هستم!"} + isAccepted={formik.values.isAccepted} + /> +
    + + + +
    + )} + + ); +}; diff --git a/src/features/aviculture/components/aviculture-give-permission/AvicultureGivePermission.js b/src/features/aviculture/components/aviculture-give-permission/AvicultureGivePermission.js new file mode 100644 index 0000000..f81537c --- /dev/null +++ b/src/features/aviculture/components/aviculture-give-permission/AvicultureGivePermission.js @@ -0,0 +1,121 @@ +import React, { useEffect, useState } from "react"; +import { useDispatch } from "react-redux"; +import { + Button, + Checkbox, + FormControlLabel, + Grid, + Typography, +} from "@mui/material"; +import { avicultureGetGivePermissionService } from "../../services/aviculture-get-give-permission"; +import { avicultureGivePermissionService } from "../../services/aviculture-give-permission"; +import { SPACING } from "../../../../data/spacing"; + +const styles = { + root: { + padding: 20, + textAlign: "left", + boxShadow: "0px 0px 10px rgba(0, 0, 0, 0.1)", + borderRadius: 8, + backgroundColor: "#fff", + }, + heading: { + textAlign: "right", + borderBottom: "2px solid #ccc", + paddingBottom: SPACING.SMALL, + marginBottom: SPACING.SMALL, + }, + checkboxContainer: { + display: "flex", + justifyContent: "flex-start", + marginBottom: SPACING.SMALL, + }, + checkbox: { + marginLeft: SPACING.SMALL, + }, + button: { + marginTop: SPACING.SMALL, + }, +}; + +export const AvicultureGivePermission = () => { + const dispatch = useDispatch(); + const [checkbox1, setCheckbox1] = useState(false); + const [checkbox2, setCheckbox2] = useState(false); + + const handleCheckbox1Change = (event) => { + setCheckbox1(event.target.checked); + }; + + const handleCheckbox2Change = (event) => { + setCheckbox2(event.target.checked); + }; + + useEffect(() => { + dispatch(avicultureGetGivePermissionService()).then((r) => { + if (r?.payload?.data?.length) { + setCheckbox1(r.payload.data[0]?.city); + setCheckbox2(r.payload.data[0]?.province); + } else { + setCheckbox1(false); + setCheckbox2(false); + } + }); + }, [dispatch]); + + return ( + + + اجازه دسترسی + + + + } + label={ + + دادن وکالت به شهرستان جهت ثبت درخواست کشتار + + } + /> + + + + } + label={ + + دادن وکالت به استان جهت ثبت درخواست کشتار + + } + /> + + + + + + ); +}; diff --git a/src/features/aviculture/components/aviculture-hatching/AvicultureHatching.js b/src/features/aviculture/components/aviculture-hatching/AvicultureHatching.js new file mode 100644 index 0000000..15e349f --- /dev/null +++ b/src/features/aviculture/components/aviculture-hatching/AvicultureHatching.js @@ -0,0 +1,242 @@ +// import { IconButton, Tooltip } from "@mui/material"; +import { Grid } from "../../../../components/grid/Grid"; +import { SPACING } from "../../../../data/spacing"; +import { useEffect } from "react"; +import { useDispatch, useSelector } from "react-redux"; +import { useFormik } from "formik"; +import { Yup } from "../../../../lib/yup/yup"; +import moment from "moment"; +import // DRAWER, + +"../../../../lib/redux/slices/appSlice"; +// import { AvicultureNewHatching } from "../aviculture-new-hatching/AvicultureNewHatching"; +import { avicultureGetHatchings } from "../../services/aviculture-get-hatchings"; +import { useState } from "react"; +// import DeleteIcon from "@mui/icons-material/Delete"; +// import { avicultureDeleteHatching } from "../../services/aviculture-delete-hatching"; +// import { useContext } from "react"; +// import { AppContext } from "../../../../contexts/AppContext"; +// import HelpOutlineIcon from "@mui/icons-material/HelpOutline"; +import Tour from "reactour"; +import { formatJustDate } from "../../../../utils/formatTime"; +import ResponsiveTable from "../../../../components/responsive-table/ResponsiveTable"; + +const steps = [ + { + selector: ".first-step", + content: () =>
    برای ثبت جوجه ریزی اینجا کلیک کنید!
    , + }, + { + selector: ".second", + content: () => ( +
    در این قسمت جوجه ریزی های ثبت شده توسط شما نمایش داده می شود.
    + ), + }, +]; + +export const AvicultureHatching = () => { + const dispatch = useDispatch(); + // const [openNotif] = useContext(AppContext); + const { avicultureHatchings } = useSelector((state) => state.avicultureSlice); + const [isTourOpen, setIsTourOpen] = useState(false); + const [dataTable, setDataTable] = useState([]); + + useEffect(() => { + dispatch(avicultureGetHatchings()); + }, []); + + useEffect(() => { + const d = avicultureHatchings?.map((item, i) => { + const killedNumber = item.quantity - item.losses - item.leftOver; + return [ + i + 1, + item.allowHatching === "pending" ? "فعال" : "بایگانی شده", + item.poultry.unitName, + item.hall, + item.period, + formatJustDate(item?.createDate), + formatJustDate(item?.date), + item.breed.map((item) => { + const title = `${item.breed} (${item.mainQuantity} قطعه)`; + return

    {title}

    ; + }), + item.age, + item.quantity, + `${item.losses} (%${((item.losses * 100) / item.quantity).toFixed(0)})`, + killedNumber + + ` (%${((killedNumber * 100) / item.quantity).toFixed(0)})`, + `${item.leftOver} (%${((item.leftOver * 100) / item.quantity).toFixed( + 0 + )})`, + // item.allowHatching === "pending" ? ( + // + // { + // dispatch(LOADING_START()); + // dispatch(avicultureDeleteHatching(item.key)).then((r) => { + // dispatch(LOADING_END()); + // if (r.error) { + // if (r.error.message.includes("403")) { + // openNotif({ + // vertical: "top", + // horizontal: "center", + // msg: "برای این جوجه ریزی درخواست کشتار ثبت شده است!", + // severity: "error", + // }); + // } else if (r.error.message.includes("400")) { + // openNotif({ + // vertical: "top", + // horizontal: "center", + // msg: "برای این جوجه ریزی بازرسی ثبت شده است!", + // severity: "error", + // }); + // } else { + // openNotif({ + // vertical: "top", + // horizontal: "center", + // msg: "مشکلی پیش آمده است!", + // severity: "error", + // }); + // } + // } else { + // dispatch(avicultureGetHatchings()); + // openNotif({ + // vertical: "top", + // horizontal: "center", + // msg: "عملیات با موفقیت انجام شد.", + // severity: "success", + // }); + // } + // }); + // }} + // > + // + // + // + // ) : ( + // "-" + // ), + ]; + }); + + setDataTable(d); + }, [avicultureHatchings]); + + const formik = useFormik({ + initialValues: { + noChicken: "", + slaughterDate: moment(Date()).format("YYYY-MM-DD hh:mm:ss"), + race: "آرین", + weight: "", + }, + validationSchema: Yup.object({ + noChicken: Yup.number() + .required("این فیلد اجباری است!") + .typeError("لطفا عدد وارد کنید!"), + weight: Yup.number() + .required("این فیلد اجباری است!") + .typeError("لطفا وزن را وارد کنید!"), + }), + }); + + useEffect(() => { + formik.validateForm(); + }, []); + + return ( + + + + + {/* + + */} + + + {/* */} + + + setIsTourOpen(false)} + styles={{ + popover: (base) => ({ + ...base, + borderRadius: "10px", + "--reactor-accent": "red", + }), + }} + /> + + + + + + + ); +}; diff --git a/src/features/aviculture/components/aviculture-new-hatching/AvicultureNewHatching.js b/src/features/aviculture/components/aviculture-new-hatching/AvicultureNewHatching.js new file mode 100644 index 0000000..7954ace --- /dev/null +++ b/src/features/aviculture/components/aviculture-new-hatching/AvicultureNewHatching.js @@ -0,0 +1,254 @@ +import { SPACING } from "../../../../data/spacing"; +import { Grid } from "../../../../components/grid/Grid"; +import { + Autocomplete, + Button, + FormControl, + FormHelperText, + InputLabel, + MenuItem, + Select, + TextField, +} from "@mui/material"; +import { useFormik } from "formik"; +import { Yup } from "../../../../lib/yup/yup"; +import { useEffect } from "react"; +import moment from "moment/moment"; +import { DatePicker } from "@mui/x-date-pickers"; +import { useDispatch } from "react-redux"; +import { avicultureGetPoultry } from "../../services/aviculture-get-poultry"; +import { useState } from "react"; +import { + DRAWER, + LOADING_END, + LOADING_START, +} from "../../../../lib/redux/slices/appSlice"; +import { avicultureNewHatching } from "../../services/aviculture-new-hatching"; +import { avicultureGetHatchings } from "../../services/aviculture-get-hatchings"; +import { useContext } from "react"; +import { AppContext } from "../../../../contexts/AppContext"; +import { NumberInput } from "../../../../components/number-format-custom/NumberFormatCustom"; + +export const AvicultureNewHatching = () => { + const dispatch = useDispatch(); + const [openNotif] = useContext(AppContext); + const [poultryKey, setPolutryKey] = useState(""); + const [polutryData, setpolutryData] = useState(""); + const [enableHall, setEnableHall] = useState(true); + const [numberOfhalls, setNumberOfHalls] = useState(1); + const [numberOfhallSelected, setNumberOfHallSelected] = useState(null); + + const formik = useFormik({ + initialValues: { + quantity: "", + hatchingDate: moment(Date()).format("YYYY-MM-DD hh:mm:ss"), + race: "آرین", + }, + validationSchema: Yup.object({ + quantity: Yup.number() + .required("این فیلد اجباری است!") + .typeError("لطفا عدد وارد کنید!"), + }), + }); + + useEffect(() => { + formik.validateForm(); + dispatch(LOADING_START()); + dispatch(avicultureGetPoultry()).then((r) => { + setpolutryData(r.payload.data); + dispatch(LOADING_END()); + }); + }, []); + + useEffect(() => { + if (poultryKey) { + if (numberOfhalls === 0) { + openNotif({ + vertical: "top", + horizontal: "center", + msg: "ابتدا برای این مرغداری جوجه ریزی ثبت کنید.", + severity: "error", + }); + dispatch(DRAWER({ right: false, bottom: false, content: null })); + } else { + setEnableHall(false); + } + } + }, [poultryKey]); + + return ( + + + + ({ + id: i.key, + label: i.unitName, + halls: i.numberOfHalls, + })) + : [] + } + onChange={(event, value) => { + setPolutryKey(value.id); + setNumberOfHalls(value.halls); + }} + renderInput={(params) => ( + + )} + /> + + + ({ + label: "سالن شماره " + (i + 1), + id: i, + }))} + onChange={(event, value) => { + setNumberOfHallSelected(value.id + 1); + }} + renderInput={(params) => ( + + )} + /> + + + } + value={formik.values.hatchingDate} + error={ + formik.touched.hatchingDate + ? Boolean(formik.errors.hatchingDate) + : null + } + onChange={(e) => { + formik.setFieldValue( + "hatchingDate", + moment(e).format("YYYY-MM-DD hh:mm:ss") + ); + }} + onBlur={formik.handleBlur} + helperText={ + formik.touched.hatchingDate && Boolean(formik.errors.hatchingDate) + ? formik.errors.hatchingDate + : null + } + /> + + نژاد مرغ + + + {formik.touched.race && Boolean(formik.errors.race) + ? formik.errors.race + : null} + + + + + + + + + ); +}; diff --git a/src/features/aviculture/components/aviculture-new-request/AvicultureNewRequest.js b/src/features/aviculture/components/aviculture-new-request/AvicultureNewRequest.js new file mode 100644 index 0000000..4292cb2 --- /dev/null +++ b/src/features/aviculture/components/aviculture-new-request/AvicultureNewRequest.js @@ -0,0 +1,1178 @@ +import { + Autocomplete, + Button, + Checkbox, + Divider, + FormControl, + FormControlLabel, + // FormGroup, + // FormControlLabel, + FormHelperText, + FormLabel, + IconButton, + InputAdornment, + InputLabel, + ListItem, + ListItemIcon, + ListItemText, + MenuItem, + Radio, + // Radio, + RadioGroup, + Select, + TextField, + Typography, +} from "@mui/material"; +import { Grid } from "../../../../components/grid/Grid"; +import { SPACING } from "../../../../data/spacing"; +import { useEffect } from "react"; +import { DatePicker } from "@mui/x-date-pickers"; +import { useDispatch, useSelector } from "react-redux"; +import { avicultureNewRequest } from "../../services/aviculture-new-request"; +import { + DRAWER, + LOADING_END, + LOADING_START, +} from "../../../../lib/redux/slices/appSlice"; +import { useFormik } from "formik"; +import { Yup } from "../../../../lib/yup/yup"; +import moment from "moment"; +import { useState } from "react"; +import { avicultureGetHatchingData } from "../../services/aviculture-get-hatching-data"; +import { avicultureGetPoultry } from "../../services/aviculture-get-poultry"; +import { avicultureGetChickenPrice } from "../../services/aviculture-get-chicken-price"; +import DeleteIcon from "@mui/icons-material/Delete"; +import { avicultureGetRequests } from "../../services/aviculture-requests"; +import { useContext } from "react"; +import { AppContext } from "../../../../contexts/AppContext"; +import AddIcon from "@mui/icons-material/Add"; +// import { NumericFormat } from "react-number-format"; +import { NumberInput } from "../../../../components/number-format-custom/NumberFormatCustom"; +import { DialogAlert } from "../../../../components/dialog-alert/DialogAlert"; +import useUserProfile from "../../../authentication/hooks/useUserProfile"; +// import { NumberFormatCustom } from "../../../../components/number-format-custom/NumberFormatCustom"; +import DoneIcon from "@mui/icons-material/Done"; +// import { SelectCheck } from "../../../../components/select-check/SelectCheck"; +import { avicultureGetSlaughters } from "../../services/aviculture-get-slaughters"; +import { avicultureGetUnions } from "../../services/aviculture-get-unions"; +import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl"; +import { SelectCheck } from "../../../../components/select-check/SelectCheck"; + +export const AvicultureNewRequest = () => { + const [openNotif] = useContext(AppContext); + const [hatchingKey, sethatchingKey] = useState(""); + const [hatchingData, setHatchingData] = useState(""); + const [hatchingSelected, setHatchingSelected] = useState(""); + const [poultryData, setPoultryData] = useState(""); + const [poultryKey, setPolutryKey] = useState(""); + const [quantity, setQuantity] = useState(""); + const [losses, setlosses] = useState(""); + const [leftOvers, setLeftOvers] = useState(""); + const [isUnion] = useState(false); + const [isStockMarket, setIsStockMarket] = useState(false); + const [pricingKey, setPriceKey] = useState(); + const [chickenBreed, setChickenBreed] = useState(""); + const [chickenCanRequest, setChickenCanRequest] = useState(""); + const [slaughterHousesListForSelect, setSlaughterHousesListForSelect] = + useState([]); + + const [, userProfile] = useUserProfile(); + + const validationSchemaFreeSale = Yup.object().shape({ + name: Yup.string().required("نام اجباری است"), + lastname: Yup.string().required("نام خانوادگی اجباری است"), + mobile: Yup.string().required("موبایل اجباری است"), + province: Yup.string().required("استان اجباری است"), + city: Yup.string().required("شهرستان اجباری است"), + buyerType: Yup.string().required("نوع خریدار اجباری است"), + }); + + const inputArr = [ + { + type: "text", + id: 1, + value: "", + }, + ]; + + const inputArrPrices = [ + { + type: "text", + id: 1, + value: "", + }, + ]; + + const [arr, setArr] = useState(inputArr); + const [arrPrices, setArrPrices] = useState(inputArrPrices); + + const dispatch = useDispatch(); + + const { avicultureChickenPrice } = useSelector( + (state) => state.avicultureSlice + ); + + const { avicultureSlaughters } = useSelector( + (state) => state.avicultureSlice + ); + + useEffect(() => { + setSlaughterHousesListForSelect( + avicultureSlaughters?.map((item) => { + return { + label: `${item.name} (${item.killHouseOperator?.user?.fullname})`, + value: `${item.name} (${item.killHouseOperator?.user?.fullname})`, + }; + }) + ); + }, [avicultureSlaughters]); + + useEffect(() => { + dispatch(LOADING_START()); + dispatch(avicultureGetChickenPrice()); + dispatch(avicultureGetSlaughters()); + dispatch(LOADING_END()); + }, []); + + const [unions, setUnions] = useState(); + const [unionSelected, setUnionSelected] = useState(); + + useEffect(() => { + dispatch(LOADING_START()); + dispatch(avicultureGetUnions()).then((r) => { + setUnionSelected(r.payload.data[0]?.key); + setUnions(r.payload.data); + }); + dispatch(LOADING_END()); + }, []); + + const addInput = () => { + if (arr.length < 3) { + setArr((prevState) => { + return [ + ...prevState, + { + type: "text", + value: "", + }, + ]; + }); + + setArrPrices((prevState) => { + return [ + ...prevState, + { + type: "text", + value: "", + }, + ]; + }); + } + }; + + const removeInput = () => { + const number = arr.length - 1; + + if (number !== 0) { + const filteredArrayPrice = arr.filter((object, i) => i !== number); + const filteredArrayTime = arrPrices.filter((object, i) => i !== number); + + setArr(filteredArrayPrice); + setArrPrices(filteredArrayTime); + } + + // setArr((s) => { + // return s.splice(arr.findIndex((item) => item.id === number, 1)); + // }); + + // setArrPrices((s) => { + // return s.splice(arr.findIndex((item) => item.id === number, 1)); + // }); + }; + + const handleChange = (e) => { + e.preventDefault(); + + const index = e.target.id; + setArr((s) => { + const newArr = s.slice(); + newArr[index].value = e.target.value; + + return newArr; + }); + }; + + const handleChangeTime = (e) => { + e.preventDefault(); + + const index = e.target.id; + + setArrPrices((s) => { + const newArrPrice = s.slice(); + newArrPrice[index].value = e.target.dataset.value; + + return newArrPrice; + }); + }; + + useEffect(() => { + if (avicultureChickenPrice) { + setPriceKey(avicultureChickenPrice?.key); + } + }, [avicultureChickenPrice]); + const formik = useFormik({ + initialValues: { + noChicken: "", + sellType: { + cash: true, + haveTime: false, + }, + price1: "", + price2: "", + price3: "", + slaughterDate: moment(Date()).format("YYYY-MM-DD hh:mm:ss"), + period1: "4", + period2: "4", + period3: "4", + weight: "", + losses: "0", + isUnion, + isStockMarket, + isAccepted: false, + selectedSlaughters: [], + }, + validationSchema: Yup.object({ + noChicken: Yup.string() + .required("این فیلد اجباری است!") + .typeError("لطفا عدد وارد کنید!") + .min(0, "تعداد وارد شده از حداقل ممکن کمتر است") + .max(chickenCanRequest, "تعداد وارد شده از کل موجودی بیشتر است"), + isAccepted: Yup.boolean() + .test("req", "باید تعهد نامه را بپذیرید!", (val, context) => { + return context.originalValue && context.originalValue === true; + }) + .required("این فیلد اجباری است!"), + price1: Yup.number() + .typeError("لطفا عدد وارد کنید!") + .min( + avicultureChickenPrice?.floorPrice, + "قیمت وارد شده از کف قیمت امروز کمتر است" + ) + .max( + avicultureChickenPrice?.ceilingPrice, + "قیمت وارد شده از سقف قیمت امروز بیشتر است" + ), + price2: Yup.number() + .typeError("لطفا عدد وارد کنید!") + .min( + avicultureChickenPrice?.floorPrice, + "قیمت وارد شده از کف قیمت امروز کمتر است" + ) + .max( + avicultureChickenPrice?.ceilingPrice, + "قیمت وارد شده از سقف قیمت امروز بیشتر است" + ), + price3: Yup.number() + .typeError("لطفا عدد وارد کنید!") + .min( + avicultureChickenPrice?.floorPrice, + "قیمت وارد شده از کف قیمت امروز کمتر است" + ) + .max( + avicultureChickenPrice?.ceilingPrice, + "قیمت وارد شده از سقف قیمت امروز بیشتر است" + ), + weight: Yup.number() + .test("weight", "وزن را تا دو رقم اعشار وارد کنید", (val, context) => { + return ( + context.originalValue && + context.originalValue.toString().length <= 4 + ); + }) + .required("این فیلد اجباری است!") + .typeError("لطفا وزن را وارد کنید!"), + losses: Yup.number() + .required("این فیلد اجباری است!") + .max(quantity, "تلفات وارد شده از باقیمانده بیشتر است!") + .typeError("لطفا تعداد تلفات را وارد کنید!"), + sellType: Yup.object() + .test("sellType", "نحوه فروش را انتخاب کنید!", (val, context) => { + return ( + context.originalValue && + Object.values(context.originalValue).some((item) => item === true) + ); + }) + .required("این فیلد اجباری است!"), + }), + }); + + const penaltyPrice = formik.values.noChicken * 1000; + const dialogContent = ( + <> + + اینجانب {userProfile.fullname} موافقت خود را نسبت به موارد ذکر شده اعلام + می نمایم. + + + + + + + + + + ); + + useEffect(() => { + dispatch(LOADING_START()); + dispatch(avicultureGetPoultry()).then((r) => { + setPoultryData(r.payload.data); + dispatch(LOADING_END()); + }); + }, []); + + useEffect(() => { + let newVal = formik.values.weight; + const mystring = formik.values.weight.toString().split(".").join(""); + if (formik.values.weight) { + if (mystring.length <= 3) { + if (mystring.length === 2) { + newVal = mystring[0] + "." + mystring[1]; + } + if (mystring.length === 3) { + newVal = mystring[0] + "." + mystring[1] + mystring[2]; + } + } + } + if (isNaN(Number.parseFloat(newVal))) { + formik.setFieldValue("weight", ""); + } else { + formik.setFieldValue("weight", Number.parseFloat(newVal)); + } + }, [formik.values.weight]); + + useEffect(() => { + if (isStockMarket) { + dispatch(avicultureGetChickenPrice()).then((r) => { + if (Array.isArray(r.payload.data)) { + openNotif({ + vertical: "top", + horizontal: "center", + msg: "قیمت روز مرغ در سامانه ثبت نشده است.", + severity: "error", + }); + + dispatch(DRAWER({ right: false, bottom: false, content: null })); + } else { + dispatch(LOADING_END()); + } + }); + } + }, [isStockMarket]); + + useEffect(() => { + formik.validateForm(); + formikFreeSale.validateForm(); + }, []); + + useEffect(() => { + if (poultryKey) { + dispatch(LOADING_START()); + dispatch(avicultureGetHatchingData({ key: poultryKey })).then((r) => { + if (r.payload.data) { + setHatchingData(r.payload.data); + + dispatch(LOADING_END()); + } else { + openNotif({ + vertical: "top", + horizontal: "center", + msg: "اطلاعات جوجه ریزی یافت نشد!", + severity: "error", + }); + } + dispatch(LOADING_END()); + }); + } + }, [poultryKey]); + + useEffect(() => { + setChickenCanRequest( + formik.values.noChicken <= Number(leftOvers) && + Number(formik.values.losses) <= Number(leftOvers) + ? Number(leftOvers) - Number(formik.values.losses) + : 0 + ); + }, [formik.values.losses, leftOvers, formik.values.noChicken]); + + useEffect(() => { + setQuantity(hatchingSelected.quantity); + setlosses(hatchingSelected.losses); + setLeftOvers(hatchingSelected.leftOver); + }, [hatchingSelected]); + + // const handleSellTypeChange = (event) => { + // formik.setFieldValue("sellType", { + // ...formik.values.sellType, + // [event.target.name]: event.target.checked, + // }); + // }; + + const formikFreeSale = useFormik({ + initialValues: { + name: "", + lastname: "", + mobile: "", + province: "", + city: "", + buyerType: "", + }, + validationSchemaFreeSale, + onSubmit: (values) => { + // console.log(values); + }, + }); + + return ( + + + + ({ + id: i.key, + label: i.unitName, + })) + : [] + } + onChange={(event, value) => { + setPolutryKey(value.id); + }} + renderInput={(params) => ( + + )} + /> + + + + { + return { + id: i.key, + race: i.chickenBreed, + selected: i, + label: `دوره ${i.period} سالن ${i.hall} نژاد ${i.chickenBreed} باقیمانده ${i.leftOver} قطعه`, + }; + }) + : [] + } + onChange={(event, value) => { + sethatchingKey(value.id); + setHatchingSelected(value.selected); + let race = value.race; + if (race.includes("-")) { + race = "ترکیبی"; + } + setChickenBreed(race); + }} + renderInput={(params) => ( + + )} + /> + + + + + + + + + + + + + {hatchingSelected && ( + + اطلاعات کشتار + {getRoleFromUrl() !== "Poultry" && ( + + + + + + )} + + {/* */} + + + + + + prop.palette.grey["A700"]} + variant={"caption"} + > + باقیمانده: + + + {formik.values.noChicken + ? formik.values.noChicken <= Number(leftOvers) && + Number(formik.values.losses) <= Number(leftOvers) && + Number(leftOvers) - + Number(formik.values.losses) - + Number(formik.values.noChicken) >= + 0 + ? Math.abs( + Number(leftOvers) - + Number(formik.values.losses) - + Number(formik.values.noChicken) + ) + : 0 + : Number(leftOvers)} + + + قطعه + + + + prop.palette.grey["A700"]} + variant={"caption"} + > + سن مرغ: + + + {hatchingSelected.age} + + روزه + + + + + + } + value={formik.values.slaughterDate} + error={ + formik.touched.slaughterDate + ? Boolean(formik.errors.slaughterDate) + : null + } + onChange={(e) => { + formik.setFieldValue( + "slaughterDate", + moment(e).format("YYYY-MM-DD hh:mm:ss") + ); + }} + onBlur={formik.handleBlur} + helperText={ + formik.touched.slaughterDate && + Boolean(formik.errors.slaughterDate) + ? formik.errors.slaughterDate + : null + } + /> + + + کیلوگرم + ), + }} + value={formik.values.weight} + error={ + formik.touched.weight ? Boolean(formik.errors.weight) : null + } + onChange={formik.handleChange} + onBlur={formik.handleBlur} + helperText={ + formik.touched.weight && Boolean(formik.errors.weight) + ? formik.errors.weight + : null + } + /> + + + {/* + نحوه فروش + */} + + + { + setIsStockMarket(event.currentTarget.value); + }} + > + {/* } + label="فروش اتحادیه" + /> */} + {/* + } + label="فروش مزایده ای" + /> */} + {isStockMarket === "فروش مزایده ای" && ( + + + prop.palette.grey["A700"]} + variant={"caption"} + > + کف قیمت امروز: + + + {avicultureChickenPrice?.floorPrice + ? avicultureChickenPrice?.floorPrice.toLocaleString() + : "نامشخص"}{" "} + {" "} + ریال + + + + prop.palette.grey["A700"]} + variant={"caption"} + > + سقف قیمت امروز: + + + {avicultureChickenPrice?.ceilingPrice + ? avicultureChickenPrice?.ceilingPrice.toLocaleString() + : "نامشخص"}{" "} + {" "} + ریال + + + + + + {arr.map((item, i) => { + return ( + + + پیشنهاد {i + 1} + + + + + + + بازه زمانی (ساعت) + + + + {formik.touched.period1 && + Boolean(formik.errors.period1) + ? formik.errors.period1 + : null} + + + {/* */} + + ); + })} + + + {arr.length > 1 && ( + + + + )} + {arr.length < 3 && ( + + + افزودن پیشنهاد جدید + + )} + + + + + در صورت عدم فروش در بورس، از طریق اتحادیه فروش برود + + + + + )} + + + + + {poultryData?.length && + poultryData[0]?.provinceAllowChooseKillHouse && ( + + + formik.setFieldValue("selectedSlaughters", e) + } + options={slaughterHousesListForSelect} + /> + + {formik.values.selectedSlaughters && ( + کشتارگاهای انتخابی + )} + + {formik.values.selectedSlaughters.map((item, i) => { + return ( + + {i + 1}- {item} + + ); + })} + + + + )} + + {/* + + نحوه فروش + + + + } + label="نقدی" + /> + + } + label="زمان دار (تا یک ماه)" + /> + + + {formik.touched.sellType && Boolean(formik.errors.sellType) + ? formik.errors.sellType + : null} + + */} + + {/* {unions?.length > 1 && ( + <> */} + + + + + اطلاعات تعاونی + + { + setUnionSelected(event.currentTarget.value); + }} + > + {unions?.map((item) => { + return ( + } + /> + ); + })} + + + + {/* + )} */} + + + + + + } + btnTitle={"با تعهد نامه موافق هستم!"} + isAccepted={formik.values.isAccepted} + /> + + + + + + )} + + ); +}; diff --git a/src/features/aviculture/components/aviculture-number-of-halls/AvicultureNumberOfHalls.js b/src/features/aviculture/components/aviculture-number-of-halls/AvicultureNumberOfHalls.js new file mode 100644 index 0000000..e69de29 diff --git a/src/features/aviculture/components/aviculture-profile/AvicultureProfile.js b/src/features/aviculture/components/aviculture-profile/AvicultureProfile.js new file mode 100644 index 0000000..ffbdff2 --- /dev/null +++ b/src/features/aviculture/components/aviculture-profile/AvicultureProfile.js @@ -0,0 +1,84 @@ +import { Box } from "@mui/system"; +import { format } from "date-fns-jalali"; +import { useEffect } from "react"; +import { useDispatch, useSelector } from "react-redux"; +import { Grid } from "../../../../components/grid/Grid"; +import { SimpleTable } from "../../../../components/simple-table/SimpleTable"; +import { SPACING } from "../../../../data/spacing"; +import { + LOADING_END, + LOADING_START, +} from "../../../../lib/redux/slices/appSlice"; +import { ChangeCardInfo } from "../../../authentication/components/change-card-info/ChangeCardInfo"; +import { avicultureGetProfile } from "../../services/aviculture-get-profile"; + +export const AvicultureProfile = () => { + const { profile } = useSelector((state) => state.avicultureSlice); + const dispatch = useDispatch(); + + useEffect(() => { + dispatch(LOADING_START()); + dispatch(avicultureGetProfile()).then((r) => { + dispatch(LOADING_END()); + }); + }, []); + + const avicultures = profile?.aviculture; + + return ( + + + + + {avicultures?.map((item, i) => ( + <> + + + + + + + + ))} + + + + + ); +}; diff --git a/src/features/aviculture/components/aviculture-rejected-requests/AvicultureRejectedRequests.js b/src/features/aviculture/components/aviculture-rejected-requests/AvicultureRejectedRequests.js new file mode 100644 index 0000000..7648d52 --- /dev/null +++ b/src/features/aviculture/components/aviculture-rejected-requests/AvicultureRejectedRequests.js @@ -0,0 +1,79 @@ +import { Card, IconButton } from "@mui/material"; +import { useEffect, useState } from "react"; +import { AdvancedTable } from "../../../../components/advanced-table/AdvancedTable"; +import PlagiarismIcon from "@mui/icons-material/Plagiarism"; +import { useNavigate } from "react-router-dom"; +import { ROUTE_AVICULTURE_FILE } from "../../../../routes/routes"; +import { useDispatch, useSelector } from "react-redux"; +import { avicultureGetRequests } from "../../services/aviculture-requests"; +import { formatJustDate } from "../../../../utils/formatTime"; + +export const AvicultureRejectedRequests = () => { + const navigate = useNavigate(); + const [dataTable, setDataTable] = useState([]); + const { avicultureRequests } = useSelector((state) => state.avicultureSlice); + + const dispatch = useDispatch(); + + useEffect(() => { + dispatch(avicultureGetRequests()); + }, []); + + useEffect(() => { + const filteredData = avicultureRequests?.filter( + (item) => + item.stateProcess === "rejected" || item.provinceState === "rejected" + ); + const d = filteredData?.map((item, i) => { + return [ + i + 1, + item.orderCode, + formatJustDate(item?.createDate), + formatJustDate(item?.sendDate), + item?.process?.poultry?.poultryName, + item?.process?.poultry?.poultryMobile, + item?.process?.poultry?.poultryCity, + item?.process?.poultry?.poultryProvince, + item?.process?.poultry?.age, + item?.process?.poultry?.poultryQuantity, + + navigate( + ROUTE_AVICULTURE_FILE + item?.process?.poultry?.poultryRequestId + ) + } + > + + , + ]; + }); + + setDataTable(d); + }, [avicultureRequests]); + + const [tableDataCol] = useState([ + "ردیف", + "کد سفارش", + "تاریخ ثبت درخواست", + "تاریخ درخواست", + "مرغدار", + "تلفن مرغدار", + "شهر", + "استان", + "سن مرغ", + "تعداد", + "مشاهده", + ]); + return ( + + + + ); +}; diff --git a/src/features/aviculture/components/aviculture-reports-charts/AvicultureReportsCharts.js b/src/features/aviculture/components/aviculture-reports-charts/AvicultureReportsCharts.js new file mode 100644 index 0000000..999392b --- /dev/null +++ b/src/features/aviculture/components/aviculture-reports-charts/AvicultureReportsCharts.js @@ -0,0 +1,84 @@ +import { Card, CardActionArea, CardContent, Typography } from "@mui/material"; +import React, { useEffect, useState } from "react"; +import ChartBar from "../../../../components/chart-bar/ChartBar"; +import { Grid } from "../../../../components/grid/Grid"; +import { SPACING } from "../../../../data/spacing"; +import { PropTypes } from "prop-types"; +import { formatJustDate } from "../../../../utils/formatTime"; +import ChartLinear from "../../../../components/chart-linear/ChartLenear"; + +export const AvicultureReportsCharts = ({ data }) => { + const [hatching, setHatching] = useState({ datasets: [] }); + const [hatchingWeight, setHatchingWeight] = useState({ datasets: [] }); + + useEffect(() => { + setHatching({ + labels: data?.hatchingChart?.map((data) => formatJustDate(data?.date)), + datasets: [ + { + label: "تعداد", + backgroundColor: ["rgba(33, 72, 214, 0.7)"], + data: data?.hatchingChart?.map((data) => data?.quantity), + borderRadius: 5, + }, + { + label: "تلفات", + backgroundColor: ["rgba(100, 130, 160, 0.7)"], + data: data.hatchingChart?.map((data) => data?.losses), + borderRadius: 5, + }, + ], + }); + + setHatchingWeight({ + labels: data?.weightChart?.map((data) => formatJustDate(data?.date)), + datasets: [ + { + label: "قیمت", + backgroundColor: ["rgba(33, 72, 214, 0.7)"], + data: data?.weightChart?.map((data) => data?.weight), + borderRadius: 5, + }, + ], + }); + }, []); + + return ( + + + + + + + نمودار حجم جوجه ریزی و تلفات دوره + + + + + + + + + + + + نمودار پایش وزن و بهره وری وزن + + + + + + + + + ); +}; + +AvicultureReportsCharts.propTypes = { + data: PropTypes.any, +}; diff --git a/src/features/aviculture/components/dashboard-operations/DashboardOperations.js b/src/features/aviculture/components/dashboard-operations/DashboardOperations.js new file mode 100644 index 0000000..fbaa491 --- /dev/null +++ b/src/features/aviculture/components/dashboard-operations/DashboardOperations.js @@ -0,0 +1,68 @@ +import { Grid } from "../../../../components/grid/Grid"; +import { SPACING } from "../../../../data/spacing"; +import { NavLink } from "../../../../components/nav-link/NavLink"; +import { useLocation } from "react-router-dom"; +import { Button } from "@mui/material"; +import { + ROUTE_USER_CHANGE_BANK_ACCOUNT, + ROUTE_USER_CHANGE_PASSWORD, + ROUTE_USER_CHANGE_PROFILE_INFO, + ROUTE_USER_CHANGE_PROFILE_PICTURE, + ROUTE_USER_PROFILE, +} from "../../../../routes/routes"; + +export const DashboardOperations = () => { + const { pathname } = useLocation(); + + return ( + + + + + + + + + + + + + + + + + + ); +}; diff --git a/src/features/aviculture/components/province-free-sale-new-request/ProvinceFreeSaleNewRequest.js b/src/features/aviculture/components/province-free-sale-new-request/ProvinceFreeSaleNewRequest.js new file mode 100644 index 0000000..3bb18bc --- /dev/null +++ b/src/features/aviculture/components/province-free-sale-new-request/ProvinceFreeSaleNewRequest.js @@ -0,0 +1,1868 @@ +import { + Autocomplete, + Button, + Checkbox, + Divider, + FormControl, + FormControlLabel, + // FormGroup, + // FormControlLabel, + FormHelperText, + FormLabel, + IconButton, + InputAdornment, + InputLabel, + ListItem, + ListItemIcon, + ListItemText, + MenuItem, + Radio, + // Radio, + RadioGroup, + Select, + TextField, + Typography, +} from "@mui/material"; +import { Grid } from "../../../../components/grid/Grid"; +import { SPACING } from "../../../../data/spacing"; +import { useEffect } from "react"; +import { DatePicker } from "@mui/x-date-pickers"; +import { useDispatch, useSelector } from "react-redux"; +import { avicultureNewRequest } from "../../services/aviculture-new-request"; +import { LabelField } from "../../../../components/label-field/LabelField"; +import { + DRAWER, + LOADING_END, + LOADING_START, +} from "../../../../lib/redux/slices/appSlice"; +import { useFormik } from "formik"; +import { Yup } from "../../../../lib/yup/yup"; +import moment from "moment"; +import { useState } from "react"; +import { avicultureGetHatchingData } from "../../services/aviculture-get-hatching-data"; +import { avicultureGetChickenPrice } from "../../services/aviculture-get-chicken-price"; +import DeleteIcon from "@mui/icons-material/Delete"; +import { avicultureGetRequests } from "../../services/aviculture-requests"; +import { useContext } from "react"; +import { AppContext } from "../../../../contexts/AppContext"; +import AddIcon from "@mui/icons-material/Add"; +// import { NumericFormat } from "react-number-format"; +import { NumberInput } from "../../../../components/number-format-custom/NumberFormatCustom"; +import { DialogAlert } from "../../../../components/dialog-alert/DialogAlert"; +// import useUserProfile from "../../../authentication/hooks/useUserProfile"; +// import { NumberFormatCustom } from "../../../../components/number-format-custom/NumberFormatCustom"; +import DoneIcon from "@mui/icons-material/Done"; +// import { SelectCheck } from "../../../../components/select-check/SelectCheck"; +import { avicultureGetSlaughters } from "../../services/aviculture-get-slaughters"; +import { avicultureGetUnions } from "../../services/aviculture-get-unions"; +import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl"; +import { provinceGetPoultry } from "../../services/province-get-poultry"; +import { CarPelak } from "../../../../components/car-pelak/CarPelak"; +import { avicultureGetWageType } from "../../services/aviculture-get-wage-type"; +import { provinceFreeSaleBuyers } from "../../../province/services/province-free-sales-get-buyers"; +import RemoveIcon from "@mui/icons-material/Remove"; +import { provincePolicyGetWeightRange } from "../../../province/services/province-policy-get-weight-range"; +import { isValidIndexWeight } from "../../../../utils/isValidIndexWeight"; + +export const ProvinceFreeSaleNewRequest = ({ fetchApiData }) => { + const [openNotif] = useContext(AppContext); + const [hatchingKey, sethatchingKey] = useState(""); + const [hatchingData, setHatchingData] = useState(""); + const [hatchingSelected, setHatchingSelected] = useState(""); + const [poultryData, setPoultryData] = useState(""); + const [poultryKey, setPolutryKey] = useState(""); + const [quantity, setQuantity] = useState(""); + const [losses, setlosses] = useState(""); + const [leftOvers, setLeftOvers] = useState(""); + const [isUnion] = useState(false); + const [isStockMarket, setIsStockMarket] = useState(false); + const [pricingKey, setPriceKey] = useState(); + const [chickenBreed, setChickenBreed] = useState(""); + const [chickenCanRequest, setChickenCanRequest] = useState(""); + const [poultry, setPoultry] = useState(); + const [buyersData, setBuyersData] = useState([]); + const [buyerSelected, setBuyerSelected] = useState(); + const [buyerItem, setBuyerItem] = useState(); + const [selectedHatchingLabel, setSelectedHatchingLabel] = useState(); + const [payerValue, setPayerValue] = useState("poultry"); + const [submitDriver, setSubmitDriver] = useState(false); + const [transportHealthCodes, setTransportHealthCodes] = useState([]); + const [showHealthCodeForm, setShowHealthCodeForm] = useState(false); + + const handleChangePayer = (event) => { + setPayerValue(event.target.value); + if (event.target.value === "poultry") { + formikPayer.setFieldValue("mobile", poultry?.user?.mobile); + } else { + if (buyerItem) { + formikPayer.setFieldValue("mobile", buyerItem.mobile); + } else { + formikPayer.setFieldValue("mobile", ""); + } + } + }; + + // const [, userProfile] = useUserProfile(); + + const [driverPelak, setDriverPelak] = useState([]); + + const carPelakHandleChange = (pelak1, pelak2, pelak3, pelak4) => { + setDriverPelak([pelak1, pelak2, pelak3, pelak4]); + }; + + const inputArr = [ + { + type: "text", + id: 1, + value: "", + }, + ]; + + const inputArrPrices = [ + { + type: "text", + id: 1, + value: "", + }, + ]; + const [arr, setArr] = useState(inputArr); + const [arrPrices, setArrPrices] = useState(inputArrPrices); + const [wageType, setWageType] = useState(); + const { weightRange } = useSelector((state) => state.provinceSlice); + + const dispatch = useDispatch(); + + const { avicultureChickenPrice } = useSelector( + (state) => state.avicultureSlice + ); + + useEffect(() => { + dispatch(LOADING_START()); + dispatch(avicultureGetChickenPrice()); + dispatch(avicultureGetSlaughters()); + dispatch(avicultureGetWageType()).then((r) => { + setWageType(r.payload.data.status); + }); + dispatch(provinceFreeSaleBuyers()).then((r) => { + setBuyersData(r.payload.data); + }); + dispatch(LOADING_END()); + }, []); + + const [unions, setUnions] = useState(); + const [unionSelected, setUnionSelected] = useState(); + + useEffect(() => { + dispatch(LOADING_START()); + dispatch(provincePolicyGetWeightRange()); + dispatch(avicultureGetUnions()).then((r) => { + if (r?.payload?.data?.length > 0) { + setUnions(r?.payload?.data[0]?.key); + } else { + setUnions([]); + } + }); + dispatch(LOADING_END()); + }, []); + + const addInput = () => { + if (arr.length < 3) { + setArr((prevState) => { + return [ + ...prevState, + { + type: "text", + value: "", + }, + ]; + }); + + setArrPrices((prevState) => { + return [ + ...prevState, + { + type: "text", + value: "", + }, + ]; + }); + } + }; + + const removeInput = () => { + const number = arr.length - 1; + + if (number !== 0) { + const filteredArrayPrice = arr.filter((object, i) => i !== number); + const filteredArrayTime = arrPrices.filter((object, i) => i !== number); + + setArr(filteredArrayPrice); + setArrPrices(filteredArrayTime); + } + + // setArr((s) => { + // return s.splice(arr.findIndex((item) => item.id === number, 1)); + // }); + + // setArrPrices((s) => { + // return s.splice(arr.findIndex((item) => item.id === number, 1)); + // }); + }; + + const handleChange = (e) => { + e.preventDefault(); + + const index = e.target.id; + setArr((s) => { + const newArr = s.slice(); + newArr[index].value = e.target.value; + + return newArr; + }); + }; + + const handleChangeTime = (e) => { + e.preventDefault(); + + const index = e.target.id; + + setArrPrices((s) => { + const newArrPrice = s.slice(); + newArrPrice[index].value = e.target.dataset.value; + + return newArrPrice; + }); + }; + + useEffect(() => { + if (avicultureChickenPrice) { + setPriceKey(avicultureChickenPrice?.key); + } + }, [avicultureChickenPrice]); + const formik = useFormik({ + initialValues: { + noChicken: "", + sellType: { + cash: true, + haveTime: false, + }, + price1: "", + price2: "", + price3: "", + slaughterDate: moment(Date()).format("YYYY-MM-DD"), + period1: "4", + period2: "4", + period3: "4", + weight: "", + losses: "0", + isUnion, + isStockMarket, + isAccepted: false, + selectedSlaughters: [], + killer_kill_house_city: "", + killer_kill_house_province: "", + killer_kill_house_unit_name: "", + kill_house_unique_id: "", + intermediaryNumber: "", + }, + validationSchema: Yup.object({ + noChicken: Yup.string() + .required("این فیلد اجباری است!") + .typeError("لطفا عدد وارد کنید!") + .min(0, "تعداد وارد شده از حداقل ممکن کمتر است") + .max(chickenCanRequest, "تعداد وارد شده از کل موجودی بیشتر است"), + isAccepted: Yup.boolean() + .test("req", "باید تعهد نامه را بپذیرید!", (val, context) => { + return context.originalValue && context.originalValue === true; + }) + .required("این فیلد اجباری است!"), + price1: Yup.number() + .typeError("لطفا عدد وارد کنید!") + .min( + avicultureChickenPrice?.floorPrice, + "قیمت وارد شده از کف قیمت امروز کمتر است" + ) + .max( + avicultureChickenPrice?.ceilingPrice, + "قیمت وارد شده از سقف قیمت امروز بیشتر است" + ), + price2: Yup.number() + .typeError("لطفا عدد وارد کنید!") + .min( + avicultureChickenPrice?.floorPrice, + "قیمت وارد شده از کف قیمت امروز کمتر است" + ) + .max( + avicultureChickenPrice?.ceilingPrice, + "قیمت وارد شده از سقف قیمت امروز بیشتر است" + ), + price3: Yup.number() + .typeError("لطفا عدد وارد کنید!") + .min( + avicultureChickenPrice?.floorPrice, + "قیمت وارد شده از کف قیمت امروز کمتر است" + ) + .max( + avicultureChickenPrice?.ceilingPrice, + "قیمت وارد شده از سقف قیمت امروز بیشتر است" + ), + weight: Yup.number() + .test("weight", "وزن را تا دو رقم اعشار وارد کنید", (val, context) => { + return ( + context.originalValue && + context.originalValue.toString().length <= 4 + ); + }) + .required("این فیلد اجباری است!") + .typeError("لطفا وزن را وارد کنید!"), + losses: Yup.number() + .required("این فیلد اجباری است!") + .max(quantity, "تلفات وارد شده از باقیمانده بیشتر است!") + .typeError("لطفا تعداد تلفات را وارد کنید!"), + sellType: Yup.object() + .test("sellType", "نحوه فروش را انتخاب کنید!", (val, context) => { + return ( + context.originalValue && + Object.values(context.originalValue).some((item) => item === true) + ); + }) + .required("این فیلد اجباری است!"), + intermediaryNumber: Yup.string() + .min(11, "شماره موبایل باید 11 رقم باشد") + .max(11, "شماره موبایل باید 11 رقم باشد") + .matches(/^09\d{9}$/, "شماره موبایل باید با 09 شروع شود و 11 رقم باشد"), + }), + }); + + const formikDriver = useFormik({ + initialValues: { + driverName: "", + driverMobile: "", + driverCar: "", + driverhealthCode: "", + }, + validationSchema: Yup.object({ + driverName: Yup.string().required("این فیلد اجباری است!"), + driverMobile: Yup.string() + .required("این فیلد اجباری است!") + .min(11, "شماره موبایل باید 11 رقم باشد") + .max(11, "شماره موبایل باید 11 رقم باشد") + .matches(/^09\d{9}$/, "شماره موبایل باید با 09 شروع شود و 11 رقم باشد"), + driverCar: Yup.string().required("این فیلد اجباری است!"), + driverhealthCode: Yup.string() + .required("این فیلد اجباری است!") + .matches( + /^[^*&^%$#@!()|.]*$/, + "این فیلد نباید شامل کاراکترهای ویژه باشد!" + ), + }), + }); + + const formikPayer = useFormik({ + initialValues: { + mobile: "", + weight: "", + quantity: "", + }, + validationSchema: Yup.object({ + mobile: Yup.string() + .required("شماره موبایل الزامی است") + .min(11, "شماره موبایل باید 11 رقم باشد") + .max(11, "شماره موبایل باید 11 رقم باشد") + .matches(/^09\d{9}$/, "شماره موبایل باید با 09 شروع شود و 11 رقم باشد"), + weight: Yup.number(), + quantity: Yup.number(), + }), + }); + + const formikTransportHealthCode = useFormik({ + initialValues: { + healthCode: "", + }, + validationSchema: Yup.object({ + healthCode: Yup.string() + .required("این فیلد اجباری است!") + .matches( + /^[^*&^%$#@!()|.]*$/, + "این فیلد نباید شامل کاراکترهای ویژه باشد!" + ), + }), + }); + + const handleAddTransportHealthCode = () => { + if (formikTransportHealthCode.values.healthCode.trim()) { + setTransportHealthCodes([ + ...transportHealthCodes, + formikTransportHealthCode.values.healthCode, + ]); + formikTransportHealthCode.resetForm(); + setShowHealthCodeForm(false); + } + }; + + const handleRemoveTransportHealthCode = (indexToRemove) => { + setTransportHealthCodes( + transportHealthCodes.filter((_, index) => index !== indexToRemove) + ); + }; + + useEffect(() => { + formikPayer.setFieldValue("mobile", poultry?.user?.mobile); + }, [poultry]); + + const penaltyPrice = formik.values.noChicken * 1000; + const dialogContent = ( + <> + + اینجانب {poultry?.user?.fullname} موافقت خود را نسبت به موارد ذکر شده + اعلام می نمایم. + + + + + + + + + + ); + + useEffect(() => { + dispatch(LOADING_START()); + dispatch(provinceGetPoultry()).then((r) => { + setPoultryData(r.payload.data); + dispatch(LOADING_END()); + }); + }, []); + + useEffect(() => { + let newVal = formik.values.weight; + const mystring = formik.values.weight.toString().split(".").join(""); + if (formik.values.weight) { + if (mystring.length <= 3) { + if (mystring.length === 2) { + newVal = mystring[0] + "." + mystring[1]; + } + if (mystring.length === 3) { + newVal = mystring[0] + "." + mystring[1] + mystring[2]; + } + } + } + if (isNaN(Number.parseFloat(newVal))) { + formik.setFieldValue("weight", ""); + } else { + formik.setFieldValue("weight", Number.parseFloat(newVal)); + } + }, [formik.values.weight]); + + useEffect(() => { + if (isStockMarket) { + dispatch(avicultureGetChickenPrice()).then((r) => { + if (Array.isArray(r.payload.data)) { + openNotif({ + vertical: "top", + horizontal: "center", + msg: "قیمت روز مرغ در سامانه ثبت نشده است.", + severity: "error", + }); + + dispatch(DRAWER({ right: false, bottom: false, content: null })); + } else { + dispatch(LOADING_END()); + } + }); + } + }, [isStockMarket]); + + useEffect(() => { + formik.validateForm(); + formikDriver.validateForm(); + }, []); + + useEffect(() => { + if (poultryKey) { + dispatch(LOADING_START()); + dispatch(avicultureGetHatchingData({ key: poultryKey })).then((r) => { + if (r.payload.data) { + setHatchingData(r.payload.data); + + dispatch(LOADING_END()); + } else { + openNotif({ + vertical: "top", + horizontal: "center", + msg: "اطلاعات جوجه ریزی یافت نشد!", + severity: "error", + }); + } + dispatch(LOADING_END()); + }); + } + }, [poultryKey, poultry]); + + useEffect(() => { + setChickenCanRequest(hatchingSelected?.leftOver); + }, [ + formik.values.losses, + leftOvers, + formik.values.noChicken, + hatchingSelected, + ]); + + useEffect(() => { + setQuantity(hatchingSelected?.quantity); + setlosses(hatchingSelected?.losses); + setLeftOvers(hatchingSelected?.leftOver); + }, [hatchingSelected]); + + // const handleSellTypeChange = (event) => { + // formik.setFieldValue("sellType", { + // ...formik.values.sellType, + // [event.target.name]: event.target.checked, + // }); + // }; + + const killerFieldsValidation = () => { + if (buyerItem?.type === "killer") { + return ( + formik.values.killer_kill_house_city && + formik.values.killer_kill_house_province && + formik.values.killer_kill_house_unit_name + ); + } else { + return true; + } + }; + + const wageValidation = () => { + if (wageType) { + return formikPayer.isValid; + } else { + return true; + } + }; + + const isFormValid = () => { + if (payerValue === "poultry") { + if (submitDriver) { + return ( + formik.isValid && + wageValidation() && + buyerSelected && + formikDriver && + driverPelak[0] && + killerFieldsValidation() + ); + } else { + return ( + formik.isValid && + wageValidation() && + buyerSelected && + killerFieldsValidation() + ); + } + } else { + if (submitDriver) { + return ( + formik.isValid && + buyerSelected && + formikDriver && + driverPelak[0] && + killerFieldsValidation() && + wageValidation() + ); + } else { + return ( + formik.isValid && + buyerSelected && + killerFieldsValidation() && + wageValidation() + ); + } + } + }; + + return ( + + + + option.disabled} + options={ + poultryData + ? poultryData.map((i) => ({ + id: i.key, + label: `${i.unitName} / ${ + i.user.mobile + } / ${i.lastHatchingRemainQuantity.toLocaleString()} `, + item: i, + disabled: !i.lastHatchingRemainQuantity, + })) + : [] + } + onChange={(event, value) => { + setHatchingSelected(null); + sethatchingKey(null); + setSelectedHatchingLabel(null); + setPolutryKey(value.id); + setPoultry(value.item); + }} + renderInput={(params) => ( + + )} + /> + + {/* + {!poultry?.provinceAllowSellFree && ( + اجازه فروش بصورت خارج از استان ندارید! + )} */} + + {poultry?.provinceAllowSellFree ? ( + + + { + return { + id: i.key, + race: i.chickenBreed, + selected: i, + label: `دوره ${i.period} سالن ${i.hall} نژاد ${ + i.chickenBreed + } باقیمانده ${ + i?.lastHatchingDiffrentRequestQuantity?.leftOver + ? i?.lastHatchingDiffrentRequestQuantity?.leftOver + : i.leftOver + } قطعه`, + }; + }) + : [] + } + onChange={(event, value) => { + setSelectedHatchingLabel(value.label); + sethatchingKey(value.id); + setHatchingSelected(value.selected); + let race = value.race; + if (race.includes("-")) { + race = "ترکیبی"; + } + setChickenBreed(race); + }} + renderInput={(params) => ( + + )} + /> + + + + + + + + + + + + ) : ( + poultry && ( + + مرغدار اجازه فروش مستقیم ندارد! + + ) + )} + + + {hatchingSelected && ( + + اطلاعات کشتار + {/* {getRoleFromUrl() !== "Poultry" && ( + + + + + + )} */} + + {/* */} + + + prop.palette.grey["A700"]} + variant={"caption"} + > + باقیمانده: + + {chickenCanRequest} + + قطعه + + + + prop.palette.grey["A700"]} + variant={"caption"} + > + سن مرغ: + + + {hatchingSelected.age} + + روزه + + + + + } + value={formik.values.slaughterDate} + error={ + formik.touched.slaughterDate + ? Boolean(formik.errors.slaughterDate) + : null + } + onChange={(e) => { + formik.setFieldValue( + "slaughterDate", + moment(e).format("YYYY-MM-DD") + ); + }} + onBlur={formik.handleBlur} + helperText={ + formik.touched.slaughterDate && + Boolean(formik.errors.slaughterDate) + ? formik.errors.slaughterDate + : null + } + /> + + + + + + + کیلوگرم + ), + }} + value={formik.values.weight} + error={ + formik.touched.weight ? Boolean(formik.errors.weight) : null + } + onChange={formik.handleChange} + onBlur={formik.handleBlur} + helperText={ + formik.touched.weight && Boolean(formik.errors.weight) + ? formik.errors.weight + : null + } + /> + + + + {formik.values.weight && ( + + وزن کل:{" "} + {parseInt( + parseInt(formik.values.noChicken) * + parseFloat(formik.values.weight) + ).toLocaleString()}{" "} + کیلوگرم + + )} + + {/* + نحوه فروش + */} + + + { + setIsStockMarket(event.currentTarget.value); + }} + > + {/* } + label="فروش اتحادیه" + /> */} + {/* + } + label="فروش مزایده ای" + /> */} + {isStockMarket === "فروش مزایده ای" && ( + + + prop.palette.grey["A700"]} + variant={"caption"} + > + کف قیمت امروز: + + + {avicultureChickenPrice?.floorPrice + ? avicultureChickenPrice?.floorPrice.toLocaleString() + : "نامشخص"}{" "} + {" "} + ریال + + + + prop.palette.grey["A700"]} + variant={"caption"} + > + سقف قیمت امروز: + + + {avicultureChickenPrice?.ceilingPrice + ? avicultureChickenPrice?.ceilingPrice.toLocaleString() + : "نامشخص"}{" "} + {" "} + ریال + + + + + + {arr.map((item, i) => { + return ( + + + پیشنهاد {i + 1} + + + + + + + بازه زمانی (ساعت) + + + + {formik.touched.period1 && + Boolean(formik.errors.period1) + ? formik.errors.period1 + : null} + + + {/* */} + + ); + })} + + + {arr.length > 1 && ( + + + + )} + {arr.length < 3 && ( + + + افزودن پیشنهاد جدید + + )} + + + + + در صورت عدم فروش در بورس، از طریق اتحادیه فروش برود + + + + + )} + + + + + اطلاعات خریدار + option.disabled} + options={ + buyersData + ? buyersData?.map((i) => ({ + id: i.key, + label: + i.type === "killhouse" + ? `کشتارگاه ${i?.unitName} / ${i.mobile} / استان ${i?.province}/ ${i?.city}` + : `کشتارکن ${i?.fullname} / ${i.mobile} / استان ${i?.province}/ ${i?.city}`, + item: i, + mobile: i.mobile, + })) + : [] + } + onChange={(event, value) => { + setBuyerSelected(value.id); + setBuyerItem(value.item); + if (payerValue === "buyer") { + formikPayer.setFieldValue("mobile", value.mobile); + } + }} + renderInput={(params) => ( + + )} + /> + + {buyerItem?.type === "killer" && ( + + + + + + + + )} + + + {buyerItem?.key && ( + <> + + { + setSubmitDriver(!submitDriver); + }} + > + + {" "} + افزودن خودرو + + + {submitDriver ? : } + + {submitDriver && ( + + اطلاعات خودرو حمل + + + + + + + + )} + + {/* افزودن کد بهداشتی حمل و نقل */} + + + + کدهای بهداشتی حمل و نقل + + + + {/* Display added health codes */} + {transportHealthCodes.length > 0 && ( + + {transportHealthCodes.map((code, index) => ( + + + + + + + handleRemoveTransportHealthCode(index) + } + aria-label="حذف" + > + + + + + ))} + + )} + + {/* Form to add new health code */} + {showHealthCodeForm && ( + + + + + + + + + + + )} + + {/* Button to show form */} + + + + + + )} + + {wageType && ( + <> + + + + } + label="مرغدار" + sx={{ + marginRight: "auto", + }} + /> + } + label="خریدار" + /> + + + + + + + از این قسمت میتوانید تلفن{" "} + {payerValue === "poultry" ? "مرغدار" : "خریدار"} را ویرایش + کنید. + + + + + )} + + + + + + {/* + + نحوه فروش + + + + } + label="نقدی" + /> + + } + label="زمان دار (تا یک ماه)" + /> + + + {formik.touched.sellType && Boolean(formik.errors.sellType) + ? formik.errors.sellType + : null} + + */} + + {unions?.length > 1 && ( + <> + + + + + انتخاب اتحادیه + + { + setUnionSelected(event.currentTarget.value); + }} + > + {unions.map((item) => { + return ( + <> + } + label={item.unitName} + /> + + ); + })} + + + + + )} + + + + + + + } + btnTitle={"با تعهد نامه موافق هستم!"} + isAccepted={formik.values.isAccepted} + /> + + + + + + )} + + ); +}; diff --git a/src/features/aviculture/components/requests-operations/RequestsOperations.js b/src/features/aviculture/components/requests-operations/RequestsOperations.js new file mode 100644 index 0000000..a8cb2ad --- /dev/null +++ b/src/features/aviculture/components/requests-operations/RequestsOperations.js @@ -0,0 +1,164 @@ +import { Grid } from "../../../../components/grid/Grid"; +import { SPACING } from "../../../../data/spacing"; +import { NavLink } from "../../../../components/nav-link/NavLink"; +import { useLocation } from "react-router-dom"; +import { + ROUTE_AVICULTURE_ARCHIVED_REQUESTS, + ROUTE_AVICULTURE_AWAITING_INSPECTION_REQUESTS, + ROUTE_AVICULTURE_AWAITING_PAYMENT_REQUESTS, + ROUTE_AVICULTURE_GIVE_PERMISSION, + ROUTE_AVICULTURE_HATCHING, + ROUTE_AVICULTURE_REJECTED_REQUESTS, + ROUTE_AVICULTURE_SUBMIT_REQUEST, +} from "../../../../routes/routes"; +import LinkItem from "../../../../components/link-item/LinkItem"; +import { + FaArchive, + FaEgg, + FaMoneyBillWave, + FaRegFileAlt, +} from "react-icons/fa"; +import { GrInspect } from "react-icons/gr"; +import { RiFolderWarningLine } from "react-icons/ri"; + +export const RequestsOperations = () => { + const { pathname } = useLocation(); + + return ( + + + + + } + title="جوجه ریزی" + description="ثبت و مدیریت جوجه ریزی ها" + /> + + {/* + + */} + + } + title="درخواست های کشتار" + description="مدیریت و ثبت درخواست های کشتار" + /> + + + } + title="در انتظار پرداخت" + description="مشاهده درخواست های در انتظار پرداخت کشتارگاه" + /> + + + + } + title="در انتظار بازرسی" + description="درخواست های در انتظار بررسی بازرس" + /> + + + + } + title="درخواست های رد شده" + description="مشاهده درخواست هایی که به دلایل مختلف توسط اتحادیه رد شده است" + /> + + + + } + title="بایگانی" + description="درخواست های پایان یافته" + /> + + + + } + title="وکالت" + /> + + + + + ); +}; diff --git a/src/features/aviculture/components/strict-missing-hall-number/StrictMissingHallNumber.js b/src/features/aviculture/components/strict-missing-hall-number/StrictMissingHallNumber.js new file mode 100644 index 0000000..391927c --- /dev/null +++ b/src/features/aviculture/components/strict-missing-hall-number/StrictMissingHallNumber.js @@ -0,0 +1,135 @@ +import { + Button, + FormControl, + InputLabel, + MenuItem, + Select, + Typography, +} from "@mui/material"; +import { useFormik } from "formik"; +import { PropTypes } from "prop-types"; +import { useContext } from "react"; +import { useEffect } from "react"; +import { useDispatch } from "react-redux"; +import { Grid } from "../../../../components/grid/Grid"; +import { AppContext } from "../../../../contexts/AppContext"; +import { SPACING } from "../../../../data/spacing"; +import { Yup } from "../../../../lib/yup/yup"; +import { avicultureGetProfile } from "../../services/aviculture-get-profile"; +import { avicultureSetHallNumber } from "../../services/aviculture-set-hall-number"; + +export const StrictMissingHallNumber = ({ + name, + id, + avicultureKey, + handleClose, +}) => { + const [openNotif] = useContext(AppContext); + const dispatch = useDispatch(); + const formik = useFormik({ + initialValues: { + number_of_halls: 1, + }, + validationSchema: Yup.object({ + number_of_halls: Yup.number() + .required("این فیلد اجباری است!") + .typeError("لطفا عدد وارد کنید!"), + }), + }); + + useEffect(() => { + formik.validateForm(); + }, []); + + return ( + + + + تعداد سالن های {name} با شناسه جوجه ریزی {id} را وارد کنید. + + + + + تعداد سالن + + + + + + ); +}; + +StrictMissingHallNumber.propTypes = { + name: PropTypes.any, + id: PropTypes.any, + avicultureKey: PropTypes.any, + handleClose: PropTypes.any, +}; diff --git a/src/features/aviculture/components/view-bank-account/ViewBankAccount.js b/src/features/aviculture/components/view-bank-account/ViewBankAccount.js new file mode 100644 index 0000000..6c440c8 --- /dev/null +++ b/src/features/aviculture/components/view-bank-account/ViewBankAccount.js @@ -0,0 +1,49 @@ +import { Typography } from "@mui/material"; +import { Box } from "@mui/system"; +import { useSelector } from "react-redux"; +import { Grid } from "../../../../components/grid/Grid"; +import { SPACING } from "../../../../data/spacing"; + +export const ViewBankAccount = () => { + const { userProfile } = useSelector((state) => state.userSlice); + const userData = [ + ["نام بانک", userProfile.userBankInfo?.bankName], + ["شماره کارت", userProfile.userBankInfo?.card], + ["شماره حساب", userProfile.userBankInfo?.account], + ["شماره شبا", userProfile.userBankInfo?.shaba], + ]; + return ( + + + + + اطلاعات حساب بانکی + + + + {userData.map((item, i) => ( + + + {item[0] + ":"} + + + {item[1] ? item[1] : "نامشخص"} + + + ))} + + + + ); +}; diff --git a/src/features/aviculture/components/view-profile/ViewProfile.js b/src/features/aviculture/components/view-profile/ViewProfile.js new file mode 100644 index 0000000..23b7ca8 --- /dev/null +++ b/src/features/aviculture/components/view-profile/ViewProfile.js @@ -0,0 +1,64 @@ +import { Chip, Divider, Typography } from "@mui/material"; +import { Box } from "@mui/system"; +import { useEffect } from "react"; +import { useDispatch, useSelector } from "react-redux"; +import { Grid } from "../../../../components/grid/Grid"; +import { SPACING } from "../../../../data/spacing"; +import { formatTime } from "../../../../utils/formatTime"; +import { avicultureGetProfile } from "../../services/aviculture-get-profile"; + +export const ViewProfile = () => { + const dispatch = useDispatch(); + const { profile } = useSelector((state) => state.avicultureSlice); + + useEffect(() => { + dispatch(avicultureGetProfile()); + }, []); + const userProfile = profile?.profile; + + const userData = [ + ["نام", userProfile?.firstName], + ["نام خانوادگی", userProfile?.lastName], + ["موبایل", userProfile?.mobile], + ["استان", userProfile?.province?.name], + ["شهر", userProfile?.city.name], + [ + "تاریخ تولد", + userProfile?.birthday ? formatTime(userProfile?.birthday) : null, + ], + ]; + return ( + + + + + + + + + {userData?.map((item, i) => ( + + + {item[0] + ":"} + + + {item[1] ? item[1] : "نامشخص"} + + + ))} + + + + ); +}; diff --git a/src/features/aviculture/hooks/useAvicultureRequests.js b/src/features/aviculture/hooks/useAvicultureRequests.js new file mode 100644 index 0000000..1aaabb7 --- /dev/null +++ b/src/features/aviculture/hooks/useAvicultureRequests.js @@ -0,0 +1,26 @@ +import { useState, useEffect } from "react"; +import { useDispatch, useSelector } from "react-redux"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; +import { avicultureGetRequests } from "../services/aviculture-requests"; + +const useAvicultureRequests = () => { + const dispatch = useDispatch(); + const { avicultureRequests } = useSelector((state) => state.avicultureSlice); + + const [data, setData] = useState(avicultureRequests); + + useEffect(() => { + dispatch(LOADING_START()); + dispatch(avicultureGetRequests()).then(() => { + dispatch(LOADING_END()); + }); + }, []); + + useEffect(() => { + setData(avicultureRequests); + }, [avicultureRequests]); + + return data ? data : []; +}; + +export default useAvicultureRequests; diff --git a/src/features/aviculture/services/aviculture-delete-hatching.js b/src/features/aviculture/services/aviculture-delete-hatching.js new file mode 100644 index 0000000..13f7978 --- /dev/null +++ b/src/features/aviculture/services/aviculture-delete-hatching.js @@ -0,0 +1,12 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; + +export const avicultureDeleteHatching = createAsyncThunk( + "AVICULTURE_DELETE_HATCHING", + async (key) => { + const { data, status } = await axios.delete( + "poultry_hatching/0/?key=" + key + ); + return { data, status }; + } +); diff --git a/src/features/aviculture/services/aviculture-delete-kill-request.js b/src/features/aviculture/services/aviculture-delete-kill-request.js new file mode 100644 index 0000000..dda1842 --- /dev/null +++ b/src/features/aviculture/services/aviculture-delete-kill-request.js @@ -0,0 +1,18 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const archiveDeleteKillRequestService = createAsyncThunk( + "ARCHIVE_DELETE_KILL_REQUEST_SERVICE", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + try { + const { data, status } = await axios.delete("Poultry_Request/" + d); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e.response.data.result }; + } + } +); diff --git a/src/features/aviculture/services/aviculture-get-chicken-price.js b/src/features/aviculture/services/aviculture-get-chicken-price.js new file mode 100644 index 0000000..ea61aaa --- /dev/null +++ b/src/features/aviculture/services/aviculture-get-chicken-price.js @@ -0,0 +1,10 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; + +export const avicultureGetChickenPrice = createAsyncThunk( + "AVICULTURE_GET_CHICKEN_PRICE", + async () => { + const { data, status } = await axios.get("pricing/?role=Poultry"); + return { data, status }; + } +); diff --git a/src/features/aviculture/services/aviculture-get-direct-buys.js b/src/features/aviculture/services/aviculture-get-direct-buys.js new file mode 100644 index 0000000..23c90fd --- /dev/null +++ b/src/features/aviculture/services/aviculture-get-direct-buys.js @@ -0,0 +1,15 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const avicultureGetDirectBuys = createAsyncThunk( + "AVICULTURE_GET_DIRECT_BUYS", + async (key, { dispatch }) => { + dispatch(LOADING_START()); + const { data, status } = await axios.get( + "kill_request/?poultry_key=" + key + ); + dispatch(LOADING_END()); + return { data, status }; + } +); diff --git a/src/features/aviculture/services/aviculture-get-give-permission.js b/src/features/aviculture/services/aviculture-get-give-permission.js new file mode 100644 index 0000000..b9720af --- /dev/null +++ b/src/features/aviculture/services/aviculture-get-give-permission.js @@ -0,0 +1,13 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const avicultureGetGivePermissionService = createAsyncThunk( + "AVICULTURE_GET_GIVE_PERMISSION_SERVICE", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + const { data, status } = await axios.get("poultry_allow_city_province/"); + dispatch(LOADING_END()); + return { data, status }; + } +); diff --git a/src/features/aviculture/services/aviculture-get-hall-inspects.js b/src/features/aviculture/services/aviculture-get-hall-inspects.js new file mode 100644 index 0000000..bc31857 --- /dev/null +++ b/src/features/aviculture/services/aviculture-get-hall-inspects.js @@ -0,0 +1,12 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; + +export const avicultureGetHallInspects = createAsyncThunk( + "AVICULTURE_GET_HALL)INSPECTS", + async (key) => { + const { data, status } = await axios.get( + "vet_farm_inspection/?poultry_key=" + key + ); + return { data, status }; + } +); diff --git a/src/features/aviculture/services/aviculture-get-halls-info.js b/src/features/aviculture/services/aviculture-get-halls-info.js new file mode 100644 index 0000000..9a2db61 --- /dev/null +++ b/src/features/aviculture/services/aviculture-get-halls-info.js @@ -0,0 +1,10 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; + +export const avicultureGetHallsInfo = createAsyncThunk( + "AVICULTURE_GET_HALLS_INFO", + async () => { + const { data, status } = await axios.get("Poultry/?info"); + return { data, status }; + } +); diff --git a/src/features/aviculture/services/aviculture-get-halls.js b/src/features/aviculture/services/aviculture-get-halls.js new file mode 100644 index 0000000..ec48801 --- /dev/null +++ b/src/features/aviculture/services/aviculture-get-halls.js @@ -0,0 +1,10 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; + +export const avicultureGetHalls = createAsyncThunk( + "AVICULTURE_GET_HALLS", + async () => { + const { data, status } = await axios.get("poultry_hatching/"); + return { data, status }; + } +); diff --git a/src/features/aviculture/services/aviculture-get-hatching-data.js b/src/features/aviculture/services/aviculture-get-hatching-data.js new file mode 100644 index 0000000..5e37ed0 --- /dev/null +++ b/src/features/aviculture/services/aviculture-get-hatching-data.js @@ -0,0 +1,24 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; + +export const avicultureGetHatchingData = createAsyncThunk( + "VET_GET_HATCHING", + async (d) => { + const { data, status } = await axios.get("poultry_hatching/", { + params: { + key: d.key || "", + }, + }); + return { data, status }; + } +); + +export const avicultureGetHatchingDataForIncreaseHatching = createAsyncThunk( + "VET_GET_HATCHING_FOR_INCREASE", + async (key) => { + const { data, status } = await axios.get( + "poultry_hatching/?increase=true&key=" + key + ); + return { data, status }; + } +); diff --git a/src/features/aviculture/services/aviculture-get-hatchings.js b/src/features/aviculture/services/aviculture-get-hatchings.js new file mode 100644 index 0000000..94db2c7 --- /dev/null +++ b/src/features/aviculture/services/aviculture-get-hatchings.js @@ -0,0 +1,10 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; + +export const avicultureGetHatchings = createAsyncThunk( + "AVICULTURE_GET_HATCHINGS", + async () => { + const { data, status } = await axios.get("poultry_hatching/"); + return { data, status }; + } +); diff --git a/src/features/aviculture/services/aviculture-get-poultry.js b/src/features/aviculture/services/aviculture-get-poultry.js new file mode 100644 index 0000000..bf1d7bc --- /dev/null +++ b/src/features/aviculture/services/aviculture-get-poultry.js @@ -0,0 +1,13 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { getRoleFromUrl } from "../../../utils/getRoleFromUrl"; + +export const avicultureGetPoultry = createAsyncThunk( + "AVICULTURE_GET_POULTRY", + async () => { + const { data, status } = await axios.get("Poultry/", { + params: { role: getRoleFromUrl() }, + }); + return { data, status }; + } +); diff --git a/src/features/aviculture/services/aviculture-get-profile.js b/src/features/aviculture/services/aviculture-get-profile.js new file mode 100644 index 0000000..40f068d --- /dev/null +++ b/src/features/aviculture/services/aviculture-get-profile.js @@ -0,0 +1,10 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; + +export const avicultureGetProfile = createAsyncThunk( + "AVICULTURE_GET_PROFILE", + async (d, { dispatch }) => { + const { data, status } = await axios.get("Poultry/0/?profile", d); + return { data, status }; + } +); diff --git a/src/features/aviculture/services/aviculture-get-reports.js b/src/features/aviculture/services/aviculture-get-reports.js new file mode 100644 index 0000000..6832f16 --- /dev/null +++ b/src/features/aviculture/services/aviculture-get-reports.js @@ -0,0 +1,10 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; + +export const avicultureGetReports = createAsyncThunk( + "AVICULTURE_GET_REPORTS", + async () => { + const { data, status } = await axios.get("poultry_report/"); + return { data, status }; + } +); diff --git a/src/features/aviculture/services/aviculture-get-slaughters.js b/src/features/aviculture/services/aviculture-get-slaughters.js new file mode 100644 index 0000000..ba392ef --- /dev/null +++ b/src/features/aviculture/services/aviculture-get-slaughters.js @@ -0,0 +1,12 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; + +export const avicultureGetSlaughters = createAsyncThunk( + "AVICULTURE_GET_SLAUGHTERS", + async (d) => { + const { data, status } = await axios.get("kill_house_list/?show_poultry", { + params: { date: d.date }, + }); + return { data, status }; + } +); diff --git a/src/features/aviculture/services/aviculture-get-unions.js b/src/features/aviculture/services/aviculture-get-unions.js new file mode 100644 index 0000000..ca10ae8 --- /dev/null +++ b/src/features/aviculture/services/aviculture-get-unions.js @@ -0,0 +1,14 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END } from "../../../lib/redux/slices/appSlice"; + +export const avicultureGetUnions = createAsyncThunk( + "AVICULTURE_GET_UNIONS", + async (d, { dispatch }) => { + const { data, status } = await axios.get("show_city_operator", { + params: d, + }); + dispatch(LOADING_END()); + return { data, status }; + } +); diff --git a/src/features/aviculture/services/aviculture-get-wage-type.js b/src/features/aviculture/services/aviculture-get-wage-type.js new file mode 100644 index 0000000..331ca9b --- /dev/null +++ b/src/features/aviculture/services/aviculture-get-wage-type.js @@ -0,0 +1,10 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; + +export const avicultureGetWageType = createAsyncThunk( + "AVICULTURE_GET_WAGE_TYPE", + async () => { + const { data, status } = await axios.get("poultry-out-province-wage-type"); + return { data, status }; + } +); diff --git a/src/features/aviculture/services/aviculture-give-permission.js b/src/features/aviculture/services/aviculture-give-permission.js new file mode 100644 index 0000000..3a669cb --- /dev/null +++ b/src/features/aviculture/services/aviculture-give-permission.js @@ -0,0 +1,16 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const avicultureGivePermissionService = createAsyncThunk( + "AVICULTURE_GIVE_PERMISSION_SERVICE", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + const { data, status } = await axios.post( + "poultry_allow_city_province/", + d + ); + dispatch(LOADING_END()); + return { data, status }; + } +); diff --git a/src/features/aviculture/services/aviculture-hatching-requests.js b/src/features/aviculture/services/aviculture-hatching-requests.js new file mode 100644 index 0000000..e0f62e1 --- /dev/null +++ b/src/features/aviculture/services/aviculture-hatching-requests.js @@ -0,0 +1,25 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import moment from "moment/moment"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; +import { getRoleFromUrl } from "../../../utils/getRoleFromUrl"; + +export const avicultureHatchingRequestsService = createAsyncThunk( + "AVICULTURE_HATCHING_REQUESTS_SERVICE", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + const today = "&today"; + d = d || moment(new Date()).format("YYYY-MM-DD"); + const { data, status } = await axios.get( + "Poultry_Request/?role=" + getRoleFromUrl() + today, + { + params: { + date1: d.selectedDate1, + date2: d.selectedDate2, + }, + } + ); + dispatch(LOADING_END()); + return { data, status }; + } +); diff --git a/src/features/aviculture/services/aviculture-new-hatching.js b/src/features/aviculture/services/aviculture-new-hatching.js new file mode 100644 index 0000000..e4c1e64 --- /dev/null +++ b/src/features/aviculture/services/aviculture-new-hatching.js @@ -0,0 +1,10 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; + +export const avicultureNewHatching = createAsyncThunk( + "VET_FARM_NEW_FARM", + async (d) => { + const { data, status } = await axios.post("poultry_hatching/", d); + return { data, status }; + } +); diff --git a/src/features/aviculture/services/aviculture-new-request.js b/src/features/aviculture/services/aviculture-new-request.js new file mode 100644 index 0000000..9fbda1a --- /dev/null +++ b/src/features/aviculture/services/aviculture-new-request.js @@ -0,0 +1,14 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; + +export const avicultureNewRequest = createAsyncThunk( + "AVICULTURE_NEW_REQUEST", + async (d) => { + try { + const { data, status } = await axios.post("Poultry_Request/", d); + return { data, status }; + } catch (e) { + return { error: e.response.data.result }; + } + } +); diff --git a/src/features/aviculture/services/aviculture-requests-state-process.js b/src/features/aviculture/services/aviculture-requests-state-process.js new file mode 100644 index 0000000..5682cdb --- /dev/null +++ b/src/features/aviculture/services/aviculture-requests-state-process.js @@ -0,0 +1,23 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; +import { getRoleFromUrl } from "../../../utils/getRoleFromUrl"; + +export const avicultureRequestsStateProcessService = createAsyncThunk( + "AVICULTURE_REQUESTS_STATE_PROCESS", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + const { data, status } = await axios.get( + "Poultry_Request/?role=" + getRoleFromUrl(), + { + params: { + date1: d.selectedDate1, + date2: d.selectedDate2, + state_process: true, + }, + } + ); + dispatch(LOADING_END()); + return { data, status }; + } +); diff --git a/src/features/aviculture/services/aviculture-requests.js b/src/features/aviculture/services/aviculture-requests.js new file mode 100644 index 0000000..5d7305c --- /dev/null +++ b/src/features/aviculture/services/aviculture-requests.js @@ -0,0 +1,19 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { getRoleFromUrl } from "../../../utils/getRoleFromUrl"; + +export const avicultureGetRequests = createAsyncThunk( + "AVICULTURE_REQUESTS_SERVICE", + async (d, { dispatch }) => { + const { data, status } = await axios.get( + "Poultry_Request/?role=" + getRoleFromUrl(), + { + params: { + date1: d.selectedDate1, + date2: d.selectedDate2, + }, + } + ); + return { data, status }; + } +); diff --git a/src/features/aviculture/services/aviculture-set-hall-number.js b/src/features/aviculture/services/aviculture-set-hall-number.js new file mode 100644 index 0000000..d222428 --- /dev/null +++ b/src/features/aviculture/services/aviculture-set-hall-number.js @@ -0,0 +1,13 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const avicultureSetHallNumber = createAsyncThunk( + "AVICULTURE_SET_HALL_NUMBER", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + const { data, status } = await axios.put("Poultry/0/", d); + dispatch(LOADING_END()); + return { data, status }; + } +); diff --git a/src/features/aviculture/services/province-get-poultry.js b/src/features/aviculture/services/province-get-poultry.js new file mode 100644 index 0000000..160a0e5 --- /dev/null +++ b/src/features/aviculture/services/province-get-poultry.js @@ -0,0 +1,20 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { getRoleFromUrl } from "../../../utils/getRoleFromUrl"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const provinceGetPoultry = createAsyncThunk( + "PROVINCE_GET_POULTRY", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + const { data, status } = await axios.get("get-all-poultry/", { + params: { + role: getRoleFromUrl(), + active_hatching: true, + ...d, + }, + }); + dispatch(LOADING_END()); + return { data, status }; + } +); diff --git a/src/features/chain-company/components/chain-company-active-chains/ChainCompanyActiveChains.js b/src/features/chain-company/components/chain-company-active-chains/ChainCompanyActiveChains.js new file mode 100644 index 0000000..9481e82 --- /dev/null +++ b/src/features/chain-company/components/chain-company-active-chains/ChainCompanyActiveChains.js @@ -0,0 +1,714 @@ +import { + Button, + FormControl, + InputLabel, + MenuItem, + Select, + TextField, + Tooltip, + Typography, +} from "@mui/material"; +import React, { useContext, useEffect, useState } from "react"; +import { useSelector } from "react-redux"; +import { RiFileExcel2Fill, RiSearchLine } from "react-icons/ri"; +import axios from "axios"; +import { AppContext } from "../../../../contexts/AppContext"; +import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl"; +import { formatTime } from "../../../../utils/formatTime"; +import { getFaUserRole } from "../../../../utils/getFaUserRole"; +import { PageTable } from "../../../../components/page-table/PageTable"; +import { Grid } from "../../../../components/grid/Grid"; +import { SPACING } from "../../../../data/spacing"; + +export const ChainCompanyActiveChains = () => { + const [selectedAge1, setSelectedAge1] = useState(0); + const [selectedAge2, setSelectedAge2] = useState(0); + const [data, setData] = useState([]); + const [loading, setLoading] = useState(false); + const [totalRows, setTotalRows] = useState(0); + const [perPage, setPerPage] = useState(10); + const [textValue, setTextValue] = useState(""); + const userKey = useSelector((state) => state.userSlice.userProfile.key); + + const handleTextChange = (event) => { + setTextValue(event.target.value); + }; + + useEffect(() => { + fetchApiData(1); + }, []); + + const [openNotif] = useContext(AppContext); + + const killedNumber = (item) => { + let killedNumber = ""; + killedNumber = item.quantity - item.losses - item.leftOver; + return killedNumber; + }; + + const fetchApiData = async (page, textValue) => { + setLoading(true); + let response; + if (textValue) { + response = await axios.get( + `poultry_hatching?search=filter&value=${textValue}&role=${getRoleFromUrl()}&page=${page}&page_size=${perPage}&chain=true` + ); + } else if (selectedAge1 && selectedAge2) { + response = await axios.get( + `poultry_hatching?role=${getRoleFromUrl()}&age1=${selectedAge1}&age2=${selectedAge2}&page=${page}&page_size=${perPage}&chain=true` + ); + } else { + response = await axios.get( + `poultry_hatching/?role=${getRoleFromUrl()}&page=${page}&page_size=${perPage}&chain=true` + ); + } + setData(response.data.results); + setTotalRows(response.data.count); + setLoading(false); + }; + + const handlePageChange = (page) => { + fetchApiData(page, textValue); + }; + + // const updateTable = () => { + // fetchApiData(1); + // }; + + const handlePerRowsChange = async (newPerPage, page) => { + setLoading(true); + let response; + if (textValue) { + response = await axios.get( + `poultry_hatching?search=filter&value=${textValue}&page=${page}&page_size=${newPerPage}&search=filter&value=${textValue}&chain=true` + ); + } else if (selectedAge1 && selectedAge2) { + response = await axios.get( + `poultry_hatching?role=${getRoleFromUrl()}&age1=${selectedAge1}&age2=${selectedAge2}&page=${page}&page_size=${perPage}&chain=true` + ); + } else { + response = await axios.get( + `poultry_hatching/?role=${getRoleFromUrl()}&page=${page}&page_size=${newPerPage}&chain=true` + ); + } + + setData(response.data.results); + setTotalRows(response.data.count); + setPerPage(newPerPage); + + setLoading(false); + }; + const handleSubmit = async (event) => { + event.preventDefault(); + setLoading(true); + + try { + const response = await axios.get( + `poultry_hatching/?role=${getRoleFromUrl()}&search=filter&value=${textValue}&chain=true` + ); + setData(response.data.results); + setTotalRows(response.data.count); + } catch (error) { + console.error("Error fetching data:", error); + } finally { + setLoading(false); + } + }; + + const handleRemoveFilter = async (event) => { + event.preventDefault(); + setSelectedAge1(null); + setSelectedAge2(null); + setLoading(true); + + try { + const response = await axios.get( + `poultry_hatching/?role=${getRoleFromUrl()}&chain=true&search=filter&value=` + ); + setData(response.data.results); + setTotalRows(response.data.count); + } catch (error) { + console.error("Error fetching data:", error); + } finally { + setLoading(false); + } + }; + + const handleSubmitSearchByAge = async (event) => { + event.preventDefault(); + setLoading(true); + + try { + const response = await axios.get( + `poultry_hatching?role=${getRoleFromUrl()}&age1=${selectedAge1}&age2=${selectedAge2}&chain=true` + ); + setData(response.data.results); + setTotalRows(response.data.count); + } catch (error) { + console.error("Error fetching data:", error); + } finally { + setLoading(false); + } + }; + + let columns = [ + // { + // name: "عملیات", + // selector: (item) => ( + // + // ), + // sortable: false, + // wrap: true, + // allowOverflow: true, + // center: true, + // width: "80px", + // }, + { + name: "ردیف", + selector: (item, i) => { + return i + 1; + }, + sortable: false, + wrap: true, + allowOverflow: true, + center: true, + width: "30px", + }, + { + name: "شرکت زنجیره", + selector: (item, i) => { + return `${item?.chainCompany?.name} (${item?.chainCompany?.user.mobile})`; + }, + sortable: false, + wrap: true, + allowOverflow: true, + center: true, + width: "80px", + }, + { + name: "وضعیت", + selector: (item, i) => { + return ( + + {item.violation ? "متخلف" : "عادی"} + + ); + }, + sortable: false, + wrap: true, + allowOverflow: true, + center: true, + width: "60px", + }, + { + name: "نام فارم", + selector: (row) => row.poultry.unitName, + sortable: true, + wrap: true, + allowOverflow: true, + center: true, + width: "90px", + }, + { + name: "مرغدار", + selector: (item) => + `${item.poultry.userprofile.fullName} (${item.poultry.userprofile.mobile})`, + sortable: true, + wrap: true, + allowOverflow: true, + center: true, + width: "80px", + }, + { + name: "شهر/تعاونی", + selector: (item) => + `${item?.poultry?.address.city.name}/${ + item?.poultry?.cityOperator + ? item?.poultry?.cityOperator + : "بدون تعاونی" + }`, + sortable: true, + wrap: true, + allowOverflow: true, + center: true, + width: "80px", + }, + { + name: "دامپزشک فارم", + selector: (item) => + item?.vetFarm?.vetFarmMobile + ? `${item?.vetFarm?.vetFarmFullName} (${item?.vetFarm?.vetFarmMobile})` + : "-", + sortable: true, + wrap: true, + allowOverflow: true, + center: true, + width: "80px", + }, + { + name: "سالن", + selector: (item) => item.hall, + sortable: true, + wrap: true, + allowOverflow: true, + center: true, + width: "60px", + }, + { + name: "دوره جوجه ریزی", + selector: (item) => item.period, + sortable: true, + wrap: true, + allowOverflow: true, + center: true, + width: "80px", + }, + { + name: "تاریخ ثبت جوجه ریزی", + selector: (item) => formatTime(item?.createDate), + sortable: false, + wrap: false, + allowOverflow: true, + center: true, + width: "100px", + }, + { + name: "تاریخ جوجه ریزی", + selector: (item) => formatTime(item?.date), + sortable: false, + wrap: true, + allowOverflow: true, + center: true, + width: "100px", + }, + { + name: "نژاد", + selector: (item) => item.chickenBreed, + sortable: true, + wrap: true, + allowOverflow: true, + center: true, + width: "80px", + }, + { + name: "سن", + selector: (row) => row.age, + sortable: true, + wrap: true, + allowOverflow: true, + center: true, + width: "60px", + }, + { + name: "تعداد جوجه ریزی", + selector: (item) => item?.quantity?.toLocaleString(), + sortable: true, + wrap: true, + allowOverflow: true, + center: true, + width: "80px", + }, + { + name: "تلفات دوره (قطعه)", + selector: (item) => + `${item.losses} (%${((item.losses * 100) / item.quantity).toFixed(0)})`, + sortable: true, + wrap: true, + allowOverflow: true, + center: true, + width: "80px", + }, + { + name: "تعداد کل تعهد دولتی (قطعه)", + selector: (item) => `${item?.totalCommitmentQuantity?.toLocaleString()}`, + sortable: true, + wrap: true, + allowOverflow: true, + center: true, + width: "80px", + }, + { + name: "تعداد کشتار شده دولتی (قطعه)", + selector: (item) => `${item?.governmentalQuantity?.toLocaleString()}`, + sortable: true, + wrap: true, + allowOverflow: true, + center: true, + width: "80px", + }, + { + name: "وزن کشتار شده دولتی", + selector: (item) => + `${item?.governmentalKilledQuantity?.toLocaleString()}`, + sortable: true, + wrap: true, + allowOverflow: true, + center: true, + width: "80px", + }, + { + name: "تعداد کشتار شده آزاد (قطعه)", + selector: (item) => `${item?.freeQuantity?.toLocaleString()}`, + sortable: true, + wrap: true, + allowOverflow: true, + center: true, + width: "80px", + }, + { + name: "وزن کشتار شده آزاد ", + selector: (item) => `${item?.freeKilledQuantity?.toLocaleString()}`, + sortable: true, + wrap: true, + allowOverflow: true, + center: true, + width: "80px", + }, + { + name: "حجم خارج از استان", + selector: (item) => + `${item?.outProvinceKilledQuantity?.toLocaleString()}`, + sortable: true, + wrap: true, + allowOverflow: true, + center: true, + width: "80px", + }, + { + name: "وزن خارج از استان", + selector: (item) => `${item?.outProvinceKilledWeight?.toLocaleString()}`, + sortable: true, + wrap: true, + allowOverflow: true, + center: true, + width: "80px", + }, + { + name: "کشتار شده (قطعه)", + selector: (item) => { + return ( + killedNumber(item)?.toLocaleString() + + ` (%${((killedNumber(item) * 100) / item.quantity).toFixed(0)})` + ); + }, + sortable: true, + wrap: true, + allowOverflow: true, + center: true, + width: "90px", + }, + { + name: "مانده در سالن (قطعه)", + selector: (item) => + `${item?.leftOver?.toLocaleString()} (%${( + (item.leftOver * 100) / + item.quantity + ).toFixed(0)})`, + sortable: true, + wrap: true, + allowOverflow: true, + center: true, + width: "90px", + }, + { + name: "وزن تعهد دولتی", + selector: (item) => item?.totalCommitment?.toLocaleString() + " کیلوگرم ", + sortable: true, + wrap: true, + allowOverflow: true, + center: true, + width: "80px", + }, + { + name: "وزن کشتار دولتی", + selector: (item) => + item?.governmentalKilledQuantity?.toLocaleString() + " کیلوگرم ", + sortable: true, + wrap: true, + allowOverflow: true, + center: true, + width: "80px", + }, + { + name: "وزن کشتار آزاد", + selector: (item) => + item?.freeKilledQuantity?.toLocaleString() + " کیلوگرم ", + sortable: true, + wrap: true, + allowOverflow: true, + center: true, + width: "80px", + }, + { + name: "میانگین وزن کشتار", + selector: (item) => + item?.totalAverageKilledWeight?.toLocaleString() + " کیلوگرم ", + sortable: true, + wrap: true, + allowOverflow: true, + center: true, + width: "80px", + }, + { + name: "وزن کل کشتار شده", + selector: (item) => + item?.totalKilledWeight?.toLocaleString() + " کیلوگرم ", + sortable: true, + wrap: true, + allowOverflow: true, + center: true, + width: "80px", + }, + { + name: "کشتار فعال", + selector: (row) => (row?.activeKill?.activeKill ? "دارد" : "ندارد"), + sortable: true, + wrap: true, + allowOverflow: true, + center: true, + width: "80px", + }, + { + name: "تعداد درخواست کشتار", + selector: (item) => + item?.activeKill?.countOfRequest ? item.activeKill.countOfRequest : "-", + sortable: true, + wrap: true, + allowOverflow: true, + center: true, + width: "80px", + }, + { + name: "آخرین تغییر", + selector: (item) => { + const lastChange = + item.lastChange && + item.lastChange.date && + `${item.lastChange.fullName} (${getFaUserRole( + item.lastChange.role + )}) در تاریخ ${formatTime(item.lastChange.date)}`; + return item.lastChange ? lastChange : "-"; + }, + sortable: true, + wrap: true, + allowOverflow: true, + center: true, + }, + { + name: "سازنده جوجه ریزی", + selector: (item) => { + const lastChange = + item.latestHatchingChange && + item.latestHatchingChange.date && + `${item.latestHatchingChange.fullName} (${getFaUserRole( + item.latestHatchingChange.role + )}) در تاریخ ${formatTime(item.latestHatchingChange.date)}`; + return item.latestHatchingChange ? lastChange : "-"; + }, + sortable: true, + wrap: true, + allowOverflow: true, + center: true, + }, + ]; + + const selectAges = Array.from({ length: 75 }, (_, i) => i + 1); + + const tableTitle = ( + + + زنجیره های زیرمجموعه +
    + + + + {/* */} + + {/* */} + + +
    + + + جستجو براساس سن: + + + + از سن + + + + + + تا سن + + + + + + {/* */} + + {/* */} + + + +
    + ); + return ( + + {/* */} + + + + + + ); +}; diff --git a/src/features/chain-company/components/chain-company-profile/ChainCompanyProfile.js b/src/features/chain-company/components/chain-company-profile/ChainCompanyProfile.js new file mode 100644 index 0000000..8060195 --- /dev/null +++ b/src/features/chain-company/components/chain-company-profile/ChainCompanyProfile.js @@ -0,0 +1,66 @@ +import { Box } from "@mui/system"; +import { useEffect, useState } from "react"; +import { useDispatch } from "react-redux"; +import { Grid } from "../../../../components/grid/Grid"; +import { SimpleTable } from "../../../../components/simple-table/SimpleTable"; +import { SPACING } from "../../../../data/spacing"; +import { + LOADING_END, + LOADING_START, +} from "../../../../lib/redux/slices/appSlice"; +import { getChainCompanyProfile } from "../../services/get-chain-company-profile"; + +export const ChainCompanyProfile = () => { + const dispatch = useDispatch(); + + const [data, setData] = useState(); + + useEffect(() => { + dispatch(LOADING_START()); + dispatch(getChainCompanyProfile()).then((r) => { + setData(r.payload.data); + dispatch(LOADING_END()); + }); + }, []); + + return ( + + + + + <> + + + + + + + + + ); +}; diff --git a/src/features/chain-company/services/get-chain-company-profile.js b/src/features/chain-company/services/get-chain-company-profile.js new file mode 100644 index 0000000..0a1f662 --- /dev/null +++ b/src/features/chain-company/services/get-chain-company-profile.js @@ -0,0 +1,10 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; + +export const getChainCompanyProfile = createAsyncThunk( + "CHAIN_GET_PROFILE", + async () => { + const { data, status } = await axios.get("chain-company/0/?profile"); + return { data, status }; + } +); diff --git a/src/features/city-jihad/components/guilds-operations-city-jihad/GuildsOperationsCityJihad.js b/src/features/city-jihad/components/guilds-operations-city-jihad/GuildsOperationsCityJihad.js new file mode 100644 index 0000000..58da228 --- /dev/null +++ b/src/features/city-jihad/components/guilds-operations-city-jihad/GuildsOperationsCityJihad.js @@ -0,0 +1,50 @@ +import { Grid } from "../../../../components/grid/Grid"; +import { SPACING } from "../../../../data/spacing"; +import { NavLink } from "../../../../components/nav-link/NavLink"; +import { + ROUTE_CITY_JIHAD_ROUTE_GUILDS, + ROUTE_CITY_JIHAD_ROUTE_STEWARDS, + ROUTE_CITY_POULTRY_ROUTE_GUILDS, + ROUTE_CITY_POULTRY_ROUTE_STEWARDS, +} from "../../../../routes/routes"; +import LinkItem from "../../../../components/link-item/LinkItem"; +import { MdCorporateFare } from "react-icons/md"; +import { IoIosPeople } from "react-icons/io"; +import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl"; + +export const GuildsOperationsCityJihad = () => { + return ( + + + } + title="اصناف" + /> + + + } + title="مباشرین" + /> + + + ); +}; diff --git a/src/features/city-vet/components/CityVetProfile.js b/src/features/city-vet/components/CityVetProfile.js new file mode 100644 index 0000000..3aff2c6 --- /dev/null +++ b/src/features/city-vet/components/CityVetProfile.js @@ -0,0 +1,61 @@ +import { Box } from "@mui/system"; +import { useEffect } from "react"; +import { useDispatch, useSelector } from "react-redux"; +import { Grid } from "../../../components/grid/Grid"; +import { SimpleTable } from "../../../components/simple-table/SimpleTable"; +import { SPACING } from "../../../data/spacing"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; +import { cityVetGetProfileService } from "../services/city-vet-profile"; + +export const CityVetProfile = () => { + const { cityVetGetProfile } = useSelector((state) => state.generalSlice); + const dispatch = useDispatch(); + + useEffect(() => { + dispatch(LOADING_START()); + dispatch(cityVetGetProfileService()).then((r) => { + dispatch(LOADING_END()); + }); + }, []); + + return ( + + + + + <> + + + + + + + + + ); +}; diff --git a/src/features/city-vet/services/city-vet-profile.js b/src/features/city-vet/services/city-vet-profile.js new file mode 100644 index 0000000..0806438 --- /dev/null +++ b/src/features/city-vet/services/city-vet-profile.js @@ -0,0 +1,10 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; + +export const cityVetGetProfileService = createAsyncThunk( + "CITY_VET_GET_PROFILE", + async () => { + const { data, status } = await axios.get("city_vet/0/?profile"); + return { data, status }; + } +); diff --git a/src/features/city/components/city-active-requests/CityActiveRequests.js b/src/features/city/components/city-active-requests/CityActiveRequests.js new file mode 100644 index 0000000..f134f32 --- /dev/null +++ b/src/features/city/components/city-active-requests/CityActiveRequests.js @@ -0,0 +1,408 @@ +import { Button, TextField, Typography } from "@mui/material"; +import { useContext, useEffect, useState } from "react"; +import PlagiarismIcon from "@mui/icons-material/Plagiarism"; +// import { ROUTE_CITY_FILE } from "../../../../routes/routes"; +// import { avicultureGetRequests } from "../../../aviculture/services/aviculture-requests"; +import { Grid } from "../../../../components/grid/Grid"; +import { SPACING } from "../../../../data/spacing"; +import { AppContext } from "../../../../contexts/AppContext"; +import { PageTable } from "../../../../components/page-table/PageTable"; +import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl"; +import axios from "axios"; +import { DatePicker } from "@mui/x-date-pickers"; +import moment from "moment/moment"; +import { formatJustDate } from "../../../../utils/formatTime"; +import { IconButton } from "@mui/material"; +import { ROUTE_CITY_FILE } from "../../../../routes/routes"; +import { useNavigate } from "react-router-dom"; +import { RiSearchLine } from "react-icons/ri"; + +export const CityActiveRequests = () => { + const navigate = useNavigate(); + const [, , selectedDate1, setSelectedDate1, selectedDate2, setSelectedDate2] = + useContext(AppContext); + useEffect(() => { + const currentDate = moment(new Date()).format("YYYY-MM-DD"); + setSelectedDate1(currentDate); + setSelectedDate2(currentDate); + }, []); + + // page table + const [data, setData] = useState([]); + const [loading, setLoading] = useState(false); + const [totalRows, setTotalRows] = useState(0); + const [perPage, setPerPage] = useState(10); + + const [textValue, setTextValue] = useState(""); + + const handleTextChange = (event) => { + setTextValue(event.target.value); + }; + + const fetchApiData = async (page, textValue) => { + setLoading(true); + let response = await axios.get( + `Poultry_Request/?state=accepted&date1=${selectedDate1}&date2=${selectedDate2}&search=filter&value=${ + textValue ? textValue : "" + }&role=${getRoleFromUrl()}&page=${page}&page_size=${perPage}` + ); + setData(response.data.results); + setTotalRows(response.data.count); + setLoading(false); + }; + + const handlePageChange = (page) => { + fetchApiData(page, textValue); + }; + + const handlePerRowsChange = async (newPerPage, page) => { + setLoading(true); + let response = await axios.get( + `Poultry_Request/?state=accepted&date1=${selectedDate1}&date2=${selectedDate2}&search=filter&value=${ + textValue ? textValue : "" + }&page=${page}&page_size=${newPerPage}` + ); + + setData(response.data.results); + setTotalRows(response.data.count); + setPerPage(newPerPage); + + setLoading(false); + }; + + useEffect(() => { + fetchApiData(1); + }, [selectedDate1, selectedDate2, perPage]); + + const handleSubmit = async (event) => { + event.preventDefault(); + setLoading(true); + + try { + const response = await axios.get( + `Poultry_Request/?state=accepted&date1=${selectedDate1}&date2=${selectedDate2}&role=${getRoleFromUrl()}&search=filter&value=${ + textValue ? textValue : "" + }` + ); + setData(response.data.results); + setTotalRows(response.data.count); + } catch (error) { + console.error("Error fetching data:", error); + } finally { + setLoading(false); + } + }; + + const columns = [ + { + name: "ردیف", + selector: (item, i) => { + return i + 1; + }, + sortable: false, + wrap: true, + allowOverflow: true, + center: true, + width: "40px", + }, + { + name: "وضعیت", + selector: (item) => ( + + {item.provinceState === "pending" + ? "درانتظار تایید استان" + : item.provinceState === "accepted" + ? "تایید شده توسط استان" + : "رد شده"} + + ), + sortable: false, + wrap: true, + allowOverflow: true, + center: true, + }, + { + name: "کدسفارش", + selector: (item) => item.orderCode, + sortable: false, + wrap: true, + allowOverflow: true, + center: true, + }, + { + name: "تاریخ ثبت درخواست", + selector: (item) => formatJustDate(item.createDate), + sortable: false, + wrap: true, + allowOverflow: true, + center: true, + }, + { + name: "نوع کشتار", + selector: (item) => { + return item?.freezing ? "انجماد" : item?.export ? "صادرات" : "عادی"; + }, + sortable: true, + wrap: true, + allowOverflow: true, + center: true, + width: "80px", + }, + { + name: "تاریخ کشتار", + selector: (item) => formatJustDate(item.sendDate), + sortable: false, + wrap: true, + allowOverflow: true, + center: true, + }, + { + name: "مرغداری", + selector: (item) => + `${item?.poultry?.unitName} (${item?.poultry?.user?.mobile})`, + sortable: false, + wrap: true, + allowOverflow: true, + center: true, + }, + { + name: "شهر", + selector: (item) => item?.poultry?.address?.city?.name, + sortable: false, + wrap: true, + allowOverflow: true, + center: true, + }, + { + name: "استان", + selector: (item) => item?.poultry?.address?.province?.name, + sortable: false, + wrap: true, + allowOverflow: true, + center: true, + }, + { + name: "تاریخ جوجه ریزی", + selector: (item) => formatJustDate(item.hatching.hatchingDate), + sortable: false, + wrap: true, + allowOverflow: true, + center: true, + }, + { + name: "سن", + selector: (item) => item.hatching.age, + sortable: false, + wrap: true, + allowOverflow: true, + center: true, + }, + { + name: "تعداد (قطعه)", + selector: (item) => item?.quantity, + sortable: false, + wrap: true, + allowOverflow: true, + center: true, + }, + { + name: "مشاهده", + selector: (item) => { + return ( + navigate(ROUTE_CITY_FILE + item?.id)} + > + + + ); + }, + sortable: false, + wrap: true, + allowOverflow: true, + center: true, + }, + ]; + + // useEffect(() => { + // dispatch(LOADING_START()); + // dispatch(avicultureGetRequests({ selectedDate1, selectedDate2 })).then( + // (r) => { + // dispatch(LOADING_END()); + // } + // ); + // }, [selectedDate1, selectedDate2]); + + // useEffect(() => { + // const filteredData = avicultureRequests?.filter( + // (item, i) => item.stateProcess === "pending" + // ); + // const d = filteredData?.map((item, i) => { + // return [ + // i + 1, + // item.orderCode, + // item.poultry.userprofile.baseOrder, + // formatJustDate(item.createDate), + // formatJustDate(item.sendDate), + // item?.process?.poultry?.poultryName, + // item?.process?.poultry?.poultryMobile, + // item?.process?.poultry?.poultryCity, + // item?.process?.poultry?.poultryProvince, + // formatJustDate(item.hatching.date), + // item?.process?.poultry?.age, + // item?.process?.poultry?.poultryQuantity, + // + // dispatch( + // DRAWER({ + // right: !(window.innerWidth <= 600), + // bottom: window.innerWidth <= 600, + // content: ( + // + // ), + // title: "انجام عملیات شهرستان", + // }) + // ) + // } + // > + // + // , + // + // navigate(ROUTE_CITY_FILE + item?.process?.poultry?.poultryRequestId) + // } + // > + // + // , + // ]; + // }); + + // setDataTable(d); + // }, [avicultureRequests]); + + return ( + <> + {/* + + درخواست های جدید فروش اتحادیه + + + + ( + + )} + value={selectedDate1} + onChange={(e) => { + setSelectedDate1(moment(e).format("YYYY-MM-DD")); + }} + /> + + + ( + + )} + value={selectedDate2} + onChange={(e) => { + setSelectedDate2(moment(e).format("YYYY-MM-DD")); + }} + /> + + + + } + columns={columnsName} + data={dataTable} + /> */} + + + + + درخواست های فعال + + + ( + + )} + value={selectedDate1} + onChange={(e) => { + setSelectedDate1(moment(e).format("YYYY-MM-DD")); + }} + /> + + + ( + + )} + value={selectedDate2} + onChange={(e) => { + setSelectedDate2(moment(e).format("YYYY-MM-DD")); + }} + /> + + +
    + + + +
    +
    + } + columns={columns} + data={data} + progressPending={loading} + pagination + paginationServer + paginationTotalRows={totalRows} + onChangeRowsPerPage={handlePerRowsChange} + onChangePage={handlePageChange} + /> + + + ); +}; diff --git a/src/features/city/components/city-archive-hatching-drawer/CityArchiveHatchingDrawer.js b/src/features/city/components/city-archive-hatching-drawer/CityArchiveHatchingDrawer.js new file mode 100644 index 0000000..138f92d --- /dev/null +++ b/src/features/city/components/city-archive-hatching-drawer/CityArchiveHatchingDrawer.js @@ -0,0 +1,87 @@ +import React, { useContext } from "react"; +import { useFormik } from "formik"; +import { Button, TextField } from "@mui/material"; +import { useDispatch } from "react-redux"; +import { AppContext } from "../../../../contexts/AppContext"; +import { archiveHatchingService } from "../../services/archive-hatching"; +import { DRAWER } from "../../../../lib/redux/slices/appSlice"; +import * as Yup from "yup"; +// import { cityGetHatchingsByAge } from "../../services/city-get-hatchings-by-age"; +import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl"; +import { cityGetHatchingsByAge } from "../../services/city-get-hatchings-by-age"; + +const validationSchema = Yup.object({ + name: Yup.string(), +}); + +export const CityArchiveHatchingDrawer = ({ + item, + selectedAge1, + selectedAge2, + updateTable, +}) => { + const [openNotif] = useContext(AppContext); + + const dispatch = useDispatch(); + + const formik = useFormik({ + initialValues: { + name: "", + }, + validationSchema, + onSubmit: (values) => { + dispatch( + archiveHatchingService({ + key: item.key, + archive_state: "", + message: values.name, + role: getRoleFromUrl(), + }) + ).then((r) => { + if (r.payload.error) { + openNotif({ + vertical: "top", + horizontal: "center", + msg: r.payload.error, + severity: "error", + }); + } else { + dispatch(DRAWER({ right: false, bottom: false, content: null })); + if (selectedAge1) { + dispatch(cityGetHatchingsByAge({ selectedAge1, selectedAge2 })); + } + updateTable(); + openNotif({ + vertical: "top", + horizontal: "center", + msg: "عملیات با موفقیت انجام شد.", + severity: "success", + }); + } + }); + }, + }); + + return ( +
    + + + + ); +}; diff --git a/src/features/city/components/city-archive-old-hatchings/CityArchvieOldHatchings.js b/src/features/city/components/city-archive-old-hatchings/CityArchvieOldHatchings.js new file mode 100644 index 0000000..46a8061 --- /dev/null +++ b/src/features/city/components/city-archive-old-hatchings/CityArchvieOldHatchings.js @@ -0,0 +1,91 @@ +import { + Button, + FormControl, + FormHelperText, + TextField, + Typography, +} from "@mui/material"; +import { useFormik } from "formik"; +import { useContext } from "react"; +import { useDispatch } from "react-redux"; +import { Grid } from "../../../../components/grid/Grid"; +import { AppContext } from "../../../../contexts/AppContext"; +import { SPACING } from "../../../../data/spacing"; +import { CLOSE_MODAL } from "../../../../lib/redux/slices/appSlice"; +import { Yup } from "../../../../lib/yup/yup"; +import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl"; +import { archiveOldHatchingsService } from "../../services/archive-old-hatchings"; + +export const CityArchiveOldHatchings = () => { + const dispatch = useDispatch(); + const [openNotif] = useContext(AppContext); + const validationSchema = Yup.object().shape({ + numberField: Yup.number().typeError("عدد وارد کنید").required("اجباری است"), + }); + + const initialValues = { + numberField: "", + }; + + const onSubmit = (values) => { + dispatch( + archiveOldHatchingsService({ + age: values.numberField, + role: getRoleFromUrl(), + }) + ).then((r) => { + dispatch(CLOSE_MODAL()); + if (r.payload.error) { + openNotif({ + vertical: "top", + horizontal: "center", + msg: r.payload.error, + severity: "error", + }); + } else { + openNotif({ + vertical: "top", + horizontal: "center", + msg: r.payload.data.msg, + severity: "success", + }); + } + }); + }; + + const formik = useFormik({ + initialValues, + onSubmit, + validationSchema, + }); + + return ( +
    + + + توجه : تمام جوجه ریزی های فعالی که بیشتر از سن وارده شده در کادر زیر + باشند به بایگانی منتقل میشوند. + + + + {formik.touched.numberField && formik.errors.numberField && ( + {formik.errors.numberField} + )} + + + +
    + ); +}; diff --git a/src/features/city/components/city-edit-aviculture-info-form/CityEditAvicultureInfoForm.js b/src/features/city/components/city-edit-aviculture-info-form/CityEditAvicultureInfoForm.js new file mode 100644 index 0000000..cb6596c --- /dev/null +++ b/src/features/city/components/city-edit-aviculture-info-form/CityEditAvicultureInfoForm.js @@ -0,0 +1,554 @@ +import { + Autocomplete, + Button, + Chip, + Divider, + FormControl, + InputLabel, + MenuItem, + Select, + TextField, +} from "@mui/material"; +import { Grid } from "../../../../components/grid/Grid"; +import { SPACING } from "../../../../data/spacing"; +import React, { useEffect } from "react"; +import { Yup } from "../../../../lib/yup/yup"; +import { useFormik } from "formik"; +import { useDispatch } from "react-redux"; +import { cityGetProvinces } from "../../services/CityGetProvinces"; +import { + DRAWER, + LOADING_END, + LOADING_START, +} from "../../../../lib/redux/slices/appSlice"; +import { useState } from "react"; +import { cityGetCity } from "../../services/city-get-city"; +import { cityEditAvicultureInfo } from "../../services/city-edit-avculture.info"; +import { useContext } from "react"; +import { AppContext } from "../../../../contexts/AppContext"; +import { PropTypes } from "prop-types"; +import { cityGetPoultryFarm } from "../../services/city-get-poultry-farms"; + +export const CityEditAvicultureInfoForm = ({ item }) => { + const dispatch = useDispatch(); + const [openNotif] = useContext(AppContext); + const [provinceData, setProvinceData] = useState(); + const [cityData, setCityData] = useState(); + const [provinceKey, setProvinceKey] = useState(); + const [cityKey, setCityKey] = useState(); + + const [isExistProvince, setIsExistProvince] = useState(true); + + const formik = useFormik({ + initialValues: { + avicultureName: item?.unitName ? item?.unitName : "", + postal: item?.address.postalCode ? item?.address.postalCode : "", + address: item?.address.address ? item?.address.address : "", + bankUser: item?.userBankInfo?.nameOfBankUser + ? item?.userBankInfo?.nameOfBankUser + : "", + card: item?.userBankInfo?.card ? item?.userBankInfo.card : "", + account: item?.userBankInfo?.account ? item?.userBankInfo.account : "", + bankName: "", + shaba: item?.userBankInfo?.shaba ? item?.userBankInfo.shaba : "", + hall: item?.numberOfHalls ? item?.numberOfHalls : "", + breedingUniqueId: item?.breedingUniqueId ? item?.breedingUniqueId : "", + systemCode: item?.systemCode ? item?.systemCode : "", + epidemiologicalCode: item?.epidemiologicalCode + ? item?.epidemiologicalCode + : "", + totalCapacity: item?.totalCapacity ? item?.totalCapacity : "", + healthCertificateNumber: item?.healthCertificateNumber + ? item?.healthCertificateNumber + : "", + }, + validationSchema: Yup.object({ + avicultureName: Yup.string().typeError( + "لطفا فیلد را به درستی وارد کنید!" + ), + address: Yup.string().typeError("لطفا فیلد را به درستی وارد کنید!"), + card: Yup.number().typeError("لطفا فیلد را به درستی وارد کنید!"), + + bankUser: Yup.string().typeError("لطفا فیلد را به درستی وارد کنید!"), + postal: Yup.number().typeError("لطفا فیلد را به درستی وارد کنید!"), + account: Yup.number().typeError("لطفا فیلد را به درستی وارد کنید!"), + bankName: Yup.string().typeError("لطفا فیلد را به درستی وارد کنید!"), + shaba: Yup.string().typeError("لطفا فیلد را به درستی وارد کنید!"), + hall: Yup.number().typeError("لطفا فیلد را به درستی وارد کنید!"), + breedingUniqueId: Yup.number().typeError( + "لطفا فیلد را به درستی وارد کنید!" + ), + systemCode: Yup.number().typeError("لطفا فیلد را به درستی وارد کنید!"), + epidemiologicalCode: Yup.number().typeError( + "لطفا فیلد را به درستی وارد کنید!" + ), + totalCapacity: Yup.number().typeError("لطفا فیلد را به درستی وارد کنید!"), + healthCertificateNumber: Yup.number().typeError( + "لطفا فیلد را به درستی وارد کنید!" + ), + }), + }); + + useEffect(() => { + formik.validateForm(); + }, []); + + useEffect(() => { + dispatch(LOADING_START()); + dispatch(cityGetProvinces())?.then((r) => { + dispatch(LOADING_END()); + setProvinceData(r.payload.data); + }); + }, []); + + useEffect(() => { + if (provinceKey) { + dispatch(LOADING_START()); + dispatch(cityGetCity(provinceKey)).then((r) => { + setCityData(r.payload.data); + setIsExistProvince(false); + dispatch(LOADING_END()); + }); + } + }, [provinceKey]); + + return ( + + + + + + + + + + + + + + + + ({ id: i.key, label: i.name })) + : [] + } + onChange={(event, value) => { + setProvinceKey(value.id); + }} + renderInput={(params) => ( + + )} + /> + + + ({ id: i.key, label: i.name })) + : [] + } + onChange={(event, value) => { + setCityKey(value.id); + }} + renderInput={(params) => ( + + )} + /> + + + + + + + + + + + + + + + + + + + + + + + + + + + بانک + + + + + + + + + + + + + + + + + + ); +}; + +CityEditAvicultureInfoForm.propTypes = { + item: PropTypes.any, +}; diff --git a/src/features/city/components/city-edit-hatching-quantity/CityEditHatchingQuantity.js b/src/features/city/components/city-edit-hatching-quantity/CityEditHatchingQuantity.js new file mode 100644 index 0000000..37d767c --- /dev/null +++ b/src/features/city/components/city-edit-hatching-quantity/CityEditHatchingQuantity.js @@ -0,0 +1,110 @@ +import { Button, IconButton, TextField, Tooltip } from "@mui/material"; +import EditIcon from "@mui/icons-material/Edit"; +import { useDispatch } from "react-redux"; +import { CLOSE_MODAL, OPEN_MODAL } from "../../../../lib/redux/slices/appSlice"; +import { useContext, useState } from "react"; +import { cityEditHatchingQuantityService } from "../../services/city-edit-hatching-quantity"; +import { AppContext } from "../../../../contexts/AppContext"; +// import { cityGetHatchings } from "../../services/city-get-hatchings"; +// import { cityGetHatchingsByAge } from "../../services/city-get-hatchings-by-age"; +import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl"; + +export const CityEditHatchingQuantity = ({ + quantity, + hatchingKey, + selectedAge1, + selectedAge2, + updateTable, +}) => { + const dispatch = useDispatch(); + + return ( + + { + dispatch( + OPEN_MODAL({ + title: "ویرایش تعداد جوجه ریزی", + content: ( + + ), + }) + ); + }} + > + + + + ); +}; + +const ModalContent = ({ + quantity, + hatchingKey, + selectedAge1, + selectedAge2, + updateTable, +}) => { + const dispatch = useDispatch(); + const [openNotif] = useContext(AppContext); + const [value, setValue] = useState(quantity); + + const handleChange = (event) => { + setValue(event.target.value); + }; + return ( + <> + + + + ); +}; diff --git a/src/features/city/components/city-hatching-info/CityHatchingInfo.js b/src/features/city/components/city-hatching-info/CityHatchingInfo.js new file mode 100644 index 0000000..62034e2 --- /dev/null +++ b/src/features/city/components/city-hatching-info/CityHatchingInfo.js @@ -0,0 +1,291 @@ +import React, { useContext, useEffect } from "react"; +import { + Button, + TextField, + Tooltip, + Typography, + Box, + Divider, + Chip, +} from "@mui/material"; +import { DatePicker } from "@mui/x-date-pickers"; +import moment from "moment"; +import { useDispatch, useSelector } from "react-redux"; +import { cityGetHatchingInfo } from "../../services/city-get-hatching-info"; +import { cityGetHatchingInfoFull } from "../../services/city-get-hatching-info-full"; +import ResponsiveTable from "../../../../components/responsive-table/ResponsiveTable"; +import { AppContext } from "../../../../contexts/AppContext"; +import { RiFileExcel2Fill } from "react-icons/ri"; +import { useFormik } from "formik"; +import axios from "axios"; +import { Grid } from "../../../../components/grid/Grid"; + +export const CityHatchingInfo = () => { + const { hatchingInfoWithDate, hatchingInfoFull } = useSelector( + (state) => state.citySlice + ); + const dispatch = useDispatch(); + const [, , selectedDate1, setSelectedDate1, selectedDate2, setSelectedDate2] = + useContext(AppContext); + + useEffect(() => { + const currentDate = moment(new Date()).format("YYYY-MM-DD"); + setSelectedDate1(currentDate); + setSelectedDate2(currentDate); + }, []); + + useEffect(() => { + dispatch(cityGetHatchingInfoFull()); + }, []); + + useEffect(() => { + dispatch(cityGetHatchingInfo({ selectedDate1, selectedDate2 })); + }, [selectedDate1, selectedDate2]); + + const formik = useFormik({ + initialValues: { + minAge: "", + maxAge: "", + }, + }); + + return ( + + + + اطلاعات جوجه ریزی + + } + /> + + + + {/* Full Summary Table */} + + + + + + + بر اساس بازه + + } + /> + + + + + + ( + + )} + value={selectedDate1} + onChange={(e) => + setSelectedDate1(moment(e).format("YYYY-MM-DD")) + } + /> + + + ( + + )} + value={selectedDate2} + onChange={(e) => + setSelectedDate2(moment(e).format("YYYY-MM-DD")) + } + /> + + + + + + + + + + + + + + + + + + گزارش مانده سالن فارم های بیشتر از 10 درصد + + } + /> + + + گزارش مانده سالن فارم های بیشتر از 10 درصد + + + + + + + + + + + + + + + + + + + + + ); +}; diff --git a/src/features/city/components/city-hatching-operations/CityOperationsOperations.js b/src/features/city/components/city-hatching-operations/CityOperationsOperations.js new file mode 100644 index 0000000..16400d4 --- /dev/null +++ b/src/features/city/components/city-hatching-operations/CityOperationsOperations.js @@ -0,0 +1,39 @@ +import { useLocation } from "react-router-dom"; +import { Button } from "@mui/material"; +import { NavLink } from "../../../../components/nav-link/NavLink"; +import { Grid } from "../../../../components/grid/Grid"; +import { SPACING } from "../../../../data/spacing"; +import { + ROUTE_CITY_HATCHING, + ROUTE_CITY_NEW_REQUEST, +} from "../../../../routes/routes"; + +export const CityHatchingOperations = () => { + const { pathname } = useLocation(); + + return ( + + + + + + + + + ); +}; diff --git a/src/features/city/components/city-hatching-show-table-detail/CityHatchingShowTableDetail.js b/src/features/city/components/city-hatching-show-table-detail/CityHatchingShowTableDetail.js new file mode 100644 index 0000000..c4a0cd4 --- /dev/null +++ b/src/features/city/components/city-hatching-show-table-detail/CityHatchingShowTableDetail.js @@ -0,0 +1,1118 @@ +import { useEffect, useState } from "react"; +import { useDispatch } from "react-redux"; +import { Grid } from "../../../../components/grid/Grid"; +import { + Accordion, + AccordionDetails, + AccordionSummary, + Box, + Button, + IconButton, + Tooltip, + Typography, +} from "@mui/material"; +import { + convertToIranianTime, + formatJustDate, + formatTime, +} from "../../../../utils/formatTime"; +import { CheckCleanceCode } from "../../../../components/check-clearance-code/ChechClearanceCode"; +import { BackButton } from "../../../../components/back-button/BackButton"; +import ResponsiveTable from "../../../../components/responsive-table/ResponsiveTable"; +import { cityHatchingShowTableDetail } from "../../services/city-hatching-show-table-detail"; +import { + LOADING_END, + LOADING_START, + OPEN_MODAL, +} from "../../../../lib/redux/slices/appSlice"; +import ExpandMoreIcon from "@mui/icons-material/ExpandMore"; +import axios from "axios"; +import { ImFilePdf } from "react-icons/im"; +import { ProvinceBarDifferencesModal } from "../../../province/components/province-bar-differences-modal/ProvinceBarDifferencesModal"; + +export const CityHatchingShowTableDetail = ({ keyItem }) => { + const [data, setData] = useState(null); + const [totalData, setTotalData] = useState([]); + const [slaughterInformation, setSlaughterInformation] = useState([]); + const [barInData, setbarInData] = useState([]); + const [barOutData, setbarOutData] = useState([]); + const [chainData, setChainData] = useState([]); + const [differnceBarData, setDiffernceBarData] = useState([]); + const [combinedCargoData, setCombinedCargoData] = useState([]); + const [returnedAllocatedData, setReturnedAllocatedData] = useState([]); + const [differenceData, setDifferenceData] = useState([]); + const [evacuationReportsData, setEvacuationReportsData] = useState([]); + const dispatch = useDispatch(); + + useEffect(() => { + dispatch(LOADING_START()); + dispatch(cityHatchingShowTableDetail({ keyItem })).then((r) => { + setData(r.payload.data); + dispatch(LOADING_END()); + }); + }, []); + + useEffect(() => { + const newTotalData = [ + { title: "نام فارم", value: data?.poultry?.unitName || "-" }, + { + title: "مرغدار", + value: data?.poultry?.user + ? `${data.poultry?.user.fullname} (${data.poultry?.user?.mobile})` + : "-", + }, + { title: "بهره برداری", value: data?.InteractTypeName || "-" }, + { title: "تاریخ جوجه ریزی", value: formatJustDate(data?.date) || "-" }, + { + title: "حجم جوجه ریزی", + value: data?.quantity?.toLocaleString() || "-", + }, + { title: "سن", value: data?.chickenAge || "-" }, + { title: "نژاد", value: data?.chickenBreed || "-" }, + { title: "وضعیت", value: data?.violation ? "پیگیری" : "عادی" }, + { title: "شماره مجوز جوجه ریزی", value: data?.licenceNumber || "-" }, + { title: "شناسه یکتا", value: data?.poultry?.breedingUniqueId || "-" }, + { title: "مجوز بهداشتی جوجه ریزی", value: data?.CertId || "-" }, + { title: "ارتباط", value: data?.UnionTypeName || "-" }, + { + title: "استان", + value: data?.poultry?.address?.province?.name || "-", + }, + { + title: "دامپزشک فارم", + value: data?.vetFarm + ? `${data?.vetFarm?.vetFarmFullName} (${data?.vetFarm?.vetFarmMobile})` + : "-", + }, + { title: "سالن", value: data?.hall || "-" }, + { title: "دوره جوجه ریزی", value: data?.period || "-" }, + { + title: "تاریخ ثبت جوجه ریزی", + value: formatJustDate(data?.createDate) || "-", + }, + { + title: "میانگین سن کشتار", + value: data?.killingAveAge?.toLocaleString() || "-", + }, + { + title: "پیش بینی تاریخ کشتار", + value: formatJustDate(data?.predicateDate) || "-", + }, + { title: "مالکیت", value: data?.PersonTypeName || "-" }, + ]; + + const newSlaughterInformation = [ + { + title: " تایید تخلیه در رصدیار", + value: `%${( + ((data?.killedQuantity + data?.totalLosses) * 100) / + data?.quantity + ).toFixed(0)}`, + }, + { + title: " تایید تخلیه در سماصط", + value: data?.samasatDischargePercentage + ? `%${data?.samasatDischargePercentage}` + : "-", + }, + { + title: "حجم کشتار شده", + value: data?.killedQuantity + ? `${data?.killedQuantity?.toLocaleString()} (%${( + (data?.killedQuantity * 100) / + data?.quantity + ).toFixed(0)})` + : "0 (0%)", + }, + // { + // title: "وزن بازگشتی", + // value: data?.killingInfo?.totalReturnWeight?.toLocaleString() || "0", + // }, + // { + // title: "حجم بازگشتی", + // value: data?.killingInfo?.totalReturnQuantity?.toLocaleString() || "0", + // }, + { + title: "حجم تخصیصات بازگشتی", + value: + data?.killingInfo?.returnProvinceKillRequestsQuantity?.toLocaleString() || + "0", + }, + { + title: "وزن تخصیصات بازگشتی", + value: + data?.killingInfo?.returnProvinceKillRequestsWeight?.toLocaleString() || + "0", + }, + { + title: "حجم بارهای بازگشتی", + value: + data?.killingInfo?.returnKillHouseQuantity?.toLocaleString() || "0", + }, + { + title: "وزن بارهای بازگشتی", + value: + data?.killingInfo?.returnKillHouseWeight?.toLocaleString() || "0", + }, + { + title: "حجم مانده در سالن", + value: data?.leftOver + ? `${data?.leftOver.toLocaleString()} (%${( + (data?.leftOver * 100) / + data?.quantity + ).toFixed(0)})` + : "0 (0%)", + }, + { + title: "تلفات کل", + value: data?.totalLosses + ? `${data?.totalLosses.toLocaleString()} (%${( + (data?.totalLosses * 100) / + data?.quantity + ).toFixed(0)})` + : "0 (0%)", + }, + { + title: "وزن کل کشتار", + value: data?.totalKilledWeight?.toLocaleString() || "0", + }, + { + title: "تعداد بارها", + value: data?.killingInfo?.killHouseRequests?.toLocaleString() || "0", + }, + { + title: "حجم بارها", + value: + data?.killingInfo?.killHouseRequestsFirstQuantity?.toLocaleString() || + "0", + }, + { + title: "وزن بارها", + value: + data?.killingInfo?.killHouseRequestsFirstWeight?.toLocaleString() || + "0", + }, + { + title: "افت بارها", + value: + `${data?.killingInfo?.wareHouseBarsWeightLose?.toFixed()}%` || "0", + }, + { + title: "حجم فروش به داخل استان", + value: + data?.killingInfo?.totalSaleInProvinceQuantity?.toLocaleString() || + "0", + }, + { + title: "وزن فروش به داخل استان", + value: + data?.killingInfo?.totalSaleInProvinceWeight?.toLocaleString() || "0", + }, + { + title: "حجم فروش به خارج استان", + value: data?.outProvinceKilledQuantity?.toLocaleString() || "0", + }, + { + title: "وزن فروش به خارج استان", + value: data?.outProvinceKilledWeight?.toLocaleString() || "0", + }, + { + title: "حجم اختلاف کشتار", + value: data?.barDifferenceRequestQuantity || "0", + }, + { + title: "وزن اختلاف کشتار", + value: data?.barDifferenceRequestWeight || "0", + }, + { + title: "تعداد بارهای تحویلی", + value: + data?.killingInfo?.barCompleteWithKillHouse?.toLocaleString() || "0", + }, + { + title: "حجم بارهای تحویلی", + value: + data?.killingInfo?.acceptedRealQuantityFinal?.toLocaleString() || "0", + }, + { + title: "وزن بارهای تحویلی", + value: + data?.killingInfo?.acceptedRealWightFinal?.toLocaleString() || "0", + }, + { + title: "بارهای ورودی به انبار", + value: data?.killingInfo?.wareHouseBars?.toLocaleString() || "0", + }, + { + title: "حجم لاشه های انبار", + value: + data?.killingInfo?.wareHouseBarsQuantity?.toLocaleString() || "0", + }, + { + title: "وزن لاشه های انبار", + value: data?.killingInfo?.wareHouseBarsWeight?.toLocaleString() || "0", + }, + { + title: "حجم تعهد دولتی", + value: data?.totalCommitmentQuantity?.toLocaleString() || "0", + }, + { + title: "حجم کشتار دولتی", + value: data?.governmentalQuantity?.toLocaleString() || "0", + }, + { + title: "حجم تعهد آزاد", + value: data?.totalFreeCommitmentQuantity?.toLocaleString() || "0", + }, + + { + title: "حجم کشتار آزاد", + value: data?.freeQuantity?.toLocaleString() || "0", + }, + { + title: "تخصیصات بدون بار", + value: data?.killingInfo?.provinceKillRequests?.toLocaleString() || "0", + }, + { + title: "حجم تخصیصات بدون بار", + value: + data?.killingInfo?.provinceKillRequestsQuantity?.toLocaleString() || + "0", + }, + { + title: "وزن تخصیصات بدون بار", + value: + data?.killingInfo?.provinceKillRequestsWeight?.toLocaleString() || + "0", + }, + { + title: "وزن تعهد دولتی", + value: data?.totalCommitment?.toLocaleString() || "0", + }, + { + title: "میانگین وزن کشتار", + value: data?.totalAverageKilledWeight?.toLocaleString() || "0", + }, + + { + title: "تعداد کشتار فعال", + value: data?.activeKill?.activeKill ? "دارد" : "ندارد", + }, + { + title: "تعداد درخواست کشتار", + value: data?.activeKill?.countOfRequest || "0", + }, + { + title: "حجم افزایشی", + value: data?.increaseQuantity?.toLocaleString() || "0", + }, + { + title: "تلفات دامپزشک", + value: data?.losses + ? `${data?.losses.toLocaleString()} (%${( + (data?.losses * 100) / + data?.quantity + ).toFixed(0)})` + : "0 (0%)", + }, + + { + title: "تلفات اتحادیه", + value: data?.directLosses + ? `${data?.directLosses.toLocaleString()} (%${( + (data?.directLosses * 100) / + data?.quantity + ).toFixed(0)})` + : "0 (0%)", + }, + + { + title: "آخرین تغییر", + value: data?.latestHatchingChange + ? `${data?.latestHatchingChange?.fullName} در تاریخ ${formatTime( + data?.latestHatchingChange?.date + )}` + : "-", + }, + ]; + + const newBarInData = data?.bars?.map((bar, index) => { + return [ + index + 1, + bar?.barCode, + bar?.status || "-", + bar?.poultryRequest?.freeSaleInProvince ? "آزاد" : "دولتی", + formatJustDate(bar?.date), + bar?.buyer?.name || "-", + bar?.buyer?.killHouseOperator?.user?.mobile || "-", + bar?.killerInfo + ? `${bar?.killerInfo?.killHouseOperator?.user?.fullname}(${bar?.killerInfo?.killHouseOperator?.user?.mobile})` + : "-", + bar?.poultryRequest?.age || "-", + bar?.product || "-", + `${bar?.buyer?.killHouseOperator?.address?.province?.name}(${bar?.buyer?.killHouseOperator?.address?.city?.name})` || + "-", + , + bar?.quarantineQuantity || "-", + bar?.acceptedRealQuantity?.toLocaleString() || "-", + bar?.acceptedRealWeight?.toLocaleString() || "-", + bar?.wareHouseAcceptedRealQuantity?.toLocaleString() || "-", + bar?.wareHouseAcceptedRealWeight?.toLocaleString() || "-", + ]; + }); + + const newBarOutData = data?.outBars?.map((bar, index) => { + return [ + index + 1, + bar?.orderCode, + formatJustDate(bar?.sendDate), + bar?.buyerFullname || "-", + bar?.buyerMobile || "-", + "مرغ گرم", + `${bar?.buyerProvince}(${bar?.buyerProvince})` || "-", + , + bar?.quarantinQuantity || "-", + bar?.killingAge || "-", + bar?.quantity?.toLocaleString() || "-", + bar?.weight?.toLocaleString() || "-", + ]; + }); + const newDiffernceBarData = data?.differentBars?.map((bar, index) => { + return [ + index + 1, + bar?.ResideDatePersian || "-", + bar?.GoodAmount?.toLocaleString() || "-", + bar?.Out ? "خارج استان" : "داخل استان", + bar?.Age || "-", + bar?.TrackingStatusDescription || "-", + bar?.DesUnitName || "-", + bar?.GoodName || "-", + bar?.City || "-", + bar?.TrackingCode || "-", + ]; + }); + // Combine nonReceipt and returnKillHouseRequest data + + const newCombinedCargoData = data?.returnKillHouseRequest?.map( + (item, index) => { + let state = ""; + if (item.state === "pending") { + state = "در انتظار تایید"; + } else if (item.state === "accepted") { + state = "تایید شده"; + } else if (item.state === "rejected") { + state = "رد شده"; + } + + let requestType = ""; + if (item?.poultryRequest?.market) { + requestType = "پنل معاملات"; + } else if (item?.poultryRequest?.directBuying) { + requestType = "خرید مستقیم"; + } else if (item?.warehouse) { + requestType = "انبار"; + } else { + requestType = "اتحادیه"; + } + + let killType = ""; + if (item?.poultryRequest?.freezing) { + killType = "انجماد"; + } else if (item?.poultryRequest?.export) { + killType = "صادرات"; + } else { + killType = "عادی"; + } + + // Determine the type based on return_trash field or dataType + + return [ + index + 1, + item?.barCode || "-", + item?.poultryRequest?.orderCode || "-", + requestType, + killType, + item?.poultryRequest?.poultry?.unitName || "-", + `${item?.poultryRequest?.poultry?.user?.fullname || "-"} (${ + item?.poultryRequest?.poultry?.user?.mobile || "-" + })`, + item?.poultryRequest?.age, + item?.poultryRequest?.poultry?.address?.city?.name || "-", + formatTime(item?.killRequest?.reciveDate) || + formatJustDate(item?.date) || + "-", + item?.quantity?.toLocaleString() || "-", + formatTime(item?.createDate) || "-", + item?.killhouseUser?.name || + item?.killer?.name || + item?.buyer?.name || + "-", + item?.killhouseUser?.killHouseOperator?.user?.city?.name || + item?.killer?.killHouseOperator?.user?.city?.name || + `${item?.buyer?.killHouseOperator?.address?.province?.name || ""}(${ + item?.buyer?.killHouseOperator?.address?.city?.name || "" + })` || + "-", + item?.weightInfo?.weight?.toLocaleString() || "-", + item?.weightInfo?.indexWeight?.toLocaleString() || "-", + item?.acceptedRealQuantity?.toLocaleString() || "-", + item?.acceptedRealWeight?.toLocaleString() || "-", + item?.poultryRequest?.amount?.toLocaleString() + " ﷼" || "-", + item?.weightInfo?.killHousePrice?.toLocaleString() + " ﷼" || "-", + state || "-", + item?.car?.pelak || "-", + item?.car?.driverName || item?.addCar?.driver?.driverName || "-", + , + item?.quarantineQuantity || "-", + formatTime(item?.modifyDate), + item?.dataType === "returned" + ? (item?.nonReceipt && item?.mainNonReceipt ? `کاربر` : "سیستم") + + " " + + formatTime(item?.modifyDate) + : "-", + ]; + } + ); + + const newChainData = data?.chainAllocation?.map((item, index) => { + return [ + index + 1, + item?.state === "accepted" + ? "تایید شده" + : item?.state === "pending" + ? "در انتظار تایید" + : "رد شده", + + formatJustDate(item?.date), + item?.outProvince ? "خارج استان" : "داخل استان", + `${item?.registerer?.fullname} (${item?.registerer?.mobile})`, + item?.killHouse?.killHouseOperator?.user.fullname + ? `${item?.killHouse?.killHouseOperator?.user.fullname} (${item?.killHouse?.killHouseOperator?.user.mobile})` + : `${item?.buyerName} (${item?.buyerMobile})`, + `${item?.companyName} (${item?.companyUserMobile})`, + + item?.healthCode, + item?.quarantineCode || "-", + item?.driverName ? `${item?.driverName} (${item?.driverMobile})` : "-", + item?.typeCar, + item?.pelak, + item?.quantity, + item?.indexWeight, + item?.weight, + ]; + }); + + // Map returnProvinceRequest data (Returned Allocated) + const newReturnedAllocatedData = data?.returnProvinceRequest?.map( + (item, index) => { + let state = ""; + if (item.state === "pending") { + state = "در انتظار تایید"; + } else if (item.state === "accepted") { + state = "تایید شده"; + } else if (item.state === "rejected") { + state = "رد شده"; + } + + let requestType = ""; + if (item?.market) { + requestType = "پنل معاملات"; + } else if (item?.directBuying) { + requestType = "خرید مستقیم"; + } else if (item?.warehouse) { + requestType = "انبار"; + } else { + requestType = "اتحادیه"; + } + + return [ + index + 1, + item?.orderCode || "-", + requestType, + item?.poultryUnitName, + `${item?.poultryFullname} (${item?.poultryMobile})`, + item?.poultryRequest?.age, + item?.poultryCity, + formatJustDate(item?.killingDate), + item?.poultryRequestQuantity?.toLocaleString(), + formatJustDate(item?.createDate), + item?.killhouseUser?.name || "-", + item?.killhouseUser?.city || "-", + item?.poultryAmount?.toLocaleString() + " ﷼", + item?.killHousePrice?.toLocaleString() + " ﷼", + item?.quantity?.toLocaleString(), + state, + item?.firstCarAllocatedQuantity > 0 ? "دارد" : "ندارد", + (item?.quantity - item?.totalKilledQuantity)?.toLocaleString(), + (item?.returner + ? `${item?.returner.fullname} (${item?.returner?.mobile})` + : "سیستم") + + " " + + convertToIranianTime(item?.modifyDate), + ]; + } + ); + + const newDifferenceData = data?.barDiffrentRequets?.map((item, index) => { + return [ + index + 1, + item?.registerFullname, + formatJustDate(item?.createDate), + `${item?.hatching?.poultry?.unitName || ""} (${ + item?.hatching?.poultry?.user?.mobile || "" + })`, + `${item?.killHouse?.name || ""} (${ + item?.killHouse?.killHouseOperator?.user?.mobile || "" + })`, + item?.barInfo?.totalQuantity?.toLocaleString(), + item?.barInfo?.totalWeight?.toLocaleString(), + item?.barInfo?.firstTotalQuantity?.toLocaleString(), + item?.barInfo?.differenceQuantity?.toLocaleString(), + item?.quantity?.toLocaleString(), + item?.weight?.toLocaleString(), + + item?.acceptorImages?.[0] || + item?.acceptorMessage || + item?.registerMessage || + item?.violationImage?.[0] ? ( + + { + dispatch( + OPEN_MODAL({ + content: , + title: "پیوست", + }) + ); + }} + > + ✉️ + + + ) : ( + "-" + ), + + item.state === "pending" + ? "در انتظار تایید" + : item.state === "rejected" + ? "رد شده" + : "تایید شده", + ]; + }); + + const newEvacuationReportsData = data?.evacuationReports?.map( + (item, index) => { + return [ + index + 1, + item?.MoReportId || "-", + item?.ReportTypeString || "-", + item?.MoDateShamsi ?? "-", + item?.GoodCount?.toLocaleString() || "-", + item?.RegDateShamsiWithTime ?? "-", + ]; + } + ); + + setTotalData(newTotalData); + setSlaughterInformation(newSlaughterInformation); + setbarInData(newBarInData); + setbarOutData(newBarOutData); + setChainData(newChainData); + setDiffernceBarData(newDiffernceBarData); + setCombinedCargoData(newCombinedCargoData); + setReturnedAllocatedData(newReturnedAllocatedData); + setDifferenceData(newDifferenceData); + setEvacuationReportsData(newEvacuationReportsData); + }, [data]); + + return ( + + + + + + + + + + + + + + + + اطلاعات واحد گله + + + + + + {totalData.map((item, index) => ( + + + {item?.title}: + + + {item?.value || "-"} + + + ))} + + + + + + + اطلاعات کشتار و تلفات + + + + + + {slaughterInformation?.map((item, index) => { + const isRedItem = [ + "حجم تخصیصات بازگشتی", + "وزن تخصیصات بازگشتی", + "حجم بارهای بازگشتی", + "وزن بارهای بازگشتی", + "وزن اختلاف کشتار", + "حجم اختلاف کشتار", + ].includes(item?.title); + + return ( + + + {item?.title}: + + + {item?.value || "-"} + + + ); + })} + + + + + + + }> + اطلاعات بارهای داخل استان + + + + + + + + + + + }> + اطلاعات بارهای قرنطینه + + + + + + + + + + + }> + اطلاعات بارهای بازگشتی + + + + + + + + + + + }> + اطلاعات تخصیصات بازگشتی + + + + + + + + + + + }> + اطلاعات بارهای خارج استان + + + + + + + + + + + + }> + مدیریت بار زنجیره + + + + + + + + + + + }> + اختلاف کشتار + + + + + + + + + + + }> + گزارش تلفات + + + + + + + + + + ); +}; diff --git a/src/features/city/components/city-hatching-unassigned/CityHatchingUnassigned.js b/src/features/city/components/city-hatching-unassigned/CityHatchingUnassigned.js new file mode 100644 index 0000000..2cd4601 --- /dev/null +++ b/src/features/city/components/city-hatching-unassigned/CityHatchingUnassigned.js @@ -0,0 +1,691 @@ +import { + Button, + IconButton, + TextField, + Tooltip, + Typography, +} from "@mui/material"; +import axios from "axios"; +import { useContext, useEffect, useState } from "react"; +import { RiFileExcel2Fill, RiSearchLine } from "react-icons/ri"; +import { Grid } from "../../../../components/grid/Grid"; +import { SPACING } from "../../../../data/spacing"; +import { formatTime, formatJustDate } from "../../../../utils/formatTime"; +import { getFaUserRole } from "../../../../utils/getFaUserRole"; +import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl"; +import { CityManageHatchingsArchiveActions } from "../city-manage-hatchings-operations/CityManageHatchingsOperations"; +import { useDispatch, useSelector } from "react-redux"; +import { AppContext } from "../../../../contexts/AppContext"; +import { cityGetHatchingInfoFull } from "../../services/city-get-hatching-info-full"; +import ResponsiveTable from "../../../../components/responsive-table/ResponsiveTable"; +import { + // DRAWER, + LOADING_END, + LOADING_START, + OPEN_MODAL, +} from "../../../../lib/redux/slices/appSlice"; +import { SimpleTable } from "../../../../components/simple-table/SimpleTable"; +import ShowImage from "../../../../components/show-image/ShowImage"; +import RemoveRedEyeIcon from "@mui/icons-material/RemoveRedEye"; +import ArticleIcon from "@mui/icons-material/Article"; +import { + ROUTE_ADMINXـHATCHINGS, + ROUTE_CITY_JIHADـHATCHINGS, + ROUTE_CITY_POULTRYـHATCHINGS, + ROUTE_PROVINCE_SUPERVISORـHATCHINGS, + ROUTE_PROVINCEـHATCHINGS, + ROUTE_SUPER_ADMINـHATCHINGS, + ROUTE_SUPPORTERـHATCHINGS, +} from "../../../../routes/routes"; +import { useNavigate } from "react-router-dom"; + +// import { CityHatchingShowTableDetail } from "../city-hatching-show-table-detail/CityHatchingShowTableDetail"; + +export const CityHatchingUnassigned = ({ readOnly }) => { + const dispatch = useDispatch(); + + const isReadOnly = readOnly || false; + const [selectedAge1, setSelectedAge1] = useState(0); + const [selectedAge2, setSelectedAge2] = useState(0); + const [data, setData] = useState([]); + const [totalRows, setTotalRows] = useState(0); + const [perPage, setPerPage] = useState(10); + const [textValue, setTextValue] = useState(""); + const [page, setPage] = useState(1); + const [tableData, setTableData] = useState([]); + const userKey = useSelector((state) => state.userSlice.userProfile.key); + const navigate = useNavigate(); + + const [openNotif] = useContext(AppContext); + + const handleTextChange = (event) => { + setTextValue(event.target.value); + }; + + const hatchingAdded = useSelector((state) => state.citySlice.hatchingAdded); + + useEffect(() => { + fetchApiData(); + }, [hatchingAdded]); + + const fetchApiData = async (pageParam = page, perPageParam = perPage) => { + dispatch(LOADING_START()); + const response = await axios.get("poultry_hatching/", { + params: { + unknown: true, + search: "filter", + value: textValue, + role: getRoleFromUrl(), + page: pageParam, + page_size: perPageParam, + age1: selectedAge1 || 0, + age2: selectedAge2 || 0, + }, + }); + dispatch(LOADING_END()); + setData(response.data.results); + setTotalRows(response.data.count); + }; + + const handlePageChange = (page) => { + setPage(page); + fetchApiData(page, perPage); + }; + + const handlePerRowsChange = (perRows) => { + setPerPage(perRows); + setPage(1); + }; + + useEffect(() => { + fetchApiData(); + }, [perPage]); + + const updateTable = () => { + fetchApiData(); + }; + + // const killedNumber = (item) => { + // let killedNumber = ""; + // killedNumber = item.quantity - item.losses - item.leftOver; + // return killedNumber; + // }; + + useEffect(() => { + const d = data?.map((item, i) => { + return [ + , + + { + navigate( + getRoleFromUrl() === "AdminX" + ? `${ROUTE_ADMINXـHATCHINGS}/${item.key}` + : getRoleFromUrl() === "Supporter" + ? `${ROUTE_SUPPORTERـHATCHINGS}/${item.key}` + : getRoleFromUrl() === "SuperAdmin" + ? `${ROUTE_SUPER_ADMINـHATCHINGS}/${item.key}` + : getRoleFromUrl() === "CityPoultry" + ? `${ROUTE_CITY_POULTRYـHATCHINGS}/${item.key}` + : getRoleFromUrl() === "ProvinceSupervisor" + ? `${ROUTE_PROVINCE_SUPERVISORـHATCHINGS}/${item.key}` + : getRoleFromUrl() === "ProvinceOperator" + ? `${ROUTE_PROVINCEـHATCHINGS}/${item.key}` + : getRoleFromUrl() === "CityJahad" + ? `${ROUTE_CITY_JIHADـHATCHINGS}/${item.key}` + : "" + ); + }} + > + + + , + page === 1 ? i + 1 : i + perPage * (page - 1) + 1, + + + {item?.violation ? "پیگیری" : "عادی"} + + , + item?.licenceNumber, + item?.poultry?.breedingUniqueId, + item?.CertId, + // item?.commitmentType === "free" ? "آزاد" : "دولتی", + item?.poultry?.unitName || "-", + `${item?.poultry?.userprofile?.fullName ?? "-"} (${ + item?.poultry?.userprofile?.mobile ?? "-" + }) ${item?.violationReport ? "✉️" : ""}`, + item?.InteractTypeName ? ( + + {item?.InteractTypeName} + + ) : ( + "-" + ), + item?.PersonTypeName, + item?.UnionTypeName, + `${item?.poultry?.address?.city?.name ?? "-"}/${ + item?.poultry?.cityOperator + ? item?.poultry?.cityOperator + : "بدون تعاونی" + }`, + item?.vetFarm?.vetFarmMobile + ? `${item?.vetFarm?.vetFarmFullName} (${item?.vetFarm?.vetFarmMobile})` + : "-", + item.hall, + item.period, + formatTime(item?.createDate), + formatTime(item?.date), + item?.poultry?.killingAveAge?.toLocaleString(), + item?.predicateDate ? formatJustDate(item?.predicateDate) : "-", + item.chickenBreed, + item.age, + item?.quantity?.toLocaleString(), + item?.increaseQuantity?.toLocaleString(), + `${item.losses} (%${((item.losses * 100) / item.quantity).toFixed(0)})`, + + + , + `${item?.totalLosses?.toLocaleString()} (%${( + (item.totalLosses * 100) / + item.quantity + ).toFixed(0)})`, + `${item?.totalCommitmentQuantity?.toLocaleString()}`, + `${item?.totalFreeCommitmentQuantity?.toLocaleString()}`, + `${item?.governmentalQuantity?.toLocaleString()}`, + `${item?.governmentalKilledQuantity?.toLocaleString()}`, + `${item?.freeQuantity?.toLocaleString()}`, + `${item?.freeKilledQuantity?.toLocaleString()}`, + `${item?.outProvinceKilledQuantity?.toLocaleString()}`, + `${item?.outProvinceKilledWeight?.toLocaleString()}`, + `${item?.barDifferenceRequestQuantity?.toLocaleString()}`, + `${item?.barDifferenceRequestWeight?.toLocaleString()}`, + `${item?.killingInfo?.provinceKillRequests?.toLocaleString()}`, + `${item?.killingInfo?.provinceKillRequestsQuantity?.toLocaleString()}`, + `${item?.killingInfo?.provinceKillRequestsWeight?.toLocaleString()}`, + item?.killedQuantity?.toLocaleString() + + ` (%${((item?.killedQuantity * 100) / item.quantity).toFixed(0)})`, + item?.leftOver?.toLocaleString(), + `%${((item?.leftOver * 100) / item?.quantity).toFixed(0)}`, + // item?.totalCommitment?.toLocaleString(), + + `%${((item.totalLosses * 100) / item.quantity).toFixed(0)}`, + `%${((item?.killedQuantity * 100) / item.quantity).toFixed(0)}`, + `%${((item?.leftOver * 100) / item?.quantity).toFixed(0)}`, + `%${( + ((item?.killedQuantity + item?.totalLosses) * 100) / + item?.quantity + ).toFixed(0)}`, + + item?.samasatDischargePercentage + ? `%${item?.samasatDischargePercentage}` + : "-", + item?.totalCommitment?.toLocaleString(), + item?.governmentalKilledQuantity?.toLocaleString(), + item?.freeKilledQuantity?.toLocaleString(), + item?.totalAverageKilledWeight?.toLocaleString(), + item?.totalKilledWeight?.toLocaleString(), + item?.activeKill?.activeKill ? "دارد" : "ندارد", + item?.activeKill?.countOfRequest ? item.activeKill.countOfRequest : "-", + item?.killingInfo?.killHouseRequests?.toLocaleString(), + item?.killingInfo?.killHouseRequestsFirstQuantity?.toLocaleString(), + item?.killingInfo?.killHouseRequestsFirstWeight?.toLocaleString(), + item?.killingInfo?.barCompleteWithKillHouse?.toLocaleString(), + item?.killingInfo?.acceptedRealWightFinal?.toLocaleString(), + item?.chainKilledQuantity?.toLocaleString(), + item?.chainKilledWeight?.toLocaleString(), + item?.exportKilledQuantity?.toLocaleString(), + item?.exportKilledWeight?.toLocaleString(), + item?.killingInfo?.wareHouseBars?.toLocaleString(), + item?.killingInfo?.wareHouseBarsQuantity?.toLocaleString(), + item?.killingInfo?.wareHouseBarsWeight?.toLocaleString(), + item?.killingInfo?.wareHouseBarsWeightLose?.toFixed(2), + item.lastChange + ? `${item.lastChange.fullName} (${getFaUserRole( + item.lastChange.role + )}) در تاریخ ${formatTime(item.lastChange.date)}` + : "-", + item.latestHatchingChange + ? `${item.latestHatchingChange.fullName} (${getFaUserRole( + item.latestHatchingChange.role + )}) در تاریخ ${formatTime(item.latestHatchingChange.date)}` + : "-", + item?.violationReport ? ( + + { + dispatch( + OPEN_MODAL({ + title: "گزارش ", + content: ( + + {item?.violationImage?.map((option, index) => ( + + ))} + , + ], + ]} + /> + ), + }) + ); + }} + > + + + + ) : ( + "-" + ), + ]; + }); + + setTableData(d); + }, [data]); + + const handleSubmit = async (event) => { + event.preventDefault(); + dispatch(LOADING_START()); + dispatch( + cityGetHatchingInfoFull({ + age1: selectedAge1, + age2: selectedAge2, + tab: "unknown", + textValue: textValue, + }) + ); + try { + const response = await axios.get( + `poultry_hatching/?role=${getRoleFromUrl()}&age1=${ + selectedAge1 ? selectedAge1 : 0 + }&age2=${ + selectedAge2 ? selectedAge2 : 0 + }&search=filter&value=${textValue}&page=${1}&page_size=${perPage}&unknown=true` + ); + setData(response.data.results); + setTotalRows(response.data.count); + dispatch(LOADING_END()); + } catch (error) { + console.error("Error fetching data:", error); + } + }; + + const handleRemoveFilter = async (event) => { + event.preventDefault(); + setSelectedAge1(0); + setSelectedAge2(0); + dispatch(LOADING_START()); + setTextValue(""); + dispatch( + cityGetHatchingInfoFull({ + age1: 0, + age2: 0, + tab: "unknown", + textValue: textValue, + }) + ); + try { + const response = await axios.get( + `poultry_hatching?role=${getRoleFromUrl()}&page=${page}&page_size=${perPage}&search=filter&value=${textValue}&unknown=true` + ); + setData(response.data.results); + setTotalRows(response.data.count); + } catch (error) { + console.error("Error fetching data:", error); + } finally { + dispatch(LOADING_END()); + } + }; + + const [lastUpdateData, setLastUpdateData] = useState(); + + useEffect(() => { + async function fetchData() { + try { + const response = await axios.get(`last_update/?type=poultry_hatching`); + setLastUpdateData(response.data); + } catch (error) { + console.error("Error fetching data:", error); + } + } + + fetchData(); + }, []); + + const tableTitle = ( + +
    + + + { + setSelectedAge1(event.target.value); + }} + /> + + + { + setSelectedAge2(event.target.value); + }} + /> + + { + if (e.key === "Enter") { + handleSubmit(e); + } + }} + /> + + + + + + +
    + +
    + ); + const { hatchingInfoFull } = useSelector((state) => state.citySlice); + + useEffect(() => { + dispatch( + cityGetHatchingInfoFull({ + age1: selectedAge1, + age2: selectedAge2, + tab: "unknown", + textValue: textValue, + }) + ); + }, []); + + return ( + + + + + + {tableTitle} + + + + ); +}; diff --git a/src/features/city/components/city-hatchings-archive-operations/CityHatchingsArchiveOperations.js b/src/features/city/components/city-hatchings-archive-operations/CityHatchingsArchiveOperations.js new file mode 100644 index 0000000..512aa70 --- /dev/null +++ b/src/features/city/components/city-hatchings-archive-operations/CityHatchingsArchiveOperations.js @@ -0,0 +1,251 @@ +import { + IconButton, + Popover, + List, + ListItemButton, + ListItemIcon, + ListItemText, + Typography, +} from "@mui/material"; +import { useContext, useState } from "react"; +import { Grid } from "../../../../components/grid/Grid"; +import TuneIcon from "@mui/icons-material/Tune"; +import { useDispatch, useSelector } from "react-redux"; +import { hatchingUndoArchiveService } from "../../services/hatching-undo-archive"; +import { AppContext } from "../../../../contexts/AppContext"; +import axios from "axios"; +import { RiFileExcel2Fill } from "react-icons/ri"; +import { OPEN_MODAL } from "../../../../lib/redux/slices/appSlice"; +import { CitySubmitHatchingReport } from "../city-submit-hatching-report/CitySubmitHatchingReport"; +import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl"; +import InsertPageBreakIcon from "@mui/icons-material/InsertPageBreak"; +import { VetFarmSubmitFarmInfoLosses } from "../../../vet-farm/components/vet-farm-submit-farm-info-losses/VetFarmSubmitFarmInfoLosses"; +import AddIcon from "@mui/icons-material/Add"; +import KeyboardReturnIcon from "@mui/icons-material/KeyboardReturn"; +import SmsIcon from "@mui/icons-material/Sms"; +import { cityGetTicketDiffrentClearanceCode } from "../../services/city-get-ticket-different-clearance-code"; +export const CityHatchingsArchiveOperations = ({ + item, + updateArchive, + readOnly, +}) => { + const { userProfile } = useSelector((state) => state.userSlice); + const dispatch = useDispatch(); + const [popoverOpen, setPopoverOpen] = useState(false); + const [anchorEl, setAnchorEl] = useState(null); + const [openNotif] = useContext(AppContext); + const role = getRoleFromUrl(); + + const openPopover = (event) => { + setPopoverOpen(true); + setAnchorEl(event.currentTarget); + }; + + const closePopover = () => { + setPopoverOpen(false); + setAnchorEl(null); + }; + + const handleUndoArchive = () => { + closePopover(); + dispatch( + hatchingUndoArchiveService({ + key: item.key, + type: "return_archive", + }) + ).then((r) => { + if (r.payload.error) { + openNotif({ + vertical: "top", + horizontal: "center", + msg: r.payload.error, + severity: "error", + }); + } else { + updateArchive(1); + openNotif({ + vertical: "top", + horizontal: "center", + msg: "عملیات با موفقیت انجام شد.", + severity: "success", + }); + } + }); + }; + + const handleOpenReportModal = () => { + closePopover(); + dispatch( + OPEN_MODAL({ + title: "ثبت گزارش", + content: ( + + ), + }) + ); + }; + + const handleOpenLossesModal = () => { + closePopover(); + dispatch( + OPEN_MODAL({ + title: "ثبت تلفات پایان دوره", + content: ( + + ), + }) + ); + }; + + const handleExcelExport = () => { + closePopover(); + const url = `${axios.defaults.baseURL}process-for-each-hatching/?key=${item.key}`; + window.open(url, "_blank"); + }; + + const handleCreateTicket = () => { + closePopover(); + dispatch( + cityGetTicketDiffrentClearanceCode({ + licence_number: item?.licenceNumber, + mobile: userProfile?.mobile, + }) + ).then((r) => { + if (r.payload.error) { + openNotif({ + vertical: "top", + horizontal: "center", + msg: "مشکلی پیش آمده است!", + severity: "error", + }); + } else { + updateArchive(1); + openNotif({ + vertical: "top", + horizontal: "center", + msg: "عملیات با موفقیت انجام شد.", + severity: "success", + }); + } + }); + }; + + const provinceAndAdminRoles = [ + "ProvinceOperator", + "CityOperator", + "AdminX", + "SuperAdmin", + ]; + const vetRoles = ["VetFarm", "CityVet", "VetSupervisor"]; + + const options = [ + !readOnly && { + key: "undo", + label: "بازگشت جوجه ریزی", + color: "primary.main", + icon: , + action: handleUndoArchive, + }, + provinceAndAdminRoles.includes(role) && { + key: "report", + label: "ثبت گزارش", + color: "secondary.main", + icon: , + action: handleOpenReportModal, + }, + vetRoles.includes(role) && { + key: "losses", + label: "ثبت تلفات پایان دوره", + color: "error.main", + icon: , + action: handleOpenLossesModal, + }, + { + key: "excel", + label: "خروجی اکسل", + color: "success.main", + icon: , + action: handleExcelExport, + }, + { + key: "ticket", + label: "تیکت گزارش کشتار جوجه ریزی", + color: "error.main", + icon: , + action: handleCreateTicket, + }, + ].filter(Boolean); + + return ( + + + + + + + {options.map((option) => ( + { + if (option.disabled) { + return; + } + option.action(); + }} + disabled={Boolean(option.disabled)} + sx={{ + borderRadius: 1, + mb: 0.5, + color: option.disabled ? "text.disabled" : option.color, + "&:last-of-type": { + mb: 0, + }, + }} + > + + {option.icon} + + + {option.label} + + } + /> + + ))} + + + + ); +}; diff --git a/src/features/city/components/city-hatchings-archive/CityHatchingsArchive.js b/src/features/city/components/city-hatchings-archive/CityHatchingsArchive.js new file mode 100644 index 0000000..280c994 --- /dev/null +++ b/src/features/city/components/city-hatchings-archive/CityHatchingsArchive.js @@ -0,0 +1,585 @@ +import React, { useContext, useEffect, useState } from "react"; +import { + Button, + Checkbox, + IconButton, + TextField, + Tooltip, + Typography, +} from "@mui/material"; +import { DatePicker } from "@mui/x-date-pickers"; +import moment from "moment"; +import { useDispatch, useSelector } from "react-redux"; +import axios from "axios"; +import ResponsiveTable from "../../../../components/responsive-table/ResponsiveTable"; +import { Grid } from "../../../../components/grid/Grid"; +import { + LOADING_END, + LOADING_START, + OPEN_MODAL, +} from "../../../../lib/redux/slices/appSlice"; +import { getFaUserRole } from "../../../../utils/getFaUserRole"; +import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl"; +import { CityHatchingsArchiveOperations } from "../city-hatchings-archive-operations/CityHatchingsArchiveOperations"; +import { cityGetHatchingInfoFull } from "../../services/city-get-hatching-info-full"; +import { AppContext } from "../../../../contexts/AppContext"; +import { SimpleTable } from "../../../../components/simple-table/SimpleTable"; +import ShowImage from "../../../../components/show-image/ShowImage"; +import { formatJustDate, formatTime } from "../../../../utils/formatTime"; +import { RiFileExcel2Fill } from "react-icons/ri"; +import { RiSearchLine } from "react-icons/ri"; +import ToggleOffOutlinedIcon from "@mui/icons-material/ToggleOffOutlined"; +import ToggleOnIcon from "@mui/icons-material/ToggleOn"; +import { useNavigate } from "react-router-dom"; +import { + ROUTE_ADMINXـHATCHINGS, + ROUTE_CITY_POULTRYـHATCHINGS, + ROUTE_CITY_VISOR_STATICSـHATCHINGS_DETAILS, + ROUTE_PROVINCE_SUPERVISORـHATCHINGS, + ROUTE_PROVINCEـHATCHINGS, + ROUTE_SUPER_ADMINـHATCHINGS, + ROUTE_SUPPORTERـHATCHINGS, +} from "../../../../routes/routes"; +import RemoveRedEyeIcon from "@mui/icons-material/RemoveRedEye"; + +export const CityHatchingsArchive = ({ readOnly }) => { + const [, , selectedDate1, setSelectedDate1, selectedDate2, setSelectedDate2] = + useContext(AppContext); + const userKey = useSelector((state) => state.userSlice.userProfile.key); + const { hatchingInfoFull } = useSelector((state) => state.citySlice); + const navigate = useNavigate(); + const dispatch = useDispatch(); + useEffect(() => { + const currentDate = moment(new Date()).format("YYYY-MM-DD"); + setSelectedDate1(currentDate); + setSelectedDate2(currentDate); + }, []); + + const handleTextChange = (event) => { + setTextValue(event.target.value); + }; + + const [data, setData] = useState([]); + const [totalRows, setTotalRows] = useState(0); + const [perPage, setPerPage] = useState(10); + const [textValue, setTextValue] = useState(""); + const [page, setPage] = useState(1); + const [tableData, setTableData] = useState([]); + const [withDate, setWithDate] = useState(false); + + const fetchApiData = async (page) => { + dispatch(LOADING_START()); + const response = await axios.get( + `poultry_hatching/?archive=true&search=filter&value=${textValue}&role=${getRoleFromUrl()} + &key=${userKey}&page=${page}&page_size=${perPage}${ + withDate ? `&date1=${selectedDate1}&date2=${selectedDate2}` : `` + }` + ); + + dispatch(LOADING_END()); + setData(response.data.results); + setTotalRows(response.data.count); + }; + + const handlePageChange = (page) => { + fetchApiData(page); + setPage(page); + }; + + const handlePerRowsChange = (perRows) => { + setPerPage(perRows); + setPage(1); + }; + + const updateTable = () => { + fetchApiData(page !== 0 ? page : 1); + }; + + useEffect(() => { + const d = data?.map((item, i) => { + return [ + , + + { + navigate( + getRoleFromUrl() === "AdminX" + ? `${ROUTE_ADMINXـHATCHINGS}/${item.key}` + : getRoleFromUrl() === "Supporter" + ? `${ROUTE_SUPPORTERـHATCHINGS}/${item.key}` + : getRoleFromUrl() === "SuperAdmin" + ? `${ROUTE_SUPER_ADMINـHATCHINGS}/${item.key}` + : getRoleFromUrl() === "CityPoultry" + ? `${ROUTE_CITY_POULTRYـHATCHINGS}/${item.key}` + : getRoleFromUrl() === "ProvinceSupervisor" + ? `${ROUTE_PROVINCE_SUPERVISORـHATCHINGS}/${item.key}` + : getRoleFromUrl() === "province" + ? `${ROUTE_PROVINCEـHATCHINGS}/${item.key}` + : getRoleFromUrl() === "CityJahad" + ? `${ROUTE_CITY_VISOR_STATICSـHATCHINGS_DETAILS}/${item.key}` + : "" + ); + }} + > + + + , + page === 1 ? i + 1 : i + perPage * (page - 1) + 1, + + + {item?.violation ? "متخلف" : "عادی"} + + , + item?.licenceNumber, + item?.poultry?.breedingUniqueId, + item?.CertId || "-", + item?.poultry?.unitName || "-", + `${item?.poultry?.userprofile?.fullName ?? "-"} (${ + item?.poultry?.userprofile?.mobile ?? "-" + })`, + item?.InteractTypeName, + item?.PersonTypeName, + item?.UnionTypeName, + `${item?.poultry?.address?.city?.name ?? "-"}/${ + item?.poultry?.cityOperator + ? item?.poultry?.cityOperator + : "بدون تعاونی" + }`, + + item?.vetFarm?.vetFarmMobile + ? `${item?.vetFarm?.vetFarmFullName} (${item?.vetFarm?.vetFarmMobile})` + : "-", + item?.hall || "-", + item?.period || "-", + formatTime(item?.createDate), + formatTime(item?.date), + item?.poultry?.killingAveAge?.toLocaleString(), + item?.predicateDate ? formatJustDate(item?.predicateDate) : "-", + + item.chickenBreed || "-", + item?.age || "-", + item?.archiveDate ? formatTime(item?.archiveDate) : "-", + item.nowAge || "-", + item?.quantity?.toLocaleString(), + item?.increaseQuantity?.toLocaleString() || "-", + + `${item.losses} (%${((item.losses * 100) / item.quantity).toFixed(0)})`, + `${item?.directLosses?.toLocaleString()} (%${( + (item.directLosses * 100) / + item.quantity + ).toFixed(0)})`, + `${item?.totalLosses?.toLocaleString()} (%${( + (item.totalLosses * 100) / + item.quantity + ).toFixed(0)})`, + `${item?.totalCommitmentQuantity?.toLocaleString()}`, + `${item?.totalFreeCommitmentQuantity?.toLocaleString()}`, + `${item?.governmentalQuantity?.toLocaleString()}`, + `${item?.governmentalKilledQuantity?.toLocaleString()}`, + `${item?.freeQuantity?.toLocaleString()}`, + `${item?.freeKilledQuantity?.toLocaleString()}`, + `${item?.outProvinceKilledQuantity?.toLocaleString()}`, + `${item?.outProvinceKilledWeight?.toLocaleString()}`, + `${item?.barDifferenceRequestQuantity?.toLocaleString()}`, + `${item?.barDifferenceRequestWeight?.toLocaleString()}`, + `${item?.killingInfo?.provinceKillRequests?.toLocaleString()}`, + `${item?.killingInfo?.provinceKillRequestsQuantity?.toLocaleString()}`, + `${item?.killingInfo?.provinceKillRequestsWeight?.toLocaleString()}`, + item?.killedQuantity?.toLocaleString() + + ` (%${((item?.killedQuantity * 100) / item.quantity).toFixed(0)})`, + + `${item?.leftOver?.toLocaleString()} (%${( + (item.leftOver * 100) / + item.quantity + ).toFixed(0)})`, + `${item?.quantity?.toLocaleString()}`, + // item?.totalCommitment?.toLocaleString(), + + `%${((item.totalLosses * 100) / item.quantity).toFixed(0)}`, + `%${((item?.killedQuantity * 100) / item.quantity).toFixed(0)}`, + `%${( + ((item?.killedQuantity + item?.totalLosses) * 100) / + item?.quantity + ).toFixed(0)}`, + item?.samasatDischargePercentage + ? `%${item?.samasatDischargePercentage}` + : "-", + + item?.totalCommitment?.toLocaleString(), + item?.governmentalKilledQuantity?.toLocaleString(), + item?.freeKilledQuantity?.toLocaleString(), + item?.totalAverageKilledWeight?.toLocaleString(), + item?.totalKilledWeight?.toLocaleString(), + item?.activeKill?.activeKill ? "دارد" : "ندارد", + item?.activeKill?.countOfRequest ? item.activeKill.countOfRequest : "-", + item?.killingInfo?.killHouseRequests?.toLocaleString(), + item?.killingInfo?.killHouseRequestsFirstQuantity?.toLocaleString(), + item?.killingInfo?.killHouseRequestsFirstWeight?.toLocaleString(), + item?.killingInfo?.barCompleteWithKillHouse?.toLocaleString(), + item?.killingInfo?.acceptedRealWightFinal?.toLocaleString(), + item?.chainKilledQuantity?.toLocaleString(), + item?.chainKilledWeight?.toLocaleString(), + item?.exportKilledQuantity?.toLocaleString(), + item?.exportKilledWeight?.toLocaleString(), + item?.killingInfo?.wareHouseBars?.toLocaleString(), + item?.killingInfo?.wareHouseBarsQuantity?.toLocaleString(), + item?.killingInfo?.wareHouseBarsWeight?.toLocaleString(), + item?.killingInfo?.wareHouseBarsWeightLose?.toFixed(2), + + item.lastChange + ? `${item.lastChange.fullName} (${getFaUserRole( + item.lastChange.role + )}) در تاریخ ${formatTime(item.lastChange.date)}` + : "-", + item.latestHatchingChange + ? `${item.latestHatchingChange.fullName} (${getFaUserRole( + item.latestHatchingChange.role + )}) در تاریخ ${formatTime(item.latestHatchingChange.date)}` + : "-", + item?.violationReport ? ( + + ) : ( + "بدون گزارش" + ), + ]; + }); + + setTableData(d); + }, [data]); + + useEffect(() => { + fetchApiData(1); + }, [selectedDate1, selectedDate2, perPage, withDate]); + + useEffect(() => { + dispatch( + cityGetHatchingInfoFull( + withDate + ? { + tab: "archive", + date1: selectedDate1, + date2: selectedDate2, + textValue: textValue, + } + : { tab: "archive", textValue: textValue } + ) + ); + }, [dispatch, withDate, selectedDate1, selectedDate2]); + + const handleSubmit = async (event) => { + event.preventDefault(); + dispatch(LOADING_START()); + + try { + const response = await axios.get( + `poultry_hatching/?archive=true&search=filter&value=${textValue}&role=${getRoleFromUrl()}&key=${userKey}&page=${1}&page_size=${perPage}${ + withDate ? `&date1=${selectedDate1}&date2=${selectedDate2}` : `` + }` + ); + dispatch( + cityGetHatchingInfoFull( + withDate + ? { + tab: "archive", + date1: selectedDate1, + date2: selectedDate2, + textValue: textValue, + } + : { tab: "archive", textValue: textValue } + ) + ); + setData(response.data.results); + setTotalRows(response.data.count); + dispatch(LOADING_END()); + } catch (error) { + console.error("Error fetching data:", error); + } + }; + + return ( + + + + + + + + } + checkedIcon={} + checked={withDate} + onChange={() => setWithDate(!withDate)} + color="primary" + size="large" + /> + + ( + + )} + value={selectedDate1} + onChange={(e) => { + setSelectedDate1(moment(e).format("YYYY-MM-DD")); + }} + /> + + + ( + + )} + value={selectedDate2} + onChange={(e) => { + setSelectedDate2(moment(e).format("YYYY-MM-DD")); + }} + /> + + + +
    + + + +
    + + + + + +
    + + +
    + ); +}; diff --git a/src/features/city/components/city-hatchings-total/CityHatchingsTotal.js b/src/features/city/components/city-hatchings-total/CityHatchingsTotal.js new file mode 100644 index 0000000..925ea03 --- /dev/null +++ b/src/features/city/components/city-hatchings-total/CityHatchingsTotal.js @@ -0,0 +1,672 @@ +import { + Button, + IconButton, + TextField, + Tooltip, + Typography, +} from "@mui/material"; +import axios from "axios"; +import { useContext, useEffect, useState } from "react"; +import { RiFileExcel2Fill, RiSearchLine } from "react-icons/ri"; +import { Grid } from "../../../../components/grid/Grid"; +import { SPACING } from "../../../../data/spacing"; +import { formatTime, formatJustDate } from "../../../../utils/formatTime"; +import { getFaUserRole } from "../../../../utils/getFaUserRole"; +import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl"; +import { CityManageHatchingsOperations } from "../city-manage-hatchings-operations/CityManageHatchingsOperations"; +import { useDispatch, useSelector } from "react-redux"; +import { AppContext } from "../../../../contexts/AppContext"; +import { cityGetHatchingInfoFull } from "../../services/city-get-hatching-info-full"; +import ResponsiveTable from "../../../../components/responsive-table/ResponsiveTable"; +import { + LOADING_END, + LOADING_START, + OPEN_MODAL, +} from "../../../../lib/redux/slices/appSlice"; +import { SimpleTable } from "../../../../components/simple-table/SimpleTable"; +import ShowImage from "../../../../components/show-image/ShowImage"; +import RemoveRedEyeIcon from "@mui/icons-material/RemoveRedEye"; +import ArticleIcon from "@mui/icons-material/Article"; +import { + ROUTE_ADMINXـHATCHINGS, + ROUTE_CITY_JIHADـHATCHINGS, + ROUTE_CITY_POULTRYـHATCHINGS, + ROUTE_PROVINCE_SUPERVISORـHATCHINGS, + ROUTE_PROVINCEـHATCHINGS, + ROUTE_SUPER_ADMINـHATCHINGS, + ROUTE_SUPPORTERـHATCHINGS, +} from "../../../../routes/routes"; +import { useNavigate } from "react-router-dom"; + +export const CityHatchingsTotal = ({ readOnly }) => { + const dispatch = useDispatch(); + + const isReadOnly = readOnly || false; + const [selectedAge1, setSelectedAge1] = useState(0); + const [selectedAge2, setSelectedAge2] = useState(0); + const [data, setData] = useState([]); + const [totalRows, setTotalRows] = useState(0); + const [perPage, setPerPage] = useState(10); + const [textValue, setTextValue] = useState(""); + const [page, setPage] = useState(1); + const [tableData, setTableData] = useState([]); + const userKey = useSelector((state) => state.userSlice.userProfile.key); + const navigate = useNavigate(); + + const [openNotif] = useContext(AppContext); + + const handleTextChange = (event) => { + setTextValue(event.target.value); + }; + + const hatchingAdded = useSelector((state) => state.citySlice.hatchingAdded); + + useEffect(() => { + fetchApiData(1); + }, [hatchingAdded]); + + const fetchApiData = async (page) => { + dispatch(LOADING_START()); + const response = await axios.get( + `poultry_hatching?search=filter&value=${textValue}&role=${getRoleFromUrl()}&page=${page}&page_size=${perPage}&age1=${ + selectedAge1 ? selectedAge1 : 0 + }&age2=${selectedAge2 ? selectedAge2 : 0}&all_active_and_archive` + ); + dispatch(LOADING_END()); + setData(response.data.results); + setTotalRows(response.data.count); + }; + + const handlePageChange = (page) => { + fetchApiData(page); + setPage(page); + }; + + const handlePerRowsChange = (perRows) => { + setPerPage(perRows); + setPage(1); + }; + + useEffect(() => { + fetchApiData(1); + }, [dispatch, perPage]); + + const updateTable = () => { + fetchApiData(page !== 0 ? page : 1); + }; + + useEffect(() => { + const d = data?.map((item, i) => { + return [ + , + + { + navigate( + getRoleFromUrl() === "AdminX" + ? `${ROUTE_ADMINXـHATCHINGS}/${item.key}` + : getRoleFromUrl() === "Supporter" + ? `${ROUTE_SUPPORTERـHATCHINGS}/${item.key}` + : getRoleFromUrl() === "SuperAdmin" + ? `${ROUTE_SUPER_ADMINـHATCHINGS}/${item.key}` + : getRoleFromUrl() === "CityPoultry" + ? `${ROUTE_CITY_POULTRYـHATCHINGS}/${item.key}` + : getRoleFromUrl() === "ProvinceSupervisor" + ? `${ROUTE_PROVINCE_SUPERVISORـHATCHINGS}/${item.key}` + : getRoleFromUrl() === "ProvinceOperator" + ? `${ROUTE_PROVINCEـHATCHINGS}/${item.key}` + : getRoleFromUrl() === "CityJahad" + ? `${ROUTE_CITY_JIHADـHATCHINGS}/${item.key}` + : "" + ); + }} + > + + + , + page === 1 ? i + 1 : i + perPage * (page - 1) + 1, + + + {item?.violation ? "پیگیری" : "عادی"} + + , + item?.licenceNumber, + item?.poultry?.breedingUniqueId, + item?.CertId, + item?.poultry?.unitName || "-", + `${item?.poultry?.userprofile?.fullName ?? "-"} (${ + item?.poultry?.userprofile?.mobile ?? "-" + }) ${item?.violationReport ? "✉️" : ""}`, + item?.InteractTypeName ? ( + + {item?.InteractTypeName} + + ) : ( + "-" + ), + item?.PersonTypeName, + item?.UnionTypeName, + `${item?.poultry?.address?.city?.name ?? "-"}/${ + item?.poultry?.cityOperator + ? item?.poultry?.cityOperator + : "بدون تعاونی" + }`, + item?.vetFarm?.vetFarmMobile + ? `${item?.vetFarm?.vetFarmFullName} (${item?.vetFarm?.vetFarmMobile})` + : "-", + item.hall, + item.period, + formatTime(item?.createDate), + formatTime(item?.date), + item?.poultry?.killingAveAge?.toLocaleString(), + item?.predicateDate ? formatJustDate(item?.predicateDate) : "-", + item.chickenBreed, + item.age, + item?.quantity?.toLocaleString(), + item?.increaseQuantity?.toLocaleString(), + `${item.losses} (%${((item.losses * 100) / item.quantity).toFixed(0)})`, + + + , + `${item?.totalLosses?.toLocaleString()} (%${( + (item.totalLosses * 100) / + item.quantity + ).toFixed(0)})`, + `${item?.totalCommitmentQuantity?.toLocaleString()}`, + `${item?.totalFreeCommitmentQuantity?.toLocaleString()}`, + `${item?.governmentalQuantity?.toLocaleString()}`, + `${item?.governmentalKilledQuantity?.toLocaleString()}`, + `${item?.freeQuantity?.toLocaleString()}`, + `${item?.freeKilledQuantity?.toLocaleString()}`, + `${item?.outProvinceKilledQuantity?.toLocaleString()}`, + `${item?.outProvinceKilledWeight?.toLocaleString()}`, + `${item?.barDifferenceRequestQuantity?.toLocaleString()}`, + `${item?.barDifferenceRequestWeight?.toLocaleString()}`, + `${item?.killingInfo?.provinceKillRequests?.toLocaleString()}`, + `${item?.killingInfo?.provinceKillRequestsQuantity?.toLocaleString()}`, + `${item?.killingInfo?.provinceKillRequestsWeight?.toLocaleString()}`, + item?.killedQuantity?.toLocaleString() + + ` (%${((item?.killedQuantity * 100) / item.quantity).toFixed(0)})`, + item?.leftOver?.toLocaleString(), + `%${((item?.leftOver * 100) / item?.quantity).toFixed(0)}`, + + `%${((item.totalLosses * 100) / item.quantity).toFixed(0)}`, + `%${((item?.killedQuantity * 100) / item.quantity).toFixed(0)}`, + `%${((item?.leftOver * 100) / item?.quantity).toFixed(0)}`, + `%${( + ((item?.killedQuantity + item?.totalLosses) * 100) / + item?.quantity + ).toFixed(0)}`, + + item?.samasatDischargePercentage + ? `%${item?.samasatDischargePercentage}` + : "-", + item?.totalCommitment?.toLocaleString(), + item?.governmentalKilledQuantity?.toLocaleString(), + item?.freeKilledQuantity?.toLocaleString(), + item?.totalAverageKilledWeight?.toLocaleString(), + item?.totalKilledWeight?.toLocaleString(), + item?.activeKill?.activeKill ? "دارد" : "ندارد", + item?.activeKill?.countOfRequest ? item.activeKill.countOfRequest : "-", + item?.killingInfo?.killHouseRequests?.toLocaleString(), + item?.killingInfo?.killHouseRequestsFirstQuantity?.toLocaleString(), + item?.killingInfo?.killHouseRequestsFirstWeight?.toLocaleString(), + item?.killingInfo?.barCompleteWithKillHouse?.toLocaleString(), + item?.killingInfo?.acceptedRealWightFinal?.toLocaleString(), + item?.chainKilledQuantity?.toLocaleString(), + item?.chainKilledWeight?.toLocaleString(), + item?.exportKilledQuantity?.toLocaleString(), + item?.exportKilledWeight?.toLocaleString(), + item?.killingInfo?.wareHouseBars?.toLocaleString(), + item?.killingInfo?.wareHouseBarsQuantity?.toLocaleString(), + item?.killingInfo?.wareHouseBarsWeight?.toLocaleString(), + item?.killingInfo?.wareHouseBarsWeightLose?.toFixed(2), + item.lastChange + ? `${item.lastChange.fullName} (${getFaUserRole( + item.lastChange.role + )}) در تاریخ ${formatTime(item.lastChange.date)}` + : "-", + item.latestHatchingChange + ? `${item.latestHatchingChange.fullName} (${getFaUserRole( + item.latestHatchingChange.role + )}) در تاریخ ${formatTime(item.latestHatchingChange.date)}` + : "-", + item?.violationReport ? ( + + { + dispatch( + OPEN_MODAL({ + title: "گزارش ", + content: ( + + {item?.violationImage?.map((option, index) => ( + + ))} + , + ], + ]} + /> + ), + }) + ); + }} + > + + + + ) : ( + "-" + ), + ]; + }); + + setTableData(d); + }, [data]); + + const handleSubmit = async (event) => { + event.preventDefault(); + dispatch(LOADING_START()); + dispatch( + cityGetHatchingInfoFull({ + age1: selectedAge1, + age2: selectedAge2, + tab: "all", + textValue: textValue, + }) + ); + try { + const response = await axios.get( + `poultry_hatching/?role=${getRoleFromUrl()}&age1=${ + selectedAge1 ? selectedAge1 : 0 + }&age2=${ + selectedAge2 ? selectedAge2 : 0 + }&search=filter&value=${textValue}&page=${1}&page_size=${perPage}&all_active_and_archive` + ); + setData(response.data.results); + setTotalRows(response.data.count); + dispatch(LOADING_END()); + } catch (error) { + console.error("Error fetching data:", error); + } + }; + + const handleRemoveFilter = async (event) => { + event.preventDefault(); + setSelectedAge1(0); + setSelectedAge2(0); + dispatch(LOADING_START()); + setTextValue(""); + dispatch( + cityGetHatchingInfoFull({ + age1: 0, + age2: 0, + tab: "all", + textValue: textValue, + }) + ); + try { + const response = await axios.get( + `poultry_hatching?role=${getRoleFromUrl()}&page=${page}&page_size=${perPage}&all_active_and_archive&search=filter&value=${textValue}` + ); + setData(response.data.results); + setTotalRows(response.data.count); + } catch (error) { + console.error("Error fetching data:", error); + } finally { + dispatch(LOADING_END()); + } + }; + + const [lastUpdateData, setLastUpdateData] = useState(); + + useEffect(() => { + async function fetchData() { + try { + const response = await axios.get(`last_update/?type=poultry_hatching`); + setLastUpdateData(response.data); + } catch (error) { + console.error("Error fetching data:", error); + } + } + + fetchData(); + }, []); + + const tableTitle = ( + +
    + + + { + setSelectedAge1(event.target.value); + }} + /> + + + { + setSelectedAge2(event.target.value); + }} + /> + + { + if (e.key === "Enter") { + handleSubmit(e); + } + }} + /> + + + + + +
    + +
    + ); + const { hatchingInfoFull } = useSelector((state) => state.citySlice); + + useEffect(() => { + dispatch( + cityGetHatchingInfoFull({ + age1: selectedAge1, + age2: selectedAge2, + tab: "all", + textValue: textValue, + }) + ); + }, []); + + return ( + + + + + + {tableTitle} + + + + ); +}; diff --git a/src/features/city/components/city-hatchings/CityHatchings.js b/src/features/city/components/city-hatchings/CityHatchings.js new file mode 100644 index 0000000..a9a22ec --- /dev/null +++ b/src/features/city/components/city-hatchings/CityHatchings.js @@ -0,0 +1,681 @@ +import { + Button, + IconButton, + TextField, + Tooltip, + Typography, +} from "@mui/material"; +import axios from "axios"; +import { useContext, useEffect, useState } from "react"; +import { RiFileExcel2Fill, RiSearchLine } from "react-icons/ri"; +import { Grid } from "../../../../components/grid/Grid"; +import { SPACING } from "../../../../data/spacing"; +import { formatTime, formatJustDate } from "../../../../utils/formatTime"; +import { getFaUserRole } from "../../../../utils/getFaUserRole"; +import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl"; +import { CityManageHatchingsOperations } from "../city-manage-hatchings-operations/CityManageHatchingsOperations"; +import { useDispatch, useSelector } from "react-redux"; +import { AppContext } from "../../../../contexts/AppContext"; +import { cityGetHatchingInfoFull } from "../../services/city-get-hatching-info-full"; +import ResponsiveTable from "../../../../components/responsive-table/ResponsiveTable"; +import { + // DRAWER, + LOADING_END, + LOADING_START, + OPEN_MODAL, +} from "../../../../lib/redux/slices/appSlice"; +import { SimpleTable } from "../../../../components/simple-table/SimpleTable"; +import ShowImage from "../../../../components/show-image/ShowImage"; +import RemoveRedEyeIcon from "@mui/icons-material/RemoveRedEye"; +import { + ROUTE_ADMINXـHATCHINGS, + ROUTE_CITY_JIHADـHATCHINGS, + ROUTE_CITY_POULTRYـHATCHINGS, + ROUTE_PROVINCE_SUPERVISORـHATCHINGS, + ROUTE_PROVINCEـHATCHINGS, + ROUTE_SUPER_ADMINـHATCHINGS, + ROUTE_SUPPORTERـHATCHINGS, +} from "../../../../routes/routes"; +import { useNavigate } from "react-router-dom"; + +// import { CityHatchingShowTableDetail } from "../city-hatching-show-table-detail/CityHatchingShowTableDetail"; + +export const CityHatchings = ({ readOnly }) => { + const dispatch = useDispatch(); + + const isReadOnly = readOnly || false; + const [selectedAge1, setSelectedAge1] = useState(0); + const [selectedAge2, setSelectedAge2] = useState(0); + const [data, setData] = useState([]); + const [totalRows, setTotalRows] = useState(0); + const [perPage, setPerPage] = useState(10); + const [textValue, setTextValue] = useState(""); + const [page, setPage] = useState(1); + const [tableData, setTableData] = useState([]); + const userKey = useSelector((state) => state.userSlice.userProfile.key); + const navigate = useNavigate(); + + const [openNotif] = useContext(AppContext); + + const handleTextChange = (event) => { + setTextValue(event.target.value); + }; + + const hatchingAdded = useSelector((state) => state.citySlice.hatchingAdded); + + useEffect(() => { + fetchApiData(1); + }, [hatchingAdded]); + + const fetchApiData = async (page) => { + dispatch(LOADING_START()); + const response = await axios.get( + `poultry_hatching?search=filter&value=${textValue}&role=${getRoleFromUrl()}&page=${page}&page_size=${perPage}&age1=${ + selectedAge1 ? selectedAge1 : 0 + }&age2=${ + selectedAge2 ? selectedAge2 : 0 + }&search=filter&value=${textValue}` + ); + dispatch(LOADING_END()); + setData(response.data.results); + setTotalRows(response.data.count); + }; + + const handlePageChange = (page) => { + fetchApiData(page); + setPage(page); + }; + + const handlePerRowsChange = (perRows) => { + setPerPage(perRows); + setPage(1); + }; + + useEffect(() => { + fetchApiData(1); + }, [dispatch, perPage]); + + const updateTable = () => { + fetchApiData(page !== 0 ? page : 1); + }; + + // const killedNumber = (item) => { + // let killedNumber = ""; + // killedNumber = item.quantity - item.losses - item.leftOver; + // return killedNumber; + // }; + + useEffect(() => { + const d = data?.map((item, i) => { + return [ + , + + { + navigate( + getRoleFromUrl() === "AdminX" + ? `${ROUTE_ADMINXـHATCHINGS}/${item.key}` + : getRoleFromUrl() === "Supporter" + ? `${ROUTE_SUPPORTERـHATCHINGS}/${item.key}` + : getRoleFromUrl() === "SuperAdmin" + ? `${ROUTE_SUPER_ADMINـHATCHINGS}/${item.key}` + : getRoleFromUrl() === "CityPoultry" + ? `${ROUTE_CITY_POULTRYـHATCHINGS}/${item.key}` + : getRoleFromUrl() === "ProvinceSupervisor" + ? `${ROUTE_PROVINCE_SUPERVISORـHATCHINGS}/${item.key}` + : getRoleFromUrl() === "ProvinceOperator" + ? `${ROUTE_PROVINCEـHATCHINGS}/${item.key}` + : getRoleFromUrl() === "CityJahad" + ? `${ROUTE_CITY_JIHADـHATCHINGS}/${item.key}` + : "" + ); + }} + > + + + , + page === 1 ? i + 1 : i + perPage * (page - 1) + 1, + + + {item?.violation ? "پیگیری" : "عادی"} + + , + item?.licenceNumber, + item?.poultry?.breedingUniqueId, + item?.CertId, + // item?.commitmentType === "free" ? "آزاد" : "دولتی", + item?.poultry?.unitName || "-", + `${item?.poultry?.userprofile?.fullName ?? "-"} (${ + item?.poultry?.userprofile?.mobile ?? "-" + }) ${item?.violationReport ? "✉️" : ""}`, + item?.InteractTypeName ? ( + + {item?.InteractTypeName} + + ) : ( + "-" + ), + item?.PersonTypeName, + item?.UnionTypeName, + `${item?.poultry?.address?.city?.name ?? "-"}/${ + item?.poultry?.cityOperator + ? item?.poultry?.cityOperator + : "بدون تعاونی" + }`, + item?.vetFarm?.vetFarmMobile + ? `${item?.vetFarm?.vetFarmFullName} (${item?.vetFarm?.vetFarmMobile})` + : "-", + item.hall, + item.period, + formatTime(item?.createDate), + formatTime(item?.date), + item?.poultry?.killingAveAge?.toLocaleString(), + item?.predicateDate ? formatJustDate(item?.predicateDate) : "-", + item.chickenBreed, + item.age, + item?.quantity?.toLocaleString(), + item?.increaseQuantity?.toLocaleString(), + `${item.losses} (%${((item.losses * 100) / item.quantity).toFixed(0)})`, + + + , + `${item?.totalLosses?.toLocaleString()} (%${( + (item.totalLosses * 100) / + item.quantity + ).toFixed(0)})`, + `${item?.totalCommitmentQuantity?.toLocaleString()}`, + `${item?.totalFreeCommitmentQuantity?.toLocaleString()}`, + `${item?.governmentalQuantity?.toLocaleString()}`, + `${item?.governmentalKilledQuantity?.toLocaleString()}`, + `${item?.freeQuantity?.toLocaleString()}`, + `${item?.freeKilledQuantity?.toLocaleString()}`, + `${item?.outProvinceKilledQuantity?.toLocaleString()}`, + `${item?.outProvinceKilledWeight?.toLocaleString()}`, + `${item?.barDifferenceRequestQuantity?.toLocaleString()}`, + `${item?.barDifferenceRequestWeight?.toLocaleString()}`, + `${item?.killingInfo?.provinceKillRequests?.toLocaleString()}`, + `${item?.killingInfo?.provinceKillRequestsQuantity?.toLocaleString()}`, + `${item?.killingInfo?.provinceKillRequestsWeight?.toLocaleString()}`, + item?.killedQuantity?.toLocaleString() + + ` (%${((item?.killedQuantity * 100) / item.quantity).toFixed(0)})`, + item?.leftOver?.toLocaleString(), + `%${((item?.leftOver * 100) / item?.quantity).toFixed(0)}`, + // item?.totalCommitment?.toLocaleString(), + + `%${((item.totalLosses * 100) / item.quantity).toFixed(0)}`, + `%${((item?.killedQuantity * 100) / item.quantity).toFixed(0)}`, + `%${((item?.leftOver * 100) / item?.quantity).toFixed(0)}`, + `%${( + ((item?.killedQuantity + item?.totalLosses) * 100) / + item?.quantity + ).toFixed(0)}`, + + item?.samasatDischargePercentage + ? `%${item?.samasatDischargePercentage}` + : "-", + item?.totalCommitment?.toLocaleString(), + item?.governmentalKilledQuantity?.toLocaleString(), + item?.freeKilledQuantity?.toLocaleString(), + item?.totalAverageKilledWeight?.toLocaleString(), + item?.totalKilledWeight?.toLocaleString(), + item?.activeKill?.activeKill ? "دارد" : "ندارد", + item?.activeKill?.countOfRequest ? item.activeKill.countOfRequest : "-", + item?.killingInfo?.killHouseRequests?.toLocaleString(), + item?.killingInfo?.killHouseRequestsFirstQuantity?.toLocaleString(), + item?.killingInfo?.killHouseRequestsFirstWeight?.toLocaleString(), + item?.killingInfo?.barCompleteWithKillHouse?.toLocaleString(), + item?.killingInfo?.acceptedRealWightFinal?.toLocaleString(), + item?.chainKilledQuantity?.toLocaleString(), + item?.chainKilledWeight?.toLocaleString(), + item?.exportKilledQuantity?.toLocaleString(), + item?.exportKilledWeight?.toLocaleString(), + item?.killingInfo?.wareHouseBars?.toLocaleString(), + item?.killingInfo?.wareHouseBarsQuantity?.toLocaleString(), + item?.killingInfo?.wareHouseBarsWeight?.toLocaleString(), + item?.killingInfo?.wareHouseBarsWeightLose?.toFixed(2), + item.lastChange + ? `${item.lastChange.fullName} (${getFaUserRole( + item.lastChange.role + )}) در تاریخ ${formatTime(item.lastChange.date)}` + : "-", + item.latestHatchingChange + ? `${item.latestHatchingChange.fullName} (${getFaUserRole( + item.latestHatchingChange.role + )}) در تاریخ ${formatTime(item.latestHatchingChange.date)}` + : "-", + item?.violationReport ? ( + + ) : ( + "بدون گزارش" + ), + ]; + }); + + setTableData(d); + }, [data]); + + const handleSubmit = async (event) => { + event.preventDefault(); + dispatch(LOADING_START()); + dispatch( + cityGetHatchingInfoFull({ + age1: selectedAge1, + age2: selectedAge2, + tab: "active", + textValue: textValue, + }) + ); + try { + const response = await axios.get( + `poultry_hatching/?role=${getRoleFromUrl()}&age1=${ + selectedAge1 ? selectedAge1 : 0 + }&age2=${ + selectedAge2 ? selectedAge2 : 0 + }&search=filter&value=${textValue}&page=${1}&page_size=${perPage}` + ); + setData(response.data.results); + setTotalRows(response.data.count); + dispatch(LOADING_END()); + } catch (error) { + console.error("Error fetching data:", error); + } + }; + + const handleRemoveFilter = async (event) => { + event.preventDefault(); + setSelectedAge1(0); + setSelectedAge2(0); + dispatch(LOADING_START()); + setTextValue(""); + dispatch( + cityGetHatchingInfoFull({ + age1: 0, + age2: 0, + tab: "active", + textValue: textValue, + }) + ); + try { + const response = await axios.get( + `poultry_hatching?role=${getRoleFromUrl()}&page=${page}&page_size=${perPage}&search=filter&value=${textValue}` + ); + setData(response.data.results); + setTotalRows(response.data.count); + } catch (error) { + console.error("Error fetching data:", error); + } finally { + dispatch(LOADING_END()); + } + }; + + const [lastUpdateData, setLastUpdateData] = useState(); + + useEffect(() => { + async function fetchData() { + try { + const response = await axios.get(`last_update/?type=poultry_hatching`); + setLastUpdateData(response.data); + } catch (error) { + console.error("Error fetching data:", error); + } + } + + fetchData(); + }, []); + + const tableTitle = ( + +
    + + + { + setSelectedAge1(event.target.value); + }} + /> + + + { + setSelectedAge2(event.target.value); + }} + /> + + { + if (e.key === "Enter") { + handleSubmit(e); + } + }} + /> + + + + + +
    + +
    + ); + const { hatchingInfoFull } = useSelector((state) => state.citySlice); + + useEffect(() => { + dispatch( + cityGetHatchingInfoFull({ + age1: selectedAge1, + age2: selectedAge2, + tab: "active", + textValue: textValue, + }) + ); + }, []); + + return ( + + + + + + {tableTitle} + + + + ); +}; diff --git a/src/features/city/components/city-increase-hatching-operation/CityIncreaseHatchingOperation.js b/src/features/city/components/city-increase-hatching-operation/CityIncreaseHatchingOperation.js new file mode 100644 index 0000000..cd0a989 --- /dev/null +++ b/src/features/city/components/city-increase-hatching-operation/CityIncreaseHatchingOperation.js @@ -0,0 +1,119 @@ +import { Button, IconButton, Popover, Tooltip } from "@mui/material"; +import { useContext, useState } from "react"; +import { useDispatch } from "react-redux"; +import { Grid } from "../../../../components/grid/Grid"; +import TuneIcon from "@mui/icons-material/Tune"; +import DeleteIcon from "@mui/icons-material/Delete"; +import { CLOSE_MODAL, OPEN_MODAL } from "../../../../lib/redux/slices/appSlice"; +import { AppContext } from "../../../../contexts/AppContext"; +import { cityDeleteIncreaseHatchingeService } from "../../services/city-increase-hatching"; + +export const CityIncreaseHatchingOperation = ({ item, updateTable }) => { + const dispatch = useDispatch(); + const [anchorEl, setAnchorEl] = useState(null); + const [openNotif] = useContext(AppContext); + + const handleClick = (event) => { + setAnchorEl(event.currentTarget); + }; + + const handleClose = () => { + setAnchorEl(null); + }; + + const open = Boolean(anchorEl); + const id = open ? "popover" : undefined; + + return ( +
    + + + + + +
    + + + { + handleClose(); + dispatch( + OPEN_MODAL({ + title: "آیا مطمئن هستید؟", + content: ( + + + + + + + + + ), + }) + ); + }} + > + + + + +
    +
    +
    + ); +}; diff --git a/src/features/city/components/city-increase-hatching-submit-diffrence/CityIncreaseHatchingSubmitDiffrence.js b/src/features/city/components/city-increase-hatching-submit-diffrence/CityIncreaseHatchingSubmitDiffrence.js new file mode 100644 index 0000000..694b503 --- /dev/null +++ b/src/features/city/components/city-increase-hatching-submit-diffrence/CityIncreaseHatchingSubmitDiffrence.js @@ -0,0 +1,240 @@ +import React, { useContext, useEffect, useState } from "react"; +import { + Autocomplete, + Button, + Stack, + TextField, + Typography, + Paper, +} from "@mui/material"; +import { useFormik } from "formik"; +import { Yup } from "../../../../lib/yup/yup"; +import { useDispatch, useSelector } from "react-redux"; +import { AppContext } from "../../../../contexts/AppContext"; +import { DRAWER } from "../../../../lib/redux/slices/appSlice"; +import { slaughterGetPoultriesService } from "../../../slaughter-house/services/salughter-get-poultries"; +import { avicultureGetHatchingDataForIncreaseHatching } from "../../../aviculture/services/aviculture-get-hatching-data"; +import { + cityEditIncreaseHatchingeService, + cityIncreaseHatchingeService, +} from "../../services/city-increase-hatching"; +import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl"; + +export const CityIncreaseHatchingSubmitDiffrence = ({ + updateTable, + isEdit, + item, +}) => { + const [poultryData, setPoultryData] = useState([]); + const [selectedPoultryInfo, setSelectedPoultryInfo] = useState(null); + const [openNotif] = useContext(AppContext); + const dispatch = useDispatch(); + const { slaughterGetPoultries } = useSelector( + (state) => state.slaughterSlice + ); + + useEffect(() => { + dispatch(slaughterGetPoultriesService()); + }, []); + + const initialValues = { + poultry: item?.poultrykey || null, + hatching_key: item?.hatchingkey || null, + quantity: item?.quantity || null, + message: item?.message || null, + }; + + const validationSchema = Yup.object().shape({ + poultry: Yup.string().required("انتخاب مرغدار الزامی است"), + hatching_key: Yup.string().required("انتخاب محل پرورش الزامی است"), + quantity: Yup.number() + .typeError("عدد وارد کنید") + .required("حجم الزامی است"), + message: Yup.string() + .typeError("پر کردن این فیلد الزامی است") + .required("پیام الزامی است"), + }); + + const formik = useFormik({ + initialValues, + validationSchema, + }); + + useEffect(() => { + if (formik.values.poultry) { + dispatch( + avicultureGetHatchingDataForIncreaseHatching(formik.values.poultry, { + increase: true, + }) + ).then((res) => { + setPoultryData(res.payload.data || []); + }); + } + }, [formik.values.poultry]); + + return ( + + ({ + label: `${item.unitName} (${item.user?.fullname})(${item.user?.mobile})`, + value: item.key, + }))} + getOptionLabel={(option) => option.label} + onChange={(_, value) => { + formik.setFieldValue("poultry", value.value); + formik.setFieldValue("hatching_key", null); + }} + renderInput={(params) => ( + + )} + /> + + ({ + label: item?.poultry?.unitName || "-", + value: item?.key, + }))} + getOptionLabel={(option) => option.label} + onChange={(_, value) => { + formik.setFieldValue("hatching_key", value?.value); + const selected = poultryData.find((i) => i.key === value?.value); + setSelectedPoultryInfo(selected); + }} + renderInput={(params) => ( + + )} + /> + + {selectedPoultryInfo && ( + + + شماره مجوز جوجه ریزی:{" "} + {selectedPoultryInfo?.licenceNumber?.toLocaleString()} + + + شناسه یکتا مرغدار :{" "} + {selectedPoultryInfo?.poultry?.breedingUniqueId?.toLocaleString()} + + + حجم جوجه ریزی: + {selectedPoultryInfo?.quantity?.toLocaleString()}قطعه + + + + سن جوجه: {selectedPoultryInfo?.chickenAge?.toLocaleString()} روز + + + مانده در سالن: {selectedPoultryInfo?.leftOver?.toLocaleString()} + قطعه + + + حجم کشتار شده: + {selectedPoultryInfo?.killedQuantity?.toLocaleString()} قطعه + + + نژاد: {selectedPoultryInfo?.chickenBreed?.toLocaleString()} + + + + تلفات: {selectedPoultryInfo?.totalLosses?.toLocaleString("fa-IR")} + قطعه + + + )} + + + + + + + + ); +}; diff --git a/src/features/city/components/city-increase-hatching/CityIncreaseHatching.js b/src/features/city/components/city-increase-hatching/CityIncreaseHatching.js new file mode 100644 index 0000000..531eb66 --- /dev/null +++ b/src/features/city/components/city-increase-hatching/CityIncreaseHatching.js @@ -0,0 +1,182 @@ +import React, { useEffect, useState } from "react"; +import { Button, TextField } from "@mui/material"; +import { useDispatch } from "react-redux"; +import axios from "axios"; +import { RiSearchLine } from "react-icons/ri"; +import { + DRAWER, + LOADING_END, + LOADING_START, +} from "../../../../lib/redux/slices/appSlice"; +import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl"; +import { Grid } from "../../../../components/grid/Grid"; +import ResponsiveTable from "../../../../components/responsive-table/ResponsiveTable"; +import { formatTime } from "../../../../utils/formatTime"; + +import { CityIncreaseHatchingOperation } from "../city-increase-hatching-operation/CityIncreaseHatchingOperation"; +import { CityIncreaseHatchingSubmitDiffrence } from "../city-increase-hatching-submit-diffrence/CityIncreaseHatchingSubmitDiffrence"; + +export const CityIncreaseHatching = ({ state }) => { + const dispatch = useDispatch(); + const handleTextChange = (event) => { + setTextValue(event.target.value); + }; + + const [data, setData] = useState([]); + const [totalRows, setTotalRows] = useState(0); + const [perPage, setPerPage] = useState(10); + const [textValue, setTextValue] = useState(""); + const [page, setPage] = useState(1); + const [tableData, setTableData] = useState([]); + + const fetchApiData = async (page) => { + dispatch(LOADING_START()); + const response = await axios.get( + `hatching-increase-request/?search=filter&value=${textValue}&role=${getRoleFromUrl()}&page=${page}&page_size=${perPage}` + ); + dispatch(LOADING_END()); + setData(response.data.results); + setTotalRows(response.data.count); + }; + + const handlePageChange = (page) => { + fetchApiData(page); + setPage(page); + }; + + const handlePerRowsChange = (perRows) => { + setPerPage(perRows); + setPage(1); + }; + + const updateTable = () => { + fetchApiData(page !== 0 ? page : 1); + }; + + useEffect(() => { + const d = data?.map((item, i) => { + return [ + page === 1 ? i + 1 : i + perPage * (page - 1) + 1, + `${item?.hatching?.poultry?.unitName} (${item?.hatching?.poultry?.user?.mobile})`, + item?.hatching?.licenceNumber, + item?.hatching?.poultry?.breedingUniqueId, + item?.hatchingQuantity?.toLocaleString(), + item?.hatchingKillQuantity?.toLocaleString(), + item?.hatchingLosses?.toLocaleString(), + item?.hatchingLeftOver?.toLocaleString(), + item?.quantity?.toLocaleString(), + `${item?.registererName} (${item?.registererMobile})`, + formatTime(item?.date), + item?.message, + , + ]; + }); + + setTableData(d); + }, [data, state]); + + useEffect(() => { + fetchApiData(1); + }, [dispatch, perPage, state]); + + const handleSubmit = async (event) => { + event.preventDefault(); + dispatch(LOADING_START()); + + try { + const response = await axios.get( + `hatching-increase-request/?role=${getRoleFromUrl()}&search=filter&value=${textValue}&page=${1}&page_size=${perPage}` + ); + setData(response.data.results); + setTotalRows(response.data.count); + dispatch(LOADING_END()); + } catch (error) { + console.error("Error fetching data:", error); + } + }; + + return ( + + + {getRoleFromUrl() !== "KillHouse" && ( + + + + )} + +
    + + + +
    +
    + + +
    + ); +}; diff --git a/src/features/city/components/city-manage-hatching-renter/CityManageHatchingRenter.js b/src/features/city/components/city-manage-hatching-renter/CityManageHatchingRenter.js new file mode 100644 index 0000000..cb2e27b --- /dev/null +++ b/src/features/city/components/city-manage-hatching-renter/CityManageHatchingRenter.js @@ -0,0 +1,240 @@ +import React, { useContext, useState } from "react"; +import { + Grid, + TextField, + Button, + Paper, + IconButton, + Typography, + Box, +} from "@mui/material"; +import EditIcon from "@mui/icons-material/Edit"; +import DeleteIcon from "@mui/icons-material/Delete"; +import { useDispatch } from "react-redux"; +import { useFormik } from "formik"; +import * as Yup from "yup"; + +import { citySubmitManageHatchingRenterService } from "../../services/city-submit-manage-hatching-renter"; +import { AppContext } from "../../../../contexts/AppContext"; +import { + CLOSE_MODAL, + LOADING_END, + LOADING_START, +} from "../../../../lib/redux/slices/appSlice"; +import { cityHatchingDeleteRenterService } from "../../services/city-delete-manage-hatching-renter"; + +export const CityManageHatchingRenter = ({ item, updateTable, readOnly }) => { + const [editing, setEditing] = useState(false); + const dispatch = useDispatch(); + const [openNotif] = useContext(AppContext); + + const formik = useFormik({ + initialValues: { + fullName: item?.tenantFullname || "", + nationalCode: item?.tenantNationalCode || "", + phoneNumber: item?.tenantMobile || "", + city: item?.tenantCity || "", + }, + validationSchema: Yup.object({ + fullName: Yup.string().required("نام و نام خانوادگی الزامی است"), + nationalCode: Yup.string() + .required("کد ملی الزامی است") + .matches(/^[0-9]{10}$/, "کد ملی باید 10 رقم باشد"), + phoneNumber: Yup.string() + .required("شماره تلفن الزامی است") + .matches(/^[0-9]{11}$/, "شماره تلفن باید 11 رقم باشد"), + city: Yup.string().required("شهر الزامی است"), + }), + onSubmit: (values) => { + dispatch(LOADING_START()); + dispatch( + citySubmitManageHatchingRenterService({ + key: item?.key, + tenant_fullname: values.fullName, + tenant_national_code: values.nationalCode, + tenant_mobile: values.phoneNumber, + tenant_city: values.city, + has_tenant: true, + }) + ).then((r) => { + dispatch(CLOSE_MODAL()); + if (r.payload.error) { + openNotif({ + vertical: "top", + horizontal: "center", + msg: "مشکلی پیش آمده است!", + severity: "error", + }); + } else { + openNotif({ + vertical: "top", + horizontal: "center", + msg: "عملیات با موفقیت انجام شد.", + severity: "success", + }); + formik.resetForm(); + updateTable(); + setEditing(false); + } + dispatch(LOADING_END()); + }); + }, + enableReinitialize: true, + }); + + const handleEdit = () => { + setEditing(true); + }; + + const handleDelete = () => { + dispatch(LOADING_START()); + + dispatch( + cityHatchingDeleteRenterService({ delete_tenant: true, key: item?.key }) + ).then((r) => { + dispatch(CLOSE_MODAL()); + if (!r.payload.error) { + openNotif({ + vertical: "top", + horizontal: "center", + msg: "مستاجر با موفقیت حذف شد.", + severity: "success", + }); + formik.resetForm(); + updateTable(); + } + }); + }; + + const hasRenter = item?.hasTenant && item?.tenantFullname; + + return ( + + {hasRenter && !editing ? ( + + + +
    + + نام مستاجر: {item.tenantFullname} + + + کد ملی: {item.tenantNationalCode} + + + شماره تلفن: {item.tenantMobile} + + + شهر: {item.tenantCity} + +
    + {!readOnly && ( +
    + + + + + + +
    + )} +
    +
    +
    + ) : ( + + + + + + + + + + + + + + + + + + + {!readOnly && ( + + + + )} + + + + )} +
    + ); +}; diff --git a/src/features/city/components/city-manage-hatchings-operations/CityManageHatchingsOperations.js b/src/features/city/components/city-manage-hatchings-operations/CityManageHatchingsOperations.js new file mode 100644 index 0000000..aa04882 --- /dev/null +++ b/src/features/city/components/city-manage-hatchings-operations/CityManageHatchingsOperations.js @@ -0,0 +1,551 @@ +import { + IconButton, + Popover, + Tooltip, + List, + ListItemButton, + ListItemIcon, + ListItemText, +} from "@mui/material"; +import { useContext, useState } from "react"; +import { useDispatch, useSelector } from "react-redux"; +// import DeleteIcon from "@mui/icons-material/Delete"; +import ArchiveIcon from "@mui/icons-material/Archive"; +import AddIcon from "@mui/icons-material/Add"; +import { + DRAWER, + OPEN_MODAL, + LOADING_START, + LOADING_END, +} from "../../../../lib/redux/slices/appSlice"; +import { CityNewKillRequest } from "../city-new-kill-request/CityNewKillRequest"; +import { CityArchiveHatchingDrawer } from "../city-archive-hatching-drawer/CityArchiveHatchingDrawer"; +import TuneIcon from "@mui/icons-material/Tune"; +// import { CityEditHatchingQuantity } from "../city-edit-hatching-quantity/CityEditHatchingQuantity"; +import axios from "axios"; +import { RiFileExcel2Fill } from "react-icons/ri"; +import SmsIcon from "@mui/icons-material/Sms"; +import { CitySubmitHatchingReport } from "../city-submit-hatching-report/CitySubmitHatchingReport"; +import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl"; +// import { cityGetHatchingsByAge } from "../../services/city-get-hatchings-by-age"; +import EditIcon from "@mui/icons-material/Edit"; +import AssignmentReturnedIcon from "@mui/icons-material/AssignmentReturned"; +import KeyboardReturnIcon from "@mui/icons-material/KeyboardReturn"; +import { archiveHatchingService } from "../../services/archive-hatching"; +import { AppContext } from "../../../../contexts/AppContext"; +import { CitySubmitLooses } from "../city-submit-looses/CitySubmitLooses"; +import PlaylistRemoveIcon from "@mui/icons-material/PlaylistRemove"; +import { VetFarmSubmitFarmInfoLosses } from "../../../vet-farm/components/vet-farm-submit-farm-info-losses/VetFarmSubmitFarmInfoLosses"; +import InsertPageBreakIcon from "@mui/icons-material/InsertPageBreak"; +import { CityManageHatchingRenter } from "../city-manage-hatching-renter/CityManageHatchingRenter"; +import PersonAddAlt1Icon from "@mui/icons-material/PersonAddAlt1"; +import { cityGetTicketDiffrentClearanceCode } from "../../services/city-get-ticket-different-clearance-code"; +import PlayArrowIcon from "@mui/icons-material/PlayArrow"; +export const CityManageHatchingsOperations = ({ + item, + selectedAge1, + selectedAge2, + updateTable, + readOnly, +}) => { + const { userProfile } = useSelector((state) => state.userSlice); + const dispatch = useDispatch(); + const [anchorEl, setAnchorEl] = useState(null); + + const handleClick = (event) => { + setAnchorEl(event.currentTarget); + }; + + const handleClose = () => { + setAnchorEl(null); + }; + + const open = Boolean(anchorEl); + const id = open ? "popover" : undefined; + + const [openNotif] = useContext(AppContext); + + return ( +
    + + + + + + {!readOnly && ( + <> + + { + handleClose(); + dispatch( + DRAWER({ + right: !(window.innerWidth <= 600), + bottom: window.innerWidth <= 600, + title: "ثبت درخواست کشتار جدید", + content: ( + + ), + }) + ); + }} + > + + + + + + + + {item?.InteractTypeName === "مستاجر" && ( + + { + handleClose(); + dispatch( + OPEN_MODAL({ + title: "ثبت مستاجر ", + content: ( + + ), + }) + ); + }} + > + + + + + + + )} + + {(getRoleFromUrl() === "ProvinceOperator" || + getRoleFromUrl() === "CityOperator" || + getRoleFromUrl() === "CityPoultry" || + getRoleFromUrl() === "CityJahad" || + getRoleFromUrl() === "CityCommerce" || + getRoleFromUrl() === "AdminX" || + getRoleFromUrl() === "SuperAdmin") && ( + + { + handleClose(); + dispatch( + OPEN_MODAL({ + title: item?.violationReport + ? "ویرایش گزارش" + : "ثبت گزارش", + content: ( + + ), + }) + ); + }} + > + + + + + + + )} + + + { + handleClose(); + dispatch( + DRAWER({ + title: "انتقال به آرشیو", + right: !(window.innerWidth <= 600), + bottom: window.innerWidth <= 600, + content: ( + + ), + }) + ); + }} + > + + + + + + + + {(getRoleFromUrl() === "ProvinceOperator" || + getRoleFromUrl() === "CityOperator" || + getRoleFromUrl() === "AdminX" || + getRoleFromUrl() === "SuperAdmin") && ( + + { + handleClose(); + dispatch( + OPEN_MODAL({ + title: "ثبت تلفات", + content: ( + + ), + }) + ); + }} + > + + + + + + + )} + + + { + handleClose(); + dispatch( + archiveHatchingService({ + key: item?.key, + violation: item?.violation ? false : true, + }) + ).then((r) => { + if (r.payload.error) { + openNotif({ + vertical: "top", + horizontal: "center", + msg: "مشکلی پیش آمده است!", + severity: "error", + }); + } else { + updateTable(); + openNotif({ + vertical: "top", + horizontal: "center", + msg: "عملیات با موفقیت انجام شد.", + severity: "success", + }); + } + }); + }} + > + + {item?.violation ? ( + + ) : ( + + )} + + + + + + )} + + {(getRoleFromUrl() === "VetFarm" || + getRoleFromUrl() === "CityVet" || + getRoleFromUrl() === "VetSupervisor") && ( + + { + handleClose(); + dispatch( + OPEN_MODAL({ + title: "ثبت تلفات پایان دوره", + content: ( + + ), + }) + ); + }} + > + + + + + + + )} + + + + + + + + + + + + { + handleClose(); + dispatch( + cityGetTicketDiffrentClearanceCode({ + licence_number: item?.licenceNumber, + mobile: userProfile?.mobile, + }) + ).then((r) => { + if (r.payload.error) { + openNotif({ + vertical: "top", + horizontal: "center", + msg: "مشکلی پیش آمده است!", + severity: "error", + }); + } else { + updateTable(); + openNotif({ + vertical: "top", + horizontal: "center", + msg: "عملیات با موفقیت انجام شد.", + severity: "success", + }); + } + }); + }} + > + + + + + + + + +
    + ); +}; + +export const CityManageHatchingsArchiveActions = ({ + item, + selectedAge1, + selectedAge2, + updateTable, + readOnly, +}) => { + const dispatch = useDispatch(); + const [openNotif] = useContext(AppContext); + const [anchorEl, setAnchorEl] = useState(null); + + const open = Boolean(anchorEl); + const popoverId = open ? "archive-activate-popover" : undefined; + + const handleOpen = (event) => { + if (readOnly) { + return; + } + setAnchorEl(event.currentTarget); + }; + + const handleClose = () => { + setAnchorEl(null); + }; + + const handleArchiveClick = () => { + if (readOnly) { + return; + } + + handleClose(); + dispatch( + DRAWER({ + title: "انتقال به آرشیو", + right: !(window.innerWidth <= 600), + bottom: window.innerWidth <= 600, + content: ( + + ), + }) + ); + }; + + const handleActivateClick = async () => { + if (readOnly) { + return; + } + + dispatch(LOADING_START()); + try { + const { data } = await axios.put("poultry_hatching/0/", { + key: item?.key, + unknown: false, + }); + + dispatch(LOADING_END()); + + if (data?.error) { + openNotif({ + vertical: "top", + horizontal: "center", + msg: data?.error || "فعال‌سازی ناموفق بود.", + severity: "error", + }); + return; + } + + updateTable(); + handleClose(); + openNotif({ + vertical: "top", + horizontal: "center", + msg: "فعال‌سازی با موفقیت انجام شد.", + severity: "success", + }); + } catch (error) { + dispatch(LOADING_END()); + const message = + error?.response?.data?.result || + error?.response?.data?.error || + error?.message || + "فعال‌سازی ناموفق بود."; + openNotif({ + vertical: "top", + horizontal: "center", + msg: message, + severity: "error", + }); + handleClose(); + } + }; + + return ( + <> + + + + + + + + + + + + + + + + + + + + + ); +}; diff --git a/src/features/city/components/city-manage-hatchings/CityManageHatchings.js b/src/features/city/components/city-manage-hatchings/CityManageHatchings.js new file mode 100644 index 0000000..99a08ce --- /dev/null +++ b/src/features/city/components/city-manage-hatchings/CityManageHatchings.js @@ -0,0 +1,589 @@ +import { + Box, + Button, + // FormControl, + // InputLabel, + // MenuItem, + // Select, + // TextField, + Tab, + Tabs, + // Tooltip, + // Typography, +} from "@mui/material"; +import { useContext, useEffect, useState } from "react"; +import { useDispatch, useSelector } from "react-redux"; +// import { AdvancedTable } from "../../../../components/advanced-table/AdvancedTable"; +// import { ExcelUploadButton } from "../../../../components/excel-upload-button/ExcelUploadButton"; +import { Grid } from "../../../../components/grid/Grid"; +import { AppContext } from "../../../../contexts/AppContext"; +import { SPACING } from "../../../../data/spacing"; +import { OPEN_MODAL } from "../../../../lib/redux/slices/appSlice"; +// import { formatJustDate } from "../../../../utils/formatTime"; +// import { cityGetHatchings } from "../../services/city-get-hatchings"; +// import { getSlaughtersKillRequestService } from "../../services/get-slaughters-kill-request"; +// import { avicultureHatchingRequestsService } from "../../../aviculture/services/aviculture-hatching-requests"; +import { useFormik } from "formik"; +// import { RiFileExcel2Fill } from "react-icons/ri"; +// import axios from "axios"; +// import { DatePicker } from "@mui/x-date-pickers"; +// import moment from "moment/moment"; +// import { CityManageHatchingsOperations } from "../city-manage-hatchings-operations/CityManageHatchingsOperations"; +// import { cityGetHatchingsByAge } from "../../services/city-get-hatchings-by-age"; +// import { getFaUserRole } from "../../../../utils/getFaUserRole"; +import { CityArchiveOldHatchings } from "../city-archive-old-hatchings/CityArchvieOldHatchings"; +import { cityGetArchiveHatchingsService } from "../../services/city-get-archive-hatchings"; +import { CityHatchings } from "../city-hatchings/CityHatchings"; +import { CityHatchingsArchive } from "../city-hatchings-archive/CityHatchingsArchive"; +import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl"; +import { CityHatchingInfo } from "../city-hatching-info/CityHatchingInfo"; +import { CityUpdateHatching } from "../city-update-hatching/CityUpdateHatching"; +import { ProvinceBarDifference } from "../../../province/components/province-bar-difference/ProvinceBarDifference"; +import { TransportChickens } from "../transport-chickens/TransportChickens"; +import { CityHatchingsTotal } from "../city-hatchings-total/CityHatchingsTotal"; +import { CityHatchingUnassigned } from "../city-hatching-unassigned/CityHatchingUnassigned"; + +export const CityManageHatchings = () => { + const dispatch = useDispatch(); + const [, , selectedDate1, , selectedDate2] = useContext(AppContext); + // const [dataTable, setDataTable] = useState([]); + + // const [searchClick, setSearchClick] = useState(true); + + // const [dataTableHatchingArchive, setDataTableHatchingArchive] = useState([]); + // const [selectedAge1, setSelectedAge1] = useState(45); + // const [selectedAge2, setSelectedAge2] = useState(75); + + // const [filterType, setFilterType] = useState("سن"); + + const formik = useFormik({ + initialValues: { + numberInput: 0, + }, + }); + + const { hatchings, poultryRequestsTotalQuantity, cityGetArchiveHatchings } = + useSelector((state) => state.citySlice); + + // const { hourLimitKillRequest } = useSelector((state) => state.citySlice); + const { getSlaughtersKillRequest } = useSelector((state) => state.citySlice); + + // useEffect(() => { + // dispatch(getSlaughtersKillRequestService()); + // dispatch( + // avicultureHatchingRequestsService({ selectedDate1, selectedDate2 }) + // ); + // }, [selectedDate1, selectedDate2]); + + // useEffect(() => { + // const past50Day = new Date(); + // past50Day.setDate(past50Day.getDate() - 45); + // setSelectedDate1(moment(past50Day).format("YYYY-MM-DD")); + // return () => { + // const date = new Date(); + // setSelectedDate1(moment(date).format("YYYY-MM-DD")); + // }; + // }, []); + + // useEffect(() => { + // dispatch(cityGetHatchings({ selectedDate1, selectedDate2 })); + // }, [searchClick]); + + // useEffect(() => { + // if (searchClick) { + // dispatch(cityGetHatchings({ selectedDate1, selectedDate2 })); + // setSearchClick(false); + // } + // }, [selectedDate1]); + + useEffect(() => { + if (poultryRequestsTotalQuantity) { + formik.setFieldValue( + "numberInput", + poultryRequestsTotalQuantity?.quantity + ); + } + }, [poultryRequestsTotalQuantity]); + + useEffect(() => { + // const d = hatchings + // ?.filter((item) => item.allowHatching === "pending") + // ?.map((item, i) => { + // const killedNumber = item.quantity - item.losses - item.leftOver; + // const lastChange = + // item.lastChange && + // `${item.lastChange.fullName} (${getFaUserRole( + // item.lastChange.role + // )}) در تاریخ ${formatJustDate(item.lastChange.date)}`; + // return [ + // i + 1, + // item.poultry.unitName, + // `${item.poultry.userprofile.fullName} (${item.poultry.userprofile.mobile})`, + // `${item?.poultry?.address.city.name}/${ + // item?.poultry?.cityOperator + // ? item?.poultry?.cityOperator + // : "بدون تعاونی" + // }`, + // item?.vetFarm?.vetFarmMobile + // ? `${item?.vetFarm?.vetFarmFullName} (${item?.vetFarm?.vetFarmMobile})` + // : "-", + // item.hall, + // item.period, + // formatJustDate(item?.createDate), + // formatJustDate(item?.date), + // item.chickenBreed, + // item.age, + // item.quantity.toLocaleString(), + // `${item.losses} (%${((item.losses * 100) / item.quantity).toFixed( + // 0 + // )})`, + // killedNumber.toLocaleString() + + // ` (%${((killedNumber * 100) / item.quantity).toFixed(0)})`, + // `${item.leftOver.toLocaleString()} (%${( + // (item.leftOver * 100) / + // item.quantity + // ).toFixed(0)})`, + // item?.activeKill?.activeKill ? "دارد" : "ندارد", + // item?.activeKill?.countOfRequest + // ? item.activeKill.countOfRequest + // : "-", + // item.lastChange ? lastChange : "-", + // // , + // ]; + // }); + // setDataTable(d); + // const hatchingArchiveData = cityGetArchiveHatchings?.map((item, i) => { + // const killedNumber = item.quantity - item.losses - item.leftOver; + // return [ + // i + 1, + // item.poultry.unitName, + // item.poultry.userprofile.baseOrder, + // item.poultry.userprofile.mobile, + // item.hall, + // item.period, + // formatJustDate(item?.createDate), + // formatJustDate(item?.date), + // item.chickenBreed, + // item.age, + // item.quantity, + // `${item.losses} (%${((item.losses * 100) / item.quantity).toFixed(0)})`, + // killedNumber + + // ` (%${((killedNumber * 100) / item.quantity).toFixed(0)})`, + // `${item.leftOver} (%${((item.leftOver * 100) / item.quantity).toFixed( + // 0 + // )})`, + // ]; + // }); + // setDataTableHatchingArchive(hatchingArchiveData); + }, [hatchings, getSlaughtersKillRequest, cityGetArchiveHatchings]); + + const [view, setView] = useState("active"); + + const handleChange = (event, newValue) => { + setView(newValue); + }; + + // const selectAges = Array.from({ length: 75 }, (_, i) => i + 1); + + // useEffect(() => { + // dispatch(cityGetHatchingsByAge({ selectedAge1, selectedAge2 })); + // }, [selectedAge1, selectedAge2]); + + useEffect(() => { + dispatch(cityGetArchiveHatchingsService({ selectedDate1, selectedDate2 })); + }, [selectedDate1, selectedDate2]); + + return ( + + + + + + + + {getRoleFromUrl() !== "CityPoultry" && ( + + )} + {/* {(getRoleFromUrl() === "CityOperator" || + getRoleFromUrl() === "ProvinceOperator" || + getRoleFromUrl() === "AdminX" || + getRoleFromUrl() === "SuperAdmin") && ( + + )} */} + {/* {(getRoleFromUrl() === "AdminX" || + getRoleFromUrl() === "SuperAdmin") && ( + + )} */} + {/* {(getRoleFromUrl() === "AdminX" || + getRoleFromUrl() === "SuperAdmin") && ( + + )} */} + {/* {(getRoleFromUrl() === "AdminX" || + getRoleFromUrl() === "SuperAdmin") && ( + + )}*/} + + + {view === "hatchingUpdate" && } + {view === "transport-chickens" && } + {/* {view === "national-info" && } */} + {view === "active" && ( + + + {/* */} + {getRoleFromUrl() !== "CityOperator" && ( + + )} + + {/* */} + + )} + + + {view === "active" && } + {view === "info" && } + {view === "bar-difference" && } + {view === "total" && } + {view === "pending" && } + {/* {view === "active" && ( + + + + + + دوره های فعال جوجه ریزی + + + + + + {filterType === "سن" && ( + + + + فیلتر براساس سن: + + + + + + از سن + + + + + + + + تا سن + + + + + + )} + + + {filterType === "تاریخ" && ( + + + + فیلتر براساس تاریخ: + + + + ( + + )} + value={selectedDate1} + onChange={(e) => { + setSelectedDate1(moment(e).format("YYYY-MM-DD")); + }} + /> + + + ( + + )} + value={selectedDate2} + onChange={(e) => { + setSelectedDate2(moment(e).format("YYYY-MM-DD")); + }} + /> + + + + + + + + + + + )} + + } + data={dataTable} + columns={[ + "ردیف", + "نام فارم", + "مرغدار", + "شهر/تعاونی", + "دامپزشک فارم", + "سالن", + "دوره جوجه ریزی", + "تاریخ ثبت جوجه ریزی", + "تاریخ جوجه ریزی", + "نژاد", + "سن", + "تعداد جوجه ریزی", + "تلفات دوره", + "کشتار شده", + "مانده در سالن", + "کشتار فعال", + "تعداد درخواست کشتار", + "آخرین تغییر", + "عملیات", + ]} + /> + + )} */} + {view === "archive" && ( + + // + // + // + // بایگانی جوجه ریزی + // + // + // ( + // + // )} + // value={selectedDate1} + // onChange={(e) => { + // setSelectedDate1(moment(e).format("YYYY-MM-DD")); + // }} + // /> + // + // + // ( + // + // )} + // value={selectedDate2} + // onChange={(e) => { + // setSelectedDate2(moment(e).format("YYYY-MM-DD")); + // }} + // /> + // + // + // + // + // + // + // + // } + // data={dataTableHatchingArchive} + // columns={[ + // "ردیف", + // "نام فارم", + // "کدکاربری", + // "تلفن", + // "سالن", + // "دوره جوجه ریزی", + // "تاریخ ثبت جوجه ریزی", + // "تاریخ جوجه ریزی", + // "نژاد", + // "سن", + // "تعداد جوجه ریزی", + // "تلفات دوره", + // "کشتار شده", + // "مانده در سالن", + // ]} + // /> + // + )} + + + + ); +}; diff --git a/src/features/city/components/city-new-hatching-request/CityNewHatchingRequest.js b/src/features/city/components/city-new-hatching-request/CityNewHatchingRequest.js new file mode 100644 index 0000000..5212ab8 --- /dev/null +++ b/src/features/city/components/city-new-hatching-request/CityNewHatchingRequest.js @@ -0,0 +1,326 @@ +import { SPACING } from "../../../../data/spacing"; +import { Grid } from "../../../../components/grid/Grid"; +import { + Autocomplete, + Button, + FormControl, + FormHelperText, + IconButton, + InputLabel, + MenuItem, + Select, + TextField, + Typography, +} from "@mui/material"; +import { useFormik } from "formik"; +import { Yup } from "../../../../lib/yup/yup"; +import { useEffect } from "react"; +import moment from "moment/moment"; +import { DatePicker } from "@mui/x-date-pickers"; +import { useDispatch } from "react-redux"; +import { useState } from "react"; +import { + DRAWER, + LOADING_END, + LOADING_START, +} from "../../../../lib/redux/slices/appSlice"; +import SearchIcon from "@mui/icons-material/Search"; + +import { useContext } from "react"; +import { AppContext } from "../../../../contexts/AppContext"; +import { NumberInput } from "../../../../components/number-format-custom/NumberFormatCustom"; +import { cityGetPoultryData } from "../../services/city-get-poultry-data"; +import { avicultureNewHatching } from "../../../aviculture/services/aviculture-new-hatching"; +import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl"; +import { cityGetHatchings } from "../../services/city-get-hatchings"; +import { reloadHatchings } from "../../../../lib/redux/slices/citySlice"; + +export const CityNewHatchingRequest = () => { + const dispatch = useDispatch(); + const [poultryKey, setPolutryKey] = useState(""); + const [polutryData, setpolutryData] = useState(""); + const [enableHall, setEnableHall] = useState(true); + const [numberOfhalls, setNumberOfHalls] = useState(1); + const [numberOfhallSelected, setNumberOfHallSelected] = useState(null); + const [openNotif, , selectedDate1, , selectedDate2] = useContext(AppContext); + + const formik2 = useFormik({ + initialValues: { + userInfoCheck: "", + }, + validationSchema: Yup.object({ + userInfoCheck: Yup.number() + .required("این فیلد اجباری است!") + .typeError("لطفا فیلد را به درستی وارد کنید!"), + }), + }); + + const formik = useFormik({ + initialValues: { + quantity: "", + hatchingDate: moment(Date()).format("YYYY-MM-DD hh:mm:ss"), + race: "آرین", + }, + validationSchema: Yup.object({ + quantity: Yup.number() + .required("این فیلد اجباری است!") + .typeError("لطفا عدد وارد کنید!"), + }), + }); + + useEffect(() => { + formik.validateForm(); + formik2.validateForm(); + }, []); + + useEffect(() => { + if (poultryKey) { + if (numberOfhalls === 0) { + openNotif({ + vertical: "top", + horizontal: "center", + msg: "ابتدا برای این مرغداری جوجه ریزی ثبت کنید.", + severity: "error", + }); + dispatch(DRAWER({ right: false, bottom: false, content: null })); + } else { + setEnableHall(false); + } + } + }, [poultryKey]); + + return ( + <> + {!polutryData ? ( + + جستجو کاربر + + + + { + dispatch(LOADING_START()); + dispatch(cityGetPoultryData(formik2.values.userInfoCheck)).then( + (r) => { + dispatch(LOADING_END()); + if (r.error) { + openNotif({ + vertical: "top", + horizontal: "center", + msg: "کاربر یافت نشد", + severity: "error", + }); + } + setpolutryData(r.payload.data); + } + ); + }} + > + + + + شماره موبایل با صفر شروع می‌شود! + + ) : ( + + + + ({ + id: i.key, + label: i.unitName, + halls: i.numberOfHalls, + })) + : [] + } + onChange={(event, value) => { + setPolutryKey(value.id); + setNumberOfHalls(value.halls); + }} + renderInput={(params) => ( + + )} + /> + + + ({ + label: "سالن شماره " + (i + 1), + id: i, + }))} + onChange={(event, value) => { + setNumberOfHallSelected(value.id + 1); + }} + renderInput={(params) => ( + + )} + /> + + + } + value={formik.values.hatchingDate} + error={ + formik.touched.hatchingDate + ? Boolean(formik.errors.hatchingDate) + : null + } + onChange={(e) => { + formik.setFieldValue( + "hatchingDate", + moment(e).format("YYYY-MM-DD hh:mm:ss") + ); + }} + onBlur={formik.handleBlur} + helperText={ + formik.touched.hatchingDate && + Boolean(formik.errors.hatchingDate) + ? formik.errors.hatchingDate + : null + } + /> + + نژاد مرغ + + + {formik.touched.race && Boolean(formik.errors.race) + ? formik.errors.race + : null} + + + + + + + + + )} + + ); +}; diff --git a/src/features/city/components/city-new-hatching/CityHatching.js b/src/features/city/components/city-new-hatching/CityHatching.js new file mode 100644 index 0000000..061ce6b --- /dev/null +++ b/src/features/city/components/city-new-hatching/CityHatching.js @@ -0,0 +1,77 @@ +import { Tab, Tabs } from "@mui/material"; +import { useState } from "react"; +import { Grid } from "../../../../components/grid/Grid"; +import { SPACING } from "../../../../data/spacing"; +import { ProvinceManagePoultryRequest } from "../../../province/components/province-manage-poultry-request/ProvinceManagePoultryRequest"; +import { ProvinceManageSlaughterRequest } from "../../../province/components/province-manage-slaughter-request/ProvinceManageSlaughterRequest"; +import { CityManageHatchings } from "../city-manage-hatchings/CityManageHatchings"; +import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl"; + +export const CityHatching = () => { + // const handleSubmit = (event) => { + // event.preventDefault(); + // // Handle form submission here + // dispatch( + // updatePoultryRequestsTotalQuantityService({ + // key: poultryRequestsTotalQuantity?.key, + // input_quantity: Number(formik.values.numberInput), + // }) + // ).then((r) => { + // openNotif({ + // vertical: "top", + // horizontal: "center", + // msg: "عملیات با موفقیت انجام شد.", + // severity: "success", + // }); + // }); + // }; + + const [activeTab, setActiveTab] = useState(0); + + const handleTabChange = (event, newValue) => { + setActiveTab(newValue); + }; + + return ( + + <> + + + {getRoleFromUrl() !== "CityPoultry" && ( + + )} + {/* */} + + + + + + + + + {getRoleFromUrl() !== "CityPoultry" ? ( + + ) : ( + + )} + + + + ); +}; + +function TabPanel(props) { + const { children, value, index } = props; + + return ( + + ); +} diff --git a/src/features/city/components/city-new-kill-request/CityNewKillRequest.js b/src/features/city/components/city-new-kill-request/CityNewKillRequest.js new file mode 100644 index 0000000..941c366 --- /dev/null +++ b/src/features/city/components/city-new-kill-request/CityNewKillRequest.js @@ -0,0 +1,2420 @@ +import { + Autocomplete, + Button, + Checkbox, + CircularProgress, + Divider, + FormControl, + FormControlLabel, + FormHelperText, + FormLabel, + IconButton, + InputAdornment, + InputLabel, + ListItem, + ListItemIcon, + ListItemText, + MenuItem, + Radio, + RadioGroup, + Select, + TextField, + Tooltip, + Typography, +} from "@mui/material"; +import SearchIcon from "@mui/icons-material/Search"; +import { useEffect } from "react"; +import { DatePicker } from "@mui/x-date-pickers"; +import { useDispatch, useSelector } from "react-redux"; +import { useFormik } from "formik"; +import moment from "moment"; +import { useState } from "react"; +import DeleteIcon from "@mui/icons-material/Delete"; +import { useContext } from "react"; +import AddIcon from "@mui/icons-material/Add"; +import DoneIcon from "@mui/icons-material/Done"; + +import { + CLOSE_MODAL, + DRAWER, + LOADING_END, + LOADING_START, + OPEN_MODAL, +} from "../../../../lib/redux/slices/appSlice"; +import { avicultureGetChickenPrice } from "../../../aviculture/services/aviculture-get-chicken-price"; +import { avicultureGetSlaughters } from "../../../aviculture/services/aviculture-get-slaughters"; +import { avicultureGetUnions } from "../../../aviculture/services/aviculture-get-unions"; +import { SPACING } from "../../../../data/spacing"; +import { Grid } from "../../../../components/grid/Grid"; +import { Yup } from "../../../../lib/yup/yup"; +import { AppContext } from "../../../../contexts/AppContext"; +import { avicultureGetHatchingData } from "../../../aviculture/services/aviculture-get-hatching-data"; +import { NumberInput } from "../../../../components/number-format-custom/NumberFormatCustom"; +import useUserProfile from "../../../authentication/hooks/useUserProfile"; +import { avicultureNewRequest } from "../../../aviculture/services/aviculture-new-request"; +import { DialogAlert } from "../../../../components/dialog-alert/DialogAlert"; +import { cityGetPoultryData } from "../../services/city-get-poultry-data"; +import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl"; +import { cityGetBuyer } from "../../services/ciry-get-buyer"; +import { avicultureGetRequests } from "../../../aviculture/services/aviculture-requests"; +import { SimpleTable } from "../../../../components/simple-table/SimpleTable"; +import { avicultureHatchingRequestsService } from "../../../aviculture/services/aviculture-hatching-requests"; +import { cityGetHatchingsByAge } from "../../services/city-get-hatchings-by-age"; +import { avicultureGetPoultry } from "../../../aviculture/services/aviculture-get-poultry"; +import { cityGetPoultriesService } from "../../services/city-get-poultries"; +import { avicultureGetDirectBuys } from "../../../aviculture/services/aviculture-get-direct-buys"; +import { formatJustDate } from "../../../../utils/formatTime"; +import { provinceGetSellForFreezingStatus } from "../../../province/services/province-get-sell-for-freezing-status"; +import { getApprovedPriceState } from "../../../province/services/get-approved-price-state"; +import { provincePolicyGetExportAllowStatus } from "../../../province/services/province-policy-get-export-allow-state"; +import { provincePolicyValidatePoultryWithSmsStatusService } from "../../../province/services/province-policy-validate-poultry-wth-sms-service"; +import { isValidIndexWeight } from "../../../../utils/isValidIndexWeight"; +import { provincePolicyGetWeightRange } from "../../../province/services/province-policy-get-weight-range"; +import { provincePolicyGetMarketDailyLimitation } from "../../../province/services/province-policy-market-daily-limitation"; +import { LabelField } from "../../../../components/label-field/LabelField"; +// import { SelectCheck } from "../../../../components/select-check/SelectCheck"; + +export const CityNewKillRequest = ({ + userCheck, + selectedAge1, + selectedAge2, + isAviculture, + updateTable, +}) => { + const [openNotif] = useContext(AppContext); + const [hatchingKey, sethatchingKey] = useState(""); + const [hatchingData, setHatchingData] = useState(""); + const [hatchingSelected, setHatchingSelected] = useState(""); + const [poultryData, setPoultryData] = useState(""); + const [poultryKey, setPolutryKey] = useState(""); + const [quantity, setQuantity] = useState(""); + const [losses, setlosses] = useState(""); + const [leftOvers, setLeftOvers] = useState(""); + const [isUnion] = useState(false); + const [isStockMarket, setIsStockMarket] = useState(false); + const [pricingKey, setPriceKey] = useState(); + const [chickenBreed, setChickenBreed] = useState(""); + const [chickenCanRequest, setChickenCanRequest] = useState(""); + const [freezing, setFreezing] = useState(false); + const [tradePanel, setTradePanel] = useState(false); + const [toExport, setToExport] = useState(false); + const [marketLimitationData, setMarketLimitationData] = useState(null); + // const [slaughterHousesListForSelect, setSlaughterHousesListForSelect] = + // useState([]); + const [buyerInfo, setBuyerInfo] = useState(); + const [, , selectedDate1, , selectedDate2] = useContext(AppContext); + const [loading, setLoading] = useState(false); + const [, userProfile] = useUserProfile(); + const [autoLoading, setAutoLoading] = useState(false); + const { weightRange } = useSelector((state) => state.provinceSlice); + + const [slaughterHousesListForSelect, setSlaughterHousesListForSelect] = + useState([]); + + const { avicultureSlaughters } = useSelector( + (state) => state.avicultureSlice + ); + const { cityGetPoultries } = useSelector((state) => state.citySlice); + + const [submitStatus, SetSubmitStatus] = useState(false); + const fetchData = () => { + dispatch(provincePolicyValidatePoultryWithSmsStatusService()).then((r) => { + SetSubmitStatus(r.payload.data.poultryStatus); + }); + }; + + useEffect(() => { + setSlaughterHousesListForSelect( + avicultureSlaughters?.map((item) => { + let name = ""; + if (item.killer) { + name = `کشتارکن ${item?.name}`; + } else { + name = `کشتارگاه ${item?.name}`; + } + return { + label: `${name} / ${item?.quantitySum?.toLocaleString()} قطعه`, + value: `${item?.name} (${item?.fullname})`, + quantity: item?.quantitySum, + killhouseKey: item?.killReqKey, + item: item, + }; + }) + ); + }, [avicultureSlaughters]); + + const [data, setData] = useState(); + const [approvedPrice, setApprovedPrice] = useState(); + + useEffect(() => { + dispatch(getApprovedPriceState()).then((r) => { + setData(r.payload.data); + if (r.payload.data?.approved === false) { + formik.setFieldValue("avicultureSellType", "freePrice"); + } + // Check if approved is true but all price/weight fields are zero + if ( + r.payload.data?.approved === true && + r.payload.data?.lowestPrice === 0 && + r.payload.data?.highestPrice === 0 && + r.payload.data?.lowestWeight === 0 && + r.payload.data?.highestWeight === 0 + ) { + formik.setFieldValue("avicultureSellType", "goverment"); + } + }); + dispatch(provincePolicyGetWeightRange()); + }, []); + + useEffect(() => { + if (userCheck) { + setAutoLoading(true); + dispatch(cityGetPoultryData(userCheck)).then((r) => { + setPoultryData(r.payload.data); + setAutoLoading(false); + }); + } + }, [userCheck]); + + useEffect(() => { + if (isAviculture) { + dispatch(LOADING_START()); + dispatch(avicultureGetPoultry()).then((r) => { + setPoultryData(r.payload.data); + dispatch(LOADING_END()); + }); + } + fetchData(); + }, []); + + const inputArr = [ + { + type: "text", + id: 1, + value: "", + }, + ]; + + const inputArrPrices = [ + { + type: "text", + id: 1, + value: "", + }, + ]; + const [arr, setArr] = useState(inputArr); + const [arrPrices, setArrPrices] = useState(inputArrPrices); + + const dispatch = useDispatch(); + + const { avicultureChickenPrice } = useSelector( + (state) => state.avicultureSlice + ); + + const [value] = useState("insideProvince"); + + // const handleChangeRadioButton = (event) => { + // setValue(event.target.value); + // }; + + // useEffect(() => { + // setSlaughterHousesListForSelect( + // avicultureSlaughters?.map((item) => { + // return { + // label: `${item.name} (${item.killHouseOperator?.user?.fullname})`, + // value: `${item.name} (${item.killHouseOperator?.user?.fullname})`, + // }; + // }) + // ); + // }, [avicultureSlaughters]); + + useEffect(() => { + dispatch(avicultureGetChickenPrice()); + }, []); + + const [unions, setUnions] = useState(); + const [unionSelected, setUnionSelected] = useState(); + + const [selectedKillhouse, setSelectedKillhouse] = useState(null); + + useEffect(() => { + if (poultryData) { + dispatch( + avicultureGetUnions({ + breeding_uniq_id: poultryData[0]?.breedingUniqueId, + }) + ).then((r) => { + setUnionSelected(r.payload.data[0]?.key); + setUnions(r.payload.data); + }); + } + }, [poultryData]); + + useEffect(() => { + setLoading(true); + dispatch(cityGetPoultriesService()).then(() => { + setLoading(false); + }); + }, []); + + const addInput = () => { + if (arr.length < 3) { + setArr((prevState) => { + return [ + ...prevState, + { + type: "text", + value: "", + }, + ]; + }); + + setArrPrices((prevState) => { + return [ + ...prevState, + { + type: "text", + value: "", + }, + ]; + }); + } + }; + + const removeInput = () => { + const number = arr.length - 1; + + if (number !== 0) { + const filteredArrayPrice = arr?.filter((object, i) => i !== number); + const filteredArrayTime = arrPrices?.filter((object, i) => i !== number); + + setArr(filteredArrayPrice); + setArrPrices(filteredArrayTime); + } + + // setArr((s) => { + // return s.splice(arr.findIndex((item) => item.id === number, 1)); + // }); + + // setArrPrices((s) => { + // return s.splice(arr.findIndex((item) => item.id === number, 1)); + // }); + }; + + const handleChange = (e) => { + e.preventDefault(); + + const index = e.target.id; + setArr((s) => { + const newArr = s.slice(); + newArr[index].value = e.target.value; + + return newArr; + }); + }; + + const handleChangeTime = (e) => { + e.preventDefault(); + + const index = e.target.id; + + setArrPrices((s) => { + const newArrPrice = s.slice(); + newArrPrice[index].value = e.target.dataset.value; + + return newArrPrice; + }); + }; + + useEffect(() => { + if (avicultureChickenPrice) { + setPriceKey(avicultureChickenPrice?.key); + } + }, [avicultureChickenPrice]); + + const formik = useFormik({ + initialValues: { + noChicken: "", + sellType: { + cash: true, + haveTime: false, + }, + price1: "", + price2: "", + price3: "", + slaughterDate: moment(Date()).format("YYYY-MM-DD"), + period1: "4", + period2: "4", + period3: "4", + weight: "", + losses: "0", + isUnion, + isStockMarket, + isAccepted: getRoleFromUrl() === "Poultry" ? false : true, + selectedSlaughters: [], + financialOperation: "outside-system", + avicultureSellType: "goverment", + poultryPrice: "", + }, + validationSchema: Yup.object({ + noChicken: Yup.string() + .required("این فیلد اجباری است!") + .typeError("لطفا عدد وارد کنید!") + .min(0, "تعداد وارد شده از حداقل ممکن کمتر است") + .max(Number(chickenCanRequest), "تعداد وارد شده قابل تخصیص نیست"), + isAccepted: Yup.boolean() + .test("req", "باید تعهد نامه را بپذیرید!", (val, context) => { + return context.originalValue && context.originalValue === true; + }) + .required("این فیلد اجباری است!"), + price1: Yup.number() + .typeError("لطفا عدد وارد کنید!") + .min( + avicultureChickenPrice?.floorPrice, + "قیمت وارد شده از کف قیمت امروز کمتر است" + ) + .max( + avicultureChickenPrice?.ceilingPrice, + "قیمت وارد شده از سقف قیمت امروز بیشتر است" + ), + price2: Yup.number() + .typeError("لطفا عدد وارد کنید!") + .min( + avicultureChickenPrice?.floorPrice, + "قیمت وارد شده از کف قیمت امروز کمتر است" + ) + .max( + avicultureChickenPrice?.ceilingPrice, + "قیمت وارد شده از سقف قیمت امروز بیشتر است" + ), + price3: Yup.number() + .typeError("لطفا عدد وارد کنید!") + .min( + avicultureChickenPrice?.floorPrice, + "قیمت وارد شده از کف قیمت امروز کمتر است" + ) + .max( + avicultureChickenPrice?.ceilingPrice, + "قیمت وارد شده از سقف قیمت امروز بیشتر است" + ), + weight: Yup.number() + .test("weight", "وزن را تا دو رقم اعشار وارد کنید", (val, context) => { + return ( + context.originalValue && + context.originalValue.toString().length <= 4 + ); + }) + .required("این فیلد اجباری است!") + .typeError("لطفا وزن را وارد کنید!"), + losses: Yup.number() + .required("این فیلد اجباری است!") + .max(quantity, "تلفات وارد شده از باقیمانده بیشتر است!") + .typeError("لطفا تعداد تلفات را وارد کنید!"), + poultryPrice: Yup.number().typeError("لطفا فیلد را به درستی وارد کنید!"), + sellType: Yup.object() + .test("sellType", "نحوه فروش را انتخاب کنید!", (val, context) => { + return ( + context.originalValue && + Object.values(context.originalValue).some((item) => item === true) + ); + }) + .required("این فیلد اجباری است!"), + selectedSlaughters: poultryData[0]?.provinceAllowChooseKillHouse + ?.mandatory + ? Yup.array() + .of(Yup.string().required("At least one item is required.")) + .min(1, "At least one item is required.") + : Yup.array(), + }), + }); + + useEffect(() => { + if ( + data?.approved && + !( + data?.lowestPrice === 0 && + data?.highestPrice === 0 && + data?.lowestWeight === 0 && + data?.highestWeight === 0 + ) + ) { + if (formik.values.weight * 1000 <= data?.lowestWeight) { + setApprovedPrice(data?.lowestPrice); + } else if (formik.values.weight * 1000 >= data?.highestWeight) { + setApprovedPrice(data?.highestPrice); + } else { + const diffWeight = data?.highestWeight - data?.lowestWeight; + const diffPrice = data?.highestPrice - data?.lowestPrice; + const fraction = diffPrice / diffWeight; + const diffFromMinWeight = + formik.values.weight * 1000 - data?.lowestWeight; + setApprovedPrice(diffFromMinWeight * fraction + data?.lowestPrice); + formik.setFieldValue( + "poultryPrice", + diffFromMinWeight * fraction + data?.lowestPrice + ); + } + } + }, [formik.values.weight]); + + const formik2 = useFormik({ + initialValues: { + userInfoCheck: "", + }, + validationSchema: Yup.object({ + userInfoCheck: Yup.string() + .min(11, "شماره موبایل باید 11 رقم باشد") + .max(11, "شماره موبایل باید 11 رقم باشد") + .matches(/^09\d{9}$/, "شماره موبایل باید با 09 شروع شود و 11 رقم باشد"), + }), + }); + + const formik3 = useFormik({ + initialValues: { + userInfoCheck: "", + }, + validationSchema: Yup.object({ + userInfoCheck: Yup.number().typeError("لطفا فیلد را به درستی وارد کنید!"), + }), + }); + + const formikBuyer = useFormik({ + initialValues: { + mobile: "", + fname: "", + lname: "", + nationalCode: "", + province: "", + city: "", + }, + validationSchema: Yup.object({ + mobile: Yup.string() + .test("len", "شماره تلفن باید با 0 شروع شود", (val, context) => { + return context.originalValue && context.originalValue.startsWith("0"); + }) + .test("len", "شماره تماس 11 رقم باید باشد", (val, context) => { + if (context.originalValue) { + return context.originalValue.length === 11; + } + }) + .required("این فیلد اجباری است!") + .typeError("لطفا عدد وارد کنید!"), + fname: Yup.string() + .required("این فیلد اجباری است!") + .typeError("لطفا فیلد را به درستی وارد کنید!"), + lname: Yup.string() + .required("این فیلد اجباری است!") + .typeError("لطفا فیلد را به درستی وارد کنید!"), + nationalCode: Yup.number() + .required("این فیلد اجباری است!") + .typeError("لطفا فیلد را به درستی وارد کنید!"), + province: Yup.string() + .required("این فیلد اجباری است!") + .typeError("لطفا فیلد را به درستی وارد کنید!"), + city: Yup.string() + .required("این فیلد اجباری است!") + .typeError("لطفا فیلد را به درستی وارد کنید!"), + }), + }); + useEffect(() => { + formik.validateForm(); + formik2.validateForm(); + formik3.validateForm(); + formikBuyer.validateForm(); + }, []); + + useEffect(() => { + dispatch(avicultureGetSlaughters({ date: formik.values.slaughterDate })); + }, [formik.values.slaughterDate]); + + const penaltyPrice = formik.values.noChicken * 1000; + const dialogContent = ( + <> + + اینجانب {userProfile?.fullname} به وکالت از{" "} + {poultryData[0]?.userprofile?.fullName} موافقت خود را نسبت به موارد ذکر + شده اعلام می نمایم. + + + + + + + + + + ); + + useEffect(() => { + let newVal = formik.values.weight; + const mystring = formik.values.weight.toString().split(".").join(""); + if (formik.values.weight) { + if (mystring.length <= 3) { + if (mystring.length === 2) { + newVal = mystring[0] + "." + mystring[1]; + } + if (mystring.length === 3) { + newVal = mystring[0] + "." + mystring[1] + mystring[2]; + } + } + } + if (isNaN(Number.parseFloat(newVal))) { + formik.setFieldValue("weight", ""); + } else { + formik.setFieldValue("weight", Number.parseFloat(newVal)); + } + }, [formik.values.weight]); + + useEffect(() => { + if (isStockMarket) { + dispatch(avicultureGetChickenPrice()).then((r) => { + if (Array.isArray(r.payload.data)) { + openNotif({ + vertical: "top", + horizontal: "center", + msg: "قیمت روز مرغ در سامانه ثبت نشده است.", + severity: "error", + }); + + dispatch(DRAWER({ right: false, bottom: false, content: null })); + } + }); + } + }, [isStockMarket]); + + useEffect(() => { + formik.validateForm(); + formik2.validateForm(); + }, []); + + useEffect(() => { + formik.setFieldValue("selectedSlaughters", []); + setSelectedKillhouse(null); + }, [formik.values.noChicken]); + + useEffect(() => { + if (poultryKey) { + dispatch(avicultureGetDirectBuys(poultryKey)).then((r) => { + const data = r?.payload?.data; + if (data?.length) { + const dataTable = data?.map((item) => { + let state = ""; + if (item.directBuyingState === "pending") { + state = "در انتظار تایید استان"; + } else if (item.directBuyingState === "rejected") { + state = "رد شده"; + } else if (item.directBuyingState === "accepted") { + state = "تایید شده"; + } else if (item.directBuyingState === "deleted") { + state = "حذف شده"; + } + return [ + item?.killHouse?.killer ? "کشتارکن" : "کشتارگاه", + `${item?.killHouse?.name} (${item?.killHouse?.killHouseOperator?.user?.fullname}) ${item?.killHouse?.killHouseOperator?.user?.mobile}`, + item?.killCapacity?.toLocaleString(), + formatJustDate(item?.reciveDate), + item.inputDirectBuyingCode ? "دارد" : "ندارد", + state, + ]; + }); + dispatch( + OPEN_MODAL({ + title: "هشدار!", + content: ( + <> + + مرغدار انتخاب شده برای تاریخ امروز درخواست فعال خرید مستقیم + دارد. + + + + + + + + ), + }) + ); + } + }); + dispatch(avicultureGetHatchingData({ key: poultryKey })).then((r) => { + if (r.payload.data) { + setHatchingData(r.payload.data); + } else { + openNotif({ + vertical: "top", + horizontal: "center", + msg: "اطلاعات جوجه ریزی یافت نشد!", + severity: "error", + }); + } + }); + } + }, [poultryKey]); + + useEffect(() => { + let baseCanRequest = + formik.values.noChicken <= Number(leftOvers) && + Number(formik.values.losses) <= Number(leftOvers) + ? formik.values.avicultureSellType === "freePrice" + ? parseInt( + hatchingSelected?.freeGovernmentalInfo + ?.leftTotalFreeCommitmentQuantity + ) + : Number(leftOvers) - Number(formik.values.losses) + : 0; + + // Apply market limitation if tradePanel is checked and active + if ( + tradePanel && + marketLimitationData?.active && + marketLimitationData?.market?.remainQuantity !== undefined && + marketLimitationData?.market?.maxLimitationQuantity !== undefined + ) { + const marketRemain = marketLimitationData.market.remainQuantity; + baseCanRequest = Math.min(baseCanRequest, marketRemain); + } + + setChickenCanRequest(baseCanRequest); + formik.validateForm(); + }, [ + formik.values.losses, + leftOvers, + formik.values.noChicken, + formik.values.avicultureSellType, + tradePanel, + marketLimitationData, + ]); + + const [sellForFreezing, setSellForFreezing] = useState(false); + const [sellForExport, setSellForExport] = useState(false); + + useEffect(() => { + setQuantity(hatchingSelected.quantity); + setlosses(hatchingSelected.losses); + setLeftOvers(hatchingSelected.leftOver); + dispatch(provinceGetSellForFreezingStatus()).then((r) => { + setSellForFreezing(r.payload.data.permission); + }); + dispatch(provincePolicyGetExportAllowStatus()).then((r) => { + setSellForExport(r.payload.data.allow); + }); + }, [hatchingSelected]); + + useEffect(() => { + if (tradePanel) { + dispatch(provincePolicyGetMarketDailyLimitation()).then((r) => { + if (r.payload?.data) { + setMarketLimitationData(r.payload.data); + } + }); + } + }, [tradePanel]); + + // const handleSellTypeChange = (event) => { + // formik.setFieldValue("sellType", { + // ...formik.values.sellType, + // [event.target.name]: event.target.checked, + // }); + // }; + + // const [policyAvicultureCommit, setPolicyAvicultureCommit] = useState(); + + // useEffect(() => { + // dispatch(provinceGetPolicyAvicultureCommitService()).then((r) => { + // setPolicyAvicultureCommit(r.payload.data); + // }); + // }, []); + + return ( + <> + {!poultryData && !isAviculture ? ( + <> + + {autoLoading && } + + {!autoLoading && ( + + جستجو کاربر + + {/* */} + { + return option.disabled <= 0; + }} + loading={loading} + options={cityGetPoultries || []} + getOptionLabel={(option) => option.label} + onChange={(event, newValue) => { + formik2.setFieldValue("userInfoCheck", newValue.value); + }} + onBlur={formik2.handleBlur} + renderInput={(params) => ( + + {loading ? ( + + ) : null} + {params.InputProps.endAdornment} + + ), + }, + }} + /> + )} + /> + + { + dispatch( + cityGetPoultryData(formik2.values.userInfoCheck) + ).then((r) => { + if (r.error) { + openNotif({ + vertical: "top", + horizontal: "center", + msg: "کاربر یافت نشد", + severity: "error", + }); + } + setPoultryData(r.payload.data); + }); + }} + > + + + + شماره موبایل با صفر شروع می‌شود! + + پس از ثبت درخواست، میتوانید آن را در بخش درخواست ها مدیریت کنید. + + + )} + + ) : ( + + + {/* + + وکالت مرغدار جهت ثبت درخواست کشتار + + } + columns={["استان", "شهرستان"]} + data={[ + [ + poultryData[0]?.allow?.province ? ( + دارد + ) : ( + ندارد + ), + poultryData[0]?.allow?.city ? ( + دارد + ) : ( + ندارد + ), + ], + ]} + /> + */} + + ({ + id: i.key, + label: i.unitName, + })) + : [] + } + onChange={(event, value) => { + setPolutryKey(value.id); + }} + renderInput={(params) => ( + + )} + /> + + + {poultryKey && ( + + { + return { + id: i.key, + race: i.chickenBreed, + selected: i, + label: `دوره ${i.period} سالن ${i.hall} نژاد ${i.chickenBreed} باقیمانده ${i.leftOver} قطعه`, + }; + }) + : [] + } + onChange={(event, value) => { + sethatchingKey(value.id); + setHatchingSelected(value.selected); + setChickenBreed(value.race); + }} + renderInput={(params) => ( + + )} + /> + + )} + + {hatchingKey && ( + <> + + + + + + + + + + + )} + + {hatchingSelected && ( + + + اطلاعات کشتار + + + {/* + + */} + + {/* */} + chickenCanRequest + ? (() => { + if ( + tradePanel && + marketLimitationData?.active && + formik.values.noChicken > + marketLimitationData?.market?.remainQuantity + ) { + return `حداکثر ظرفیت پنل معاملات ${marketLimitationData?.market?.remainQuantity?.toLocaleString()} قطعه است!`; + } + return "این حجم قابل تخصیص نیست!"; + })() + : formik.touched.noChicken + ? Boolean(formik.errors.noChicken) + : null + } + onChange={formik.handleChange} + onBlur={formik.handleBlur} + helperText={ + formik.values.noChicken > chickenCanRequest + ? (() => { + if ( + tradePanel && + marketLimitationData?.active && + formik.values.noChicken > + marketLimitationData?.market?.remainQuantity + ) { + return `حداکثر ظرفیت پنل معاملات ${marketLimitationData?.market?.remainQuantity?.toLocaleString()} قطعه است!`; + } + return "این حجم قابل تخصیص نیست!"; + })() + : formik.touched.noChicken && + Boolean(formik.errors.noChicken) + ? formik.errors.noChicken + : null + } + /> + + + {data?.approved && ( + + + prop.palette.grey["A700"]} + variant={"caption"} + > + مجوز فروش آزاد: + + + {parseInt( + hatchingSelected?.freeGovernmentalInfo + ?.totalFreeCommitmentQuantity + )?.toLocaleString()} + + + قطعه + + + + + مانده فروش آزاد: + + + {parseInt( + hatchingSelected?.freeGovernmentalInfo + ?.leftTotalFreeCommitmentQuantity + ).toLocaleString()} + {"‌‌"} + قطعه + + + + )} + + + } + value={formik.values.slaughterDate} + error={ + formik.touched.slaughterDate + ? Boolean(formik.errors.slaughterDate) + : null + } + onChange={(e) => { + formik.setFieldValue( + "slaughterDate", + moment(e).format("YYYY-MM-DD") + ); + }} + onBlur={formik.handleBlur} + helperText={ + formik.touched.slaughterDate && + Boolean(formik.errors.slaughterDate) + ? formik.errors.slaughterDate + : null + } + /> + + + + کیلوگرم + ), + }} + value={formik.values.weight} + error={ + formik.touched.weight ? Boolean(formik.errors.weight) : null + } + onChange={formik.handleChange} + onBlur={formik.handleBlur} + helperText={ + formik.touched.weight && Boolean(formik.errors.weight) + ? formik.errors.weight + : null + } + /> + + + {/* + + + } + label="فروش داخل استان" + /> + } + label="فروش خارج استان" + /> + + + */} + + {/* + نحوه فروش + */} + + {value === "insideProvince" ? ( + <> + + + { + setIsStockMarket(event.currentTarget.value); + }} + > + {/* } + label="فروش اتحادیه" + /> */} + {/* + } + label="فروش مزایده ای" + /> */} + {isStockMarket === "فروش مزایده ای" && ( + + + prop.palette.grey["A700"]} + variant={"caption"} + > + کف قیمت امروز: + + + {avicultureChickenPrice?.floorPrice + ? avicultureChickenPrice?.floorPrice.toLocaleString() + : "نامشخص"}{" "} + {" "} + ریال + + + + prop.palette.grey["A700"]} + variant={"caption"} + > + سقف قیمت امروز: + + + {avicultureChickenPrice?.ceilingPrice + ? avicultureChickenPrice?.ceilingPrice.toLocaleString() + : "نامشخص"} + ریال + + + + + + {arr.map((item, i) => { + return ( + + + پیشنهاد {i + 1} + + + + + + + بازه زمانی (ساعت) + + + + {formik.touched.period1 && + Boolean(formik.errors.period1) + ? formik.errors.period1 + : null} + + + {/* */} + + ); + })} + + + {arr.length > 1 && ( + + + + )} + {arr.length < 3 && ( + + + افزودن پیشنهاد جدید + + )} + + + + + در صورت عدم فروش در بورس، از طریق اتحادیه فروش + برود + + + + + )} + + + + {/* + formik.setFieldValue("selectedSlaughters", e) + } + options={slaughterHousesListForSelect} + /> */} + {/* + {formik.values.selectedSlaughters && ( + + کشتارگاهای انتخابی + + )} + + {formik.values.selectedSlaughters.map((item, i) => { + return ( + + {i + 1}- {item} + + ); + })} + + */} + {/* + + نحوه فروش + + + + } + label="نقدی" + /> + + } + label="زمان دار (تا یک ماه)" + /> + + + {formik.touched.sellType && + Boolean(formik.errors.sellType) + ? formik.errors.sellType + : null} + + */} + + {/* {unions?.length > 1 && ( */} + {/* <> */} + + {data?.approved && + !( + data?.lowestPrice === 0 && + data?.highestPrice === 0 && + data?.lowestWeight === 0 && + data?.highestWeight === 0 + ) && ( + + نوع فروش + + } + label="دولتی" + /> + } + label="آزاد" + /> + + + )} + + {data?.approved && + formik.values.avicultureSellType === "goverment" && + !( + data?.lowestPrice === 0 && + data?.highestPrice === 0 && + data?.lowestWeight === 0 && + data?.highestWeight === 0 + ) && ( + + + + قیمت مصوب: + + + + {approvedPrice + ? Math.round(approvedPrice)?.toLocaleString() + : 0} + ریال + + + )} + + + + + نحوه تسویه حساب + + + } + label="خارج از سامانه" + /> + + } + label="درون سامانه" + disabled={true} + /> + + + + {poultryData?.length && + poultryData[0]?.provinceAllowChooseKillHouse + ?.allowState && ( + + { + formik.setFieldValue("selectedSlaughters", [ + v.value, + ]); + setSelectedKillhouse(v.killhouseKey); + }} + id="combo-box-demo" + options={slaughterHousesListForSelect} + sx={{ width: "100%" }} + getOptionDisabled={(option) => { + const limit = Number(formik.values.noChicken); + return option.item.quantitySum < limit; + }} + renderInput={(params) => ( + + )} + /> + {/* { + formik.setFieldValue("selectedSlaughters", e); + }} + options={slaughterHousesListForSelect} + /> */} + + {formik.values.selectedSlaughters && ( + + کشتارگاهای انتخابی + + )} + + {formik.values.selectedSlaughters.map((item, i) => { + return ( + + {i + 1}- {item} + + ); + })} + + + + )} + + + + اطلاعات تعاونی + + { + setUnionSelected(event.currentTarget.value); + }} + > + {unions?.map((item) => { + return ( + <> + } + label={item.unitName} + /> + + ); + })} + + + + {/* + )} */} + + ) : ( + <> + + + اطلاعات کاربر را وارد یا جستجو کنید. + + + + + { + dispatch( + cityGetBuyer(formik3.values.userInfoCheck) + ).then((r) => { + if (r.error) { + openNotif({ + vertical: "top", + horizontal: "center", + msg: "کاربر یافت نشد", + severity: "error", + }); + setBuyerInfo(""); + } else { + setBuyerInfo(r.payload.data); + } + }); + }} + > + + + + + شماره موبایل با صفر شروع می‌شود! + + + + {buyerInfo ? ( + + + prop.palette.grey["A700"]} + > + نام کامل: + + + {(buyerInfo?.firstname ? buyerInfo?.firstname : "") + + " " + + (buyerInfo?.lastname ? buyerInfo?.lastname : "")} + + + + + prop.palette.grey["A700"]} + > + نقش: + + + اپراتور استان + + + + + prop.palette.grey["A700"]} + > + استان: + + + {buyerInfo?.province} + + + + + prop.palette.grey["A700"]} + > + شهر: + + + {buyerInfo?.city} + + + + ) : ( + + + اطلاعات کاربر را وارد کنید + + + + + + + + + + + + + + )} + + )} + + + {sellForFreezing && ( + + + { + setFreezing(!freezing); + }} + inputProps={{ "aria-label": "controlled" }} + /> + کشتار برای انجماد + + + )} + + {marketLimitationData?.active ? ( + + + + { + setTradePanel(!tradePanel); + }} + inputProps={{ "aria-label": "controlled" }} + /> + + نمایش در پنل معاملات + + + {tradePanel && ( + + + + prop.palette.grey["A700"]} + > + باقیمانده مجاز: + + + {marketLimitationData?.market?.remainQuantity?.toLocaleString()}{" "} + قطعه + + + + prop.palette.grey["A700"]} + > + حداکثر قطعه مجاز: + + + {marketLimitationData?.market?.maxLimitationQuantity?.toLocaleString()}{" "} + قطعه + + + + )} + + + ) : ( + + { + setTradePanel(!tradePanel); + }} + inputProps={{ "aria-label": "controlled" }} + /> + + نمایش در پنل معاملات + + + )} + + + {(formik.values.avicultureSellType !== "goverment" || + (data?.approved && + data?.lowestPrice === 0 && + data?.highestPrice === 0 && + data?.lowestWeight === 0 && + data?.highestWeight === 0)) && ( + + ریال + ), + }} + value={formik.values.poultryPrice} + error={ + formik.touched.poultryPrice + ? Boolean(formik.errors.poultryPrice) + : null + } + onChange={formik.handleChange} + onBlur={formik.handleBlur} + helperText={ + formik.touched.poultryPrice && + Boolean(formik.errors.poultryPrice) + ? formik.errors.poultryPrice + : null + } + sx={{ + "& .Mui-disabled": { + backgroundColor: "#f0f0f0", + color: "#666", + "& .MuiOutlinedInput-notchedOutline": { + borderColor: "#ccc", + }, + }, + }} + disabled={freezing} + /> + {!data?.approved && + formik.values.avicultureSellType !== "goverment" && ( + + نوع فروش: آزاد + + )} + + )} + {sellForExport && ( + + { + setToExport(!toExport); + }} + inputProps={{ "aria-label": "controlled" }} + /> + کشتار برای صادرات + + )} + + {getRoleFromUrl() === "Poultry" && ( + + + + + + } + btnTitle={"متن تعهد نامه تایید شد!"} + isAccepted={formik.values.isAccepted} + /> + + )} + + {submitStatus && ( + + )} + + {submitStatus && ( + + احراز پیامکی قیمت مرغدار در استان فعال است. در صورت ویرایش، + تلفن مرغدار در سراسر سامانه با تلفن جدید جایگزین میگردد! + + )} + + + + + )} + + )} + + ); +}; diff --git a/src/features/city/components/city-new-request/CityNewRequest.js b/src/features/city/components/city-new-request/CityNewRequest.js new file mode 100644 index 0000000..c961513 --- /dev/null +++ b/src/features/city/components/city-new-request/CityNewRequest.js @@ -0,0 +1,62 @@ +import { Button, Card } from "@mui/material"; +import React from "react"; +import { useDispatch } from "react-redux"; +import { AdvancedTable } from "../../../../components/advanced-table/AdvancedTable"; +import { Grid } from "../../../../components/grid/Grid"; +import { columnsName } from "../../../../data/columnsName"; +import { SPACING } from "../../../../data/spacing"; +import { DRAWER } from "../../../../lib/redux/slices/appSlice"; +import { AvicultureNewRequest } from "../../../aviculture/components/aviculture-new-request/AvicultureNewRequest"; + +export const CityNewRequest = () => { + const dispatch = useDispatch(); + return ( + + + + + + + + + + + + + + + ); +}; diff --git a/src/features/city/components/city-new-requests/CityNewRequests.js b/src/features/city/components/city-new-requests/CityNewRequests.js new file mode 100644 index 0000000..3120df9 --- /dev/null +++ b/src/features/city/components/city-new-requests/CityNewRequests.js @@ -0,0 +1,461 @@ +import { Button, TextField, Typography } from "@mui/material"; +import { useContext, useEffect, useState } from "react"; +import PlagiarismIcon from "@mui/icons-material/Plagiarism"; +// import { ROUTE_CITY_FILE } from "../../../../routes/routes"; +// import { avicultureGetRequests } from "../../../aviculture/services/aviculture-requests"; +import CreateIcon from "@mui/icons-material/Create"; +import CityFileOperations from "../../../file/components/city-file-operations/CityFileOperations"; +import { Grid } from "../../../../components/grid/Grid"; +import { SPACING } from "../../../../data/spacing"; +import { AppContext } from "../../../../contexts/AppContext"; +import { PageTable } from "../../../../components/page-table/PageTable"; +import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl"; +import axios from "axios"; +import { DatePicker } from "@mui/x-date-pickers"; +import moment from "moment/moment"; +import { formatJustDate } from "../../../../utils/formatTime"; +import { IconButton } from "@mui/material"; +import { DRAWER } from "../../../../lib/redux/slices/appSlice"; +import { useDispatch } from "react-redux"; +import { ROUTE_CITY_FILE } from "../../../../routes/routes"; +import { useNavigate } from "react-router-dom"; +import { RiSearchLine } from "react-icons/ri"; + +export const CityNewRequests = () => { + const dispatch = useDispatch(); + const navigate = useNavigate(); + const [, , selectedDate1, setSelectedDate1, selectedDate2, setSelectedDate2] = + useContext(AppContext); + useEffect(() => { + const currentDate = moment(new Date()).format("YYYY-MM-DD"); + setSelectedDate1(currentDate); + setSelectedDate2(currentDate); + }, []); + + // page table + const [data, setData] = useState([]); + const [loading, setLoading] = useState(false); + const [totalRows, setTotalRows] = useState(0); + const [perPage, setPerPage] = useState(10); + + const [textValue, setTextValue] = useState(""); + + const handleTextChange = (event) => { + setTextValue(event.target.value); + }; + + const fetchApiData = async (page, textValue) => { + setLoading(true); + let response = await axios.get( + `Poultry_Request/?state=pending&date1=${selectedDate1}&date2=${selectedDate2}&search=filter&value=${ + textValue ? textValue : "" + }&role=${getRoleFromUrl()}&page=${page}&page_size=${perPage}` + ); + setData(response.data.results); + setTotalRows(response.data.count); + setLoading(false); + }; + + const handlePageChange = (page) => { + fetchApiData(page, textValue); + }; + + const handlePerRowsChange = async (newPerPage, page) => { + setLoading(true); + let response = await axios.get( + `Poultry_Request/?state=pending&date1=${selectedDate1}&date2=${selectedDate2}&search=filter&value=${ + textValue ? textValue : "" + }&page=${page}&page_size=${newPerPage}` + ); + + setData(response.data.results); + setTotalRows(response.data.count); + setPerPage(newPerPage); + + setLoading(false); + }; + + useEffect(() => { + fetchApiData(1); + }, [selectedDate1, selectedDate2, perPage]); + + const handleSubmit = async (event) => { + event.preventDefault(); + setLoading(true); + + try { + const response = await axios.get( + `Poultry_Request/?state=pending&date1=${selectedDate1}&date2=${selectedDate2}&role=${getRoleFromUrl()}&search=filter&value=${ + textValue ? textValue : "" + }` + ); + setData(response.data.results); + setTotalRows(response.data.count); + } catch (error) { + console.error("Error fetching data:", error); + } finally { + setLoading(false); + } + }; + + const updateTable = () => { + fetchApiData(1); + }; + + const columns = [ + { + name: "کدسفارش", + selector: (item) => item?.orderCode, + sortable: false, + wrap: true, + allowOverflow: true, + center: true, + width: "90px", + }, + { + name: "تاریخ ثبت درخواست", + selector: (item) => formatJustDate(item?.createDate), + sortable: false, + wrap: true, + allowOverflow: true, + center: true, + width: "90px", + }, + { + name: "نوع کشتار", + selector: (item) => { + return item?.freezing ? "انجماد" : item?.export ? "صادرات" : "عادی"; + }, + sortable: true, + wrap: true, + allowOverflow: true, + center: true, + width: "90px", + }, + { + name: "تاریخ کشتار", + selector: (item) => formatJustDate(item?.sendDate), + sortable: false, + wrap: true, + allowOverflow: true, + center: true, + width: "90px", + }, + { + name: "مرغداری", + selector: (item) => + `${item?.poultry?.unitName} (${item?.poultry?.user?.mobile})`, + sortable: false, + wrap: true, + allowOverflow: true, + center: true, + width: "90px", + }, + { + name: "دامپزشک فارم", + selector: (item) => + `${item?.vetFarm?.vetFarmFullname} (${item?.vetFarm?.vetFarmMobile})`, + sortable: false, + wrap: true, + allowOverflow: true, + center: true, + width: "90px", + }, + { + name: "استان/شهر", + selector: (item) => + `${item?.poultry?.address?.province?.name}/${item?.poultry?.address?.city?.name}`, + sortable: false, + wrap: true, + allowOverflow: true, + center: true, + width: "90px", + }, + { + name: "تعاونی", + selector: (item) => { + return item?.poultry?.cityOperator; + }, + sortable: false, + wrap: true, + allowOverflow: true, + center: true, + width: "90px", + }, + { + name: "تاریخ جوجه ریزی", + selector: (item) => formatJustDate(item?.hatching?.hatchingDate), + sortable: false, + wrap: true, + allowOverflow: true, + center: true, + width: "90px", + }, + { + name: "سن", + selector: (item) => item?.hatching?.age, + sortable: false, + wrap: true, + allowOverflow: true, + center: true, + width: "90px", + }, + { + name: "میانگین وزن (کیلوگرم)", + selector: (item) => { + return item?.IndexWeight; + }, + sortable: false, + wrap: true, + allowOverflow: true, + center: true, + width: "90px", + }, + { + name: "تعداد (قطعه)", + selector: (item) => item?.quantity, + sortable: false, + wrap: true, + allowOverflow: true, + center: true, + width: "90px", + }, + { + name: "وزن بار (کیلوگرم)", + selector: (item) => (item?.quantity * item?.IndexWeight).toLocaleString(), + sortable: false, + wrap: true, + allowOverflow: true, + center: true, + width: "90px", + }, + { + name: "عملیات", + selector: (item) => { + return ( + + dispatch( + DRAWER({ + right: !(window.innerWidth <= 600), + bottom: window.innerWidth <= 600, + content: ( + + ), + title: "انجام عملیات شهرستان", + }) + ) + } + > + + + ); + }, + sortable: false, + wrap: true, + allowOverflow: true, + center: true, + }, + { + name: "مشاهده", + selector: (item) => { + return ( + navigate(ROUTE_CITY_FILE + item?.id)} + > + + + ); + }, + sortable: false, + wrap: true, + allowOverflow: true, + center: true, + }, + ]; + + // useEffect(() => { + // dispatch(LOADING_START()); + // dispatch(avicultureGetRequests({ selectedDate1, selectedDate2 })).then( + // (r) => { + // dispatch(LOADING_END()); + // } + // ); + // }, [selectedDate1, selectedDate2]); + + // useEffect(() => { + // const filteredData = avicultureRequests?.filter( + // (item, i) => item.stateProcess === "pending" + // ); + // const d = filteredData?.map((item, i) => { + // return [ + // i + 1, + // item.orderCode, + // item.poultry.userprofile.baseOrder, + // formatJustDate(item.createDate), + // formatJustDate(item.sendDate), + // item?.process?.poultry?.poultryName, + // item?.process?.poultry?.poultryMobile, + // item?.process?.poultry?.poultryCity, + // item?.process?.poultry?.poultryProvince, + // formatJustDate(item.hatching.date), + // item?.process?.poultry?.age, + // item?.process?.poultry?.poultryQuantity, + // + // dispatch( + // DRAWER({ + // right: !(window.innerWidth <= 600), + // bottom: window.innerWidth <= 600, + // content: ( + // + // ), + // title: "انجام عملیات شهرستان", + // }) + // ) + // } + // > + // + // , + // + // navigate(ROUTE_CITY_FILE + item?.process?.poultry?.poultryRequestId) + // } + // > + // + // , + // ]; + // }); + + // setDataTable(d); + // }, [avicultureRequests]); + + return ( + <> + {/* + + درخواست های جدید فروش اتحادیه + + + + ( + + )} + value={selectedDate1} + onChange={(e) => { + setSelectedDate1(moment(e).format("YYYY-MM-DD")); + }} + /> + + + ( + + )} + value={selectedDate2} + onChange={(e) => { + setSelectedDate2(moment(e).format("YYYY-MM-DD")); + }} + /> + + + + } + columns={columnsName} + data={dataTable} + /> */} + + + + + درخواست های جدید فروش اتحادیه + + + ( + + )} + value={selectedDate1} + onChange={(e) => { + setSelectedDate1(moment(e).format("YYYY-MM-DD")); + }} + /> + + + ( + + )} + value={selectedDate2} + onChange={(e) => { + setSelectedDate2(moment(e).format("YYYY-MM-DD")); + }} + /> + + +
    + + + +
    +
    + } + columns={columns} + data={data} + progressPending={loading} + pagination + paginationServer + paginationTotalRows={totalRows} + onChangeRowsPerPage={handlePerRowsChange} + onChangePage={handlePageChange} + /> + + + ); +}; diff --git a/src/features/city/components/city-operations/CityOperations.js b/src/features/city/components/city-operations/CityOperations.js new file mode 100644 index 0000000..bfe4d5d --- /dev/null +++ b/src/features/city/components/city-operations/CityOperations.js @@ -0,0 +1,135 @@ +import { Grid } from "../../../../components/grid/Grid"; +import { SPACING } from "../../../../data/spacing"; +import { NavLink } from "../../../../components/nav-link/NavLink"; +import { useLocation } from "react-router-dom"; +import { + ROUTE_CITY_ACTIVE_REQUESTS, + ROUTE_CITY_ARCHIVED_REQUESTS, + ROUTE_CITY_AWAITING_INSPECTION_REQUESTS, + ROUTE_CITY_REJECTED_REQUESTS, + ROUTE_CITY_AWAITING_PAYMENT_REQUESTS, + ROUTE_CITY_NEW_REQUESTS, + ROUTE_CITY_FREE_SALES_REQUESTS, +} from "../../../../routes/routes"; +import LinkItem from "../../../../components/link-item/LinkItem"; +import { VscFolderActive, VscNewFolder } from "react-icons/vsc"; +import { GiMoneyStack } from "react-icons/gi"; +import { GrInspect } from "react-icons/gr"; +import { RiFolderWarningLine } from "react-icons/ri"; +import { FaArchive } from "react-icons/fa"; + +export const CityOperations = () => { + const { pathname } = useLocation(); + + return ( + + + + + } + title="درخواست های جدید" + description="درخواست های در انتظار بررسی" + /> + + + } + title="درخواست های فعال" + description="مشاهده درخواست های در جریان" + /> + + + + } + title="در انتظار پرداخت" + description="مشاهده درخواست های در انتظار پرداخت کشتارگاه" + /> + + + + } + title="در انتظار بازرسی" + description="درخواست های در انتظار بررسی بازرس" + /> + + + + + } + title="درخواست های رد شده" + description="مشاهده درخواست هایی که به دلایل مختلف توسط اتحادیه رد شده است" + /> + + + } + title="فروش خارج از استان" + /> + + + + + } + title="بایگانی" + description="درخواست های پایان یافته" + /> + + + + + ); +}; diff --git a/src/features/city/components/city-poultry-farms/CityPoultryFarms.js b/src/features/city/components/city-poultry-farms/CityPoultryFarms.js new file mode 100644 index 0000000..024a7d1 --- /dev/null +++ b/src/features/city/components/city-poultry-farms/CityPoultryFarms.js @@ -0,0 +1,197 @@ +import { + Grid, + IconButton, + List, + ListItemButton, + ListItemIcon, + ListItemText, + Popover, +} from "@mui/material"; +import ResponsiveTable from "../../../../components/responsive-table/ResponsiveTable"; +import { SPACING } from "../../../../data/spacing"; +import { useDispatch, useSelector } from "react-redux"; + +import { useEffect, useState } from "react"; +import { DRAWER, OPEN_MODAL } from "../../../../lib/redux/slices/appSlice"; +import { CitySubmitTenantForm } from "../city-submit-tenant-form/CitySubmitTenantForm"; +import { CityEditAvicultureInfoForm } from "../city-edit-aviculture-info-form/CityEditAvicultureInfoForm"; +import { cityGetPoultryFarm } from "../../services/city-get-poultry-farms"; +import { CityTenantOwnerInfo } from "../city-tenant-owner-info/CityTenantOwnerInfo"; +import TuneIcon from "@mui/icons-material/Tune"; +import PersonAddAltIcon from "@mui/icons-material/PersonAddAlt"; +import InfoOutlinedIcon from "@mui/icons-material/InfoOutlined"; +import EditOutlinedIcon from "@mui/icons-material/EditOutlined"; + +const PoultryFarmActions = ({ item }) => { + const dispatch = useDispatch(); + const [anchorPosition, setAnchorPosition] = useState(null); + + const hasTenant = Object.keys(item.poultryTenant).length !== 0; + + const handleOpen = (event) => { + const rect = event.currentTarget.getBoundingClientRect(); + setAnchorPosition({ + top: rect.bottom + window.scrollY, + left: rect.left + rect.width / 2 + window.scrollX, + }); + }; + + const handleClose = () => { + setAnchorPosition(null); + }; + + const handleAddTenant = () => { + dispatch( + DRAWER({ + right: !(window.innerWidth <= 600), + bottom: window.innerWidth <= 600, + title: "ایجاد مستاجر جدید", + content: , + }) + ); + handleClose(); + }; + + const handleShowTenantInfo = () => { + dispatch( + OPEN_MODAL({ + title: "اطلاعات مستاجر", + content: , + }) + ); + handleClose(); + }; + + const handleEditInfo = () => { + dispatch( + DRAWER({ + right: !(window.innerWidth <= 600), + bottom: window.innerWidth <= 600, + title: "ویرایش اطلاعات مرغدار", + content: , + }) + ); + handleClose(); + }; + + return ( + + + + + + + {hasTenant ? ( + + + + + + + ) : ( + + + + + + + )} + + + + + + + + + + ); +}; + +export const CityPoultryFarms = () => { + const [dataTable, setDataTable] = useState([]); + const { poultryFarms } = useSelector((state) => state.citySlice); + const dispatch = useDispatch(); + + useEffect(() => { + dispatch(cityGetPoultryFarm()); + }, []); + + useEffect(() => { + const d = poultryFarms + ?.filter((item) => Object.keys(item.poultryOwner).length === 0) + .map((item, i) => { + return [ + i + 1, + item.unitName, + item.userprofile.fullName, + item.userprofile.breedingUniqueId, + item.address.province.name, + item.address.city.name, + item.userprofile.mobile, + , + ]; + }); + + setDataTable(d); + }, [poultryFarms]); + + const [tableDataCol] = useState([ + "ردیف", + "نام مرغداری", + "نام صاحب", + "شناسه یکتا", + "استان", + "شهر", + "تلفن همراه", + "عملیات", + ]); + + return ( + + + + ); +}; diff --git a/src/features/city/components/city-profile/CityProfile.js b/src/features/city/components/city-profile/CityProfile.js new file mode 100644 index 0000000..7d3c47f --- /dev/null +++ b/src/features/city/components/city-profile/CityProfile.js @@ -0,0 +1,61 @@ +import { Box } from "@mui/system"; +import { useEffect } from "react"; +import { useDispatch, useSelector } from "react-redux"; +import { Grid } from "../../../../components/grid/Grid"; +import { SimpleTable } from "../../../../components/simple-table/SimpleTable"; +import { SPACING } from "../../../../data/spacing"; +import { + LOADING_END, + LOADING_START, +} from "../../../../lib/redux/slices/appSlice"; +import { ChangeCardInfo } from "../../../authentication/components/change-card-info/ChangeCardInfo"; +// import { ChangeCardInfo } from "../../../authentication/components/change-card-info/ChangeCardInfo"; +// import { ChangeCardInfo } from "../../../authentication/components/change-card-info/ChangeCardInfo"; +import { cityGetProfile } from "../../services/city-get-profile"; + +export const CityProfile = () => { + const { profile } = useSelector((state) => state.citySlice); + const dispatch = useDispatch(); + + useEffect(() => { + dispatch(LOADING_START()); + dispatch(cityGetProfile()).then((r) => { + dispatch(LOADING_END()); + }); + }, []); + + return ( + + + + + <> + + + + + + + + + + + + ); +}; diff --git a/src/features/city/components/city-rejected-requests/CityRejectedRequests.js b/src/features/city/components/city-rejected-requests/CityRejectedRequests.js new file mode 100644 index 0000000..db4c21b --- /dev/null +++ b/src/features/city/components/city-rejected-requests/CityRejectedRequests.js @@ -0,0 +1,74 @@ +import { Card, IconButton } from "@mui/material"; +import { useEffect, useState } from "react"; +import { AdvancedTable } from "../../../../components/advanced-table/AdvancedTable"; +import PlagiarismIcon from "@mui/icons-material/Plagiarism"; +import { useNavigate } from "react-router-dom"; +import { ROUTE_CITY_FILE } from "../../../../routes/routes"; +import { FileInformation } from "../../../file/components/file-information/FileInformation"; +import useAvicultureRequests from "../../../aviculture/hooks/useAvicultureRequests"; +import { formatJustDate } from "../../../../utils/formatTime"; + +export const CityRejectedRequests = () => { + const navigate = useNavigate(); + + const [dataTable, setDataTable] = useState([]); + const avicultureRequests = useAvicultureRequests("CityOperator"); + useEffect(() => { + const filteredData = avicultureRequests?.filter( + (item, i) => item.stateProcess === "rejected" + ); + const d = filteredData?.map((item, i) => { + return [ + i + 1, + item.orderCode, + formatJustDate(item?.createDate), + formatJustDate(item?.sendDate), + item?.process?.poultry?.poultryName, + item?.process?.poultry?.poultryMobile, + item?.process?.poultry?.poultryCity, + item?.process?.poultry?.poultryProvince, + item?.process?.poultry?.age, + item?.process?.poultry?.poultryQuantity, + + navigate(ROUTE_CITY_FILE + item?.process?.poultry?.poultryRequestId) + } + > + + , + ]; + }); + + setDataTable(d); + }, []); + + const [tableDataCol] = useState([ + "ردیف", + "کد سفارش", + "تاریخ ثبت درخواست", + "تاریخ درخواست", + "مرغدار", + "تلفن مرغدار", + "شهر", + "استان", + "سن مرغ", + "تعداد", + "مشاهده", + ]); + return ( + + ( + + )} + data={dataTable} + /> + + ); +}; diff --git a/src/features/city/components/city-submit-aviculture/CitySubmitAviculture.js b/src/features/city/components/city-submit-aviculture/CitySubmitAviculture.js new file mode 100644 index 0000000..d256fe5 --- /dev/null +++ b/src/features/city/components/city-submit-aviculture/CitySubmitAviculture.js @@ -0,0 +1,1211 @@ +import { + Autocomplete, + Button, + Checkbox, + Chip, + Divider, + FormControl, + FormControlLabel, + FormHelperText, + IconButton, + InputLabel, + MenuItem, + Select, + TextField, + Typography, +} from "@mui/material"; + +import React, { useEffect } from "react"; +import { useFormik } from "formik"; + +import DeleteIcon from "@mui/icons-material/Delete"; +import AddIcon from "@mui/icons-material/Add"; +import CheckIcon from "@mui/icons-material/Check"; + +import { + DRAWER, + LOADING_END, + LOADING_START, +} from "../../../../lib/redux/slices/appSlice"; + +import { useDispatch } from "react-redux"; +import { useState } from "react"; +import { DatePicker } from "@mui/x-date-pickers"; +import moment from "moment"; +import SearchIcon from "@mui/icons-material/Search"; +import { useContext } from "react"; +import { AppContext } from "../../../../contexts/AppContext"; +import { Yup } from "../../../../lib/yup/yup"; +import { cityGetCity } from "../../services/city-get-city"; +import { Grid } from "../../../../components/grid/Grid"; +import { SPACING } from "../../../../data/spacing"; +import { provinceCheckUserExistence } from "../../../province/services/province-check-user-existence"; +import { formatJustDate } from "../../../../utils/formatTime"; +import { provinceRegisterUser } from "../../../province/services/province-register-user"; +import { provinceGetUserProfiles } from "../../../province/services/province-get-user-profiles"; +import { cityGetProvinces } from "../../services/CityGetProvinces"; + +export const CitySubmitAviculture = () => { + const [openNotif] = useContext(AppContext); + + const [provinceData, setProvinceData] = useState([]); + const [cityData, setCityData] = useState([]); + const [provinceKey, setProvinceKey] = useState(); + const [cityKey, setCityKey] = useState(); + + const [poultryProvinceKey, setPoultryProvinceKey] = useState(); + const [poultryCityKey, setPoultryCityKey] = useState(); + + const [userChecked, setUserChecked] = useState(false); + + const [isExistProvince, setIsExistProvince] = useState(true); + + const [userData, setUserData] = useState(); + + const dispatch = useDispatch(); + + const formik = useFormik({ + initialValues: { + mobile: "", + fname: "", + lname: "", + nationalcode: "", + password: "", + birthday: moment(Date()).format("YYYY-MM-DD hh:mm:ss"), + }, + validationSchema: Yup.object({ + mobile: Yup.number() + .required("این فیلد اجباری است!") + .typeError("لطفا فیلد را به صورت عددی وارد کنید!") + .test("len", "شماره تلفن باید با 0 شروع شود", (val, context) => { + return context.originalValue && context.originalValue.startsWith("0"); + }) + .test("len", "شماره تماس 11 رقم باید باشد", (val, context) => { + if (context.originalValue) { + return context.originalValue.length === 11; + } + }), + fname: Yup.string() + .required("این فیلد اجباری است!") + .typeError("لطفا فیلد را پر کنید!"), + lname: Yup.string() + .required("این فیلد اجباری است!") + .typeError("لطفا فیلد را پر کنید!"), + nationalcode: Yup.number() + .required("این فیلد اجباری است!") + .test("len", "کد ملی میبایست ده رقم باشد.", (val, context) => { + if (context.originalValue) { + return context.originalValue.length === 10; + } + }), + password: Yup.string() + .required("این فیلد اجباری است!") + .typeError("لطفا مقادیر را به درستی وارد کنید!"), + }), + }); + + // const formikPoultry = useFormik({ + // initialValues: { + // uniqueID: "", + // poultryAddress: "", + // halls: "", + // systemCode: "", + // epidemiologicalCode: "", + // unitName: "", + // ownerName: "", + // capacity: "", + // licenseNumber: "", + // postal: "", + // }, + // validationSchema: Yup.object({ + // uniqueID: Yup.number() + // .required("این فیلد اجباری است!") + // .typeError("لطفا فیلد را به صورت عددی وارد کنید!"), + // poultryAddress: Yup.string() + // .required("این فیلد اجباری است!") + // .typeError("لطفا فیلد را به درستی وارد کنید!"), + // halls: Yup.number() + // .required("این فیلد اجباری است!") + // .typeError("لطفا فیلد را به صورت عددی وارد کنید!"), + // systemCode: Yup.string() + // .required("این فیلد اجباری است!") + // .typeError("لطفا فیلد را به درستی وارد کنید!"), + // epidemiologicalCode: Yup.string() + // .required("این فیلد اجباری است!") + // .typeError("لطفا فیلد را به صورت عددی وارد کنید!"), + // unitName: Yup.string() + // .required("این فیلد اجباری است!") + // .typeError("لطفا فیلد را به درستی وارد کنید!"), + // ownerName: Yup.string() + // .required("این فیلد اجباری است!") + // .typeError("لطفا فیلد را به درستی وارد کنید!"), + // capacity: Yup.number() + // .required("این فیلد اجباری است!") + // .typeError("لطفا فیلد را به صورت عددی وارد کنید!"), + // licenseNumber: Yup.number() + // .required("این فیلد اجباری است!") + // .typeError("لطفا فیلد را به صورت عددی وارد کنید!"), + // postal: Yup.number() + // .required("این فیلد اجباری است!") + // .typeError("لطفا فیلد را به صورت عددی وارد کنید!"), + // }), + // }); + + useEffect(() => { + formik.validateForm(); + formik2.validateForm(); + }, []); + + const formik2 = useFormik({ + initialValues: { + userInfoCheck: "", + }, + validationSchema: Yup.object({ + userInfoCheck: Yup.number() + .required("این فیلد اجباری است!") + .typeError("لطفا فیلد را به درستی وارد کنید!"), + }), + }); + + const [user, setUser] = React.useState(); + + const handleChange = () => { + if (user === "Poultry") { + setUser(""); + } else { + setUser("Poultry"); + } + }; + + useEffect(() => { + dispatch(LOADING_START()); + dispatch(cityGetProvinces())?.then((r) => { + dispatch(LOADING_END()); + setProvinceData(r.payload.data); + }); + }, []); + + useEffect(() => { + if (poultryProvinceKey) { + dispatch(LOADING_START()); + dispatch(cityGetCity(poultryProvinceKey)).then((r) => { + setCityData(r.payload.data); + setIsExistProvince(false); + dispatch(LOADING_END()); + }); + } else if (provinceKey) { + dispatch(LOADING_START()); + dispatch(cityGetCity(provinceKey)).then((r) => { + setCityData(r.payload.data); + setIsExistProvince(false); + dispatch(LOADING_END()); + }); + } + }, [provinceKey, poultryProvinceKey]); + + const [arr, setArr] = useState([ + { + id: 0, + uniqueID: "", + poultryAddress: "", + halls: "", + systemCode: "", + epidemiologicalCode: "", + unitName: "", + capacity: "", + licenseNumber: "", + postal: "", + bankName: "", + cardNumber: "", + accountNumber: "", + shabaNumber: "", + accountHolder: "", + }, + ]); + + const addInput = () => { + setArr((prevState) => { + return [ + ...prevState, + { + id: prevState.length, + uniqueID: "", + poultryAddress: "", + halls: "", + systemCode: "", + epidemiologicalCode: "", + unitName: "", + capacity: "", + licenseNumber: "", + postal: "", + bankName: "", + cardNumber: "", + accountNumber: "", + shabaNumber: "", + accountHolder: "", + }, + ]; + }); + }; + + const removeInput = () => { + const number = arr.length - 1; + + if (number !== 0) { + const filteredArrayPrice = arr.filter((object, i) => i < number); + // let filteredArrayTime = arrPrices.filter((object, i) => i < number); + + setArr(filteredArrayPrice); + // setArrPrices(filteredArrayTime); + } + }; + + const handleChangeArray = (e) => { + const [itemName, itemIndex] = e.target.name.split("-"); + if (itemName === "uniqueID") { + setArr((prevState) => { + const newState = prevState; + newState[itemIndex].uniqueID = e.target.value; + return newState; + }); + } else if (itemName === "poultryAddress") { + setArr((prevState) => { + const newState = prevState; + newState[itemIndex].poultryAddress = e.target.value; + return newState; + }); + } else if (itemName === "halls") { + setArr((prevState) => { + const newState = prevState; + newState[itemIndex].halls = Number(e.target.value); + return newState; + }); + } else if (itemName === "systemCode") { + setArr((prevState) => { + const newState = prevState; + newState[itemIndex].systemCode = Number(e.target.value); + return newState; + }); + } else if (itemName === "epidemiologicalCode") { + setArr((prevState) => { + const newState = prevState; + newState[itemIndex].epidemiologicalCode = Number(e.target.value); + return newState; + }); + } else if (itemName === "ownerName") { + setArr((prevState) => { + const newState = prevState; + newState[itemIndex].ownerName = e.target.value; + return newState; + }); + } else if (itemName === "unitName") { + setArr((prevState) => { + const newState = prevState; + newState[itemIndex].unitName = e.target.value; + return newState; + }); + } else if (itemName === "capacity") { + setArr((prevState) => { + const newState = prevState; + newState[itemIndex].capacity = Number(e.target.value); + return newState; + }); + } else if (itemName === "licenseNumber") { + setArr((prevState) => { + const newState = prevState; + newState[itemIndex].licenseNumber = Number(e.target.value); + return newState; + }); + } else if (itemName === "postal") { + setArr((prevState) => { + const newState = prevState; + newState[itemIndex].postal = Number(e.target.value); + return newState; + }); + } else if (itemName === "bankName") { + setArr((prevState) => { + const newState = prevState; + newState[itemIndex].bankName = e.target.value; + return newState; + }); + } else if (itemName === "cardNumber") { + setArr((prevState) => { + const newState = prevState; + newState[itemIndex].cardNumber = Number(e.target.value); + return newState; + }); + } else if (itemName === "accountNumber") { + setArr((prevState) => { + const newState = prevState; + newState[itemIndex].accountNumber = Number(e.target.value); + return newState; + }); + } else if (itemName === "shabaNumber") { + setArr((prevState) => { + const newState = prevState; + newState[itemIndex].shabaNumber = Number(e.target.value); + return newState; + }); + } else if (itemName === "accountHolder") { + setArr((prevState) => { + const newState = prevState; + newState[itemIndex].accountHolder = e.target.value; + return newState; + }); + } + }; + + return ( + + + {!userChecked && ( + <> + بررسی کاربر + + + + { + dispatch(LOADING_START()); + dispatch( + provinceCheckUserExistence({ + type: "check_user", + value: formik2.values.userInfoCheck, + }) + ).then((r) => { + dispatch(LOADING_END()); + if (r.error) { + if (r.error.message.includes("409")) { + openNotif({ + vertical: "top", + horizontal: "center", + msg: "کاربر پیدا نشد، یک کاربر جدید بسازید!", + severity: "error", + }); + } + } else { + if (r.payload.data) { + setUserData(r.payload.data.profile); + } else { + openNotif({ + vertical: "top", + horizontal: "center", + msg: "مشکلی پیش آمده است!", + severity: "error", + }); + + dispatch( + DRAWER({ + right: false, + bottom: false, + content: null, + }) + ); + } + } + }); + setUserChecked(true); + }} + > + + + + شماره موبایل با صفر شروع می‌شود! + + )} + + {userChecked && ( + <> + {userData ? ( + <> + + + prop.palette.grey["A700"]} + > + نام کامل: + + + {userData.fullname} + {" "} + + + + prop.palette.grey["A700"]} + > + موبایل: + + + {userData.mobile} + + + + + prop.palette.grey["A700"]} + > + استان: + + + {userData.province} + {" "} + + + + prop.palette.grey["A700"]} + > + شهر: + + + {userData.city} + + + + + prop.palette.grey["A700"]} + > + تاریخ تولد: + + + {formatJustDate(userData.birthday)} + + + {userData?.role.length > 0 && ( + + prop.palette.grey["A700"]} + > + {userData?.role?.length > 1 ? "نقش ها:" : "نقش:"} + + + + {userData?.role?.map((item, i) => { + let name = ""; + switch (item) { + case "ProvinceOperator": + name = "اپراتور تخصیص استان"; + break; + case "CityOperator": + name = "اپراتور شهرستان"; + break; + case "KillHouseVet": + name = "دامپزشک کشتارگاه"; + break; + case "Poultry": + name = "مرغدار"; + break; + case "KillHouse": + name = "کشتارگاه"; + break; + case "VetFarm": + name = "دامپزشک"; + break; + case "Vet": + name = "دامپزشک"; + break; + case "ProvinceInspector": + name = "بازرس استان"; + break; + case "ProvinceFinancial": + name = "اپراتور مالی"; + break; + case "Driver": + name = "راننده"; + break; + case "Admin": + name = "ادمین کل"; + break; + default: + break; + } + return [ + + + {name} + , + ]; + })} + + + )} + + {userData?.image?.length > 5 && ( + <> + + prop.palette.grey["A700"]} + > + پروفایل: + + + + img + + + + + )} + + + ) : ( + <> + + + + + + + + + + + } + value={formik.values.birthday} + error={ + formik.touched.birthday + ? Boolean(formik.errors.birthday) + : null + } + onChange={(e) => { + formik.setFieldValue( + "birthday", + moment(e).format("YYYY-MM-DD hh:mm:ss") + ); + }} + onBlur={formik.handleBlur} + helperText={ + formik.touched.birthday && Boolean(formik.errors.birthday) + ? formik.errors.birthday + : null + } + /> + + + ({ + id: i.key, + label: i.name, + }))} + onChange={(e, value) => { + setProvinceKey(value.id); + }} + renderInput={(params) => ( + + )} + /> + + + + ({ + id: i.key, + label: i.name, + }))} + onChange={(e, value) => { + setCityKey(value.id); + }} + renderInput={(params) => ( + + )} + /> + + + + + + + + + + + )} + + + {userData && ( + + {!userData.role.includes("Poultry") && ( + } + label="ثبت مرغداری برای این کاربر" + onChange={handleChange} + /> + )} + + )} + + {/* start of poultry ============================================================================= */} + + {arr.map((item, i) => { + return ( + <> + {user === "Poultry" && ( + <> + + + + + + + + ({ + id: i.key, + label: i.name, + }))} + onChange={(e, value) => { + setPoultryProvinceKey(value.id); + }} + renderInput={(params) => ( + + )} + /> + + + ({ + id: i.key, + label: i.name, + }))} + onChange={(e, value) => { + setPoultryCityKey(value.id); + }} + renderInput={(params) => ( + + )} + /> + + + + + + + + + + + + + + + + + {/* + + */} + + + + + + + + + + + + + + + + بانک + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + )} + + ); + })} + + {/* end of poultry ============================================================================= */} + + + + + + )} + + + ); +}; diff --git a/src/features/city/components/city-submit-hatching-report/CitySubmitHatchingReport.js b/src/features/city/components/city-submit-hatching-report/CitySubmitHatchingReport.js new file mode 100644 index 0000000..6ab275c --- /dev/null +++ b/src/features/city/components/city-submit-hatching-report/CitySubmitHatchingReport.js @@ -0,0 +1,192 @@ +import React, { useContext, useEffect, useState } from "react"; +import { Grid } from "../../../../components/grid/Grid"; +import { + Button, + FormControlLabel, + Switch, + TextField, + Typography, +} from "@mui/material"; +import { useFormik } from "formik"; +import { Yup } from "../../../../lib/yup/yup"; +import { useDispatch } from "react-redux"; +import { archiveHatchingService } from "../../services/archive-hatching"; +import { AppContext } from "../../../../contexts/AppContext"; +import { CLOSE_MODAL } from "../../../../lib/redux/slices/appSlice"; +import { FileUploader } from "../../../../components/file-uploader/FileUploader"; + +export const CitySubmitHatchingReport = ({ item, updateTable, isArchive }) => { + const [checked, setChecked] = useState(item?.violation); + const [sendToArchive, setSendToArchive] = useState(false); + const dispatch = useDispatch(); + const handleChange = (event) => { + setChecked(event.target.checked); + }; + const handleChangeArchive = (event) => { + setSendToArchive(event.target.checked); + }; + + const [openNotif] = useContext(AppContext); + + const [filesList, setFilesList] = useState([]); + + const hanleFilesChange = (e) => { + setFilesList(e); + }; + + const formik = useFormik({ + initialValues: { + reportText: item?.violationReport, + bar_image: "", + }, + validationSchema: Yup.object({ + reportText: Yup.string() + .required("این فیلد اجباری است!") + .typeError("لطفا گزارش خود را بیان کنید."), + bar_image: Yup.array(), + }), + }); + + useEffect(() => { + formik.validateForm(); + }, []); + + // const factorPaymentHandler = (imageList, addUpdateIndex) => { + // if (imageList[0]) { + // formik.setFieldValue( + // "bar_image", + // imageList.map((img) => fixBase64(img.data_url)) + // ); + // } + // setProfileImages(imageList); + // }; + + return ( + + + } + label={checked ? "متخلف" : "بدون تخلف"} + style={{ + justifyContent: "center", + alignItems: "center", + display: "flex", + }} + /> + {!isArchive && ( + + } + label={"انتقال به بایگانی"} + style={{ + justifyContent: "center", + alignItems: "center", + display: "flex", + }} + /> + )} + + + در صورت آپلود فایل جدید، سندهای پیشین حذف میشوند! + + + {/* */} + + + {/* {item?.violationImage?.length && !profileImages?.length && ( + <> + {item?.violationImage?.map((option, i) => ( + تصویر گزارش + ))} + + )} */} + + + + ); +}; diff --git a/src/features/city/components/city-submit-looses/CitySubmitLooses.js b/src/features/city/components/city-submit-looses/CitySubmitLooses.js new file mode 100644 index 0000000..4692a64 --- /dev/null +++ b/src/features/city/components/city-submit-looses/CitySubmitLooses.js @@ -0,0 +1,77 @@ +import React, { useContext } from "react"; +import { TextField, Button } from "@mui/material"; +import { Formik, Form, Field, ErrorMessage } from "formik"; +import * as Yup from "yup"; +import { useDispatch } from "react-redux"; +import { archiveHatchingService } from "../../services/archive-hatching"; +import { AppContext } from "../../../../contexts/AppContext"; +import { CLOSE_MODAL } from "../../../../lib/redux/slices/appSlice"; + +const validationSchema = Yup.object().shape({ + looses_amount: Yup.number() + .required("این فیلد اجباری است!") + .min(0, "عدد مثبت وارد کنید!"), +}); + +export const CitySubmitLooses = ({ updateTable, item }) => { + const dispatch = useDispatch(); + const [openNotif] = useContext(AppContext); + + const handleSubmit = (values, { resetForm }) => { + dispatch( + archiveHatchingService({ + key: item?.key, + direct_losses: values.looses_amount, + }) + ).then((r) => { + if (r.payload.error) { + openNotif({ + vertical: "top", + horizontal: "center", + msg: r.payload.error, + severity: "error", + }); + } else { + openNotif({ + vertical: "top", + horizontal: "center", + msg: "عملیات با موفقیت انجام شد.", + severity: "success", + }); + updateTable(); + dispatch(CLOSE_MODAL()); + } + }); + resetForm(); + }; + + return ( +
    + + {({ handleChange, handleBlur }) => ( +
    + } + /> + + + )} +
    +
    + ); +}; diff --git a/src/features/city/components/city-submit-tenant-form/CitySubmitTenantForm.js b/src/features/city/components/city-submit-tenant-form/CitySubmitTenantForm.js new file mode 100644 index 0000000..17acd91 --- /dev/null +++ b/src/features/city/components/city-submit-tenant-form/CitySubmitTenantForm.js @@ -0,0 +1,378 @@ +import { Autocomplete, Button, TextField } from "@mui/material"; +import { Grid } from "../../../../components/grid/Grid"; +import { SPACING } from "../../../../data/spacing"; +import React, { useEffect } from "react"; +import { Yup } from "../../../../lib/yup/yup"; +import { useFormik } from "formik"; +import { useState } from "react"; +import { useDispatch } from "react-redux"; +import { + DRAWER, + LOADING_END, + LOADING_START, +} from "../../../../lib/redux/slices/appSlice"; +import { cityGetProvinces } from "../../services/CityGetProvinces"; +import { cityGetCity } from "../../services/city-get-city"; +import { citySubmitNewTenant } from "../../services/city-submit-new-tenant"; +import { useContext } from "react"; +import { AppContext } from "../../../../contexts/AppContext"; +import { PropTypes } from "prop-types"; +import { provinceGetUserByKey } from "../../../province/services/province-get-user-by-key"; + +export const CitySubmitTenantForm = ({ id, userid }) => { + const [openNotif] = useContext(AppContext); + const dispatch = useDispatch(); + const [provinceData, setProvinceData] = useState(); + const [cityData, setCityData] = useState(); + const [provinceKey, setProvinceKey] = useState(); + const [cityKey, setCityKey] = useState(); + + const [isExistProvince, setIsExistProvince] = useState(true); + + const formik = useFormik({ + initialValues: { + mobile: "", + fname: "", + lname: "", + nationalcode: "", + address: "", + postal: "", + password: "", + uniqueID: "", + }, + validationSchema: Yup.object({ + mobile: Yup.number() + .required("این فیلد اجباری است!") + .typeError("لطفا فیلد را به صورت عددی وارد کنید!") + .test("len", "شماره تلفن باید با 0 شروع شود", (val, context) => { + return context.originalValue && context.originalValue.startsWith("0"); + }) + .test("len", "شماره تماس 11 رقم باید باشد", (val, context) => { + if (context.originalValue) { + return context.originalValue.length === 11; + } + }), + fname: Yup.string() + .required("این فیلد اجباری است!") + .typeError("لطفا فیلد را پر کنید!"), + lname: Yup.string() + .required("این فیلد اجباری است!") + .typeError("لطفا فیلد را پر کنید!"), + nationalcode: Yup.number() + .required("این فیلد اجباری است!") + .test("len", "کد ملی میبایست ده رقم باشد.", (val, context) => { + if (context.originalValue) { + return context.originalValue.length === 10; + } + }), + + address: Yup.string() + .required("این فیلد اجباری است!") + .typeError("لطفا فیلد را پر کنید!"), + postal: Yup.number() + .required("این فیلد اجباری است!") + .typeError("لطفا فیلد را به صورت عددی وارد کنید!"), + uniqueID: Yup.number() + .required("این فیلد اجباری است!") + .typeError("لطفا فیلد را به صورت عددی وارد کنید!"), + password: Yup.string() + .required("این فیلد اجباری است!") + .typeError("لطفا مقادیر را به درستی وارد کنید!") + .test( + "len", + "لطفا حداقل 5 حرف و حداکثر 12 حرف وارد کنید", + (val) => val.toString().length >= 5 && val.toString().length <= 12 + ), + }), + }); + + useEffect(() => { + formik.validateForm(); + }, []); + + useEffect(() => { + dispatch(LOADING_START()); + dispatch(cityGetProvinces())?.then((r) => { + dispatch(LOADING_END()); + setProvinceData(r.payload.data); + }); + }, []); + + useEffect(() => { + formik.validateForm(); + }, []); + + useEffect(() => { + if (provinceKey) { + dispatch(LOADING_START()); + dispatch(cityGetCity(provinceKey)).then((r) => { + setCityData(r.payload.data); + setIsExistProvince(false); + dispatch(LOADING_END()); + }); + } + }, [provinceKey]); + + return ( + + + + ({ id: i.key, label: i.name })) + : [] + } + onChange={(event, value) => { + setProvinceKey(value.id); + }} + renderInput={(params) => ( + + )} + /> + + + ({ id: i.key, label: i.name })) + : [] + } + onChange={(event, value) => { + setCityKey(value.id); + }} + renderInput={(params) => ( + + )} + /> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ); +}; + +CitySubmitTenantForm.propTypes = { + id: PropTypes.any, + userid: PropTypes.any, +}; diff --git a/src/features/city/components/city-tenant-owner-info/CityTenantOwnerInfo.js b/src/features/city/components/city-tenant-owner-info/CityTenantOwnerInfo.js new file mode 100644 index 0000000..a38dbdb --- /dev/null +++ b/src/features/city/components/city-tenant-owner-info/CityTenantOwnerInfo.js @@ -0,0 +1,64 @@ +import { Divider, List, ListItem, ListItemText } from "@mui/material"; +import React from "react"; +import { Grid } from "../../../../components/grid/Grid"; +import { PropTypes } from "prop-types"; + +export const CityTenantOwnerInfo = ({ item }) => { + return ( + <> + + + + + + + {" "} + + + + {" "} + + + + + + + {" "} + + + + + + + + + ); +}; + +CityTenantOwnerInfo.propTypes = { + item: PropTypes.object, +}; diff --git a/src/features/city/components/city-update-hatching/CityUpdateHatching.js b/src/features/city/components/city-update-hatching/CityUpdateHatching.js new file mode 100644 index 0000000..7f802ef --- /dev/null +++ b/src/features/city/components/city-update-hatching/CityUpdateHatching.js @@ -0,0 +1,180 @@ +import React, { useContext, useEffect, useState } from "react"; +import { styled } from "@mui/material/styles"; +import Button from "@mui/material/Button"; +import CloudUploadIcon from "@mui/icons-material/CloudUpload"; +import { Grid } from "../../../../components/grid/Grid"; +import { Typography } from "@mui/material"; +import { useDispatch } from "react-redux"; +import { cityUpdateHatchingService } from "../../services/city-update-hatching"; +import { AppContext } from "../../../../contexts/AppContext"; +import { SimpleTable } from "../../../../components/simple-table/SimpleTable"; +import { cityUpdateChickenBreedService } from "../../services/city-update-chicken-breen"; + +const VisuallyHiddenInput = styled("input")({ + clip: "rect(0 0 0 0)", + clipPath: "inset(50%)", + height: 1, + overflow: "hidden", + position: "absolute", + bottom: 0, + left: 0, + whiteSpace: "nowrap", + width: 1, +}); + +export const CityUpdateHatching = () => { + const dispatch = useDispatch(); + const [openNotif] = useContext(AppContext); + const [response, setResponse] = useState(); + const [tableData, setTableData] = useState(); + const handleFileUpload = async (event) => { + const file = event.target.files[0]; + if (!file) return; + + const formData = new FormData(); + formData.append("file", file); + + dispatch(cityUpdateHatchingService(formData)) + .unwrap() + .then((r) => { + setResponse(r.data); + if (r.status === 201) { + openNotif({ + vertical: "top", + horizontal: "center", + msg: "عملیات با موفقیت انجام شد.", + severity: "success", + }); + } else { + openNotif({ + vertical: "top", + horizontal: "center", + msg: "فایل اکسل به درستی ارسال نشده است!", + severity: "error", + }); + } + }); + }; + const handleUpdateChickenBreed = async (event) => { + const file = event.target.files[0]; + if (!file) return; + + const formData = new FormData(); + formData.append("file", file); + + dispatch(cityUpdateChickenBreedService(formData)) + .unwrap() + .then((r) => { + if (r.status === 201) { + openNotif({ + vertical: "top", + horizontal: "center", + msg: "عملیات با موفقیت انجام شد.", + severity: "success", + }); + } else { + openNotif({ + vertical: "top", + horizontal: "center", + msg: "فایل اکسل به درستی ارسال نشده است!", + severity: "error", + }); + } + }); + }; + useEffect(() => { + const d = response?.map((item, i) => { + return [i + 1, item]; + }); + setTableData(d); + }, [response]); + return ( + + = 800 && { + borderStyle: "solid", + borderWidth: "0px 0px 0px 1px", + borderColor: "gray", + } + } + > + + + آپدیت جوجه ریزی + + + + + + {response?.length ? ( + + + + ) : ( + <> + )} + + + + + + آپدیت نژاد + + + + + + + + ); +}; diff --git a/src/features/city/components/city-update-kill-request/CityUpdateKillRequest.js b/src/features/city/components/city-update-kill-request/CityUpdateKillRequest.js new file mode 100644 index 0000000..da2ed70 --- /dev/null +++ b/src/features/city/components/city-update-kill-request/CityUpdateKillRequest.js @@ -0,0 +1,111 @@ +import { Button, Grid } from "@mui/material"; +import { useFormik } from "formik"; +import { useContext, useEffect } from "react"; +import { useDispatch } from "react-redux"; +import { NumberInput } from "../../../../components/number-format-custom/NumberFormatCustom"; +import { AppContext } from "../../../../contexts/AppContext"; +import { CLOSE_MODAL } from "../../../../lib/redux/slices/appSlice"; +import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl"; +import { avicultureHatchingRequestsService } from "../../../aviculture/services/aviculture-hatching-requests"; +import { avicultureGetRequests } from "../../../aviculture/services/aviculture-requests"; +import { updateKillPoultryRequest } from "../../../province/services/update-kill-poultry-request"; +import { cityGetHatchings } from "../../services/city-get-hatchings"; +import { getSlaughtersKillRequestService } from "../../services/get-slaughters-kill-request"; + +export const CityUpdateKillRequest = ({ item, updateTable }) => { + const [openNotif] = useContext(AppContext); + const dispatch = useDispatch(); + const [, , selectedDate1, , selectedDate2] = useContext(AppContext); + + const formik = useFormik({ + initialValues: { + quantity: "", + }, + validate: (values) => { + const errors = {}; + + if (!values.quantity) { + errors.quantity = "Required"; + } else if (isNaN(values.quantity)) { + errors.quantity = "Must be a number"; + } + // else if ( + // values.quantity > item.process?.poultry?.poultryPreviousQuantity + // ) { + // errors.quantity = + // "Quantity cannot be greater than poultryPreviousQuantity"; + // } else if (0 >= item.process?.poultry?.poultryRemainQuantity) { + // errors.quantity = + // "Quantity cannot be greater than poultryPreviousQuantity"; + // } + + return errors; + }, + onSubmit: (values) => { + // console.log(values); + }, + }); + + useEffect(() => { + formik.validateForm(); + }, []); + + useEffect(() => { + formik.setFieldValue("quantity", item.quantity); + }, [item.quantity]); + + return ( + + + + + ); +}; diff --git a/src/features/city/components/city-user-file-info/CityUserFileInfo.js b/src/features/city/components/city-user-file-info/CityUserFileInfo.js new file mode 100644 index 0000000..37cfbf8 --- /dev/null +++ b/src/features/city/components/city-user-file-info/CityUserFileInfo.js @@ -0,0 +1,411 @@ +import { + Button, + FormControlLabel, + IconButton, + Switch, + Tooltip, + Typography, +} from "@mui/material"; +import React from "react"; +import { useEffect } from "react"; +import { useNavigate, useParams } from "react-router-dom"; +import NavigateNextIcon from "@mui/icons-material/NavigateNext"; +import { useDispatch, useSelector } from "react-redux"; +import { useState } from "react"; +import EditIcon from "@mui/icons-material/Edit"; +import InfoIcon from "@mui/icons-material/Info"; +import { + DRAWER, + LOADING_END, + LOADING_START, +} from "../../../../lib/redux/slices/appSlice"; +import { provinceGetUserByKey } from "../../../province/services/province-get-user-by-key"; +import { InspectorEditUserProfile } from "../../../inspector/components/inspector-edit-user-profile/InspectorEditUserProfile"; +import { Grid } from "../../../../components/grid/Grid"; +import { SPACING } from "../../../../data/spacing"; +import { SimpleTable } from "../../../../components/simple-table/SimpleTable"; +import { inspectorChangeUserState } from "../../../inspector/services/inspector-change-user-state"; +import { CitySubmitTenantForm } from "../city-submit-tenant-form/CitySubmitTenantForm"; +import { InspectorEditAviculture } from "../../../inspector/components/inspector-edit-aviculture/InspectorEditAviculture"; +import { format } from "date-fns-jalali"; + +// import { inspectorUpdateUserProfile } from "../../services/inspector-update-user-profile"; + +export const CityUserFileInfo = () => { + const { userid } = useParams(); + const dispatch = useDispatch(); + const navigate = useNavigate(); + const [dataTable, setDataTable] = useState([]); + const { provinceUserInfo } = useSelector((state) => state.provinceSlice); + + useEffect(() => { + dispatch(LOADING_START()); + dispatch(provinceGetUserByKey(userid)).then(() => { + dispatch(LOADING_END()); + }); + }, []); + + useEffect(() => { + const userRoles = provinceUserInfo?.profile.role?.map((item, i) => { + let name = ""; + switch (item) { + case "ProvinceOperator": + name = "اپراتور تخصیص استان"; + break; + case "CityOperator": + name = "اپراتور شهرستان"; + break; + case "KillHouseVet": + name = "دامپزشک کشتارگاه"; + break; + case "VetFarm": + name = "دامپزشک"; + break; + case "Poultry": + name = "مرغدار"; + break; + case "KillHouse": + name = "کشتارگاه"; + break; + case "Vet": + name = "دامپزشک"; + break; + case "ProvinceInspector": + name = "بازرس استان"; + break; + case "ProvinceFinancial": + name = "اپراتور مالی"; + break; + case "Driver": + name = "راننده"; + break; + case "Admin": + name = "ادمین"; + break; + default: + name = "کاربر پایه"; + break; + } + return
    {name}
    ; + }); + const userProfilePic = + provinceUserInfo?.profile?.image > 5 ? ( + + img + + ) : ( + "موجود نیست" + ); + const b = [ + [ + provinceUserInfo?.profile?.fullname + ? provinceUserInfo?.profile?.fullname + : provinceUserInfo?.profile?.firstName + + " " + + provinceUserInfo?.profile?.lastName, + userRoles, + provinceUserInfo?.profile?.mobile, + provinceUserInfo?.profile?.birthday + ? format(new Date(provinceUserInfo?.profile?.birthday), "yyyy/MM/dd") + : "نامشخص", + provinceUserInfo?.profile?.city, + + {provinceUserInfo?.profile?.password} + , + userProfilePic, + { + // dispatch(inspectorUpdateUserProfile()); + dispatch( + DRAWER({ + title: "ویرایش پروفایل کاربر", + right: !(window.innerWidth <= 600), + bottom: window.innerWidth <= 600, + content: ( + + ), + }) + ); + }} + > + + , + ], + ]; + + setDataTable(b); + }, [provinceUserInfo]); + + return ( + <> + + navigate(-1)} + > + + بازگشت + + + + + + + + + {provinceUserInfo?.rolesData?.map((item, i) => { + if (Object.keys(item).includes("Poultry")) { + return ( + <> + + { + dispatch( + DRAWER({ + title: "ویرایش اطلاعات مرغدار", + right: !(window.innerWidth <= 600), + bottom: window.innerWidth <= 600, + content: ( + + ), + }) + ); + }} + > + + + , + + { + dispatch(LOADING_START()); + dispatch( + inspectorChangeUserState({ + type: + item.Poultry.trash === true + ? "Activate" + : "Deactivate", + role_data_key: item.Poultry.key, + role: "Poultry", + }) + ).then((r) => { + dispatch(LOADING_END()); + window.location.reload(false); + }); + }} + /> + } + /> + , + ], + ]} + /> + + + {Object.keys(item.Poultry?.poultryTenant).length > 0 ? ( + + ) : ( + !item.Poultry.poultryOwner.length > 0 && ( + + + + مرغدار مستاجر ندارد + + + + ) + )} + + ); + } + return null; + })} + + + + + ); +}; diff --git a/src/features/city/components/city-users/CityUsers.js b/src/features/city/components/city-users/CityUsers.js new file mode 100644 index 0000000..ee8edac --- /dev/null +++ b/src/features/city/components/city-users/CityUsers.js @@ -0,0 +1,199 @@ +import { + Button, + Checkbox, + FormControlLabel, + IconButton, + Tooltip, + Typography, +} from "@mui/material"; +import { useState } from "react"; +import { useEffect } from "react"; +import { useDispatch, useSelector } from "react-redux"; + +import ContactPageIcon from "@mui/icons-material/ContactPage"; +import { useNavigate } from "react-router-dom"; +import { ROUTE_CITY_USER_FILE } from "../../../../routes/routes"; +import { + DRAWER, + LOADING_END, + LOADING_START, +} from "../../../../lib/redux/slices/appSlice"; +import { Grid } from "../../../../components/grid/Grid"; +import { SPACING } from "../../../../data/spacing"; +import { AdvancedTable } from "../../../../components/advanced-table/AdvancedTable"; +import { CitySubmitAviculture } from "../city-submit-aviculture/CitySubmitAviculture"; +import { cityGetUserProfiles } from "../../services/city-get-user-profiles"; + +export const CityUsers = () => { + const dispatch = useDispatch(); + const [dataTable, setDataTable] = useState([]); + const navigate = useNavigate(); + + const { cityUsers } = useSelector((state) => state.citySlice); + + useEffect(() => { + dispatch(LOADING_START()); + dispatch(cityGetUserProfiles()).then((r) => { + dispatch(LOADING_END()); + }); + }, []); + + const [justBaseUsers, setJustBaseUsers] = useState(false); + + const handleChange = (event) => { + setJustBaseUsers(!justBaseUsers); + }; + const [filteredData, setFilteredData] = useState(cityUsers); + + useEffect(() => { + if (justBaseUsers) { + const newUsers = cityUsers?.filter((item, i) => { + return item?.profile?.role.length === 0; + }); + setFilteredData(newUsers); + } else { + setFilteredData(cityUsers); + } + const d = filteredData?.map((item, i) => { + return [ + i + 1, + item?.profile?.fullname + ? item?.profile?.fullname + : item?.profile?.firstName + " " + item?.profile?.lastName, + + {!(item?.profile?.role.length > 0) && "کاربر پایه"} + {item?.profile?.role?.map((item, i) => { + var name = ""; + switch (item) { + case "ProvinceOperator": + name = "اپراتور تخصیص استان"; + break; + case "CityOperator": + name = "اپراتور شهرستان"; + break; + case "KillHouseVet": + name = "دامپزشک کشتارگاه"; + break; + case "VetFarm": + name = "دامپزشک"; + break; + case "Poultry": + name = "مرغدار"; + break; + case "KillHouse": + name = "کشتارگاه"; + break; + case "Vet": + name = "دامپزشک"; + break; + case "ProvinceInspector": + name = "بازرس استان"; + break; + case "ProvinceFinancial": + name = "اپراتور مالی"; + break; + case "Driver": + name = "راننده"; + break; + case "Admin": + name = "ادمین"; + break; + + default: + break; + } + return [{name}]; + })} + , + item?.profile?.mobile, + item?.profile?.baseOrder, + item?.profile?.city, + + {item?.profile?.password} + , + + + { + navigate(ROUTE_CITY_USER_FILE + item?.profile?.key); + }} + > + + + + , + ]; + }); + + setDataTable(d); + }, [cityUsers, justBaseUsers, filteredData]); + + return ( + + + + + + } + label="فقط نمایش کاربران پایه" + onChange={handleChange} + /> + + + + + + + + ); +}; diff --git a/src/features/city/components/city_manage-diffrence-killer-operation/CityManageDiffrenceKillerOperation.js b/src/features/city/components/city_manage-diffrence-killer-operation/CityManageDiffrenceKillerOperation.js new file mode 100644 index 0000000..5a880db --- /dev/null +++ b/src/features/city/components/city_manage-diffrence-killer-operation/CityManageDiffrenceKillerOperation.js @@ -0,0 +1,67 @@ +import { Grid } from "../../../../components/grid/Grid"; +import { SPACING } from "../../../../data/spacing"; +import { NavLink } from "../../../../components/nav-link/NavLink"; + +import LinkItem from "../../../../components/link-item/LinkItem"; +import { VscCompassDot } from "react-icons/vsc"; +import { IoIosArrowDropupCircle } from "react-icons/io"; +import { + ROUTE_ADMINX_DIFFRENCE_KILLER_SLAUGHTER, + ROUTE_ADMINX_INCREASE_HATCHING, + ROUTE_CITY_DIFFRENCE_KILLER_SLAUGHTER, + ROUTE_CITY_INCREASE_HATCHING, + ROUTE_PROVINCE_DIFFRENCE_KILLER_SLAUGHTER, + ROUTE_PROVINCE_INCREASE_HATCHING, + ROUTE_SUPER_ADMIN_DIFFRENCE_KILLER_SLAUGHTER, + ROUTE_SUPER_ADMIN_INCREASE_HATCHING, +} from "../../../../routes/routes"; +import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl"; + +export const CityManageDiffrenceKillerOperation = () => { + return ( + + + } + title="اختلاف کشتار در کشتارگاه" + /> + + + } + title="افزایش حجم جوجه ریزی" + /> + + + ); +}; diff --git a/src/features/city/components/natinal-info-details/NationalInfoDetails.js b/src/features/city/components/natinal-info-details/NationalInfoDetails.js new file mode 100644 index 0000000..e51fce2 --- /dev/null +++ b/src/features/city/components/natinal-info-details/NationalInfoDetails.js @@ -0,0 +1,45 @@ +import React, { useEffect, useState } from "react"; +import { Grid } from "../../../../components/grid/Grid"; + +import { AdvancedTable } from "../../../../components/advanced-table/AdvancedTable"; +import { CheckCleanceCode } from "../../../../components/check-clearance-code/ChechClearanceCode"; + +export const NationalInfoDetails = ({ data }) => { + const [tableData, setTableData] = useState([]); + + useEffect(() => { + const d = data?.bars?.map((item, i) => { + return [ + i + 1, + , + item?.IssueDatePersian, + item?.GoodAmount?.toLocaleString(), + item?.TrackingStatusDescription, + item?.GoodName, + item?.DesPartIdCode, + item?.DesUnitName, + item?.ResideDatePersian, + ]; + }); + setTableData(d); + }, [data]); + return ( + + + + ); +}; diff --git a/src/features/city/components/national-info-bars/NationalInfoTransports.js b/src/features/city/components/national-info-bars/NationalInfoTransports.js new file mode 100644 index 0000000..9ef1283 --- /dev/null +++ b/src/features/city/components/national-info-bars/NationalInfoTransports.js @@ -0,0 +1,394 @@ +import { Grid } from "../../../../components/grid/Grid"; +import React, { useContext, useEffect, useState } from "react"; +import { + Autocomplete, + Button, + Checkbox, + IconButton, + TextField, + Tooltip, +} from "@mui/material"; +import { DatePicker } from "@mui/x-date-pickers"; +import moment from "moment"; +import { useDispatch } from "react-redux"; +import axios from "axios"; +import { RiFileExcel2Fill, RiSearchLine } from "react-icons/ri"; +import { AppContext } from "../../../../contexts/AppContext"; +import { + LOADING_END, + LOADING_START, +} from "../../../../lib/redux/slices/appSlice"; +import ResponsiveTable from "../../../../components/responsive-table/ResponsiveTable"; +import { CheckCleanceCode } from "../../../../components/check-clearance-code/ChechClearanceCode"; +import { provinceNationalTransportManagementInfoDashboardService } from "../../../province/services/province-national-transport-managemant-info-dashboard-service"; +import { useParams } from "react-router-dom"; +import { getSamasatProvinces } from "../../../../utils/getSamasatProvinces"; +import { formatJustDate } from "../../../../utils/formatTime"; +import ToggleOffOutlinedIcon from "@mui/icons-material/ToggleOffOutlined"; +import ToggleOnIcon from "@mui/icons-material/ToggleOn"; + +export const NationalInfoTransports = () => { + const [, , selectedDate1, setSelectedDate1, selectedDate2, setSelectedDate2] = + useContext(AppContext); + const [selectedProvince, setSelectedProvince] = useState(""); + + const getProvince = () => { + if (key === undefined) { + return selectedProvince === "همه" ? "" : selectedProvince; + } else { + return key; + } + }; + + const getDashboardData = () => { + dispatch( + provinceNationalTransportManagementInfoDashboardService({ + date1: withDate ? selectedDate1 : null, + date2: withDate ? selectedDate2 : null, + search: textValue, + province: getProvince(), + PartIdCode: unitkey !== undefined ? unitkey : null, + }) + ).then((r) => { + setDashboardData(r.payload.data); + }); + }; + + const dispatch = useDispatch(); + useEffect(() => { + const currentDate = moment(new Date()).format("YYYY-MM-DD"); + setSelectedDate1(currentDate); + setSelectedDate2(currentDate); + }, []); + + const handleTextChange = (event) => { + setTextValue(event.target.value); + }; + const [data, setData] = useState([]); + const [totalRows, setTotalRows] = useState(0); + const [perPage, setPerPage] = useState(10); + const [textValue, setTextValue] = useState(""); + const [page, setPage] = useState(1); + const [tableData, setTableData] = useState([]); + const [withDate, setWithDate] = useState(true); + const [dashboardData, setDashboardData] = useState([]); + const { key, unitkey, name } = useParams(); + + const fetchApiData = async (page) => { + let response; + dispatch(LOADING_START()); + response = await axios.get( + `https://rsibackend.rasadyar.com/app/transporting-detail/?search=${textValue}${ + withDate ? `&date1=${selectedDate1}&date2=${selectedDate2}` : `` + }&page=${page}&page_size=${perPage}${ + unitkey !== undefined ? "&PartIdCode=" + unitkey : "" + }&province=${getProvince()}` + ); + dispatch(LOADING_END()); + getDashboardData(); + setData(response.data.results); + setTotalRows(response.data.count); + }; + + const handlePageChange = (page) => { + fetchApiData(page); + setPage(page); + }; + + const handlePerRowsChange = (perRows) => { + setPerPage(perRows); + setPage(1); + }; + + // const updateTable = () => { + // fetchApiData(page !== 0 ? page : 1); + // }; + + useEffect(() => { + const d = data?.map((item, i) => { + return [ + page === 1 ? i + 1 : i + perPage * (page - 1) + 1, + , + formatJustDate(item?.Date), + item?.DesUnitName, + item?.DesPartIdCode, + item?.Province, + item?.City, + item?.GoodAmount?.toLocaleString(), + item?.TrackingStatusDescription, + item?.Out ? "خارج استان" : "داخل استان", + item?.SourceUnitName, + item?.hatching?.poultry?.PartIdCode, + item?.hatching?.RequestCode, + item?.hatching?.poultry?.Province, + item?.hatching?.poultry?.City, + item?.Age, + item?.hatching?.PedigreeName, + // , + ]; + }); + + setTableData(d); + }, [data]); + + useEffect(() => { + fetchApiData(1); + }, [ + dispatch, + selectedDate1, + selectedDate2, + perPage, + withDate, + selectedProvince, + ]); + + const handleSubmit = async (event) => { + event.preventDefault(); + getDashboardData(); + dispatch(LOADING_START()); + + try { + const response = await axios.get( + `https://rsibackend.rasadyar.com/app/transporting-detail/?search=${textValue}${ + withDate ? `&date1=${selectedDate1}&date2=${selectedDate2}` : `` + }&page=${1}&page_size=${perPage}${ + unitkey !== undefined ? "&PartIdCode=" + unitkey : "" + }&province=${getProvince()}` + ); + setData(response.data.results); + setTotalRows(response.data.count); + dispatch(LOADING_END()); + } catch (error) { + console.error("Error fetching data:", error); + } + }; + + const getProvinceList = () => { + return [{ name: "همه" }, ...getSamasatProvinces()]; + }; + + return ( + + + {key === undefined && unitkey === undefined && name === undefined && ( + + { + return { + label: i.name, + }; + })} + onChange={(event, value) => { + if (value.label !== "همه") { + setSelectedProvince(value.label); + } else { + setSelectedProvince(""); + } + }} + renderInput={(params) => ( + + )} + /> + + )} + + + } + checkedIcon={} + checked={withDate} + onChange={() => setWithDate(!withDate)} + color="primary" + size="large" + /> + + ( + + )} + value={selectedDate1} + onChange={(e) => { + setSelectedDate1(moment(e).format("YYYY-MM-DD")); + }} + /> + + + ( + + )} + value={selectedDate2} + onChange={(e) => { + setSelectedDate2(moment(e).format("YYYY-MM-DD")); + }} + /> + + + +
    + + + +
    + + + + + + + +
    + + + + + +
    + ); +}; diff --git a/src/features/city/components/national-info-hatching-details/NationalInfoHatchingDetails.js b/src/features/city/components/national-info-hatching-details/NationalInfoHatchingDetails.js new file mode 100644 index 0000000..fb4efc0 --- /dev/null +++ b/src/features/city/components/national-info-hatching-details/NationalInfoHatchingDetails.js @@ -0,0 +1,284 @@ +import { Grid } from "../../../../components/grid/Grid"; +import React, { useContext, useEffect, useState } from "react"; +import { Button, Checkbox, FormControlLabel, TextField } from "@mui/material"; +import { DatePicker } from "@mui/x-date-pickers"; +import moment from "moment"; +import { useDispatch } from "react-redux"; +import axios from "axios"; +import { RiSearchLine } from "react-icons/ri"; +import { AppContext } from "../../../../contexts/AppContext"; +import { + LOADING_END, + LOADING_START, +} from "../../../../lib/redux/slices/appSlice"; +import ResponsiveTable from "../../../../components/responsive-table/ResponsiveTable"; +import { CheckCleanceCode } from "../../../../components/check-clearance-code/ChechClearanceCode"; +import { useParams } from "react-router-dom"; +import { formatJustDate } from "../../../../utils/formatTime"; +import { provinceNationalTransportManagementInfoDashboardService } from "../../../province/services/province-national-transport-managemant-info-dashboard-service"; + +export const NationalInfoHatchingDetails = () => { + const [, , selectedDate1, setSelectedDate1, selectedDate2, setSelectedDate2] = + useContext(AppContext); + + const getDashboardData = () => { + dispatch( + provinceNationalTransportManagementInfoDashboardService({ + date1: withDate ? selectedDate1 : null, + date2: withDate ? selectedDate2 : null, + search: textValue, + RequestCode: key, + }) + ).then((r) => { + setDashboardData(r.payload.data); + }); + }; + + const dispatch = useDispatch(); + useEffect(() => { + const currentDate = moment(new Date()).format("YYYY-MM-DD"); + setSelectedDate1(currentDate); + setSelectedDate2(currentDate); + }, []); + + const handleTextChange = (event) => { + setTextValue(event.target.value); + }; + const [data, setData] = useState([]); + const [totalRows, setTotalRows] = useState(0); + const [perPage, setPerPage] = useState(10); + const [textValue, setTextValue] = useState(""); + const [page, setPage] = useState(1); + const [tableData, setTableData] = useState([]); + const [withDate, setWithDate] = useState(false); + const [dashboardData, setDashboardData] = useState([]); + const { key, name } = useParams(); + + const fetchApiData = async (page) => { + dispatch(LOADING_START()); + const response = await axios.get( + `https://rsibackend.rasadyar.com/app/transporting-detail/?search=${textValue}${ + withDate ? `&date1=${selectedDate1}&date2=${selectedDate2}` : `` + }&page=${page}&page_size=${perPage}&RequestCode=${key}` + ); + dispatch(LOADING_END()); + getDashboardData(); + setData(response.data.results); + setTotalRows(response.data.count); + }; + + const handlePageChange = (page) => { + fetchApiData(page); + setPage(page); + }; + + const handlePerRowsChange = (perRows) => { + setPerPage(perRows); + setPage(1); + }; + + // const updateTable = () => { + // fetchApiData(page !== 0 ? page : 1); + // }; + + useEffect(() => { + const d = data?.map((item, i) => { + return [ + page === 1 ? i + 1 : i + perPage * (page - 1) + 1, + , + formatJustDate(item?.Date), + item?.DesUnitName, + item?.DesPartIdCode, + item?.Province, + item?.City, + item?.GoodAmount?.toLocaleString(), + item?.TrackingStatusDescription, + item?.Out ? "خارج استان" : "داخل استان", + item?.SourceUnitName, + item?.hatching?.poultry?.PartIdCode, + item?.hatching?.RequestCode, + item?.hatching?.poultry?.Province, + item?.hatching?.poultry?.City, + item?.Age, + item?.hatching?.PedigreeName, + ]; + }); + + setTableData(d); + }, [data]); + + useEffect(() => { + fetchApiData(1); + }, [dispatch, selectedDate1, selectedDate2, perPage, withDate]); + + const handleSubmit = async (event) => { + event.preventDefault(); + dispatch(LOADING_START()); + + try { + const response = await axios.get( + `https://rsibackend.rasadyar.com/app/transporting-detail/?search=${textValue}${ + withDate ? `&date1=${selectedDate1}&date2=${selectedDate2}` : `` + }&page=${1}&page_size=${perPage}&RequestCode=${key}` + ); + setData(response.data.results); + setTotalRows(response.data.count); + getDashboardData(); + dispatch(LOADING_END()); + } catch (error) { + console.error("Error fetching data:", error); + } + }; + + return ( + + + + + setWithDate(!withDate)} + color="primary" + /> + } + /> + + + ( + + )} + value={selectedDate1} + onChange={(e) => { + setSelectedDate1(moment(e).format("YYYY-MM-DD")); + }} + /> + + + ( + + )} + value={selectedDate2} + onChange={(e) => { + setSelectedDate2(moment(e).format("YYYY-MM-DD")); + }} + /> + + + +
    + + + +
    +
    + + + + + +
    + ); +}; diff --git a/src/features/city/components/national-info-hatchings/NationalInfoHatchings.js b/src/features/city/components/national-info-hatchings/NationalInfoHatchings.js new file mode 100644 index 0000000..a8e9df0 --- /dev/null +++ b/src/features/city/components/national-info-hatchings/NationalInfoHatchings.js @@ -0,0 +1,458 @@ +import { Grid } from "../../../../components/grid/Grid"; +import React, { useContext, useEffect, useState } from "react"; +import { + Autocomplete, + Button, + Checkbox, + IconButton, + Tab, + Tabs, + TextField, + Tooltip, +} from "@mui/material"; +import { DatePicker } from "@mui/x-date-pickers"; +import moment from "moment"; +import { useDispatch } from "react-redux"; +import axios from "axios"; +import { RiFileExcel2Fill, RiSearchLine } from "react-icons/ri"; +import { AppContext } from "../../../../contexts/AppContext"; +import { + LOADING_END, + LOADING_START, +} from "../../../../lib/redux/slices/appSlice"; +import ResponsiveTable from "../../../../components/responsive-table/ResponsiveTable"; +import { useParams } from "react-router-dom"; +import { formatJustDate } from "../../../../utils/formatTime"; +import { nationalInfoGetDashboardService } from "../../services/national-info-get-dashboard-info-service"; +import { getSamasatProvinces } from "../../../../utils/getSamasatProvinces"; +import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl"; +import { + ROUTE_ADMINX_ROUTE_NATIONAL_INFO, + ROUTE_PROVINCE_SUPERVISOR_ROUTE_NATIONAL_INFO, + ROUTE_SUPER_ADMIN_ROUTE_NATIONAL_INFO, +} from "../../../../routes/routes"; +import ToggleOffOutlinedIcon from "@mui/icons-material/ToggleOffOutlined"; +import ToggleOnIcon from "@mui/icons-material/ToggleOn"; +import VisibilityIcon from "@mui/icons-material/Visibility"; + +export const NationalInfoHatchings = () => { + const [, , selectedDate1, setSelectedDate1, selectedDate2, setSelectedDate2] = + useContext(AppContext); + const dispatch = useDispatch(); + useEffect(() => { + const currentDate = moment(new Date()).format("YYYY-MM-DD"); + setSelectedDate1(currentDate); + setSelectedDate2(currentDate); + }, []); + + const handleTextChange = (event) => { + setTextValue(event.target.value); + }; + + const [selectedProvince, setSelectedProvince] = useState(""); + + const { key } = useParams(); + + const [dashboardData, setDashboardData] = useState([]); + const [data, setData] = useState([]); + const [totalRows, setTotalRows] = useState(0); + const [perPage, setPerPage] = useState(10); + const [textValue, setTextValue] = useState(""); + const [page, setPage] = useState(1); + const [tableData, setTableData] = useState([]); + const [withDate, setWithDate] = useState(false); + const [value, setValue] = useState("0"); + + const handleChange = (event, newValue) => { + setValue(newValue); + }; + + const getDashboardData = () => { + dispatch( + nationalInfoGetDashboardService({ + date1: withDate ? selectedDate1 : null, + date2: withDate ? selectedDate2 : null, + search: textValue, + province: selectedProvince === "همه" ? "" : selectedProvince, + }) + ).then((r) => { + setDashboardData(r.payload.data); + }); + }; + + const fetchApiData = async (page) => { + let response; + dispatch(LOADING_START()); + response = await axios.get( + `https://rsibackend.rasadyar.com/app/hatchings/?search=${textValue}${ + withDate ? `&date1=${selectedDate1}&date2=${selectedDate2}` : `` + }&page=${page}&page_size=${perPage}&province=${ + key || selectedProvince ? selectedProvince : "" + }&state=${value === "0" ? "pending" : "archive"}` + ); + dispatch(LOADING_END()); + getDashboardData(); + setData(response.data.results); + setTotalRows(response.data.count); + }; + + const handlePageChange = (page) => { + fetchApiData(page); + setPage(page); + }; + + const handlePerRowsChange = (perRows) => { + setPerPage(perRows); + setPage(1); + }; + + // const updateTable = () => { + // fetchApiData(page !== 0 ? page : 1); + // }; + + useEffect(() => { + const d = data?.map((item, i) => { + return [ + page === 1 ? i + 1 : i + perPage * (page - 1) + 1, + item?.poultry?.Province || "-", + item?.poultry?.City || "-", + item?.poultry?.UnitName, + `${item?.poultry?.FirstName} ${item?.poultry?.LastName || ""}`, + item?.RequestCode, + item?.CertId, + item?.CapacityFemale?.toLocaleString(), + formatJustDate(item?.Date), + Math.floor(item?.Age), + item?.PedigreeName, + item?.ChickCountSum?.toLocaleString(), + item?.Period?.toLocaleString(), + item?.Evacuation?.toLocaleString(), + item?.info?.percentHatchingLicense?.toFixed(2), + item?.LeftOver?.toLocaleString(), + Math.floor(item?.KillingAve), + item?.info?.numberLoads?.toLocaleString(), + item?.info?.loadVolume?.toLocaleString(), + + + window.open( + getRoleFromUrl() === "AdminX" + ? `${ROUTE_ADMINX_ROUTE_NATIONAL_INFO}/${item.RequestCode}/${item?.poultry?.UnitName}` + : getRoleFromUrl() === "SuperAdmin" + ? `${ROUTE_SUPER_ADMIN_ROUTE_NATIONAL_INFO}/${item.RequestCode}/${item?.poultry?.UnitName}` + : `${ROUTE_PROVINCE_SUPERVISOR_ROUTE_NATIONAL_INFO}/${item.RequestCode}/${item?.poultry?.UnitName}`, + "_blank" + ) + } + > + + + , + ]; + }); + + setTableData(d); + }, [data]); + + useEffect(() => { + fetchApiData(1); + }, [ + dispatch, + selectedDate1, + selectedDate2, + perPage, + withDate, + value, + selectedProvince, + ]); + + const handleSubmit = async (event) => { + event.preventDefault(); + dispatch(LOADING_START()); + + try { + const response = await axios.get( + `https://rsibackend.rasadyar.com/app/hatchings/?search=${textValue}${ + withDate ? `&date1=${selectedDate1}&date2=${selectedDate2}` : `` + }&page=${1}&page_size=${perPage}&province=${ + key || selectedProvince ? selectedProvince : "" + }&state=${value === "0" ? "pending" : "archive"}` + ); + setData(response.data.results); + setTotalRows(response.data.count); + + dispatch(LOADING_END()); + getDashboardData(); + } catch (error) { + console.error("Error fetching data:", error); + } + }; + + const getProvinceList = () => { + return [{ name: "همه" }, ...getSamasatProvinces()]; + }; + + return ( + + + + + + + + + {!key && ( + + { + return { + label: i.name, + }; + })} + onChange={(event, value) => { + if (value.label !== "همه") { + setSelectedProvince(value.label); + } else { + setSelectedProvince(""); + } + }} + renderInput={(params) => ( + + )} + /> + + )} + +
    + + + +
    + + } + checkedIcon={} + checked={withDate} + onChange={() => setWithDate(!withDate)} + color="primary" + size="large" + /> + + ( + + )} + value={selectedDate1} + onChange={(e) => { + setSelectedDate1(moment(e).format("YYYY-MM-DD")); + }} + /> + + + ( + + )} + value={selectedDate2} + onChange={(e) => { + setSelectedDate2(moment(e).format("YYYY-MM-DD")); + }} + /> + + + + + + + +
    + + + + + + + +
    + ); +}; diff --git a/src/features/city/components/national-info/NationalInfo.js b/src/features/city/components/national-info/NationalInfo.js new file mode 100644 index 0000000..9b5fac0 --- /dev/null +++ b/src/features/city/components/national-info/NationalInfo.js @@ -0,0 +1,66 @@ +import React, { useState } from "react"; +import { Grid } from "../../../../components/grid/Grid"; +import { Tab, Tabs } from "@mui/material"; +import { NationalInfoHatchings } from "../national-info-hatchings/NationalInfoHatchings"; +import { NationalInfoTransports } from "../national-info-bars/NationalInfoTransports"; +// import { NationalinfokillingReport } from "../national-info-killing-report/NationalinfokillingReport"; +import NationalMap from "../national-map/NationalMap"; +import { ProvinceNationalInfoFarms } from "../../../province/components/province-national-info-farms/ProvinceNationalInfoFarms"; +import { ProvinceNationalInfoSlaughterhouse } from "../../../province/components/province-national-info-Slaughterhouse/ProvinceNationalInfoSlaughterhouse"; +import { ProvinceChickenDistributionsAndSales } from "../../../province/components/province-chicken-distribution-and-sales/ProvinceChickenDistributionsAndSales"; +import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl"; +import { ProvinceChickenStewardSales } from "../../../province/components/province-chicken-steward-sales/ProvinceChickenStewardSales"; +import { TotalCargoInformation } from "../../../province/components/total-cargo-information/TotalCargoInformation"; + +export const NationalInfo = () => { + const [value, setValue] = useState(0); + + const ableToSee = + getRoleFromUrl() === "AdminX" || + getRoleFromUrl() === "SuperAdmin" || + getRoleFromUrl() === "ProvinceOperator"; + + const handleChange = (event, newValue) => { + setValue(newValue); + }; + return ( + + + + + + + + + {ableToSee && } + {ableToSee && } + {ableToSee && } + + + + + {value === 0 && } + {value === 1 && } + {value === 2 && } + {value === 3 && } + {value === 4 && } + {value === 5 && } + {value === 6 && } + {value === 7 && } + + + ); +}; diff --git a/src/features/city/components/national-map/NationalMap.js b/src/features/city/components/national-map/NationalMap.js new file mode 100644 index 0000000..d4c16c3 --- /dev/null +++ b/src/features/city/components/national-map/NationalMap.js @@ -0,0 +1,142 @@ +import { useEffect, useState } from "react"; +import Grid from "@mui/material/Grid"; +import { useDispatch } from "react-redux"; +import { AllProvinceDetailsForMap } from "../../services/all-province-details-for-map"; +import NationalMapOverview from "./NationalMapOverview"; +import NationalMapGuidline from "./NationalMapGuidline"; + +import NationalMapSumTotal from "./NationalMapSumTotal"; + +import NationalMapRadioBtn from "./NationalMapRadioBtn"; +import ResponsiveTable from "../../../../components/responsive-table/ResponsiveTable"; +const NationalMap = () => { + const [tableData, setTableData] = useState([]); + const [percentageType, setPercentageType] = useState("hatching"); // hatching or active + const [provinceData, setProvinceData] = useState([]); + const dispatch = useDispatch(); + + const fetchTableData = () => { + dispatch(AllProvinceDetailsForMap()).then((r) => { + const data = r.payload?.data || []; + setProvinceData(data); + + // const sum = data.reduce((total, item) => { + // return total + (item?.totalQuantity || 0); + // }, 0); + + const d = data.map((item, i) => { + return [ + i + 1, + item?.provinceName || "", + item?.totalQuantity?.toLocaleString() || "0", + item?.totalKilledQuantity?.toLocaleString() || "0", + item?.totalLeftOver?.toLocaleString() || "0", + // sum.toLocaleString(), + `% ${item?.totalHatchingLeftOverPercent.toLocaleString()} `, + item?.totalActiveLeft.toLocaleString(), + ` % ${item?.totalActiveLeftPercent.toLocaleString()}`, + ]; + }); + + setTableData(d); + }); + }; + + useEffect(() => { + fetchTableData(); + }, []); + + const getColorByPercentage = (percent) => { + if (percent < 25) return "#F18989"; + if (percent < 50) return "#FF944D"; + if (percent < 75) return "#F4C430"; + return "#61D8BA"; + }; + + const provincePercentages = {}; + provinceData.forEach((item) => { + if (item?.provinceName && item?.totalHatchingLeftOverPercent) { + provincePercentages[item?.provinceName] = + item?.totalHatchingLeftOverPercent; + } + }); + + const getProvinceColor = (provinceName) => { + const province = provinceData.find((p) => p?.provinceName === provinceName); + if (!province) return "#B0B0B0"; + + const percent = + percentageType === "hatching" + ? province?.totalHatchingLeftOverPercent + : province?.totalActiveLeftPercent; + + return percent ? getColorByPercentage(percent) : "#B0B0B0"; + }; + + const handlePercentageTypeChange = (type) => { + setPercentageType(type); + }; + + return ( + + + + + + + + + + + + + + ); +}; + +export default NationalMap; diff --git a/src/features/city/components/national-map/NationalMapGuidline.js b/src/features/city/components/national-map/NationalMapGuidline.js new file mode 100644 index 0000000..111e884 --- /dev/null +++ b/src/features/city/components/national-map/NationalMapGuidline.js @@ -0,0 +1,142 @@ +import { Grid, Typography } from "@mui/material"; + +function NationalMapGuidline() { + return ( + + + + + کمتر از 25% + + + + + + + 25% تا 50% + + + + + + 50% تا 75% + + + + + + 75% تا 100% + + + + ); +} + +export default NationalMapGuidline; diff --git a/src/features/city/components/national-map/NationalMapOverview.js b/src/features/city/components/national-map/NationalMapOverview.js new file mode 100644 index 0000000..db48af7 --- /dev/null +++ b/src/features/city/components/national-map/NationalMapOverview.js @@ -0,0 +1,433 @@ +import Grid from "@mui/material/Grid"; +import { OPEN_MODAL } from "../../../../lib/redux/slices/appSlice"; +import { ProvinceNationalInfoOverview } from "../../../province/components/province-national-info-overview/ProvinceNationalInfoOverview"; +import { Tooltip, useMediaQuery, useTheme } from "@mui/material"; +import { useDispatch } from "react-redux"; + +function NationalMapOverview({ getProvinceColor }) { + const dispatch = useDispatch(); + const theme = useTheme(); + const isMobile = useMediaQuery(theme.breakpoints.down("md")); + const handleSelect = (event) => { + dispatch( + OPEN_MODAL({ + title: `نمای کلی استان ${event.target.parentNode?.id}`, + content: ( + + ), + }) + ); + }; + + return ( + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + {/* خزر */} + + + + + + + {/* خلیج */} + + + + + + {/* دریا */} + + + + + + + {/* دریاچه */} + + + + + + + {/* ارومیه */} + + + + + + +
    +
    + ); +} + +export default NationalMapOverview; diff --git a/src/features/city/components/national-map/NationalMapRadioBtn.js b/src/features/city/components/national-map/NationalMapRadioBtn.js new file mode 100644 index 0000000..f346187 --- /dev/null +++ b/src/features/city/components/national-map/NationalMapRadioBtn.js @@ -0,0 +1,40 @@ +import * as React from "react"; +import Radio from "@mui/material/Radio"; +import RadioGroup from "@mui/material/RadioGroup"; +import FormControlLabel from "@mui/material/FormControlLabel"; +import FormControl from "@mui/material/FormControl"; + +export default function NationalMapRadioBtn({ + onPercentageTypeChange, + selectedPercentageType, +}) { + const handleChange = (event) => { + onPercentageTypeChange(event.target.value); + }; + + return ( + + + } + label="مانده در سالن" + /> + } + label="آماده کشتار" + /> + + + ); +} diff --git a/src/features/city/components/national-map/NationalMapSumTotal.js b/src/features/city/components/national-map/NationalMapSumTotal.js new file mode 100644 index 0000000..12280e7 --- /dev/null +++ b/src/features/city/components/national-map/NationalMapSumTotal.js @@ -0,0 +1,173 @@ +import { useEffect, useState } from "react"; +import Grid from "@mui/material/Grid"; +import Typography from "@mui/material/Typography"; +import { useDispatch } from "react-redux"; +import { DashboardProvinceDetailsForMap } from "../../services/dashboard-province-details-for-map"; + +const NationalMapSumTotal = () => { + const [data, setData] = useState({ + totalQuantity: 0, + totalLeftOver: 0, + totalKilledQuantity: 0, + totalHatchingLeftOverPercent: 0, + totalActiveLeft: 0, + totalActiveLeftPercent: 0, + }); + const dispatch = useDispatch(); + + const fetchData = () => { + dispatch(DashboardProvinceDetailsForMap()).then((r) => { + if (r.payload?.data) { + setData(r.payload.data); + } + }); + }; + + useEffect(() => { + fetchData(); + }, []); + + return ( + + + + حجم کل جوجه ریزی: + + + {data?.totalQuantity.toLocaleString()} قطعه + + + + + حجم مانده در سالن: + + + {data?.totalLeftOver?.toLocaleString()} قطعه + + + + + حجم کل کشتار شده: + + + {data?.totalKilledQuantity.toLocaleString()} + + + + + + درصد مانده در سالن : + + + + + {data?.totalHatchingLeftOverPercent}% + + + + + + + درصد آماده کشتار: + + + + + {data.totalActiveLeftPercent}% + + + + + ); +}; + +export default NationalMapSumTotal; diff --git a/src/features/city/components/province-manage-selling-force-governmental-buy/ProvinceManageSellingForceGovernmentalBuy.js b/src/features/city/components/province-manage-selling-force-governmental-buy/ProvinceManageSellingForceGovernmentalBuy.js new file mode 100644 index 0000000..9563963 --- /dev/null +++ b/src/features/city/components/province-manage-selling-force-governmental-buy/ProvinceManageSellingForceGovernmentalBuy.js @@ -0,0 +1,293 @@ +import { + Button, + Switch, + TextField, + Typography, + Radio, + RadioGroup, + FormControlLabel, + FormControl, +} from "@mui/material"; +import DoneIcon from "@mui/icons-material/Done"; +import { useDispatch } from "react-redux"; +import { useContext, useState, useEffect } from "react"; +import { Grid } from "../../../../components/grid/Grid"; +import { AppContext } from "../../../../contexts/AppContext"; +import { SPACING } from "../../../../data/spacing"; +import { provincePolicyWagesEditKillhouse } from "../../../province/services/province-policy-wages-edit-killhouse"; + +export const ProvinceManageSellingForceGovernmentalBuy = ({ + item, + fetchdata, +}) => { + const dispatch = useDispatch(); + const [openNotif] = useContext(AppContext); + + const [state, setState] = useState({ + minimumSaleState: item?.quota || false, + quotaOption: item?.quotaMaxKillLimit + ? "max_kill_limit" + : item?.quotaRequest + ? "request" + : item?.quotaCustom + ? "custom" + : "", + qoutaCustomQuntity: item?.quotaCustomQuantity || 0, + percent: item?.governmentalQuota || 0, + }); + + const [errors, setErrors] = useState({ + percent: false, + qoutaCustomQuntity: false, + }); + + useEffect(() => { + if (!state.minimumSaleState) { + setState((prev) => ({ + ...prev, + quotaOption: "", + qoutaCustomQuntity: 0, + percent: 0, + })); + setErrors({ percent: false, qoutaCustomQuntity: false }); + } + }, [state.minimumSaleState]); + + const handleToggle = (key, value) => { + setState((prev) => ({ ...prev, [key]: value })); + }; + + const handleRadioChange = (event) => { + const newOption = event.target.value; + setState((prev) => ({ + ...prev, + quotaOption: newOption, + ...(newOption !== "custom" && { qoutaCustomQuntity: 0 }), + ...(newOption === "custom" && { percent: 0 }), + })); + setErrors({ percent: false, qoutaCustomQuntity: false }); + }; + + const handleInputChange = (field, value) => { + setState((prev) => ({ ...prev, [field]: value })); + setErrors((prev) => ({ ...prev, [field]: false })); + }; + + const validateForm = () => { + const newErrors = { + percent: false, + qoutaCustomQuntity: false, + }; + + if (state.minimumSaleState) { + if ( + (state.quotaOption === "max_kill_limit" || + state.quotaOption === "request") && + (!state.percent || state.percent <= 0 || state.percent > 100) + ) { + newErrors.percent = true; + } + + if ( + state.quotaOption === "custom" && + (!state.qoutaCustomQuntity || state.qoutaCustomQuntity <= 0) + ) { + newErrors.qoutaCustomQuntity = true; + } + } + + setErrors(newErrors); + return !Object.values(newErrors).some((error) => error); + }; + + const handleSubmit = () => { + if (!validateForm()) { + openNotif({ + vertical: "top", + horizontal: "center", + msg: "لطفاً مقادیر الزامی را به درستی وارد کنید", + severity: "error", + }); + return; + } + + dispatch( + provincePolicyWagesEditKillhouse({ + kill_house_key: item?.key, + quota: state.minimumSaleState, + quota_max_kill_limit: state.quotaOption === "max_kill_limit", + quota_request: state.quotaOption === "request", + quota_custom: state.quotaOption === "custom", + quota_custom_quantity: state.qoutaCustomQuntity, + governmental_quota: state.percent, + }) + ).then((r) => { + if (r.payload?.error) { + openNotif({ + vertical: "top", + horizontal: "center", + msg: r.payload.error, + severity: "error", + }); + } else { + openNotif({ + vertical: "top", + horizontal: "center", + msg: "تغییرات با موفقیت ذخیره شد", + severity: "success", + }); + fetchdata(); + } + }); + }; + + const isFormValid = () => { + if (!state.minimumSaleState) return true; + + if ( + state.quotaOption === "max_kill_limit" || + state.quotaOption === "request" + ) { + return state.percent > 0 && state.percent <= 100; + } + + if (state.quotaOption === "custom") { + return state.qoutaCustomQuntity > 0; + } + + return false; + }; + + return ( + + + + { + handleToggle("minimumSaleState", e.target.checked); + + if (!e.target.checked) { + dispatch( + provincePolicyWagesEditKillhouse({ + kill_house_key: item?.key, + quota: false, + quota_max_kill_limit: false, + quota_request: false, + quota_custom: false, + quota_custom_quantity: 0, + governmental_quota: 0, + }) + ).then((r) => { + if (r.payload?.error) { + openNotif({ + vertical: "top", + horizontal: "center", + msg: r.payload.error, + severity: "error", + }); + } else { + openNotif({ + vertical: "top", + horizontal: "center", + msg: "تغییرات با موفقیت ذخیره شد", + severity: "success", + }); + fetchdata(); + } + }); + } + }} + inputProps={{ + "aria-label": "in-province-selling-limitation-switch", + }} + /> + + + الزام به خرید دولتی + + + + {state.minimumSaleState && ( + + + + + } + label="بر اساس سقف کشتار" + /> + } + label="بر اساس اعلام نیازها" + /> + } + label="بر اساس حجم از سقف کشتار" + /> + + + + + {(state.quotaOption === "max_kill_limit" || + state.quotaOption === "request") && ( + + handleInputChange( + "percent", + Math.max(0, Math.min(100, e.target.value)) + ) + } + inputProps={{ min: 1, max: 100 }} + error={errors.percent} + helperText={errors.percent ? "درصد باید بین ۱ تا ۱۰۰ باشد" : ""} + /> + )} + + {state.quotaOption === "custom" && ( + + handleInputChange( + "qoutaCustomQuntity", + Math.max(0, e.target.value) + ) + } + inputProps={{ min: 1 }} + error={errors.qoutaCustomQuntity} + helperText={ + errors.qoutaCustomQuntity ? "حجم باید بزرگتر از صفر باشد" : "" + } + /> + )} + + + + )} + + ); +}; diff --git a/src/features/city/components/province-manage-selling-max-limitation/ProvinceManageSellingMaxLimitation.js b/src/features/city/components/province-manage-selling-max-limitation/ProvinceManageSellingMaxLimitation.js new file mode 100644 index 0000000..e43b10b --- /dev/null +++ b/src/features/city/components/province-manage-selling-max-limitation/ProvinceManageSellingMaxLimitation.js @@ -0,0 +1,125 @@ +import { Switch, TextField, Typography, Button } from "@mui/material"; +import DoneIcon from "@mui/icons-material/Done"; +import { useDispatch } from "react-redux"; +import { useContext, useState } from "react"; +import { Grid } from "../../../../components/grid/Grid"; +import { AppContext } from "../../../../contexts/AppContext"; +import { SPACING } from "../../../../data/spacing"; +import { provincePolicyWagesEditKillhouse } from "../../../province/services/province-policy-wages-edit-killhouse"; + +export const ProvinceManageSellingMaxLimitation = ({ item, fetchdata }) => { + const dispatch = useDispatch(); + const [openNotif] = useContext(AppContext); + + const [percent, setPercent] = useState( + item?.outProvinceSellingLimitationPercent + ); + const [minimumSaleState, setMinimumSaleState] = useState( + item?.outProvinceSellingLimitation + ); + + const handleToggle = (value) => { + dispatch( + provincePolicyWagesEditKillhouse({ + kill_house_key: item?.key, + out_province_selling_limitation: value, + out_province_selling_limitation_percent: value ? percent || 0 : 0, + }) + ).then((r) => { + setMinimumSaleState(value); + + if (r.payload?.error) { + openNotif({ + vertical: "top", + horizontal: "center", + msg: r.payload.error, + severity: "error", + }); + } else { + fetchdata(); + } + }); + }; + + const handleUpdatePercent = () => { + if (percent > 100 || percent < 1) { + openNotif({ + vertical: "top", + horizontal: "center", + msg: "درصد باید بین ۱ تا ۱۰۰ باشد.", + severity: "error", + }); + return; + } + + dispatch( + provincePolicyWagesEditKillhouse({ + kill_house_key: item?.key, + out_province_selling_limitation: true, + out_province_selling_limitation_percent: percent, + }) + ).then((r) => { + if (r.payload?.error) { + openNotif({ + vertical: "top", + horizontal: "center", + msg: r.payload.error, + severity: "error", + }); + } else { + fetchdata(); + } + }); + }; + + return ( + + + + handleToggle(e.target.checked)} + inputProps={{ + "aria-label": "in-province-selling-limitation-switch", + }} + /> + + + حداکثر فروش به خارج استان + + + + {minimumSaleState && ( + + + + { + setPercent(e.target.value); + }} + inputProps={{ min: 1, max: 100 }} + /> + + + + + + + )} + + ); +}; diff --git a/src/features/city/components/transport-chickens-details/TransportChickensDetails.js b/src/features/city/components/transport-chickens-details/TransportChickensDetails.js new file mode 100644 index 0000000..3f02656 --- /dev/null +++ b/src/features/city/components/transport-chickens-details/TransportChickensDetails.js @@ -0,0 +1,66 @@ +import React, { useContext, useEffect, useState } from "react"; +import { Grid } from "../../../../components/grid/Grid"; +import { useDispatch } from "react-redux"; +import { cityFetchSamasatTransportChickensDetails } from "../../../visors/services/fetch-samasat-transport-chickens"; +import { AdvancedTable } from "../../../../components/advanced-table/AdvancedTable"; +import { AppContext } from "../../../../contexts/AppContext"; + +export const TransportChickensDetails = ({ code, cookie }) => { + const dispatch = useDispatch(); + const [openNotif] = useContext(AppContext); + + const [tableData, setTableData] = useState([]); + + useEffect(() => { + dispatch( + cityFetchSamasatTransportChickensDetails({ + cookie, + certId: code, + }) + ).then((r) => { + if (r.error) { + openNotif({ + vertical: "top", + horizontal: "center", + msg: "کوکی معتبر نیست!", + severity: "error", + }); + } else { + const d = r.payload.data?.map((item, i) => { + return [ + i + 1, + item?.TrackingCode, + item?.ResideDatePersian, + item?.GoodAmount?.toLocaleString(), + item?.TrackingStatusDescription, + item?.GoodName, + item?.DesPartIdCode, + item?.DesUnitName, + item?.IssueDatePersian, + ]; + }); + setTableData(d); + } + }); + }, []); + + return ( + + + + ); +}; diff --git a/src/features/city/components/transport-chickens/TransportChickens.js b/src/features/city/components/transport-chickens/TransportChickens.js new file mode 100644 index 0000000..d633fbb --- /dev/null +++ b/src/features/city/components/transport-chickens/TransportChickens.js @@ -0,0 +1,131 @@ +import React, { useContext, useEffect, useState } from "react"; +import { IconButton, Tooltip } from "@mui/material"; +import { Grid } from "../../../../components/grid/Grid"; +import { useDispatch } from "react-redux"; +import RemoveRedEyeIcon from "@mui/icons-material/RemoveRedEye"; +import { + cityFetchSamasatTransportChickens, + visorsGetSamasatCookieService, +} from "../../../visors/services/fetch-samasat-transport-chickens"; +import { DRAWER, LOADING_END } from "../../../../lib/redux/slices/appSlice"; +import ResponsiveTable from "../../../../components/responsive-table/ResponsiveTable"; +import { TransportChickensDetails } from "../transport-chickens-details/TransportChickensDetails"; +import { AppContext } from "../../../../contexts/AppContext"; +import { useProvinceName } from "../../../../utils/getProvinceName"; + +export const TransportChickens = () => { + const [tableData, setTableData] = useState([]); + const [openNotif] = useContext(AppContext); + const [data, setData] = useState([]); + const dispatch = useDispatch(); + const province = useProvinceName(); + const [cookie, setCookie] = useState(); + + useEffect(() => { + dispatch(visorsGetSamasatCookieService()).then((r) => { + setCookie(r.payload.data.cookie); + dispatch( + cityFetchSamasatTransportChickens({ + cookie: r.payload.data.cookie, + province: + province === "hamedan" + ? "65550" + : province === "bushehr" + ? "65527" + : "65548", + }) + ).then((r) => { + dispatch(LOADING_END()); + if (r.error) { + openNotif({ + vertical: "top", + horizontal: "center", + msg: "کوکی معتبر نیست!", + severity: "error", + }); + } else { + setData(r.payload.data); + } + }); + }); + }, []); + + useEffect(() => { + const d = data?.map((item, i) => { + return [ + i + 1, + item?.LocationNameProvince, + item?.LocationNameCity, + item?.PersonFullName, + item?.PartIdCode, + item?.UnitName, + item?.EpidemiologicCode, + item?.PostalCode, + item?.CapacityFemale.toLocaleString(), + item?.RequestCode, + item?.SourceCertId, + item?.HatchingDatePersian, + item?.HatchingCount?.toLocaleString(), + item?.RemoveCount, + item?.RemoveCountTakhlie, + item?.RemovePartyCount, + + { + dispatch( + DRAWER({ + right: false, + top: true, + content: ( + + ), + title: "جزئیات حمل مرغ زنده", + }) + ); + }} + > + + + , + ]; + }); + + setTableData(d); + }, [data]); + + return ( + + + + + + ); +}; diff --git a/src/features/city/services/CityGetProvinces.js b/src/features/city/services/CityGetProvinces.js new file mode 100644 index 0000000..22386cf --- /dev/null +++ b/src/features/city/services/CityGetProvinces.js @@ -0,0 +1,13 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const cityGetProvinces = createAsyncThunk( + "CITY_GET_PROVINCES", + async (_, { dispatch }) => { + dispatch(LOADING_START()); + const { data, status } = await axios.get("province"); + dispatch(LOADING_END()); + return { data, status }; + } +); diff --git a/src/features/city/services/all-province-details-for-map.js b/src/features/city/services/all-province-details-for-map.js new file mode 100644 index 0000000..89320bb --- /dev/null +++ b/src/features/city/services/all-province-details-for-map.js @@ -0,0 +1,15 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const AllProvinceDetailsForMap = createAsyncThunk( + "ALL_PROVINCE_DETAIL_FOR_MAP", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + const { data, status } = await axios.get( + "https://rsibackend.rasadyar.com/app/all_province_detail_for_map/" + ); + dispatch(LOADING_END()); + return { data, status }; + } +); diff --git a/src/features/city/services/archive-avicalture-request.js b/src/features/city/services/archive-avicalture-request.js new file mode 100644 index 0000000..9728a43 --- /dev/null +++ b/src/features/city/services/archive-avicalture-request.js @@ -0,0 +1,18 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const archiveAvicaltureRequestService = createAsyncThunk( + "ARCHIVE_AVICALTURE_REQUEST_SERVICE", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + try { + const { data, status } = await axios.put("Poultry_Request/0/", d); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e.response.data.result }; + } + } +); diff --git a/src/features/city/services/archive-hatching.js b/src/features/city/services/archive-hatching.js new file mode 100644 index 0000000..b67a634 --- /dev/null +++ b/src/features/city/services/archive-hatching.js @@ -0,0 +1,18 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const archiveHatchingService = createAsyncThunk( + "ARCHIVE_HATCHING_SERVICE", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + try { + const { data, status } = await axios.put("poultry_hatching/0/", d); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e.response.data.result }; + } + } +); diff --git a/src/features/city/services/archive-old-hatchings.js b/src/features/city/services/archive-old-hatchings.js new file mode 100644 index 0000000..bd67d18 --- /dev/null +++ b/src/features/city/services/archive-old-hatchings.js @@ -0,0 +1,18 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const archiveOldHatchingsService = createAsyncThunk( + "ARCHIVE_OLD_HATCHINGS_SERVICE", + async (d, { dispatch }) => { + try { + dispatch(LOADING_START()); + const { data, status } = await axios.post("archive_hatching/", d); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e.response.data.result }; + } + } +); diff --git a/src/features/city/services/ciry-get-buyer.js b/src/features/city/services/ciry-get-buyer.js new file mode 100644 index 0000000..2cf6b69 --- /dev/null +++ b/src/features/city/services/ciry-get-buyer.js @@ -0,0 +1,9 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; + +export const cityGetBuyer = createAsyncThunk("CITY_GET_BUYER", async (d) => { + const { data, status } = await axios.get( + "https://artasystemback.rasadyaar.ir/api/find/?data=" + d + ); + return { data, status }; +}); diff --git a/src/features/city/services/city-delete-manage-hatching-renter.js b/src/features/city/services/city-delete-manage-hatching-renter.js new file mode 100644 index 0000000..5aa74b8 --- /dev/null +++ b/src/features/city/services/city-delete-manage-hatching-renter.js @@ -0,0 +1,18 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; +import axios from "axios"; + +export const cityHatchingDeleteRenterService = createAsyncThunk( + "CITY_HATCHING_DELETE_RENTER_SERVICE", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + try { + const { data, status } = await axios.put(`poultry_hatching/0/`, d); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e.response.data.result }; + } + } +); diff --git a/src/features/city/services/city-edit-avculture.info.js b/src/features/city/services/city-edit-avculture.info.js new file mode 100644 index 0000000..dda573b --- /dev/null +++ b/src/features/city/services/city-edit-avculture.info.js @@ -0,0 +1,13 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const cityEditAvicultureInfo = createAsyncThunk( + "CITY_EDIT_AVICULTURE_INFO", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + const { data, status } = await axios.put("/edit_poultry/0/", d); + dispatch(LOADING_END()); + return { data, status }; + } +); diff --git a/src/features/city/services/city-edit-hatching-quantity.js b/src/features/city/services/city-edit-hatching-quantity.js new file mode 100644 index 0000000..ac04e5f --- /dev/null +++ b/src/features/city/services/city-edit-hatching-quantity.js @@ -0,0 +1,18 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const cityEditHatchingQuantityService = createAsyncThunk( + "CITY_EDIT_HATCHING_QUANTITY_SERVICE", + async (d, { dispatch }) => { + try { + dispatch(LOADING_START()); + const { data, status } = await axios.put("poultry_hatching/0/", d); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e.response.data.result }; + } + } +); diff --git a/src/features/city/services/city-get-archive-hatchings.js b/src/features/city/services/city-get-archive-hatchings.js new file mode 100644 index 0000000..8571592 --- /dev/null +++ b/src/features/city/services/city-get-archive-hatchings.js @@ -0,0 +1,21 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; +import { getRoleFromUrl } from "../../../utils/getRoleFromUrl"; + +export const cityGetArchiveHatchingsService = createAsyncThunk( + "CITY_GET_ARCHIVE_HATCHINGS_SERVICE", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + const { data, status } = await axios.get("poultry_hatching/", { + params: { + archive: true, + role: getRoleFromUrl(), + date1: d.selectedDate1, + date2: d.selectedDate2, + }, + }); + dispatch(LOADING_END()); + return { data, status }; + } +); diff --git a/src/features/city/services/city-get-city.js b/src/features/city/services/city-get-city.js new file mode 100644 index 0000000..492b133 --- /dev/null +++ b/src/features/city/services/city-get-city.js @@ -0,0 +1,10 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; + +export const cityGetCity = createAsyncThunk( + "CITY_GET_PROVINCES", + async (key) => { + const { data, status } = await axios.get("city/?province_key=" + key); + return { data, status }; + } +); diff --git a/src/features/city/services/city-get-hatching-info-full.js b/src/features/city/services/city-get-hatching-info-full.js new file mode 100644 index 0000000..fc73bfa --- /dev/null +++ b/src/features/city/services/city-get-hatching-info-full.js @@ -0,0 +1,20 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { getRoleFromUrl } from "../../../utils/getRoleFromUrl"; + +export const cityGetHatchingInfoFull = createAsyncThunk( + "CITY_GET_HATCHING_INFO_FULL", + async (d = {}) => { + const { age1 = 0, age2 = 0 } = d; + const { data, status } = await axios.get( + `/hatching-for-dashboard/?type=total-dashboard&search=filter&value=${ + d?.textValue || "" + }&role=${getRoleFromUrl()}&age1=${age1}&age2=${age2}${ + d?.unknown ? `&unknown=true` : "" + }${d?.all ? `&all=true` : ""}${d?.tab ? `&tab=${d.tab}` : ""}&date1=${ + d?.date1 || "" + }&date2=${d?.date2 || ""}` + ); + return { data, status }; + } +); diff --git a/src/features/city/services/city-get-hatching-info.js b/src/features/city/services/city-get-hatching-info.js new file mode 100644 index 0000000..74787a8 --- /dev/null +++ b/src/features/city/services/city-get-hatching-info.js @@ -0,0 +1,23 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; +import { getRoleFromUrl } from "../../../utils/getRoleFromUrl"; + +export const cityGetHatchingInfo = createAsyncThunk( + "CITY_GET_HATCHING_INFO", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + const { data, status } = await axios.get( + "/hatching-for-dashboard/?type=date-dashboard", + { + params: { + date1: d.selectedDate1, + date2: d.selectedDate2, + role: getRoleFromUrl(), + }, + } + ); + dispatch(LOADING_END()); + return { data, status }; + } +); diff --git a/src/features/city/services/city-get-hatchings-by-age.js b/src/features/city/services/city-get-hatchings-by-age.js new file mode 100644 index 0000000..5133ba1 --- /dev/null +++ b/src/features/city/services/city-get-hatchings-by-age.js @@ -0,0 +1,21 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; +import { getRoleFromUrl } from "../../../utils/getRoleFromUrl"; + +export const cityGetHatchingsByAge = createAsyncThunk( + "CITY_GET_HATCHINGS_BY_AGE", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + const { data, status } = await axios.get("poultry_hatching/", { + params: { + chicken_age: true, + role: getRoleFromUrl(), + chicken_age1: d.selectedAge1, + chicken_age2: d.selectedAge2, + }, + }); + dispatch(LOADING_END()); + return { data, status }; + } +); diff --git a/src/features/city/services/city-get-hatchings.js b/src/features/city/services/city-get-hatchings.js new file mode 100644 index 0000000..d3405ea --- /dev/null +++ b/src/features/city/services/city-get-hatchings.js @@ -0,0 +1,20 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; +import { getRoleFromUrl } from "../../../utils/getRoleFromUrl"; + +export const cityGetHatchings = createAsyncThunk( + "CITY_GET_HATCHINGS", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + const { data, status } = await axios.get("poultry_hatching/", { + params: { + role: getRoleFromUrl(), + date1: d.selectedDate1, + date2: d.selectedDate2, + }, + }); + dispatch(LOADING_END()); + return { data, status }; + } +); diff --git a/src/features/city/services/city-get-poultries.js b/src/features/city/services/city-get-poultries.js new file mode 100644 index 0000000..f60b01a --- /dev/null +++ b/src/features/city/services/city-get-poultries.js @@ -0,0 +1,21 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; +import { getRoleFromUrl } from "../../../utils/getRoleFromUrl"; + +export const cityGetPoultriesService = createAsyncThunk( + "CITY_GET_POULTRIES_SERVICE", + async (_, { dispatch }) => { + const role = getRoleFromUrl(); + let obj = { role }; + if (role === "CityOperator" || role === "ProvinceOperator") { + obj = { role, active_hatching: true }; + } + dispatch(LOADING_START()); + const { data, status } = await axios.get("get-all-poultry/", { + params: obj, + }); + dispatch(LOADING_END()); + return { data, status }; + } +); diff --git a/src/features/city/services/city-get-poultry-data.js b/src/features/city/services/city-get-poultry-data.js new file mode 100644 index 0000000..a25b1d9 --- /dev/null +++ b/src/features/city/services/city-get-poultry-data.js @@ -0,0 +1,13 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const cityGetPoultryData = createAsyncThunk( + "CITY_GET_POULTRY_DATA", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + const { data, status } = await axios.get("Poultry/?type=filter&value=" + d); + dispatch(LOADING_END()); + return { data, status }; + } +); diff --git a/src/features/city/services/city-get-poultry-farms copy.js b/src/features/city/services/city-get-poultry-farms copy.js new file mode 100644 index 0000000..23d8eff --- /dev/null +++ b/src/features/city/services/city-get-poultry-farms copy.js @@ -0,0 +1,13 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const cityGetPoultryFarm = createAsyncThunk( + "CITY_GET_POULTRY_FARMS", + async (_, { dispatch }) => { + dispatch(LOADING_START()); + const { data, status } = await axios.get("Poultry/?operator=CityOperator"); + dispatch(LOADING_END()); + return { data, status }; + } +); diff --git a/src/features/city/services/city-get-poultry-farms.js b/src/features/city/services/city-get-poultry-farms.js new file mode 100644 index 0000000..23d8eff --- /dev/null +++ b/src/features/city/services/city-get-poultry-farms.js @@ -0,0 +1,13 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const cityGetPoultryFarm = createAsyncThunk( + "CITY_GET_POULTRY_FARMS", + async (_, { dispatch }) => { + dispatch(LOADING_START()); + const { data, status } = await axios.get("Poultry/?operator=CityOperator"); + dispatch(LOADING_END()); + return { data, status }; + } +); diff --git a/src/features/city/services/city-get-profile.js b/src/features/city/services/city-get-profile.js new file mode 100644 index 0000000..dfaaef3 --- /dev/null +++ b/src/features/city/services/city-get-profile.js @@ -0,0 +1,7 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; + +export const cityGetProfile = createAsyncThunk("CITY_GET_PROFILE", async () => { + const { data, status } = await axios.get("city_operator/0/?profile"); + return { data, status }; +}); diff --git a/src/features/city/services/city-get-province-info-map.js b/src/features/city/services/city-get-province-info-map.js new file mode 100644 index 0000000..7f2e847 --- /dev/null +++ b/src/features/city/services/city-get-province-info-map.js @@ -0,0 +1,19 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; + +export const cityGetProvinceInfoMap = createAsyncThunk( + "CITY_GET_PROVINCE_INFO_MAP", + async (d, { dispatch }) => { + const { data, status } = await axios.get( + "https://rsibackend.rasadyar.com/app/hatching-calculating/", + { + params: { + // city: d.city, + province: d.province, + }, + } + ); + + return { data, status }; + } +); diff --git a/src/features/city/services/city-get-ticket-different-clearance-code.js b/src/features/city/services/city-get-ticket-different-clearance-code.js new file mode 100644 index 0000000..1e01c33 --- /dev/null +++ b/src/features/city/services/city-get-ticket-different-clearance-code.js @@ -0,0 +1,22 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const cityGetTicketDiffrentClearanceCode = createAsyncThunk( + "CITY_GET_TICKET_DIFFRENT_CLEARANCE_CODE", + async ({ licence_number, mobile }, { dispatch }) => { + dispatch(LOADING_START()); + try { + const { data, status } = await axios.get( + `ticket_different_clearance_code_from_rsi/`, + { + params: { licence_number, mobile }, + } + ); + dispatch(LOADING_END()); + return { data, status }; + } catch (error) { + dispatch(LOADING_END()); + } + } +); diff --git a/src/features/city/services/city-get-user-profiles.js b/src/features/city/services/city-get-user-profiles.js new file mode 100644 index 0000000..9f6d22c --- /dev/null +++ b/src/features/city/services/city-get-user-profiles.js @@ -0,0 +1,10 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; + +export const cityGetUserProfiles = createAsyncThunk( + "PROVINCE_GET_USER_PROFILES", + async () => { + const { data, status } = await axios.get("system_user_profile/?city_users"); + return { data, status }; + } +); diff --git a/src/features/city/services/city-hatching-show-table-detail.js b/src/features/city/services/city-hatching-show-table-detail.js new file mode 100644 index 0000000..78a597a --- /dev/null +++ b/src/features/city/services/city-hatching-show-table-detail.js @@ -0,0 +1,20 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; +import axios from "axios"; + +export const cityHatchingShowTableDetail = createAsyncThunk( + "GET_CITY_HATCHING_SHOW_DETAIL_SERVICE", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + const { data, status } = await axios.get( + `hatching-detail/?key=${d.keyItem}`, + { + params: { + d, + }, + } + ); + dispatch(LOADING_END()); + return { data, status }; + } +); diff --git a/src/features/city/services/city-increase-hatching.js b/src/features/city/services/city-increase-hatching.js new file mode 100644 index 0000000..df4e2fb --- /dev/null +++ b/src/features/city/services/city-increase-hatching.js @@ -0,0 +1,66 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const cityIncreaseHatchingeService = createAsyncThunk( + "CITY_INCREASE_HATCHING_SERVICE", + async (d, { dispatch }) => { + try { + dispatch(LOADING_START()); + const { data, status } = await axios.post( + "hatching-increase-request/", + d + ); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e.response.data.result }; + } + } +); + +export const cityEditIncreaseHatchingeService = createAsyncThunk( + "CITY_EDIT_INCREASE_HATCHING_SERVICE", + async (d, { dispatch }) => { + try { + dispatch(LOADING_START()); + const { data, status } = await axios.put( + "hatching-increase-request/0/", + d + ); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e.response.data.result }; + } + } +); + +export const cityDeleteIncreaseHatchingeService = createAsyncThunk( + "CITY_DELETE_INCREASE_HATCHING_SERVICE", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + try { + const { data, status } = await axios.delete( + `/hatching-increase-request/0/?key=${d}` + ); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e.response.data.result }; + } + } +); + +export const cityIncreaseGetHatchingeService = createAsyncThunk( + "CITY_INCREASE_GET_HATCHING_SERVICE", + async (d) => { + const { data, status } = await axios.get("hatching-increase-request/", { + params: d, + }); + return { data, status }; + } +); diff --git a/src/features/city/services/city-submit-manage-hatching-renter.js b/src/features/city/services/city-submit-manage-hatching-renter.js new file mode 100644 index 0000000..c5f2da9 --- /dev/null +++ b/src/features/city/services/city-submit-manage-hatching-renter.js @@ -0,0 +1,13 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; +import axios from "axios"; + +export const citySubmitManageHatchingRenterService = createAsyncThunk( + "CITY_SUBMIT_MANAGE_HATCHING_RENTER_SERVICE", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + const { data, status } = await axios.put(`/poultry_hatching/0/`, d); + dispatch(LOADING_END()); + return { data, status }; + } +); diff --git a/src/features/city/services/city-submit-new-tenant.js b/src/features/city/services/city-submit-new-tenant.js new file mode 100644 index 0000000..ab5cb1c --- /dev/null +++ b/src/features/city/services/city-submit-new-tenant.js @@ -0,0 +1,13 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const citySubmitNewTenant = createAsyncThunk( + "CITY_NEW_TENANT", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + const { data, status } = await axios.post("api/newregister/", d); + dispatch(LOADING_END()); + return { data, status }; + } +); diff --git a/src/features/city/services/city-update-chicken-breen.js b/src/features/city/services/city-update-chicken-breen.js new file mode 100644 index 0000000..2ddc388 --- /dev/null +++ b/src/features/city/services/city-update-chicken-breen.js @@ -0,0 +1,21 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const cityUpdateChickenBreedService = createAsyncThunk( + "CITY_UPDATE_CHICKEN_BREED", + async (d, { dispatch }) => { + try { + dispatch(LOADING_START()); + const { data, status } = await axios.post( + "update_chicken_breed_from_excel/", + d + ); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e }; + } + } +); diff --git a/src/features/city/services/city-update-hatching.js b/src/features/city/services/city-update-hatching.js new file mode 100644 index 0000000..cd61aa3 --- /dev/null +++ b/src/features/city/services/city-update-hatching.js @@ -0,0 +1,18 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const cityUpdateHatchingService = createAsyncThunk( + "CITY_UPDATE_HATCHING", + async (d, { dispatch }) => { + try { + dispatch(LOADING_START()); + const { data, status } = await axios.post("hatching_excel/", d); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e }; + } + } +); diff --git a/src/features/city/services/dashboard-province-details-for-map.js b/src/features/city/services/dashboard-province-details-for-map.js new file mode 100644 index 0000000..ac237a3 --- /dev/null +++ b/src/features/city/services/dashboard-province-details-for-map.js @@ -0,0 +1,15 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const DashboardProvinceDetailsForMap = createAsyncThunk( + "DASHBOARD_PROVINCE_DETAILS_FOR_MAP", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + const { data, status } = await axios.get( + "https://rsibackend.rasadyar.com/app/dashboard_province_detail_for_map/" + ); + dispatch(LOADING_END()); + return { data, status }; + } +); diff --git a/src/features/city/services/get-hour-limit-kill-request-killhouse.js b/src/features/city/services/get-hour-limit-kill-request-killhouse.js new file mode 100644 index 0000000..ed67baa --- /dev/null +++ b/src/features/city/services/get-hour-limit-kill-request-killhouse.js @@ -0,0 +1,13 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const getHourLimitKillRequestKillhouseService = createAsyncThunk( + "GET_HOUR_LIMIT_KILL_REQUEST_KILLHOUSE_SERVICE", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + const { data, status } = await axios.get("kill_house_hour_limit/"); + dispatch(LOADING_END()); + return { data, status }; + } +); diff --git a/src/features/city/services/get-poultry-requests-total-quantity.js b/src/features/city/services/get-poultry-requests-total-quantity.js new file mode 100644 index 0000000..6cb9152 --- /dev/null +++ b/src/features/city/services/get-poultry-requests-total-quantity.js @@ -0,0 +1,19 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import moment from "moment/moment"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const getPoultryRequestsTotalQuantityService = createAsyncThunk( + "GET_POULTRY_REQUESTS_TOTAL_QUANTITY", + async (d, { dispatch }) => { + d = d || moment(new Date()).format("YYYY-MM-DD"); + dispatch(LOADING_START()); + const { data, status } = await axios.get( + "total_poultry_request_quantity/", + { params: { date: d } } + ); + dispatch(LOADING_END()); + + return { data, status }; + } +); diff --git a/src/features/city/services/get-slaughters-kill-request.js b/src/features/city/services/get-slaughters-kill-request.js new file mode 100644 index 0000000..7168cb2 --- /dev/null +++ b/src/features/city/services/get-slaughters-kill-request.js @@ -0,0 +1,21 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const getSlaughtersKillRequestService = createAsyncThunk( + "GET_SLAUGHTERS_KILL_REQUEST_SERVICE", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + const { data, status } = await axios.get( + "kill_request/?role=ProvinceOperator", + { + params: { + date1: d.selectedDate1, + date2: d.selectedDate2, + }, + } + ); + dispatch(LOADING_END()); + return { data, status }; + } +); diff --git a/src/features/city/services/hatching-undo-archive.js b/src/features/city/services/hatching-undo-archive.js new file mode 100644 index 0000000..bede4cb --- /dev/null +++ b/src/features/city/services/hatching-undo-archive.js @@ -0,0 +1,18 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const hatchingUndoArchiveService = createAsyncThunk( + "HATCHING_UNDO_ARCHIVE_SERVICE", + async (d, { dispatch }) => { + try { + dispatch(LOADING_START()); + const { data, status } = await axios.put("poultry_hatching/0/", d); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e.response.data.result }; + } + } +); diff --git a/src/features/city/services/hour-limit-get-kill-request.js b/src/features/city/services/hour-limit-get-kill-request.js new file mode 100644 index 0000000..734ea50 --- /dev/null +++ b/src/features/city/services/hour-limit-get-kill-request.js @@ -0,0 +1,13 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const hourLimitGetKillRequestService = createAsyncThunk( + "HOUR_LIMIT_GET_KILL_REQUEST_SERVICE", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + const { data, status } = await axios.get("hour_limit/"); + dispatch(LOADING_END()); + return { data, status }; + } +); diff --git a/src/features/city/services/hour-limit-kill-request-killhouse.js b/src/features/city/services/hour-limit-kill-request-killhouse.js new file mode 100644 index 0000000..d4ce022 --- /dev/null +++ b/src/features/city/services/hour-limit-kill-request-killhouse.js @@ -0,0 +1,13 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const hourLimitKillRequestKillhouseService = createAsyncThunk( + "HOUR_LIMIT_KILL_REQUEST_KILLHOUSE_SERVICE", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + const { data, status } = await axios.post("kill_house_hour_limit/", d); + dispatch(LOADING_END()); + return { data, status }; + } +); diff --git a/src/features/city/services/hour-limit-kill-request.js b/src/features/city/services/hour-limit-kill-request.js new file mode 100644 index 0000000..f895c3e --- /dev/null +++ b/src/features/city/services/hour-limit-kill-request.js @@ -0,0 +1,14 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const hourLimitKillRequestService = createAsyncThunk( + "HOUR_LIMIT_KILL_REQUEST_SERVICE", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + const { data, status } = await axios.post("hour_limit/", d); + dispatch(LOADING_END()); + + return { data, status }; + } +); diff --git a/src/features/city/services/national-info-get-dashboard-info-service.js b/src/features/city/services/national-info-get-dashboard-info-service.js new file mode 100644 index 0000000..535c30f --- /dev/null +++ b/src/features/city/services/national-info-get-dashboard-info-service.js @@ -0,0 +1,24 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const nationalInfoGetDashboardService = createAsyncThunk( + "NATIONAL_INFO_DASHBOARD", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + const { data, status } = await axios.get( + "https://rsibackend.rasadyar.com/app/hatchings-dashboard", + { + params: { + date1: d.date1, + date2: d.date2, + search: d.search, + province: d.province, + system_code: d.system_code, + }, + } + ); + dispatch(LOADING_END()); + return { data, status }; + } +); diff --git a/src/features/city/services/poultry-auto-request.js b/src/features/city/services/poultry-auto-request.js new file mode 100644 index 0000000..f42ecda --- /dev/null +++ b/src/features/city/services/poultry-auto-request.js @@ -0,0 +1,13 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const poultryAutoRequestService = createAsyncThunk( + "POULTRY_AUTO_REQUEST_SERVICE", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + const { data, status } = await axios.post("automatic_kill_request/", d); + dispatch(LOADING_END()); + return { data, status }; + } +); diff --git a/src/features/city/services/poultry-get-auto-request.js b/src/features/city/services/poultry-get-auto-request.js new file mode 100644 index 0000000..f89f564 --- /dev/null +++ b/src/features/city/services/poultry-get-auto-request.js @@ -0,0 +1,13 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const poultryGetAutoRequestService = createAsyncThunk( + "POULTRY_GET_AUTO_REQUEST_SERVICE", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + const { data, status } = await axios.get("automatic_kill_request/"); + dispatch(LOADING_END()); + return { data, status }; + } +); diff --git a/src/features/city/services/province-national-info-slughter-house-service.js b/src/features/city/services/province-national-info-slughter-house-service.js new file mode 100644 index 0000000..de7962b --- /dev/null +++ b/src/features/city/services/province-national-info-slughter-house-service.js @@ -0,0 +1,24 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const provinceNationalInfoSlaughterhouseGetDashboardService = + createAsyncThunk( + "PROVINCE-NATIONAL-INFO-SLAUGHTER-HOUSE-SERVICE", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + const { data, status } = await axios.get( + "https://rsibackend.rasadyar.com/app/dashboard_total_kill_house", + { + params: { + date1: d.date1, + date2: d.date2, + search: d.search, + province: d.province, + }, + } + ); + dispatch(LOADING_END()); + return { data, status }; + } + ); diff --git a/src/features/city/services/remove-avicalture-request.js b/src/features/city/services/remove-avicalture-request.js new file mode 100644 index 0000000..1aec0b0 --- /dev/null +++ b/src/features/city/services/remove-avicalture-request.js @@ -0,0 +1,18 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const removeAvicaltureRequestService = createAsyncThunk( + "REMOVE_AVICALTURE_REQUEST_SERVICE", + async (id, { dispatch }) => { + dispatch(LOADING_START()); + try { + const { data, status } = await axios.delete("Poultry_Request/" + id); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e.response.data.result }; + } + } +); diff --git a/src/features/city/services/update-poultry-requests-total-quantity.js b/src/features/city/services/update-poultry-requests-total-quantity.js new file mode 100644 index 0000000..1bf861d --- /dev/null +++ b/src/features/city/services/update-poultry-requests-total-quantity.js @@ -0,0 +1,17 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const updatePoultryRequestsTotalQuantityService = createAsyncThunk( + "UPDATE_POULTRY_REQUESTS_TOTAL_QUANTITY", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + const { data, status } = await axios.put( + "total_poultry_request_quantity/0/", + d + ); + dispatch(LOADING_END()); + + return { data, status }; + } +); diff --git a/src/features/commerce/components/commerce-operations/CommerceOperations.js b/src/features/commerce/components/commerce-operations/CommerceOperations.js new file mode 100644 index 0000000..5532705 --- /dev/null +++ b/src/features/commerce/components/commerce-operations/CommerceOperations.js @@ -0,0 +1,49 @@ +import { Grid } from "../../../../components/grid/Grid"; +import { SPACING } from "../../../../data/spacing"; +import { NavLink } from "../../../../components/nav-link/NavLink"; +import LinkItem from "../../../../components/link-item/LinkItem"; +import { FaFilePdf } from "react-icons/fa"; +import { useDispatch } from "react-redux"; +import PorvinceGetReportOperations from "../../../province/components/province-get-report-operations/PorvinceGetReportOperations"; +import { OPEN_MODAL } from "../../../../lib/redux/slices/appSlice"; + +export const CommerceOperations = () => { + const dispatch = useDispatch(); + return ( + + + + + dispatch( + OPEN_MODAL({ + title: "اطلاعات گزارش", + content: , + }) + ) + } + > + + } + title="گزارش روزانه" + description="گزارش روزانه" + /> + + + + + ); +}; diff --git a/src/features/commerce/components/guilds-operations-commerce/GuildsOperationsCommerce.js b/src/features/commerce/components/guilds-operations-commerce/GuildsOperationsCommerce.js new file mode 100644 index 0000000..9dbeb95 --- /dev/null +++ b/src/features/commerce/components/guilds-operations-commerce/GuildsOperationsCommerce.js @@ -0,0 +1,64 @@ +import { Grid } from "../../../../components/grid/Grid"; +import { SPACING } from "../../../../data/spacing"; +import { NavLink } from "../../../../components/nav-link/NavLink"; +import { + ROUTE_COMMERCE_ROUTE_GUILDS, + ROUTE_COMMERCE_ROUTE_GUILDS_SETTINGS, + ROUTE_COMMERCE_ROUTE_STEWARDS, + ROUTE_PROVINCE_SUPERVISOR_ROUTE_GUILDS, + ROUTE_PROVINCE_SUPERVISOR_ROUTE_GUILDS_SETTINGS, + ROUTE_PROVINCE_SUPERVISOR_ROUTE_STEWARDS, +} from "../../../../routes/routes"; +import LinkItem from "../../../../components/link-item/LinkItem"; +import { MdCorporateFare } from "react-icons/md"; +import { IoIosPeople } from "react-icons/io"; +import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl"; + +export const GuildsOperationsCommerce = () => { + return ( + + + } + title="اصناف" + /> + + + } + title="مباشرین" + /> + + + } + title="مدیریت فرآیند" + /> + + + ); +}; diff --git a/src/features/commerce/components/hatching-details/HatchingDetails.js b/src/features/commerce/components/hatching-details/HatchingDetails.js new file mode 100644 index 0000000..8dced9e --- /dev/null +++ b/src/features/commerce/components/hatching-details/HatchingDetails.js @@ -0,0 +1,35 @@ +import { useState } from "react"; +import { CityHatchingsArchive } from "../../../city/components/city-hatchings-archive/CityHatchingsArchive"; +import { CityHatchings } from "../../../city/components/city-hatchings/CityHatchings"; +import { Tab, Tabs } from "@mui/material"; +import { Grid } from "../../../../components/grid/Grid"; +import { CityHatchingInfo } from "../../../city/components/city-hatching-info/CityHatchingInfo"; + +export const HatchingDetails = () => { + const [value, setValue] = useState(0); + + const handleChange = (event, newValue) => { + setValue(newValue); + }; + return ( + + + + + + + + + + {value === 0 && } + {value === 1 && } + {value === 2 && } + + ); +}; diff --git a/src/features/dashboard/components/dashboard-allocation-with-out-bar/DashboardAllocationWithOutBar.js b/src/features/dashboard/components/dashboard-allocation-with-out-bar/DashboardAllocationWithOutBar.js new file mode 100644 index 0000000..6abc221 --- /dev/null +++ b/src/features/dashboard/components/dashboard-allocation-with-out-bar/DashboardAllocationWithOutBar.js @@ -0,0 +1,49 @@ +import { Box, Typography } from "@mui/material"; +import { SPACING } from "../../../../data/spacing"; + +export const DashboardAllocationWithOutBar = ({ boxStats }) => ( + + + تخصیصات بدون بار + + + + تعداد تخصیصات + + + {boxStats?.provinceKillRequestWithoutBar?.count?.toLocaleString() || 0} + + + + حجم تخصیصات(قطعه) + + + {boxStats?.provinceKillRequestWithoutBar?.quantity?.toLocaleString() || 0} + + + + وزن تخصیصات(کیلوگرم) + + + {boxStats?.provinceKillRequestWithoutBar?.indexWeight?.toLocaleString() || + 0}{" "} + کیلوگرم + + +); diff --git a/src/features/dashboard/components/dashboard-bar-chart-section/BarChartSection.js b/src/features/dashboard/components/dashboard-bar-chart-section/BarChartSection.js new file mode 100644 index 0000000..3752439 --- /dev/null +++ b/src/features/dashboard/components/dashboard-bar-chart-section/BarChartSection.js @@ -0,0 +1,145 @@ +import { Box, Typography } from "@mui/material"; +import { Bar } from "react-chartjs-2"; + +import { useRef, useEffect, useState } from "react"; +import { SPACING } from "../../../../data/spacing"; + +export const BarChartSection = ({ boxStats }) => { + const chartRef = useRef(null); + const [gradient, setGradient] = useState([]); + + useEffect(() => { + if (!chartRef.current) return; + + const chart = chartRef.current; + const ctx = chart.ctx; + const newGradient = []; + + const colors = [ + ["#FF6384", "#FF9FA8"], + ["#36A2EB", "#7BC1FF"], + ["#FFCE56", "#FFE39F"], + ["#4BC0C0", "#8CDFDF"], + ]; + + for (let i = 0; i < 4; i++) { + const grad = ctx.createLinearGradient(0, 0, 0, 300); + grad.addColorStop(0, colors[i][0]); + grad.addColorStop(1, colors[i][1]); + newGradient.push(grad); + } + + setGradient(newGradient); + }, []); + + const barChartData = { + labels: [ + "مانده انبار گوشت", + "مانده انبار سردخانه", + "کل وزن فروش به خارج استان", + "کل وزن توزیع داخل استان", + ], + datasets: [ + { + label: "وزن (کیلوگرم)", + data: [ + boxStats?.warehouseKillHouse?.remainingChickenStock || 0, + boxStats?.warehouseKillHouse?.remainingFreezingWeight || 0, + boxStats?.warehouseKillHouse?.outProvinceAllocatedWeight || 0, + boxStats?.warehouseKillHouse?.allocationWeight || 0, + ], + backgroundColor: gradient.length + ? gradient + : [ + "rgba(255, 99, 132, 0.7)", + "rgba(54, 162, 235, 0.7)", + "rgba(255, 206, 86, 0.7)", + "rgba(75, 192, 192, 0.7)", + ], + borderRadius: 12, + borderSkipped: false, + }, + ], + }; + + const barChartOptions = { + responsive: true, + maintainAspectRatio: false, + plugins: { + legend: { + display: false, + }, + tooltip: { + callbacks: { + label: (context) => { + return `${context.raw.toLocaleString()} کیلوگرم`; + }, + }, + }, + datalabels: { + display: false, + }, + }, + scales: { + y: { + beginAtZero: true, + ticks: { + display: false, + }, + grid: { + display: false, + }, + }, + x: { + grid: { + display: false, + }, + }, + }, + }; + + return ( + + + گزارش انبار کشتارگاه + + + + + + ); +}; diff --git a/src/features/dashboard/components/dashboard-buying-carcassess/DashboardBuyingCarcassess.js b/src/features/dashboard/components/dashboard-buying-carcassess/DashboardBuyingCarcassess.js new file mode 100644 index 0000000..5ae489c --- /dev/null +++ b/src/features/dashboard/components/dashboard-buying-carcassess/DashboardBuyingCarcassess.js @@ -0,0 +1,86 @@ +import { Box, Typography } from "@mui/material"; +import { SPACING } from "../../../../data/spacing"; + +export const DashboardBuyingCarcassess = ({ boxStats }) => ( + + + خرید لاشه خارج استان + + + + + تعداد بار : + + {boxStats?.buyFreeCarcasses?.count?.toLocaleString() || 0} + + + + حجم لاشه(قطعه) : + + {boxStats?.buyFreeCarcasses?.quantity?.toLocaleString() || 0} + + + + وزن لاشه(کیلوگرم) : + + {boxStats?.buyFreeCarcasses?.weight?.toLocaleString() || 0} + + + + +); diff --git a/src/features/dashboard/components/dashboard-daily-killing-report/DailyKillingReport .js b/src/features/dashboard/components/dashboard-daily-killing-report/DailyKillingReport .js new file mode 100644 index 0000000..baa9ff3 --- /dev/null +++ b/src/features/dashboard/components/dashboard-daily-killing-report/DailyKillingReport .js @@ -0,0 +1,109 @@ +import { Box, Typography } from "@mui/material"; +import { SPACING } from "../../../../data/spacing"; + +const reportItems = [ + { label: "حجم درخواست کشتار مرغدار:", key: "quantity" }, + { label: "وزن درخواست کشتار مرغدار:", key: "totalWeight" }, + { label: "حجم خرید های مستقیم :", key: "killRequestQuantity" }, + { label: "وزن خرید های مستقیم :", key: "killRequestWeight" }, + { + label: "حجم خرید های خارج از استان (زنده) :", + key: "quantityKillHouseFreeBarLive", + }, + { + label: "وزن خرید های خارج از استان (زنده) :", + key: "WeightKillHouseFreeBarLive", + }, + { + label: "وزن خرید های خارج از استان (لاشه) :", + key: "WeightKillHouseFreeBarCarcass", + }, + { + label: "حجم کل تخصیصات (خرید مستقیم/ مرغدار ):", + key: "provinceKillRequestQuantity", + }, + { + label: "وزن کل تخصیصات (خرید مستقیم/ مرغدار ):", + key: "provinceKillRequestWeightCarcass", + }, + { label: "حجم فروش به خارج استان:", key: "poultryOutProvinceQuantity" }, + { label: "وزن فروش به خارج استان:", key: "poultryOutProvinceWeight" }, + { label: "حجم بارها:", key: "KillHouseRequestQuantity" }, + { label: "وزن بارها:", key: "KillHouseRequestWeight" }, + { + label: "لاشه تولیدی امروز با احتساب 25درصد افت کشتار :", + key: "totalLossWeight", + }, +]; + +const ReportRow = ({ label, value }) => ( + + + {label} + + + {value?.toLocaleString() || 0} + + +); + +export const DailykillingReport = ({ boxStats }) => ( + + + گزارش کشتار امروز مرغ گوشتی استان + + + {reportItems.map((item) => ( + + ))} + + +); diff --git a/src/features/dashboard/components/dashboard-equivalent-tab/DashboardEquivalentTab.js b/src/features/dashboard/components/dashboard-equivalent-tab/DashboardEquivalentTab.js new file mode 100644 index 0000000..2265995 --- /dev/null +++ b/src/features/dashboard/components/dashboard-equivalent-tab/DashboardEquivalentTab.js @@ -0,0 +1,925 @@ +import React, { useContext, useEffect, useState } from "react"; +import { Grid } from "../../../../components/grid/Grid"; +import { DatePicker } from "@mui/x-date-pickers"; +import { AppContext } from "../../../../contexts/AppContext"; +import { useDispatch } from "react-redux"; +import moment from "moment"; +import { Button, Chip, TextField, Typography } from "@mui/material"; +import { RiSearchLine } from "react-icons/ri"; +import { dashboardGetEquivalentInfoService } from "../../services/dahsboard-get-equivalent-info"; +import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl"; +import ReactECharts from "echarts-for-react"; +import ResponsiveTable from "../../../../components/responsive-table/ResponsiveTable"; +import InfoIcon from "@mui/icons-material/Info"; +import { formatJustDate } from "../../../../utils/formatTime"; +import { + LOADING_END, + LOADING_START, +} from "../../../../lib/redux/slices/appSlice"; + +export const DashboardEquivalentTab = () => { + const [ + openNotif, + , + selectedDate1, + setSelectedDate1, + selectedDate2, + setSelectedDate2, + ] = useContext(AppContext); + const [textValue, setTextValue] = useState(""); + const [data, setData] = useState([]); + const [tableData, setTableData] = useState([]); + const [has500Error, setHas500Error] = useState(false); + + const dispatch = useDispatch(); + const colorScheme = { + rasad: "#5b5b9d", + quarantine: "#bf5757", + }; + + function subtractOneDay(dateString) { + if (!dateString) { + return ""; + } + try { + const date = new Date(dateString); + if (isNaN(date.getTime())) { + return ""; + } + date.setDate(date.getDate() - 1); + + const year = date.getFullYear(); + const month = String(date.getMonth() + 1).padStart(2, "0"); + const day = String(date.getDate()).padStart(2, "0"); + + return `${year}-${month}-${day}`; + } catch (error) { + console.error("Error subtracting one day:", error); + return ""; + } + } + + const staticLineChartData = { + data: + data && Array.isArray(data) + ? data.map((series) => series?.name || "").filter((name) => name) + : [], + series: [ + { + name: "رصدیار", + type: "line", + data: + data && Array.isArray(data) + ? data.map((itm) => { + const value = parseInt(itm?.info?.totalLiveBarsQuantity); + return isNaN(value) ? 0 : value; + }) + : [], + itemStyle: { color: "#5470c6" }, + }, + { + name: "قرنطینه", + type: "line", + data: + data && Array.isArray(data) + ? data.map((itm) => { + const value = parseInt( + itm?.info?.killHouseRsiInfo?.info?.totalWareHouse + ); + return isNaN(value) ? 0 : value; + }) + : [], + itemStyle: { color: "#fac858" }, + }, + ], + }; + + const staticDistributionLineChartData = { + data: + data && Array.isArray(data) + ? data.map((series) => series?.name || "").filter((name) => name) + : [], + series: [ + { + name: "رصدیار", + type: "line", + data: + data && Array.isArray(data) + ? data.map((itm) => { + const value = parseInt( + itm?.info?.totalKillHouseWarehouseCacassesEnteredWeight + ); + return isNaN(value) ? 0 : value; + }) + : [], + itemStyle: { color: "#5470c6" }, + }, + { + name: "قرنطینه", + type: "line", + data: + data && Array.isArray(data) + ? data.map((itm) => { + const value = parseInt( + itm?.info?.killHouseRsiInfo?.info?.totalBarsWight + ); + return isNaN(value) ? 0 : value; + }) + : [], + itemStyle: { color: "#fac858" }, + }, + ], + }; + + const getCarcassDate = () => { + if (!selectedDate1) { + return ""; + } + if (selectedDate1 === selectedDate2) { + return formatJustDate(subtractOneDay(selectedDate1)) || ""; + } else { + const date1 = formatJustDate(subtractOneDay(selectedDate1)) || ""; + const date2 = selectedDate2 + ? formatJustDate(subtractOneDay(selectedDate2)) || "" + : ""; + return `${date1} تا ${date2}`; + } + }; + + const barChartOption = { + title: { + text: `گزارش کل توزیع لاشه رصدیار و قرنطینه `, + textStyle: { + fontFamily: "iranyekan", + fontSize: 16, + }, + right: "center", + }, + tooltip: { + trigger: "axis", + axisPointer: { + type: "shadow", + }, + textStyle: { + fontFamily: "iranyekan", + fontSize: 12, + }, + backgroundColor: "rgba(255, 255, 255, 0.95)", + borderColor: "#ddd", + borderWidth: 1, + formatter: function (params) { + if (!params || !Array.isArray(params) || params.length === 0) { + return ""; + } + let result = `
    ${ + params[0]?.name || "" + }
    `; + params.forEach((param) => { + if (param) { + const value = + param.value !== undefined && param.value !== null + ? param.value.toLocaleString() + : "0"; + result += ` +
    + + ${param.seriesName || ""}: ${value} +
    + `; + } + }); + return result; + }, + }, + grid: { + left: "3%", + right: "4%", + bottom: "15%", + top: "15%", + containLabel: true, + }, + xAxis: { + type: "category", + data: + data && Array.isArray(data) + ? data.map((itm) => itm?.name || "").filter((name) => name) + : [], + axisLabel: { + fontFamily: "iranyekan", + }, + name: "کشتارگاه", + }, + yAxis: { + type: "value", + axisLabel: { + fontFamily: "iranyekan", + formatter: "{value}", + }, + name: "وزن", + }, + series: [ + { + name: "توزیع داخل استان (R)", + type: "bar", + data: + data && Array.isArray(data) + ? data.map((itm) => itm?.info?.totalKillHouseAllocationsWeight || 0) + : [], + itemStyle: { color: "#fac858" }, + emphasis: { focus: "series" }, + }, + { + name: "توزیع خارج استان (R)", + type: "bar", + data: + data && Array.isArray(data) + ? data.map((itm) => itm?.info?.totalKillHouseFreeSaleBarWeight || 0) + : [], + itemStyle: { color: "#c4a051" }, + emphasis: { focus: "series" }, + }, + { + name: "توزیع داخل استان (G)", + type: "bar", + data: + data && Array.isArray(data) + ? data.map((itm) => { + const value = parseInt( + itm?.info?.killHouseRsiInfo?.info?.totalInputBarsWight + ); + return isNaN(value) ? 0 : value; + }) + : [], + itemStyle: { color: "#5470c6" }, + emphasis: { focus: "series" }, + }, + { + name: "توزیع خارج استان (G)", + type: "bar", + data: + data && Array.isArray(data) + ? data.map((itm) => { + const value = parseInt( + itm?.info?.killHouseRsiInfo?.info?.totalOutputBarsWight + ); + return isNaN(value) ? 0 : value; + }) + : [], + itemStyle: { color: "#364982" }, + emphasis: { focus: "series" }, + }, + ], + }; + + const lineChartOption = { + title: { + text: `گزارش حجم کشتار زنده قرنطینه و رصدیار ${getCarcassDate()}`, + textStyle: { + fontFamily: "iranyekan", + fontSize: 16, + }, + right: "center", + }, + tooltip: { + trigger: "axis", + textStyle: { + fontFamily: "iranyekan", + }, + }, + grid: { + left: "3%", + right: "4%", + bottom: "15%", + top: "15%", + containLabel: true, + }, + xAxis: { + type: "category", + boundaryGap: false, + data: staticLineChartData.data, + axisLabel: { + fontFamily: "iranyekan", + }, + name: "کشتارگاه", + }, + yAxis: { + type: "value", + axisLabel: { + fontFamily: "iranyekan", + formatter: "{value}", + }, + name: "حجم", + }, + series: + staticLineChartData?.series && Array.isArray(staticLineChartData.series) + ? staticLineChartData.series.map((series) => ({ + ...series, + smooth: true, + lineStyle: { + width: 3, + }, + symbolSize: 8, + })) + : [], + }; + + const distributionLineChartOption = { + title: { + text: `گزارش کل توزیع لاشه رصدیار و قرنطینه`, + textStyle: { + fontFamily: "iranyekan", + fontSize: 16, + }, + right: "center", + }, + tooltip: { + trigger: "axis", + textStyle: { + fontFamily: "iranyekan", + }, + }, + grid: { + left: "3%", + right: "4%", + bottom: "15%", + top: "15%", + containLabel: true, + }, + xAxis: { + type: "category", + boundaryGap: false, + data: staticDistributionLineChartData.data, + axisLabel: { + fontFamily: "iranyekan", + }, + name: "کشتارگاه", + }, + yAxis: { + type: "value", + axisLabel: { + fontFamily: "iranyekan", + formatter: "{value}", + }, + name: "وزن", + }, + series: + staticDistributionLineChartData?.series && + Array.isArray(staticDistributionLineChartData.series) + ? staticDistributionLineChartData.series.map((series) => ({ + ...series, + smooth: true, + lineStyle: { + width: 3, + }, + symbolSize: 8, + })) + : [], + }; + + useEffect(() => { + const currentDate = moment(new Date()).format("YYYY-MM-DD"); + setSelectedDate1(currentDate); + setSelectedDate2(currentDate); + }, []); + + const handleTextChange = (event) => { + setTextValue(event.target.value); + }; + + useEffect(() => { + if (!data || !Array.isArray(data)) { + setTableData([]); + return; + } + + const safeParseInt = (value) => { + const parsed = parseInt(value); + return isNaN(parsed) ? 0 : parsed; + }; + + const safeToLocaleString = (value) => { + const parsed = safeParseInt(value); + return parsed.toLocaleString(); + }; + + const d = data.map((item, i) => { + const totalBarsWight = safeParseInt( + item?.info?.killHouseRsiInfo?.info?.totalBarsWight + ); + const totalWareHouse = safeParseInt( + item?.info?.killHouseRsiInfo?.info?.totalWareHouse + ); + const totalInputBarsWight = safeParseInt( + item?.info?.killHouseRsiInfo?.info?.totalInputBarsWight + ); + const totalOutputBarsWight = safeParseInt( + item?.info?.killHouseRsiInfo?.info?.totalOutputBarsWight + ); + const totalLiveBarsQuantity = safeParseInt( + item?.info?.totalLiveBarsQuantity + ); + const totalEnteredWarehouseBarsQuantity = safeParseInt( + item?.info?.totalEnteredWarehouseBarsQuantity + ); + const totalKillHouseWarehouseCacassesEnteredWeight = safeParseInt( + item?.info?.totalKillHouseWarehouseCacassesEnteredWeight + ); + const totalOutputWeight = safeParseInt(item?.info?.totalOutputWeight); + + return [ + i + 1, + item?.name || "", + safeToLocaleString(totalWareHouse), + safeToLocaleString(Math.floor(totalWareHouse * 2.6)), + safeToLocaleString(totalBarsWight), + totalBarsWight && totalWareHouse + ? "%" + + Math.floor((totalBarsWight * 100) / (totalWareHouse * 2.6 * 0.75)) + : 0, + safeToLocaleString(totalInputBarsWight), + totalInputBarsWight && totalBarsWight + ? "%" + ((totalInputBarsWight * 100) / totalBarsWight).toFixed(1) + : 0, + safeToLocaleString(totalOutputBarsWight), + totalOutputBarsWight && totalBarsWight + ? "%" + ((totalOutputBarsWight * 100) / totalBarsWight).toFixed(1) + : 0, + safeToLocaleString(totalLiveBarsQuantity), + safeToLocaleString( + item?.info?.totalKillHouseRequestGovernmentalQuantity + ), + safeToLocaleString(item?.info?.totalKillHouseRequestFreeQuantity), + safeToLocaleString(item?.info?.totalKillHouseFreeBarLiveTotalQuantity), + safeToLocaleString(totalEnteredWarehouseBarsQuantity), + totalEnteredWarehouseBarsQuantity && totalLiveBarsQuantity + ? "%" + + Math.floor( + (totalEnteredWarehouseBarsQuantity * 100) / totalLiveBarsQuantity + ) + : 0, + safeToLocaleString(item?.info?.totalEnteredWarehouseBarsWeight), + safeToLocaleString(totalKillHouseWarehouseCacassesEnteredWeight), + safeToLocaleString( + item?.info?.totalKillHouseWarehouseGovermentalCacassesEnteredWeight + ), + safeToLocaleString( + item?.info?.totalKillHouseWarehouseFreeCacassesEnteredWeight + ), + safeToLocaleString(totalOutputWeight), + totalOutputWeight && totalKillHouseWarehouseCacassesEnteredWeight + ? "%" + + Math.floor( + (totalOutputWeight * 100) / + totalKillHouseWarehouseCacassesEnteredWeight + ) + : 0, + safeToLocaleString(item?.info?.totalKillHouseAllocationsWeight), + safeToLocaleString(item?.info?.totalKillHouseFreeSaleBarWeight), + safeToLocaleString(item?.info?.totalOtherOutputWeight), + safeToLocaleString(item?.info?.totalRemainWeight), + safeToLocaleString(item?.info?.totalRemainFreeWeight), + safeToLocaleString(item?.info?.totalRemainGovernmentalWeight), + safeToLocaleString(item?.info?.lastTotalRemainWeight), + safeToLocaleString(item?.info?.lastTotalRemainGovernmentalWeight), + safeToLocaleString(item?.info?.lastTotalRemainFreeWeight), + ]; + }); + + setTableData(d); + }, [data]); + + useEffect(() => { + // Prevent request if there was a 500 error + if (has500Error) { + return; + } + + dispatch(LOADING_START()); + dispatch( + dashboardGetEquivalentInfoService({ + date1: selectedDate1, + date2: selectedDate2, + filter: "search", + value: textValue || null, + role: getRoleFromUrl(), + }) + ) + .then((r) => { + if (r?.error) { + const errorMessage = r.error?.message || ""; + const is500Error = + errorMessage.includes("500") || + r.error?.status === 500 || + r.error?.statusCode === 500; + + if (is500Error) { + setHas500Error(true); + openNotif({ + vertical: "top", + horizontal: "center", + msg: "مشکلی در دریافت اطلاعات پیش آمده است!", + severity: "error", + }); + } else { + openNotif({ + vertical: "top", + horizontal: "center", + msg: "مشکلی در دریافت اطلاعات پیش آمده است!", + severity: "error", + }); + } + setData([]); + } else if (r?.payload?.data) { + // Reset error state on successful response + setHas500Error(false); + setData(Array.isArray(r.payload.data) ? r.payload.data : []); + } else { + setData([]); + } + }) + .catch((error) => { + console.error("Error fetching equivalent info:", error); + const errorMessage = error?.message || ""; + const is500Error = + errorMessage.includes("500") || + error?.status === 500 || + error?.statusCode === 500; + + if (is500Error) { + setHas500Error(true); + openNotif({ + vertical: "top", + horizontal: "center", + msg: "مشکلی در دریافت اطلاعات پیش آمده است!", + severity: "error", + }); + } else { + openNotif({ + vertical: "top", + horizontal: "center", + msg: "مشکلی در دریافت اطلاعات پیش آمده است!", + severity: "error", + }); + } + setData([]); + }) + .finally(() => { + dispatch(LOADING_END()); + }); + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [dispatch, selectedDate1, selectedDate2, openNotif]); + + // Reset error state when dates change + useEffect(() => { + setHas500Error(false); + }, [selectedDate1, selectedDate2]); + + const handleSubmit = async (event) => { + event.preventDefault(); + // Reset error state on manual submit (user retry) + setHas500Error(false); + dispatch(LOADING_START()); + dispatch( + dashboardGetEquivalentInfoService({ + date1: selectedDate1, + date2: selectedDate2, + filter: "search", + value: textValue || null, + role: getRoleFromUrl(), + }) + ) + .then((r) => { + if (r?.error) { + const errorMessage = r.error?.message || ""; + const is500Error = + errorMessage.includes("500") || + r.error?.status === 500 || + r.error?.statusCode === 500; + + if (is500Error) { + setHas500Error(true); + openNotif({ + vertical: "top", + horizontal: "center", + msg: "مشکلی در دریافت اطلاعات پیش آمده است!", + severity: "error", + }); + } else { + openNotif({ + vertical: "top", + horizontal: "center", + msg: "مشکلی در دریافت اطلاعات پیش آمده است!", + severity: "error", + }); + } + setData([]); + } else if (r?.payload?.data) { + // Reset error state on successful response + setHas500Error(false); + setData(Array.isArray(r.payload.data) ? r.payload.data : []); + } else { + setData([]); + } + }) + .catch((error) => { + console.error("Error fetching equivalent info:", error); + const errorMessage = error?.message || ""; + const is500Error = + errorMessage.includes("500") || + error?.status === 500 || + error?.statusCode === 500; + + if (is500Error) { + setHas500Error(true); + openNotif({ + vertical: "top", + horizontal: "center", + msg: "مشکلی در دریافت اطلاعات پیش آمده است!", + severity: "error", + }); + } else { + openNotif({ + vertical: "top", + horizontal: "center", + msg: "مشکلی در دریافت اطلاعات پیش آمده است!", + severity: "error", + }); + } + setData([]); + }) + .finally(() => { + dispatch(LOADING_END()); + }); + }; + + return ( + + + + ( + + )} + value={selectedDate1} + onChange={(e) => { + setSelectedDate1(moment(e).format("YYYY-MM-DD")); + }} + /> + + + ( + + )} + value={selectedDate2} + onChange={(e) => { + setSelectedDate2(moment(e).format("YYYY-MM-DD")); + }} + /> + + +
    + + + +
    +
    + + + + + + + + + + + + + + ملاک حجم، قطعه و ملاک وزن، کیلوگرم میباشد. + + + + + + اطلاعات کشتار زنده مربوط به یک روز قبل ({getCarcassDate()}) می باشد. + + + + + + + + + + {barChartOption?.series?.map((itm, i) => ( + + + {itm?.name} + + + + ))} + + + + + + + {staticLineChartData?.series?.map((itm, i) => ( + + + {itm?.name} + + + + ))} + + + + + {staticDistributionLineChartData?.series?.map((itm, i) => ( + + + {itm?.name} + + + + ))} + + + {"‌‌‌ ‌"} +
    + ); +}; diff --git a/src/features/dashboard/components/dashboard-inventory-section/InventorySection.js b/src/features/dashboard/components/dashboard-inventory-section/InventorySection.js new file mode 100644 index 0000000..871d41f --- /dev/null +++ b/src/features/dashboard/components/dashboard-inventory-section/InventorySection.js @@ -0,0 +1,87 @@ +import { Box, Typography } from "@mui/material"; +import { SPACING } from "../../../../data/spacing"; + +const inventoryItems = [ + { + label: "حجم آماده کشتار بزرگتر از 40 روز (قطعه) :", + key: "leftOverBetweenFortySeventyFive", + }, + { + label: "وزن تقریبی کشتار بزرگتر از 40 روز (کیلوگرم) :", + key: "weightBetweenFortySeventyFive", + }, + { + label: "میانگین وزن مرغداری‌های آماده کشتار:", + key: "aveWeight", + suffix: " کیلوگرم", + }, + { label: "وزن گوشت قابل تولید:", key: "carcassWeight", suffix: " کیلوگرم" }, +]; + +const InventoryRow = ({ label, value, suffix = "" }) => ( + + + {label} + + + {value?.toLocaleString() || 0} + {suffix} + + +); + +export const InventorySection = ({ boxStats, sx }) => ( + + + موجودی + + + + {inventoryItems.map((item) => ( + + ))} + + +); diff --git a/src/features/dashboard/components/dashboard-killing-information/KillingInformation.js b/src/features/dashboard/components/dashboard-killing-information/KillingInformation.js new file mode 100644 index 0000000..63da1ae --- /dev/null +++ b/src/features/dashboard/components/dashboard-killing-information/KillingInformation.js @@ -0,0 +1,106 @@ +import { Box, Typography } from "@mui/material"; +import { SPACING } from "../../../../data/spacing"; + +export const KillingInformation = ({ boxStats }) => ( + + + اطلاعات کشتار داخل استان و خرید زنده خارج از استان + + + + + تعداد سفارشات: + + {boxStats?.killingInfo?.count?.toLocaleString() || 0} + + + + حجم کل کشتار (قطعه): + + {boxStats?.killingInfo?.quantity?.toLocaleString() || 0} + + + + وزن کل کشتار(کیلوگرم) : + + {boxStats?.killingInfo?.weight?.toLocaleString() || 0} + + + + + میانگین وزن (کیلوگرم): + + {boxStats?.killingInfo?.avgWeight?.toLocaleString() || 0} + + + + +); diff --git a/src/features/dashboard/components/dashboard-live-purchase/DashboardLivePurchase.js b/src/features/dashboard/components/dashboard-live-purchase/DashboardLivePurchase.js new file mode 100644 index 0000000..f4d4d4e --- /dev/null +++ b/src/features/dashboard/components/dashboard-live-purchase/DashboardLivePurchase.js @@ -0,0 +1,156 @@ +import { + Box, + Typography, + Avatar, + Card, + CardHeader, + CardContent, +} from "@mui/material"; +import { + LocalShipping, + Scale, + Numbers, + TrendingUp, + FitnessCenter, +} from "@mui/icons-material"; +import { SPACING } from "../../../../data/spacing"; +import { Grid } from "../../../../components/grid/Grid"; + +export const DashboardLivePurchase = ({ boxStats }) => { + const livePurchaseStats = [ + { + title: "تعداد بار زنده", + value: boxStats?.freeLiveBar?.count?.toLocaleString() || "0", + icon: , + }, + { + title: "حجم بار زنده", + value: `${boxStats?.freeLiveBar?.quantity?.toLocaleString() || "0"} قطعه`, + icon: , + }, + { + title: "وزن بار زنده", + value: `${ + boxStats?.freeLiveBar?.weight?.toLocaleString() || "0" + } کیلوگرم`, + icon: , + }, + { + title: "وزن لاشه بار", + value: `${ + boxStats?.freeLiveBar?.weightCarcass?.toLocaleString() || "0" + } کیلوگرم`, + icon: , + }, + { + title: "میانگین وزن", + value: `${ + boxStats?.freeLiveBar?.avgWeight?.toLocaleString() || "0" + } کیلوگرم`, + icon: , + }, + ]; + + return ( + + + خرید زنده خارج از استان + + + + {livePurchaseStats.map((stat, index) => ( + + + + + {stat.icon} + + + + + + {stat.title} + + + {stat.value} + + + + + ))} + + + ); +}; diff --git a/src/features/dashboard/components/dashboard-periodic-performance/DashboardPeriodicPerformance.js b/src/features/dashboard/components/dashboard-periodic-performance/DashboardPeriodicPerformance.js new file mode 100644 index 0000000..4ce4a03 --- /dev/null +++ b/src/features/dashboard/components/dashboard-periodic-performance/DashboardPeriodicPerformance.js @@ -0,0 +1,1385 @@ +import { useContext, useEffect, useState } from "react"; +import { AppContext } from "../../../../contexts/AppContext"; +import { Button, TextField, Tooltip, Typography } from "@mui/material"; +import { Grid } from "../../../../components/grid/Grid"; +import { DatePicker } from "@mui/x-date-pickers"; +import moment from "moment"; +import { useDispatch } from "react-redux"; +import { dashboardGetSlaughterPeriodicPerformance } from "../../services/dashboard-slaughter-periodic-performance"; +import farmIcon1 from "../../../../assets/images/dashboard/farmIcon1.png"; +import farmIcon2 from "../../../../assets/images/dashboard/farmIcon2.png"; +import farmIcon4 from "../../../../assets/images/dashboard/farmIcon4.png"; +import farmIcon6 from "../../../../assets/images/dashboard/farmIcon6.png"; +import farmIcon7 from "../../../../assets/images/dashboard/farmIcon7.png"; +import farmIcon8 from "../../../../assets/images/dashboard/farmIcon8.png"; +import killedInProvinceIcon1 from "../../../../assets/images/dashboard/killedInProvinceIcon1.png"; +import killedInProvinceIcon2 from "../../../../assets/images/dashboard/killedInProvinceIcon2.png"; +import killedInProvinceIcon3 from "../../../../assets/images/dashboard/killedInProvinceIcon3.png"; +import iconLeft from "../../../../assets/images/dashboard/iconLeft.png"; +import iconRight from "../../../../assets/images/dashboard/iconRight.png"; +import buyerPerformanceIcon from "../../../../assets/images/dashboard/buyerPerformanceIcon.png"; +import warningIcon from "../../../../assets/images/dashboard/warningIcon.png"; +import { SPACING } from "../../../../data/spacing"; +import { SimpleTable } from "../../../../components/simple-table/SimpleTable"; +import { LinearProgress } from "@mui/material"; +import { ImFilePdf } from "react-icons/im"; +import axios from "axios"; + +export const DashboardPeriodicPerformance = () => { + const dispatch = useDispatch(); + const [, , selectedDate1, setSelectedDate1, selectedDate2, setSelectedDate2] = + useContext(AppContext); + const [data, setData] = useState({}); + + useEffect(() => { + dispatch( + dashboardGetSlaughterPeriodicPerformance({ + date1: selectedDate1, + date2: selectedDate2, + }) + ).then((r) => { + if (r.payload?.data) { + setData(r.payload.data); + } + }); + }, [dispatch, selectedDate1, selectedDate2]); + + const reportCards = [ + { + title: "تعداد ", + + key: (data) => + `${data?.poultryHatchingGt60?.toLocaleString() || "0"} فارم`, + }, + { + title: "حجم ", + + key: (data) => + `${data?.poultryHatchingGt60Quantity?.toLocaleString() || "0"} قطعه`, + }, + { + title: "مانده در سالن", + + key: (data) => + `${data?.poultryHatchingGt60LeftOver?.toLocaleString() || "0"} قطعه (${ + ( + (data?.poultryHatchingGt60LeftOver / + data?.poultryHatchingGt60Quantity) * + 100 || 0 + ).toFixed(0) || 0 + }%)`, + }, + ]; + + const reportBarKilledInProvince = [ + { + title: "تعداد بارها", + icon: killedInProvinceIcon1, + key: (data) => + `${data?.killHouseRequestCount?.toLocaleString() || 0} بار`, + }, + { + title: "حجم کشتار", + icon: killedInProvinceIcon2, + key: (data) => + `${data?.killHouseRequestQuantity?.toLocaleString() || 0} قطعه`, + }, + { + title: "وزن کشتار", + icon: killedInProvinceIcon1, + key: (data) => + `${data?.killHouseRequestWeight?.toLocaleString() || 0} کیلوگرم`, + }, + + { + title: "میانگین وزن", + + icon: killedInProvinceIcon3, + key: (data) => + `${data?.killHouseRequestAverageWeight?.toLocaleString() || 0} کیلوگرم`, + }, + ]; + + console.log(data); + const reportBarKilledOutProvince = [ + { + title: "تعداد بارها", + icon: iconLeft, + key: (data) => `${data?.freeBarsCount?.toLocaleString() || 0} بار`, + }, + { + title: "حجم کشتار", + icon: iconRight, + key: (data) => `${data?.freeBarsQuantity?.toLocaleString() || 0} قطعه`, + }, + // { + // title: "وزن کشتار", + // icon: iconRight, + // key: (data) => `${data?.freeBarsWeight?.toLocaleString() || 0} کیلوگرم`, + // }, + { + title: `بیشترین خرید : ${data?.killHouseName}`, + icon: iconLeft, + key: (data) => `${data?.transactionCount?.toLocaleString() || 0} بار`, + }, + ]; + + const reportBuyerPerformance = [ + { + title: "بیشترین خرید داخل استان", + key: (data) => `${data?.killHouseNameReq?.toLocaleString() || 0} `, + }, + { + title: "بیشترین خرید خارج از استان", + key: (data) => `${data?.killHouseName?.toLocaleString() || 0}`, + }, + { + title: "بیشترین بار ارسالی مرغدار داخل استان", + key: (data) => + `${data?.poultryReqNameReq?.toLocaleString() || 0} با ${ + data?.topPoultryReqStatsTotalQuantity + } قطعه در شهرستان ${data?.poultryCityReqNameReq}`, + }, + + { + title: "بیشترین بار ارسالی مرغدار خارج استان", + key: (data) => + `${data?.outPoultryReqNameReq?.toLocaleString() || 0} با ${ + data?.outTopPoultryReqStatsTotalQuantity + } قطعه در شهرستان ${data?.outPoultryCityReqNameReq}`, + }, + ]; + + const reportDistributerCorpse = [ + { + title: "بیشترین درصد توزیع", + key: (data) => `${data?.managementKillHouseDict?.maxPercent || "-"} `, + }, + + { + title: "بیشترین درصد توزیع به خارج استان", + key: (data) => `${data?.managementKillHouseDict?.maxOutProvince || "-"} `, + }, + { + title: "بیشترین درصد توزیع به داخل استان", + key: (data) => `${data?.managementKillHouseDict?.maxInProvince || "-"} `, + }, + + { + title: "کمترین درصد توزیع به خارج استان", + key: (data) => `${data?.managementKillHouseDict?.minOutProvince || "-"} `, + }, + { + title: "کمترین درصد توزیع به داخل استان", + key: (data) => `${data?.managementKillHouseDict?.minInProvince || "-"} `, + }, + { + title: "بیشترین وزن مانده در انبار", + key: (data) => `${data?.managementKillHouseDict?.maxProduct || "-"} `, + }, + ]; + + const reportBillScale = [ + { + title: "بیشترین سند ثبت شده نسبت به تعداد بارها", + key: (data) => `${data?.maxAndMinAssigment?.maxDucName || "-"} `, + }, + { + title: "کمترین سند ثبت شده نسبت به تعداد بارها", + key: (data) => `${data?.maxAndMinAssigment?.minDucName || "-"} `, + }, + { + title: "بیشترین سند تایید شده نسبت به تعداد بارها", + key: (data) => `${data?.maxAndMinAssigment?.maxDucAcceptedName || "-"} `, + }, + + { + title: "کمترین سند تایید شده نسبت به تعداد بارها", + key: (data) => `${data?.maxAndMinAssigment?.minDucAcceptedName || "-"} `, + }, + { + title: "بیشترین مغایرت نسبت به کل بارها", + key: (data) => `${data?.maxAndMinAssigment?.maxDucRejectedName || "-"} `, + }, + { + title: "کمترین مغایرت نسبت به کل بارها", + key: (data) => `${data?.maxAndMinAssigment?.minDucRejectedName || "-"} `, + }, + ]; + + return ( + + + + ( + + )} + value={selectedDate1} + onChange={(newValue) => { + setSelectedDate1(moment(newValue).format("YYYY-MM-DD")); + }} + /> + + + ( + + )} + value={selectedDate2} + onChange={(newValue) => { + setSelectedDate2(moment(newValue).format("YYYY-MM-DD")); + }} + /> + + + + + + + + + + + + وضعیت فارم های فعال + + + + {[ + { + label: "تعداد فارم‌ها", + value: data?.poultryCount ?? 0, + unit: "فارم", + icon: farmIcon1, + }, + { + label: "حجم جوجه‌ریزی", + value: data?.poultryHatchingQuantity ?? 0, + unit: "قطعه", + icon: farmIcon2, + }, + + { + label: "حجم تلفات", + value: data?.poultryHatchingTotalLosses ?? 0, + unit: `قطعه (${( + ((data?.poultryHatchingTotalLosses ?? 0) / + (data?.poultryHatchingQuantity ?? 1)) * + 100 + ).toFixed(1)}%)`, + icon: farmIcon4, + }, + { + label: "حجم کشتار", + value: data?.poultryHatchingKilledQuantity ?? 0, + unit: "قطعه", + icon: farmIcon6, + }, + + { + label: " وزن کشتار", + value: data?.poultryHatchingTotalKilledWeight ?? 0, + unit: "کیلوگرم", + icon: farmIcon7, + }, + { + label: "حجم مانده در سالن", + value: data?.poultryHatchingLeftOver ?? 0, + unit: `قطعه (${( + ((data?.poultryHatchingLeftOver ?? 0) / + (data?.poultryHatchingQuantity ?? 1)) * + 100 + ).toFixed(0)}%)`, + icon: farmIcon8, + }, + + { + label: "میانگین تلفات", + value: data?.avgLosses?.toLocaleString() || 0, + unit: "قطعه", + icon: farmIcon7, + }, + { + label: "میانگین سن کشتار", + value: data?.totalKillingAveAge?.toLocaleString() || 0, + unit: "روز", + icon: farmIcon7, + }, + + { + label: "میانگین وزن کشتار", + value: data?.avgTotalKilledWeight?.toLocaleString() || 0, + unit: "کیلوگرم", + icon: farmIcon7, + }, + ].map((item, index) => ( + + + icon + + {item.label}{" "} + + + + 0 || item.value === 0 + ? "rgba(53, 53, 53, 1)" + : "red", + display: "flex", + alignItems: "center", + }} + > + + {item.value?.toLocaleString?.() || item.value} + + {item.unit} + + + ))} + + + + + + + فارم‌های با سن بیشتر از ۶۰ روز + + + + {reportCards.map((item, index) => ( + + + + {item.title} + + + + + {item.key(data)} + + + + ))} + + + + + + + بیشترین سن کشتار :{data?.maxAgePoultry} روز + + {(data?.maxAgePoultryName !== "-" || + data?.maxAgePoultryCity !== "-") && ( + + + {data?.maxAgePoultryName} - {data?.maxAgePoultryCity} + + + )} + + + { + const percent = + (data?.maxAgePoultryLeftOver * 100) / + data?.maxAgePoultryQuantity; + + if (percent > 0 && percent < 25) return "red"; + if (percent >= 25 && percent < 50) return "orange"; + if (percent >= 50 && percent < 75) return "yellow"; + return "green"; + })(), + }, + }} + /> + + + + + + حجم جوجه ریزی: + {data?.maxAgePoultryQuantity?.toLocaleString()} + + + کشتار شده : {data?.maxAgePoultryKilledQuantity?.toLocaleString()} + + + مانده در سالن : {data?.maxAgePoultryLeftOver?.toLocaleString()} + + + + + + کمترین سن کشتار: {data?.minAgePoultry} روز + + + {(data?.minAgePoultryName !== "-" || + data?.minAgePoultryCity !== "-") && ( + + + {data?.minAgePoultryName} - {data?.minAgePoultryCity} + + + )} + + + { + const percent = + (data?.minAgePoultryLeftOver / + data?.minAgePoultryQuantity) * + 100; + + if (percent > 0 && percent < 25) return "red"; + if (percent >= 25 && percent < 50) return "orange"; + if (percent >= 50 && percent < 75) return "yellow"; + return "green"; + })(), + }, + }} + /> + + + + + حجم جوجه ریزی: + {data?.minAgePoultryQuantity?.toLocaleString() || 0} + + + کشتار شده : + {data?.minAgePoultryKilledQuantity?.toLocaleString() || 0} + + + مانده در سالن : + {data?.minAgePoultryLeftOver?.toLocaleString() || 0} + + + + + + + + + کشتار داخل استان (زنده) + + + + {reportBarKilledInProvince?.map((item, index) => ( + + icon + + + {item.title} + + + {item.key(data)} + + + + ))} + + + + + + کشتار خارج استان (زنده) + + + + {reportBarKilledOutProvince.map((item, index) => ( + + {item.icon === iconLeft && ( + icon-left + )} + + + + {item?.title} + + + {item.key(data)} + + + + {item.icon === iconRight && ( + icon-right + )} + + ))} + + + * بیشترین حجم کشتار در {data?.persianDate} با{" "} + {data?.freeBarsQuantity?.toLocaleString() || "0"} قطعه رخ داده است + + + + + + + عملکرد خریداران + + {data?.killHousesData?.length > 0 && ( + + + + + + + نام کشتارگاه + + + + + {data.killHousesData.map((item, index) => ( + + + + {item?.name || "-"} + + + + ))} + + + + + داخل استان + + + + + تعداد بار + + + حجم بار + + + + وزن بار + + + + {data.killHousesData.map((item, index) => ( + + + + {item?.loadCountInProvince?.toLocaleString() || 0} + + + + + {item?.inProvinceQuantity?.toLocaleString() || 0} + + + + + {item?.inProvinceWight?.toLocaleString() || 0} + + + + ))} + + + + + خارج استان + + + + + تعداد بار + + + حجم بار + + + + وزن بار + + + + {data.killHousesData.map((item, index) => ( + + + + {item?.loadCountOutProvince?.toLocaleString() || 0} + + + + + {item?.outProvinceQuantity?.toLocaleString() || 0} + + + + + {item?.outProvinceWeight?.toLocaleString() || 0} + + + + ))} + + + + + + کل بارها + + + + + تعداد بار + + + حجم بار + + + + وزن بار + + + + {data.killHousesData.map((item, index) => ( + + + + {item?.loadCount?.toLocaleString() || 0} + + + + + {item?.totalQuantity?.toLocaleString() || 0} + + + + + {item?.totalWeight?.toLocaleString() || 0} + + + + ))} + + + + )} + + + {reportBuyerPerformance.map((item, index) => ( + + + + icon + + {item.title} : {item.key(data)} + + + + + ))} + + + + + عملکرد کشتار و توزیع لاشه + + + + [ + i + 1, + item?.name || " -", + item?.inProvinceQuantity.toLocaleString() || 0, + item?.inWareHouseQuantity.toLocaleString() || 0, + item?.stewardAllocationQuantity.toLocaleString() || 0, + item?.killHouseFreeBarQuantity.toLocaleString() || 0, + item?.allQuantity.toLocaleString() || 0, + item?.product.toLocaleString() || 0, + item?.percent.toLocaleString() || 0, + ])} + rowColors={["#FFF", "#F2F5FF"]} + headerColor="#E0E7FF" + /> + + + + * وزن ها بر حسب کیلوگرم میباشد. + + + + {reportDistributerCorpse.map((item, index) => ( + + + + icon + + {item.title} : {item.key(data)} + + + + + ))} + + + + + گزارش اسناد و قبوض باسکول + + + + [ + i + 1, + item?.name || " -", + item?.killHouseRequest1Count.toLocaleString() || 0, + item?.barAssigmentTrueCount.toLocaleString() || 0, + item?.barAssigmentPendingCount.toLocaleString() || 0, + item?.barDocumentStatusAccepted.toLocaleString() || 0, + item?.barDocumentStatusRejected.toLocaleString() || 0, + item?.percentBarDocumentStatusAccepted.toLocaleString() || 0, + item?.percentBarDocumentStatusRejected.toLocaleString() || 0, + ])} + headerColor="#B0EFDF" + rowColors={["#FFF", "#E6FAF5"]} + /> + + + icon + + هشدار: بیش از ۵۰٪ بارها دارای سند مشکوک یا دست‌نویس هستند. + + + + icon + + هشدار: تعداد اسناد مشکوک و دارای مغایرت{" "} + {data?.barAssigmentPendingCount1?.toLocaleString() || 0} بار + می‌باشد. + + + + + {reportBillScale.map((item, index) => ( + + + + icon + + {item.title} : {item.key(data)} + + + + + ))} + + + + ); +}; diff --git a/src/features/dashboard/components/dashboard-pie-chart-section/PieChartSection.js b/src/features/dashboard/components/dashboard-pie-chart-section/PieChartSection.js new file mode 100644 index 0000000..c9f5f8f --- /dev/null +++ b/src/features/dashboard/components/dashboard-pie-chart-section/PieChartSection.js @@ -0,0 +1,213 @@ +import { Box, Typography } from "@mui/material"; +import { Grid } from "../../../../components/grid/Grid"; +import { Pie } from "react-chartjs-2"; +import { StatItem } from "../dashboard-state-item/StateItem"; +import { SPACING } from "../../../../data/spacing"; + +export const PieChartSection = ({ boxStats }) => { + const pieChartTotal = + (boxStats?.yesterdayKilling?.quantityKillHouseFreeBarCarcass || 0) + + (boxStats?.yesterdayKilling?.weightKillHouseFreeBarCarcass || 0) + + (boxStats?.yesterdayKilling?.provinceKillRequestQuantity || 0) + + (boxStats?.yesterdayKilling?.provinceKillRequestWeight || 0) + + (boxStats?.yesterdayKilling?.quantityKillHouseFreeBarLive || 0) + + (boxStats?.yesterdayKilling?.weightOfCarcass || 0) + + (boxStats?.yesterdayKilling?.losses || 0); + + const pieChartData = { + labels: [ + "حجم خرید خارج استان", + "وزن خرید خارج استان", + "حجم کشتار داخل استان", + "وزن کشتار داخل استان", + "حجم فروش به خارج استان (زنده)", + "وزن لاشه تولیدی", + "درصد افت دیروز", + ], + datasets: [ + { + data: [ + boxStats?.yesterdayKilling?.quantityKillHouseFreeBarCarcass || 0, + boxStats?.yesterdayKilling?.weightKillHouseFreeBarCarcass || 0, + boxStats?.yesterdayKilling?.provinceKillRequestQuantity || 0, + boxStats?.yesterdayKilling?.provinceKillRequestWeight || 0, + boxStats?.yesterdayKilling?.outQuantity || 0, + boxStats?.yesterdayKilling?.weightOfCarcass || 0, + boxStats?.yesterdayKilling?.losses || 0, + ], + backgroundColor: [ + "#FF6384", + "#36A2EB", + "#FFCE56", + "#4BC0C0", + "#9966FF", + "#FF9F40", + "#C9CBCF", + ], + hoverBackgroundColor: [ + "#FF6384", + "#36A2EB", + "#FFCE56", + "#4BC0C0", + "#9966FF", + "#FF9F40", + "#C9CBCF", + ], + borderWidth: 1, + }, + ], + }; + + const pieChartOptions = { + responsive: true, + maintainAspectRatio: false, + plugins: { + datalabels: { + display: false, + }, + tooltip: { + enabled: true, + callbacks: { + label: (context) => { + const value = context.raw; + const total = context.dataset.data.reduce((a, b) => a + b, 0); + if (total === 0) return "0"; + const percentage = ((value / total) * 100).toFixed(2); + return `${value.toLocaleString()} (${percentage}%)`; + }, + }, + }, + legend: { + display: false, + }, + }, + }; + + return ( + + + آمار روز گذشته کشتار مرغ گوشتی استان + + + + {pieChartTotal > 0 ? ( + + ) : ( + + داده‌ای برای نمایش چارت موجود نیست. + + )} + + + + + + + + + + + + + + + + + + + + + + + ); +}; diff --git a/src/features/dashboard/components/dashboard-price-chart-section/PriceChartSection.js b/src/features/dashboard/components/dashboard-price-chart-section/PriceChartSection.js new file mode 100644 index 0000000..803223a --- /dev/null +++ b/src/features/dashboard/components/dashboard-price-chart-section/PriceChartSection.js @@ -0,0 +1,145 @@ +import { Box, Typography } from "@mui/material"; +import { formatJustDate } from "../../../../utils/formatTime"; +import { Line } from "react-chartjs-2"; +import { Grid } from "../../../../components/grid/Grid"; + +export const PriceChartSection = ({ boxStats }) => ( + + + نمودار قیمت مرغ در هفته گذشته (میانگین قیمت) + + + {boxStats?.chickenPrice?.length > 0 ? ( + + formatJustDate(item.date) + ), + datasets: [ + { + label: "میانگین قیمت مرغ (ریال)", + data: boxStats.chickenPrice.map( + (item) => item.chickenAveragePrice + ), + fill: { + target: "origin", + above: "rgba(75, 192, 192, 0.2)", + below: "rgba(75, 192, 192, 0.2)", + }, + backgroundColor: "rgba(75, 192, 192, 0.2)", + borderColor: "rgba(75, 192, 192, 1)", + borderWidth: 4, + tension: 0.4, + pointRadius: 5, + pointHoverRadius: 7, + pointBackgroundColor: "rgba(75, 192, 192, 1)", + pointBorderColor: "#fff", + pointBorderWidth: 2, + }, + ], + }} + options={{ + responsive: true, + maintainAspectRatio: false, + plugins: { + legend: { + position: "top", + rtl: true, + labels: { + font: { + family: "iranyekan", + size: 12, + }, + padding: 20, + usePointStyle: true, + }, + }, + tooltip: { + callbacks: { + label: (context) => { + return `${ + context.dataset.label + }: ${context.parsed.y.toLocaleString()} ریال`; + }, + }, + displayColors: false, + backgroundColor: "rgba(0, 0, 0, 0.7)", + titleFont: { + size: 14, + family: "iranyekan", + }, + bodyFont: { + size: 12, + family: "iranyekan", + }, + }, + }, + scales: { + x: { + grid: { + display: false, + drawBorder: false, + }, + ticks: { + color: "#6B7280", + font: { + family: "iranyekan", + }, + }, + }, + y: { + beginAtZero: false, + grid: { + display: false, + drawBorder: false, + }, + ticks: { + color: "#6B7280", + font: { + family: "iranyekan", + }, + callback: function (value) { + return value.toLocaleString() + " ریال"; + }, + }, + }, + }, + elements: { + line: { + tension: 0.4, + }, + point: { + radius: 5, + hoverRadius: 7, + }, + }, + }} + /> + ) : ( + + داده‌ای برای نمایش موجود نیست + + )} + + +); diff --git a/src/features/dashboard/components/dashboard-sell-out/DashboardProvinceSellOut.js b/src/features/dashboard/components/dashboard-sell-out/DashboardProvinceSellOut.js new file mode 100644 index 0000000..35400f8 --- /dev/null +++ b/src/features/dashboard/components/dashboard-sell-out/DashboardProvinceSellOut.js @@ -0,0 +1,102 @@ +import { Box, Typography } from "@mui/material"; +import { SPACING } from "../../../../data/spacing"; + +export const DashboardProvinceSellOut = ({ boxStats }) => ( + + + فروش زنده به خارج استان + + + + + تعداد بار : + + {boxStats?.outLiveBar?.count?.toLocaleString() || 0} + + + + حجم بار(قطعه) : + + {boxStats?.outLiveBar?.quantity?.toLocaleString() || 0} + + + + وزن(کیلوگرم) : + + {boxStats?.outLiveBar?.weight?.toLocaleString() || 0} + + + + میانگین وزن(کیلوگرم): + + {boxStats?.outLiveBar?.avgWeight?.toLocaleString() || 0} + + + + +); diff --git a/src/features/dashboard/components/dashboard-slaughter-information/DashboardSlaughterInformation.js b/src/features/dashboard/components/dashboard-slaughter-information/DashboardSlaughterInformation.js new file mode 100644 index 0000000..cde5299 --- /dev/null +++ b/src/features/dashboard/components/dashboard-slaughter-information/DashboardSlaughterInformation.js @@ -0,0 +1,291 @@ +import React, { useContext, useEffect, useState } from "react"; +import { Grid } from "../../../../components/grid/Grid"; +import axios from "axios"; +import { useDispatch } from "react-redux"; +import moment from "moment"; +import { RiFileExcel2Fill } from "react-icons/ri"; +import { Button, Tooltip, Checkbox, TextField } from "@mui/material"; +import { dashboardGetSlaughterInformationService } from "../../services/dashboard-slaughter-get-information"; +import { AppContext } from "../../../../contexts/AppContext"; +import ResponsiveTable from "../../../../components/responsive-table/ResponsiveTable"; +import { provinceGetDispenserKillhousesService } from "../../../province/services/province-get-dispenser-killhouses"; +import ToggleOffOutlinedIcon from "@mui/icons-material/ToggleOffOutlined"; +import ToggleOnIcon from "@mui/icons-material/ToggleOn"; +import { DatePicker } from "@mui/x-date-pickers"; + +export const DashboardSlaughterInformation = () => { + const [openNotif, , selectedDate1, , selectedDate2] = useContext(AppContext); + + const [dashboardData, setDashboardData] = useState([]); + const [tableData, setTableData] = useState([]); + const [withDate, setWithDate] = useState(true); + const [selectedDate3, setSelectedDate3] = useState( + moment().format("YYYY-MM-DD") + ); + const [selectedDate4, setSelectedDate4] = useState( + moment().format("YYYY-MM-DD") + ); + const dispatch = useDispatch(); + + useEffect(() => { + fetchTableData(); + fetchDashboardData(); + }, [selectedDate1, selectedDate2, selectedDate3, selectedDate4, withDate]); + + const fetchDashboardData = () => { + dispatch( + dashboardGetSlaughterInformationService({ + date1: selectedDate1, + date2: selectedDate2, + }) + ) + .then((r) => { + if (r.payload?.data) { + const d = r.payload.data.map((item, i) => { + return [ + i + 1, + item?.killer ? "کشتارکن" : "کشتارگاه", + item?.name || "", + `${item?.killHouseOperator?.user?.fullname} (${item?.killHouseOperator?.user?.mobile})` || + "-", + item?.killHouseOperator?.user?.city?.toLocaleString() || "-", + item?.killingInfo?.killHouseRequestsCount?.toLocaleString() || + "0", + item?.killingInfo?.killHouseRequestsQuantity?.toLocaleString() || + "0", + item?.killingInfo?.killHouseRequestsWeight?.toLocaleString() || + "0", + item?.killingInfo?.killHouseFreeBarCount?.toLocaleString() || "0", + item?.killingInfo?.killHouseFreeBarQuantity?.toLocaleString() || + "0", + item?.killingInfo?.killHouseFreeBarWeight?.toLocaleString() || + "0", + item?.killingInfo?.provinceKillRequestsQuantity?.toLocaleString() || + "0", + item?.killingInfo?.totalQuantity?.toLocaleString() || "0", + item?.killingInfo?.totalWeight?.toLocaleString() || "0", + item?.killingInfo?.totalAvgWeight?.toLocaleString() || "0", + item?.killingInfo?.killHouseRequestsWareHouseTrueQuantity?.toLocaleString() || + "0", + item?.killingInfo?.killHouseRequestsWareHouseTrueWeight?.toLocaleString() || + "0", + item?.killingInfo?.killHouseRequestsWareHouseFalseQuantity?.toLocaleString() || + "0", + item?.killingInfo?.killHouseRequestsWareHouseFalseWeight?.toLocaleString() || + "0", + ]; + }); + setDashboardData(d); + } + }) + .catch((error) => { + openNotif({ + vertical: "top", + horizontal: "center", + msg: "خطا در دریافت اطلاعات کشتارگاه", + severity: "error", + }); + console.error("Error fetching dashboard data:", error); + }); + }; + + const fetchTableData = () => { + dispatch( + provinceGetDispenserKillhousesService( + withDate + ? { + selectedDate1: selectedDate3, + selectedDate2: selectedDate4, + } + : {} + ) + ) + .then((r) => { + const d = r.payload?.data?.map((item, i) => { + return [ + i + 1, + `${item?.killHouseOperator?.user?.fullname} (${item?.killHouseOperator?.user?.mobile})`, + `${item?.killer ? "کشتارکن" : "کشتارگاه"} (${item?.name})`, + item?.killHouseOperator?.user?.city?.name, + item?.wareHouseInfo?.productRemainWeight?.toLocaleString(), + item?.wareHouseInfo?.totalSell?.toLocaleString(), + item?.wareHouseInfo?.totalKillHouseAllocationsWeight?.toLocaleString(), + item?.wareHouseInfo?.totalKillHouseFreeSale_barCarcassesWeight?.toLocaleString(), + + + , + ]; + }); + setTableData(d); + }) + .catch((error) => { + openNotif({ + vertical: "top", + horizontal: "center", + msg: "خطا در دریافت اطلاعات توزیع", + severity: "error", + }); + console.error("Error fetching table data:", error); + }); + }; + + return ( + + + + + + } + checkedIcon={} + checked={withDate} + onChange={() => setWithDate(!withDate)} + color="primary" + size="large" + /> + + + ( + + )} + value={moment(selectedDate3)} + onChange={(newValue) => { + setSelectedDate3(moment(newValue).format("YYYY-MM-DD")); + }} + /> + + + ( + + )} + value={moment(selectedDate4)} + onChange={(newValue) => { + setSelectedDate4(moment(newValue).format("YYYY-MM-DD")); + }} + minDate={moment(selectedDate3)} + /> + + + + + + ); +}; diff --git a/src/features/dashboard/components/dashboard-slaughter-performance/DashboardSlaughterPerformance.js b/src/features/dashboard/components/dashboard-slaughter-performance/DashboardSlaughterPerformance.js new file mode 100644 index 0000000..238771f --- /dev/null +++ b/src/features/dashboard/components/dashboard-slaughter-performance/DashboardSlaughterPerformance.js @@ -0,0 +1,881 @@ +import { useContext, useEffect, useState } from "react"; +import { Grid } from "../../../../components/grid/Grid"; +import { Chart as ChartJS, ArcElement, Tooltip, Legend } from "chart.js"; +import { Line, Pie } from "react-chartjs-2"; +import ChartDataLabels from "chartjs-plugin-datalabels"; +import { SPACING } from "../../../../data/spacing"; +import { AppContext } from "../../../../contexts/AppContext"; +import { DatePicker } from "@mui/x-date-pickers"; +import { TextField, Typography } from "@mui/material"; +import moment from "moment"; + +import { AdvancedChart } from "../../../../components/advanced-chart/AdvancedChart"; +import { useDispatch } from "react-redux"; +import { dashboardGetSlaughterManagementKillHouse } from "../../services/dashboard-slaughter-performance"; + +ChartJS.register(ArcElement, Tooltip, Legend, ChartDataLabels); +export const DashboardSlaughterPerformance = () => { + const dispatch = useDispatch(); + const [, , selectedDate1, setSelectedDate1, selectedDate2, setSelectedDate2] = + useContext(AppContext); + const [data, setData] = useState({}); + + useEffect(() => { + dispatch( + dashboardGetSlaughterManagementKillHouse({ + date1: selectedDate1, + date2: selectedDate2, + }) + ).then((r) => { + if (r.payload?.data) { + setData(r.payload.data); + } + }); + }, [dispatch, selectedDate1, selectedDate2]); + + const options = { + responsive: true, + maintainAspectRatio: false, + plugins: { + datalabels: { + color: "#fff", + font: { + size: 10, + family: "iranyekan", + }, + formatter: (value, context) => { + const percentage = context.dataset.data[context.dataIndex]; + return percentage > 10 ? `${percentage}%` : ""; + }, + clamp: true, + anchor: "center", + align: "center", + offset: 0, + clip: true, + }, + legend: { + labels: { + color: "#333", + font: { + size: 12, + }, + }, + }, + }, + }; + + const lineOptions = { + scales: { + y: { + beginAtZero: true, + }, + }, + plugins: { + rtl: true, + }, + }; + const firstChart = [ + data?.allManagementKillHouseData?.stewardAllocations || 0, + data?.allManagementKillHouseData?.freeBars || 0, + data?.allManagementKillHouseData?.inWarehouse || 0, + ]; + + const firstChartData = { + labels: [ + "وزن توزیع شده داخل استان", + "وزن توزیع شده خارج استان", + "وزن وارد شده به انبار", + ], + datasets: [ + { + label: "", + data: firstChart?.map((v) => + ((v / firstChart.reduce((a, b) => a + b, 0)) * 100).toFixed(0) + ), + + backgroundColor: ["#2D5FFF", "#00CC99", "#dada95"], + }, + ], + }; + + const secondChart = [ + data?.allManagementKillHouseData?.inWarehouse || 0, + data?.totalWeightHasntWarehouse || 0, + data?.poultryHatchingTotalKilledWeight || 0, + ]; + + const secondChartData = { + labels: [ + "وزن وارد شده به انبار", + "وزن کل کشتار شده", + "وزن وارد نشده به انبار", + ], + datasets: [ + { + label: "", + data: secondChart.map((v) => + ((v / secondChart.reduce((a, b) => a + b, 0)) * 100).toFixed(1) + ), + + backgroundColor: ["#2D5FFF", "#00CC99", "#dada95"], + }, + ], + }; + + const getChartOptions = () => { + return [ + { + name: "درصد توزیع به خارج استان", + data: data?.managementKillHouseData?.map((item) => { + const killHouse = parseFloat(item?.killHouseFreeBarQuantity || 0); + const all = parseFloat(item?.allQuantity || 0); + return all ? parseFloat(((killHouse / all) * 100).toFixed(0)) : 0; + }), + }, + { + name: "درصد توزیع به داخل استان", + data: data?.managementKillHouseData?.map((item) => { + const inProvince = parseFloat(item?.inProvinceQuantity || 0); + const all = parseFloat(item?.allQuantity || 0); + return all ? parseFloat(((inProvince / all) * 100).toFixed(0)) : 0; + }), + }, + { + name: "درصد مانده در انبار", + data: data?.managementKillHouseData?.map((item) => { + const product = parseFloat(item?.product || 0); + const all = parseFloat(item?.allQuantity || 0); + return all ? parseFloat(((product / all) * 100).toFixed(0)) : 0; + }), + }, + { + name: "درصد توزیع", + // data: data?.managementKillHouseData?.map(() => 100), + data: data?.managementKillHouseData?.map( + (item) => + item?.inProvinceQuantity + item?.killHouseFreeBarQuantity || 0 + ), + }, + ]; + }; + + const getChartStewardOptions = () => { + return [ + { + name: "وزن کل تخصیصات", + data: data?.killHousesData?.map( + (item) => item?.wightOfSteward + item?.wightOfGuild || 0 + ), + }, + { + name: "وزن تخصیصات به مباشرین", + data: data?.killHousesData?.map((item) => item?.wightOfSteward || 0), + }, + { + name: "وزن تخصیصات به صنوف", + data: data?.killHousesData?.map((item) => item?.wightOfGuild || 0), + }, + ]; + }; + + const lineData = { + labels: data?.killHousesData?.map((item) => item?.name), + datasets: [ + { + label: "وزن توزیع خارج استان", + data: data?.killHousesData?.map((item) => item?.outProvinceWeight || 0), + backgroundColor: "rgba(255, 99, 132, 0.2)", + borderColor: "rgba(255, 99, 132, 1)", + borderWidth: 1, + }, + { + label: "وزن توزیع داخل استان", + data: data?.killHousesData?.map((item) => item?.inProvinceWight || 0), + backgroundColor: "rgba(54, 162, 235, 0.2)", + borderColor: "rgba(54, 162, 235, 1)", + borderWidth: 1, + }, + { + label: "کل وزن مانده به انبار", + data: data?.killHousesData?.map((item) => item?.totalWeight), + backgroundColor: "rgba(75, 192, 192, 0.2)", + borderColor: "rgba(75, 192, 192, 1)", + borderWidth: 1, + }, + ], + }; + + return ( + + + + ( + + )} + value={selectedDate1} + onChange={(newValue) => { + setSelectedDate1(moment(newValue).format("YYYY-MM-DD")); + }} + /> + + + ( + + )} + value={selectedDate2} + onChange={(newValue) => { + setSelectedDate2(moment(newValue).format("YYYY-MM-DD")); + }} + /> + + + + + + عملکرد کشتارگاه ها در بخش توزیع + + + + + + + + {[ + { + label: "وزن وارد شده به انبار", + value: data?.allManagementKillHouseData?.inWarehouse, + }, + { + label: "وزن توزیع شده خارج استان", + value: data?.allManagementKillHouseData?.freeBars, + }, + { + label: "وزن توزیع شده داخل استان", + value: data?.allManagementKillHouseData?.stewardAllocations, + }, + { + label: "مانده انبار", + value: data?.allManagementKillHouseData?.products, + }, + ].map((item, index) => ( + + + {item.label} : {item.value?.toLocaleString()} + + + ))} + + + + + عملکرد کشتارگاه ها در بخش ورود و خروج بارها به انبار + + + + + + {[ + { + label: "وزن وارد شده به انبار", + value: data?.allManagementKillHouseData?.inWarehouse, + }, + { + label: "وزن توزیع شده خارج استان", + value: data?.allManagementKillHouseData?.freeBars, + }, + { + label: "وزن توزیع شده داخل استان", + value: data?.allManagementKillHouseData?.stewardAllocations, + }, + { + label: "مانده انبار", + value: data?.allManagementKillHouseData?.products, + }, + ].map((item, index) => ( + + + {item.label} : {item.value?.toLocaleString()} + + + ))} + + + + + {data?.killHousesData?.length > 0 && ( + + + + گزارش درصد خرید کشتارگاه های استان (بر اساس حجم) + + + + {data?.killHousesData?.map((item, idx) => ( + + + + {item?.name} + + + + + درصد خرید داخل استان: + + + {(() => { + return `${ + Math.floor( + ((item?.inProvinceQuantity || 0) / + (item?.totalQuantity || 0)) * + 100 + ) || 0 + }% `; + })()} + + + درصد خرید خارج استان: + + + {(() => { + return `${ + Math.floor( + ((item?.outProvinceQuantity || 0) / + (item?.totalQuantity || 0)) * + 100 + ) || 0 + }% `; + })()} + + + + ))} + + + + )} + + {data?.managementKillHouseData?.length > 0 && ( + + + گزارش عملکرد انبار و توزیع کشتارگاه های استان (بر اساس درصد) + + + item?.name)} + info={getChartOptions()} + /> + + )} + {data?.killHousesData?.length > 0 && ( + + + + + گزارش درصد خرید کشتارگاه های استان (بر اساس وزن) + + + + + نام کشتارگاه + درصد خرید از استان + درصد خرید از خارج استان + + + {data.killHousesData.map((item, idx) => ( + + {item?.name} + + + {(() => { + const total = parseFloat(item?.totalWeight) || 0; + const inProvince = + parseFloat(item?.inProvinceWight) || 0; + return total > 0 + ? `${((inProvince / total) * 100).toFixed(0)}%` + : "0%"; + })()} + + + + {(() => { + const total = parseFloat(item?.totalWeight) || 0; + const outProvince = + parseFloat(item?.outProvinceWeight) || 0; + return total > 0 + ? `${((outProvince / total) * 100).toFixed(0)}%` + : "0%"; + })()} + + + ))} + + + + + {data?.killHousesData?.length > 0 && ( + + + گزارش کلی عملکرد توزیع به مباشرین و صنوف استان + + + + + نام کشتارگاه + تعداد تخصیصات به مباشرین + تعداد تخصیصات به صنوف + + + {data.killHousesData.map((item, idx) => ( + + {item?.name} + + {item?.lenOfSteward} + + {item?.lenOfGuild} + + ))} + + + )} + + + )} + + {data?.managementKillHouseData?.length > 0 && ( + + + + گزارش کلی عملکرد توزیع به مباشرین و صنوف استان (بر اساس وزن) + + + + + + + )} + + + + + + گزارش درصد خرید کشتارگاه های استان (بر اساس وزن) + + + item?.name)} + info={getChartStewardOptions()} + /> + + + + + + + + گزارش کلی عملکرد توزیع به مباشرین و صنوف استان (درصد) + + + + + نام کشتارگاه + تعداد تخصیصات به مباشرین + تعداد تخصیصات به صنوف + + + {data?.killHousesData?.map((item, idx) => ( + + {item?.name} + + {(() => { + const stewardWeight = + parseFloat(item?.wightOfSteward) || 0; + const guildWeight = parseFloat(item?.wightOfGuild) || 0; + const total = stewardWeight + guildWeight; + + const steward = parseFloat(item?.lenOfSteward) || 0; + + return total > 0 + ? `${((steward / total) * 100).toFixed(0)}%` + : "0%"; + })()} + + + + {(() => { + const total = + parseFloat(item?.wightOfSteward + item?.wightOfGuild) || + 0; + const guild = parseFloat(item?.lenOfGuild) || 0; + return total > 0 + ? `${((guild / total) * 100).toFixed(0)}%` + : "0%"; + })()} + + + ))} + + + + + + ); +}; diff --git a/src/features/dashboard/components/dashboard-slaughter/SlaughterDashboard.js b/src/features/dashboard/components/dashboard-slaughter/SlaughterDashboard.js new file mode 100644 index 0000000..681c469 --- /dev/null +++ b/src/features/dashboard/components/dashboard-slaughter/SlaughterDashboard.js @@ -0,0 +1,368 @@ +import React, { useContext, useEffect, useState } from "react"; +import { + Grid, + Typography, + Box, + TextField, + Tooltip, + Button, +} from "@mui/material"; +import { KillingInformation } from "../dashboard-killing-information/KillingInformation"; +import { useDispatch, useSelector } from "react-redux"; +import { SPACING } from "../../../../data/spacing"; +import { StatBox } from "../dashboard-state-box/StatBox"; +import { DashboardAllocationWithOutBar } from "../dashboard-allocation-with-out-bar/DashboardAllocationWithOutBar"; +import { DashboardLivePurchase } from "../dashboard-live-purchase/DashboardLivePurchase"; +import { AppContext } from "../../../../contexts/AppContext"; +import { DatePicker } from "@mui/x-date-pickers"; +import moment from "moment"; + +import axios from "axios"; +import { RiFileExcel2Fill } from "react-icons/ri"; +import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl"; +import { DashboardBuyingCarcassess } from "../dashboard-buying-carcassess/DashboardBuyingCarcassess"; +import { DashboardProvinceSellOut } from "../dashboard-sell-out/DashboardProvinceSellOut"; +import { dashboardGetMonitoringBarAndKillingService } from "../../services/dashboard-get-service"; +import { DashboardSlaughterInformation } from "../dashboard-slaughter-information/DashboardSlaughterInformation"; +import { ImFilePdf } from "react-icons/im"; + +export const SlaughterDashboard = () => { + const dispatch = useDispatch(); + + const [boxStats, setBoxStats] = useState({ + killingInfo: {}, + bar: {}, + freeLiveBar: {}, + provinceKillRequestWithoutBar: {}, + outLiveBar: {}, + buyFreeCarcasses: {}, + }); + const [, , selectedDate1, setSelectedDate1, selectedDate2, setSelectedDate2] = + useContext(AppContext); + const userKey = useSelector((state) => state.userSlice.userProfile.key); + + useEffect(() => { + dispatch( + dashboardGetMonitoringBarAndKillingService({ + date1: selectedDate1 || "null", + date2: selectedDate2 || "null", + }) + ).then((r) => { + if (r.payload?.data) { + setBoxStats(r.payload.data); + } + }); + }, [dispatch, selectedDate1, selectedDate2]); + + const firstRowBoxes = [ + { + title: "تعداد بارها", + value: boxStats?.bar?.count?.toLocaleString() || 0, + }, + { + title: "حجم بارها", + value: boxStats?.bar?.quantity?.toLocaleString() || 0, + unit: "قطعه", + }, + { + title: "وزن بارها", + value: boxStats?.bar?.weight?.toLocaleString() || 0, + unit: "کیلوگرم", + }, + { + title: "میانگین سن", + value: boxStats?.bar?.avgAge?.toLocaleString() || 0, + unit: "روز", + }, + { + title: "میانگین وزن", + value: boxStats?.bar?.avgWeight?.toLocaleString() || 0, + unit: "کیلوگرم", + }, + ]; + + const secondRowBoxes = [ + { + title: "تعداد بارها", + value: boxStats?.bar?.countHasQuarantine?.toLocaleString() || 0, + }, + { + title: "حجم بارهای رصدیار", + value: boxStats?.bar?.quantityHasQuarantine?.toLocaleString() || 0, + unit: "قطعه", + }, + { + title: "حجم بارهای قرنطینه", + value: boxStats?.bar?.totalQuarantineQuantity?.toLocaleString() || 0, + unit: "قطعه", + }, + + { + title: "اختلاف قطعه", + value: `${( + boxStats?.bar?.quantityHasQuarantine - + boxStats?.bar?.totalQuarantineQuantity || 0 + )?.toLocaleString()} (${ + boxStats?.bar?.quantityHasQuarantine + ? ( + ((boxStats?.bar?.quantityHasQuarantine - + boxStats?.bar?.totalQuarantineQuantity) / + boxStats?.bar?.quantityHasQuarantine) * + 100 + )?.toFixed(0) + "%)" + : "0%)" + }`, + isNegative: + boxStats?.bar?.quantityHasQuarantine - + boxStats?.bar?.totalQuarantineQuantity < + 0, + }, + ]; + + return ( + + + + + ( + + )} + value={selectedDate1} + onChange={(newValue) => { + setSelectedDate1(moment(newValue).format("YYYY-MM-DD")); + }} + /> + + + ( + + )} + value={selectedDate2} + onChange={(newValue) => { + setSelectedDate2(moment(newValue).format("YYYY-MM-DD")); + }} + /> + + + + + + + + + + + + + + + + + + + + + اطلاعات بار + + + + {firstRowBoxes.map((box, index) => ( + + + + ))} + + + اطلاعات بارهای دارای استعلام قرنطینه + + + + {secondRowBoxes.map((box, index) => ( + + + + ))} + + + + + + + + + + + + + + + + + + + ); +}; diff --git a/src/features/dashboard/components/dashboard-state-box/StatBox.js b/src/features/dashboard/components/dashboard-state-box/StatBox.js new file mode 100644 index 0000000..18b6cdf --- /dev/null +++ b/src/features/dashboard/components/dashboard-state-box/StatBox.js @@ -0,0 +1,58 @@ +import { Box, Typography } from "@mui/material"; +import { SPACING } from "../../../../data/spacing"; + +export const StatBox = ({ + title, + value, + textColor, + color = "primary", + unit, +}) => { + return ( + + + {title} + + + {value.toLocaleString()} + + {unit && ( + + {unit} + + )} + + ); +}; diff --git a/src/features/dashboard/components/dashboard-state-item/StateItem.js b/src/features/dashboard/components/dashboard-state-item/StateItem.js new file mode 100644 index 0000000..de87da9 --- /dev/null +++ b/src/features/dashboard/components/dashboard-state-item/StateItem.js @@ -0,0 +1,56 @@ +import { Box, Typography } from "@mui/material"; +import { Grid } from "../../../../components/grid/Grid"; + +export const StatItem = ({ + title, + value, + unit = "", + color = "text", + small = false, + rightAlign = false, + colon = false, + bgGreen = false, + bgPurple = false, +}) => { + let backgroundColor = "background.paper"; + let textColor = `${color}.main`; + + if (bgGreen) { + backgroundColor = "rgba(0,128,0,0.1)"; + textColor = "success.main"; + } else if (bgPurple) { + backgroundColor = "#9370db"; + textColor = "primary.main"; + } + + return ( + + + + {colon ? `${title} :` : title} + + + {value?.toLocaleString?.() || value} {unit} + + + + ); +}; diff --git a/src/features/dashboard/components/dashboard-tab/DashboardTab.js b/src/features/dashboard/components/dashboard-tab/DashboardTab.js new file mode 100644 index 0000000..ea5bf50 --- /dev/null +++ b/src/features/dashboard/components/dashboard-tab/DashboardTab.js @@ -0,0 +1,57 @@ +import { useState } from "react"; +import { Grid } from "../../../../components/grid/Grid"; +import { Tab, Tabs } from "@mui/material"; +import { Dashboard } from "../dashboard/Dashboard"; +import { SlaughterDashboard } from "../dashboard-slaughter/SlaughterDashboard"; +// import { DashboardSlaughterPerformance } from "../dashboard-slaughter-performance/DashboardSlaughterPerformance"; +import { DashboardPeriodicPerformance } from "../dashboard-periodic-performance/DashboardPeriodicPerformance"; +import { DashboardSlaughterPerformance } from "../dashboard-slaughter-performance/DashboardSlaughterPerformance"; +import { DashboardEquivalentTab } from "../dashboard-equivalent-tab/DashboardEquivalentTab"; + +export const DashboardTab = () => { + const [value, setValue] = useState(0); + + const handleChange = (event, newValue) => { + setValue(newValue); + }; + return ( + + + + + + + + {/* */} + + + {value === 0 && } + {value === 1 && } + {value === 2 && } + {value === 3 && } + {value === 4 && } + + + + ); +}; diff --git a/src/features/dashboard/components/dashboard-ware-house-info-section/WarehouseInfoSection.js b/src/features/dashboard/components/dashboard-ware-house-info-section/WarehouseInfoSection.js new file mode 100644 index 0000000..2cd2805 --- /dev/null +++ b/src/features/dashboard/components/dashboard-ware-house-info-section/WarehouseInfoSection.js @@ -0,0 +1,85 @@ +import { Box, Typography } from "@mui/material"; + +const warehouseItems = [ + { label: "وزن ورودی به انبار:", key: "enterWarehouseWeight" }, + { label: "وزن فروش به خارج استان:", key: "outSellWeight" }, + { label: "وزن توزیع به داخل استان:", key: "allocationWeight" }, + { label: "وزن مانده در انبار کشتارگاه:", key: "leftOverWarehouseWeight" }, +]; + +const WarehouseRow = ({ label, value }) => ( + + + {label} + + + + {value?.toLocaleString() || 0} + + + کیلوگرم + + + +); + +export const WarehouseInfoSection = ({ boxStats, sx }) => ( + + + اطلاعات انبار و توزیع امروز + + + + {warehouseItems.map((item) => ( + + ))} + + +); diff --git a/src/features/dashboard/components/dashboard-yesterday-killing-report/YesterdayKillingReport.js b/src/features/dashboard/components/dashboard-yesterday-killing-report/YesterdayKillingReport.js new file mode 100644 index 0000000..92f10ab --- /dev/null +++ b/src/features/dashboard/components/dashboard-yesterday-killing-report/YesterdayKillingReport.js @@ -0,0 +1,116 @@ +import { Box, Typography } from "@mui/material"; +import { SPACING } from "../../../../data/spacing"; + +const reportItems = [ + { label: "حجم درخواست کشتار مرغدار:", key: "quantityYesterday" }, + { label: "وزن درخواست کشتار مرغدار:", key: "totalWeightYesterday" }, + { label: "حجم خرید های مستقیم :", key: "killRequestQuantityYesterday" }, + { label: "وزن خرید های مستقیم :", key: "killRequestWeightYesterday" }, + { + label: "حجم خرید های خارج از استان (زنده) :", + key: "quantityKillHouseFreeBarLiveYesterday", + }, + { + label: "وزن خرید های خارج از استان (زنده) :", + key: "WeightKillHouseFreeBarLiveYesterday", + }, + { + label: "وزن خرید های خارج از استان (لاشه) :", + key: "WeightKillHouseFreeBarCarcassYesterday", + }, + { + label: "حجم کل تخصیصات (خرید مستقیم/ مرغدار ):", + key: "provinceKillRequestQuantityYesterday", + }, + { + label: "وزن کل تخصیصات (خرید مستقیم/ مرغدار ):", + key: "provinceKillRequestWeightCarcassYesterday", + }, + { + label: "حجم فروش به خارج استان:", + key: "poultryOutProvinceQuantityYesterday", + }, + { + label: "وزن فروش به خارج استان:", + key: "poultryOutProvinceWeightYesterday", + }, + { label: "حجم بارها:", key: "KillHouseRequestQuantityYesterday" }, + { label: "وزن بارها:", key: "KillHouseRequestWeightYesterday" }, + { + label: "لاشه تولیدی با احتساب 25درصد افت کشتار :", + key: "totalLossWeightYesterday", + }, +]; + +const ReportRow = ({ label, value }) => ( + + + {label} + + + {value?.toLocaleString() || 0} + + +); + +export const YesterdayKillingReport = ({ boxStats }) => ( + + + گزارش کشتار دیروز مرغ گوشتی استان + + + + {reportItems.map((item, index) => ( + + ))} + + +); diff --git a/src/features/dashboard/components/dashboard/Dashboard.js b/src/features/dashboard/components/dashboard/Dashboard.js new file mode 100644 index 0000000..03f2ee4 --- /dev/null +++ b/src/features/dashboard/components/dashboard/Dashboard.js @@ -0,0 +1,590 @@ +import { Typography, Avatar, Badge, Chip, Box, Button } from "@mui/material"; +import { Tooltip as MUITooltip } from "@mui/material"; +import { + LOADING_END, + LOADING_START, +} from "../../../../lib/redux/slices/appSlice"; +import { useEffect, useState } from "react"; +import { useDispatch } from "react-redux"; +import { + Chart as ChartJs, + ArcElement, + Tooltip, + Legend, + BarElement, + CategoryScale, + LinearScale, + LineElement, + PointElement, +} from "chart.js"; +import ChartDataLabels from "chartjs-plugin-datalabels"; +import { PieChartSection } from "../dashboard-pie-chart-section/PieChartSection"; +import { InventorySection } from "../dashboard-inventory-section/InventorySection"; +import { WarehouseInfoSection } from "../dashboard-ware-house-info-section/WarehouseInfoSection"; +import { PriceChartSection } from "../dashboard-price-chart-section/PriceChartSection"; +import AnnouncementIcon from "@mui/icons-material/Announcement"; +import { getUnseenMessages } from "../../../authentication/services/getUnseenMessage"; +import { motion } from "framer-motion"; +import CircleNotificationsIcon from "@mui/icons-material/CircleNotifications"; +import { useNavigate } from "react-router-dom"; +import { YesterdayKillingReport } from "../dashboard-yesterday-killing-report/YesterdayKillingReport"; +import { BarChartSection } from "../dashboard-bar-chart-section/BarChartSection"; +import { DailykillingReport } from "../dashboard-daily-killing-report/DailyKillingReport "; +import { Grid } from "../../../../components/grid/Grid"; +import { SPACING } from "../../../../data/spacing"; +import { StatBox } from "../dashboard-state-box/StatBox"; +import { dashboardGetMonitoringService } from "../../services/dashboard-get-service"; +import { dashboardGetTicketService } from "../../services/dashboard-ticket-service"; +import { dashboardGetNewsService } from "../../services/dashboard-get-news-service"; +import ResponsiveTable from "../../../../components/responsive-table/ResponsiveTable"; +import axios from "axios"; +import { RiFileExcel2Fill } from "react-icons/ri"; + +ChartJs.register( + ArcElement, + Tooltip, + Legend, + ChartDataLabels, + BarElement, + CategoryScale, + LinearScale, + LineElement, + PointElement +); + +export const Dashboard = () => { + const dispatch = useDispatch(); + + const [boxStats, setBoxStats] = useState({ + hatching: {}, + yesterdayKilling: {}, + Killing: {}, + inventory: {}, + warehouseKillHouse: {}, + warehouseInformation: {}, + chickenPrice: [], + }); + + const [notifications, setNotifications] = useState([]); + const [tickets, setTickets] = useState([]); + const [unseenMessages, setUnseenMessages] = useState({ + state: false, + num: 0, + }); + const navigate = useNavigate(); + + useEffect(() => { + dispatch(LOADING_START()); + dispatch(dashboardGetMonitoringService()).then((r) => { + if (r.payload?.data) { + setBoxStats(r.payload.data); + } + dispatch(LOADING_END()); + }); + }, [dispatch]); + + useEffect(() => { + dispatch(LOADING_START()); + dispatch(dashboardGetNewsService()).then((r) => { + if (r.payload?.data) { + const formattedNotifications = r.payload.data.map((item) => ({ + id: item.id, + title: item.title, + date: item.created_at, + type: item.status || "تازه", + message: item.text, + isNew: true, + })); + setNotifications(formattedNotifications); + } else { + setNotifications([]); + } + dispatch(LOADING_END()); + }); + }, [dispatch]); + + useEffect(() => { + dispatch(LOADING_START()); + dispatch(dashboardGetTicketService()).then((r) => { + if (r.payload?.data) { + const ticketsData = Array.isArray(r.payload.data) + ? r.payload.data + : [r.payload.data]; + setTickets(ticketsData); + } else { + setTickets([]); + } + dispatch(LOADING_END()); + }); + }, [dispatch]); + + useEffect(() => { + dispatch(getUnseenMessages()).then((r) => { + setUnseenMessages(r.payload.data); + }); + }, [window.location.pathname]); + + const handleNotificationClick = (id) => { + navigate(`/ticket/${id}/false`); + }; + + const statBoxes = [ + { + title: "حجم جوجه ریزی فعال (قطعه)", + value: boxStats?.hatching?.quantity || 0, + }, + { + title: "حجم کشتار شده (قطعه)", + value: boxStats?.hatching?.killedQuantity || 0, + }, + { + title: "حجم مانده در سالن (قطعه)", + value: boxStats?.hatching?.leftOver || 0, + }, + { + title: "حجم مانده در سالن بزرگتر از 40 روز(قطعه) ", + value: boxStats?.hatching?.leftOverBetweenFortySeventyFive || 0, + }, + { + title: "میانگین سن کشتار فارم های فعال", + value: boxStats?.hatching?.killingAveAge || 0, + }, + ]; + + return ( + + + + + + + + آخرین اطلاعیه و اخبار + + + + {notifications.length > 0 ? ( + + {notifications.map((notification) => ( + + + + {notification.title} + + + {notification.message} + + + + + {notification.date} + + + + + + ))} + + ) : ( + + + اخبار جدیدی وجود ندارد + + + )} + + + + + + + تیکت های خوانده نشده + + {unseenMessages?.state ? ( + + + + + + ) : ( + + )} + + + {tickets.length > 0 ? ( + + {tickets.map((ticket) => ( + + { + handleNotificationClick(ticket?.ticketId); + }} + > + + {ticket.user?.fullname?.charAt(0) || ""} + + + {ticket.user?.fullname || "نامشخص"} + + {ticket.unread_message && ( + + )} + + + {ticket.title} + + + ))} + + ) : ( + + + تیکتی جهت نمایش وجود ندارد + + + )} + + + + + + + آمار جوجه ریزی استان + + + + {statBoxes.map((box, index) => ( + + + + ))} + + + + + + + + + } + data={[ + [ + boxStats?.hatching?.totalLeftOverLt35?.toLocaleString() || "0", + boxStats?.hatching?.totalLeftOverBetween3540?.toLocaleString() || + "0", + boxStats?.hatching?.totalLeftOverBetween4045?.toLocaleString() || + "0", + boxStats?.hatching?.totalLeftOverBetween4550?.toLocaleString() || + "0", + boxStats?.hatching?.totalLeftOverBetween5055?.toLocaleString() || + "0", + boxStats?.hatching?.totalLeftOverBetween5560?.toLocaleString() || + "0", + boxStats?.hatching?.totalLeftOverBetween6065?.toLocaleString() || + "0", + boxStats?.hatching?.totalLeftOverBetween6570?.toLocaleString() || + "0", + boxStats?.hatching?.totalLeftOverGt70?.toLocaleString() || "0", + ], + ]} + allColors={{ color: "#244CCC", text: "#fff" }} + columns={[ + "کمتر از 35 روز", + "بین 35 تا 40 روز", + "بین 40 تا 45 روز", + "بین 45 تا 50 روز", + "بین 50 تا 55 روز", + "بین 55 تا 60 روز", + "بین 60 تا 65 روز", + "بین 65 تا 70 روز", + "بیش از 70 روز", + ]} + title="مانده در سالن (قطعه)" + /> + + + + + + + + + + + + + + + + + + + + + + + + + + + + ); +}; diff --git a/src/features/dashboard/services/dahsboard-get-equivalent-info.js b/src/features/dashboard/services/dahsboard-get-equivalent-info.js new file mode 100644 index 0000000..5c75f11 --- /dev/null +++ b/src/features/dashboard/services/dahsboard-get-equivalent-info.js @@ -0,0 +1,15 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; +import axios from "axios"; + +export const dashboardGetEquivalentInfoService = createAsyncThunk( + "DASHBOARD_GET_EQUIVALENT_INFO_SERVICE", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + const { data, status } = await axios.get("kill-house-comparative-info", { + params: d, + }); + dispatch(LOADING_END()); + return { data, status }; + } +); diff --git a/src/features/dashboard/services/dashboard-get-news-service.js b/src/features/dashboard/services/dashboard-get-news-service.js new file mode 100644 index 0000000..3d64001 --- /dev/null +++ b/src/features/dashboard/services/dashboard-get-news-service.js @@ -0,0 +1,19 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; +import axios from "axios"; +import { getRoleFromUrl } from "../../../utils/getRoleFromUrl"; + +export const dashboardGetNewsService = createAsyncThunk( + "DASHBOARD_GET_NEWS_SERVICE", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + const { data, status } = await axios.get("dashboard_notification/", { + params: { + role: getRoleFromUrl(), + ...d, + }, + }); + dispatch(LOADING_END()); + return { data, status }; + } +); diff --git a/src/features/dashboard/services/dashboard-get-service.js b/src/features/dashboard/services/dashboard-get-service.js new file mode 100644 index 0000000..9b74c01 --- /dev/null +++ b/src/features/dashboard/services/dashboard-get-service.js @@ -0,0 +1,35 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; +import axios from "axios"; + +export const dashboardGetMonitoringService = createAsyncThunk( + "DASHBOARD_GET_MONITORING_SERVICE", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + const { data, status } = await axios.get("dashboard_monitoring_view/", { + params: { + ...d, + }, + }); + dispatch(LOADING_END()); + return { data, status }; + } +); +export const dashboardGetMonitoringBarAndKillingService = createAsyncThunk( + "DASHBOARD_GET_MONITORING_BAR_SERVICE", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + const { data, status } = await axios.get( + "dashboard_monitoring_bar_and_killing", + { + params: { + date1: d.date1, + date2: d.date2, + ...d, + }, + } + ); + dispatch(LOADING_END()); + return { data, status }; + } +); diff --git a/src/features/dashboard/services/dashboard-slaughter-get-information.js b/src/features/dashboard/services/dashboard-slaughter-get-information.js new file mode 100644 index 0000000..1819d83 --- /dev/null +++ b/src/features/dashboard/services/dashboard-slaughter-get-information.js @@ -0,0 +1,22 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; +import axios from "axios"; + +export const dashboardGetSlaughterInformationService = createAsyncThunk( + "DASHBOARD_GET_SLAUGHTER_INFORMATION_SERVICE", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + const { data, status } = await axios.get( + "kill-house-performance-dashboard", + { + params: { + date1: d.date1, + date2: d.date2, + ...d, + }, + } + ); + dispatch(LOADING_END()); + return { data, status }; + } +); diff --git a/src/features/dashboard/services/dashboard-slaughter-performance.js b/src/features/dashboard/services/dashboard-slaughter-performance.js new file mode 100644 index 0000000..688d299 --- /dev/null +++ b/src/features/dashboard/services/dashboard-slaughter-performance.js @@ -0,0 +1,18 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; +import axios from "axios"; + +export const dashboardGetSlaughterManagementKillHouse = createAsyncThunk( + "MANAGEMENT_KILLHOUSE_DASHBOARD", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + const { data, status } = await axios.get( + "management_kill_house_dashboard", + { + params: d, + } + ); + dispatch(LOADING_END()); + return { data, status }; + } +); diff --git a/src/features/dashboard/services/dashboard-slaughter-periodic-performance.js b/src/features/dashboard/services/dashboard-slaughter-periodic-performance.js new file mode 100644 index 0000000..0c0cf10 --- /dev/null +++ b/src/features/dashboard/services/dashboard-slaughter-periodic-performance.js @@ -0,0 +1,18 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; +import axios from "axios"; + +export const dashboardGetSlaughterPeriodicPerformance = createAsyncThunk( + "PERIODIC_PERFORMANCE_REPORT_DASHBOARD", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + const { data, status } = await axios.get( + "periodic_performance_report_dashboard", + { + params: d, + } + ); + dispatch(LOADING_END()); + return { data, status }; + } +); diff --git a/src/features/dashboard/services/dashboard-ticket-service.js b/src/features/dashboard/services/dashboard-ticket-service.js new file mode 100644 index 0000000..1527aed --- /dev/null +++ b/src/features/dashboard/services/dashboard-ticket-service.js @@ -0,0 +1,20 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; +import axios from "axios"; + +export const dashboardGetTicketService = createAsyncThunk( + "DASHBOARD__GET_TICKET_SERVICE", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + const { data, status } = await axios.get( + "get_unread_ticket_for_dashboard/", + { + params: { + ...d, + }, + } + ); + dispatch(LOADING_END()); + return { data, status }; + } +); diff --git a/src/features/driver/components/driver-cars/DriverCars.js b/src/features/driver/components/driver-cars/DriverCars.js new file mode 100644 index 0000000..d1c9594 --- /dev/null +++ b/src/features/driver/components/driver-cars/DriverCars.js @@ -0,0 +1,83 @@ +import { Card, Grid } from "@mui/material"; +import { AdvancedTable } from "../../../../components/advanced-table/AdvancedTable"; +import { SPACING } from "../../../../data/spacing"; +import { useFormik } from "formik"; +import moment from "moment"; +import { Yup } from "../../../../lib/yup/yup"; +import { useDispatch, useSelector } from "react-redux"; +import { useEffect, useState } from "react"; +import { driverGetCars } from "../../services/driver-get-cars"; + +export const DriverCars = () => { + const [dataTable, setDataTable] = useState([]); + const { driverCars } = useSelector((state) => state.driverSlice); + const dispatch = useDispatch(); + + useEffect(() => { + dispatch(driverGetCars()); + }, []); + + useEffect(() => { + const d = driverCars.map((item, i) => { + return [ + i + 1, + item.name, + item.typeCar, + item.pelak, + item.capocity, + item.healthCode, + item.typeWeight, + ]; + }); + + setDataTable(d); + }, [driverCars]); + + const [tableDataCol] = useState([ + "ردیف", + "نام", + "نوع خودرو", + "پلاک", + "ظرفیت", + "کد بهداشتی", + "وزن", + ]); + + const formik = useFormik({ + initialValues: { + capacity: "", + recieveTime: "", + recieveDate: moment(Date()).format("YYYY-MM-DD hh:mm:ss"), + }, + validationSchema: Yup.object({ + capacity: Yup.number() + .required("این فیلد اجباری است!") + .typeError("لطفا عدد وارد کنید!"), + recieveTime: Yup.string() + .required("این فیلد اجباری است!") + .typeError("لطفا وزن را وارد کنید!"), + }), + }); + + useEffect(() => { + formik.validateForm(); + }, []); + + return ( + + + + + + ); +}; diff --git a/src/features/driver/components/driver-operations/DriverOperations.js b/src/features/driver/components/driver-operations/DriverOperations.js new file mode 100644 index 0000000..7aebd51 --- /dev/null +++ b/src/features/driver/components/driver-operations/DriverOperations.js @@ -0,0 +1,39 @@ +import { Grid } from "../../../../components/grid/Grid"; +import { SPACING } from "../../../../data/spacing"; +import { NavLink } from "../../../../components/nav-link/NavLink"; +import { useLocation } from "react-router-dom"; +import { Button } from "@mui/material"; +import { + ROUTE_DRIVER_CARS, + ROUTE_DRIVER_REQUESTS, +} from "../../../../routes/routes"; + +export const DriverOperations = () => { + const { pathname } = useLocation(); + + return ( + + + + + + + + + ); +}; diff --git a/src/features/driver/components/driver-profile/DriverProfile.js b/src/features/driver/components/driver-profile/DriverProfile.js new file mode 100644 index 0000000..d7d677b --- /dev/null +++ b/src/features/driver/components/driver-profile/DriverProfile.js @@ -0,0 +1,58 @@ +import { Box } from "@mui/system"; +import { useEffect } from "react"; +import { useDispatch, useSelector } from "react-redux"; +import { Grid } from "../../../../components/grid/Grid"; +import { SimpleTable } from "../../../../components/simple-table/SimpleTable"; +import { SPACING } from "../../../../data/spacing"; +import { + LOADING_END, + LOADING_START, +} from "../../../../lib/redux/slices/appSlice"; +import { ChangeCardInfo } from "../../../authentication/components/change-card-info/ChangeCardInfo"; +import { driverGetProfile } from "../../services/driver-get-profile"; + +export const DriverProfile = () => { + const { profile } = useSelector((state) => state.driverSlice); + const dispatch = useDispatch(); + + useEffect(() => { + dispatch(LOADING_START()); + dispatch(driverGetProfile()).then((r) => { + dispatch(LOADING_END()); + }); + }, []); + + return ( + + + + + <> + + + + + + + + + + + + ); +}; diff --git a/src/features/driver/components/driver-requests/DriverRequests.js b/src/features/driver/components/driver-requests/DriverRequests.js new file mode 100644 index 0000000..14f3f5f --- /dev/null +++ b/src/features/driver/components/driver-requests/DriverRequests.js @@ -0,0 +1,165 @@ +import { Button, Card, Grid } from "@mui/material"; +import { AdvancedTable } from "../../../../components/advanced-table/AdvancedTable"; +import { SPACING } from "../../../../data/spacing"; +import { useFormik } from "formik"; +import moment from "moment"; +import { Yup } from "../../../../lib/yup/yup"; +import { useDispatch, useSelector } from "react-redux"; +import { useEffect, useState } from "react"; +import { driverGetRequests } from "../../services/driver-get-requests"; +import { DRAWER } from "../../../../lib/redux/slices/appSlice"; +import { DriverSubmitCancellationRequest } from "../driver-submit-cancellation-request/DriverSubmitCancellationRequest"; +import { format } from "date-fns-jalali"; + +export const DriverRequests = () => { + const [dataTable, setDataTable] = useState([]); + const [archiveDataTable, setArchiveDataTable] = useState([]); + const { driverRequests } = useSelector((state) => state.driverSlice); + const dispatch = useDispatch(); + + useEffect(() => { + dispatch(driverGetRequests()); + }, []); + + useEffect(() => { + const d = driverRequests + ?.filter((item) => item.vetState === "pending") + .map((item, i) => { + return [ + i + 1, + item.barCode, + item.car.typeCar, + item.car.pelak, + item?.poultry?.poultryName, + item?.poultry?.poultryMobile, + item?.poultry?.poultryProvince + + " - " + + item?.poultry?.poultryCity + + " - " + + item?.poultry?.poultryAddress, + item.killhouseUser.name, + item.killhouseUser?.killHouseOperator?.user?.mobile, + item.killhouseUser?.address?.address, + format(new Date(item.killRequest.reciveDate), "yyyy/MM/dd"), + item.killRequest.reciveTime, + , + ]; + }); + + setDataTable(d); + }, [driverRequests]); + + useEffect(() => { + const d = driverRequests + ?.filter((item) => item.vetState !== "pending") + .map((item, i) => { + return [ + i + 1, + item.barCode, + item.car.typeCar, + item.car.pelak, + item?.poultry?.poultryName, + item?.poultry?.poultryMobile, + item?.poultry?.poultryProvince + + " - " + + item?.poultry?.poultryCity + + " - " + + item?.poultry?.poultryAddress, + item.killhouseUser.name, + item.killhouseUser?.killHouseOperator?.user?.mobile, + item.killhouseUser?.address?.address, + format(new Date(item.killRequest.reciveDate), "yyyy/MM/dd"), + item.killRequest.reciveTime, + ]; + }); + + setArchiveDataTable(d); + }, [driverRequests]); + + const formik = useFormik({ + initialValues: { + capacity: "", + recieveTime: "", + recieveDate: moment(Date()).format("YYYY-MM-DD hh:mm:ss"), + }, + validationSchema: Yup.object({ + capacity: Yup.number() + .required("این فیلد اجباری است!") + .typeError("لطفا عدد وارد کنید!"), + recieveTime: Yup.string() + .required("این فیلد اجباری است!") + .typeError("لطفا وزن را وارد کنید!"), + }), + }); + + useEffect(() => { + formik.validateForm(); + }, []); + + return ( + + + + + + + ); +}; diff --git a/src/features/driver/components/driver-submit-cancellation-request/DriverSubmitCancellationRequest.js b/src/features/driver/components/driver-submit-cancellation-request/DriverSubmitCancellationRequest.js new file mode 100644 index 0000000..c2f66a0 --- /dev/null +++ b/src/features/driver/components/driver-submit-cancellation-request/DriverSubmitCancellationRequest.js @@ -0,0 +1,115 @@ +import { Button, TextField } from "@mui/material"; +import { Grid } from "../../../../components/grid/Grid"; +import { SPACING } from "../../../../data/spacing"; +import React, { useContext, useEffect } from "react"; +import { Yup } from "../../../../lib/yup/yup"; +import { useFormik } from "formik"; +import { useDispatch } from "react-redux"; +import { driverSubmitCancellationRequest } from "../../services/driver-submit-cancellation-request"; +import { + DRAWER, + LOADING_END, + LOADING_START, +} from "../../../../lib/redux/slices/appSlice"; +import { PropTypes } from "prop-types"; +import { AppContext } from "../../../../contexts/AppContext"; + +export const DriverSubmitCancellationRequest = ({ item }) => { + const [openNotif] = useContext(AppContext); + const dispatch = useDispatch(); + const formik = useFormik({ + initialValues: { + description: "", + }, + validationSchema: Yup.object({ + description: Yup.string() + .required("این فیلد اجباری است!") + .typeError("لطفا فیلد را پر کنید!"), + }), + }); + + useEffect(() => { + formik.validateForm(); + }, []); + + return ( + + + + + + + + + + + ); +}; + +DriverSubmitCancellationRequest.propTypes = { + item: PropTypes.any, +}; diff --git a/src/features/driver/services/driver-get-cars.js b/src/features/driver/services/driver-get-cars.js new file mode 100644 index 0000000..f11f7d5 --- /dev/null +++ b/src/features/driver/services/driver-get-cars.js @@ -0,0 +1,7 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; + +export const driverGetCars = createAsyncThunk("DRIVER_GET_CARS", async () => { + const { data, status } = await axios.get("driver/?my_car"); + return { data, status }; +}); diff --git a/src/features/driver/services/driver-get-profile.js b/src/features/driver/services/driver-get-profile.js new file mode 100644 index 0000000..023891e --- /dev/null +++ b/src/features/driver/services/driver-get-profile.js @@ -0,0 +1,10 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; + +export const driverGetProfile = createAsyncThunk( + "DRIVER_GET_PROFILE", + async () => { + const { data, status } = await axios.get("driver/0/?profile"); + return { data, status }; + } +); diff --git a/src/features/driver/services/driver-get-requests.js b/src/features/driver/services/driver-get-requests.js new file mode 100644 index 0000000..2475379 --- /dev/null +++ b/src/features/driver/services/driver-get-requests.js @@ -0,0 +1,10 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; + +export const driverGetRequests = createAsyncThunk( + "DRIVER_GET_REQUESTS", + async () => { + const { data, status } = await axios.get("driver/?my_allocations"); + return { data, status }; + } +); diff --git a/src/features/driver/services/driver-submit-cancellation-request.js b/src/features/driver/services/driver-submit-cancellation-request.js new file mode 100644 index 0000000..59b0207 --- /dev/null +++ b/src/features/driver/services/driver-submit-cancellation-request.js @@ -0,0 +1,10 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; + +export const driverSubmitCancellationRequest = createAsyncThunk( + "DRIVER_CANCELLATION_REQUEST", + async (d) => { + const { data, status } = await axios.post("driver_cancel/", d); + return { data, status }; + } +); diff --git a/src/features/file/components/aviculture-bar-form/AvicultureBarForm.js b/src/features/file/components/aviculture-bar-form/AvicultureBarForm.js new file mode 100644 index 0000000..ee72cf6 --- /dev/null +++ b/src/features/file/components/aviculture-bar-form/AvicultureBarForm.js @@ -0,0 +1,111 @@ +import { SPACING } from "../../../../data/spacing"; +import UploadIcon from "@mui/icons-material/Upload"; +import { Grid } from "../../../../components/grid/Grid"; +import { Button, Card, TextField, Typography } from "@mui/material"; +import { useFormik } from "formik"; +import { Yup } from "../../../../lib/yup/yup"; +import { useEffect, useState } from "react"; + +export const AvicultureBarForm = () => { + const [barWeight, setbarWeight] = useState(0); + const formik = useFormik({ + initialValues: { + firstweight: "", + lastweight: "", + }, + validationSchema: Yup.object({ + firstweight: Yup.number() + .required("این فیلد اجباری است!") + .typeError("لطفا عدد وارد کنید!"), + lastweight: Yup.number() + .required("این فیلد اجباری است!") + .typeError("لطفا وزن را وارد کنید!"), + }), + }); + + useEffect(() => { + formik.validateForm(); + }, []); + + useEffect(() => { + const numFirstWeight = Number(formik.values.firstweight); + const numLastWeight = Number(formik.values.lastweight); + if (numFirstWeight && numLastWeight) { + if (numFirstWeight < numLastWeight) { + setbarWeight(numLastWeight - numFirstWeight); + } else { + setbarWeight(0); + } + } + }, [formik.values.firstweight, formik.values.lastweight]); + + return ( + <> + + + + + + + + + وزن بار: {barWeight} کیلوگرم + + + + + + ); +}; diff --git a/src/features/file/components/bank-account-information/BankAccountInformation.js b/src/features/file/components/bank-account-information/BankAccountInformation.js new file mode 100644 index 0000000..24467c1 --- /dev/null +++ b/src/features/file/components/bank-account-information/BankAccountInformation.js @@ -0,0 +1,87 @@ +import { PropTypes } from "prop-types"; +// import { Typography } from "@mui/material"; +import { Grid } from "../../../../components/grid/Grid"; +import { SPACING } from "../../../../data/spacing"; +import BankCard from "../../../../components/bank-card/BankCard"; +// import { Typography } from "@mui/material"; + +export const BankAccountInformation = ({ + card, + shaba, + info, + price, + priceText, + bankName, + bankUser, +}) => { + return ( + + + + + + {/* + + + اطلاعات بانکی جهت واریز مبلغ: + + + + + + شماره کارت + + {card} + + + + شماره شبا + + {shaba} + + + + + مبلغ قابل پرداخت + + + {price?.toLocaleString()} ریال + + + + + مبلغ قابل پرداخت به حروف + + + {priceText} + + + + + + {info} + + + */} + + ); +}; + +BankAccountInformation.propTypes = { + card: PropTypes.string, + shaba: PropTypes.string, + info: PropTypes.string, + price: PropTypes.any, + priceText: PropTypes.any, +}; diff --git a/src/features/file/components/check-request-item/CheckRequestItem.js b/src/features/file/components/check-request-item/CheckRequestItem.js new file mode 100644 index 0000000..655fd20 --- /dev/null +++ b/src/features/file/components/check-request-item/CheckRequestItem.js @@ -0,0 +1,297 @@ +import { Button, TextField, Typography } from "@mui/material"; +import React, { useState } from "react"; +import { SPACING } from "../../../../data/spacing"; +import { AnimatePresence, motion } from "framer-motion"; +import { + CLOSE_MODAL, + DRAWER, + LOADING_END, + LOADING_START, + OPEN_MODAL, +} from "../../../../lib/redux/slices/appSlice"; +import { checkRequestBySlaughter } from "../../services/checkRequestBySlaughter"; +import { useFormik } from "formik"; +import { Yup } from "../../../../lib/yup/yup"; +import { useDispatch, useSelector } from "react-redux"; +import { PropTypes } from "prop-types"; +import { getAllocationInformation } from "../../services/get-allocation-information"; +import { Grid } from "../../../../components/grid/Grid"; +import { useParams } from "react-router-dom"; +import { getAcceptedSlaughterRequest } from "../../services/getAcceptedSlaughterRequest"; +import { useContext } from "react"; +import { AppContext } from "../../../../contexts/AppContext"; +import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl"; +import { slaughterGetActiveRequests } from "../../../slaughter-house/services/slaughter-get-active-requests"; +import { checkPathStartsWith } from "../../../../utils/checkPathStartsWith"; + +export default function CheckRequestItem({ reqKey, poultryRequestKey }) { + const [openNotif] = useContext(AppContext); + const [isDenyed, setisDenyed] = useState(false); + const dispatch = useDispatch(); + const { id } = useParams(); + const selectedSubUser = useSelector( + (state) => state.userSlice.selectedSubUser + ); + const [, , selectedDate1, , selectedDate2] = useContext(AppContext); + + const formik = useFormik({ + initialValues: { + rejectText: "", + }, + validationSchema: Yup.object({ + rejectText: Yup.string() + .required("این فیلد اجباری است!") + .typeError("لطفا دلیل خود را بیان کنید."), + }), + }); + + const acceptButtonText = + getRoleFromUrl() === "ProvinceOperator" + ? "ثبت اطلاعات بجای کشتارگاه" + : "ثبت اطلاعات و ارسال به استان"; + + const rejectButtonText = + getRoleFromUrl() === "ProvinceOperator" + ? "رد اطلاعات بجای کشتارگاه" + : "رد اطلاعات و پیام به استان"; + + return ( + + + + {isDenyed ? ( + + + + + + + + + + + + + + + + + ) : ( + + + + + + ), + }) + ); + } + }); + }} + > + {acceptButtonText} + + + )} + +
    +
    + ); +} +CheckRequestItem.propTypes = { + reqKey: PropTypes.string, + poultryRequestKey: PropTypes.string, +}; diff --git a/src/features/file/components/city-file-operations/CityFileOperations.js b/src/features/file/components/city-file-operations/CityFileOperations.js new file mode 100644 index 0000000..283f8a9 --- /dev/null +++ b/src/features/file/components/city-file-operations/CityFileOperations.js @@ -0,0 +1,439 @@ +import { + TimelineConnector, + TimelineContent, + // TimelineContent, + TimelineDot, + TimelineItem, + TimelineOppositeContent, + TimelineSeparator, +} from "@mui/lab"; +import { + Button, + // FormControl, + // FormControlLabel, + // FormLabel, + // Radio, + // RadioGroup, + TextField, + Typography, +} from "@mui/material"; +import React, { useState } from "react"; +// import { formatTime } from "../../../../utils/formatTime"; +import { PropTypes } from "prop-types"; +import { SPACING } from "../../../../data/spacing"; +import { Grid } from "../../../../components/grid/Grid"; +import { AnimatePresence, motion } from "framer-motion"; +import { useDispatch } from "react-redux"; +import { checkRequestByCity } from "../../services/checkRequestByCity"; +import { useFormik } from "formik"; +import { Yup } from "../../../../lib/yup/yup"; +import { + CLOSE_MODAL, + DRAWER, + LOADING_END, + LOADING_START, + OPEN_MODAL, +} from "../../../../lib/redux/slices/appSlice"; +import useUserProfile from "../../../authentication/hooks/useUserProfile"; +import { getFileFromApi } from "../../hooks/useRequestFile"; +import { useContext } from "react"; +import { AppContext } from "../../../../contexts/AppContext"; +import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl"; +import { avicultureGetRequests } from "../../../aviculture/services/aviculture-requests"; +import { getProvinceNewRequests } from "../../../province/services/get-province-new-requests"; +import { avicultureRequestsStateProcessService } from "../../../aviculture/services/aviculture-requests-state-process"; + +const CityFileOperations = ({ id, file, updateTable }) => { + // const myFile = useRequestFile(id); + // const file = myFile?.file?.process; + const [openNotif, , selectedDate1, , selectedDate2, ,] = + useContext(AppContext); + const [isSubmited] = useState(false); + const [roles] = useUserProfile(); + + // useEffect(() => { + // if (file?.city !== null) { + // setIsSubmited(true); + // } + // }, []); + + const formik = useFormik({ + initialValues: { + rejectText: "", + canHaching: "False", + }, + validationSchema: Yup.object({ + rejectText: Yup.string() + .required("این فیلد اجباری است!") + .typeError("لطفا دلیل خود را بیان کنید."), + }), + }); + const [isDenyed, setisDenyed] = useState(false); + + const showHatchingAllowed = + file?.hatching?.allowHatching === "pending" && + file?.hatching?.leftOver !== 0; + const buttonState = !formik.values.canHaching && showHatchingAllowed; + + // const animationControl = useAnimation(); + + // useEffect(() => { + // if (isDenyed) { + // animationControl.start({ + // x: -10, + // display: "block", + // transition: { duration: 0.3 }, + // }); + // } + // }, [isDenyed]); + + // const MotionInput = motion(TextField); + const dispatch = useDispatch(); + const acceptButtonText = + getRoleFromUrl() === "ProvinceOperator" + ? "تایید اطلاعات بجای شهرستان" + : "ثبت اطلاعات و ارسال به استان"; + return ( + <> + {!isSubmited && ( + + + + + + + + + + انجام عملیات + + + + + + در این مرحله درخواست را تایید یا رد کنید. + + + + + + + + + {isDenyed ? ( + + + + + + + + + + + + + + + + + ) : ( + + + + + تعداد درخواست کشتار: + + + {file?.quantity?.toLocaleString()} قطعه + + + + + تعداد باقی مانده از جوجه ریزی: + + + {file?.hatching?.leftOver?.toLocaleString()} قطعه + + + {!!showHatchingAllowed && ( + + {/* + + + مرغدار اجازه جوجه ریزی ...... + + { + formik.setFieldValue( + "canHaching", + event.currentTarget.value + ); + }} + value={formik.values.canHaching} + > + } + label="دارد" + /> + } + label="ندارد" + /> + + + + مرغ دار اجازه جوجه ریزی دارد بدین معناست + که باقی مانده مرغ صفر در نظر گرفته می شود + و مرغ دار اجازه جوجه ریزی برای سالن خود را + خواهد داشت. + + + + */} + + )} + + + + + + + + ), + }) + ); + } + } + }); + }} + > + {acceptButtonText} + + + + + )} + + + + + + + )} + + ); +}; +CityFileOperations.propTypes = { + file: PropTypes.object, +}; + +export default CityFileOperations; diff --git a/src/features/file/components/city-information/CityInformation.js b/src/features/file/components/city-information/CityInformation.js new file mode 100644 index 0000000..05574dc --- /dev/null +++ b/src/features/file/components/city-information/CityInformation.js @@ -0,0 +1,153 @@ +import { SimpleTable } from "../../../../components/simple-table/SimpleTable"; +import { PropTypes } from "prop-types"; +import { useEffect, useState } from "react"; +import TimelineSeparator from "@mui/lab/TimelineSeparator"; +import TimelineDot from "@mui/lab/TimelineDot"; +import TimelineConnector from "@mui/lab/TimelineConnector"; +import { Grid } from "../../../../components/grid/Grid"; +import TimelineOppositeContent from "@mui/lab/TimelineOppositeContent"; +import { Typography } from "@mui/material"; +import TimelineContent from "@mui/lab/TimelineContent"; +import { SPACING } from "../../../../data/spacing"; +import TimelineItem from "@mui/lab/TimelineItem"; +import { formatTime } from "../../../../utils/formatTime"; +import { format } from "date-fns-jalali"; + +export const CityInformation = ({ file }) => { + const [cityInfoData, setCityInfo] = useState({ + cityOperatorName: "اپراتور شهرستان", + cityOperatorMobile: "-", + cityUnionName: "-", + acceptedRejectedDate: "", + cityState: "در انتظار تایید", + }); + + const { city, cityOperator } = file; + useEffect(() => { + let cityOperatorName, + cityOperatorMobile, + acceptedRejectedDate, + cityState, + cityUnionName; + if (city) { + cityOperatorName = city.cityOperatorName; + cityOperatorMobile = city.cityOperatorMobile; + acceptedRejectedDate = city.acceptedRejectedDate; + cityUnionName = city.unitName; + cityState = city.cityState === "accept" ? "تایید شده" : "رد شده"; + } else { + cityOperatorName = cityOperator?.cityOperatorName; + cityOperatorMobile = cityOperator.cityOperatorMobile; + cityUnionName = cityOperator.unitName; + acceptedRejectedDate = null; + cityState = "در انتظار تایید"; + } + setCityInfo({ + cityOperatorName, + cityOperatorMobile, + acceptedRejectedDate, + cityUnionName, + cityState, + }); + }, [city]); + + return ( + <> + + + + + + + + + + + مرحله شهرستان + + + + + + + + {cityInfoData.cityState === "در انتظار تایید" ? ( + + درخواست منتظر انجام عملیات توسط اپراتور می باشد. + + ) : ( + <> + + درخواست در تاریخ + + + {cityInfoData.acceptedRejectedDate + ? formatTime(cityInfoData.acceptedRejectedDate) + : "-"} + + + {cityInfoData.cityState} است. + + + )} + + + + + + + + + + + + + + ); +}; + +CityInformation.propTypes = { + file: PropTypes.any, +}; diff --git a/src/features/file/components/city-information/CityInformationContent.js b/src/features/file/components/city-information/CityInformationContent.js new file mode 100644 index 0000000..432a044 --- /dev/null +++ b/src/features/file/components/city-information/CityInformationContent.js @@ -0,0 +1,79 @@ +import { SimpleTable } from "../../../../components/simple-table/SimpleTable"; +import { PropTypes } from "prop-types"; +import { useEffect, useState } from "react"; +import { Grid } from "../../../../components/grid/Grid"; +import { format } from "date-fns-jalali"; + +export const CityInformationContent = ({ file }) => { + const [cityInfoData, setCityInfo] = useState({ + cityOperatorName: "اپراتور شهرستان", + cityOperatorMobile: "-", + cityUnionName: "-", + acceptedRejectedDate: "", + cityState: "در انتظار تایید", + }); + + const { city, cityOperator } = file; + useEffect(() => { + let cityOperatorName, + cityOperatorMobile, + acceptedRejectedDate, + cityState, + cityUnionName; + if (city) { + cityOperatorName = city.cityOperatorName; + cityOperatorMobile = city.cityOperatorMobile; + acceptedRejectedDate = city.acceptedRejectedDate; + cityUnionName = city.unitName; + cityState = city.cityState === "accept" ? "تایید شده" : "رد شده"; + } else { + cityOperatorName = cityOperator?.cityOperatorName; + cityOperatorMobile = cityOperator.cityOperatorMobile; + cityUnionName = cityOperator.unitName; + acceptedRejectedDate = null; + cityState = "در انتظار تایید"; + } + setCityInfo({ + cityOperatorName, + cityOperatorMobile, + acceptedRejectedDate, + cityUnionName, + cityState, + }); + }, [city]); + + return ( + + + + ); +}; + +CityInformationContent.propTypes = { + file: PropTypes.any, +}; diff --git a/src/features/file/components/city-information/CityInformationTitle.js b/src/features/file/components/city-information/CityInformationTitle.js new file mode 100644 index 0000000..07739c2 --- /dev/null +++ b/src/features/file/components/city-information/CityInformationTitle.js @@ -0,0 +1,96 @@ +import { PropTypes } from "prop-types"; +import { useEffect, useState } from "react"; +import { Grid } from "../../../../components/grid/Grid"; +import TimelineOppositeContent from "@mui/lab/TimelineOppositeContent"; +import { Typography } from "@mui/material"; +import TimelineContent from "@mui/lab/TimelineContent"; +import { SPACING } from "../../../../data/spacing"; +import { formatTime } from "../../../../utils/formatTime"; + +export const CityInformationTitle = ({ file }) => { + const [cityInfoData, setCityInfo] = useState({ + cityOperatorName: "اپراتور شهرستان", + cityOperatorMobile: "-", + acceptedRejectedDate: "", + cityState: "در انتظار تایید", + }); + + const { city, cityOperator } = file; + useEffect(() => { + let cityOperatorName, cityOperatorMobile, acceptedRejectedDate, cityState; + if (city) { + cityOperatorName = city.cityOperatorName; + cityOperatorMobile = city.cityOperatorMobile; + acceptedRejectedDate = city.acceptedRejectedDate; + cityState = city.cityState === "accept" ? "تایید شده" : "رد شده"; + } else { + cityOperatorName = cityOperator?.cityOperatorName; + cityOperatorMobile = cityOperator.cityOperatorMobile; + acceptedRejectedDate = null; + cityState = "در انتظار تایید"; + } + setCityInfo({ + cityOperatorName, + cityOperatorMobile, + acceptedRejectedDate, + cityState, + }); + }, [city]); + + return ( + + + + + + مرحله شهرستان + + + + + + + + {cityInfoData.cityState === "در انتظار تایید" ? ( + + درخواست منتظر انجام عملیات توسط اپراتور می باشد. + + ) : ( + <> + + درخواست در تاریخ + + + {cityInfoData.acceptedRejectedDate + ? formatTime(cityInfoData.acceptedRejectedDate) + : "-"} + + + {cityInfoData.cityState} است. + + + )} + + + + + + + ); +}; + +CityInformationTitle.propTypes = { + file: PropTypes.any, +}; diff --git a/src/features/file/components/close-file-financial-info/CloseFileFinancialInfo.js b/src/features/file/components/close-file-financial-info/CloseFileFinancialInfo.js new file mode 100644 index 0000000..421f532 --- /dev/null +++ b/src/features/file/components/close-file-financial-info/CloseFileFinancialInfo.js @@ -0,0 +1,424 @@ +import { + TimelineConnector, + TimelineContent, + TimelineDot, + TimelineItem, + TimelineOppositeContent, + TimelineSeparator, +} from "@mui/lab"; +import { Button, Typography } from "@mui/material"; +import React, { useEffect } from "react"; +import { PropTypes } from "prop-types"; +import { Grid } from "../../../../components/grid/Grid"; +import { SimpleTable } from "../../../../components/simple-table/SimpleTable"; +import { SPACING } from "../../../../data/spacing"; +import { formatTime } from "../../../../utils/formatTime"; +import moment from "moment"; +import { Timer } from "../../../../components/timer/Timer"; +import { useDispatch, useSelector } from "react-redux"; +import { avicultureGetChickenPrice } from "../../../aviculture/services/aviculture-get-chicken-price"; +import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl"; +// import { useSelector } from "react-redux"; +import CloseIcon from "@mui/icons-material/Close"; +import { DRAWER } from "../../../../lib/redux/slices/appSlice"; +import { CloseFileSubmitInfo } from "../close-file-submit-info/CloseFileSubmitInfo"; + +const CloseFileFinancialInfo = ({ data, auction }) => { + const dispatch = useDispatch(); + useEffect(() => { + dispatch(avicultureGetChickenPrice()); + }, []); + + const { avicultureChickenPrice } = useSelector( + (state) => state.avicultureSlice + ); + + const liveChickenPrice = avicultureChickenPrice?.liveChickenPrice; + + let barInfoColumns, + barInfoData, + financialColumns, + financialColumnsCash, + financialData, + financialDataCash; + const paymentDate = moment(new Date(data.paymentDeadLine)); + const currentDate = moment(); + const diff = paymentDate.diff(currentDate); + const paymentRemainedSeconds = moment.duration(diff).asSeconds(); + + if (auction) { + // columns = [ + // "کشتارگاه", + // "تعداد", + // "نام راننده", + // "ماشین", + // "وزن بار", + // "سند خودرو بدون بار", + // "سند خودرو با بار", + // "وضعیت", + // ]; + // item = [ + // [ + // data.quantity + " قطعه", + // data.cars.driverName + ` (${data.cars.driverMobile})`, + // `${data.cars.typeCar} با پلاک ${data.cars.pelak}`, + // data.barInfo.killHouseNetWeight + " کیلوگرم", + // data.barInfo.killHouseNetWeight + " کیلوگرم", + // + // بدون بار + // , + // + // بدون بار + // , + // !data.killHouseFactorToProvince && data.provinceFactorToKillHouse + // ? "در انتظار پرداخت کشتارگاه" + // : "پرداخت شده توسط کشتارگاه", + // ], + // ]; + } else { + let state; + state = + !data.killHouseFactorToProvince && !data.provinceFactorToKillHouse + ? "در انتظار تایید مالی" + : state; + state = + !data.killHouseFactorToProvince && data.provinceFactorToKillHouse + ? "در انتظار پرداخت کشتارگاه" + : state; + state = + data.killHouseFactorToProvince && data.provinceFactorToKillHouse + ? "پرداخت شده توسط کشتارگاه" + : state; + + let timerState; + const isFactorPayed = + data.killHouseFactorToProvince?.factorState === "accepted" || + data.killHouseFactorToPoultry?.factorState === "accepted"; + + const timer = data && ( + + ); + const isPaymentFactorPending = + !data.killHouseFactorToProvince && + !data.provinceFactorToKillHouseForPoultry; + + const isPaymentPendingAndTimerEnabled = Boolean(data.paymentDeadLine); + + // if ( + // !data.provinceFactorToKillHouse || + // !data.provinceFactorToKillHouseForPoultry + // ) { + // timerState = "در انتظار تایید مالی"; + // } else if (isFactorPayed) { + // timerState = "پرداخت شده ✔"; + // } else if (isPaymentPendingAndTimerEnabled) { + // timerState = timer; + // } else if (isPaymentPending) { + // timerState = "در انتظار صدور تمامی فاکتورها"; + // } + + if (isPaymentPendingAndTimerEnabled) { + timerState = timer; + } else if (isPaymentFactorPending) { + timerState = "در انتظار تایید مالی"; + } else { + timerState = "در انتظار صدور تمامی فاکتورها"; + } + if (isFactorPayed) { + timerState = "پرداخت شده ✔"; + } + + barInfoColumns = [ + "کشتارگاه", + "نام راننده", + "ماشین", + "نوع خرید", + "سند خودرو بدون بار", + "سند خودرو با بار", + "تعداد", + "وزن بار", + "میانگین وزن", + "عملیات", + ]; + barInfoData = [ + [ + `${data.killHouseName} (${data.killHouseUserProvince}/${data.killHouseUserCity})`, + data.cars?.driverName + ` (${data.cars?.driverMobile})`, + `${data.cars?.typeCar} با پلاک ${data.cars?.pelak}`, + `${data.paymentType === "credit" ? "زمان دار" : "نقدی"}`, + + بدون بار +

    {data.barInfo.killHouseWeightWithoutLoad} کیلوگرم

    +
    , + + بدون بار +

    {data.barInfo.killHouseWeightWithLoad} کیلوگرم

    +
    , + data.quantity + " قطعه", + data.barInfo.killHouseNetWeight + " کیلوگرم", + (data.barInfo.killHouseNetWeight / data.quantity).toFixed(2) + + " کیلوگرم", + , + ], + ]; + financialColumns = [ + "قیمت روز", + "قیمت هرکیلو", + "سهم مرغدار", + "سهم اتحادیه", + "مانده تا سررسید 30 روزه", + "سهم مرغدار با ضریب سود", + "سهم اتحادیه با ضریب سود", + "جمع مبلغ قابل پرداخت", + "وضعیت", + "جریمه مرغدار", + "جریمه کشتارگاه", + ]; + + let poultryShareWithProfit; + if (data.provinceFactorToKillHouse?.poultryShareWithProfit) { + poultryShareWithProfit = + data.provinceFactorToKillHouse?.poultryShareWithProfit; + } else if ( + data.provinceFactorToKillHouseForPoultry?.poultryShareWithProfit + ) { + poultryShareWithProfit = + data.provinceFactorToKillHouseForPoultry?.poultryShareWithProfit; + } + financialData = [ + [ + liveChickenPrice + " ﷼", + data.provinceFactorToKillHouse + ? data.provinceFactorToKillHouse.provinceFactorFee + " ریال" + : "نامشخص", + data.provinceFactorToKillHouse + ? data.provinceFactorToKillHouse.provinceFactorFee * + data.barInfo.killHouseNetWeight + + " ریال" + : "نامشخص", + data.provinceFactorToKillHouse?.totalShareAllocation + ? data.provinceFactorToKillHouse?.totalShareAllocation + " ریال" + : "نامشخص", + timerState, + poultryShareWithProfit ? `${poultryShareWithProfit} ریال` : "نامشخص", + data.provinceFactorToKillHouse?.unionShareWithProfit + ? `${data.provinceFactorToKillHouse?.unionShareWithProfit} ریال` + : "نامشخص", + data.provinceFactorToKillHouse?.cost + ? `${ + data.provinceFactorToKillHouse?.cost + + data.provinceFactorToKillHouse?.poultryShareWithProfit + } ریال` + : "نامشخص", + state, + ], + ]; + + financialColumnsCash = [ + "قیمت روز", + "قیمت هرکیلو", + "سهم مرغدار", + "سهم اتحادیه", + "مبلغ قابل پرداخت", + "وضعیت", + ]; + + let pricePayment; + if (data.provinceFactorToKillHouse?.cost) { + pricePayment = `${data.provinceFactorToKillHouse?.cost} ریال`; + } else if (data.provinceFactorToKillHouseForPoultry?.cost) { + pricePayment = `${data.provinceFactorToKillHouseForPoultry?.cost} ریال`; + } else { + pricePayment = "نامشخص"; + } + + financialDataCash = [ + [ + liveChickenPrice + " ﷼", + data.provinceFactorToKillHouse + ? data.provinceFactorToKillHouse.provinceFactorFee + " ریال" + : "ندارد", + // data.provinceFactorToKillHouse + // ? data.provinceFactorToKillHouse.provinceFactorFee * + // data.barInfo.killHouseNetWeight + + // " ریال" + // : "ندارد", + poultryShareWithProfit ? `${poultryShareWithProfit} ریال` : "نامشخص", + data.provinceFactorToKillHouse?.totalShareAllocation + ? data.provinceFactorToKillHouse?.totalShareAllocation + " ریال" + : "نامشخص", + pricePayment, + state, + ], + ]; + + // remove payment fields for aviculture + const urlRole = getRoleFromUrl(); + if (urlRole === "Poultry") { + financialColumnsCash.splice(5, 3); + financialDataCash[0]?.splice(5, 3); + + financialColumns.splice(5, 4); + financialData[0]?.splice(5, 4); + } + } + return ( + + + + + + + + + + + مرحله مالی + + + + + + + {data.barInfo.killHouseAssignmentState === "pending" ? ( + + درخواست در انتظار تایید اپراتور مالی است. + + ) : ( + <> + + درخواست در تاریخ + + + {formatTime(new Date(data.barInfo.acceptRejectDate))} + + + {data.barInfo.killHouseAssignmentState === "accepted" + ? "تایید شده است." + : data.barInfo.killHouseAssignmentState === "pending" + ? "در انتظار تایید" + : "رد شده است."} + + + )} + + + + + + + + {data.paymentType === "cash" ? ( + + ) : ( + + )} + + + + + ); +}; +CloseFileFinancialInfo.propTypes = { + item: PropTypes.array, + data: PropTypes.any, + auction: PropTypes.bool, +}; + +export default CloseFileFinancialInfo; diff --git a/src/features/file/components/close-file-submit-info/CloseFileSubmitInfo.js b/src/features/file/components/close-file-submit-info/CloseFileSubmitInfo.js new file mode 100644 index 0000000..ac15aad --- /dev/null +++ b/src/features/file/components/close-file-submit-info/CloseFileSubmitInfo.js @@ -0,0 +1,346 @@ +import { + Button, + Checkbox, + Divider, + FormControl, + FormControlLabel, + FormLabel, + Radio, + RadioGroup, + TextField, + Typography, +} from "@mui/material"; +import { useFormik } from "formik"; +import React, { useEffect } from "react"; +import { Grid } from "../../../../components/grid/Grid"; +import { ImageUpload } from "../../../../components/image-upload/ImageUpload"; +import { SPACING } from "../../../../data/spacing"; +import { Yup } from "../../../../lib/yup/yup"; +import { fixBase64 } from "../../../../utils/toBase64"; + +export const CloseFileSubmitInfo = () => { + const [closeFileWeightWithoutBar, setCloseFileWeightWithoutBar] = + React.useState([]); + const [closeFileWeightWithoutBarBase64, setCloseFileWeightWithoutBarBase64] = + React.useState([]); + + const closeFileWeightWithoutBarHandler = (imageList, addUpdateIndex) => { + setCloseFileWeightWithoutBar(imageList); + setCloseFileWeightWithoutBarBase64( + imageList.map((img) => fixBase64(img.data_url)) + ); + }; + + const [closeFileWeightWithBar, setCloseFileWeightWithBar] = React.useState( + [] + ); + const [closeFileWeightWithBarBase64, setCloseFileWeightWithBarBase64] = + React.useState([]); + + const closeFileWeightWithBarHandler = (imageList, addUpdateIndex) => { + setCloseFileWeightWithBar(imageList); + setCloseFileWeightWithBarBase64( + imageList.map((img) => fixBase64(img.data_url)) + ); + }; + + const [closeWithNoOperation, setCloseWithNoOperation] = React.useState(false); + const handleToggle = () => { + setCloseWithNoOperation(!closeWithNoOperation); + }; + + const isFormValid = (closeWithNoOperation) => { + if (closeWithNoOperation) { + return false; + } else { + return !formik.isValid; + } + }; + + const formik = useFormik({ + initialValues: { + pultrypenalty: "", + killHousepenalty: "", + image: "", + carweightwithbar: "", + carweightwithoutbar: "", + payablemoney: "", + realLoadCount: "", + }, + validationSchema: Yup.object({ + pultrypenalty: Yup.number().typeError("لطفا عدد وارد کنید!"), + killHousepenalty: Yup.number().typeError("لطفا عدد وارد کنید!"), + carweightwithbar: Yup.number().typeError("لطفا عدد وارد کنید!"), + carweightwithoutbar: Yup.number().typeError("لطفا عدد وارد کنید!"), + payablemoney: Yup.number().typeError("لطفا عدد وارد کنید!"), + realLoadCount: Yup.number().typeError("لطفا عدد وارد کنید!"), + image: Yup.string().typeError("لطفا تصویر را وارد کنید!"), + }), + }); + + useEffect(() => { + formik.validateForm(); + }, []); + + return ( + + + } + label="کد بار بدون اقدام بسته شود" + /> + + + + اطلاعات جریمه + + + + پیشنهاد قیمت: 1400,000,000 + + + + + + پیشنهاد قیمت: 1400,000,000 + + + + + اطلاعات بار + + + + + + + + + + تصویر سند وزن خودرو بدون بار + + + تصویر سند وزن خودرو با بار + + + + + + + + + + پیشنهاد قیمت: 1400,000,000 + + + + مبلغ قابل پرداخت: 1400,000,000 + + + + + نوع پرداخت + + + } label="نقدی" /> + } + label="زماندار" + /> + + + + + + + + ); +}; diff --git a/src/features/file/components/factor-payment-share-drawer/FactorPaymentShareDrawer.js b/src/features/file/components/factor-payment-share-drawer/FactorPaymentShareDrawer.js new file mode 100644 index 0000000..6f6920c --- /dev/null +++ b/src/features/file/components/factor-payment-share-drawer/FactorPaymentShareDrawer.js @@ -0,0 +1,137 @@ +import { Button } from "@mui/material"; +import { useFormik } from "formik"; +import { useContext, useEffect, useState } from "react"; +import { Grid } from "../../../../components/grid/Grid"; +import { ImageUpload } from "../../../../components/image-upload/ImageUpload"; +import { NumberInput } from "../../../../components/number-format-custom/NumberFormatCustom"; +import { SPACING } from "../../../../data/spacing"; +import { Yup } from "../../../../lib/yup/yup"; +import { fixBase64 } from "../../../../utils/toBase64"; +import { PropTypes } from "prop-types"; +import { useDispatch } from "react-redux"; +import { + CLOSE_MODAL, + LOADING_END, + LOADING_START, +} from "../../../../lib/redux/slices/appSlice"; +import { depositeAllocation } from "../../services/deposite-allocation"; +import { AppContext } from "../../../../contexts/AppContext"; +import { provinceFinancialGetFinalFactorsService } from "../../../province-finacial/services/province-financial-get-final-factors-service"; + +export const FactorPaymentShareDrawer = ({ + share, + allocationKey, + paymentPrice, + fileId, +}) => { + const [openNotif] = useContext(AppContext); + const dispatch = useDispatch(); + const formik = useFormik({ + initialValues: { + factorImg: "", + payment: paymentPrice, + }, + validationSchema: Yup.object({ + factorImg: Yup.string() + .required("این فیلد اجباری است!") + .typeError("لطفا عدد وارد کنید!"), + payment: Yup.string() + .required("این فیلد اجباری است!") + .typeError("لطفا عدد وارد کنید!"), + }), + }); + + const [factorImgs, setFactorImgs] = useState([]); + + const factorImgHandler = (imageList, addUpdateIndex) => { + if (imageList[0]) { + formik.setFieldValue("factorImg", fixBase64(imageList[0]?.data_url)); + } else { + formik.setFieldValue("factorImg", ""); + } + setFactorImgs(imageList); + }; + + useEffect(() => { + formik.validateForm(); + }, []); + + return ( + + + + + + + + ); +}; + +FactorPaymentShareDrawer.propTypes = { + share: PropTypes.string, + allocationKey: PropTypes.string, + paymentPrice: PropTypes.any, + fileId: PropTypes.any, +}; diff --git a/src/features/file/components/file-auction-status/FileAuctionStatus.js b/src/features/file/components/file-auction-status/FileAuctionStatus.js new file mode 100644 index 0000000..255dc95 --- /dev/null +++ b/src/features/file/components/file-auction-status/FileAuctionStatus.js @@ -0,0 +1,96 @@ +import { + TimelineConnector, + TimelineContent, + TimelineDot, + TimelineItem, + TimelineOppositeContent, + TimelineSeparator, +} from "@mui/lab"; +import { Typography } from "@mui/material"; +import React from "react"; +import { PropTypes } from "prop-types"; +import { Grid } from "../../../../components/grid/Grid"; +import { SimpleTable } from "../../../../components/simple-table/SimpleTable"; +import { Timer } from "../../../../components/timer/Timer"; +import moment from "moment"; + +const FileAuctionStatus = ({ file }) => { + const { ceilingPrice, floorPrice, date, fee, index, totalIndex } = + file.auctionsList[0]; + const { fee: highestBid } = file?.killHouseAuctionsList + ? file.killHouseAuctionsList[0] + : { fee: "پیشنهادی وجود ندارد" }; + const totalBids = file.killHouseAuctionsList?.length; + + const auctionFinishDate = moment(new Date(date)); + const currentDate = moment(); + const diff = auctionFinishDate.diff(currentDate); + let auctionRemainedSeconds = moment.duration(diff).asSeconds(); + return ( + <> + + + + + + + + + + در حال مزایده + + + + + + درخواست درحال مزایده می باشد. + + + + + + , + highestBid === "پیشنهادی وجود ندارد" + ? highestBid + : `${highestBid} ﷼`, + totalBids ? totalBids : "پیشنهادی وجود ندارد", + // file.provinceRequestAuctionList ? "استان" : "مرغدار", + ], + ]} + /> + + + + + ); +}; + +FileAuctionStatus.propTypes = { + file: PropTypes.object, +}; + +export default FileAuctionStatus; diff --git a/src/features/file/components/file-auction-winner/FileAuctionWinner.js b/src/features/file/components/file-auction-winner/FileAuctionWinner.js new file mode 100644 index 0000000..251d746 --- /dev/null +++ b/src/features/file/components/file-auction-winner/FileAuctionWinner.js @@ -0,0 +1,60 @@ +import { + TimelineConnector, + TimelineContent, + TimelineDot, + TimelineItem, + TimelineOppositeContent, + TimelineSeparator, +} from "@mui/lab"; +import { Typography } from "@mui/material"; +import React from "react"; +import { PropTypes } from "prop-types"; +import { Grid } from "../../../../components/grid/Grid"; +import { SimpleTable } from "../../../../components/simple-table/SimpleTable"; + +export const FileAuctionWinner = ({ file }) => { + const { killHouseWinner } = file; + return ( + <> + + + + + + + + + + اطلاعات مزایده + + + + + + در این قسمت اطلاعات برنده خرید در مزایده را مشاهده می کنید. + + + + + + + + + + + ); +}; + +FileAuctionWinner.propTypes = { + file: PropTypes.object, +}; diff --git a/src/features/file/components/file-complaint/FileComplaint.js b/src/features/file/components/file-complaint/FileComplaint.js new file mode 100644 index 0000000..12efa97 --- /dev/null +++ b/src/features/file/components/file-complaint/FileComplaint.js @@ -0,0 +1,106 @@ +import { Typography } from "@mui/material"; +import React from "react"; +import { Grid } from "../../../../components/grid/Grid"; +import { SimpleTable } from "../../../../components/simple-table/SimpleTable"; +import { formatJustDate } from "../../../../utils/formatTime"; +import { PropTypes } from "prop-types"; +import { SPACING } from "../../../../data/spacing"; +import { TimelineOppositeContent } from "@mui/lab"; +import { format } from "date-fns-jalali"; + +export const FileComplaint = ({ item }) => { + return ( + <> + + + + بررسی شکایت + + + + + + { + return [ + + + دانلود + + , + ]; + }) + : "بدون پیوست", + ], + ]} + /> + {item?.complaint?.reviewer && ( + prop.palette.grey["A700"]} + > + {`تلفات در تاریخ ${formatJustDate( + item?.complaint?.reviewer?.createDate + )} توسط ${item?.complaint?.reviewer?.operatorname} `} + {item?.complaint?.reviewer?.state === "accepted" ? "تایید " : "رد "} + شده است. + + )} + + + ); +}; + +FileComplaint.propTypes = { + item: PropTypes.object, +}; diff --git a/src/features/file/components/file-information/FileInformation.js b/src/features/file/components/file-information/FileInformation.js new file mode 100644 index 0000000..e1ef6de --- /dev/null +++ b/src/features/file/components/file-information/FileInformation.js @@ -0,0 +1,57 @@ +import * as React from "react"; + +import { PropTypes } from "prop-types"; +import { SimpleTable } from "../../../../components/simple-table/SimpleTable"; +import { format } from "date-fns-jalali"; + +export const FileInformation = ({ file }) => { + const requestedSellTypeCash = file.poultry?.sellType?.cash ? "نقدی" : null; + const requestedSellTypeCredit = file.poultry?.sellType?.credit + ? "زمان دار" + : null; + const requestedSellType = [requestedSellTypeCash, requestedSellTypeCredit] + .filter((item) => item) + .join(" یا "); + return ( + + ); +}; + +FileInformation.propTypes = { + file: PropTypes.any, +}; diff --git a/src/features/file/components/file-operator-check-complaint/FileOperatorCheckComplaint.js b/src/features/file/components/file-operator-check-complaint/FileOperatorCheckComplaint.js new file mode 100644 index 0000000..301925e --- /dev/null +++ b/src/features/file/components/file-operator-check-complaint/FileOperatorCheckComplaint.js @@ -0,0 +1,199 @@ +import { Button, TextField } from "@mui/material"; +import React, { useContext, useEffect, useState } from "react"; +import { Grid } from "../../../../components/grid/Grid"; +import { PropTypes } from "prop-types"; +import { Yup } from "../../../../lib/yup/yup"; +import { useFormik } from "formik"; +import { SPACING } from "../../../../data/spacing"; +import { useDispatch } from "react-redux"; +import useUserProfile from "../../../authentication/hooks/useUserProfile"; +import { useParams } from "react-router-dom"; +import { AppContext } from "../../../../contexts/AppContext"; +import { AnimatePresence, motion } from "framer-motion"; + +import { + LOADING_END, + LOADING_START, +} from "../../../../lib/redux/slices/appSlice"; +import { getFileFromApi } from "../../hooks/useRequestFile"; +import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl"; +import { provinceCheckComplaint } from "../../services/province-check-complaint"; + +export const FileOperatorCheckComplaint = ({ item }) => { + const [isDenyedComplaint, setisDenyedComplaint] = useState(false); + const [roles] = useUserProfile(); + const { id } = useParams(); + const [openNotif] = useContext(AppContext); + + const dispatch = useDispatch(); + const formik = useFormik({ + initialValues: { + rejectText: "", + }, + validationSchema: Yup.object({ + rejectText: Yup.string() + .required("این فیلد اجباری است!") + .typeError("لطفا دلیل خود را بیان کنید."), + }), + }); + + useEffect(() => { + formik.validateForm(); + }, []); + + return ( + <> + + + + {item.complaint.state === "pending" && ( + + + {isDenyedComplaint ? ( + + + + + + + + + + + + + + + + + ) : ( + + + + + )} + + + )} + + + + + ); +}; + +FileOperatorCheckComplaint.propTypes = { + item: PropTypes.object, +}; diff --git a/src/features/file/components/final-factor-title/FinalFactorTitle.js b/src/features/file/components/final-factor-title/FinalFactorTitle.js new file mode 100644 index 0000000..5fe2b1f --- /dev/null +++ b/src/features/file/components/final-factor-title/FinalFactorTitle.js @@ -0,0 +1,24 @@ +import { PropTypes } from "prop-types"; +import { Grid } from "../../../../components/grid/Grid"; +import TimelineOppositeContent from "@mui/lab/TimelineOppositeContent"; +import { Typography } from "@mui/material"; + +export const FinalFactorTitle = ({ file }) => { + return ( + + + + + + فاکتور نهایی + + + + + + ); +}; + +FinalFactorTitle.propTypes = { + file: PropTypes.any, +}; diff --git a/src/features/file/components/financial-check-request-information/FinancialCheckRequestInformation.js b/src/features/file/components/financial-check-request-information/FinancialCheckRequestInformation.js new file mode 100644 index 0000000..95dc73c --- /dev/null +++ b/src/features/file/components/financial-check-request-information/FinancialCheckRequestInformation.js @@ -0,0 +1,400 @@ +import { + TimelineConnector, + TimelineContent, + TimelineDot, + TimelineItem, + TimelineOppositeContent, + TimelineSeparator, +} from "@mui/lab"; +import { Typography } from "@mui/material"; +import React, { useEffect } from "react"; +import { PropTypes } from "prop-types"; +import { Grid } from "../../../../components/grid/Grid"; +import { SimpleTable } from "../../../../components/simple-table/SimpleTable"; +import { SPACING } from "../../../../data/spacing"; +import { formatTime } from "../../../../utils/formatTime"; +import moment from "moment"; +import { Timer } from "../../../../components/timer/Timer"; +import { useDispatch, useSelector } from "react-redux"; +import { avicultureGetChickenPrice } from "../../../aviculture/services/aviculture-get-chicken-price"; +import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl"; +// import { useSelector } from "react-redux"; + +const FinancialCheckRequestInformation = ({ data, auction }) => { + const dispatch = useDispatch(); + useEffect(() => { + dispatch(avicultureGetChickenPrice()); + }, []); + // let columns = []; + // let item = []; + + const { avicultureChickenPrice } = useSelector( + (state) => state.avicultureSlice + ); + + const liveChickenPrice = avicultureChickenPrice?.liveChickenPrice; + + let barInfoColumns, + barInfoData, + financialColumns, + financialColumnsCash, + financialData, + financialDataCash; + const paymentDate = moment(new Date(data.paymentDeadLine)); + const currentDate = moment(); + const diff = paymentDate.diff(currentDate); + let paymentRemainedSeconds = moment.duration(diff).asSeconds(); + if (auction) { + // columns = [ + // "کشتارگاه", + // "تعداد", + // "نام راننده", + // "ماشین", + // "وزن بار", + // "سند خودرو بدون بار", + // "سند خودرو با بار", + // "وضعیت", + // ]; + // item = [ + // [ + // data.quantity + " قطعه", + // data.cars.driverName + ` (${data.cars.driverMobile})`, + // `${data.cars.typeCar} با پلاک ${data.cars.pelak}`, + // data.barInfo.killHouseNetWeight + " کیلوگرم", + // data.barInfo.killHouseNetWeight + " کیلوگرم", + // + // بدون بار + // , + // + // بدون بار + // , + // !data.killHouseFactorToProvince && data.provinceFactorToKillHouse + // ? "در انتظار پرداخت کشتارگاه" + // : "پرداخت شده توسط کشتارگاه", + // ], + // ]; + } else { + let state; + state = + !data.killHouseFactorToProvince && !data.provinceFactorToKillHouse + ? "در انتظار تایید مالی" + : state; + state = + !data.killHouseFactorToProvince && data.provinceFactorToKillHouse + ? "در انتظار پرداخت کشتارگاه" + : state; + state = + data.killHouseFactorToProvince && data.provinceFactorToKillHouse + ? "پرداخت شده توسط کشتارگاه" + : state; + + let timerState; + const isFactorPayed = + data.killHouseFactorToProvince?.factorState === "accepted" || + data.killHouseFactorToPoultry?.factorState === "accepted"; + + const timer = data && ( + + ); + const isPaymentFactorPending = + !data.killHouseFactorToProvince && + !data.provinceFactorToKillHouseForPoultry; + + const isPaymentPendingAndTimerEnabled = Boolean(data.paymentDeadLine); + + // if ( + // !data.provinceFactorToKillHouse || + // !data.provinceFactorToKillHouseForPoultry + // ) { + // timerState = "در انتظار تایید مالی"; + // } else if (isFactorPayed) { + // timerState = "پرداخت شده ✔"; + // } else if (isPaymentPendingAndTimerEnabled) { + // timerState = timer; + // } else if (isPaymentPending) { + // timerState = "در انتظار صدور تمامی فاکتورها"; + // } + + if (isPaymentPendingAndTimerEnabled) { + timerState = timer; + } else if (isPaymentFactorPending) { + timerState = "در انتظار تایید مالی"; + } else { + timerState = "در انتظار صدور تمامی فاکتورها"; + } + if (isFactorPayed) { + timerState = "پرداخت شده ✔"; + } + + barInfoColumns = [ + "کشتارگاه", + "نام راننده", + "ماشین", + // "کد قرنطینه", + // "کد حمل و نقل", + "نوع خرید", + "سند خودرو بدون بار", + "سند خودرو با بار", + "تعداد درخواست", + "تعداد واقعی بارگیری", + "وزن بار", + "میانگین وزن", + ]; + + barInfoData = [ + [ + `${data.killHouseName} (${data.killHouseUserProvince}/${data.killHouseUserCity})`, + data.cars?.driverName + ` (${data.cars?.driverMobile})`, + `${data.cars?.typeCar} با پلاک ${data.cars?.pelak}`, + `${data.paymentType === "credit" ? "زمان دار" : "نقدی"}`, + + بدون بار +

    {data.barInfo.killHouseWeightWithoutLoad} کیلوگرم

    +
    , + + بدون بار +

    {data.barInfo.killHouseWeightWithLoad} کیلوگرم

    +
    , + data.quantity + " قطعه", + data.barInfo.realQuantity + " قطعه", + data.barInfo.killHouseNetWeight + " کیلوگرم", + (data.barInfo.killHouseNetWeight / data.barInfo.realQuantity).toFixed( + 2 + ) + " کیلوگرم", + ], + ]; + financialColumns = [ + "قیمت روز", + "قیمت هرکیلو", + "سهم مرغدار", + "سهم اتحادیه", + "مانده تا سررسید 30 روزه", + "سهم مرغدار با ضریب سود", + "سهم اتحادیه با ضریب سود", + "جمع مبلغ قابل پرداخت", + "وضعیت", + ]; + + let poultryShareWithProfit; + if (data.provinceFactorToKillHouse?.poultryShareWithProfit) { + poultryShareWithProfit = + data.provinceFactorToKillHouse?.poultryShareWithProfit; + } else if ( + data.provinceFactorToKillHouseForPoultry?.poultryShareWithProfit + ) { + poultryShareWithProfit = + data.provinceFactorToKillHouseForPoultry?.poultryShareWithProfit; + } + financialData = [ + [ + liveChickenPrice + " ﷼", + data.provinceFactorToKillHouse + ? data.provinceFactorToKillHouse.provinceFactorFee + " ریال" + : "نامشخص", + data.provinceFactorToKillHouse + ? data.provinceFactorToKillHouse.provinceFactorFee * + data.barInfo.killHouseNetWeight + + " ریال" + : "نامشخص", + data.provinceFactorToKillHouse?.totalShareAllocation + ? data.provinceFactorToKillHouse?.totalShareAllocation + " ریال" + : "نامشخص", + timerState, + poultryShareWithProfit ? `${poultryShareWithProfit} ریال` : "نامشخص", + data.provinceFactorToKillHouse?.unionShareWithProfit + ? `${data.provinceFactorToKillHouse?.unionShareWithProfit} ریال` + : "نامشخص", + data.provinceFactorToKillHouse?.cost + ? `${ + data.provinceFactorToKillHouse?.cost + + data.provinceFactorToKillHouse?.poultryShareWithProfit + } ریال` + : "نامشخص", + state, + ], + ]; + + financialColumnsCash = [ + "قیمت روز", + "قیمت هرکیلو", + "سهم مرغدار", + "سهم اتحادیه", + "مبلغ قابل پرداخت", + "وضعیت", + ]; + + let pricePayment; + if (data.provinceFactorToKillHouse?.cost) { + pricePayment = `${data.provinceFactorToKillHouse?.cost} ریال`; + } else if (data.provinceFactorToKillHouseForPoultry?.cost) { + pricePayment = `${data.provinceFactorToKillHouseForPoultry?.cost} ریال`; + } else { + pricePayment = "نامشخص"; + } + + financialDataCash = [ + [ + liveChickenPrice + " ﷼", + data.provinceFactorToKillHouse + ? data.provinceFactorToKillHouse.provinceFactorFee + " ریال" + : "ندارد", + // data.provinceFactorToKillHouse + // ? data.provinceFactorToKillHouse.provinceFactorFee * + // data.barInfo.killHouseNetWeight + + // " ریال" + // : "ندارد", + poultryShareWithProfit ? `${poultryShareWithProfit} ریال` : "نامشخص", + data.provinceFactorToKillHouse?.totalShareAllocation + ? data.provinceFactorToKillHouse?.totalShareAllocation + " ریال" + : "نامشخص", + pricePayment, + state, + ], + ]; + + // remove payment fields for aviculture + const urlRole = getRoleFromUrl(); + if (urlRole === "Poultry") { + financialColumnsCash.splice(5, 3); + financialDataCash[0]?.splice(5, 3); + + financialColumns.splice(5, 4); + financialData[0]?.splice(5, 4); + } + } + return ( + + + + + + + + + + + مرحله مالی + + + + + + + {data.barInfo.killHouseAssignmentState === "pending" ? ( + + درخواست در انتظار تایید اپراتور مالی است. + + ) : ( + <> + + درخواست در تاریخ + + + {formatTime(new Date(data.barInfo.acceptRejectDate))} + + + {data.barInfo.killHouseAssignmentState === "accepted" + ? "تایید شده است." + : data.barInfo.killHouseAssignmentState === "pending" + ? "در انتظار تایید" + : "رد شده است."} + + + )} + + + + + + + + {data.paymentType === "cash" ? ( + + ) : ( + + )} + + + + + ); +}; +FinancialCheckRequestInformation.propTypes = { + item: PropTypes.array, + data: PropTypes.any, + auction: PropTypes.bool, +}; + +export default FinancialCheckRequestInformation; diff --git a/src/features/file/components/financial-check-request-information/FinancialCheckRequestInformationContent.js b/src/features/file/components/financial-check-request-information/FinancialCheckRequestInformationContent.js new file mode 100644 index 0000000..a94c782 --- /dev/null +++ b/src/features/file/components/financial-check-request-information/FinancialCheckRequestInformationContent.js @@ -0,0 +1,322 @@ +import React, { useEffect } from "react"; +import { PropTypes } from "prop-types"; +import { Grid } from "../../../../components/grid/Grid"; +import { SimpleTable } from "../../../../components/simple-table/SimpleTable"; +import moment from "moment"; +import { Timer } from "../../../../components/timer/Timer"; +import { useDispatch, useSelector } from "react-redux"; +import { avicultureGetChickenPrice } from "../../../aviculture/services/aviculture-get-chicken-price"; +import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl"; +// import { useSelector } from "react-redux"; + +const FinancialCheckRequestInformationContent = ({ data, auction }) => { + const dispatch = useDispatch(); + useEffect(() => { + dispatch(avicultureGetChickenPrice()); + }, []); + + const { avicultureChickenPrice } = useSelector( + (state) => state.avicultureSlice + ); + + const liveChickenPrice = avicultureChickenPrice?.liveChickenPrice; + + let barInfoColumns, + barInfoData, + financialColumns, + financialColumnsCash, + financialData, + financialDataCash; + const paymentDate = moment(new Date(data.paymentDeadLine)); + const currentDate = moment(); + const diff = paymentDate.diff(currentDate); + const paymentRemainedSeconds = moment.duration(diff).asSeconds(); + + if (auction) { + // columns = [ + // "کشتارگاه", + // "تعداد", + // "نام راننده", + // "ماشین", + // "وزن بار", + // "سند خودرو بدون بار", + // "سند خودرو با بار", + // "وضعیت", + // ]; + // item = [ + // [ + // data.quantity + " قطعه", + // data.cars.driverName + ` (${data.cars.driverMobile})`, + // `${data.cars.typeCar} با پلاک ${data.cars.pelak}`, + // data.barInfo.killHouseNetWeight + " کیلوگرم", + // data.barInfo.killHouseNetWeight + " کیلوگرم", + // + // بدون بار + // , + // + // بدون بار + // , + // !data.killHouseFactorToProvince && data.provinceFactorToKillHouse + // ? "در انتظار پرداخت کشتارگاه" + // : "پرداخت شده توسط کشتارگاه", + // ], + // ]; + } else { + let state; + state = + !data.killHouseFactorToProvince && !data.provinceFactorToKillHouse + ? "در انتظار تایید مالی" + : state; + state = + !data.killHouseFactorToProvince && data.provinceFactorToKillHouse + ? "در انتظار پرداخت کشتارگاه" + : state; + state = + data.killHouseFactorToProvince && data.provinceFactorToKillHouse + ? "پرداخت شده توسط کشتارگاه" + : state; + + let timerState; + const isFactorPayed = + data.killHouseFactorToProvince?.factorState === "accepted" || + data.killHouseFactorToPoultry?.factorState === "accepted"; + + const timer = data && ( + + ); + const isPaymentFactorPending = + !data.killHouseFactorToProvince && + !data.provinceFactorToKillHouseForPoultry; + + const isPaymentPendingAndTimerEnabled = Boolean(data.paymentDeadLine); + + // if ( + // !data.provinceFactorToKillHouse || + // !data.provinceFactorToKillHouseForPoultry + // ) { + // timerState = "در انتظار تایید مالی"; + // } else if (isFactorPayed) { + // timerState = "پرداخت شده ✔"; + // } else if (isPaymentPendingAndTimerEnabled) { + // timerState = timer; + // } else if (isPaymentPending) { + // timerState = "در انتظار صدور تمامی فاکتورها"; + // } + + if (isPaymentPendingAndTimerEnabled) { + timerState = timer; + } else if (isPaymentFactorPending) { + timerState = "در انتظار تایید مالی"; + } else { + timerState = "در انتظار صدور تمامی فاکتورها"; + } + if (isFactorPayed) { + timerState = "پرداخت شده ✔"; + } + + barInfoColumns = [ + "کشتارگاه", + "نام راننده", + "ماشین", + "نوع خرید", + "سند خودرو بدون بار", + "سند خودرو با بار", + "تعداد درخواست", + "تعداد واقعی بارگیری", + "وزن بار", + "میانگین وزن", + ]; + barInfoData = [ + [ + `${data.killHouseName} (${data.killHouseUserProvince}/${data.killHouseUserCity})`, + data.cars?.driverName + ` (${data.cars?.driverMobile})`, + `${data.cars?.typeCar} با پلاک ${data.cars?.pelak}`, + `${data.paymentType === "credit" ? "زمان دار" : "نقدی"}`, + + بدون بار +

    {data.barInfo.killHouseWeightWithoutLoad} کیلوگرم

    +
    , + + بدون بار +

    {data.barInfo.killHouseWeightWithLoad} کیلوگرم

    +
    , + data.quantity + " قطعه", + data.barInfo.realQuantity + " قطعه", + data.barInfo.killHouseNetWeight + " کیلوگرم", + (data.barInfo.killHouseNetWeight / data.barInfo.realQuantity).toFixed( + 2 + ) + " کیلوگرم", + ], + ]; + financialColumns = [ + "قیمت روز", + "قیمت هرکیلو", + "سهم مرغدار", + "سهم اتحادیه", + "مانده تا سررسید 30 روزه", + "سهم مرغدار با ضریب سود", + "سهم اتحادیه با ضریب سود", + "جمع مبلغ قابل پرداخت", + "وضعیت", + ]; + + let poultryShareWithProfit; + if (data.provinceFactorToKillHouse?.poultryShareWithProfit) { + poultryShareWithProfit = + data.provinceFactorToKillHouse?.poultryShareWithProfit; + } else if ( + data.provinceFactorToKillHouseForPoultry?.poultryShareWithProfit + ) { + poultryShareWithProfit = + data.provinceFactorToKillHouseForPoultry?.poultryShareWithProfit; + } + financialData = [ + [ + liveChickenPrice + " ﷼", + data.provinceFactorToKillHouse + ? data.provinceFactorToKillHouse.provinceFactorFee + " ریال" + : "نامشخص", + data.provinceFactorToKillHouse + ? data.provinceFactorToKillHouse.provinceFactorFee * + data.barInfo.killHouseNetWeight + + " ریال" + : "نامشخص", + data.provinceFactorToKillHouse?.totalShareAllocation + ? data.provinceFactorToKillHouse?.totalShareAllocation + " ریال" + : "نامشخص", + timerState, + poultryShareWithProfit ? `${poultryShareWithProfit} ریال` : "نامشخص", + data.provinceFactorToKillHouse?.unionShareWithProfit + ? `${data.provinceFactorToKillHouse?.unionShareWithProfit} ریال` + : "نامشخص", + data.provinceFactorToKillHouse?.cost + ? `${ + data.provinceFactorToKillHouse?.cost + + data.provinceFactorToKillHouse?.poultryShareWithProfit + } ریال` + : "نامشخص", + state, + ], + ]; + + financialColumnsCash = [ + "قیمت روز", + "قیمت هرکیلو", + "سهم مرغدار", + "سهم اتحادیه", + "مبلغ قابل پرداخت", + "وضعیت", + ]; + financialDataCash = [ + [ + liveChickenPrice + " ﷼", + data.provinceFactorToKillHouse + ? data.provinceFactorToKillHouse.provinceFactorFee + " ریال" + : "ندارد", + data.provinceFactorToKillHouse + ? data.provinceFactorToKillHouse.provinceFactorFee * + data.barInfo.killHouseNetWeight + + " ریال" + : "ندارد", + data.provinceFactorToKillHouse?.totalShareAllocation + ? data.provinceFactorToKillHouse?.totalShareAllocation + " ریال" + : "نامشخص", + data.provinceFactorToKillHouse?.cost + ? `${data.provinceFactorToKillHouse?.cost} ریال` + : "ندارد", + state, + ], + ]; + + // remove payment fields for aviculture + const urlRole = getRoleFromUrl(); + if (urlRole === "Poultry") { + financialColumnsCash.splice(5, 3); + financialDataCash[0]?.splice(5, 3); + + financialColumns.splice(5, 4); + financialData[0]?.splice(5, 4); + } + } + return ( + + + + + {data.paymentType === "cash" ? ( + + ) : ( + + )} + + + + ); +}; +FinancialCheckRequestInformationContent.propTypes = { + item: PropTypes.array, + data: PropTypes.any, + auction: PropTypes.bool, +}; + +export default FinancialCheckRequestInformationContent; diff --git a/src/features/file/components/financial-check-request-operation/FinancialCheckRequestOperation.js b/src/features/file/components/financial-check-request-operation/FinancialCheckRequestOperation.js new file mode 100644 index 0000000..506f08c --- /dev/null +++ b/src/features/file/components/financial-check-request-operation/FinancialCheckRequestOperation.js @@ -0,0 +1,751 @@ +import { + TimelineConnector, + TimelineContent, + TimelineDot, + TimelineItem, + TimelineOppositeContent, + TimelineSeparator, +} from "@mui/lab"; +import { + Button, + ButtonGroup, + TextField, + ToggleButton, + ToggleButtonGroup, + Typography, +} from "@mui/material"; +import React, { useEffect, useState } from "react"; +import { PropTypes } from "prop-types"; +import { Grid } from "../../../../components/grid/Grid"; +import { SPACING } from "../../../../data/spacing"; +import { AnimatePresence, motion } from "framer-motion"; +import { + DRAWER, + LOADING_END, + LOADING_START, +} from "../../../../lib/redux/slices/appSlice"; +import { useFormik } from "formik"; +import { Yup } from "../../../../lib/yup/yup"; +import { useDispatch, useSelector } from "react-redux"; +import { financialCheckRequest } from "../../services/financial-check-request"; +import { useContext } from "react"; +import { AppContext } from "../../../../contexts/AppContext"; +import { avicultureGetChickenPrice } from "../../../aviculture/services/aviculture-get-chicken-price"; +import { provinceFinancialGetPendingRequestsService } from "../../../province-finacial/services/province-financial-get-pending-requests"; +import { NumberInput } from "../../../../components/number-format-custom/NumberFormatCustom"; +import { SimpleTable } from "../../../../components/simple-table/SimpleTable"; +import { formatJustDate } from "../../../../utils/formatTime"; + +export const FinancialCheckRequestOperation = ({ item }) => { + const [openNotif, , selectedDate1, , selectedDate2] = useContext(AppContext); + const dispatch = useDispatch(); + + useEffect(() => { + dispatch(avicultureGetChickenPrice()); + formik.validateForm(); + formik2.validateForm(); + }, []); + + const { avicultureChickenPrice } = useSelector( + (state) => state.avicultureSlice + ); + + const liveChickenPrice = avicultureChickenPrice?.liveChickenPrice; + // calc suggest price + // const chickenWeight = parseFloat( + // file.poultry.poultryIndexWeight.split(" ")[0] + // ); + + const chickenWeight = parseFloat( + (item.barInfo.killHouseNetWeight / item.barInfo.realQuantity).toFixed(2) + ); + // let suggestPrice = liveChickenPrice; + //buildchange + // hamedan & arak & bushehr + const standardChicken = 2.5; + // kermanshah + // const standardChicken = 2.7; + // const checkStep = 0.05; + // const costPerStep = 500; + + if (chickenWeight < standardChicken) { + // const howMuchToReduce = + // ((standardChicken - chickenWeight).toFixed(2) / checkStep) * costPerStep; + // suggestPrice = liveChickenPrice - howMuchToReduce; + } + + const formik = useFormik({ + initialValues: { + rejectText: "", + // wage: "1000", + }, + validationSchema: Yup.object({ + rejectText: Yup.string() + .required("این فیلد اجباری است!") + .typeError("لطفا دلیل خود را بیان کنید."), + }), + }); + + const [activeButtonIndex, setActiveButtonIndex] = useState(false); + + const handleButtonClick = (index) => { + setActiveButtonIndex(index); + if (!activeButtonIndex) { + formik2.setFieldValue("reason", ""); + formik2.setFieldValue("amount", ""); + } + }; + + const formik2 = useFormik({ + initialValues: { + fee: "", + paymentType: "together", + wage: 0, + amount: "", + reason: "", + }, + validationSchema: Yup.object({ + fee: Yup.number().required("این فیلد اجباری است!"), + amount: Yup.number(), + paymentType: Yup.string().required("این فیلد اجباری است!"), + reason: activeButtonIndex + ? Yup.string().required("این فیلد اجباری است!") + : Yup.string(), + wage: Yup.number().required("این فیلد اجباری است!"), + }), + }); + + let totalFactorPrice = + (formik2.values.fee + formik2.values.wage) * item.killHouseNetWeight; + if (activeButtonIndex === "plus") { + totalFactorPrice += Number(formik2.values.amount); + } else if (activeButtonIndex === "decrease") { + totalFactorPrice -= Number(formik2.values.amount); + } + + let finalTotalFactorPrice = + totalFactorPrice - item.killRequestPaymentRemainAmount; + + if (item.smsPayment) { + finalTotalFactorPrice += 50000; + } + + const [isDenyed, setisDenyed] = useState(false); + const btnValidation = !formik2.isValid; + + const [paymentType, setPaymentType] = React.useState("union"); + + const handleChange = (event, newAlignment) => { + if (newAlignment) { + setPaymentType(newAlignment); + } + }; + + return ( + + + + + + + <> + + + + + انجام عملیات + + + + + + درخواست را بررسی و سپس تایید یا رد کنید. + + + + + + + prop.palette.grey["A700"]} + variant={"caption"} + > + موجودی کیف پول کشتارگاه: + + + {`${item.killHouseWalletAmount?.toLocaleString()} ﷼`} + + + + + + + + + صدور فاکتور بنام: + + + اتحادیه + مرغدار + + + {paymentType === "union" && ( + + + اطلاعات حساب اتحادیه + + + + شماره کارت: {item?.provinceBank?.card} + + + شماره شبا: {item?.provinceBank?.shaba} + + + شماره حساب: {item?.provinceBank?.account} + + + بانک {item?.provinceBank?.bankName} - بنام{" "} + {item.provinceBank?.nameOfBankUser} + + + + )} + {paymentType === "poultry" && ( + + + اطلاعات حساب مرغدار + + + + شماره کارت:{" "} + {item?.poultryBank?.card + ? item?.poultryBank?.card + : "ندارد"} + + + شماره شبا:{" "} + {item?.poultryBank?.shaba + ? item?.poultryBank?.shaba + : "ندارد"} + + + شماره حساب:{" "} + {item?.poultryBank?.account + ? item?.poultryBank?.account + : "ندارد"} + + + بانک{" "} + {item?.poultryBank?.bankName + ? item?.poultryBank?.bankName + : "نامشخص"}{" "} + - بنام{" "} + {item.poultryBank?.nameOfBankUser + ? item.poultryBank?.nameOfBankUser + : "نامشخص"} + + + + )} + + + + + + + + + + + + + + + + اضافه یا کسر از فاکتور + + + + + + + + {!!activeButtonIndex && ( + + + + + + + + + )} + + + + + + + + + + قیمت مرغ: + + + {liveChickenPrice?.toLocaleString()} ﷼ + + + + + آخرین تاریخ قیمت گذاری: + + + {avicultureChickenPrice?.createDate && + formatJustDate(avicultureChickenPrice?.createDate)} + + + + {/* + prop.palette.grey["A700"]} + variant={"caption"} + > + قیمت پیشنهادی: + + + {suggestPrice > 0 + ? `${suggestPrice?.toLocaleString()} ﷼` + : "نامعتبر"} + + */} + + + + {/* + + + نحوه پرداخت + + { + formik2.setFieldValue("paymentType", e.target.value); + }} + > + } + label="پرداخت جداگانه به اتحادیه و مرغدار" + /> + } + label="پرداخت یکجا به حساب اتحادیه" + /> + + + */} + + + + {isDenyed ? ( + + + + + + + + + + + + + + + + + ) : ( + + + + + )} + + + + + + + + + ); +}; + +FinancialCheckRequestOperation.propTypes = { + item: PropTypes.object, + file: PropTypes.object, +}; diff --git a/src/features/file/components/financial-check-request-title/FinancialCheckRequestTitle.js b/src/features/file/components/financial-check-request-title/FinancialCheckRequestTitle.js new file mode 100644 index 0000000..4fb464a --- /dev/null +++ b/src/features/file/components/financial-check-request-title/FinancialCheckRequestTitle.js @@ -0,0 +1,24 @@ +import { PropTypes } from "prop-types"; +import { Grid } from "../../../../components/grid/Grid"; +import TimelineOppositeContent from "@mui/lab/TimelineOppositeContent"; +import { Typography } from "@mui/material"; + +export const FinancialCheckRequestTitle = ({ file }) => { + return ( + + + + + + مرحله تایید پرداخت فاکتور + + + + + + ); +}; + +FinancialCheckRequestTitle.propTypes = { + file: PropTypes.any, +}; diff --git a/src/features/file/components/financial-create-factor-title/FinancialCreateFactorTitle.js b/src/features/file/components/financial-create-factor-title/FinancialCreateFactorTitle.js new file mode 100644 index 0000000..1573c30 --- /dev/null +++ b/src/features/file/components/financial-create-factor-title/FinancialCreateFactorTitle.js @@ -0,0 +1,24 @@ +import { PropTypes } from "prop-types"; +import { Grid } from "../../../../components/grid/Grid"; +import TimelineOppositeContent from "@mui/lab/TimelineOppositeContent"; +import { Typography } from "@mui/material"; + +export const FinancialCreateFactorTitle = ({ file }) => { + return ( + + + + + + مرحله صدور و پرداخت فاکتور مالی + + + + + + ); +}; + +FinancialCreateFactorTitle.propTypes = { + file: PropTypes.any, +}; diff --git a/src/features/file/components/inspector-check-request-title/InspectorCheckRequestTitle.js b/src/features/file/components/inspector-check-request-title/InspectorCheckRequestTitle.js new file mode 100644 index 0000000..bb805a0 --- /dev/null +++ b/src/features/file/components/inspector-check-request-title/InspectorCheckRequestTitle.js @@ -0,0 +1,24 @@ +import { PropTypes } from "prop-types"; +import { Grid } from "../../../../components/grid/Grid"; +import TimelineOppositeContent from "@mui/lab/TimelineOppositeContent"; +import { Typography } from "@mui/material"; + +export const InspectorCheckRequestTitle = ({ file }) => { + return ( + + + + + + تایید بازرس + + + + + + ); +}; + +InspectorCheckRequestTitle.propTypes = { + file: PropTypes.any, +}; diff --git a/src/features/file/components/inspector-information/InspectorInformation.js b/src/features/file/components/inspector-information/InspectorInformation.js new file mode 100644 index 0000000..08c0ff1 --- /dev/null +++ b/src/features/file/components/inspector-information/InspectorInformation.js @@ -0,0 +1,72 @@ +import * as React from "react"; + +import { PropTypes } from "prop-types"; +import { SimpleTable } from "../../../../components/simple-table/SimpleTable"; +import { Grid } from "../../../../components/grid/Grid"; +import { + TimelineConnector, + TimelineContent, + TimelineDot, + TimelineItem, + TimelineOppositeContent, + TimelineSeparator, +} from "@mui/lab"; +import { Typography } from "@mui/material"; +import { SPACING } from "../../../../data/spacing"; + +export const InspectorInformation = ({ data }) => { + return ( + <> + + + + + + + + + + + اطلاعات تایید نهایی بازرس + + + + + + + + وضعیت نهایی پرونده بررسی شده توسط بازرس در این مرحله نمایش + داده شده است. + + + + + + + + + + + + + + ); +}; + +InspectorInformation.propTypes = { + data: PropTypes.any, +}; diff --git a/src/features/file/components/inspector-request-operations/InspectorRequestOperations.js b/src/features/file/components/inspector-request-operations/InspectorRequestOperations.js new file mode 100644 index 0000000..b517dc3 --- /dev/null +++ b/src/features/file/components/inspector-request-operations/InspectorRequestOperations.js @@ -0,0 +1,253 @@ +import { + TimelineConnector, + TimelineContent, + TimelineDot, + TimelineItem, + TimelineOppositeContent, + TimelineSeparator, +} from "@mui/lab"; +import { Button, TextField, Typography } from "@mui/material"; +import React, { useEffect, useState } from "react"; +import { PropTypes } from "prop-types"; +import { AnimatePresence, motion } from "framer-motion"; +import { useDispatch } from "react-redux"; +import { useFormik } from "formik"; + +import { useContext } from "react"; +import { AppContext } from "../../../../contexts/AppContext"; +import { Yup } from "../../../../lib/yup/yup"; +import { Grid } from "../../../../components/grid/Grid"; +import { SPACING } from "../../../../data/spacing"; +import { + DRAWER, + LOADING_END, + LOADING_START, +} from "../../../../lib/redux/slices/appSlice"; +import { inspectorCheckRequest } from "../../services/inspector-check-request"; +import { getFileFromApi } from "../../hooks/useRequestFile"; +import useUserProfile from "../../../authentication/hooks/useUserProfile"; +import { useParams } from "react-router-dom"; +import { inspectorGetNewRequests } from "../../../inspector/services/inspector-new-requests"; + +export const InspectorRequestOperations = ({ process }) => { + const [openNotif] = useContext(AppContext); + const [isSubmited, setIsSubmited] = useState(false); + + useEffect(() => { + if (process === null) { + setIsSubmited(true); + } + }, []); + + const formik = useFormik({ + initialValues: { + rejectText: "", + }, + validationSchema: Yup.object({ + rejectText: Yup.string() + .required("این فیلد اجباری است!") + .typeError("لطفا دلیل خود را بیان کنید."), + }), + }); + const [isDenyed, setisDenyed] = useState(false); + const dispatch = useDispatch(); + const [roles] = useUserProfile(); + const { id } = useParams(); + + return ( + <> + {!isSubmited && ( + + + + + + + + + + انجام عملیات بازرسی + + + + + + در این مرحله درخواست را تایید یا رد کنید. + + + + + + + + + {isDenyed ? ( + + + + + + + + + + + + + + + + + ) : ( + + + + + )} + + + + + + + )} + + ); +}; +InspectorRequestOperations.propTypes = { + process: PropTypes.any, +}; diff --git a/src/features/file/components/province-allocated/ProvinceAllocated.js b/src/features/file/components/province-allocated/ProvinceAllocated.js new file mode 100644 index 0000000..fc9d22c --- /dev/null +++ b/src/features/file/components/province-allocated/ProvinceAllocated.js @@ -0,0 +1,36 @@ +import { format } from "date-fns-jalali"; +import { useEffect, useState } from "react"; +import { SimpleTable } from "../../../../components/simple-table/SimpleTable"; + +export const ProvinceAllocated = ({ allocated }) => { + const [data, setData] = useState([]); + + useEffect(() => { + const d = allocated?.map((item, i) => { + let assignmentState; + if (item.provinceKillRequestState === "accepted") { + assignmentState = "تایید شده"; + } else if (item.provinceKillRequestState === "pending") { + assignmentState = + "در انتظار تایید و تخصیص خودرو توسط کشتارگاه می باشد."; + } else if (item.provinceKillRequestState === "rejected") { + assignmentState = "درخواست توسط کشتارگاه رد شده است!"; + } + return [ + `${item.killHouseName} (${item.killHouseUserName})`, + format(new Date(item.date), "yyyy/MM/dd"), + item.mainQuantity?.toLocaleString(), + item.automaticState ? "تخصیص خودکار" : "تخصیص دستی", + assignmentState, + ]; + }); + setData(d); + }, []); + + return ( + + ); +}; diff --git a/src/features/file/components/province-allocation-information/ProvinceAllocationInformation.js b/src/features/file/components/province-allocation-information/ProvinceAllocationInformation.js new file mode 100644 index 0000000..8dbad7b --- /dev/null +++ b/src/features/file/components/province-allocation-information/ProvinceAllocationInformation.js @@ -0,0 +1,105 @@ +import { Grid } from "../../../../components/grid/Grid"; +import { SimpleTable } from "../../../../components/simple-table/SimpleTable"; +import { PropTypes } from "prop-types"; +import { + TimelineConnector, + TimelineContent, + TimelineDot, + TimelineItem, + TimelineOppositeContent, + TimelineSeparator, +} from "@mui/lab"; +import { Typography } from "@mui/material"; +import { format } from "date-fns-jalali"; + +export const ProvinceAllocationInformation = ({ item, i }) => { + let columns = []; + let data = []; + let state; + state = + item.provinceKillRequestState === "pending" + ? "در انتظار تایید کشتارگاه" + : state; + state = item.provinceKillRequestState === "accepted" ? "تایید شده" : state; + state = item.provinceKillRequestState === "rejected" ? "رد شده" : state; + if (item.provinceKillRequestMessage) { + columns = [ + "نام کشتارگاه", + "مالک کشتارگاه", + "تعداد تخصیص داده شده", + "تاریخ تخصیص", + "نحوه خرید", + "نوع تخصیص", + "وضعیت درخواست", + "دلیل رد", + ]; + data = [ + item.killHouseName, + item.killHouseUserName, + item.mainQuantity + " قطعه", + format(new Date(item.date), "yyyy/MM/dd"), + item.paymentType, + item.automaticState ? "اتوماتیک" : "دستی", + state, + item.provinceKillRequestMessage, + ]; + } else { + columns = [ + "نام کشتارگاه", + "مالک کشتارگاه", + "تعداد تخصیص داده شده", + "تاریخ تخصیص", + "نوع تخصیص", + "وضعیت درخواست", + ]; + data = [ + item.killHouseName, + item.killHouseUserName, + item.mainQuantity + " قطعه", + format(new Date(item.date), "yyyy/MM/dd"), + item.automaticState ? "اتوماتیک" : "دستی", + state, + ]; + } + + return ( + + + + + + + + + + تخصیصات استان به کشتارگاه + + + + + + در این قسمت جزییات تخصیصات را مشاهده می کنید. + + + + + + + + + + + + + + ); +}; + +ProvinceAllocationInformation.propTypes = { + item: PropTypes.object, + i: PropTypes.any, +}; diff --git a/src/features/file/components/province-allocation-information/ProvinceAllocationInformationContent.js b/src/features/file/components/province-allocation-information/ProvinceAllocationInformationContent.js new file mode 100644 index 0000000..6c71c9b --- /dev/null +++ b/src/features/file/components/province-allocation-information/ProvinceAllocationInformationContent.js @@ -0,0 +1,82 @@ +import { Grid } from "../../../../components/grid/Grid"; +import { SimpleTable } from "../../../../components/simple-table/SimpleTable"; +import { PropTypes } from "prop-types"; +import { TimelineOppositeContent } from "@mui/lab"; +import { format } from "date-fns-jalali"; + +export const ProvinceAllocationInformationContent = ({ item, i }) => { + let columns = []; + let data = []; + let state; + state = + item.provinceKillRequestState === "pending" + ? "در انتظار تایید کشتارگاه" + : state; + state = item.provinceKillRequestState === "accepted" ? "تایید شده" : state; + state = item.provinceKillRequestState === "rejected" ? "رد شده" : state; + if (item.provinceKillRequestMessage) { + columns = [ + "نام کشتارگاه", + "مالک کشتارگاه", + "تعداد تخصیص داده شده", + "تاریخ تخصیص", + "نحوه خرید", + "وضعیت درخواست", + "دلیل رد", + ]; + data = [ + item.killHouseName, + item.killHouseUserName, + item.mainQuantity + " قطعه", + format(new Date(item.date), "yyyy/MM/dd"), + item.paymentType, + state, + item.provinceKillRequestMessage, + ]; + } else { + columns = [ + "نام کشتارگاه", + "مالک کشتارگاه", + "تعداد تخصیص داده شده", + "تاریخ تخصیص", + "وضعیت درخواست", + ]; + data = [ + item.killHouseName, + item.killHouseUserName, + item.mainQuantity + " قطعه", + format(new Date(item.date), "yyyy/MM/dd"), + state, + ]; + } + + return ( + + + + + + تخصیصات استان به کشتارگاه + + + + + + + + + + + + + ); +}; + +ProvinceAllocationInformationContent.propTypes = { + item: PropTypes.object, + i: PropTypes.any, +}; diff --git a/src/features/file/components/province-allocation/ProvinceAllocation.js b/src/features/file/components/province-allocation/ProvinceAllocation.js new file mode 100644 index 0000000..660064a --- /dev/null +++ b/src/features/file/components/province-allocation/ProvinceAllocation.js @@ -0,0 +1,666 @@ +import { + TimelineConnector, + TimelineContent, + TimelineDot, + TimelineOppositeContent, + TimelineSeparator, +} from "@mui/lab"; +import { Grid } from "../../../../components/grid/Grid"; +import { + Button, + TextField, + // FormControl, + // FormControlLabel, + // Radio, + // RadioGroup, + Typography, +} from "@mui/material"; +import React, { useEffect, useState } from "react"; +import { PropTypes } from "prop-types"; +import TimelineItem from "@mui/lab/TimelineItem"; +import { useFormik } from "formik"; +import { Yup } from "../../../../lib/yup/yup"; +import useGetAllocationInformation from "../../hooks/useGetAllocationInformation"; +import { SPACING } from "../../../../data/spacing"; +import { useDispatch, useSelector } from "react-redux"; +// import PendingIcon from "@mui/icons-material/Pending"; +import AccessTimeIcon from "@mui/icons-material/AccessTime"; +import { format } from "date-fns-jalali"; +// import { getSlaughterHousesRequest } from "../../services/getSlaughterHousesRequest"; +import { ProvinceAuction } from "../province-auction/ProvinceAuction"; +import { useContext } from "react"; +import { AppContext } from "../../../../contexts/AppContext"; +import ThumbDownAltIcon from "@mui/icons-material/ThumbDownAlt"; +import { avicultureGetChickenPrice } from "../../../aviculture/services/aviculture-get-chicken-price"; +import { provinceRemoveAllocation } from "../../services/province-remove-allocation"; +import { SlaghterHouseRequestAllocationItem } from "../slaghterhouse-request-allocation-Item/SlaghterHouseRequestAllocationItem"; +import { poultryRequestIndexWeightService } from "../../services/city-edit-avculture.info"; +import MyTable from "../../../../components/my-table/MyTable"; +import { getAllocationInformation } from "../../services/get-allocation-information"; +import { provinceGetAllRequests } from "../../../province/services/province-get-all-requests"; +import { getSlaughterHousesRequest } from "../../services/getSlaughterHousesRequest"; +import useRequestFile, { getFileFromApi } from "../../hooks/useRequestFile"; +import useUserProfile from "../../../authentication/hooks/useUserProfile"; +import { LOADING_END, OPEN_MODAL } from "../../../../lib/redux/slices/appSlice"; +// import useRequestFile from "../../hooks/useRequestFile"; +import { ProvinceEditPoultryRequestForm } from "../../../province/components/province-edit-poultry-request-form/ProvinceEditPoultryRequestForm"; +import { ProvinceAllocated } from "../province-allocated/ProvinceAllocated"; + +export const ProvinceAllocation = ({ + id, + orginalQuantity, + // file, + item, + // remainQuantity, + getItemFreeSaleInProvince, + updateTable, +}) => { + const myFile = useRequestFile(id); + const file = myFile?.file?.process; + const [openNotif, , selectedDate1] = useContext(AppContext); + const remainQuantity = file?.poultry?.poultryRemainQuantity; + let { slaughterHousesRequest } = useSelector((state) => state.fileSlice); + const [, setRequestedWeight] = useState(); + const [, setRequestedBuyType] = useState(); + + const [fileQauntity, setFileQauntity] = useState(remainQuantity); + + useEffect(() => { + setFileQauntity(remainQuantity); + }, [remainQuantity, file]); + + const [allEntredQauntity, setAllEntredQauntity] = useState(null); + + const handleAllEntredQauntity = (q) => { + setAllEntredQauntity(q); + }; + + useEffect(() => { + // if (allEntredQauntity === null) { + // let obj = {}; + // slaughterHousesRequest.map((item, i) => { + // obj = { ...obj, [i]: item.remainQuantity }; + // }); + // setAllEntredQauntity(obj); + // } else { + // const getSum = (a, b) => a + b; + // const dd = Object.values(allEntredQauntity).reduce(getSum, 0); + // setFileQauntity(file.poultry.poultryQuantity - dd); + // } + if (allEntredQauntity !== null) { + const getSum = (a, b) => a + b; + const dd = Object.values(allEntredQauntity).reduce(getSum, 0); + setFileQauntity(remainQuantity - dd); + } + }, [allEntredQauntity]); + + useEffect(() => { + dispatch(poultryRequestIndexWeightService()); + dispatch(getSlaughterHousesRequest(file?.poultry?.poultryRequestKey)); + }, [file]); + // const [allocateOrAuction, setAllocateOrAuction] = useState("allocate"); + const [allocateOrAuction] = useState("allocate"); + + const [slaughterAllocationLimit] = useState(); + + const getSum = (a, b) => a + b; + const avgLast4KillhousesWeight = Array.isArray(slaughterHousesRequest) + ? slaughterHousesRequest + ?.map((item) => item.firstAverageWeight) + ?.reduce(getSum, 0) / slaughterHousesRequest?.length + : ""; + + // useEffect(() => { + // dispatch( + // getSlaughterHousesRequest({ key: file.poultry.poultryRequestKey }) + // ); + // }, []); + + const allocationInformation = useGetAllocationInformation( + file?.poultry?.poultryRequestKey + ); + + const dispatch = useDispatch(); + const [roles] = useUserProfile(); + + // const { avicultureChickenPrice } = useSelector( + // (state) => state.avicultureSlice + // ); + + // const liveChickenPrice = avicultureChickenPrice?.liveChickenPrice; + + // calc suggest price + // const chickenWeight = parseFloat( + // file.poultry.poultryIndexWeight.split(" ")[0] + // ); + // let suggestPrice = liveChickenPrice; + // const standardChicken = 2.75; + // const checkStep = 0.05; + // const costPerStep = 500; + + // if (chickenWeight < 2.7) { + // const howMuchToReduce = + // ((standardChicken - chickenWeight).toFixed(2) / checkStep) * costPerStep; + // suggestPrice = liveChickenPrice - howMuchToReduce; + // } + + useEffect(() => { + dispatch(avicultureGetChickenPrice()); + }, []); + + const formik = useFormik({ + initialValues: { + quantity: "", + slaughterHouse: "", + paymentType: "cash", + // fee: "", + }, + validationSchema: Yup.object({ + quantity: Yup.number() + .test( + "testlimit", + "تعداد باید کمتر یا مساوی ظرفیت کشتارگاه و مانده درخواست باشد", + (val, context) => { + return ( + context.originalValue && + context.originalValue <= allocationInformation.quantity && + context.originalValue <= slaughterAllocationLimit && + context.originalValue > 0 + ); + } + ) + // .max(allocationInformation.quantity, "بالاتر از ظرفیت وارد شده است") + .required("این فیلد اجباری است!") + .typeError("لطفا عدد وارد کنید!"), + slaughterHouse: Yup.string().required("این فیلد اجباری است!"), + paymentType: Yup.string().required("این فیلد اجباری است!"), + // fee: Yup.number().required("این فیلد اجباری است!"), + }), + }); + + useEffect(() => { + formik.validateForm(); + }, []); + + useEffect(() => { + if (!formik.values.slaughterHouse) { + setRequestedBuyType(null); + setRequestedWeight(null); + } + }, [formik.values.slaughterHouse]); + + const fileWeight = file?.poultry?.IndexWeight; + let weightType; + + const { poultryRequestIndexWeight } = useSelector((state) => state.fileSlice); + const avgPoultryRequestsWeight = poultryRequestIndexWeight?.ave; + + if (fileWeight > avgPoultryRequestsWeight) { + weightType = "high"; + } else if (fileWeight < avgPoultryRequestsWeight) { + weightType = "low"; + } + + slaughterHousesRequest = Array.isArray(slaughterHousesRequest) + ? slaughterHousesRequest + : []; + const sortedSlaughterReqs = [...slaughterHousesRequest]?.sort(function ( + a, + b + ) { + if (weightType === "high") { + if ( + a.firstAverageWeight < b.firstAverageWeight && + a.killHouse.systemAddress?.city?.name === file?.poultry?.poultryCity + ) { + return -1; + // return a.firstAverageWeight - b.firstAverageWeight; + } + } + if (weightType === "low") { + if ( + a.firstAverageWeight > b.firstAverageWeight && + a.killHouse.systemAddress?.city?.name === file?.poultry?.poultryCity + ) { + return -1; + // return b.firstAverageWeight - a.firstAverageWeight; + } + } + return 0; + }); + + const totalAllocatedMainQuantity = allocationInformation?.provinceAssignments + ?.length + ? allocationInformation?.provinceAssignments?.reduce( + (accumulator, currentValue) => { + if (currentValue.provinceKillRequestState !== "rejected") { + return accumulator + currentValue.mainQuantity; + } + return accumulator; + }, + 0 + ) + : 0; + const defaultValueForAllocate = orginalQuantity - totalAllocatedMainQuantity; + + const [searchText, setSearchText] = useState(""); + + return ( + + + + + + + + + + انجام عملیات + + + + + {/* + در این مرحله سفارش را به کشتارگاه تخصیص دهید. + */} + + + تعداد اولیه درخواست کشتار: {orginalQuantity?.toLocaleString()}{" "} + قطعه + + + + تخصیص داده شده: ‌ + {totalAllocatedMainQuantity?.toLocaleString()} قطعه + + + + تعداد قابل تخصیص:‌ {fileQauntity?.toLocaleString()} قطعه + + + + مرغدار:‌{" "} + {`${item?.poultryRequest?.poultry?.unitName} (${item?.poultryRequest?.poultry?.userprofile?.mobile})`} + + + + نوع فروش:‌ {getItemFreeSaleInProvince(item)} + + + + + + {/* + + + فروش از طریق + { + setAllocateOrAuction(e.currentTarget.value); + }} + > + } + label="تخصیص به کشتارگاه" + /> + } + label="مزایده" + /> + + + + */} + + {allocateOrAuction === "allocate" && ( + + + + setSearchText(e.target.value)} + /> + + {sortedSlaughterReqs + ?.filter((item) => { + const buyerNamePrefix = item?.killHouse?.killer + ? "کشتارکن" + : "کشتارگاه"; + const forSearch = + buyerNamePrefix + " " + item?.killHouse?.name; + return forSearch.includes(searchText); + }) + .map((slaughterHouseReq, i) => { + return ( + + ); + })} + + + + {/* + + نحوه فروش + { + formik.setFieldValue( + "paymentType", + event.currentTarget.value + ); + }} + > + } + label="نقدی" + /> + } + label="زمان دار (تا یک ماه)" + /> + + + */} + {/* + + + prop.palette.grey["A700"]} + variant={"caption"} + > + قیمت مرغ استاندارد: + + + {liveChickenPrice} ﷼ + + + + prop.palette.grey["A700"]} + variant={"caption"} + > + قیمت پیشنهادی: + + {suggestPrice} ﷼ + + */} + + {/* + + کدرهگیری سامانه قرنطینه:{" "} + {file?.poultry?.clearanceCode + ? file?.poultry?.clearanceCode + : "در انتظار صدور"} + + */} + + + تخصیص های انجام شده + + + {!allocationInformation?.provinceAssignments?.length && ( + + تخصیصی انجام نشده است. + + )} + {allocationInformation?.provinceAssignments?.map((item, i) => { + let assignmentState; + if (item.provinceKillRequestState === "accept") { + assignmentState = "تایید شده است."; + } else if (item.provinceKillRequestState === "pending") { + assignmentState = + "در انتظار تایید و تخصیص خودرو توسط کشتارگاه می باشد."; + } else if (item.provinceKillRequestState === "rejected") { + assignmentState = "درخواست توسط کشتارگاه رد شده است!"; + } + return ( + + + + + + {item.killHouseName} / {item.killHouseUserName} / + {item.killHouseMobile} + + + + + تاریخ کشتار{" "} + {format(new Date(item.date), "yyyy/MM/dd")} + + + + + {item.mainQuantity?.toLocaleString()} قطعه + + + + + {item?.market + ? "پنل معاملات" + : item.automaticState + ? "تخصیص خودکار" + : "تخصیص دستی"} + + + + + {item.provinceKillRequestState !== "rejected" ? ( + + ) : ( + + )} + + + {assignmentState} + + + + {item.provinceKillRequestState !== "rejected" && + item?.returnToProvince === false && ( + + + + + + )} + + ); + })} + + )} + {allocateOrAuction === "auction" && ( + + + + )} + + + ); +}; + +ProvinceAllocation.propTypes = { + file: PropTypes.object, +}; diff --git a/src/features/file/components/province-allocation/ProvinceAllocationContent.js b/src/features/file/components/province-allocation/ProvinceAllocationContent.js new file mode 100644 index 0000000..1ced5e9 --- /dev/null +++ b/src/features/file/components/province-allocation/ProvinceAllocationContent.js @@ -0,0 +1,613 @@ +import { Autocomplete } from "@mui/lab"; +import { Grid } from "../../../../components/grid/Grid"; +import { + Button, + FormControl, + FormControlLabel, + Radio, + RadioGroup, + TextField, + Typography, +} from "@mui/material"; +import React, { useEffect, useState } from "react"; +import { PropTypes } from "prop-types"; +import { useFormik } from "formik"; +import { Yup } from "../../../../lib/yup/yup"; +import useSlaughterHousesRequest from "../../hooks/useSlaughterHousesRequest"; +import useGetAllocationInformation from "../../hooks/useGetAllocationInformation"; +import { SPACING } from "../../../../data/spacing"; +import { useDispatch } from "react-redux"; +import { provinceDoAllocation } from "../../services/province-do-allocation"; +import { getSlaughterHousesForSelect } from "../../utils/getSlaughterHousesForSelect"; +import { + LOADING_END, + LOADING_START, +} from "../../../../lib/redux/slices/appSlice"; +import { getAllocationInformation } from "../../services/get-allocation-information"; +// import PendingIcon from "@mui/icons-material/Pending"; +import AccessTimeIcon from "@mui/icons-material/AccessTime"; +import { format } from "date-fns-jalali"; +// import { getSlaughterHousesRequest } from "../../services/getSlaughterHousesRequest"; +import { ProvinceAuction } from "../province-auction/ProvinceAuction"; +import { useContext } from "react"; +import { AppContext } from "../../../../contexts/AppContext"; +import { getFileFromApi } from "../../hooks/useRequestFile"; +import useUserProfile from "../../../authentication/hooks/useUserProfile"; +import { useParams } from "react-router-dom"; +import ThumbDownAltIcon from "@mui/icons-material/ThumbDownAlt"; +import { avicultureGetChickenPrice } from "../../../aviculture/services/aviculture-get-chicken-price"; +import { provinceRemoveAllocation } from "../../services/province-remove-allocation"; + +export const ProvinceAllocationContent = ({ file }) => { + const [openNotif] = useContext(AppContext); + + const [selectedSlaughterHouseKey, setSelectedSlaughterHouseKey] = + useState(null); + + const [requestedWeight, setRequestedWeight] = useState(); + const [requestedBuyType, setRequestedBuyType] = useState(); + + // const [allocateOrAuction, setAllocateOrAuction] = useState("allocate"); + const [allocateOrAuction] = useState("allocate"); + + const [slaughterAllocationLimit, setSlaughterAllocationLimit] = useState(); + + const slaughterHousesRequest = useSlaughterHousesRequest( + file.poultry.poultryRequestKey + ); + + // useEffect(() => { + // dispatch( + // getSlaughterHousesRequest({ key: file.poultry.poultryRequestKey }) + // ); + // }, []); + + const allocationInformation = useGetAllocationInformation( + file.poultry.poultryRequestKey + ); + + const dispatch = useDispatch(); + const [roles] = useUserProfile(); + const { id } = useParams(); + + // const { avicultureChickenPrice } = useSelector( + // (state) => state.avicultureSlice + // ); + + // const liveChickenPrice = avicultureChickenPrice?.liveChickenPrice; + + // calc suggest price + // const chickenWeight = parseFloat( + // file.poultry.poultryIndexWeight.split(" ")[0] + // ); + // let suggestPrice = liveChickenPrice; + // const standardChicken = 2.75; + // const checkStep = 0.05; + // const costPerStep = 500; + + // if (chickenWeight < 2.7) { + // const howMuchToReduce = + // ((standardChicken - chickenWeight).toFixed(2) / checkStep) * costPerStep; + // suggestPrice = liveChickenPrice - howMuchToReduce; + // } + + // poultry sellType + const requestedSellTypeCash = file.poultry.sellType.cash ? "نقدی" : null; + const requestedSellTypeCredit = file.poultry.sellType.credit + ? "زمان دار" + : null; + const requestedSellType = [requestedSellTypeCash, requestedSellTypeCredit] + .filter((item) => item) + .join(" یا "); + + useEffect(() => { + dispatch(avicultureGetChickenPrice()); + }, []); + + const formik = useFormik({ + initialValues: { + quantity: "", + slaughterHouse: "", + paymentType: "", + // fee: "", + }, + validationSchema: Yup.object({ + quantity: Yup.number() + .test( + "testlimit", + "تعداد باید کمتر یا مساوی ظرفیت کشتارگاه و مانده درخواست باشد", + (val, context) => { + return ( + context.originalValue && + context.originalValue <= allocationInformation.quantity && + context.originalValue <= slaughterAllocationLimit && + context.originalValue > 0 + ); + } + ) + // .max(allocationInformation.quantity, "بالاتر از ظرفیت وارد شده است") + .required("این فیلد اجباری است!") + .typeError("لطفا عدد وارد کنید!"), + slaughterHouse: Yup.string().required("این فیلد اجباری است!"), + paymentType: Yup.string().required("این فیلد اجباری است!"), + // fee: Yup.number().required("این فیلد اجباری است!"), + }), + }); + + useEffect(() => { + formik.validateForm(); + }, []); + + useEffect(() => { + if (!formik.values.slaughterHouse) { + setRequestedBuyType(null); + setRequestedWeight(null); + } + }, [formik.values.slaughterHouse]); + + return ( + <> + + {/* + + + فروش از طریق + { + setAllocateOrAuction(e.currentTarget.value); + }} + > + } + label="تخصیص به کشتارگاه" + /> + } + label="مزایده" + /> + + + + */} + + {allocateOrAuction === "allocate" && ( + + + + { + // if (e.target.nodeName === "svg") { + // formik.setFieldValue("slaughterHouse", ""); + // } else { + // const target = e.target || e.srcElement; + formik.setFieldValue("slaughterHouse", e.target.outerText); + if (option?.key) { + setSelectedSlaughterHouseKey(option.key); + } + setSlaughterAllocationLimit(option.remainQuantity); + setRequestedWeight(option.requestedWeight); + setRequestedBuyType(option.requestedBuyType); + // } + }} + onBlur={formik.handleBlur} + sx={{ width: "100%", minWidth: 300 }} + renderInput={(params) => ( + + )} + /> + + + + مرغدار: + + + prop.palette.grey["A700"]} + variant={"caption"} + > + حدود وزنی اعلامی: + + + {file.poultry.poultryIndexWeight} + + + + + prop.palette.grey["A700"]} + variant={"caption"} + > + پیشنهاد فروش: + + + {requestedSellType} + + + + + prop.palette.grey["A700"]} + variant={"caption"} + > + کشتارگاه های پیشنهادی: + + + {file?.poultry?.killHouseList?.join(" - ")} + + + + + + کشتارگاه: + + + prop.palette.grey["A700"]} + variant={"caption"} + > + پیشنهاد وزن: + + + {requestedWeight} + + + + prop.palette.grey["A700"]} + variant={"caption"} + > + پیشنهاد خرید: + + + {requestedBuyType} + + + + + + + + + prop.palette.grey["A700"]} + variant={"caption"} + > + مانده درخواست + + + {allocationInformation.quantity - formik.values.quantity >= + 0 + ? allocationInformation.quantity - formik.values.quantity + : allocationInformation.quantity}{" "} + قطعه + + + + + + نحوه فروش + { + formik.setFieldValue( + "paymentType", + event.currentTarget.value + ); + }} + > + } + label="نقدی" + /> + } + label="زمان دار (تا یک ماه)" + /> + + + + {/* + + + prop.palette.grey["A700"]} + variant={"caption"} + > + قیمت مرغ استاندارد: + + + {liveChickenPrice} ﷼ + + + + prop.palette.grey["A700"]} + variant={"caption"} + > + قیمت پیشنهادی: + + {suggestPrice} ﷼ + + */} + + + + + + + + تخصیص های انجام شده + + + {!allocationInformation?.provinceAssignments?.length && ( + + تخصیصی انجام نشده است. + + )} + {allocationInformation?.provinceAssignments?.map((item, i) => { + let assignmentState; + if (item.provinceKillRequestState === "accept") { + assignmentState = "تایید شده است."; + } else if (item.provinceKillRequestState === "pending") { + assignmentState = + "در انتظار تایید و تخصیص خودرو توسط کشتارگاه می باشد."; + } else if (item.provinceKillRequestState === "rejected") { + assignmentState = "درخواست توسط کشتارگاه رد شده است!"; + } + return ( + + + + + + {item.killHouseName} / {item.killHouseUserName} / + {item.killHouseMobile} + + + + + تاریخ کشتار{" "} + {format(new Date(item.date), "yyyy/MM/dd")} + + + + + {item.quantity} قطعه + + + + + {item.provinceKillRequestState !== "rejected" ? ( + + ) : ( + + )} + + + {assignmentState} + + + + {item.provinceKillRequestState !== "rejected" && ( + + + + + + )} + + ); + })} + + )} + {allocateOrAuction === "auction" && ( + + + + )} + + + ); +}; + +ProvinceAllocationContent.propTypes = { + file: PropTypes.object, +}; diff --git a/src/features/file/components/province-allocation/ProvinceAllocationTitle.js b/src/features/file/components/province-allocation/ProvinceAllocationTitle.js new file mode 100644 index 0000000..afa5ae9 --- /dev/null +++ b/src/features/file/components/province-allocation/ProvinceAllocationTitle.js @@ -0,0 +1,24 @@ +import { PropTypes } from "prop-types"; +import { Grid } from "../../../../components/grid/Grid"; +import TimelineOppositeContent from "@mui/lab/TimelineOppositeContent"; +import { Typography } from "@mui/material"; + +export const ProvinceAllocationTitle = ({ file }) => { + return ( + + + + + + مرحله تخصیص استان + + + + + + ); +}; + +ProvinceAllocationTitle.propTypes = { + file: PropTypes.any, +}; diff --git a/src/features/file/components/province-auction/ProvinceAuction.js b/src/features/file/components/province-auction/ProvinceAuction.js new file mode 100644 index 0000000..e39ea25 --- /dev/null +++ b/src/features/file/components/province-auction/ProvinceAuction.js @@ -0,0 +1,311 @@ +import { + Button, + Divider, + FormControl, + FormHelperText, + IconButton, + InputLabel, + MenuItem, + Select, + TextField, + Typography, +} from "@mui/material"; +import { useFormik } from "formik"; +import moment from "moment"; +import { useContext, useEffect, useState } from "react"; +import { useDispatch, useSelector } from "react-redux"; +import { Grid } from "../../../../components/grid/Grid"; +import { SPACING } from "../../../../data/spacing"; +import { PropTypes } from "prop-types"; + +import { + DRAWER, + LOADING_END, + LOADING_START, +} from "../../../../lib/redux/slices/appSlice"; +import { Yup } from "../../../../lib/yup/yup"; +import { avicultureGetChickenPrice } from "../../../aviculture/services/aviculture-get-chicken-price"; +import { avicultureGetRequests } from "../../../aviculture/services/aviculture-requests"; +import DeleteIcon from "@mui/icons-material/Delete"; +import AddIcon from "@mui/icons-material/Add"; +import { provinceRequestAuction } from "../../services/province-request-auction"; +import { AppContext } from "../../../../contexts/AppContext"; +import { getFileFromApi } from "../../hooks/useRequestFile"; +import { useParams } from "react-router-dom"; +import useUserProfile from "../../../authentication/hooks/useUserProfile"; + +export const ProvinceAuction = ({ poultryRequestKey }) => { + const [pricingKey, setPriceKey] = useState(); + const { id } = useParams(); + const [roles] = useUserProfile(); + + const { avicultureChickenPrice } = useSelector( + (state) => state.avicultureSlice + ); + + const [openNotif] = useContext(AppContext); + + const dispatch = useDispatch(); + + useEffect(() => { + dispatch(avicultureGetChickenPrice()); + }, []); + + const [arr, setArr] = useState([ + { + id: 0, + value: "", + hour: 2, + }, + ]); + + const addInput = () => { + setArr((prevState) => { + return [ + ...prevState, + { + id: prevState.length, + value: "", + hour: 1, + }, + ]; + }); + }; + + const removeInput = (e) => { + let number = arr.length - 1; + + if (number !== 0) { + let filteredArrayPrice = arr.filter((object, i) => i < number); + // let filteredArrayTime = arrPrices.filter((object, i) => i < number); + + setArr(filteredArrayPrice); + // setArrPrices(filteredArrayTime); + } + }; + + const handleChange = (e) => { + const [itemName, itemIndex] = e.target.name.split("-"); + if (itemName === "price") { + setArr((prevState) => { + const newState = prevState; + newState[itemIndex].value = e.target.value; + return newState; + }); + } else if (itemName === "hour") { + setArr((prevState) => { + const newState = prevState; + newState[itemIndex].hour = Number(e.target.value); + return newState; + }); + } + }; + useEffect(() => { + if (avicultureChickenPrice) { + setPriceKey(avicultureChickenPrice.key); + } + }, [avicultureChickenPrice]); + + const formik = useFormik({ + initialValues: { + noChicken: "", + price1: "", + price2: "", + price3: "", + slaughterDate: moment(Date()).format("YYYY-MM-DD hh:mm:ss"), + period1: "4", + period2: "4", + period3: "4", + weight: "", + }, + validationSchema: Yup.object({ + price1: Yup.number() + .typeError("لطفا عدد وارد کنید!") + .min( + avicultureChickenPrice?.floorPrice, + "قیمت وارد شده از کف قیمت امروز کمتر است" + ) + .max( + avicultureChickenPrice?.ceilingPrice, + "قیمت وارد شده از سقف قیمت امروز بیشتر است" + ), + price2: Yup.number() + .typeError("لطفا عدد وارد کنید!") + .min( + avicultureChickenPrice?.floorPrice, + "قیمت وارد شده از کف قیمت امروز کمتر است" + ) + .max( + avicultureChickenPrice?.ceilingPrice, + "قیمت وارد شده از سقف قیمت امروز بیشتر است" + ), + price3: Yup.number() + .typeError("لطفا عدد وارد کنید!") + .min( + avicultureChickenPrice?.floorPrice, + "قیمت وارد شده از کف قیمت امروز کمتر است" + ) + .max( + avicultureChickenPrice?.ceilingPrice, + "قیمت وارد شده از سقف قیمت امروز بیشتر است" + ), + weight: Yup.number() + .required("این فیلد اجباری است!") + .typeError("لطفا وزن را وارد کنید!"), + }), + }); + + return ( + + + prop.palette.grey["A700"]} + variant={"caption"} + > + کف قیمت امروز: + + + {avicultureChickenPrice?.floorPrice + ? avicultureChickenPrice?.floorPrice.toLocaleString() + : "نامشخص"}{" "} + {" "} + ریال + + + + prop.palette.grey["A700"]} + variant={"caption"} + > + سقف قیمت امروز: + + + {avicultureChickenPrice?.ceilingPrice + ? avicultureChickenPrice?.ceilingPrice.toLocaleString() + : "نامشخص"}{" "} + {" "} + ریال + + + + + + + + {arr.map((item, i) => { + return ( + + + پیشنهاد {i + 1} + + + + + بازه زمانی (ساعت) + + + + {formik.touched.period1 && Boolean(formik.errors.period1) + ? formik.errors.period1 + : null} + + + {/* */} + + ); + })} + + + + + + + + + + + + + + ); +}; + +ProvinceAuction.propTypes = { + poultryRequestKey: PropTypes.any, +}; diff --git a/src/features/file/components/province-check-request/ProvinceCheckRequest.js b/src/features/file/components/province-check-request/ProvinceCheckRequest.js new file mode 100644 index 0000000..07fdf7d --- /dev/null +++ b/src/features/file/components/province-check-request/ProvinceCheckRequest.js @@ -0,0 +1,322 @@ +import { + TimelineConnector, + TimelineContent, + // TimelineContent, + TimelineDot, + TimelineItem, + TimelineOppositeContent, + TimelineSeparator, +} from "@mui/lab"; +import { Button, TextField, Typography } from "@mui/material"; +import React, { useEffect, useState } from "react"; +// import { formatTime } from "../../../../utils/formatTime"; +import { PropTypes } from "prop-types"; +import { SPACING } from "../../../../data/spacing"; +import { Grid } from "../../../../components/grid/Grid"; +import { AnimatePresence, motion } from "framer-motion"; +import { useDispatch } from "react-redux"; +import { useFormik } from "formik"; +import { Yup } from "../../../../lib/yup/yup"; +import { provinceAcceptRequest } from "../../services/provinceAcceptRequest"; +import { + CLOSE_MODAL, + DRAWER, + LOADING_END, + LOADING_START, + OPEN_MODAL, +} from "../../../../lib/redux/slices/appSlice"; +import { provinceRejectRequest } from "../../services/provinceRejectRequest"; +import useRequestFile from "../../hooks/useRequestFile"; +// import useUserProfile from "../../../authentication/hooks/useUserProfile"; +import { useContext } from "react"; +import { AppContext } from "../../../../contexts/AppContext"; +import { getProvinceNewRequests } from "../../../province/services/get-province-new-requests"; + +const ProvinceCheckRequest = ({ id, file, item, updateTable }) => { + const myFile = useRequestFile(id); + file = file ? file : myFile?.file?.process; + const [openNotif, , selectedDate1, , selectedDate2, ,] = + useContext(AppContext); + const [isSubmited, setIsSubmited] = useState(false); + // const [roles] = useUserProfile(); + + useEffect(() => { + if (file?.province !== null) { + setIsSubmited(true); + } + }, [file]); + + const formik = useFormik({ + initialValues: { + rejectText: "", + }, + validationSchema: Yup.object({ + rejectText: Yup.string() + .required("این فیلد اجباری است!") + .typeError("لطفا دلیل خود را بیان کنید."), + }), + }); + const [isDenyed, setisDenyed] = useState(false); + // const animationControl = useAnimation(); + + // useEffect(() => { + // if (isDenyed) { + // animationControl.start({ + // x: -10, + // display: "block", + // transition: { duration: 0.3 }, + // }); + // } + // }, [isDenyed]); + + // const MotionInput = motion(TextField); + const dispatch = useDispatch(); + + return ( + <> + {!isSubmited && ( + + + + + + + + + + انجام عملیات + + + + + + در این مرحله درخواست را تایید یا رد کنید. + + + + + + + + + {isDenyed ? ( + + + + + + + + + + + + + + + + + ) : ( + + + + + + ), + }) + ); + dispatch( + getProvinceNewRequests({ + selectedDate1, + selectedDate2, + }) + ); + openNotif({ + vertical: "top", + horizontal: "center", + msg: "عملیات با موفقیت انجام شد.", + severity: "success", + }); + dispatch(LOADING_END()); + updateTable(); + } + }); + }} + > + تایید و اختصاص به کشتارگاه + + + )} + + + + + + + )} + + ); +}; +ProvinceCheckRequest.propTypes = { + file: PropTypes.object, +}; + +export default ProvinceCheckRequest; diff --git a/src/features/file/components/province-financial-slaughter-check-request/ProvinceFinancialSlaughterCheckRequest.js b/src/features/file/components/province-financial-slaughter-check-request/ProvinceFinancialSlaughterCheckRequest.js new file mode 100644 index 0000000..9015590 --- /dev/null +++ b/src/features/file/components/province-financial-slaughter-check-request/ProvinceFinancialSlaughterCheckRequest.js @@ -0,0 +1,254 @@ +import { + TimelineConnector, + TimelineContent, + // TimelineContent, + TimelineDot, + TimelineItem, + TimelineOppositeContent, + TimelineSeparator, +} from "@mui/lab"; +import { Button, TextField, Typography } from "@mui/material"; +import React, { useState } from "react"; +// import { formatTime } from "../../../../utils/formatTime"; +import { PropTypes } from "prop-types"; +import { Grid } from "../../../../components/grid/Grid"; + +import { SPACING } from "../../../../data/spacing"; +import { useFormik } from "formik"; +import { Yup } from "../../../../lib/yup/yup"; +import { useDispatch } from "react-redux"; +import { AnimatePresence, motion } from "framer-motion"; +import { + DRAWER, + LOADING_END, + LOADING_START, +} from "../../../../lib/redux/slices/appSlice"; +import { provinceFinancialSlaughterCheckRequest } from "../../services/provinceFinancialSlaughterCheckRequest"; +import { useContext } from "react"; +import { AppContext } from "../../../../contexts/AppContext"; +import { provinceFinancialGetPayedFactorsService } from "../../../province-finacial/services/province-financial-get-payed-factors-service"; + +const ProvinceFinancialSlaughterCheckRequest = ({ factorKey, factorType }) => { + const [openNotif] = useContext(AppContext); + const [isSubmited] = useState(false); + const [isDenyed, setisDenyed] = useState(false); + const dispatch = useDispatch(); + + const formik = useFormik({ + initialValues: { + rejectText: "", + }, + validationSchema: Yup.object({ + rejectText: Yup.string() + .required("این فیلد اجباری است!") + .typeError("لطفا دلیل خود را بیان کنید."), + }), + }); + + return ( + <> + {!isSubmited && ( + + + + + + + + + + انجام عملیات + + + + + + در این مرحله فاکتور پرداخت را تایید یا رد کنید. + + + + + + + + + {isDenyed ? ( + + + + + + + + + + + + + + + + + ) : ( + + + + + )} + + + + + + + )} + + ); +}; +ProvinceFinancialSlaughterCheckRequest.propTypes = { + factorKey: PropTypes.any, + factorType: PropTypes.any, +}; + +export default ProvinceFinancialSlaughterCheckRequest; diff --git a/src/features/file/components/province-information/ProvinceInformation.js b/src/features/file/components/province-information/ProvinceInformation.js new file mode 100644 index 0000000..7fcbc57 --- /dev/null +++ b/src/features/file/components/province-information/ProvinceInformation.js @@ -0,0 +1,143 @@ +import { SimpleTable } from "../../../../components/simple-table/SimpleTable"; +import { PropTypes } from "prop-types"; +import { useEffect, useState } from "react"; +import TimelineSeparator from "@mui/lab/TimelineSeparator"; +import TimelineDot from "@mui/lab/TimelineDot"; +import TimelineConnector from "@mui/lab/TimelineConnector"; +import { Grid } from "../../../../components/grid/Grid"; +import TimelineOppositeContent from "@mui/lab/TimelineOppositeContent"; +import { Typography } from "@mui/material"; +import TimelineContent from "@mui/lab/TimelineContent"; +import { SPACING } from "../../../../data/spacing"; +import TimelineItem from "@mui/lab/TimelineItem"; +import { formatTime } from "../../../../utils/formatTime"; +import { format } from "date-fns-jalali"; + +export const ProvinceInformation = ({ file, quantity }) => { + const [provinceInfoData, setProvinceInfoData] = useState({ + provinceOperatorName: "اپراتور استان", + provinceOperatorMobile: "-", + acceptedRejectedDate: null, + provinceState: "در انتظار تایید", + }); + + const { province, provinceOperator } = file; + + useEffect(() => { + let provinceOperatorName, + provinceOperatorMobile, + acceptedRejectedDate, + provinceState; + if (province) { + provinceOperatorName = province.provinceOperatorName; + provinceOperatorMobile = province.provinceOperatorMobile; + acceptedRejectedDate = province.acceptedRejectedDate; + provinceState = + province.provinceState === "accept" ? "تایید شده" : "رد شده"; + } else { + provinceOperatorName = provinceOperator?.provinceOperatorName; + provinceOperatorMobile = provinceOperator?.provinceOperatorMobile; + acceptedRejectedDate = null; + provinceState = "در انتظار تایید"; + } + setProvinceInfoData({ + provinceOperatorName, + provinceOperatorMobile, + acceptedRejectedDate, + provinceState, + }); + }, [province]); + + return ( + <> + + + + + + + + + + + مرحله استان + + + + + + + {provinceInfoData.provinceState === "در انتظار تایید" ? ( + + درخواست منتظر انجام عملیات توسط اپراتور می باشد. + + ) : ( + <> + + درخواست در تاریخ + + + {provinceInfoData.acceptedRejectedDate + ? formatTime(provinceInfoData.acceptedRejectedDate) + : "-"} + + + {provinceInfoData.provinceState} است. + + + )} + + + + + + + + + + + + + ); +}; + +ProvinceInformation.propTypes = { + file: PropTypes.any, + quantity: PropTypes.any, +}; diff --git a/src/features/file/components/province-information/ProvinceInformationContent.js b/src/features/file/components/province-information/ProvinceInformationContent.js new file mode 100644 index 0000000..e0fbf96 --- /dev/null +++ b/src/features/file/components/province-information/ProvinceInformationContent.js @@ -0,0 +1,80 @@ +import { SimpleTable } from "../../../../components/simple-table/SimpleTable"; +import { PropTypes } from "prop-types"; +import { useEffect, useState } from "react"; +import { Grid } from "../../../../components/grid/Grid"; +import { format } from "date-fns-jalali"; + +export const ProvinceInformationContent = ({ file, quantity }) => { + const [provinceInfoData, setProvinceInfoData] = useState({ + provinceOperatorName: "اپراتور استان", + provinceOperatorMobile: "-", + acceptedRejectedDate: null, + provinceState: "در انتظار تایید", + }); + + const { province, provinceOperator } = file; + + useEffect(() => { + let provinceOperatorName, + provinceOperatorMobile, + acceptedRejectedDate, + provinceState; + if (province) { + provinceOperatorName = province.provinceOperatorName; + provinceOperatorMobile = province.provinceOperatorMobile; + acceptedRejectedDate = province.acceptedRejectedDate; + provinceState = + province.provinceState === "accept" ? "تایید شده" : "رد شده"; + } else { + provinceOperatorName = provinceOperator?.provinceOperatorName; + provinceOperatorMobile = provinceOperator?.provinceOperatorMobile; + acceptedRejectedDate = null; + provinceState = "در انتظار تایید"; + } + setProvinceInfoData({ + provinceOperatorName, + provinceOperatorMobile, + acceptedRejectedDate, + provinceState, + }); + }, [province]); + + return ( + <> + + + + + + + ); +}; + +ProvinceInformationContent.propTypes = { + file: PropTypes.any, + quantity: PropTypes.any, +}; diff --git a/src/features/file/components/province-information/ProvinceInformationTitle.js b/src/features/file/components/province-information/ProvinceInformationTitle.js new file mode 100644 index 0000000..06a9277 --- /dev/null +++ b/src/features/file/components/province-information/ProvinceInformationTitle.js @@ -0,0 +1,96 @@ +import { PropTypes } from "prop-types"; +import { useEffect, useState } from "react"; +import { Grid } from "../../../../components/grid/Grid"; +import TimelineOppositeContent from "@mui/lab/TimelineOppositeContent"; +import { Typography } from "@mui/material"; +import TimelineContent from "@mui/lab/TimelineContent"; +import { SPACING } from "../../../../data/spacing"; +import { formatTime } from "../../../../utils/formatTime"; + +export const ProvinceInformationTitle = ({ file, quantity }) => { + const [provinceInfoData, setProvinceInfoData] = useState({ + provinceOperatorName: "اپراتور استان", + provinceOperatorMobile: "-", + acceptedRejectedDate: null, + provinceState: "در انتظار تایید", + }); + + const { province, provinceOperator } = file; + + useEffect(() => { + let provinceOperatorName, + provinceOperatorMobile, + acceptedRejectedDate, + provinceState; + if (province) { + provinceOperatorName = province.provinceOperatorName; + provinceOperatorMobile = province.provinceOperatorMobile; + acceptedRejectedDate = province.acceptedRejectedDate; + provinceState = + province.provinceState === "accept" ? "تایید شده" : "رد شده"; + } else { + provinceOperatorName = provinceOperator?.provinceOperatorName; + provinceOperatorMobile = provinceOperator?.provinceOperatorMobile; + acceptedRejectedDate = null; + provinceState = "در انتظار تایید"; + } + setProvinceInfoData({ + provinceOperatorName, + provinceOperatorMobile, + acceptedRejectedDate, + provinceState, + }); + }, [province]); + + return ( + + + + + + مرحله استان + + + + + + + {provinceInfoData.provinceState === "در انتظار تایید" ? ( + + درخواست منتظر انجام عملیات توسط اپراتور می باشد. + + ) : ( + <> + + درخواست در تاریخ + + + {provinceInfoData.acceptedRejectedDate + ? formatTime(provinceInfoData.acceptedRejectedDate) + : "-"} + + + {provinceInfoData.provinceState} است. + + + )} + + + + + + ); +}; + +ProvinceInformationTitle.propTypes = { + file: PropTypes.any, + quantity: PropTypes.any, +}; diff --git a/src/features/file/components/slaghter-check-request-title/SlaghterCheckRequestTitle.js b/src/features/file/components/slaghter-check-request-title/SlaghterCheckRequestTitle.js new file mode 100644 index 0000000..76474a0 --- /dev/null +++ b/src/features/file/components/slaghter-check-request-title/SlaghterCheckRequestTitle.js @@ -0,0 +1,24 @@ +import { PropTypes } from "prop-types"; +import { Grid } from "../../../../components/grid/Grid"; +import TimelineOppositeContent from "@mui/lab/TimelineOppositeContent"; +import { Typography } from "@mui/material"; + +export const SlaghterCheckRequestTitle = ({ file }) => { + return ( + + + + + + مرحله تایید کشتارگاه + + + + + + ); +}; + +SlaghterCheckRequestTitle.propTypes = { + file: PropTypes.any, +}; diff --git a/src/features/file/components/slaghterhouse-request-allocation-Item/SlaghterHouseRequestAllocationItem.js b/src/features/file/components/slaghterhouse-request-allocation-Item/SlaghterHouseRequestAllocationItem.js new file mode 100644 index 0000000..0c4ac17 --- /dev/null +++ b/src/features/file/components/slaghterhouse-request-allocation-Item/SlaghterHouseRequestAllocationItem.js @@ -0,0 +1,306 @@ +import { + Button, + Checkbox, + TableCell, + TableRow, + TextField, + Tooltip, +} from "@mui/material"; +import { useFormik } from "formik"; +import React, { useContext, useEffect, useState } from "react"; +import { useDispatch, useSelector } from "react-redux"; +// import { useParams } from "react-router-dom"; +import { Grid } from "../../../../components/grid/Grid"; +import { AppContext } from "../../../../contexts/AppContext"; +import { + LOADING_END, + LOADING_START, + OPEN_MODAL, +} from "../../../../lib/redux/slices/appSlice"; +// import useUserProfile from "../../../authentication/hooks/useUserProfile"; +// import { getFileFromApi } from "../../hooks/useRequestFile"; +import { getAllocationInformation } from "../../services/get-allocation-information"; +import { provinceDoAllocation } from "../../services/province-do-allocation"; +import * as Yup from "yup"; +// import useUserProfile from "../../../authentication/hooks/useUserProfile"; +// import { useParams } from "react-router-dom"; +import { getSlaughterHousesRequest } from "../../services/getSlaughterHousesRequest"; +// import useUserProfile from "../../../authentication/hooks/useUserProfile"; +// import { useParams } from "react-router-dom"; +import { provinceGetAllRequests } from "../../../province/services/province-get-all-requests"; +import { getFileFromApi } from "../../hooks/useRequestFile"; +import useUserProfile from "../../../authentication/hooks/useUserProfile"; +import { ProvinceEditKillCapacityForm } from "../../../province/components/province-edit-kill-capacity-form/ProvinceEditKillCapacityForm"; +// import { getSlaughterHousesRequest } from "../../services/getSlaughterHousesRequest"; +import VerifiedIcon from "@mui/icons-material/Verified"; + +const validationSchema = Yup.object().shape({ + quantity: Yup.number() + .required("تعداد اجباری است.") + .positive("تعداد باید بالاتر از 0 باشد.") + .integer("تعداد باید عدد باشد."), +}); + +export function SlaghterHouseRequestAllocationItem({ + slaughterHouseReq, + provinceCheckRequestKey, + poultryRequestId, + poultryRequestKey, + // handleFileQuantity, + handleAllEntredQauntity, + allEntredQauntity, + name, + file, + avgLast4KillhousesWeight, + defaultValueForAllocate, + updateTable, +}) { + const [openNotif, , selectedDate1] = useContext(AppContext); + + const [roles] = useUserProfile(); + // const { id } = useParams(); + const dispatch = useDispatch(); + const [checked, setChecked] = useState(false); + + const handleCheckboxChange = (event) => { + setChecked(event.target.checked); + }; + + const formik = useFormik({ + initialValues: { + quantity: slaughterHouseReq.remainQuantity, + }, + validationSchema: validationSchema, + onSubmit: (values) => { + dispatch(LOADING_START()); + dispatch( + provinceDoAllocation({ + kill_request_key: slaughterHouseReq.key, + province_check_request_key: provinceCheckRequestKey, + quantity: values.quantity, + payment_type: "نقدی", + }) + ).then((r) => { + dispatch(LOADING_END()); + if (r.payload.error) { + openNotif({ + vertical: "top", + horizontal: "center", + msg: r.payload.error, + severity: "error", + }); + } else { + setChecked(false); + // handleAllEntredQauntity(null); + getFileFromApi(roles, poultryRequestId, dispatch); + dispatch(provinceGetAllRequests(selectedDate1)); + dispatch(getSlaughterHousesRequest({ key: poultryRequestKey })); + dispatch(getAllocationInformation({ key: poultryRequestKey })); + openNotif({ + vertical: "top", + horizontal: "center", + msg: "عملیات با موفقیت انجام شد.", + severity: "success", + }); + updateTable(); + } + }); + }, + }); + + useEffect(() => { + formik.validateForm(); + }, []); + + useEffect(() => { + const num = + Number(defaultValueForAllocate) < 0 ? 0 : Number(defaultValueForAllocate); + formik.setFieldValue("quantity", num); + }, [defaultValueForAllocate]); + + useEffect(() => { + if (checked) { + const num = + Number(formik.values.quantity) < 0 ? 0 : Number(formik.values.quantity); + handleAllEntredQauntity({ + ...allEntredQauntity, + [name]: num, + }); + } else { + handleAllEntredQauntity({ + ...allEntredQauntity, + [name]: Number(0), + }); + } + }, [formik.values.quantity, checked]); + + const { poultryRequestIndexWeight } = useSelector((state) => state.fileSlice); + const avgPoultryRequestsWeight = poultryRequestIndexWeight?.ave; + const fileWeight = file?.poultry?.IndexWeight; + // let weightProirity; + if ( + fileWeight > avgPoultryRequestsWeight && + slaughterHouseReq.firstAverageWeight < avgLast4KillhousesWeight + ) { + // weightType = "high"; + // weightProirity = true; + } else if ( + fileWeight < avgPoultryRequestsWeight && + slaughterHouseReq.firstAverageWeight > avgLast4KillhousesWeight + ) { + // weightType = "low"; + // weightProirity = true; + } else { + // weightProirity = false; + } + + const allocationBtnDisabled = + checked && formik.isValid && defaultValueForAllocate > 0; + + const buyerNamePrefix = slaughterHouseReq?.killHouse?.killer + ? "کشتارکن" + : "کشتارگاه"; + + return ( + + + + + {buyerNamePrefix + " " + slaughterHouseReq?.killHouse?.name} + + {slaughterHouseReq?.priority && ( + + + + )} + + + + {slaughterHouseReq?.killHouse?.killHouseOperator?.user?.fullname} ( + {slaughterHouseReq?.killHouse?.killHouseOperator?.user?.mobile}) + + + + {slaughterHouseReq.firstAverageWeight} کیلوگرم + + + {/* + + {slaughterHouseReq.secondAverageWeight} کیلوگرم + + */} + {/* + {weightProirity ? ( + دارد + ) : ( + ندارد + )} + + + {slaughterHouseReq?.killHouse?.systemAddress?.city?.name === + file?.poultry?.poultryCity ? ( + دارد + ) : ( + ندارد + )} + + + {slaughterHouseReq.debt ? ( + دارد + ) : ( + ندارد + )} + + + + {slaughterHouseReq?.factorAmount?.toLocaleString() + " ﷼"} + + + + + {slaughterHouseReq?.factorDeposit?.toLocaleString() + " ﷼"} + + */} + + + {slaughterHouseReq?.killCapacity} + + + + + + {slaughterHouseReq?.remainQuantity?.toLocaleString()} + + + + + {slaughterHouseReq?.numberOfAllocated?.toLocaleString()} + + + + + + + + + + + + + + + + ); +} + +const DisabledWrap = ({ children, checked }) => { + return {children}; +}; diff --git a/src/features/file/components/slaughter-assign-car-title/SlaughterAssignCarTitle.js b/src/features/file/components/slaughter-assign-car-title/SlaughterAssignCarTitle.js new file mode 100644 index 0000000..4833937 --- /dev/null +++ b/src/features/file/components/slaughter-assign-car-title/SlaughterAssignCarTitle.js @@ -0,0 +1,24 @@ +import { PropTypes } from "prop-types"; +import { Grid } from "../../../../components/grid/Grid"; +import TimelineOppositeContent from "@mui/lab/TimelineOppositeContent"; +import { Typography } from "@mui/material"; + +export const SlaghterAssignCarTitle = ({ file }) => { + return ( + + + + + + مرحله تخصیص و ثبت اطلاعات بار ماشین کشتارگاه + + + + + + ); +}; + +SlaghterAssignCarTitle.propTypes = { + file: PropTypes.any, +}; diff --git a/src/features/file/components/slaughter-assign-car/SlaughterAssignCar.js b/src/features/file/components/slaughter-assign-car/SlaughterAssignCar.js new file mode 100644 index 0000000..1c5a4ba --- /dev/null +++ b/src/features/file/components/slaughter-assign-car/SlaughterAssignCar.js @@ -0,0 +1,762 @@ +import { + TimelineConnector, + TimelineContent, + TimelineDot, + TimelineItem, + TimelineOppositeContent, + TimelineSeparator, +} from "@mui/lab"; +import { + Autocomplete, + Button, + FormControl, + FormHelperText, + InputLabel, + MenuItem, + Select, + TextField, + Typography, +} from "@mui/material"; +import React, { useState } from "react"; +import { PropTypes } from "prop-types"; +import { Grid } from "../../../../components/grid/Grid"; +import { useSlaughterHouseCars } from "../../hooks/useSlaughterHouseCars"; +import { SPACING } from "../../../../data/spacing"; +import { useFormik } from "formik"; +import { Yup } from "../../../../lib/yup/yup"; +import { useEffect } from "react"; +// import { useAcceptedSlaughterRequest } from "../../hooks/useAcceptedSlaughterRequest"; +import { useDispatch } from "react-redux"; +import { postSlaughterCarAllocation } from "../../services/postSlaughterCarAllocation"; +import { + DRAWER, + LOADING_END, + LOADING_START, +} from "../../../../lib/redux/slices/appSlice"; +import { getAllocationInformation } from "../../services/get-allocation-information"; +import { getAcceptedSlaughterRequest } from "../../services/getAcceptedSlaughterRequest"; +import { useParams } from "react-router-dom"; +import { useContext } from "react"; +import { AppContext } from "../../../../contexts/AppContext"; +import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl"; +import { slaughterGetActiveRequests } from "../../../slaughter-house/services/slaughter-get-active-requests"; +import { slaughterGetAllocatedCarsService } from "../../../slaughter-house/services/slaughter-get-allocated-cars"; +import { slaughterGetExlusiveKillers } from "../../services/slaughterGetExlusiveKillers"; +import { provincePolicyGetMaximumBarQuantityStatus } from "../../../province/services/province-policy-get-maximum-bar-quantity"; + +const SlaughterAssignCar = ({ + poultryRequestKey, + provinceAllocationLimit, + killRequestKey, + killHouseKey, + // killHouseName, + killHouseCheckKey, + indexWeight, + item, +}) => { + const file = {}; + const [openNotif] = useContext(AppContext); + const slaughterHouseCars = useSlaughterHouseCars( + poultryRequestKey, + killHouseKey, + killRequestKey + ); + + const [, , selectedDate1, , selectedDate2] = useContext(AppContext); + + const [maximumQuantity, setMaximumQuantity] = useState(false); + const fetchData = () => { + dispatch(provincePolicyGetMaximumBarQuantityStatus()).then((r) => { + setMaximumQuantity(r.payload.data); + }); + }; + + useEffect(() => { + fetchData(); + }, []); + + const { id } = useParams(); + const buttonText = + getRoleFromUrl() === "ProvinceOperator" + ? "ثبت اطلاعات خودرو بجای کشتارگاه" + : "ثبت اطلاعات خودرو"; + + // const killHouseCheckKey = acceptedSlaughterRequests.filter( + // (item) => item.quantity > 0 + // )[0]?.killHouseCheckKey; + + // useEffect(() => { + // const d = acceptedSlaughterRequests?.reduce( + // (total, item) => (item.quantity > total ? item.quantity : total), + // 0 + // ); + // setLimit(d); + // }, [acceptedSlaughterRequests]); + + const getMaxLimit = () => { + return maximumQuantity?.allow ? maximumQuantity?.limitation : 3100; + }; + const dispatch = useDispatch(); + const formik = useFormik({ + initialValues: { + // selectedRequest: "", + quantity: "", + car: "", + realCar: "", + shippingCode: "", + }, + validationSchema: Yup.object({ + // selectedRequest: Yup.string().required("این فیلد اجباری است!"), + quantity: Yup.number("یک عدد وارد کنید") + .typeError("لطفا ظرفیت را به عدد وارد کنید!") + .required("این فیلد اجباری است!") + .min(1, "یک مقدار مجاز وارد کنید!") + .max( + getMaxLimit(), + `حداکثر میزان تخصیص به ماشین ${getMaxLimit()} قطعه میباشد` + ), + shippingCode: Yup.string().required("این فیلد اجباری است!"), + // .test("len", "ظرفیت بیشتر از حد مجاز است!", (val, context) => { + // return context.originalValue && context.originalValue <= limit; + // }), + car: Yup.object().required("این فیلد اجباری است!"), + realCar: Yup.object(), + }), + }); + + useEffect(() => { + formik.validateForm(); + }, []); + + useEffect(() => { + if (file.killHouseWinner) { + formik.setFieldValue("selectedRequest", "not required"); + } + }, []); + + useEffect(() => { + if (file.killHouseWinner) { + formik.setFieldValue("selectedRequest", "not required"); + } + }, []); + + // const carsOptions = slaughterHouseCars?.map((car, i) => { + // let carType = "اختصاصی"; + // if (car.type === "exclusive") { + // carType = "اختصاصی"; + // } else if (car.type === "rental") { + // carType = "اجاره ای"; + // } + // const carLbl = `${car.driverName} (${car.driverMobile}) ${car.typeCar} پلاک ${car.pelak} ظرفیت ${car.capocity} قطعه (${carType})`; + // // const carLbl = ` ${car.driverName} (${car.driverMobile}) ${car.typeCar} ${car.typeWeight} پلاک ${car.pelak} ظرفیت ${car.capocity} قطعه `; + + // return ( + // + // {carLbl} + // + // ); + // }); + + const [chooseRealCar] = useState(false); + + // const handleChange = (event) => { + // setChooseRealCar(!chooseRealCar); + // }; + + const [exclusiveKillers, setExclusiveKillers] = useState(); + const [selectedOption, setSelectedOption] = useState(); + useEffect(() => { + if (item?.exclusiveKiller) { + dispatch(slaughterGetExlusiveKillers()).then((r) => { + setExclusiveKillers(r.payload.data); + }); + } + }, []); + + const handleOptionChange = (event) => { + setSelectedOption(event?.target.value); + }; + + const getFormValidation = () => { + if (exclusiveKillers && exclusiveKillers.length > 0) { + return selectedOption && formik.isValid; + } else { + return formik.isValid; + } + }; + + return ( + <> + {/* {acceptedSlaughterRequests.some((item) => item.quantity > 0) && ( */} + + + + + + + + + + انجام عملیات + + + + + + {/* ماشین های {killHouseName} خود را به تخصیص اختصاص دهید. */} + + + + + + + + {/* {!file.killHouseWinner && ( + + + + درخواست های تخصیص داده شده شما + + + + {formik.touched.race && Boolean(formik.errors.race) + ? formik.errors.race + : null} + + + + )} */} + + + + خودرو دارای کد بهداشتی حمل + + + + + { + if (car) { + const carType = + car.type === "exclusive" ? "اختصاصی" : "اجاره ای"; + return `${car.driverName} (${car.driverMobile}) ${car.typeCar} پلاک ${car.pelak} (${carType})`; + } + return ""; + }} + value={formik.values.car} + onChange={(e, car) => { + formik.setFieldValue("car", car); + formik.setFieldValue( + "shippingCode", + car ? car.healthCode : "" + ); + }} + onBlur={formik.handleBlur} + renderInput={(params) => ( + + )} + /> + + + {formik.touched.car && Boolean(formik.errors.car) + ? formik.errors.car + : null} + + + {/* + } + onChange={handleChange} + label="انتخاب خودرو واقعی برای حمل مرغ زنده (اختیاری)" + componentsProps={{ + typography: { + sx: { fontSize: "12px", color: "red" }, + }, + }} + /> + */} + + {chooseRealCar && ( + + { + if (car) { + const carType = + car.type === "exclusive" ? "اختصاصی" : "اجاره ای"; + return `${car.driverName} (${car.driverMobile}) ${car.typeCar} پلاک ${car.pelak} ظرفیت ${car.capocity} قطعه (${carType})`; + } + return ""; + }} + value={formik.values.realCar} + onChange={(e, car) => { + formik.setFieldValue("realCar", car); + }} + onBlur={formik.handleBlur} + renderInput={(params) => ( + + )} + /> + + + {formik.touched.realCar && + Boolean(formik.errors.realCar) + ? formik.errors.realCar + : null} + + + )} + + {exclusiveKillers?.length > 0 && ( + <> + + + انتخاب کشتارکن جهت تخصیص + + + + + انتخاب کشتارکن (اجباری) + + + + + )} + + {slaughterHouseCars + .filter((item) => item.busy) + .map((car, i) => { + const carLbl = `راننده ${car.driverName} ${car.typeCar} با پلاک ${car.pelak} جهت حمل بار کشتارگاه دیگری رزرو شده است.`; + // const carLbl = ` ${car.driverName} (${car.driverMobile}) ${car.typeCar} ${car.typeWeight} پلاک ${car.pelak} ظرفیت ${car.capocity} قطعه `; + return ( + + {carLbl} + + ); + })} + + + + + + + + + prop.palette.grey["A700"]} + variant={"caption"} + > + ظرفیت مجاز ماشین: + + + {getMaxLimit()} قطعه + + + + prop.palette.grey["A700"]} + variant={"caption"} + > + باقی مانده: + + + {provinceAllocationLimit - + Number(formik.values.quantity) >= + 0 + ? provinceAllocationLimit - + Number(formik.values.quantity) + : 0}{" "} + قطعه + + + + prop.palette.grey["A700"]} + variant={"caption"} + > + مازاد: + + + {Number(formik.values.quantity) > provinceAllocationLimit + ? Math.abs( + Number(formik.values.quantity) - + provinceAllocationLimit + ) + : 0}{" "} + قطعه + + + + prop.palette.grey["A700"]} + variant={"caption"} + > + وزن تقریبی هرقطعه مرغ: + + + {indexWeight.toLocaleString()} کیلوگرم + + + + + + prop.palette.grey["A700"]}> + = + + prop.palette.grey["A700"]} + variant={"caption"} + > + وزن تقریبی بار: + + + {( + Number(formik.values.quantity) * indexWeight + ).toLocaleString()}{" "} + کیلوگرم + + + + + + + + + {/* + + + ماشین های ثبت شده + + + + {!file.killHouseWinner && + acceptedSlaughterRequests?.map((item, i) => { + const head = `برای سفارش ${item.orderCode} با باقی مانده ظرفیت ${item.quantity} قطعه `; + const killHouseAssignments = + item.killHouseAssignments.map((assignment, index) => { + const barItem = `کدبار ${assignment.barcod} تعداد ${assignment.quantity} قطعه با ماشین ${assignment.cars.typeCar} راننده ${assignment.cars.driverName}`; + return ( + + prop.palette.grey["A700"]}> + + + + + + + + + ); + }); + return ( + + + {head} + + {killHouseAssignments} + + ); + })} + + {file.killHouseWinner && + file.auction?.map((item, i) => { + const head = `برای سفارش ${item.orderCode} با باقی مانده ظرفیت ${file.killHouseWinner.quantity} قطعه `; + const barItem = `کدبار ${item.barcod} تعداد ${item.quantity} قطعه با ماشین ${item.cars.typeCar} راننده ${item.cars.driverName}`; + const returnItem = ( + + prop.palette.grey["A700"]}> + + + + + + + + + ); + return ( + + + {head} + + {returnItem} + + ); + })} + + */} + + + + + {/* )} */} + + ); +}; +SlaughterAssignCar.propTypes = { + file: PropTypes.object, + provinceAllocationLimit: PropTypes.any, +}; + +export default SlaughterAssignCar; diff --git a/src/features/file/components/slaughter-check-request/SlaughterCheckRequest.js b/src/features/file/components/slaughter-check-request/SlaughterCheckRequest.js new file mode 100644 index 0000000..c01769e --- /dev/null +++ b/src/features/file/components/slaughter-check-request/SlaughterCheckRequest.js @@ -0,0 +1,93 @@ +import { + TimelineConnector, + TimelineContent, + // TimelineContent, + TimelineDot, + TimelineItem, + TimelineOppositeContent, + TimelineSeparator, +} from "@mui/lab"; +import { Typography } from "@mui/material"; +import React from "react"; +// import { formatTime } from "../../../../utils/formatTime"; +import { PropTypes } from "prop-types"; +import { Grid } from "../../../../components/grid/Grid"; + +import CheckRequestItem from "../check-request-item/CheckRequestItem"; +import { SPACING } from "../../../../data/spacing"; + +const SlaughterCheckRequest = ({ item }) => { + // useEffect(() => { + // if (file.city !== null) { + // setIsSubmited(true); + // } + // }, []); + + // const animationControl = useAnimation(); + + // useEffect(() => { + // ("eeeeeee", isDenyed); + // if (isDenyed) { + // animationControl.start({ + // x: -10, + // display: "block", + // transition: { duration: 0.3 }, + // }); + // } + // }, [isDenyed]); + + // const MotionInput = motion(TextField); + + return ( + <> + + + + + + + + + + انجام عملیات + + + + + + در این مرحله تخصیص را تایید یا رد کنید. + + + + + + + + + + + + + ); +}; +SlaughterCheckRequest.propTypes = { + item: PropTypes.object, + i: PropTypes.any, + poultryRequestKey: PropTypes.any, +}; + +export default SlaughterCheckRequest; diff --git a/src/features/file/components/slaughter-enter-bar-item/SlaughterEnterBarItem.js b/src/features/file/components/slaughter-enter-bar-item/SlaughterEnterBarItem.js new file mode 100644 index 0000000..2ede861 --- /dev/null +++ b/src/features/file/components/slaughter-enter-bar-item/SlaughterEnterBarItem.js @@ -0,0 +1,513 @@ +import { Grid } from "../../../../components/grid/Grid"; +import { SimpleTable } from "../../../../components/simple-table/SimpleTable"; +import { + Button, + FormControl, + InputLabel, + MenuItem, + Select, + Typography, +} from "@mui/material"; +import React, { useEffect, useState } from "react"; +import { useFormik } from "formik"; +import { Yup } from "../../../../lib/yup/yup"; +import { PropTypes } from "prop-types"; +import { SPACING } from "../../../../data/spacing"; +import { ImageUpload } from "../../../../components/image-upload/ImageUpload"; +import { fixBase64 } from "../../../../utils/toBase64"; +import { useDispatch, useSelector } from "react-redux"; +import { slaughterEnterBarWeight } from "../../../slaughter-house/services/slaughter-enter-bar-weight"; +import { DRAWER } from "../../../../lib/redux/slices/appSlice"; +import { useContext } from "react"; +import { AppContext } from "../../../../contexts/AppContext"; +import { slaughterUpdateBarWeight } from "../../../slaughter-house/services/slaughter-update-bar-weight"; +import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl"; +import { NumberInput } from "../../../../components/number-format-custom/NumberFormatCustom"; +import { resizeImage } from "../../../../utils/resizeImage"; +import { slaughterGetExlusiveKillers } from "../../services/slaughterGetExlusiveKillers"; +import { isValidIndexWeight } from "../../../../utils/isValidIndexWeight"; +import { checkPathStartsWith } from "../../../../utils/checkPathStartsWith"; + +export const SlaughterEnterBarItem = ({ + data, + reqKey, + // checkKey, + isRejected, + item, + realNumber, + updateTable, +}) => { + const [openNotif] = useContext(AppContext); + + const [weightWithBarImages, setWeightWithBarImages] = React.useState([]); + const [weightWithBarImg, setWeightWithBarImg] = React.useState(null); + const { weightRange } = useSelector((state) => state.provinceSlice); + const selectedSubUser = useSelector( + (state) => state.userSlice.selectedSubUser + ); + const weightWithBarImgHandler = (imageList) => { + setWeightWithBarImages(imageList); + formik.setFieldValue("weightWithBarImg", ""); + setWeightWithBarImg(null); + + if (imageList[0]) { + const file = imageList[0]?.file; + resizeImage(file, (resizedDataUrl) => { + const optimizedBase64 = fixBase64(resizedDataUrl); + setWeightWithBarImg(optimizedBase64); + formik.setFieldValue("weightWithBarImg", optimizedBase64); + }); + } else { + formik.setFieldValue("weightWithBarImg", ""); + } + }; + const [barWeight, setBarWeight] = useState(0); + + const dispatch = useDispatch(); + + let numFirstWeight = 0; + + const formik = useFormik({ + initialValues: { + weightWithoutBar: "", + weightWithBar: "", + weightWithBarImg: "", + loadRealNumber: item.acceptedRealQuantity + ? item.acceptedRealQuantity + : realNumber, + exploitedCarcass: 0, + }, + validationSchema: Yup.object({ + weightWithoutBar: Yup.number() + // .test( + // "weightWithoutBar", + // "وزن بدون بار نباید بزرگتر از وزن با بار باشد!", + // (val, context) => { + // return ( + // context.originalValue && context.originalValue < numLastWeight + // ); + // } + // ) + .min(0, "عدد منفی وارد نکنید!") + .required("این فیلد اجباری است!") + .typeError("لطفا عدد وارد کنید!"), + weightWithBar: Yup.number() + .test( + "len", + "وزن با بار باید بیشتر از وزن بدون بار باشد!", + (val, context) => { + return ( + context.originalValue && context.originalValue > numFirstWeight + ); + } + ) + .required("این فیلد اجباری است!") + .typeError("لطفا وزن را وارد کنید!"), + weightWithBarImg: Yup.string().required("این فیلد اجباری است!"), + loadRealNumber: Yup.number() + .required("این فیلد اجباری است!") + .typeError("لطفا عدد وارد کنید!"), + exploitedCarcass: Yup.number() + .required("این فیلد اجباری است!") + .typeError("لطفا عدد وارد کنید!"), + }), + }); + + numFirstWeight = Number(formik.values.weightWithoutBar); + + useEffect(() => { + formik.validateForm(); + }, []); + + useEffect(() => { + // fill the form if req is rejected + if (isRejected || item) { + formik.setFieldValue( + "weightWithoutBar", + item.assignmentInfo?.carWeightWithoutLoad + ); + formik.setFieldValue( + "weightWithBar", + item.assignmentInfo?.carWeightWithLoad + ); + } + }, []); + + useEffect(() => { + const numFirstWeight = Number(formik.values.weightWithoutBar); + const numLastWeight = Number(formik.values.weightWithBar); + if (numLastWeight) { + if (numFirstWeight < numLastWeight) { + setBarWeight(numLastWeight - numFirstWeight); + } else { + setBarWeight(0); + } + } + }, [formik.values.weightWithoutBar, formik.values.weightWithBar]); + + const [exclusiveKillers, setExclusiveKillers] = useState(); + const [selectedOption, setSelectedOption] = useState(); + + useEffect(() => { + dispatch( + slaughterGetExlusiveKillers({ + role_key: checkPathStartsWith("slaughter") + ? selectedSubUser?.key || "" + : "", + }) + ).then((r) => { + setExclusiveKillers(r.payload.data); + }); + }, [selectedSubUser?.key]); + + const handleOptionChange = (event) => { + setSelectedOption(event?.target.value); + }; + + const buttonText = + getRoleFromUrl() !== "KillHouse" + ? "ثبت اطلاعات بجای کشتارگاه" + : "ثبت اطلاعات"; + + return ( + + + + + + + + اطلاعات بار با کدبار {data[0][0]} را وارد کنید. + + {(isRejected || item.assignmentInfo) && ( + + توجه: حتما باید اطلاعات جدید دوباره وارد گردد. (سند ماشین و وزن + ماشین) + + )} + + {isRejected && ( + <> + + ({"اطلاعات بار توسط واحد مالی استان رد شده است."}) + + {/* + دلیل رد: {item?.barInfo?.message} + */} + + )} + + + + + + + {item.assignmentInfo.imageWithBar && ( + + + killHouseImageWithLoad + + + سند ماشین با بار بارگذاری شده + + + )} + + + + + + + + + + + + + + + prop.palette.grey["A700"]} + variant={"caption"} + > + وزن بار وارد شده + + {barWeight} کیلوگرم + + {exclusiveKillers?.length > 1 && ( + + + + انتخاب کشتارکن + + + + + + ویرایش کشتارکن اختصاصی (اختیاری) + + + + )} + + + + + + + + ); +}; + +SlaughterEnterBarItem.propTypes = { + data: PropTypes.array, + reqKey: PropTypes.string, + checkKey: PropTypes.string, + isRejected: PropTypes.bool, + item: PropTypes.any, + realNumber: PropTypes.any, +}; diff --git a/src/features/file/components/slaughter-enter-bar-weight/SlaughterEnterBarWeight.js b/src/features/file/components/slaughter-enter-bar-weight/SlaughterEnterBarWeight.js new file mode 100644 index 0000000..01e0a09 --- /dev/null +++ b/src/features/file/components/slaughter-enter-bar-weight/SlaughterEnterBarWeight.js @@ -0,0 +1,101 @@ +import { + TimelineConnector, + TimelineContent, + TimelineDot, + TimelineOppositeContent, + TimelineSeparator, +} from "@mui/lab"; +import { Grid } from "../../../../components/grid/Grid"; +import { Typography } from "@mui/material"; +import React, { useEffect } from "react"; +import { PropTypes } from "prop-types"; +import TimelineItem from "@mui/lab/TimelineItem"; +import { SlaughterEnterBarItem } from "../slaughter-enter-bar-item/SlaughterEnterBarItem"; +import { format } from "date-fns-jalali"; +import { provincePolicyGetWeightRange } from "../../../province/services/province-policy-get-weight-range"; +import { useDispatch, useSelector } from "react-redux"; +import { checkPathStartsWith } from "../../../../utils/checkPathStartsWith"; + +export const SlaughterEnterBarWeight = ({ item, updateTable }) => { + const dispatch = useDispatch(); + const selectedSubUser = useSelector( + (state) => state.userSlice.selectedSubUser + ); + const sum = item?.acceptedRealWeight / item?.acceptedRealQuantity; + const data = [ + [ + item.barCode, + `${item.poultryRequest?.poultry?.unitName} (${item.poultryRequest.poultry?.user?.mobile})`, + item.quantity.toLocaleString(), + item?.acceptedRealQuantity + ? item?.acceptedRealQuantity?.toLocaleString() + : "وارد نشده", + item?.acceptedRealWeight + ? item?.acceptedRealWeight?.toLocaleString() + : "وارد نشده", + sum ? sum.toFixed(2) : "وارد نشده", + item?.poultryRequest?.age, + format(new Date(item?.poultryRequest?.sendDate), "yyyy/MM/dd"), + item?.killer?.name, + ], + ]; + + useEffect(() => { + dispatch( + provincePolicyGetWeightRange({ + role_key: checkPathStartsWith("slaughter") + ? selectedSubUser?.key || "" + : "", + }) + ); + }, [selectedSubUser?.key]); + + return ( + + + + + + + + + + انجام عملیات + + + + + + در این مرحله اطلاعات مربوط به وزن و سند باسکول را وارد نمایید. + + + + + + + + + + + + ); +}; + +SlaughterEnterBarWeight.propTypes = { + file: PropTypes.object, +}; diff --git a/src/features/file/components/slaughter-house-vet-cancel-bar/SlaughterHouseVetCancelBar.js b/src/features/file/components/slaughter-house-vet-cancel-bar/SlaughterHouseVetCancelBar.js new file mode 100644 index 0000000..b3973f4 --- /dev/null +++ b/src/features/file/components/slaughter-house-vet-cancel-bar/SlaughterHouseVetCancelBar.js @@ -0,0 +1,40 @@ +import { + Button, + FormControl, + InputLabel, + MenuItem, + Select, +} from "@mui/material"; +import { useState } from "react"; +import { Grid } from "../../../../components/grid/Grid"; +import { SPACING } from "../../../../data/spacing"; + +export const SlaughterHouseVetCancelBar = () => { + const [selectedOption, setSelectedOption] = useState(null); + + const handleSelectChange = (event) => { + setSelectedOption(event.target.value); + }; + return ( + + + دلیل لغو بار + + + + + ); +}; diff --git a/src/features/file/components/slaughter-house-vet-check-request/SlaughterHouseVetCheckRequest.js b/src/features/file/components/slaughter-house-vet-check-request/SlaughterHouseVetCheckRequest.js new file mode 100644 index 0000000..f71e8f6 --- /dev/null +++ b/src/features/file/components/slaughter-house-vet-check-request/SlaughterHouseVetCheckRequest.js @@ -0,0 +1,181 @@ +import { Button, TextField, Typography } from "@mui/material"; +import React, { useState } from "react"; +import { SPACING } from "../../../../data/spacing"; +import { AnimatePresence } from "framer-motion"; +import { + DRAWER, + LOADING_END, + LOADING_START, + OPEN_MODAL, +} from "../../../../lib/redux/slices/appSlice"; +import { useDispatch } from "react-redux"; +import { PropTypes } from "prop-types"; +import { Grid } from "../../../../components/grid/Grid"; +import { useContext } from "react"; +import { AppContext } from "../../../../contexts/AppContext"; +import { slaughterHouseVetSendCheckRequest } from "../../services/slaughter-house-vet-send-check-request"; +import { + TimelineConnector, + TimelineContent, + TimelineDot, + TimelineItem, + TimelineOppositeContent, + TimelineSeparator, +} from "@mui/lab"; +import { slaughterHouseVetNewRequests } from "../../../slaughter-house-vet/services/slaughter-house-vet-new-requests"; +// import { SlaughterHouseVetCancelBar } from "../slaughter-house-vet-cancel-bar/SlaughterHouseVetCancelBar"; +import { VetFarmCancelBar } from "../../../vet-farm/components/vet-farm-cancel-bar/VetFarmCancelBar"; + +export default function SlaughterHouseVetCheckRequest({ item }) { + const dispatch = useDispatch(); + const [openNotif, , selectedDate1, , selectedDate2] = useContext(AppContext); + + const [value, setValue] = useState(item.quantity); + const [realWeight, setRealWeight] = useState(); + + const handleInputChange = (event) => { + setValue(event.target.value); + }; + + const handleInputChangeRealWeight = (event) => { + setRealWeight(event.target.value); + }; + + return ( + + + + + + + + + + انجام عملیات + + + + + + در این مرحله درخواست را بررسی و تایید کنید. + + + + + + + + + + + + + + + + + + + + + + ); +} +SlaughterHouseVetCheckRequest.propTypes = { + file: PropTypes.any, +}; diff --git a/src/features/file/components/slaughter-pay-factor-bank-gateway/SlaughterPayFactorBankGateway.js b/src/features/file/components/slaughter-pay-factor-bank-gateway/SlaughterPayFactorBankGateway.js new file mode 100644 index 0000000..85d0bb2 --- /dev/null +++ b/src/features/file/components/slaughter-pay-factor-bank-gateway/SlaughterPayFactorBankGateway.js @@ -0,0 +1,36 @@ +import { Button, InputAdornment } from "@mui/material"; +import { Grid } from "../../../../components/grid/Grid"; +import { useState } from "react"; +import { SPACING } from "../../../../data/spacing"; +import { NumberInput } from "../../../../components/number-format-custom/NumberFormatCustom"; + +export const SlaughterPayFactorBankGateway = ({ + provinceFactorToKillHouse, + price, + isRejected, + barCode, + killHouseFactorToProvince, +}) => { + const [inputValue, setInputValue] = useState(""); + return ( + + + ریال, + }} + value={inputValue} + onChange={(event) => setInputValue(event.target.value)} + /> + + + + + + ); +}; diff --git a/src/features/file/components/slaughter-pay-factor-manual/SlaughterPayFactorManual.js b/src/features/file/components/slaughter-pay-factor-manual/SlaughterPayFactorManual.js new file mode 100644 index 0000000..df9be61 --- /dev/null +++ b/src/features/file/components/slaughter-pay-factor-manual/SlaughterPayFactorManual.js @@ -0,0 +1,279 @@ +import { + Button, + IconButton, + InputAdornment, + TextField, + Typography, +} from "@mui/material"; +import { Grid } from "../../../../components/grid/Grid"; +import { SPACING } from "../../../../data/spacing"; +import { BankAccountInformation } from "../bank-account-information/BankAccountInformation"; +import ImgUploader from "../../../../components/img-uploader/ImgUploader"; +import { slaughterGetPayFactorRequestsService } from "../../../slaughter-house/services/slaughter-get-pay-factor-requests"; +import { + DRAWER, + LOADING_END, + LOADING_START, +} from "../../../../lib/redux/slices/appSlice"; +import { slaughterGetPaiedFactorsService } from "../../../slaughter-house/services/slaughter-get-paied-factors"; +import { slaughterUpdatePayProvinceFactor } from "../../services/slaughterUpdatePayProvinceFactor"; +import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl"; +import { slaughterPayProvinceFactor } from "../../services/slaughterPayProvinceFactor"; +import { useDispatch } from "react-redux"; +import { useContext, useState } from "react"; +import { AppContext } from "../../../../contexts/AppContext"; +import AddIcon from "@mui/icons-material/Add"; +import DeleteIcon from "@mui/icons-material/Delete"; +import { NumberInput } from "../../../../components/number-format-custom/NumberFormatCustom"; + +export const SlaughterPayFactorManual = ({ + provinceFactorToKillHouse, + price, + isRejected, + barCode, + killHouseFactorToProvince, +}) => { + const dispatch = useDispatch(); + const [, , selectedDate1, , selectedDate2] = useContext(AppContext); + const [openNotif] = useContext(AppContext); + const [inputValues, setInputValues] = useState([ + { id: 11, paymentId: "", doc: "", amount: "" }, + { id: 22, paymentId: "", doc: "", amount: "" }, + ]); + + const totalAmount = inputValues.reduce( + (acc, item) => acc + Number(item.amount), + 0 + ); + + return ( + + + + + + + + + + + مبلغ قابل پرداخت + + + {totalAmount + ? (Number(price) - totalAmount)?.toLocaleString() + : Number(price)?.toLocaleString()}{" "} + ریال + + + + + شناسه پرداخت + + + {barCode} + + + + + + {/* {info} */} + + + + + {inputValues + .sort((a, b) => a.id - b.id) + .map((item, i) => { + return ( + + {i + 1}. + + ریال + ), + }} + label="مبلغ پرداخت شده" + value={item.amount} + onChange={(e) => { + setInputValues((prevState) => { + const idToRemove = item.id; + const filteredArray = prevState.filter( + (obj) => obj.id !== idToRemove + ); + return [ + ...filteredArray, + { + ...item, + id: item.id, + amount: e.target.value, + }, + ]; + }); + }} + /> + + + { + setInputValues((prevState) => { + const idToRemove = item.id; + const filteredArray = prevState.filter( + (obj) => obj.id !== idToRemove + ); + return [ + ...filteredArray, + { + ...item, + id: item.id, + paymentId: e.target.value, + }, + ]; + }); + }} + /> + + + + + + { + setInputValues((prevState) => { + const idToRemove = item.id; + const filteredArray = prevState.filter( + (obj) => obj.id !== idToRemove + ); + return filteredArray; + }); + }} + > + + + + + ); + })} + + + + + + + + + + ); +}; diff --git a/src/features/file/components/slaughter-pay-poultry-factor-form/SlaughterPayPoultryFactorForm.js b/src/features/file/components/slaughter-pay-poultry-factor-form/SlaughterPayPoultryFactorForm.js new file mode 100644 index 0000000..892e789 --- /dev/null +++ b/src/features/file/components/slaughter-pay-poultry-factor-form/SlaughterPayPoultryFactorForm.js @@ -0,0 +1,226 @@ +import { + TimelineConnector, + TimelineContent, + TimelineDot, + TimelineItem, + TimelineOppositeContent, + TimelineSeparator, +} from "@mui/lab"; +import { Button, TextField, Typography } from "@mui/material"; +import { useEffect, useState } from "react"; +import { Grid } from "../../../../components/grid/Grid"; +import { SPACING } from "../../../../data/spacing"; +import { BankAccountInformation } from "../bank-account-information/BankAccountInformation"; +import { useFormik } from "formik"; +import { Yup } from "../../../../lib/yup/yup"; +import { ImageUpload } from "../../../../components/image-upload/ImageUpload"; +import { fixBase64 } from "../../../../utils/toBase64"; +import { useDispatch } from "react-redux"; +import { PropTypes } from "prop-types"; + +import { + LOADING_END, + LOADING_START, +} from "../../../../lib/redux/slices/appSlice"; +import { getFileFromApi } from "../../hooks/useRequestFile"; +import useUserProfile from "../../../authentication/hooks/useUserProfile"; +import { useParams } from "react-router-dom"; +import { useContext } from "react"; +import { AppContext } from "../../../../contexts/AppContext"; +import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl"; +import { slaughterUpdatePayPoultryFactor } from "../../services/slaughterUpdatePayPoultryFactor"; +import { slaughterPayPoultryFactor } from "../../services/slaughterPayPoultryFactor"; + +export const SlaughterPayPoultryFactorForm = ({ + factorKey, + price, + provinceFactorToPoultry, + killHouseFactorToPoultry, + isRejected, +}) => { + const [openNotif] = useContext(AppContext); + const [factorPaymentImages, setFactorPaymentImages] = useState([]); + const [factorPaymentImg, setFactorPaymentImg] = useState(); + const dispatch = useDispatch(); + const [roles] = useUserProfile(); + const { id } = useParams(); + + const formik = useFormik({ + initialValues: { + paymentId: "", + factorPaymentImg: "", + }, + validationSchema: Yup.object({ + paymentId: Yup.number() + .required("این فیلد اجباری است!") + .typeError("لطفا عدد وارد کنید!"), + factorPaymentImg: Yup.string().required("این فیلد اجباری است!"), + }), + }); + + const factorPaymentHandler = (imageList, addUpdateIndex) => { + if (imageList[0]) { + setFactorPaymentImg(fixBase64(imageList[0]?.data_url)); + formik.setFieldValue( + "factorPaymentImg", + fixBase64(imageList[0]?.data_url) + ); + } else { + formik.setFieldValue("factorPaymentImg", ""); + } + setFactorPaymentImages(imageList); + }; + + useEffect(() => { + formik.validateForm(); + }, []); + + useEffect(() => { + // fill the form if req is rejected + if (isRejected) { + formik.setFieldValue("paymentId", killHouseFactorToPoultry.paymentCode); + } + }, []); + + return ( + + + + + + + + + + انجام عملیات - پرداخت به مرغدار + + + + + + + در این مرحله مبلغ را پرداخت کنید و شناسه پرداخت را وارد و سند + آن را بارگذاری کنید. + + + + + + + + + + + + + + + + + + + + + + + + + + ); +}; +SlaughterPayPoultryFactorForm.propTypes = { + factorKey: PropTypes.string, + price: PropTypes.any, + provinceFactorToPoultry: PropTypes.any, + killHouseFactorToPoultry: PropTypes.any, + isRejected: PropTypes.any, +}; diff --git a/src/features/file/components/slaughter-pay-province-factor-form/SlaughterPayProvinceFactorForm.js b/src/features/file/components/slaughter-pay-province-factor-form/SlaughterPayProvinceFactorForm.js new file mode 100644 index 0000000..3fe3d7b --- /dev/null +++ b/src/features/file/components/slaughter-pay-province-factor-form/SlaughterPayProvinceFactorForm.js @@ -0,0 +1,166 @@ +import { + TimelineConnector, + TimelineContent, + TimelineDot, + TimelineItem, + TimelineOppositeContent, + TimelineSeparator, +} from "@mui/lab"; +import { FormControlLabel, Radio, RadioGroup, Typography } from "@mui/material"; +import React, { useEffect, useState } from "react"; +import { Grid } from "../../../../components/grid/Grid"; +import { SPACING } from "../../../../data/spacing"; +import { useFormik } from "formik"; +import { Yup } from "../../../../lib/yup/yup"; +// import { ImageUpload } from "../../../../components/image-upload/ImageUpload"; +// import { fixBase64 } from "../../../../utils/toBase64"; +import { PropTypes } from "prop-types"; +// import { slaughterPayProvinceFactor } from "../../services/slaughterPayProvinceFactor"; +// import { useContext } from "react"; +// import { AppContext } from "../../../../contexts/AppContext"; +// import { slaughterUpdatePayProvinceFactor } from "../../services/slaughterUpdatePayProvinceFactor"; +// import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl"; +// import { slaughterGetPayFactorRequestsService } from "../../../slaughter-house/services/slaughter-get-pay-factor-requests"; +// import { slaughterGetPaiedFactorsService } from "../../../slaughter-house/services/slaughter-get-paied-factors"; +// import ImgUploader from "../../../../components/img-uploader/ImgUploader"; +import { SlaughterPayFactorManual } from "../slaughter-pay-factor-manual/SlaughterPayFactorManual"; +import { SlaughterPayFactorBankGateway } from "../slaughter-pay-factor-bank-gateway/SlaughterPayFactorBankGateway"; + +export const SlaughterPayProvinceFactorForm = ({ + factorKey, + price, + provinceFactorToKillHouse, + killHouseFactorToProvince, + isRejected, + barCode, + item, +}) => { + // const [factorPaymentImages, setFactorPaymentImages] = React.useState([]); + // const [factorPaymentImg, setFactorPaymentImg] = React.useState(); + // const dispatch = useDispatch(); + // const [roles] = useUserProfile(); + // const { id } = useParams(); + + const formik = useFormik({ + initialValues: { + paymentId: "", + // factorPaymentImg: "", + }, + validationSchema: Yup.object({ + paymentId: Yup.number() + .required("این فیلد اجباری است!") + .typeError("لطفا عدد وارد کنید!"), + // factorPaymentImg: Yup.string().required("این فیلد اجباری است!"), + }), + }); + + // const factorPaymentHandler = (imageList, addUpdateIndex) => { + // if (imageList[0]) { + // setFactorPaymentImg(fixBase64(imageList[0]?.data_url)); + // formik.setFieldValue( + // "factorPaymentImg", + // fixBase64(imageList[0]?.data_url) + // ); + // } else { + // formik.setFieldValue("factorPaymentImg", ""); + // } + // setFactorPaymentImages(imageList); + // }; + + useEffect(() => { + formik.validateForm(); + }, []); + + useEffect(() => { + // fill the form if req is rejected + if (isRejected) { + formik.setFieldValue("paymentId", killHouseFactorToProvince.paymentCode); + } + }, []); + + let paymentTo = ""; + if (item?.factorPersonType === "union") { + paymentTo = "اتحادیه"; + } else { + paymentTo = "مرغدار"; + } + + const [selectedOption, setSelectedOption] = useState("option1"); + + const handleChange = (event) => { + setSelectedOption(event.target.value); + }; + + return ( + + + + + + + + + + انجام عملیات - پرداخت به {paymentTo} + + + + + + + در این مرحله مبلغ را پرداخت کنید و شناسه پرداخت را وارد و سند + آن را بارگذاری کنید. + + + + + + + + } + label="پرداخت از طریق درگاه پرداخت" + /> + } + label="ثبت سند پرداخت" + /> + + + + {selectedOption === "bank-gateway" && ( + + )} + {selectedOption === "manual-payment" && ( + + )} + + + + ); +}; + +SlaughterPayProvinceFactorForm.propTypes = { + factorKey: PropTypes.string, + price: PropTypes.any, + provinceFactorToKillHouse: PropTypes.any, + killHouseFactorToProvince: PropTypes.any, + isRejected: PropTypes.any, +}; diff --git a/src/features/file/components/slaughter-pay-province-factor/SlaughterPayProvinceFactor.js b/src/features/file/components/slaughter-pay-province-factor/SlaughterPayProvinceFactor.js new file mode 100644 index 0000000..0f375a0 --- /dev/null +++ b/src/features/file/components/slaughter-pay-province-factor/SlaughterPayProvinceFactor.js @@ -0,0 +1,68 @@ +import { + TimelineConnector, + TimelineContent, + TimelineDot, + TimelineItem, + TimelineOppositeContent, + TimelineSeparator, +} from "@mui/lab"; +import { Typography } from "@mui/material"; +import React from "react"; +// import { formatTime } from "../../../../utils/formatTime"; +import { PropTypes } from "prop-types"; +import { Grid } from "../../../../components/grid/Grid"; + +import { SimpleTable } from "../../../../components/simple-table/SimpleTable"; +import { SPACING } from "../../../../data/spacing"; + +const SlaughterPayProvinceFactor = ({ file }) => { + return ( + + + + + + + + + + + مرحله صدور فاکتور توسط استان + + + + + + + + در این مرحله اطلاعات مربوط به فاکتور های صادر شده توسط استان + را مشاهده می کنید. + + + + + + + + + + + + + ); +}; +SlaughterPayProvinceFactor.propTypes = { + file: PropTypes.object, +}; + +export default SlaughterPayProvinceFactor; diff --git a/src/features/file/components/slaughter-payment-factor-poultry/SlaughterPaymentFactorPoultry.js b/src/features/file/components/slaughter-payment-factor-poultry/SlaughterPaymentFactorPoultry.js new file mode 100644 index 0000000..d7ab46c --- /dev/null +++ b/src/features/file/components/slaughter-payment-factor-poultry/SlaughterPaymentFactorPoultry.js @@ -0,0 +1,98 @@ +import { + TimelineConnector, + TimelineContent, + TimelineDot, + TimelineItem, + TimelineOppositeContent, + TimelineSeparator, +} from "@mui/lab"; +import { Typography } from "@mui/material"; +import React from "react"; +import { Grid } from "../../../../components/grid/Grid"; +import { PropTypes } from "prop-types"; +import { SimpleTable } from "../../../../components/simple-table/SimpleTable"; +import { SPACING } from "../../../../data/spacing"; +import { formatTime } from "../../../../utils/formatTime"; + +export const SlaughterPaymentFactorPoultry = ({ data, barCode }) => { + return ( + <> + + + + + + + + + + + اطلاعات پرداختی کشتارگاه به مرغدار + + + + + + + + اطلاعات پرداختی کشتارگاه در این قسمت نمایش داده میشود. + + + + + + + + + Slaughter Payment Factor + , + ], + ]} + /> + + + + + + ); +}; + +SlaughterPaymentFactorPoultry.propTypes = { + data: PropTypes.any, + barCode: PropTypes.any, +}; diff --git a/src/features/file/components/slaughter-payment-factor/SlaughterPaymentFactor.js b/src/features/file/components/slaughter-payment-factor/SlaughterPaymentFactor.js new file mode 100644 index 0000000..0c63d70 --- /dev/null +++ b/src/features/file/components/slaughter-payment-factor/SlaughterPaymentFactor.js @@ -0,0 +1,99 @@ +import { + TimelineConnector, + TimelineContent, + TimelineDot, + TimelineItem, + TimelineOppositeContent, + TimelineSeparator, +} from "@mui/lab"; +import { Typography } from "@mui/material"; +import React from "react"; +import { Grid } from "../../../../components/grid/Grid"; +import { PropTypes } from "prop-types"; +import { SimpleTable } from "../../../../components/simple-table/SimpleTable"; +import { SPACING } from "../../../../data/spacing"; +import { formatTime } from "../../../../utils/formatTime"; + +const SlaughterPaymentFactor = ({ data, barCode }) => { + return ( + <> + + + + + + + + + + + اطلاعات پرداختی کشتارگاه + + + + + + + + اطلاعات پرداختی کشتارگاه در این قسمت نمایش داده میشود. + + + + + + + + + Slaughter Payment Factor + , + ], + ]} + /> + + + + + + ); +}; +SlaughterPaymentFactor.propTypes = { + data: PropTypes.any, + barCode: PropTypes.any, +}; + +export default SlaughterPaymentFactor; diff --git a/src/features/file/hooks/useAcceptedSlaughterRequest.js b/src/features/file/hooks/useAcceptedSlaughterRequest.js new file mode 100644 index 0000000..2c94d65 --- /dev/null +++ b/src/features/file/hooks/useAcceptedSlaughterRequest.js @@ -0,0 +1,23 @@ +import { useState, useEffect } from "react"; +import { useDispatch, useSelector } from "react-redux"; +import { getAcceptedSlaughterRequest } from "../services/getAcceptedSlaughterRequest"; + +export const useAcceptedSlaughterRequest = (id) => { + const dispatch = useDispatch(); + const { acceptedSlaughterRequest } = useSelector((state) => state.fileSlice); + const [data, setData] = useState(acceptedSlaughterRequest); + + useEffect(() => { + dispatch(getAcceptedSlaughterRequest({ id })); + }, []); + + useEffect(() => { + setData( + acceptedSlaughterRequest?.filter( + (item) => item.quantity > 0 && item.provinceKillState === "accepted" + ) + ); + }, [acceptedSlaughterRequest]); + + return data ? data : []; +}; diff --git a/src/features/file/hooks/useGetAllocationInformation.js b/src/features/file/hooks/useGetAllocationInformation.js new file mode 100644 index 0000000..41c318e --- /dev/null +++ b/src/features/file/hooks/useGetAllocationInformation.js @@ -0,0 +1,23 @@ +import { useState, useEffect } from "react"; +import { useDispatch, useSelector } from "react-redux"; +import { getAllocationInformation } from "../services/get-allocation-information"; + +const useGetAllocationInformation = (id) => { + const dispatch = useDispatch(); + const { allocationInformation } = useSelector((state) => state.fileSlice); + const [data, setData] = useState(allocationInformation); + + useEffect(() => { + if (id) { + dispatch(getAllocationInformation({ key: id })); + } + }, [id]); + + useEffect(() => { + setData(allocationInformation); + }, [allocationInformation]); + + return data ? data : []; +}; + +export default useGetAllocationInformation; diff --git a/src/features/file/hooks/useRequestFile.js b/src/features/file/hooks/useRequestFile.js new file mode 100644 index 0000000..aa4202f --- /dev/null +++ b/src/features/file/hooks/useRequestFile.js @@ -0,0 +1,55 @@ +import { useState, useEffect } from "react"; +import { useDispatch, useSelector } from "react-redux"; +import { + getFileProcess, + getFileProcessOther, +} from "../services/getFileProcess"; +import useUserProfile from "../../authentication/hooks/useUserProfile"; +import { getRoleFromUrl } from "../../../utils/getRoleFromUrl"; + +export function getFileFromApi(roles, id, dispatch) { + if ( + (getRoleFromUrl() === "CityOperator" || + getRoleFromUrl() === "Poultry" || + getRoleFromUrl() === "KillHouse") && + (roles.includes("Poultry") || + roles.includes("CityOperator") || + roles.includes("KillHouse")) + ) { + dispatch(getFileProcessOther(id)); + } else { + dispatch(getFileProcess(id)); + } +} + +const useRequestFile = (id) => { + const dispatch = useDispatch(); + const file = useSelector((state) => state.fileSlice); + const [data, setData] = useState(file); + const [roles] = useUserProfile(); + + useEffect(() => { + if ( + (getRoleFromUrl() === "CityOperator" || + getRoleFromUrl() === "Poultry" || + getRoleFromUrl() === "KillHouse" || + getRoleFromUrl() === "KillHouseVet") && + (roles.includes("Poultry") || + roles.includes("CityOperator") || + roles.includes("KillHouse") || + roles.includes("KillHouseVet")) + ) { + dispatch(getFileProcessOther(id)); + } else { + dispatch(getFileProcess(id)); + } + }, []); + + useEffect(() => { + setData(file); + }, [file]); + + return data ? data : []; +}; + +export default useRequestFile; diff --git a/src/features/file/hooks/useSlaughterAllocatedRequests.js b/src/features/file/hooks/useSlaughterAllocatedRequests.js new file mode 100644 index 0000000..8b181fa --- /dev/null +++ b/src/features/file/hooks/useSlaughterAllocatedRequests.js @@ -0,0 +1,19 @@ +import { useState, useEffect } from "react"; +import { useDispatch, useSelector } from "react-redux"; +import { getAcceptedSlaughterRequest } from "../services/getAcceptedSlaughterRequest"; + +export const useSlaughterAllocatedRequests = (id) => { + const dispatch = useDispatch(); + const { acceptedSlaughterRequest } = useSelector((state) => state.fileSlice); + const [data, setData] = useState(acceptedSlaughterRequest); + + useEffect(() => { + dispatch(getAcceptedSlaughterRequest({ id })); + }, []); + + useEffect(() => { + setData(acceptedSlaughterRequest); + }, [acceptedSlaughterRequest]); + + return data ? data : []; +}; diff --git a/src/features/file/hooks/useSlaughterHouseCars.js b/src/features/file/hooks/useSlaughterHouseCars.js new file mode 100644 index 0000000..2652a81 --- /dev/null +++ b/src/features/file/hooks/useSlaughterHouseCars.js @@ -0,0 +1,25 @@ +import { useState, useEffect } from "react"; +import { useDispatch } from "react-redux"; +import { slaughterGetCars } from "../../slaughter-house/services/slaughter-get-cars"; + +export const useSlaughterHouseCars = (id, killHouseKey, killRequestKey) => { + const dispatch = useDispatch(); + // const { slaughterHouseCars } = useSelector((state) => state.slaughterSlice); + const [data, setData] = useState([]); + + useEffect(() => { + if (id) { + dispatch(slaughterGetCars({ id, killHouseKey, killRequestKey })).then( + (r) => setData(r.payload.data) + ); + } else { + dispatch(slaughterGetCars()).then((r) => setData(r.payload.data)); + } + }, []); + + // useEffect(() => { + // setData(slaughterHouseCars); + // }, [slaughterHouseCars]); + + return data ? data : []; +}; diff --git a/src/features/file/hooks/useSlaughterHousesRequest.js b/src/features/file/hooks/useSlaughterHousesRequest.js new file mode 100644 index 0000000..8cca135 --- /dev/null +++ b/src/features/file/hooks/useSlaughterHousesRequest.js @@ -0,0 +1,21 @@ +import { useState, useEffect } from "react"; +import { useDispatch, useSelector } from "react-redux"; +import { getSlaughterHousesRequest } from "../services/getSlaughterHousesRequest"; + +const useSlaughterHousesRequest = (id) => { + const dispatch = useDispatch(); + const { slaughterHousesRequest } = useSelector((state) => state.fileSlice); + const [data, setData] = useState(slaughterHousesRequest); + + useEffect(() => { + dispatch(getSlaughterHousesRequest({ key: id })); + }, []); + + useEffect(() => { + setData(slaughterHousesRequest); + }, [slaughterHousesRequest]); + + return data ? data : []; +}; + +export default useSlaughterHousesRequest; diff --git a/src/features/file/services/checkRequestByCity.js b/src/features/file/services/checkRequestByCity.js new file mode 100644 index 0000000..ed6a68b --- /dev/null +++ b/src/features/file/services/checkRequestByCity.js @@ -0,0 +1,13 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; + +export const checkRequestByCity = createAsyncThunk( + "REJECT_REQUEST_CITY", + async (d) => { + const { data, status } = await axios.post( + `city_operator_check_request/`, + d + ); + return { data, status }; + } +); diff --git a/src/features/file/services/checkRequestBySlaughter.js b/src/features/file/services/checkRequestBySlaughter.js new file mode 100644 index 0000000..a649e1b --- /dev/null +++ b/src/features/file/services/checkRequestBySlaughter.js @@ -0,0 +1,10 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; + +export const checkRequestBySlaughter = createAsyncThunk( + "CHECK_REQUEST_BY_SLAUGHTER", + async (d) => { + const { data, status } = await axios.post(`kill_house_check_request/`, d); + return { data, status }; + } +); diff --git a/src/features/file/services/city-edit-avculture.info.js b/src/features/file/services/city-edit-avculture.info.js new file mode 100644 index 0000000..66679f4 --- /dev/null +++ b/src/features/file/services/city-edit-avculture.info.js @@ -0,0 +1,13 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const poultryRequestIndexWeightService = createAsyncThunk( + "POULTRY_REQUEST_INDEX_WEIGHT_SERVICE", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + const { data, status } = await axios.get("/poultry_request_index_weight/"); + dispatch(LOADING_END()); + return { data, status }; + } +); diff --git a/src/features/file/services/deposite-allocation.js b/src/features/file/services/deposite-allocation.js new file mode 100644 index 0000000..642318f --- /dev/null +++ b/src/features/file/services/deposite-allocation.js @@ -0,0 +1,10 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; + +export const depositeAllocation = createAsyncThunk( + "DEPOSITE_ALLOCATION", + async (d) => { + const { data, status } = await axios.put(`deposit_allocation/0/`, d); + return { data, status }; + } +); diff --git a/src/features/file/services/financial-check-request.js b/src/features/file/services/financial-check-request.js new file mode 100644 index 0000000..c03d9ea --- /dev/null +++ b/src/features/file/services/financial-check-request.js @@ -0,0 +1,18 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const financialCheckRequest = createAsyncThunk( + "PROVINCE_CHECK_REQUEST", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + try { + const { data, status } = await axios.post(`province_check_info/`, d); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e.response.data.result }; + } + } +); diff --git a/src/features/file/services/get-allocation-information.js b/src/features/file/services/get-allocation-information.js new file mode 100644 index 0000000..be04d1f --- /dev/null +++ b/src/features/file/services/get-allocation-information.js @@ -0,0 +1,14 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { getRoleFromUrl } from "../../../utils/getRoleFromUrl"; + +export const getAllocationInformation = createAsyncThunk( + "GET_ALLOCATION_INFORMATION", + async (d) => { + const { data, status } = await axios.get( + `province_check_operator_request/`, + { params: { ...d, role: getRoleFromUrl() } } + ); + return { data, status }; + } +); diff --git a/src/features/file/services/get-monthly-percent.js b/src/features/file/services/get-monthly-percent.js new file mode 100644 index 0000000..bebfc2a --- /dev/null +++ b/src/features/file/services/get-monthly-percent.js @@ -0,0 +1,10 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; + +export const getMonthlyPercent = createAsyncThunk( + "GET_MONTHLY_PERCENT", + async (d) => { + const { data, status } = await axios.get(`monthly_percent/`); + return { data, status }; + } +); diff --git a/src/features/file/services/getAcceptedSlaughterRequest.js b/src/features/file/services/getAcceptedSlaughterRequest.js new file mode 100644 index 0000000..3a16e67 --- /dev/null +++ b/src/features/file/services/getAcceptedSlaughterRequest.js @@ -0,0 +1,17 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { getRoleFromUrl } from "../../../utils/getRoleFromUrl"; + +export const getAcceptedSlaughterRequest = createAsyncThunk( + "GET_ACCEPTED_SLAUGHTER_REQUEST", + async ({ id, role_key }) => { + const { data, status } = await axios.get("province_kill_request", { + params: { + id, + role: getRoleFromUrl(), + role_key: role_key || "", + }, + }); + return { data, status }; + } +); diff --git a/src/features/file/services/getFileProcess.js b/src/features/file/services/getFileProcess.js new file mode 100644 index 0000000..2705812 --- /dev/null +++ b/src/features/file/services/getFileProcess.js @@ -0,0 +1,27 @@ +import axios from "axios"; +import { createAsyncThunk } from "@reduxjs/toolkit"; +import { getRoleFromUrl } from "../../../utils/getRoleFromUrl"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const getFileProcess = createAsyncThunk( + "GET_FILE", + async (id, { dispatch }) => { + dispatch(LOADING_START()); + const { data, status } = await axios.get(`/Poultry_Request/${id}/`); + dispatch(LOADING_END()); + + return { data, status }; + } +); + +export const getFileProcessOther = createAsyncThunk( + "GET_FILE_OTHER", + async (id, { dispatch }) => { + dispatch(LOADING_START()); + const { data, status } = await axios.get( + "process/?id=" + id + `&role=${getRoleFromUrl()}` + ); + dispatch(LOADING_END()); + return { data, status }; + } +); diff --git a/src/features/file/services/getSlaughterHousesRequest.js b/src/features/file/services/getSlaughterHousesRequest.js new file mode 100644 index 0000000..076eabd --- /dev/null +++ b/src/features/file/services/getSlaughterHousesRequest.js @@ -0,0 +1,12 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; + +export const getSlaughterHousesRequest = createAsyncThunk( + "GET_SLAUGHTER_HOUSES_REQUEST", + async (d) => { + const { data, status } = await axios.get("/kill_request", { + params: d, + }); + return { data, status }; + } +); diff --git a/src/features/file/services/getUserInformation.js b/src/features/file/services/getUserInformation.js new file mode 100644 index 0000000..3a853ab --- /dev/null +++ b/src/features/file/services/getUserInformation.js @@ -0,0 +1,10 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; + +export const getUserInformation = createAsyncThunk( + "USER_INFO_REQUESTS", + async () => { + const { data, status } = await axios.get("user-profile/?type=user"); + return { data, status }; + } +); diff --git a/src/features/file/services/inspector-check-request.js b/src/features/file/services/inspector-check-request.js new file mode 100644 index 0000000..847a3ef --- /dev/null +++ b/src/features/file/services/inspector-check-request.js @@ -0,0 +1,10 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; + +export const inspectorCheckRequest = createAsyncThunk( + "INSPECTOR_REQUEST_OPERATIONS", + async (d) => { + const { data, status } = await axios.post("inspector/", d); + return { data, status }; + } +); diff --git a/src/features/file/services/postSlaughterCarAllocation.js b/src/features/file/services/postSlaughterCarAllocation.js new file mode 100644 index 0000000..dd33ba3 --- /dev/null +++ b/src/features/file/services/postSlaughterCarAllocation.js @@ -0,0 +1,17 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const postSlaughterCarAllocation = createAsyncThunk( + "POST_SLAUGHTER_CAR_ALLOCATION", + async (d, { dispatch }) => { + try { + const { data, status } = await axios.post(`kill_house_request/`, d); + dispatch(LOADING_START()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e.response.data.result }; + } + } +); diff --git a/src/features/file/services/province-check-complaint.js b/src/features/file/services/province-check-complaint.js new file mode 100644 index 0000000..77163a2 --- /dev/null +++ b/src/features/file/services/province-check-complaint.js @@ -0,0 +1,10 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; + +export const provinceCheckComplaint = createAsyncThunk( + "PROVINCE_CHECK_COMPLAINT", + async (d) => { + const { data, status } = await axios.post(`check_losses/`, d); + return { data, status }; + } +); diff --git a/src/features/file/services/province-do-allocation.js b/src/features/file/services/province-do-allocation.js new file mode 100644 index 0000000..c043077 --- /dev/null +++ b/src/features/file/services/province-do-allocation.js @@ -0,0 +1,17 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const provinceDoAllocation = createAsyncThunk( + "PROVINCE_DO_ALLOCATION", + async (d, { dispatch }) => { + try { + const { data, status } = await axios.post(`province_kill_request/`, d); + dispatch(LOADING_START()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e.response.data.result }; + } + } +); diff --git a/src/features/file/services/province-remove-allocation.js b/src/features/file/services/province-remove-allocation.js new file mode 100644 index 0000000..9d419e8 --- /dev/null +++ b/src/features/file/services/province-remove-allocation.js @@ -0,0 +1,15 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const provinceRemoveAllocation = createAsyncThunk( + "PROVINCE_REMOVE_ALLOCATION", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + const { data, status } = await axios.delete(`province_kill_request/0/`, { + params: d, + }); + dispatch(LOADING_END()); + return { data, status }; + } +); diff --git a/src/features/file/services/province-request-auction.js b/src/features/file/services/province-request-auction.js new file mode 100644 index 0000000..ec7b9f6 --- /dev/null +++ b/src/features/file/services/province-request-auction.js @@ -0,0 +1,10 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; + +export const provinceRequestAuction = createAsyncThunk( + "PROVINCE_REQUEST_AUCTION", + async (d) => { + const { data, status } = await axios.post(`province_request_auction/`, d); + return { data, status }; + } +); diff --git a/src/features/file/services/provinceAcceptRequest.js b/src/features/file/services/provinceAcceptRequest.js new file mode 100644 index 0000000..b78eff9 --- /dev/null +++ b/src/features/file/services/provinceAcceptRequest.js @@ -0,0 +1,13 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; + +export const provinceAcceptRequest = createAsyncThunk( + "PROVINCE_ACCEPT_REQUEST", + async (d) => { + const { data, status } = await axios.post( + `province_check_operator_request/`, + d + ); + return { data, status }; + } +); diff --git a/src/features/file/services/provinceFinancialSlaughterCheckRequest.js b/src/features/file/services/provinceFinancialSlaughterCheckRequest.js new file mode 100644 index 0000000..4ca9437 --- /dev/null +++ b/src/features/file/services/provinceFinancialSlaughterCheckRequest.js @@ -0,0 +1,10 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; + +export const provinceFinancialSlaughterCheckRequest = createAsyncThunk( + "PROVINCE_FINANCIAL_CHECK_REQUEST", + async (d) => { + const { data, status } = await axios.post(`province_check_factor/`, d); + return { data, status }; + } +); diff --git a/src/features/file/services/provinceRejectRequest.js b/src/features/file/services/provinceRejectRequest.js new file mode 100644 index 0000000..1acf761 --- /dev/null +++ b/src/features/file/services/provinceRejectRequest.js @@ -0,0 +1,13 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; + +export const provinceRejectRequest = createAsyncThunk( + "PROVINCE_REJECT_REQUEST", + async (d) => { + const { data, status } = await axios.post( + `province_check_operator_request/`, + d + ); + return { data, status }; + } +); diff --git a/src/features/file/services/slaughter-house-vet-send-check-request.js b/src/features/file/services/slaughter-house-vet-send-check-request.js new file mode 100644 index 0000000..a1e8a90 --- /dev/null +++ b/src/features/file/services/slaughter-house-vet-send-check-request.js @@ -0,0 +1,17 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const slaughterHouseVetSendCheckRequest = createAsyncThunk( + "SLAUGHTER_HOUSE_VET_SEND_CHECK_REQUEST", + async (d, { dispatch }) => { + try { + const { data, status } = await axios.post(`vet_check/`, d); + dispatch(LOADING_START()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e.response.data.result }; + } + } +); diff --git a/src/features/file/services/slaughterGetExlusiveKillers.js b/src/features/file/services/slaughterGetExlusiveKillers.js new file mode 100644 index 0000000..34bf8a4 --- /dev/null +++ b/src/features/file/services/slaughterGetExlusiveKillers.js @@ -0,0 +1,18 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const slaughterGetExlusiveKillers = createAsyncThunk( + "SLAUGHTER_GET_EXCLUSIVE_KILLERS", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + const { data, status } = await axios.get( + "kill_house/?exclusive-killers=true", + { + params: d, + } + ); + dispatch(LOADING_END()); + return { data, status }; + } +); diff --git a/src/features/file/services/slaughterPayPoultryFactor.js b/src/features/file/services/slaughterPayPoultryFactor.js new file mode 100644 index 0000000..64a3e5d --- /dev/null +++ b/src/features/file/services/slaughterPayPoultryFactor.js @@ -0,0 +1,10 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; + +export const slaughterPayPoultryFactor = createAsyncThunk( + "SLAUGHTER_PAY_POULTRY_FACTOR", + async (d) => { + const { data, status } = await axios.post(`kill_house_factor_poultry/`, d); + return { data, status }; + } +); diff --git a/src/features/file/services/slaughterPayProvinceFactor.js b/src/features/file/services/slaughterPayProvinceFactor.js new file mode 100644 index 0000000..9f6e9a9 --- /dev/null +++ b/src/features/file/services/slaughterPayProvinceFactor.js @@ -0,0 +1,10 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; + +export const slaughterPayProvinceFactor = createAsyncThunk( + "SLAUGHTER_PAY_PROVINCE_FACTOR", + async (d) => { + const { data, status } = await axios.post(`kill_house_factor_province/`, d); + return { data, status }; + } +); diff --git a/src/features/file/services/slaughterUpdatePayPoultryFactor.js b/src/features/file/services/slaughterUpdatePayPoultryFactor.js new file mode 100644 index 0000000..f439126 --- /dev/null +++ b/src/features/file/services/slaughterUpdatePayPoultryFactor.js @@ -0,0 +1,10 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; + +export const slaughterUpdatePayPoultryFactor = createAsyncThunk( + "SLAUGHTER_UPDATE_PAY_POULTRY_FACTOR", + async (d) => { + const { data, status } = await axios.put(`kill_house_factor_poultry/0/`, d); + return { data, status }; + } +); diff --git a/src/features/file/services/slaughterUpdatePayProvinceFactor.js b/src/features/file/services/slaughterUpdatePayProvinceFactor.js new file mode 100644 index 0000000..afe1290 --- /dev/null +++ b/src/features/file/services/slaughterUpdatePayProvinceFactor.js @@ -0,0 +1,13 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; + +export const slaughterUpdatePayProvinceFactor = createAsyncThunk( + "SLAUGHTER_UPDATE_PAY_PROVINCE_FACTOR", + async (d) => { + const { data, status } = await axios.put( + `kill_house_factor_province/0/`, + d + ); + return { data, status }; + } +); diff --git a/src/features/file/utils/getAllocatedAndAcceptedRequests.js b/src/features/file/utils/getAllocatedAndAcceptedRequests.js new file mode 100644 index 0000000..e7ca2ab --- /dev/null +++ b/src/features/file/utils/getAllocatedAndAcceptedRequests.js @@ -0,0 +1,18 @@ +import moment from "moment/moment"; +import { format } from "date-fns-jalali"; + +export const getAllocatedAndAcceptedRequests = (requests) => { + return requests + .filter((item) => item.provinceKillRequestState === "accepted") + .map((item, i) => { + return { + label: `${item.killHouse.name} (${ + item.killHouse.user.fullname + }) - تاریخ کشتار ${format( + new Date(moment(new Date(item.reciveDate)).format("YYYY-MM-DD")), + "yyyy/MM/dd" + )} `, + key: item.key, + }; + }); +}; diff --git a/src/features/file/utils/getSlaughterHousesForSelect.js b/src/features/file/utils/getSlaughterHousesForSelect.js new file mode 100644 index 0000000..821ac49 --- /dev/null +++ b/src/features/file/utils/getSlaughterHousesForSelect.js @@ -0,0 +1,38 @@ +import moment from "moment/moment"; +import { format } from "date-fns-jalali"; + +export const getSlaughterHousesForSelect = (slaughterHouses) => { + return slaughterHouses + .filter((item) => item.remainQuantity > 0) + .map((item, i) => { + const requestedHighWeight = item?.weightType?.highWeight + ? "بالای 2.5 کیلو" + : null; + const requestedLowWeight = item?.weightType?.lowWeight + ? "بین 2 تا 2.5 کیلو" + : null; + const requestedWeight = [requestedLowWeight, requestedHighWeight] + .filter((item) => item) + .join(" و "); + const requestedBuyTypeCash = item.buyType?.cash ? "نقدی" : null; + const requestedBuyTypeCredit = item.buyType?.credit ? "زمان دار" : null; + const requestedBuyType = [requestedBuyTypeCash, requestedBuyTypeCredit] + .filter((item) => item) + .join(" یا "); + + return { + label: `${item.killHouse.name} (${ + item.killHouse.killHouseOperator.user.fullname + }) - تاریخ کشتار ${format( + new Date(moment(new Date(item.reciveDate)).format("YYYY-MM-DD")), + "yyyy/MM/dd" + )} با تعداد مانده درخواست ${ + item.remainQuantity + } قطعه با وزن درخواستی: ${requestedWeight} و پرداخت بصورت ${requestedBuyType}`, + key: item.key, + remainQuantity: item.remainQuantity, + requestedWeight: requestedWeight, + requestedBuyType: requestedBuyType, + }; + }); +}; diff --git a/src/features/guild-room/components/guild-room-operations/GuildRoomOperations.js b/src/features/guild-room/components/guild-room-operations/GuildRoomOperations.js new file mode 100644 index 0000000..b18ffe0 --- /dev/null +++ b/src/features/guild-room/components/guild-room-operations/GuildRoomOperations.js @@ -0,0 +1,65 @@ +import { Grid } from "../../../../components/grid/Grid"; +import { SPACING } from "../../../../data/spacing"; +import { NavLink } from "../../../../components/nav-link/NavLink"; +import { useLocation } from "react-router-dom"; +import { + ROUTE_GUILD_ROOM_ROUTE_GUILDS, + ROUTE_GUILD_ROOM_ROUTE_GUILDS_REQUESTS, + // ROUTE_GUILD_ROOM_ROUTE_GUILDS_SETTINGS, + ROUTE_GUILD_ROOM_ROUTE_STEWARDS, + // ROUTE_PROVINCE_ROUTE_GUILDS_SETTINGS, + // ROUTE_PROVINCE_ROUTE_IN_PROVINCE_STEWARDS, +} from "../../../../routes/routes"; +import LinkItem from "../../../../components/link-item/LinkItem"; +import { MdCorporateFare } from "react-icons/md"; +import { IoIosPeople } from "react-icons/io"; + +export const GuildRoomOperations = () => { + const { pathname } = useLocation(); + + return ( + + + } + title="درخواست های ثبت صنف" + /> + + + } + title="اصناف" + /> + + + } + title="مباشرین" + /> + + {/* + } + title="مدیریت فرآیند" + /> + */} + + ); +}; diff --git a/src/features/guild/components/GuildAddSteward.js b/src/features/guild/components/GuildAddSteward.js new file mode 100644 index 0000000..b80b5a2 --- /dev/null +++ b/src/features/guild/components/GuildAddSteward.js @@ -0,0 +1,335 @@ +import { + Autocomplete, + Button, + FormControl, + InputAdornment, + InputLabel, + MenuItem, + Select, + TextField, +} from "@mui/material"; +import { useFormik } from "formik"; +import { useContext, useEffect, useState } from "react"; +import { useDispatch, useSelector } from "react-redux"; +import { AppContext } from "../../../contexts/AppContext"; +import { Yup } from "../../../lib/yup/yup"; +import { CLOSE_MODAL } from "../../../lib/redux/slices/appSlice"; +import { SPACING } from "../../../data/spacing"; +import { Grid } from "../../../components/grid/Grid"; +import { guildGetStewardsService } from "../services/guild-get-guilds"; +import { guildGetAllocationData } from "../services/guildGetAllocationData"; +import { guildGetStewards } from "../services/guild-get-stewards"; +import { slaughterAllocateStewardService } from "../../slaughter-house/services/slaughter-allocate-steward"; +import { guildGetInventoryStockService } from "../services/guild-get-inventory-stock"; +import { GuildEditAllocateStewardService } from "../services/guildEditAllocateStewardService"; +import { NumberInput } from "../../../components/number-format-custom/NumberFormatCustom"; + +export const GuildAddSteward = ({ + stewardKey, + guildKey, + sellType, + isGuild, + weight, + quantity, + item, + totalAverageWeightOfCarcasses, +}) => { + const dispatch = useDispatch(); + const [openNotif] = useContext(AppContext); + const [, , selectedDate1] = useContext(AppContext); + const [price, setPrice] = useState(); + + const { guildGetStewardsState } = useSelector((state) => state.generalSlice); + + useEffect(() => { + if (sellType !== "exclusive") { + dispatch(guildGetStewardsService()); + } + }, []); + + const getOptionLabel = (option) => option.label; + + const validationSchema = Yup.object({ + slaughteSteward: Yup.string(), + // price: Yup.number().when("quantity", { + // is: quantity, + // then: Yup.number().required("لطفا این فیلد را پر کنید"), + // otherwise: Yup.number(), + // }), + wholePrice: Yup.number().when("quantity", { + is: quantity, + then: Yup.number().required("لطفا این فیلد را پر کنید"), + otherwise: Yup.number(), + }), + numberOfPieces: Yup.number() + .required("حجم لاشه را وارد کنید") + .min(1, "حداقل یک قطعه"), + weight: Yup.number() + .required("وزن لاشه را وارد کنید") + .min(0.01, "حداقل 0.01 کیلوگرم"), + }); + + let defaultKey; + + if (isGuild) { + defaultKey = guildKey; + } else { + defaultKey = stewardKey; + } + + const formik = useFormik({ + initialValues: { + slaughteSteward: defaultKey, + numberOfPieces: "", + wholePrice: "", + weight: weight ? weight : "", + }, + validationSchema, + onSubmit: (values) => { + let req; + + if (quantity) { + dispatch( + GuildEditAllocateStewardService({ + steward_allocation_key: item.key, + number_of_carcasses: Number(values.numberOfPieces), + weight_of_carcasses: Number(values.weight), + }) + ).then(() => { + dispatch( + guildGetAllocationData({ + date: selectedDate1, + }) + ); + dispatch(guildGetStewards({ date: selectedDate1 })); + dispatch( + guildGetAllocationData({ + date: selectedDate1, + }) + ); + dispatch( + guildGetInventoryStockService({ + date: selectedDate1, + }) + ); + + dispatch(CLOSE_MODAL()); + openNotif({ + vertical: "top", + horizontal: "center", + msg: "عملیات با موفقیت انجام شد.", + severity: "success", + }); + }); + } else { + if (isGuild) { + req = { + guild_key: values.slaughteSteward, + number_of_carcasses: Number(values.numberOfPieces), + weight_of_carcasses: Number(values.weight), + sell_type: sellType, + date: selectedDate1, + broadcast_type: "steward_broadcast", + amount: Number(price), + total_amount: Number(values.wholePrice), + }; + } else { + req = { + guild_key: values.slaughteSteward, + number_of_carcasses: Number(values.numberOfPieces), + weight_of_carcasses: Number(values.weight), + sell_type: sellType, + date: selectedDate1, + broadcast_type: "steward_broadcast", + amount: Number(price), + total_amount: Number(values.wholePrice), + }; + } + dispatch(slaughterAllocateStewardService(req)).then((r) => { + if (r.payload.error) { + openNotif({ + vertical: "top", + horizontal: "center", + msg: r.payload.error, + severity: "error", + }); + } else { + dispatch(guildGetStewards({ date: selectedDate1 })); + dispatch( + guildGetAllocationData({ + date: selectedDate1, + }) + ); + dispatch( + guildGetInventoryStockService({ + date: selectedDate1, + }) + ); + + dispatch(CLOSE_MODAL()); + openNotif({ + vertical: "top", + horizontal: "center", + msg: "عملیات با موفقیت انجام شد.", + severity: "success", + }); + } + }); + } + }, + }); + + useEffect(() => { + const finalQuantity = formik.values.weight / totalAverageWeightOfCarcasses; + formik.setFieldValue("numberOfPieces", Number(finalQuantity).toFixed(0)); + }, [formik.values.weight]); + + useEffect(() => { + const calcPrice = formik.values.wholePrice / Number(formik.values.weight); + setPrice(Number(calcPrice.toFixed(0))); + }, [formik.values.wholePrice]); + + return ( +
    + + {!stewardKey && !guildKey && !isGuild && !quantity && ( + + formik.setFieldValue("slaughteSteward", value.value) + } + onBlur={formik.handleBlur("slaughteSteward")} + // value={formik.values.slaughteSteward} + renderInput={(params) => } + /> + )} + + {isGuild && !quantity && !stewardKey && !guildKey && ( + + formik.setFieldValue("slaughteSteward", value.value) + } + onBlur={formik.handleBlur("slaughteSteward")} + // value={formik.values.slaughteSteward} + renderInput={(params) => } + /> + )} + + کیلوگرم + ), + }} + {...formik.getFieldProps("weight")} + error={formik.touched.weight && formik.errors.weight} + helperText={formik.touched.weight && formik.errors.weight} + /> + + {!quantity && ( + <> + ریال + ), + }} + value={formik.values.wholePrice} + error={ + formik.touched.wholePrice + ? Boolean(formik.errors.wholePrice) + : null + } + onChange={formik.handleChange} + onBlur={formik.handleBlur} + helperText={ + formik.touched.wholePrice && Boolean(formik.errors.wholePrice) + ? formik.errors.wholePrice + : null + } + /> + + خودرو حمل لاشه + + + ریال + ), + readOnly: true, + }} + value={price} + /> + + )} + + قطعه, + }} + {...formik.getFieldProps("numberOfPieces")} + error={formik.touched.numberOfPieces && formik.errors.numberOfPieces} + helperText={ + formik.touched.numberOfPieces && formik.errors.numberOfPieces + } + /> + + + +
    + ); +}; diff --git a/src/features/guild/components/GuildBroadCastManagement.js b/src/features/guild/components/GuildBroadCastManagement.js new file mode 100644 index 0000000..13457dc --- /dev/null +++ b/src/features/guild/components/GuildBroadCastManagement.js @@ -0,0 +1,778 @@ +import { + Button, + Collapse, + IconButton, + List, + ListItem, + ListItemText, + TextField, + Tooltip, + Typography, +} from "@mui/material"; +import { DatePicker } from "@mui/x-date-pickers"; +import axios from "axios"; +import moment from "moment/moment"; +import { useContext, useEffect, useState } from "react"; +import { RiFileExcel2Fill } from "react-icons/ri"; +import { useDispatch, useSelector } from "react-redux"; +import ExpandMoreIcon from "@mui/icons-material/ExpandMore"; +import ExpandLessIcon from "@mui/icons-material/ExpandLess"; +import { AppContext } from "../../../contexts/AppContext"; +import { guildGetInventoryStockService } from "../services/guild-get-inventory-stock"; +import { guildGetStewards } from "../services/guild-get-stewards"; +import { formatJustDate } from "../../../utils/formatTime"; +import { SPACING } from "../../../data/spacing"; +import { Grid } from "../../../components/grid/Grid"; +import { SimpleTable } from "../../../components/simple-table/SimpleTable"; +import EditIcon from "@mui/icons-material/Edit"; +import DeleteIcon from "@mui/icons-material/Delete"; + +import { + CLOSE_MODAL, + DRAWER, + OPEN_MODAL, +} from "../../../lib/redux/slices/appSlice"; +import { GuildAddSteward } from "./GuildAddSteward"; +import { guildGetAllocationData } from "../services/guildGetAllocationData"; +import { GuildManageInventoryAllocationOperations } from "./GuildManageInventoryAllocationOperations"; +import { guildInventoryFinalSubmitService } from "../services/guildInventoryFinalSubmitService"; +import BoxList from "../../../components/box-list/BoxList"; +import { RespSlaughterGuildListItem } from "../../slaughter-house/components/resp-slaughter-guild-list-item/RespSlaughterGuildListItem"; +import { RespGuildExclusiveItem } from "../../slaughter-house/components/resp-guild-exclusive-item/RespGuildExclusiveItem"; +import { SlaughterSubmitOutProvinceSell } from "../../slaughter-house/components/slaughter-submit-out-province-sell/SlaughterSubmitOutProvinceSell"; +import { guildGetFreeSaleBarService } from "../services/guild-get-free-sale-bar"; +import { guildDeleteOutOfProvinceSell } from "../services/guild-delete-free-sale"; + +export const GuildBroadCastManagement = () => { + const dispatch = useDispatch(); + const [openNotif] = useContext(AppContext); + const [, , selectedDate1, setSelectedDate1] = useContext(AppContext); + const [stewardsDataTable, setStewardsDataTable] = useState([]); + const [inventoryAllocationsDataTable, setInventoryAllocationsDataTable] = + useState([]); + + const { + guildGetInventoryStock, + guildStewards, + guildGetGuildData, + guildFreeSaleBars, + } = useSelector((state) => state.generalSlice); + + const [outOfProvinceSells, setOutOfProvinceSells] = useState([]); + + useEffect(() => { + dispatch( + guildGetInventoryStockService({ + date: selectedDate1, + }) + ).then(() => { + dispatch( + guildGetFreeSaleBarService({ + date: selectedDate1, + steward_key: guildGetInventoryStock?.stewardKey, + }) + ); + }); + dispatch(guildGetStewards({ date: selectedDate1 })); + dispatch( + guildGetAllocationData({ + date: selectedDate1, + }) + ); + }, [selectedDate1]); + + useEffect(() => { + const inventoryAllocationsData = guildGetGuildData?.map((item, i) => { + let sellType, sellerType; + if (item.sellerType === "guilds") { + sellerType = "صنف"; + } else if (item.sellerType === "steward") { + sellerType = "مباشر"; + } + + if (item.sellType === "free") { + sellType = "آزاد"; + } else { + if (item.type === "manual") { + sellType = "اختصاصی (دستی)"; + } else { + sellType = "اختصاصی (اتوماتیک)"; + } + } + + return [ + i + 1, + item?.guilds?.guildsId, + formatJustDate(item.date), + sellerType, + sellType, + item?.guilds?.guildsName, + item?.guilds?.user?.fullname, + item?.guilds?.user?.nationalId, + item?.guilds?.user?.mobile, + item?.guilds?.typeActivity, + item?.guilds?.areaActivity, + item?.guilds?.licenseNumber, + item?.guilds?.address?.city.name, + item?.numberOfCarcasses, + item?.weightOfCarcasses, + item?.loggedRegistrationCode ? item.loggedRegistrationCode : "-", + , + ]; + }); + setInventoryAllocationsDataTable(inventoryAllocationsData); + + const d1 = guildStewards?.map((item, i) => { + return [ + item?.guildsId, + "صنف", + item.guildsName, + item.user.fullname, + item.user.nationalId, + item.user.mobile, + item.typeActivity, + item.areaActivity, + item.licenseNumber, + item.address.city.name, + item?.allocationLimit + ? `${item?.allocationLimit?.toLocaleString()} کیلوگرم` + : "بدون محدودیت", + , + ]; + }); + + setStewardsDataTable(d1); + + const sells = guildFreeSaleBars?.map((item, i) => { + return [ + i + 1, + formatJustDate(item?.createDate), + item?.buyerName, + item?.buyerMobile, + item?.province, + item?.city, + item?.driverName, + item?.driverMobile, + item?.driverName, + item?.clearanceCode, + item?.numberOfCarcasses, + item?.weightOfCarcasses, + <> + { + dispatch( + DRAWER({ + right: !(window.innerWidth <= 600), + bottom: window.innerWidth <= 600, + title: "ویرایش فروش خارج از استان", + content: ( + + ), + }) + ); + }} + > + + + { + dispatch(guildDeleteOutOfProvinceSell(item?.key)).then((r) => { + if (r.payload.error) { + openNotif({ + vertical: "top", + horizontal: "center", + msg: r.payload.error, + severity: "error", + }); + } else { + dispatch( + guildGetFreeSaleBarService({ + date: selectedDate1, + steward_key: guildGetInventoryStock?.stewardKey, + }) + ); + openNotif({ + vertical: "top", + horizontal: "center", + msg: r.payload.data.result, + severity: "success", + }); + } + }); + }} + > + + + , + ]; + }); + + setOutOfProvinceSells(sells); + }, [guildStewards, guildGetGuildData, guildFreeSaleBars]); + + const finalSubmitDisabled = + (Array.isArray(guildGetGuildData) && !guildGetGuildData?.length) || + (Array.isArray(guildGetGuildData) && + guildGetGuildData[0]?.finalRegistration); + + const [inventoryDate, setInventoryDate] = useState(new Date(selectedDate1)); + + useEffect(() => { + const tempDate = new Date(inventoryDate); + tempDate.setDate(new Date(selectedDate1).getDate() - 1); + setInventoryDate(tempDate); + }, [selectedDate1]); + + const [isMessageVisible, setMessageVisible] = useState(true); + + const toggleMessageVisibility = () => { + setMessageVisible(!isMessageVisible); + }; + + const isMobile = window.innerWidth <= 600; + + const [value, setValue] = useState(""); + const [searchFilter, setSearchFilter] = useState([]); + + const handleChange = (event) => { + setValue(event.target.value); + const regex = new RegExp(value, "i"); + const d = stewardsDataTable.filter((item) => regex.test(item)); + setSearchFilter(d); + }; + + return ( + + مدیریت پخش + + + ( + + )} + value={selectedDate1} + onChange={(e) => { + setSelectedDate1(moment(e).format("YYYY-MM-DD")); + }} + /> + + + {isMobile ? ( + + + + موجودی انبار + + + + + + + + + + + + + + ) : ( + + + موجودی انبار + + + + + + + + + + + + } + columns={[ + "حجم لاشه ها", + "وزن لاشه ها (کیلوگرم)", + // "تعداد تخصیصات", + "حجم لاشه تخصیص داده شده", + "وزن تخصیص داده شده (کیلوگرم)", + "حجم لاشه قابل تخصیص", + "وزن قابل تخصیص (کیلوگرم)", + "وزن بار فروش آزاد (کیلوگرم)", + "حجم بار فروش آزاد (قطعه)", + ]} + data={[ + [ + guildGetInventoryStock?.realNumberOfCarcasses?.toLocaleString(), + guildGetInventoryStock?.realWeightOfCarcasses?.toLocaleString(), + guildGetInventoryStock?.allocatedTotalNumberOfCarcasses?.toLocaleString(), + guildGetInventoryStock?.allocatedTotalWeightOfCarcasses?.toLocaleString(), + guildGetInventoryStock?.remainTotalNumberOfCarcasses?.toLocaleString(), + guildGetInventoryStock?.remainTotalWeightOfCarcasses?.toLocaleString(), + guildGetInventoryStock?.freeSaleWeight?.toLocaleString(), + guildGetInventoryStock?.freeSaleQuantity?.toLocaleString(), + ], + ]} + /> + )} + + + + + + + + + + + + + {isMobile ? ( + + ) : ( + + + + )} + + + + {isMobile ? ( + <> + + مدیریت کل تخصیصات + + + + + + + ), + }) + ); + }} + > + ارسال یکجا کداحراز + + + + + {!!outOfProvinceSells?.length && ( + + + + )} + + ) : ( + + + مدیریت کل تخصیصات + + + + + + + ), + }) + ); + }} + > + ارسال یکجا کداحراز + + + + } + columns={[ + "ردیف", + "شناسه صنف", + "تاریخ ثبت", + "ماهیت", + "نوع تخصیص", + "نام واحد صنفی", + "نام شخص/شرکت", + "کدملی", + "موبایل", + "نوع فعالیت", + "حوزه فعالیت", + "شماره مجوز", + "شهرستان", + "حجم لاشه", + "وزن لاشه", + "کداحراز", + "عملیات", + ]} + data={inventoryAllocationsDataTable} + /> + {!!outOfProvinceSells?.length && ( + + + + )} + + )} + + ); +}; diff --git a/src/features/guild/components/GuildInventoryOperation.js b/src/features/guild/components/GuildInventoryOperation.js new file mode 100644 index 0000000..bb265a2 --- /dev/null +++ b/src/features/guild/components/GuildInventoryOperation.js @@ -0,0 +1,78 @@ +import { VscNewFolder } from "react-icons/vsc"; +import { useLocation } from "react-router-dom"; +import { Grid } from "../../../components/grid/Grid"; +import LinkItem from "../../../components/link-item/LinkItem"; +import { NavLink } from "../../../components/nav-link/NavLink"; +import { SPACING } from "../../../data/spacing"; +import { + ROUTE_STEWARD_SALE_IN_PROVINCE, + ROUTE_STEWARD_INVENTORY_STOCK, + ROUTE_STEWARD_PURCHASE_OUT_PROVINCE, + ROUTE_STEWARD_SALE_OUT_PROVINCE, + ROUTE_STEWARD_SEGMENT, +} from "../../../routes/routes"; + +export const GuildInventoryOperation = () => { + const { pathname } = useLocation(); + + return ( + + + } + title="ورود به انبار" + /> + + + } + title="فروش داخل استان" + /> + + + } + title="خرید خارج استان" + /> + + + } + title="فروش به خارج استان" + /> + + + } + title="قطعه بندی" + /> + + + ); +}; diff --git a/src/features/guild/components/GuildManageGuilds.js b/src/features/guild/components/GuildManageGuilds.js new file mode 100644 index 0000000..bd01696 --- /dev/null +++ b/src/features/guild/components/GuildManageGuilds.js @@ -0,0 +1,415 @@ +import { + Button, + Pagination, + TextField, + Tooltip, + Typography, +} from "@mui/material"; +import axios from "axios"; +import { useEffect, useState } from "react"; +import { RiFileExcel2Fill } from "react-icons/ri"; +import { useDispatch, useSelector } from "react-redux"; +import { RiSearchLine } from "react-icons/ri"; + +import { ManageGuildsOperations } from "../../province/components/manage-guilds-operations/ManageGuildsOperations"; +import { Grid } from "../../../components/grid/Grid"; +import { SPACING } from "../../../data/spacing"; +import { CreateGuilds } from "../../province/components/create-guilds/CreateGuilds"; +import { PageTable } from "../../../components/page-table/PageTable"; +import { + LOADING_END, + LOADING_START, + OPEN_MODAL, +} from "../../../lib/redux/slices/appSlice"; +import { getRoleFromUrl } from "../../../utils/getRoleFromUrl"; +import BoxList from "../../../components/box-list/BoxList"; + +const GuildMaangeGuilds = () => { + const dispatch = useDispatch(); + const [dataTableM, setDataTableM] = useState([]); + const userKey = useSelector((state) => state.userSlice.userProfile.key); + + const [data, setData] = useState([]); + const [loading, setLoading] = useState(false); + const [totalRows, setTotalRows] = useState(0); + const [perPage, setPerPage] = useState(10); + + const [textValue, setTextValue] = useState(""); + + const handleTextChange = (event) => { + setTextValue(event.target.value); + }; + + const fetchApiData = async (page, textValue) => { + setLoading(true); + let response = await axios.get( + `total_guilds/?role=Guilds&steward=true&search=filter&value=${textValue}&page=${page}&page_size=${perPage}` + ); + + setData(response.data.results); + setTotalRows(response.data.count); + setLoading(false); + }; + + const handlePageChange = (page) => { + fetchApiData(page, textValue); + }; + + const handlePerRowsChange = async (newPerPage, page) => { + setLoading(true); + + let response = await axios.get( + `total_guilds/?role=Guilds&steward=true&search=filter&value=${textValue}&page=${page}&page_size=${newPerPage}` + ); + + setData(response.data.results); + setTotalRows(response.data.count); + setPerPage(newPerPage); + + setLoading(false); + dispatch(LOADING_END()); + }; + + const [page, setPage] = useState(0); + const handleChangePageM = (event, newPage) => { + dispatch(LOADING_START()); + setPage(newPage); + fetchApiData(newPage + 1, textValue); + }; + + useEffect(() => { + fetchApiData(1); + }, []); + + const updateTable = () => { + fetchApiData(1); + }; + + const columns = [ + { + name: "شناسه صنف", + selector: (item) => item.guildsId, + sortable: false, + wrap: true, + allowOverflow: true, + center: true, + width: "80px", + }, + { + name: "نام واحد صنفی", + selector: (item) => item?.guildsName, + sortable: false, + wrap: true, + allowOverflow: true, + center: true, + width: "80px", + }, + { + name: "نام شخص/شرکت", + selector: (item) => `${item?.user?.fullname} (${item?.user?.mobile})`, + sortable: false, + wrap: true, + allowOverflow: true, + center: true, + width: "100px", + }, + { + name: "کدملی", + selector: (item) => item?.user?.nationalId, + sortable: false, + wrap: true, + allowOverflow: true, + center: true, + width: "100px", + }, + { + name: "نوع فعالیت", + selector: (item) => item?.typeActivity, + sortable: false, + wrap: true, + allowOverflow: true, + center: true, + width: "80px", + }, + { + name: "حوزه فعالیت", + selector: (item) => item?.areaActivity, + sortable: false, + wrap: true, + allowOverflow: true, + center: true, + width: "80px", + }, + { + name: "کدپستی", + selector: (item) => item?.address?.postalCode, + sortable: false, + wrap: true, + allowOverflow: true, + center: true, + width: "80px", + }, + { + name: "استان/شهر/آدرس", + selector: (item) => + `${item?.address?.province.name}/${item?.address?.city.name}/${item?.address?.address}`, + sortable: false, + wrap: true, + allowOverflow: true, + center: true, + width: "80px", + }, + { + name: "مباشر", + selector: (item) => (item?.steward ? "می باشد" : "نمی باشد"), + sortable: false, + wrap: true, + allowOverflow: true, + center: true, + width: "80px", + }, + { + name: "محدودیت تخصیص", + selector: (item) => (item?.limitationAllocation ? "دارد" : "ندارد"), + sortable: false, + wrap: true, + allowOverflow: true, + center: true, + width: "80px", + }, + { + name: "حداکثر تخصیص", + selector: (item) => item?.allocationLimit, + sortable: false, + wrap: true, + allowOverflow: true, + center: true, + width: "80px", + }, + { + name: "مباشر", + selector: (item) => + item?.centersAllocation?.map((item) => item.label).join(" - "), + sortable: false, + wrap: true, + allowOverflow: true, + center: true, + width: "80px", + }, + { + name: "کشتارگاه", + selector: (item) => { + return item?.killHouseInfo + ?.map((item) => `${item.name} (${item.mobile})`) + .join(" - "); + }, + sortable: true, + wrap: true, + allowOverflow: true, + center: true, + width: "80px", + }, + { + name: "وضعیت", + selector: (item) => { + let state = ""; + if (item?.provinceAcceptState === "accepted") { + state = "تایید شده"; + } else if (item?.provinceAcceptState === "rejected") { + state = "رد شده"; + } else if (item?.provinceAcceptState === "pending") { + state = "در انتظار تایید"; + } + return state; + }, + sortable: true, + wrap: true, + allowOverflow: true, + center: true, + }, + { + name: "عملیات", + selector: (item, i) => ( + + ), + sortable: false, + wrap: true, + allowOverflow: true, + center: true, + width: "110px", + }, + ]; + + const handleSubmit = async (event) => { + event.preventDefault(); + setLoading(true); + try { + const response = await axios.get( + `total_guilds/?role=${getRoleFromUrl()}&search=filter&value=${textValue}&steward=true` + ); + setData(response.data.results); + setTotalRows(response.data.count); + } catch (error) { + console.error("Error fetching data:", error); + } finally { + setLoading(false); + } + }; + + if (getRoleFromUrl() === "CityJahad") { + columns.pop(); + } + + const getItemState = (item) => { + let state = ""; + if (item?.provinceAcceptState === "accepted") { + state = "تایید شده"; + } else if (item?.provinceAcceptState === "rejected") { + state = "رد شده"; + } else if (item?.provinceAcceptState === "pending") { + state = "در انتظار تایید"; + } + return state; + }; + + useEffect(() => { + const d = data?.map((item, i) => { + return [ + item.guildsId, + item?.guildsName, + `${item?.user?.fullname} (${item?.user?.mobile})`, + item?.user?.nationalId, + item?.typeActivity, + item?.areaActivity, + item?.address?.postalCode, + `${item?.address?.province.name}/${item?.address?.city.name}/${item?.address?.address}`, + item?.steward ? "می باشد" : "نمی باشد", + item?.limitationAllocation ? "دارد" : "ندارد", + item?.allocationLimit, + item?.centersAllocation?.map((item) => item.label).join(" - "), + item?.killHouseInfo + ?.map((item) => `${item.name} (${item.mobile})`) + .join(" - "), + getItemState(item), + , + ]; + }); + + setDataTableM(d); + }, [data]); + + const columnNames = columns.map((column) => column.name); + const isMobile = window.innerWidth <= 600; + + const tableTitle = ( + + +
    + + مدیریت اصناف + + + +
    + + {getRoleFromUrl() !== "CityJahad" && ( + + )} + + + + + + + +
    +
    + ); + + return ( + + {isMobile ? ( + + {tableTitle} + + { + handleChangePageM(event, newPage - 1); + }} + /> + + ) : ( + + )} + + ); +}; + +export default GuildMaangeGuilds; diff --git a/src/features/guild/components/GuildManageInventoryAllocationOperations.js b/src/features/guild/components/GuildManageInventoryAllocationOperations.js new file mode 100644 index 0000000..04559c0 --- /dev/null +++ b/src/features/guild/components/GuildManageInventoryAllocationOperations.js @@ -0,0 +1,197 @@ +import { Button, Typography } from "@mui/material"; +import { useDispatch } from "react-redux"; +import { GuildAddSteward } from "./GuildAddSteward"; +import { Grid } from "../../../components/grid/Grid"; +import { + CLOSE_MODAL, + LOADING_END, + OPEN_MODAL, +} from "../../../lib/redux/slices/appSlice"; +import { guildGetAllocationData } from "../services/guildGetAllocationData"; +import { guildGetStewards } from "../services/guild-get-stewards"; +import { guildGetInventoryStockService } from "../services/guild-get-inventory-stock"; +import { AppContext } from "../../../contexts/AppContext"; +import { useContext } from "react"; +import { guildDeleteAllocatedService } from "../services/guildDeleteAllocatedService"; +import { SPACING } from "../../../data/spacing"; +import { guildInventoryFinalSubmitService } from "../services/guildInventoryFinalSubmitService"; +import { GuildSubmitAuthCode } from "./GuildSubmitAuthCode"; + +export const GuildManageInventoryAllocationOperations = ({ item }) => { + const dispatch = useDispatch(); + const [openNotif] = useContext(AppContext); + const [, , selectedDate1] = useContext(AppContext); + // const { inventorySelectedKillHouse } = useSelector( + // (state) => state.slaughterSlice + // ); + + return ( + + {item.systemRegistrationCode && ( + + )} + {!item.systemRegistrationCode && ( + + + + + ), + }) + ); + }} + > + ارسال کداحراز + + )} + + {!item.systemRegistrationCode && ( + <> + + + + )} + + ); +}; diff --git a/src/features/guild/components/GuildProfile.js b/src/features/guild/components/GuildProfile.js new file mode 100644 index 0000000..2d4a155 --- /dev/null +++ b/src/features/guild/components/GuildProfile.js @@ -0,0 +1,67 @@ +import { Box } from "@mui/system"; +import { useEffect } from "react"; +import { useDispatch, useSelector } from "react-redux"; +import { Grid } from "../../../components/grid/Grid"; +import { SimpleTable } from "../../../components/simple-table/SimpleTable"; +import { SPACING } from "../../../data/spacing"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; +import { guildGetProfile } from "../services/guild-get-profile"; + +export const GuildProfile = () => { + const { guildProfile } = useSelector((state) => state.generalSlice); + const dispatch = useDispatch(); + + useEffect(() => { + dispatch(LOADING_START()); + dispatch(guildGetProfile()).then((r) => { + dispatch(LOADING_END()); + }); + }, []); + + return ( + + + + + <> + + item.label) + .join(" - "), + guildProfile?.killHouseCentersAllocation + ?.map((item) => item.label) + .join(" - "), + ], + ]} + /> + + + + + + + ); +}; diff --git a/src/features/guild/components/GuildReceiveBarOperation.js b/src/features/guild/components/GuildReceiveBarOperation.js new file mode 100644 index 0000000..fd2fb6e --- /dev/null +++ b/src/features/guild/components/GuildReceiveBarOperation.js @@ -0,0 +1,317 @@ +import { + Button, + Checkbox, + Divider, + FormControl, + FormControlLabel, + Radio, + RadioGroup, + TextField, + Typography, +} from "@mui/material"; +import { useContext, useEffect, useState } from "react"; +import { Grid } from "../../../components/grid/Grid"; +import { SPACING } from "../../../data/spacing"; +import { Yup } from "../../../lib/yup/yup"; +import { useFormik } from "formik"; +import { guildAllocatedStockOperationService } from "../services/guild-allocated-stock-operation"; +import { useDispatch } from "react-redux"; +import { AppContext } from "../../../contexts/AppContext"; +import { guildGetInventoryStockService } from "../services/guild-get-inventory-stock"; +import { guildGetInventoryAllocatedService } from "../services/guild-get-inventory-allocated"; +import { CLOSE_MODAL } from "../../../lib/redux/slices/appSlice"; +import { getRoleFromUrl } from "../../../utils/getRoleFromUrl"; +import { senfGetInventoryStockService } from "../services/senf-get-inventory-stock"; +import { senfGetInventoryAllocatedService } from "../services/senf-get-inventory-allocated"; + +export const GuildReceiveBarOperation = ({ item }) => { + const dispatch = useDispatch(); + const [, , selectedDate1] = useContext(AppContext); + const [openNotif] = useContext(AppContext); + const [selectedValue, setSelectedValue] = useState("option1"); + + const handleChange = (event) => { + setSelectedValue(event.target.value); + }; + + const initialValues = { + authCode: "", + }; + + const validationSchema = Yup.object({ + authCode: Yup.string().required("کداحراز اجباری است"), + }); + + const onSubmit = () => { + // Handle form submission here + // console.log("Form submitted with values:", values); + }; + + const formik = useFormik({ + initialValues, + validationSchema, + onSubmit, + }); + + const [isChecked, setChecked] = useState(false); + + const handleCheckboxChange = () => { + setChecked(!isChecked); + }; + + const formikRealInfo = useFormik({ + initialValues: { + number: "", + weight: "", + }, + validationSchema: Yup.object({ + weight: Yup.number() + .required("این فیلد اجباری است!") + .typeError("لطفا وزن را وارد کنید!"), + }), + }); + + useEffect(() => { + formik.validateForm(); + formikRealInfo.validateForm(); + }, []); + + return ( + + + + وزن تخصیصی: {item.weightOfCarcasses.toLocaleString()} کیلوگرم + + + تعداد تخصیصی: {item.numberOfCarcasses.toLocaleString()} قطعه + + + + + + + + } + label="ثبت تعداد واقعی تحویلی" + /> + + + + + + + + + + } + label="تحویل بار با کداحراز" + /> + } + label="تحویل بار بدون کداحراز" + /> + + + + {selectedValue === "option1" && ( + + )} + + + + ); +}; diff --git a/src/features/guild/components/GuildSubmitAuthCode.js b/src/features/guild/components/GuildSubmitAuthCode.js new file mode 100644 index 0000000..de4708e --- /dev/null +++ b/src/features/guild/components/GuildSubmitAuthCode.js @@ -0,0 +1,87 @@ +import { Button, TextField } from "@mui/material"; +import { useFormik } from "formik"; +import { useContext } from "react"; +import { useDispatch } from "react-redux"; +import { Yup } from "../../../lib/yup/yup"; +import { AppContext } from "../../../contexts/AppContext"; +import { CLOSE_MODAL } from "../../../lib/redux/slices/appSlice"; +import { getRoleFromUrl } from "../../../utils/getRoleFromUrl"; +import { guildGetAllocationData } from "../services/guildGetAllocationData"; +import { Grid } from "../../../components/grid/Grid"; +import { SPACING } from "../../../data/spacing"; +import { guildAuthCodeSubmitService } from "../services/guild-auth-code-submit"; + +const validationSchema = Yup.object({ + phoneNumber: Yup.string() + .matches(/^\d+$/, "فقط عدد مجاز است") + .required("کداحراز اجباری است"), +}); + +export const GuildSubmitAuthCode = ({ item }) => { + const dispatch = useDispatch(); + const [openNotif] = useContext(AppContext); + const [, , selectedDate1] = useContext(AppContext); + + const formik = useFormik({ + initialValues: { + phoneNumber: "", + }, + validationSchema: validationSchema, + onSubmit: (values) => { + dispatch( + guildAuthCodeSubmitService({ + logged_registration_code: values.phoneNumber, + steward_allocation_key: item.key, + role: getRoleFromUrl(), + }) + ).then((r) => { + dispatch(CLOSE_MODAL()); + if (r.payload.error) { + openNotif({ + vertical: "top", + horizontal: "center", + msg: r.payload.error, + severity: "error", + }); + } else { + dispatch( + guildGetAllocationData({ + date: selectedDate1, + }) + ); + + openNotif({ + vertical: "top", + horizontal: "center", + msg: "عملیات با موفقیت انجام شد.", + severity: "success", + }); + } + }); + }, + }); + + return ( +
    + + + + +
    + ); +}; diff --git a/src/features/guild/components/GuildSubmitFreeBar.js b/src/features/guild/components/GuildSubmitFreeBar.js new file mode 100644 index 0000000..bf75566 --- /dev/null +++ b/src/features/guild/components/GuildSubmitFreeBar.js @@ -0,0 +1,380 @@ +import { Button, InputAdornment, TextField, Typography } from "@mui/material"; +import { DatePicker } from "@mui/x-date-pickers"; +import { useFormik } from "formik"; +// import moment from "moment/moment"; +import { useContext, useEffect, useState } from "react"; +import { useDispatch } from "react-redux"; +import { Yup } from "../../../lib/yup/yup"; +import { AppContext } from "../../../contexts/AppContext"; +import { fixBase64 } from "../../../utils/toBase64"; +import { Grid } from "../../../components/grid/Grid"; +import { SPACING } from "../../../data/spacing"; +import { ImageUpload } from "../../../components/image-upload/ImageUpload"; +import { guildSubmitFreeBar } from "../services/guild-submit-free-bar"; +import { guildGetInventoryStockService } from "../services/guild-get-inventory-stock"; +import { guildGetInventoryAllocatedService } from "../services/guild-get-inventory-allocated"; +import { DRAWER } from "../../../lib/redux/slices/appSlice"; +import { guildGetFreeBars } from "../services/guild-get-free-bars"; +import { guildEditFreeBar } from "../services/guild-edit-free-bar"; + +const ValidationSchema = Yup.object().shape({ + // kill_house_key: Yup.string().required("کد خانه کشتار الزامی است"), + slaughter_name: Yup.string().required("نام کشتارگاه الزامی است"), + slaughter_mobile: Yup.string() + .required("شماره موبایل کشتارگاه الزامی است") + .min(11, "شماره موبایل باید دقیقاً 11 رقم باشد") + .max(11, "شماره موبایل باید دقیقاً 11 رقم باشد"), + province: Yup.string().required("استان الزامی است"), + city: Yup.string().required("شهر الزامی است"), + vet_farm_name: Yup.string().required("نام دامپزشک مربوطه الزامی است"), + vet_farm_mobile: Yup.string() + .required("شماره موبایل دامپزشک مربوطه الزامی است") + .min(11, "شماره موبایل باید دقیقاً 11 رقم باشد") + .max(11, "شماره موبایل باید دقیقاً 11 رقم باشد"), + driver_name: Yup.string().required("نام راننده الزامی است"), + driver_mobile: Yup.string() + .required("شماره موبایل راننده الزامی است") + .min(11, "شماره موبایل باید دقیقاً 11 رقم باشد") + .max(11, "شماره موبایل باید دقیقاً 11 رقم باشد"), + car: Yup.string().required("نوع خودرو الزامی است"), + number_of_carcasses: Yup.number() + .required("حجم لاشه الزامی است") + .min(1, "حجم لاشه باید بیشتر از 0 باشد"), + weight_of_carcasses: Yup.number() + .required("وزن لاشه الزامی است") + .min(0.01, "وزن باید بیشتر از 0 باشد"), + bar_image: Yup.string(), + selectedDate: Yup.date().required("تاریخ الزامی است"), +}); + +export const GuildSubmitFreeBar = ({ guildKey, item, editMode }) => { + const dispatch = useDispatch(); + const [openNotif] = useContext(AppContext); + // const { inventorySelectedKillHouse } = useSelector( + // (state) => state.slaughterSlice + // ); + const [, , selectedDate1] = useContext(AppContext); + + const thenCallback = (r) => { + dispatch( + guildGetInventoryStockService({ + date: selectedDate1, + }) + ); + dispatch( + guildGetInventoryAllocatedService({ + date: selectedDate1, + }) + ); + + dispatch( + guildGetFreeBars({ + date: selectedDate1, + }) + ); + + if (r.error) { + openNotif({ + vertical: "top", + horizontal: "center", + msg: r.error, + severity: "error", + }); + } else { + dispatch(DRAWER({ right: false, bottom: false, content: null })); + openNotif({ + vertical: "top", + horizontal: "center", + msg: "عملیات با موفقیت انجام شد.", + severity: "success", + }); + } + }; + + const [profileImages, setProfileImages] = useState([]); + + const formik = useFormik({ + initialValues: { + kill_house_key: "", + slaughter_name: item ? item.killHouseName : "", + slaughter_mobile: item ? item.killHouseMobile : "", + province: item ? item.province : "", + city: item ? item.city : "", + vet_farm_name: item ? item.killHouseVetName : "", + vet_farm_mobile: item ? item.killHouseVetMobile : "", + driver_name: item ? item.driverName : "", + driver_mobile: item ? item.driverMobile : "", + car: item ? item.car : "", + number_of_carcasses: item ? item.numberOfCarcasses : "", + weight_of_carcasses: item ? item.weightOfCarcasses : "", + bar_image: "", + selectedDate: item ? new Date(item.date) : new Date(), + }, + validationSchema: ValidationSchema, + }); + + useEffect(() => { + formik.validateForm(); + if (item?.barImage) { + factorPaymentHandler([{ data_url: item?.barImage }]); + } + }, []); + + const factorPaymentHandler = (imageList, addUpdateIndex) => { + if (imageList[0]) { + formik.setFieldValue("bar_image", fixBase64(imageList[0]?.data_url)); + } + setProfileImages(imageList); + }; + + return ( + +
    + ( + + )} + value={formik.values.selectedDate} + onChange={(e) => { + formik.setFieldValue("selectedDate", new Date(e)); + }} + /> + + + + + + + + + + + + + + + + + + قطعه, + }} + value={formik.values.number_of_carcasses} + onChange={formik.handleChange} + onBlur={formik.handleBlur} + error={ + formik.touched.number_of_carcasses && + Boolean(formik.errors.number_of_carcasses) + } + helperText={ + formik.touched.number_of_carcasses && + formik.errors.number_of_carcasses + } + /> + + کیلوگرم + ), + }} + value={formik.values.weight_of_carcasses} + onChange={formik.handleChange} + onBlur={formik.handleBlur} + error={ + formik.touched.weight_of_carcasses && + Boolean(formik.errors.weight_of_carcasses) + } + helperText={ + formik.touched.weight_of_carcasses && + formik.errors.weight_of_carcasses + } + /> + + + + {formik.touched.driver_mobile && + Boolean(formik.errors.driver_mobile) && ( + ثبت تصویر بار الزامی است + )} + + + +
    + ); +}; diff --git a/src/features/guild/components/GuilldBroadcast.js b/src/features/guild/components/GuilldBroadcast.js new file mode 100644 index 0000000..67a1884 --- /dev/null +++ b/src/features/guild/components/GuilldBroadcast.js @@ -0,0 +1,5 @@ +import { GuildBroadCastManagement } from "./GuildBroadCastManagement"; + +export const GuildBroadcast = () => { + return ; +}; diff --git a/src/features/guild/components/RegisterEditDeliveryNumberAndWeight.js b/src/features/guild/components/RegisterEditDeliveryNumberAndWeight.js new file mode 100644 index 0000000..fd62700 --- /dev/null +++ b/src/features/guild/components/RegisterEditDeliveryNumberAndWeight.js @@ -0,0 +1,143 @@ +import { useFormik } from "formik"; +import { Grid } from "../../../components/grid/Grid"; +import { Button, InputAdornment, TextField } from "@mui/material"; +import { Yup } from "../../../lib/yup/yup"; +import { useContext, useEffect } from "react"; +import { SPACING } from "../../../data/spacing"; +import { useDispatch, useSelector } from "react-redux"; +import { guildUpdateAllocatedStockService } from "../services/guild-update-allocated-stock"; +import { AppContext } from "../../../contexts/AppContext"; +import { guildGetInventoryStockService } from "../services/guild-get-inventory-stock"; +import { guildGetInventoryAllocatedService } from "../services/guild-get-inventory-allocated"; +import { CLOSE_MODAL } from "../../../lib/redux/slices/appSlice"; +import { getRoleFromUrl } from "../../../utils/getRoleFromUrl"; +import { senfGetInventoryStockService } from "../services/senf-get-inventory-stock"; +import { senfGetInventoryAllocatedService } from "../services/senf-get-inventory-allocated"; +import { checkPathStartsWith } from "../../../utils/checkPathStartsWith"; + +const schema = Yup.object().shape({ + quantity: Yup.number().required("وارد کردن تعداد اجباری است"), + weight: Yup.number().required("وارد کردن وزن اجباری است"), +}); + +export const RegisterEditDeliveryNumberAndWeight = ({ item }) => { + const [openNotif] = useContext(AppContext); + const [, , selectedDate1] = useContext(AppContext); + const dispatch = useDispatch(); + const selectedSubUser = useSelector( + (state) => state.userSlice.selectedSubUser + ); + const formik = useFormik({ + initialValues: { + quantity: item?.receiverRealNumberOfCarcasses, + weight: item?.receiverRealWeightOfCarcasses, + }, + validationSchema: schema, + onSubmit: (values) => { + dispatch( + guildUpdateAllocatedStockService({ + steward: true, + allocation_key: item.key, + receiver_real_number_of_carcasses: Number(values.quantity), + receiver_real_weight_of_carcasses: Number(values.weight), + }) + ).then((r) => { + if (r.payload.error) { + openNotif({ + vertical: "top", + horizontal: "center", + msg: r.payload.error, + severity: "error", + }); + } else { + if (getRoleFromUrl() === "senf") { + dispatch( + senfGetInventoryStockService({ + date: selectedDate1, + }) + ); + dispatch( + senfGetInventoryAllocatedService({ + date: selectedDate1, + }) + ); + } else { + dispatch( + guildGetInventoryStockService({ + date: selectedDate1, + role_key: checkPathStartsWith("senf") + ? selectedSubUser?.key + : "", + }) + ); + dispatch( + guildGetInventoryAllocatedService({ + date: selectedDate1, + role_key: checkPathStartsWith("senf") + ? selectedSubUser?.key + : "", + }) + ); + } + openNotif({ + vertical: "top", + horizontal: "center", + msg: "عملیات با موفقیت انجام شد.", + severity: "success", + }); + dispatch(CLOSE_MODAL()); + } + }); + }, + }); + + useEffect(() => { + formik.validateForm(); + }, []); + + useEffect(() => { + const quantity = formik.values.weight / item.indexWeight; + formik.setFieldValue("quantity", quantity.toFixed(0)); + }, [formik.values.weight]); + + return ( + +
    + + کیلوگرم + ), + }} + value={formik.values.weight} + onChange={formik.handleChange} + error={formik.touched.weight && formik.errors.weight} + helperText={formik.touched.weight && formik.errors.weight} + /> + قطعه + ), + }} + value={formik.values.quantity} + onChange={formik.handleChange} + error={formik.touched.quantity && formik.errors.quantity} + helperText={formik.touched.quantity && formik.errors.quantity} + /> + + +
    +
    + ); +}; diff --git a/src/features/guild/components/StewardAllocationToGuild.js b/src/features/guild/components/StewardAllocationToGuild.js new file mode 100644 index 0000000..77ca761 --- /dev/null +++ b/src/features/guild/components/StewardAllocationToGuild.js @@ -0,0 +1,890 @@ +import React, { useContext, useEffect, useState, useCallback } from "react"; +import { + Autocomplete, + Button, + Checkbox, + FormControl, + FormControlLabel, + InputAdornment, + Radio, + RadioGroup, + TextField, + Typography, +} from "@mui/material"; +import { useDispatch, useSelector } from "react-redux"; +import { useFormik } from "formik"; +import { DatePicker } from "@mui/x-date-pickers"; +import moment from "moment"; +import { AppContext } from "../../../contexts/AppContext"; +import { provincePolicyGetUploadImageService } from "../../province/services/province-policy-upload-image"; +import { getRoleFromUrl } from "../../../utils/getRoleFromUrl"; +import { slaughterGetProductsService } from "../../slaughter-house/services/slaughter-inventory-gets"; +import { slaughterGetGuildsForAllocateService } from "../../slaughter-house/services/slaughter-get-guilds-for-allocate"; +import { Yup } from "../../../lib/yup/yup"; +import { fixBase64 } from "../../../utils/toBase64"; +import { CLOSE_MODAL, DRAWER } from "../../../lib/redux/slices/appSlice"; +import { NumberInput } from "../../../components/number-format-custom/NumberFormatCustom"; +import { ImageUpload } from "../../../components/image-upload/ImageUpload"; +import { Grid } from "../../../components/grid/Grid"; +import { + slaughterAllocateStewardService, + slaughterEditAllocateStewardService, +} from "../../slaughter-house/services/slaughter-allocate-steward"; +import { fetchSlaughterBroadcastAndProducts } from "../../slaughter-house/services/handle-fetch-slaughter-products"; +import MonthlyDataCalendar from "../../../components/date-picker/MonthlyDataCalendar"; +import PersianDate from "persian-date"; +import axios from "axios"; +import { LabelField } from "../../../components/label-field/LabelField"; +import { SPACING } from "../../../data/spacing"; +import { checkPathStartsWith } from "../../../utils/checkPathStartsWith"; + +export const StewardAllocationToGuild = ({ + item, + key, + sellerType, + fetchData, + buyerType, + allocationType, + sellType, + updateTable, + fetchApiData, + editData, + coldHouseKey, + coldHouseItemKey, + killHouseAllocation, + priceInfo, +}) => { + const dispatch = useDispatch(); + const [productData, setProductData] = useState([]); + const [guildsData, setGuildsData] = useState([]); + const [selectedInventory, setSelectedInventory] = useState("governmental"); + const [approvedStatus, setApprovedStatus] = useState("true"); + const [productKey, setProductKey] = useState(null); + const [openNotif] = useContext(AppContext); + const [profileImages, setProfileImages] = useState( + editData?.image ? [{ data_url: editData.image }] : [] + ); + + const [value, setValue] = useState("own"); + const [imageUploadLimit, setImageUploadLimit] = useState(1); + const [imageChanged, setImageChanged] = useState(false); + const [changeMobile, setChangeMobile] = useState(false); + const [selectedCalendarDate, setSelectedCalendarDate] = useState(null); + const [calendarDayData, setCalendarDayData] = useState({}); + const [productionDate, setProductionDate] = useState(null); + const [selectedDateAmount, setSelectedDateAmount] = useState(null); + const [calendarRawData, setCalendarRawData] = useState({ + governmental: [], + free: [], + }); + const [selectedDate1, setSelectedDate1] = useState( + moment(new Date()).format("YYYY-MM-DD") + ); + const selectedSubUser = useSelector( + (state) => state.userSlice.selectedSubUser + ); + + const handleChange = (event) => { + setValue(event.target.value); + setBuyerData({ + key: "", + item: "", + buyerType: "", + allocationType: "", + }); + }; + + useEffect(() => { + if (priceInfo?.active === false) { + setApprovedStatus("false"); + } + }, [priceInfo?.active]); + + useEffect(() => { + if (approvedStatus === "true" && priceInfo?.active) { + formik.setFieldValue("price", priceInfo?.killHousePrice); + } + }, [approvedStatus]); + + const handleSellType = (event) => { + const newType = event.target.value; + setSelectedInventory(newType); + }; + + const handleApprovedPrice = (event) => { + const newType = event.target.value; + setApprovedStatus(newType); + }; + + const handleDateSelect = (dateInfo) => { + if (dateInfo && dateInfo.formattedDate) { + setSelectedCalendarDate(dateInfo.formattedDate); + + const data = calendarDayData[dateInfo.formattedDate]; + + if (data && data.originalDay) { + setProductionDate(data.originalDay); + } + + if (data && (data.amount !== undefined || data.value1 !== undefined)) { + const rawAmount = data.amount !== undefined ? data.amount : data.value1; + const normalizedAmount = + typeof rawAmount === "string" + ? Number(rawAmount.replace(/,/g, "")) + : Number(rawAmount); + setSelectedDateAmount( + Number.isFinite(normalizedAmount) ? normalizedAmount : null + ); + } else { + setSelectedDateAmount(null); + } + } + }; + + const transformCalendarData = useCallback((dataArray) => { + if (!Array.isArray(dataArray)) return {}; + + const transformedData = {}; + dataArray.forEach((item) => { + if (item.day && item.amount !== undefined) { + const persianDate = new PersianDate(new Date(item.day)); + const persianDateStr = persianDate.format("YYYY/MM/DD"); + const rawAmount = item.amount; + const normalizedAmount = + typeof rawAmount === "string" + ? Number(rawAmount.replace(/,/g, "")) + : Number(rawAmount); + transformedData[persianDateStr] = { + value1: normalizedAmount, + originalDay: item.day, + active: item.active === true, // Store active status + }; + } + }); + return transformedData; + }, []); + + const updateCalendarData = useCallback((dataArray) => { + const transformed = transformCalendarData(dataArray); + setCalendarDayData(transformed); + }, []); + + const fetchCalendarData = useCallback( + async (dateParam = selectedDate1) => { + try { + const response = await axios.get("/steward-remain-weight/", { + params: { + date: dateParam, + role_key: checkPathStartsWith("steward") + ? selectedSubUser?.key + : "", + }, + }); + if (response.data) { + setCalendarRawData({ + governmental: response.data.governmental || [], + free: response.data.free || [], + }); + const dataToShow = + selectedInventory === "governmental" + ? response.data.governmental + : response.data.free; + updateCalendarData(dataToShow || []); + } + } catch (error) { + console.error("Error fetching calendar data:", error); + } + }, + [selectedInventory, updateCalendarData, selectedDate1, selectedSubUser] + ); + + const [buyerData, setBuyerData] = useState({ + key, + item, + buyerType, + allocationType, + }); + + useEffect(() => { + if (getRoleFromUrl() === "Steward") { + setValue("free"); + } + }, []); + + useEffect(() => { + fetchCalendarData(selectedDate1); + }, [selectedDate1]); + + useEffect(() => { + if ( + calendarRawData.governmental.length > 0 || + calendarRawData.free.length > 0 + ) { + const dataToShow = + selectedInventory === "governmental" + ? calendarRawData.governmental + : calendarRawData.free; + updateCalendarData(dataToShow); + setSelectedCalendarDate(null); + setProductionDate(null); + setSelectedDateAmount(null); + } + }, [selectedInventory, calendarRawData]); + + useEffect(() => { + dispatch( + provincePolicyGetUploadImageService({ + role_key: checkPathStartsWith("steward") ? selectedSubUser?.key : "", + }) + ).then((r) => { + if (r.payload?.data) { + setImageUploadLimit(r.payload.data.killHouseAllocation); + } + }); + + if (!editData) { + dispatch( + slaughterGetProductsService({ + role_key: checkPathStartsWith("steward") ? selectedSubUser?.key : "", + }) + ).then((r) => { + setProductData(r.payload.data); + }); + if (!item) { + dispatch( + slaughterGetGuildsForAllocateService({ + free: value === "free" ? true : false, + role_key: checkPathStartsWith("steward") + ? selectedSubUser?.key + : "", + }) + ).then((r) => { + setGuildsData(r.payload.data); + }); + } + } + }, [value, selectedSubUser?.key]); + + const validationSchema = Yup.object({ + mobile: Yup.string().when([], { + is: () => !editData, + then: (schema) => + schema + .required("شماره موبایل الزامی است") + .min(11, "شماره موبایل باید 11 رقم باشد") + .max(11, "شماره موبایل باید 11 رقم باشد") + .matches( + /^09\d{9}$/, + "شماره موبایل باید با 09 شروع شود و 11 رقم باشد" + ), + otherwise: (schema) => schema.notRequired(), + }), + weight: Yup.number() + .required("این فیلد اجباری است!") + .integer("عدد باید صحیح باشد!") + .min(1, "یک مقدار مثبت وارد کنید!") + .test( + "max-production-date-amount", + `وزن نمی‌تواند بیشتر از موجودی تاریخ تولید (${ + selectedDateAmount?.toLocaleString() || 0 + } کیلوگرم) باشد!`, + function (value) { + if (!selectedDateAmount || selectedDateAmount === null) return true; + return ( + value <= selectedDateAmount + (editData?.realWeightOfCarcasses || 0) + ); + } + ), + price: Yup.number() + .required("این فیلد اجباری است!") + .min(1, "یک مقدار مثبت وارد کنید!"), + wholePrice: Yup.number() + .required("این فیلد اجباری است!") + .min(1, "یک مقدار مثبت وارد کنید!"), + ...(killHouseAllocation && { + image: Yup.string().when([], { + is: () => (!editData || imageChanged) && imageUploadLimit > 0, + then: Yup.string().required("عکس الزامی است"), + otherwise: Yup.string().notRequired(), + }), + }), + }); + + const factorPaymentHandler = (imageList) => { + if (imageList[0]) { + formik.setFieldValue("image", fixBase64(imageList[0]?.data_url)); + setImageChanged(true); + } else { + formik.setFieldValue("image", ""); + setImageChanged(true); + } + setProfileImages(imageList); + }; + + const formik = useFormik({ + initialValues: { + mobile: "", + weight: editData?.realWeightOfCarcasses || "", + wholePrice: editData?.totalAmount || "", + price: editData?.amount || "", + image: editData?.image || "", + }, + validationSchema, + }); + + useEffect(() => { + formik.validateForm(); + }, []); + + useEffect(() => { + formik.validateForm(); + }, [selectedDateAmount]); + + useEffect(() => { + if (formik.values.weight && formik.values.price) { + formik.setFieldValue( + "wholePrice", + formik.values.price * formik.values.weight + ); + } + }, [formik.values.price, formik.values.weight]); + + const successSubmit = () => { + dispatch( + fetchSlaughterBroadcastAndProducts({ + role_key: checkPathStartsWith("steward") ? selectedSubUser?.key : "", + }) + ); + dispatch( + DRAWER({ + right: false, + bottom: false, + left: false, + content: null, + }) + ); + fetchApiData && fetchApiData(1); + updateTable && updateTable(); + fetchData && fetchData(1); + dispatch(CLOSE_MODAL()); + openNotif({ + vertical: "top", + horizontal: "center", + msg: "عملیات با موفقیت انجام شد.", + severity: "success", + }); + }; + + const [dateRangeError, setDateRangeError] = useState(null); + + return ( + + {!editData && ( + ( + + )} + shouldDisableDate={(date) => { + const d = moment(date); + const today = moment(); + const yesterday = moment().subtract(1, "day"); + return !(d.isSame(today, "day") || d.isSame(yesterday, "day")); + }} + value={selectedDate1} + onChange={(e) => { + if (!e) { + setDateRangeError(null); + return; + } + const d = moment(e); + const today = moment(); + const yesterday = moment().subtract(1, "day"); + const isAllowed = + d.isSame(today, "day") || d.isSame(yesterday, "day"); + if (!isAllowed) { + setDateRangeError( + "تنها امکان انتخاب «امروز» یا «دیروز» وجود دارد." + ); + return; + } + setDateRangeError(null); + const formatted = moment(e).format("YYYY-MM-DD"); + setSelectedDate1(formatted); + fetchCalendarData(formatted); + }} + /> + )} + + {!editData && !coldHouseKey && ( + + { + return { + data: i, + label: `${i.name}`, + }; + }) + : [] + } + onChange={(event, value) => { + setProductKey(value.data); + }} + renderInput={(params) => ( + + )} + /> + + )} + + {!editData && ( + + + + } + label="اختصاصی" + /> + } label="آزاد" /> + + + + )} + + {!item && !editData && ( + + { + return { + data: i, + label: `${i?.guildsName} ${i?.user?.fullname} (${i?.user?.mobile})`, + }; + }) + : [] + } + onChange={(event, value) => { + setBuyerData({ + item: value?.data, + key: value?.data?.key, + allocationType: "steward_guild", + buyerType: "Guild", + }); + formik.setFieldValue("mobile", value?.data?.user?.mobile); + formik.setFieldTouched("mobile", true, false); + formik.validateField("mobile"); + const reg = new RegExp(/^09\d{9}$/); + if (!reg.test(value?.data?.user?.mobile)) { + setChangeMobile(true); + } + }} + renderInput={(params) => ( + + )} + /> + + )} + {!item && !editData && ( + + + setChangeMobile(!changeMobile)} + /> + از این قسمت میتوانید تلفن صنف را ویرایش کنید. + + + {buyerData?.key && changeMobile && ( + + )} + + )} + + {!item && !editData && priceInfo?.active !== false && ( + + + + } + label="قیمت دولتی" + /> + } + label="قیمت آزاد" + /> + + + + )} + + {!item && !editData && ( + + + + } + label="دولتی" + /> + } label="آزاد" /> + + + + )} + + + {productionDate && + selectedDate1 && + moment(productionDate).isAfter(moment(selectedDate1), "day") && ( + + تاریخ تولید نمی‌تواند بعد از تاریخ انتخابی باشد + + )} + + selectedDateAmount + } + onChange={(e) => { + const value = e.target.value; + if (value === "" || value === null || value === undefined) { + formik.setFieldValue("weight", ""); + return; + } + const intValue = Math.floor(Number(value)); + if (intValue > 0) { + formik.setFieldValue("weight", intValue); + } else if (intValue === 0) { + formik.setFieldValue("weight", ""); + } + }} + onBlur={formik.handleBlur} + helperText={ + !selectedDateAmount && !productionDate + ? "لطفاً ابتدا تاریخ تولید را انتخاب کنید!" + : formik.touched.weight && Boolean(formik.errors.weight) + ? formik.errors.weight + : null + } + disabled={!selectedDateAmount && !productionDate} + sx={{ + "& .MuiFormHelperText-root": { + color: + selectedDateAmount && formik.values.weight > selectedDateAmount + ? "error.main" + : undefined, + }, + }} + /> + + ریال, + }} + value={formik.values.price} + error={formik.touched.price ? Boolean(formik.errors.price) : null} + onChange={formik.handleChange} + onBlur={formik.handleBlur} + helperText={ + formik.touched.price && Boolean(formik.errors.price) + ? formik.errors.price + : null + } + /> + + ریال, + }} + value={formik.values.wholePrice} + error={ + formik.touched.wholePrice ? Boolean(formik.errors.wholePrice) : null + } + onChange={formik.handleChange} + onBlur={formik.handleBlur} + helperText={ + formik.touched.wholePrice && Boolean(formik.errors.wholePrice) + ? formik.errors.wholePrice + : null + } + /> + {(killHouseAllocation || (editData && editData.image)) && ( + + + {formik.touched.image && Boolean(formik.errors.image) && ( + ثبت تصویر الزامی است + )} + + )} + + + + + + + + + + + ); +}; diff --git a/src/features/guild/components/StewardDailyList.js b/src/features/guild/components/StewardDailyList.js new file mode 100644 index 0000000..d14d97e --- /dev/null +++ b/src/features/guild/components/StewardDailyList.js @@ -0,0 +1,609 @@ +import React, { useContext, useEffect, useRef, useState } from "react"; +import { useDispatch, useSelector } from "react-redux"; +import InfoIcon from "@mui/icons-material/Info"; +import TextField from "@mui/material/TextField"; +import InputAdornment from "@mui/material/InputAdornment"; +import SearchIcon from "@mui/icons-material/Search"; +import axios from "axios"; +import { + Box, + Button, + Card, + CardContent, + IconButton, + Typography, +} from "@mui/material"; + +import moment from "moment"; +import AddIcon from "@mui/icons-material/Add"; +import CheckCircleIcon from "@mui/icons-material/CheckCircle"; +import DeleteIcon from "@mui/icons-material/Delete"; +import { getRoleFromUrl } from "../../../utils/getRoleFromUrl"; +import { + DRAWER, + LOADING_END, + LOADING_START, +} from "../../../lib/redux/slices/appSlice"; +import { slaughterGetProductsService } from "../../slaughter-house/services/slaughter-inventory-gets"; +import { + slaughterDeleteDailyListService, + slaughterGetPriceService, + submitBatchAllocationsService, +} from "../../slaughter-house/services/slaughter-add-daily-list"; +import { SlaughterAddDailyList } from "../../slaughter-house/components/slaughter-add-daily-list/SlaughterAddDailyList"; +import { Grid } from "../../../components/grid/Grid"; +import { NumberInput } from "../../../components/number-format-custom/NumberFormatCustom"; +import ResponsiveTable from "../../../components/responsive-table/ResponsiveTable"; +import { AppContext } from "../../../contexts/AppContext"; +import { checkPathStartsWith } from "../../../utils/checkPathStartsWith"; + +export const StewardDailyList = () => { + const [productsTable, setProductsTable] = useState(); + const [slaughterProducts, setSlaughterProducts] = useState(); + const [prices, setPrices] = useState([]); + const [rendered, setrendered] = useState(false); + const [weights, setWeights] = useState([]); + const [data, setData] = useState([]); + const [tableData, setTableData] = useState([]); + const [searchTerm, setSearchTerm] = useState(""); + const [filteredData, setFilteredData] = useState([]); + + const [openNotif] = useContext(AppContext); + const selectedSubUser = useSelector( + (state) => state.userSlice.selectedSubUser + ); + const priceRefs = useRef([]); + const weightRefs = useRef([]); + + const dispatch = useDispatch(); + + const [priceState, setPriceState] = useState({ + active: false, + killHousePrice: 0, + stewardPrice: 0, + guildPrice: 0, + }); + + const getPriceByRole = () => { + const role = getRoleFromUrl(); + if (role === "KillHouse") return priceState.killHousePrice; + if (role === "Steward") return priceState.stewardPrice; + if (role === "Guilds") return priceState.guildPrice; + return 0; + }; + + useEffect(() => { + priceRefs.current = priceRefs.current.slice(0, data?.length || 0); + weightRefs.current = weightRefs.current.slice(0, data?.length || 0); + }, [data]); + + useEffect(() => { + if (searchTerm) { + const filtered = tableData.filter((item) => + item.some((cell) => + String(cell).toLowerCase().includes(searchTerm.toLowerCase()) + ) + ); + setFilteredData(filtered); + } else { + setFilteredData(tableData); + } + }, [searchTerm, tableData]); + + const handleKeyDown = (e, index, fieldType) => { + if (e.key === "Enter") { + e.preventDefault(); + + if (fieldType === "price") { + const updatedPrices = [...prices]; + updatedPrices[index] = Number(e.target.value.replace(/,/g, "")); + setPrices(updatedPrices); + + if (weightRefs.current[index]) { + weightRefs.current[index].focus(); + } + } else if (fieldType === "weight") { + const updatedWeights = [...weights]; + updatedWeights[index] = Number(e.target.value.replace(/,/g, "")); + setWeights(updatedWeights); + + if (priceState?.active) { + let nextIndex = index + 1; + while (nextIndex < data.length) { + if (weightRefs.current[nextIndex]) { + weightRefs.current[nextIndex].focus(); + break; + } + nextIndex++; + } + + if (nextIndex >= data.length && weightRefs.current[0]) { + weightRefs.current[0]?.focus(); + } + } else { + let nextIndex = index + 1; + while (nextIndex < data.length) { + if (priceRefs.current[nextIndex]) { + priceRefs.current[nextIndex].focus(); + break; + } + nextIndex++; + } + + if (nextIndex >= data.length && priceRefs.current[0]) { + priceRefs.current[0]?.focus(); + } + } + } + } + }; + const fetchPriceStatus = async () => { + dispatch( + slaughterGetPriceService({ + role: getRoleFromUrl(), + role_key: checkPathStartsWith("steward") ? selectedSubUser?.key : "", + }) + ).then((r) => { + setPriceState(r.payload.data); + }); + }; + + const fetchApiData = async () => { + dispatch(LOADING_START()); + try { + const response = await axios.get( + `commonly-used/?search=filter&value=&role=${getRoleFromUrl()}${ + checkPathStartsWith("steward") + ? `&role_key=${selectedSubUser?.key}` + : "" + }&page=1&page_size=10000` + ); + setrendered(true); + setData(response.data.results || []); + } catch (e) { + console.error(e); + } finally { + dispatch(LOADING_END()); + } + }; + + useEffect(() => { + const d = data?.map((item, i) => { + const getPrice = + parseInt(priceState?.active ? getPriceByRole() : prices[i]) * + parseInt(weights[i]); + return [ + i + 1, + item?.guild?.steward ? "مباشر" : "صنف", + `${item?.guild?.guildsName}/${item?.guild?.user?.fullname}/${item?.guild?.user?.city}/${item?.guild?.user?.mobile}`, + item?.exclusive ? "اختصاصی" : "آزاد", + handleKeyDown(e, i, "price")} + inputRef={(el) => (priceRefs.current[i] = el)} + variant="outlined" + style={{ width: 100 }} + />, + + { + handleKeyDown(e, i, "weight"); + }} + inputRef={(el) => (weightRefs.current[i] = el)} + variant="outlined" + style={{ width: 100 }} + />, + isNaN(getPrice) ? "وارد نشده! " : getPrice?.toLocaleString() + " ریال", + + handleDeleteItem(item.key)} /> + , + ]; + }); + + setTableData(d); + setFilteredData(d); + }, [data, prices, weights, priceState]); + + useEffect(() => { + fetchApiData(); + fetchPriceStatus(); + dispatch(slaughterGetProductsService()).then((r) => { + setSlaughterProducts(r.payload.data); + }); + }, [selectedSubUser?.key]); + + useEffect(() => { + const d = slaughterProducts?.map((item) => { + return [item?.name, item?.totalRemainWeight?.toLocaleString()]; + }); + + setProductsTable(d); + }, [slaughterProducts]); + + const handleDeleteItem = (key) => { + dispatch(slaughterDeleteDailyListService(key)).then((r) => { + if (r.payload.error) { + openNotif({ + vertical: "top", + horizontal: "center", + msg: r.payload.error, + severity: "error", + }); + } else { + openNotif({ + vertical: "top", + horizontal: "center", + msg: "عملیات با موفقیت انجام شد.", + severity: "success", + }); + + fetchApiData(1); + } + }); + }; + + const handleSendAllocate = () => { + const filterdData = data?.map((item, i) => { + const price = priceState?.active ? getPriceByRole() : prices[i]; + let d = { + seller_type: "Steward", + buyer_type: item?.guild?.steward ? "Steward" : "Guild", + guild_key: !item?.guild?.steward ? item?.guild?.key : null, + steward_key: item?.guild?.steward ? item?.guild?.key : null, + product_key: slaughterProducts[0]?.key, + type: "manual", + allocation_type: item?.steward ? "steward_steward" : "steward_guild", + number_of_carcasses: 0, + weight_of_carcasses: weights[i] || null, + sell_type: "free", + amount: price || null, + total_amount: price * weights[i], + approved_price_status: priceState?.active, + date: moment(new Date()).format("YYYY-MM-DD"), + }; + d = Object.fromEntries( + Object.entries(d).filter(([_, value]) => value !== null) + ); + return d; + }); + + const finalData = filterdData.filter( + (option) => + option.total_amount > 1 && option?.amount && option?.weight_of_carcasses + ); + + dispatch(submitBatchAllocationsService(finalData)).then((r) => { + if (r.payload.error) { + openNotif({ + vertical: "top", + horizontal: "center", + msg: r.payload.error, + severity: "error", + }); + } else { + openNotif({ + vertical: "top", + horizontal: "center", + msg: "عملیات با موفقیت انجام شد.", + severity: "success", + }); + setPrices([]); + setWeights([]); + fetchApiData(1); + fetchPriceStatus(); + dispatch(slaughterGetProductsService()).then((r) => { + setSlaughterProducts(r.payload.data); + }); + } + }); + }; + + return ( + + + + + + + + + + + + + + + + مجموع وزن وارد شده + + + {weights?.length + ? weights.reduce((a, b) => a + b, 0).toLocaleString() + : "۰"} + + + + + وزن باقیمانده + a + b, 0) > + slaughterProducts[0]?.totalRemainWeight + ? "error" + : "text.secondary" + : "text.secondary" + } + > + {slaughterProducts?.[0]?.totalRemainWeight !== undefined + ? weights?.length + ? ( + slaughterProducts[0]?.totalRemainWeight - + weights.reduce((a, b) => a + b, 0) + ).toLocaleString() + : slaughterProducts[0]?.totalRemainWeight.toLocaleString() + : "۰"} + + + + + + + + + + + + + + + + پس از وارد کردن هر مقدار، کلید Enter را فشار دهید! + + + + + + + صرفا تخصیصاتی که هر دو مقدار قیمت و وزن آنها را وارد کنید ثبت خواهند + شد. + + + + + setSearchTerm(e.target.value)} + InputProps={{ + startAdornment: ( + + + + ), + }} + sx={{ mb: 2 }} + /> + + + {filteredData?.length ? ( + + {filteredData?.map((item, i) => ( + + + {item[0]} + + + + + ماهیت: + + + {item[1]} + + + + + + خریدار: + + + {item[2]} + + + + + + نوع فروش: + + + {item[3]} + + + + + + قیمت هرکیلو: + + + {item[4]} + + + + + + وزن لاشه: + + + {item[5]} + + + + + + قیمت کل: + + + {item[6]} + + + + {item[7]} + + + + {!priceState?.active && + (!prices[i] || !weights[i]) && + (prices[i] || weights[i]) && ( + + لطفا همه موارد را وارد کنید و کلید Enter را بزنید + + )} + + + ))} + + ) : ( + + {!rendered + ? searchTerm + ? "نتیجه‌ای یافت نشد" + : "در حال بارگزاری..." + : "موردی یافت نشد!"} + + )} + + ); +}; diff --git a/src/features/guild/components/StewardDispenserSaleOutDashboard.js b/src/features/guild/components/StewardDispenserSaleOutDashboard.js new file mode 100644 index 0000000..03fe756 --- /dev/null +++ b/src/features/guild/components/StewardDispenserSaleOutDashboard.js @@ -0,0 +1,21 @@ +import { Grid } from "../../../components/grid/Grid"; +import ResponsiveTable from "../../../components/responsive-table/ResponsiveTable"; + +export const StewardDispenserSaleOutDashboard = ({ dashboardData }) => { + return ( + + + + ); +}; diff --git a/src/features/guild/components/StewardNorEnterdBarChangeState.js b/src/features/guild/components/StewardNorEnterdBarChangeState.js new file mode 100644 index 0000000..e9055d3 --- /dev/null +++ b/src/features/guild/components/StewardNorEnterdBarChangeState.js @@ -0,0 +1,230 @@ +import React, { useContext } from "react"; +import { + Grid, + TextField, + Button, + RadioGroup, + FormControlLabel, + Radio, + FormControl, +} from "@mui/material"; +import { useFormik } from "formik"; +import * as Yup from "yup"; +import { useDispatch } from "react-redux"; +import { guildAllocatedStockOperationService } from "../services/guild-allocated-stock-operation"; +import { AppContext } from "../../../contexts/AppContext"; +import { CLOSE_MODAL } from "../../../lib/redux/slices/appSlice"; + +export const StewardNorEnterdBarChangeState = ({ + item, + handleUpdate, + updateTable, +}) => { + const [openNotif] = useContext(AppContext); + const dispatch = useDispatch(); + const formik = useFormik({ + initialValues: { + decision: "approve", + weight: item?.realWeightOfCarcasses, + volume: item?.realNumberOfCarcasses, + weightLoss: item?.weightLossOfCarcasses, + regCode: "", + regState: "with_code", + }, + validationSchema: Yup.object({ + decision: Yup.string().required("انتخاب گزینه الزامی است"), + regState: Yup.string(), + weight: Yup.string().when("decision", { + is: "approve", + then: Yup.string().required("وزن الزامی است"), + }), + volume: Yup.string().when("decision", { + is: "approve", + then: Yup.string().required("حجم الزامی است"), + }), + weightLoss: Yup.string().when("decision", { + is: "approve", + then: Yup.string().required("افت وزن الزامی است"), + }), + regCode: Yup.string() + .matches(/^\d{5}$/, "کد باید یک عدد پنج رقمی باشد") + .typeError("یک عدد پنج رقمی وارد کنید!") + .when(["regState", "decision"], { + is: (regState, decision) => + regState === "with_code" && decision === "approve", + then: Yup.string().required("کد احراز الزامی است"), + }), + }), + onSubmit: (values) => { + const baseRequest = { + check_allocation: true, + allocation_key: item?.key, + }; + + const req = + values.decision === "reject" + ? { ...baseRequest, state: "rejected" } + : { + ...baseRequest, + state: "accepted", + ...(values.regState === "with_code" && { + registration_code: parseInt(values.regCode), + }), + receiver_real_number_of_carcasses: parseInt(values.volume), + receiver_real_weight_of_carcasses: parseInt(values.weight), + weight_loss_of_carcasses: parseInt(values.weightLoss), + }; + + dispatch(guildAllocatedStockOperationService(req)).then((r) => { + if (r.payload.error) { + openNotif({ + vertical: "top", + horizontal: "center", + msg: r.payload.error, + severity: "error", + }); + } else { + openNotif({ + vertical: "top", + horizontal: "center", + msg: "عملیات با موفقیت انجام شد.", + severity: "success", + }); + dispatch(CLOSE_MODAL()); + handleUpdate(); + updateTable && updateTable(); + } + }); + }, + }); + + const handleDecisionChange = (event) => { + formik.setFieldValue("decision", event.target.value); + }; + + return ( + + + + + } + label="تایید" + /> + } label="رد" /> + + + {formik.touched.decision && formik.errors.decision && ( +
    + {formik.errors.decision} +
    + )} +
    + + {formik.values.decision === "approve" && ( + <> + + + + + + + + + + + + { + formik.setFieldValue("regState", e.target.value); + }} + > + } + label="با کد احراز" + /> + } + label="بدون کد احراز" + /> + + + {formik.touched.regState && formik.errors.regState && ( +
    + {formik.errors.regState} +
    + )} +
    + {formik.values.regState === "with_code" && ( + + + + )} + + )} + + + + +
    + ); +}; diff --git a/src/features/guild/components/StewardSaleDispenserWithinDashboard.js b/src/features/guild/components/StewardSaleDispenserWithinDashboard.js new file mode 100644 index 0000000..b519e1d --- /dev/null +++ b/src/features/guild/components/StewardSaleDispenserWithinDashboard.js @@ -0,0 +1,27 @@ +import { Grid } from "../../../components/grid/Grid"; +import ResponsiveTable from "../../../components/responsive-table/ResponsiveTable"; + +export const StewardSaleDispenserWithinDashboard = ({ dashboardData }) => { + return ( + + + + ); +}; diff --git a/src/features/guild/components/StewardSegmant.js b/src/features/guild/components/StewardSegmant.js new file mode 100644 index 0000000..af8e597 --- /dev/null +++ b/src/features/guild/components/StewardSegmant.js @@ -0,0 +1,316 @@ +import { useContext, useEffect, useState } from "react"; +import { AppContext } from "../../../contexts/AppContext"; +import { useDispatch, useSelector } from "react-redux"; +import ResponsiveTable from "../../../components/responsive-table/ResponsiveTable"; +import { Grid } from "../../../components/grid/Grid"; +import moment from "moment"; +import { Button, TextField } from "@mui/material"; +import { DatePicker } from "@mui/x-date-pickers"; +import { RiSearchLine } from "react-icons/ri"; +import { SPACING } from "../../../data/spacing"; +import { + DRAWER, + LOADING_END, + LOADING_START, +} from "../../../lib/redux/slices/appSlice"; +import axios from "axios"; +import { getRoleFromUrl } from "../../../utils/getRoleFromUrl"; +import { StewardSegmentSubmitOperation } from "./StewardSegmentSubmitOperation"; +import { stewardGetOutSellService } from "../services/steward-get-sell-out-service"; +import { formatJustDate, formatTime } from "../../../utils/formatTime"; +import { StewardSegmentOperation } from "./StewardSegmentOperation"; +import { stawardGetSegmentDashboardService } from "../services/steward-get-dashboard-service"; +import { checkPathStartsWith } from "../../../utils/checkPathStartsWith"; + +export const StewardSegmant = () => { + const [data, setData] = useState([]); + const [products, setProducts] = useState([]); + const [tableData, setTableData] = useState([]); + const [totalRows, setTotalRows] = useState(0); + const [perPage, setPerPage] = useState(10); + const [textValue, setTextValue] = useState(""); + const [page, setPage] = useState(1); + const [dashboardData, setDashboardData] = useState([]); + const [, , selectedDate1, setSelectedDate1, selectedDate2, setSelectedDate2] = + useContext(AppContext); + const dispatch = useDispatch(); + const selectedSubUser = useSelector( + (state) => state.userSlice.selectedSubUser + ); + + // const userKey = useSelector((state) => state.userSlice.userProfile.key); + + const getDashboardData = () => { + dispatch( + stawardGetSegmentDashboardService({ + value: textValue, + date1: selectedDate1, + date2: selectedDate2, + role_key: checkPathStartsWith("steward") ? selectedSubUser?.key : "", + }) + ).then((r) => { + setDashboardData(r.payload.data); + }); + }; + + useEffect(() => { + const currentDate = moment(new Date()).format("YYYY-MM-DD"); + setSelectedDate1(currentDate); + setSelectedDate2(currentDate); + }, []); + + const fetchApiData = async (page) => { + dispatch(LOADING_START()); + const response = await axios.get( + `app-segmentation/?search=filter&value=${textValue}&date1=${selectedDate1}&date2=${selectedDate2}&page=${page}&page_size=${perPage}&role=${getRoleFromUrl()}${ + checkPathStartsWith("steward") + ? `&role_key=${selectedSubUser?.key}` + : "" + }` + ); + + getDashboardData(); + dispatch(LOADING_END()); + setData(response.data.results); + setTotalRows(response.data.count); + }; + + useEffect(() => { + fetchApiData(1); + }, [selectedDate1, selectedDate2, perPage]); + + const handlePageChange = (page) => { + fetchApiData(page); + setPage(page); + }; + const updateTable = () => { + fetchApiData(page); + }; + + const handlePerRowsChange = (perRows) => { + setPerPage(perRows); + setPage(1); + }; + + const handleTextChange = (event) => { + setTextValue(event.target.value); + }; + + useEffect(() => { + fetchApiData(1); + dispatch( + stewardGetOutSellService({ + role_key: checkPathStartsWith("steward") ? selectedSubUser?.key : "", + }) + ).then((r) => { + setProducts(r.payload.data); + }); + }, [selectedSubUser?.key]); + + useEffect(() => { + const d = data?.map((item, i) => { + return [ + page === 1 ? i + 1 : i + perPage * (page - 1) + 1, + item?.toGuild ? "قطعه بند" : "مباشر", + `${item?.buyer?.fullname}(${item?.buyer?.mobile})`, + item?.toGuild + ? `${item?.toGuild?.user?.fullname}(${item?.toGuild?.user?.mobile})` + : "-", + item?.date ? formatTime(item?.date) : "-", + item?.productionDate ? formatJustDate(item?.productionDate) : "-", + item?.distributionType === "web" + ? "سایت" + : item?.distributionType === "app" + ? "موبایل" + : item?.distributionType === "pos" + ? "پوز" + : item?.distributionType || "-", + item?.weight, + item?.quota === "governmental" + ? "دولتی" + : item?.quota === "free" + ? "آزاد" + : "-", + item?.saleType === "governmental" + ? "دولتی" + : item?.saleType === "free" + ? "آزاد" + : "-", + , + ]; + }); + + setTableData(d); + }, [data]); + + useEffect(() => { + fetchApiData(1); + }, [selectedDate1, selectedDate2, perPage]); + + const handleSubmit = async (event) => { + event.preventDefault(); + dispatch(LOADING_START()); + try { + const response = await axios.get( + `app-segmentation/?search=filter&value=${textValue}&date1=${selectedDate1}&date2=${selectedDate2}&page=${page}&role=${getRoleFromUrl()}${ + checkPathStartsWith("steward") + ? `&role_key=${selectedSubUser?.key}` + : "" + }` + ); + setData(response.data.results); + setTotalRows(response.data.count); + getDashboardData(); + dispatch(LOADING_END()); + } catch (error) { + console.error("Error fetching data:", error); + } + }; + + return ( + + + + + +
    + + + + + + + ( + + )} + value={selectedDate1} + onChange={(e) => + setSelectedDate1(moment(e).format("YYYY-MM-DD")) + } + /> + + + ( + + )} + value={selectedDate2} + onChange={(e) => + setSelectedDate2(moment(e).format("YYYY-MM-DD")) + } + /> + + {/* + + */} + +
    + + +
    +
    + ); +}; diff --git a/src/features/guild/components/StewardSegmentOperation.js b/src/features/guild/components/StewardSegmentOperation.js new file mode 100644 index 0000000..57d12d8 --- /dev/null +++ b/src/features/guild/components/StewardSegmentOperation.js @@ -0,0 +1,108 @@ +import { useState } from "react"; +import { useDispatch } from "react-redux"; +import { stewardDeleteSegmentService } from "../services/steward-segment-delete-operation"; +import { + IconButton, + Popover, + List, + ListItem, + ListItemButton, + ListItemIcon, + Typography, +} from "@mui/material"; +import { DRAWER } from "../../../lib/redux/slices/appSlice"; +import { StewardSegmentSubmitOperation } from "./StewardSegmentSubmitOperation"; +import TuneIcon from "@mui/icons-material/Tune"; +import EditOutlinedIcon from "@mui/icons-material/EditOutlined"; +import DeleteOutlineOutlinedIcon from "@mui/icons-material/DeleteOutlineOutlined"; + +export const StewardSegmentOperation = ({ item, updateTable, productKey }) => { + const dispatch = useDispatch(); + const [anchorEl, setAnchorEl] = useState(null); + + const handleClick = (event) => { + setAnchorEl(event.currentTarget); + }; + + const handleClose = () => { + setAnchorEl(null); + }; + + const open = Boolean(anchorEl); + const id = open ? "popover" : undefined; + + const handleDelete = () => { + handleClose(); + dispatch(stewardDeleteSegmentService(item.key)).then(() => { + updateTable(); + }); + }; + + return ( +
    + + + + + + + { + handleClose(); + dispatch( + DRAWER({ + right: !(window.innerWidth <= 600), + bottom: window.innerWidth <= 600, + title: "ویرایش قطعه بندی", + content: ( + + ), + }) + ); + }} + > + + + + ویرایش + + + + + + + + + حذف + + + + + +
    + ); +}; diff --git a/src/features/guild/components/StewardSegmentSubmitOperation.js b/src/features/guild/components/StewardSegmentSubmitOperation.js new file mode 100644 index 0000000..6348ab5 --- /dev/null +++ b/src/features/guild/components/StewardSegmentSubmitOperation.js @@ -0,0 +1,654 @@ +import { + Autocomplete, + Button, + FormControl, + FormControlLabel, + InputAdornment, + Radio, + RadioGroup, + TextField, +} from "@mui/material"; +import { SPACING } from "../../../data/spacing"; +import { Grid } from "../../../components/grid/Grid"; +import { DRAWER } from "../../../lib/redux/slices/appSlice"; +import { stewardSegmentSubmitService } from "../services/steward-segment-submit-service"; +import { useDispatch, useSelector } from "react-redux"; +import { useContext, useEffect, useState, useCallback } from "react"; +import { AppContext } from "../../../contexts/AppContext"; +import { useFormik } from "formik"; +import { Yup } from "../../../lib/yup/yup"; +import { getRoleFromUrl } from "../../../utils/getRoleFromUrl"; +import { stewardEditSegmentService } from "../services/steward-segment-edit-operation"; +import MonthlyDataCalendar from "../../../components/date-picker/MonthlyDataCalendar"; +import PersianDate from "persian-date"; +import axios from "axios"; +import { LabelField } from "../../../components/label-field/LabelField"; +import { checkPathStartsWith } from "../../../utils/checkPathStartsWith"; +import { + slaughterGetGuildsForAllocateService, + slaughterGetStewardsForAllocateService, +} from "../../slaughter-house/services/slaughter-get-guilds-for-allocate"; +import { Typography } from "@mui/material"; + +const getValidationSchema = (selectedDateAmount) => + Yup.object().shape({ + weight: Yup.number() + .required("وزن لاشه الزامی است") + .min(0.01, "وزن باید بیشتر از 0 باشد") + .test( + "max-production-date-amount", + `وزن نمی‌تواند بیشتر از موجودی تاریخ تولید (${ + selectedDateAmount?.toLocaleString() || 0 + } کیلوگرم) باشد!`, + function (value) { + if (!selectedDateAmount || selectedDateAmount === null) return true; + return value <= selectedDateAmount; + } + ), + product_key: Yup.string().when("segmentType", { + is: "own", + then: Yup.string().required("انتخاب کلید الزامی است"), + }), + }); + +export const StewardSegmentSubmitOperation = ({ + updateTable, + productKey, + editData, + item, +}) => { + const dispatch = useDispatch(); + const [openNotif] = useContext(AppContext); + const [segmentType, setSegmentType] = useState("own"); + const [selectedInventory] = useState("free"); + const [approvedStatus, setApprovedStatus] = useState("governmental"); + const [buyerCategory, setBuyerCategory] = useState(""); // "stewards" or "guilds" + const [guildsData, setGuildsData] = useState([]); + const [stewardsData, setStewardsData] = useState([]); + const [buyerData, setBuyerData] = useState({ + key: "", + item: "", + buyerType: "", + allocationType: "", + }); + const selectedSubUser = useSelector( + (state) => state.userSlice.selectedSubUser + ); + + const [selectedCalendarDate, setSelectedCalendarDate] = useState(null); + const [calendarDayData, setCalendarDayData] = useState({}); + const [productionDate, setProductionDate] = useState(null); + const [selectedDateAmount, setSelectedDateAmount] = useState(null); + const [calendarRawData, setCalendarRawData] = useState({ + governmental: [], + free: [], + }); + + const formik = useFormik({ + initialValues: { + product_key: productKey || editData?.productkey || "", + weight: editData?.weight || "", + segmentType: editData ? (editData?.guildkey ? "free" : "own") : "own", + }, + validationSchema: getValidationSchema(selectedDateAmount), + onSubmit: (values) => { + if (editData) { + const req = { + weight: values.weight, + key: item?.key, + }; + + dispatch(stewardEditSegmentService(req)).then((r) => { + if (r.payload?.error) { + openNotif({ + vertical: "top", + horizontal: "center", + msg: r.payload.error, + severity: "error", + }); + } else { + dispatch(DRAWER({ right: false, bottom: false, content: null })); + updateTable(); + openNotif({ + vertical: "top", + horizontal: "center", + msg: "عملیات با موفقیت انجام شد.", + severity: "success", + }); + } + }); + } else { + let req; + + if (segmentType === "own") { + req = { + product_key: values?.product_key, + weight: values.weight, + sale_type: selectedInventory, + quota: approvedStatus, + production_date: productionDate, + distribution_type: "web", + }; + } else { + if (!buyerData?.key) { + openNotif({ + vertical: "top", + horizontal: "center", + msg: "لطفا مباشر یا صنف را انتخاب کنید", + severity: "error", + }); + return; + } + + req = { + guild_key: buyerData?.buyerType === "Guild" ? buyerData?.key : null, + steward_key: + buyerData?.buyerType === "Steward" ? buyerData?.key : null, + weight: values.weight, + product_key: productKey || "", + sale_type: selectedInventory, + quota: approvedStatus, + production_date: productionDate, + distribution_type: "web", + }; + req = Object.fromEntries( + Object.entries(req).filter(([, val]) => val !== null) + ); + } + + dispatch(stewardSegmentSubmitService(req)).then((r) => { + if (r.payload.error) { + openNotif({ + vertical: "top", + horizontal: "center", + msg: r.payload.error, + severity: "error", + }); + } else { + dispatch(DRAWER({ right: false, bottom: false, content: null })); + updateTable(); + openNotif({ + vertical: "top", + horizontal: "center", + msg: "عملیات با موفقیت انجام شد.", + severity: "success", + }); + } + }); + } + }, + }); + + const handleSegmentTypeChange = (event) => { + const newType = event.target.value; + setSegmentType(newType); + formik.setFieldValue("segmentType", newType); + }; + + // const handleSellType = (event) => { + // const newType = event.target.value; + // setSelectedInventory(newType); + // }; + + const handleApprovedPrice = (event) => { + const newType = event.target.value; + setApprovedStatus(newType); + }; + + const handleBuyerCategoryChange = (event) => { + const newCategory = event.target.value; + setBuyerCategory(newCategory); + setBuyerData({ + key: "", + item: "", + buyerType: "", + allocationType: "", + }); + setGuildsData([]); + setStewardsData([]); + }; + + // Calendar functions + const handleDateSelect = (dateInfo) => { + if (dateInfo && dateInfo.formattedDate) { + setSelectedCalendarDate(dateInfo.formattedDate); + + // Get the data for the selected date + const data = calendarDayData[dateInfo.formattedDate]; + + if (data && data.originalDay) { + setProductionDate(data.originalDay); + } + + // Get the amount for the selected date + if (data && data.value1 !== undefined) { + setSelectedDateAmount(data.value1); + } else { + setSelectedDateAmount(null); + } + } + }; + + const transformCalendarData = useCallback((dataArray) => { + if (!Array.isArray(dataArray)) return {}; + + const transformedData = {}; + dataArray.forEach((item) => { + if (item.day && item.amount !== undefined) { + const persianDate = new PersianDate(new Date(item.day)); + const persianDateStr = persianDate.format("YYYY/MM/DD"); + transformedData[persianDateStr] = { + value1: item.amount, + originalDay: item.day, + active: item.active === true, + }; + } + }); + return transformedData; + }, []); + + const updateCalendarData = useCallback( + (dataArray) => { + const transformed = transformCalendarData(dataArray); + setCalendarDayData(transformed); + }, + [transformCalendarData] + ); + + // Fetch calendar data from API + const fetchCalendarData = useCallback(async () => { + try { + const currentRole = getRoleFromUrl(); + console.log(getRoleFromUrl()); + let remainWeightEndpoint = "kill-house-remain-weight"; + if (currentRole === "Steward") { + remainWeightEndpoint = "steward-remain-weight"; + } else if (currentRole === "Guilds") { + remainWeightEndpoint = "guild-remain-weight"; + } + + const response = await axios.get(`${remainWeightEndpoint}/`, { + params: { + role_key: + checkPathStartsWith("slaughter") || + checkPathStartsWith("steward") || + checkPathStartsWith("senf") + ? selectedSubUser?.key || "" + : "", + }, + }); + if (response.data) { + setCalendarRawData({ + governmental: response.data.governmental || [], + free: response.data.free || [], + }); + const dataToShow = + approvedStatus === "governmental" + ? response.data.governmental + : response.data.free; + updateCalendarData(dataToShow); + } + } catch (error) { + console.error("Error fetching calendar data:", error); + } + }, [approvedStatus, updateCalendarData, selectedSubUser]); + + useEffect(() => { + fetchCalendarData(); + }, []); + + useEffect(() => { + if (!editData && buyerCategory) { + if (buyerCategory === "guilds") { + dispatch( + slaughterGetGuildsForAllocateService({ + free: true, + role_key: + checkPathStartsWith("slaughter") || checkPathStartsWith("steward") + ? selectedSubUser?.key || "" + : "", + }) + ).then((r) => { + setGuildsData(r.payload.data || []); + }); + } else if (buyerCategory === "stewards") { + dispatch( + slaughterGetStewardsForAllocateService({ + free: true, + role_key: + checkPathStartsWith("slaughter") || checkPathStartsWith("steward") + ? selectedSubUser?.key || "" + : "", + }) + ).then((r) => { + setStewardsData(r.payload.data || []); + }); + } + } + }, [buyerCategory, selectedSubUser?.key, editData]); + + useEffect(() => { + if ( + calendarRawData.governmental.length > 0 || + calendarRawData.free.length > 0 + ) { + const dataToShow = + approvedStatus === "governmental" + ? calendarRawData.governmental + : calendarRawData.free; + updateCalendarData(dataToShow); + setSelectedCalendarDate(null); + setProductionDate(null); + setSelectedDateAmount(null); + } + }, [approvedStatus, calendarRawData, updateCalendarData]); + + useEffect(() => { + formik.validateForm(); + }, [selectedDateAmount]); + + // Set segmentType to "own" for Guilds role + useEffect(() => { + const currentRole = getRoleFromUrl(); + if (currentRole === "Guilds" && !editData) { + setSegmentType("own"); + formik.setFieldValue("segmentType", "own"); + } + }, [editData]); + + return ( + + +
    + {!editData && getRoleFromUrl() !== "Guilds" && ( + + + + } + label="قطعه بندی (کاربر)" + /> + } + label="تخصیص به قطعه بند" + /> + + + + )} + + {!editData && segmentType === "free" && ( + <> + + + + } + label="مباشرین" + /> + } + label="اصناف" + /> + + + + + {buyerCategory && ( + + {(() => { + const currentData = + buyerCategory === "guilds" ? guildsData : stewardsData; + const isEmpty = !currentData || currentData.length === 0; + + if (isEmpty) { + return ( + + {buyerCategory === "guilds" + ? "هیچ صنفی یافت نشد" + : "هیچ مباشری یافت نشد"} + + ); + } + + return ( + { + return { + data: i, + label: `${i?.guildsName} ${i?.user?.fullname} (${i?.user?.mobile})`, + }; + }) + : stewardsData.map((i) => { + return { + data: i, + label: `${i?.name || ""} - ${ + i?.user?.fullname || "" + } (${i?.user?.mobile || ""})`, + }; + }) + } + onChange={(event, value) => { + if (buyerCategory === "guilds") { + setBuyerData({ + item: value?.data, + key: value?.data?.key, + allocationType: value?.data?.steward + ? "steward_steward" + : "steward_guild", + buyerType: value?.data?.steward + ? "Steward" + : "Guild", + }); + } else if (buyerCategory === "stewards") { + setBuyerData({ + item: value?.data, + key: value?.data?.key, + allocationType: "steward_steward", + buyerType: "Steward", + }); + } + }} + renderInput={(params) => ( + + )} + /> + ); + })()} + + )} + + )} + + {/* {!editData && ( + + + + } + label="قیمت دولتی" + /> + } + label="قیمت آزاد" + /> + + + + )} */} + {!editData && ( + + + + } + label="دولتی" + /> + } + label="آزاد" + /> + + + + )} + {!editData && ( + + + + )} + + کیلوگرم + ), + }} + value={formik.values.weight} + onChange={formik.handleChange} + onBlur={formik.handleBlur} + error={ + (formik.touched.weight && Boolean(formik.errors.weight)) || + (selectedDateAmount && formik.values.weight > selectedDateAmount) + } + helperText={ + selectedDateAmount && formik.values.weight > selectedDateAmount + ? `وزن نمی‌تواند بیشتر از موجودی تاریخ تولید (${selectedDateAmount?.toLocaleString()} کیلوگرم) باشد!` + : formik.touched.weight && formik.errors.weight + } + fullWidth + /> + + + + + + + + + + +
    +
    + ); +}; diff --git a/src/features/guild/components/guild-psp-devices/AddAccessLevelModal.js b/src/features/guild/components/guild-psp-devices/AddAccessLevelModal.js new file mode 100644 index 0000000..f3db663 --- /dev/null +++ b/src/features/guild/components/guild-psp-devices/AddAccessLevelModal.js @@ -0,0 +1,141 @@ +import { useContext, useState } from "react"; +import { useDispatch } from "react-redux"; +import { + Button, + FormControl, + Grid, + InputLabel, + MenuItem, + Select, + Typography, +} from "@mui/material"; +import axios from "axios"; +import { AppContext } from "../../../../contexts/AppContext"; +import { CLOSE_MODAL } from "../../../../lib/redux/slices/appSlice"; +import { SPACING } from "../../../../data/spacing"; +import { getFaUserRole } from "../../../../utils/getFaUserRole"; + +export const AddAccessLevelModal = ({ device, onSuccess }) => { + const dispatch = useDispatch(); + const [openNotif] = useContext(AppContext); + const [selectedAccessLevel, setSelectedAccessLevel] = useState(""); + const [submitting, setSubmitting] = useState(false); + + const accessLevelOptions = ["Steward", "KillHouse", "Guilds"]; + + const handleCloseModal = () => { + dispatch(CLOSE_MODAL()); + }; + + const handleSubmit = async () => { + if (!selectedAccessLevel) { + openNotif({ + vertical: "top", + horizontal: "center", + severity: "error", + msg: "لطفاً یک سطح دسترسی را انتخاب کنید.", + }); + return; + } + + if (!device?.key && !device?.id) { + openNotif({ + vertical: "top", + horizontal: "center", + severity: "error", + msg: "شناسه دستگاه یافت نشد. لطفاً دوباره تلاش کنید.", + }); + return; + } + + setSubmitting(true); + try { + const payload = { + pos_key: device?.key || device?.id, + name: selectedAccessLevel, + }; + + await axios.post("/pos-access-level/", payload); + + openNotif({ + vertical: "top", + horizontal: "center", + severity: "success", + msg: "سطح دسترسی با موفقیت افزوده شد.", + }); + + if (onSuccess) { + onSuccess(); + } + handleCloseModal(); + } catch (error) { + openNotif({ + vertical: "top", + horizontal: "center", + severity: "error", + msg: + error?.response?.data?.result || + error?.response?.data?.detail || + "افزودن سطح دسترسی با خطا مواجه شد.", + }); + } finally { + setSubmitting(false); + } + }; + + return ( + + + دستگاه انتخاب شده:{" "} + {device?.serial || + device?.pos_unique_id || + device?.pos_id || + device?.posId || + "-"} + + + سطح دسترسی + + + + + + + + ); +}; diff --git a/src/features/guild/components/guild-psp-devices/AssignSubUserModal.js b/src/features/guild/components/guild-psp-devices/AssignSubUserModal.js new file mode 100644 index 0000000..7446ef9 --- /dev/null +++ b/src/features/guild/components/guild-psp-devices/AssignSubUserModal.js @@ -0,0 +1,354 @@ +import { useContext, useEffect, useState } from "react"; +import { useDispatch, useSelector } from "react-redux"; +import { + Autocomplete, + Button, + CircularProgress, + FormControl, + FormControlLabel, + Grid, + MenuItem, + Radio, + RadioGroup, + Select, + TextField, + Typography, +} from "@mui/material"; +import axios from "axios"; +import { AppContext } from "../../../../contexts/AppContext"; +import { CLOSE_MODAL } from "../../../../lib/redux/slices/appSlice"; +import { LabelField } from "../../../../components/label-field/LabelField"; +import { SPACING } from "../../../../data/spacing"; +import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl"; +import { getFaUserRole } from "../../../../utils/getFaUserRole"; +import { checkPathStartsWith } from "../../../../utils/checkPathStartsWith"; + +export const AssignSubUserModal = ({ device, onSuccess }) => { + const dispatch = useDispatch(); + const [openNotif] = useContext(AppContext); + const [options, setOptions] = useState([]); + const [selectedUser, setSelectedUser] = useState(null); + const [selectedAccessLevel, setSelectedAccessLevel] = useState(""); + const [loading, setLoading] = useState(false); + const [submitting, setSubmitting] = useState(false); + const [fetchError, setFetchError] = useState(""); + const [userType, setUserType] = useState("delegate"); + const selectedSubUser = useSelector( + (state) => state.userSlice.selectedSubUser + ); + useEffect(() => { + let isMounted = true; + + const fetchUsers = async () => { + setLoading(true); + setFetchError(""); + setSelectedUser(null); + setSelectedAccessLevel(""); + try { + let response; + const role = getRoleFromUrl(); + + if (userType === "delegate") { + response = await axios.get( + `/get_representatives/?role=${role}${ + checkPathStartsWith("slaughter") || checkPathStartsWith("steward") + ? `&role_key=${selectedSubUser?.key}` + : "" + }` + ); + } else { + response = await axios.get( + `/get_dispensers/?role=${role}${ + checkPathStartsWith("slaughter") || checkPathStartsWith("steward") + ? `&role_key=${selectedSubUser?.key}` + : "" + }` + ); + } + + if (isMounted) { + const rawOptions = Array.isArray(response?.data?.results) + ? response?.data?.results + : Array.isArray(response?.data) + ? response?.data + : Array.isArray(response?.data?.data) + ? response?.data?.data + : Array.isArray(response) + ? response + : []; + + // Normalize the data - both delegates and dispensers have the same structure + const normalizedOptions = rawOptions.map((item) => { + const fullname = item?.fullname || "-"; + const mobile = item?.mobile || ""; + const mobileLabel = mobile ? ` (${mobile})` : ""; + const label = `${fullname}${mobileLabel}`; + + return { + ...item, + label: label || "-", + }; + }); + + setOptions(normalizedOptions); + } + } catch (error) { + if (isMounted) { + setFetchError("دریافت لیست کاربران با خطا مواجه شد."); + console.error("Error fetching users:", error); + } + } finally { + if (isMounted) { + setLoading(false); + } + } + }; + + fetchUsers(); + + return () => { + isMounted = false; + }; + }, [userType, selectedSubUser?.key]); + + const handleCloseModal = () => { + dispatch(CLOSE_MODAL()); + }; + + const getSubAccessLevels = (user) => { + if (!user) return []; + + const subAccessLevels = []; + + // Common excluded boolean fields that are not access levels + const excludedFields = [ + "active", + "trash", + "deleted", + "isActive", + "isDeleted", + ]; + + // Get all boolean fields that represent sub access levels + // These are fields in the object that are boolean and indicate sub access levels + Object.keys(user).forEach((key) => { + if (typeof user[key] === "boolean" && user[key] === true) { + // Exclude common boolean fields that aren't access levels + if (!excludedFields.includes(key.toLowerCase())) { + // Use getFaUserRole to get the Persian translation + const translatedLabel = getFaUserRole(key); + subAccessLevels.push({ + key: key, + label: translatedLabel || key, + }); + } + } + }); + + return subAccessLevels; + }; + + const handleSubmit = async () => { + if (!selectedUser) { + openNotif({ + vertical: "top", + horizontal: "center", + severity: "error", + msg: "لطفاً یک کاربر را انتخاب کنید.", + }); + return; + } + + if (!device?.key && !device?.id) { + openNotif({ + vertical: "top", + horizontal: "center", + severity: "error", + msg: "شناسه دستگاه یافت نشد. لطفاً دوباره تلاش کنید.", + }); + return; + } + + setSubmitting(true); + try { + const payload = { + key: device?.key || device?.id, + recipient_type: + userType === "delegate" ? "representative" : "dispenser", + recipient_key: selectedUser?.key || selectedUser?.id, + }; + + await axios.put("/user-pos-machine/0/", payload); + + openNotif({ + vertical: "top", + horizontal: "center", + severity: "success", + msg: "دستگاه با موفقیت به کاربر فرعی اختصاص داده شد.", + }); + + if (onSuccess) { + onSuccess(); + } + handleCloseModal(); + } catch (error) { + openNotif({ + vertical: "top", + horizontal: "center", + severity: "error", + msg: + error?.response?.data?.result || + error?.response?.data?.detail || + "اختصاص دستگاه با خطا مواجه شد.", + }); + } finally { + setSubmitting(false); + } + }; + + const selectedUserSubAccessLevels = selectedUser + ? getSubAccessLevels(selectedUser) + : []; + + return ( + + + دستگاه انتخاب شده:{" "} + {device?.serial || + device?.pos_unique_id || + device?.pos_id || + device?.posId || + "-"} + + + + setUserType(e.target.value)} + > + } + label="نماینده‌ها" + /> + } + label="پخش‌کنندگان" + /> + + + + {loading ? ( + + + + ) : ( + { + setSelectedUser(value); + setSelectedAccessLevel(""); + }} + isOptionEqualToValue={(option, value) => + option?.key === value?.key || option?.id === value?.id + } + getOptionLabel={(option) => option?.label || ""} + renderOption={(props, option) => { + if (!option) return null; + return ( +
  • + + + {option?.label || "-"} + + {option?.city && ( + + {option.city} + + )} + +
  • + ); + }} + renderInput={(params) => ( + + {loading ? ( + + ) : null} + {params.InputProps.endAdornment} + + ), + }} + /> + )} + /> + )} + {fetchError && ( + + {fetchError} + + )} + {selectedUser && selectedUserSubAccessLevels.length > 0 && ( + + + + )} + + + + +
    + ); +}; diff --git a/src/features/guild/components/guild-psp-devices/DeviceOperations.js b/src/features/guild/components/guild-psp-devices/DeviceOperations.js new file mode 100644 index 0000000..cb4ac01 --- /dev/null +++ b/src/features/guild/components/guild-psp-devices/DeviceOperations.js @@ -0,0 +1,266 @@ +import { useContext, useState } from "react"; +import { useDispatch } from "react-redux"; +import { + Box, + Grid, + IconButton, + List, + ListItemButton, + ListItemIcon, + ListItemText, + Popover, + Typography, + Button, +} from "@mui/material"; +import TuneIcon from "@mui/icons-material/Tune"; +import PersonAddAlt1RoundedIcon from "@mui/icons-material/PersonAddAlt1Rounded"; +import AddIcon from "@mui/icons-material/Add"; +import EditIcon from "@mui/icons-material/Edit"; +import DeleteIcon from "@mui/icons-material/Delete"; +import { AppContext } from "../../../../contexts/AppContext"; +import { + LOADING_START, + LOADING_END, + CLOSE_MODAL, + OPEN_MODAL, +} from "../../../../lib/redux/slices/appSlice"; +import axios from "axios"; +import { getFaUserRole } from "../../../../utils/getFaUserRole"; +import { AssignSubUserModal } from "./AssignSubUserModal"; +import { AddAccessLevelModal } from "./AddAccessLevelModal"; +import { EditSubSectionsModal } from "./EditSubSectionsModal"; + +export const DeviceOperations = ({ + device, + onSubUserAssigned, + fetchApiData, + page, +}) => { + const [anchorEl, setAnchorEl] = useState(null); + const dispatch = useDispatch(); + const [openNotif] = useContext(AppContext); + + const handleOpen = (event) => { + setAnchorEl(event.currentTarget); + }; + + const handleClose = () => { + setAnchorEl(null); + }; + + const handleAssignSubUser = () => { + handleClose(); + dispatch( + OPEN_MODAL({ + title: "اختصاص دستگاه به کاربر فرعی", + width: "auto", + content: ( + + ), + }) + ); + }; + + const handleAddAccessLevel = () => { + handleClose(); + dispatch( + OPEN_MODAL({ + title: "افزودن سطح دسترسی", + width: "auto", + content: ( + + ), + }) + ); + }; + + const handleEditSubSections = (accessLevel) => { + handleClose(); + dispatch( + OPEN_MODAL({ + title: "ویرایش زیربخش‌های سطح دسترسی", + width: "auto", + content: ( + fetchApiData(page)} + /> + ), + }) + ); + }; + + const handleDeleteAccessLevel = (accessLevel) => { + handleClose(); + dispatch( + OPEN_MODAL({ + title: "حذف سطح دسترسی", + size: 320, + content: ( + + + + آیا از حذف سطح دسترسی{" "} + {getFaUserRole(accessLevel?.name) || accessLevel?.name} مطمئن + هستید؟ + + + + + + + + + + ), + }) + ); + }; + + const open = Boolean(anchorEl); + const id = open ? "device-operations-popover" : undefined; + + const accessLevels = Array.isArray(device?.accessLevels) + ? device.accessLevels.filter((level) => !level?.trash) + : []; + + return ( + <> + + + + + + + + + + + + + + + + + + {accessLevels.length > 0 && ( + <> + + + مدیریت سطح دسترسی: + + + {accessLevels.map((level, idx) => ( + + + + {getFaUserRole(level?.name) || level?.name || "-"} + + + handleEditSubSections(level)} + > + + + handleDeleteAccessLevel(level)} + > + + + + + + ))} + + )} + + + + ); +}; diff --git a/src/features/guild/components/guild-psp-devices/EditSubSectionsModal.js b/src/features/guild/components/guild-psp-devices/EditSubSectionsModal.js new file mode 100644 index 0000000..3cc4cd1 --- /dev/null +++ b/src/features/guild/components/guild-psp-devices/EditSubSectionsModal.js @@ -0,0 +1,202 @@ +import { useContext, useState } from "react"; +import { useDispatch } from "react-redux"; +import { + Button, + Checkbox, + FormControlLabel, + Grid, + Typography, +} from "@mui/material"; +import axios from "axios"; +import { AppContext } from "../../../../contexts/AppContext"; +import { CLOSE_MODAL } from "../../../../lib/redux/slices/appSlice"; +import { LabelField } from "../../../../components/label-field/LabelField"; +import { SPACING } from "../../../../data/spacing"; +import { getFaUserRole } from "../../../../utils/getFaUserRole"; + +export const EditSubSectionsModal = ({ accessLevel, device, onSuccess }) => { + const dispatch = useDispatch(); + const [openNotif] = useContext(AppContext); + const [submitting, setSubmitting] = useState(false); + const [values, setValues] = useState({ + in_province_sale: accessLevel?.in_province_sale || false, + out_province_sale: accessLevel?.out_province_sale || false, + cutting: accessLevel?.cutting || false, + freezing: accessLevel?.freezing || false, + warehouse: accessLevel?.warehouse || false, + retail: accessLevel?.retail || false, + }); + + const handleCloseModal = () => { + dispatch(CLOSE_MODAL()); + }; + + const handleChange = (field) => (event) => { + setValues((prev) => ({ + ...prev, + [field]: event.target.checked, + })); + }; + + const handleSubmit = async () => { + if (!accessLevel?.key) { + openNotif({ + vertical: "top", + horizontal: "center", + severity: "error", + msg: "شناسه سطح دسترسی یافت نشد. لطفاً دوباره تلاش کنید.", + }); + return; + } + + setSubmitting(true); + try { + const payload = { + key: accessLevel.key, + in_province_sale: values.in_province_sale, + out_province_sale: values.out_province_sale, + cutting: values.cutting, + freezing: values.freezing, + warehouse: values.warehouse, + retail: values.retail, + }; + + await axios.put("/pos-access-level/0/", payload); + + openNotif({ + vertical: "top", + horizontal: "center", + severity: "success", + msg: "زیربخش‌های سطح دسترسی با موفقیت ویرایش شد.", + }); + + if (onSuccess) { + onSuccess(); + } + handleCloseModal(); + } catch (error) { + openNotif({ + vertical: "top", + horizontal: "center", + severity: "error", + msg: + error?.response?.data?.result || + error?.response?.data?.detail || + "ویرایش زیربخش‌ها با خطا مواجه شد.", + }); + } finally { + setSubmitting(false); + } + }; + + return ( + + + سطح دسترسی:{" "} + {getFaUserRole(accessLevel?.name) || accessLevel?.name || "-"} + + + دستگاه:{" "} + {device?.serial || + device?.pos_unique_id || + device?.pos_id || + device?.posId || + "-"} + + + + + + } + label="فروش داخل استان" + /> + + + + } + label="فروش خارج استان" + /> + + + + } + label="قطعه بندی" + /> + + + + } + label="انجماد" + /> + + + + } + label="انبار" + /> + + + + } + label="خرده‌فروشی" + /> + + + + + + + + + ); +}; diff --git a/src/features/guild/components/guild-psp-devices/GuildPspDevices.js b/src/features/guild/components/guild-psp-devices/GuildPspDevices.js new file mode 100644 index 0000000..d639e0b --- /dev/null +++ b/src/features/guild/components/guild-psp-devices/GuildPspDevices.js @@ -0,0 +1,284 @@ +import { useEffect, useState } from "react"; +import { useDispatch, useSelector } from "react-redux"; +import { + LOADING_END, + LOADING_START, +} from "../../../../lib/redux/slices/appSlice"; +import axios from "axios"; +import { Grid } from "../../../../components/grid/Grid"; +import { SPACING } from "../../../../data/spacing"; +import { BackButton } from "../../../../components/back-button/BackButton"; +import { Autocomplete, Button, TextField, Box, Chip } from "@mui/material"; +import { RiSearchLine } from "react-icons/ri"; +import ResponsiveTable from "../../../../components/responsive-table/ResponsiveTable"; +import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl"; +import { formatJustDate } from "../../../../utils/formatTime"; +import { getFaUserRole } from "../../../../utils/getFaUserRole"; +import { DeviceOperations } from "./DeviceOperations"; +import { Lock } from "@mui/icons-material"; +import { checkPathStartsWith } from "../../../../utils/checkPathStartsWith"; + +const GuildPspDevices = () => { + const [data, setData] = useState([]); + const [totalRows, setTotalRows] = useState(0); + const [perPage, setPerPage] = useState(10); + const [textValue, setTextValue] = useState(""); + const [page, setPage] = useState(1); + const [tableData, setTableData] = useState([]); + const [brands, setBrands] = useState([]); + const [selectedBrand, setSelectedBrand] = useState(""); + const selectedSubUser = useSelector( + (state) => state.userSlice.selectedSubUser + ); + const dispatch = useDispatch(); + + const fetchBrands = async () => { + try { + dispatch(LOADING_START()); + const response = await axios.get( + `/get_all_pos_company/?role=${getRoleFromUrl()}${ + checkPathStartsWith("slaughter") || checkPathStartsWith("steward") + ? `&role_key=${selectedSubUser?.key}` + : "" + }` + ); + setBrands(response.data); + dispatch(LOADING_END()); + } catch (error) { + console.error("Error fetching brands:", error); + dispatch(LOADING_END()); + } + }; + + const canDoAction = (item) => { + if (item?.owner?.role?.includes("KillHouse")) { + return getRoleFromUrl() === "KillHouse"; + } + if (item?.owner?.includes("Steward")) { + return getRoleFromUrl() === "Steward"; + } + return false; + }; + + const fetchApiData = async (page) => { + try { + dispatch(LOADING_START()); + let url = `/user-pos-machine/?search=filter&value=${textValue}&role=${getRoleFromUrl()}${ + checkPathStartsWith("slaughter") || checkPathStartsWith("steward") + ? `&role_key=${selectedSubUser?.key}` + : "" + }&page=${page}&page_size=${perPage}`; + if (selectedBrand) { + url += `&company=${selectedBrand}`; + } + const response = await axios.get(url); + + setData(response.data?.results || []); + setTotalRows(response.data?.count || 0); + } catch (error) { + console.error("Error fetching devices:", error); + } finally { + dispatch(LOADING_END()); + } + }; + + const handlePageChange = (page) => { + fetchApiData(page); + setPage(page); + }; + + const handlePerRowsChange = (perRows) => { + setPerPage(perRows); + setPage(1); + }; + + const handleTextChange = (event) => { + setTextValue(event.target.value); + }; + + useEffect(() => { + const d = data?.map((item, i) => { + const owner = item?.owner || {}; + const posCompany = item?.posCompany || {}; + + // Format recipient information + const recipientDisplay = item?.recipient + ? `${item?.recipient?.firstName || ""} ${ + item?.recipient?.lastName || "" + }`.trim() + + (item?.recipient?.mobile + ? ` (${item?.recipient?.mobile} - ${ + item?.recipient?.agentType === "dispenser" + ? "توزیع کننده" + : "نماینده" + })` + : "") + : "-"; + + // Format access_levels to display as chips only (filter out trash items) + const activeAccessLevels = Array.isArray(item?.accessLevels) + ? item.accessLevels.filter((level) => !level?.trash) + : []; + const accessLevelsDisplay = + activeAccessLevels.length > 0 ? ( + + {activeAccessLevels.map((level, idx) => ( + + ))} + + ) : ( + "-" + ); + + return [ + page === 1 ? i + 1 : i + perPage * (page - 1) + 1, + posCompany?.name || "-", + item?.serial ?? "-", + item?.receiverNumber ?? "-", + item?.terminalNumber ?? "-", + item?.password ?? "-", + item?.posUniqueId || item?.posId || "-", + owner?.fullname ? `${owner?.fullname} (${owner?.mobile ?? "-"})` : "-", + owner?.nationalId || owner?.nationalCode || "-", + item?.createDate ? formatJustDate(item?.createDate) : "-", + accessLevelsDisplay, + recipientDisplay, + item?.active ? "فعال" : "غیرفعال", + canDoAction(item) ? ( + + ) : ( + + ), + ]; + }); + + setTableData(d); + }, [data, page, perPage]); + + useEffect(() => { + fetchBrands(); + }, [dispatch, selectedSubUser?.key]); + + useEffect(() => { + fetchApiData(page); + }, [selectedBrand, perPage, selectedSubUser?.key]); + + const handleSubmit = async (event) => { + event.preventDefault(); + fetchApiData(1); + }; + + const tableTitle = ( + + + + { + return { + data: i, + label: `${i?.name || ""}`, + }; + }) + : [] + } + onChange={(event, value) => { + setSelectedBrand(value?.data?.key); + }} + renderInput={(params) => ( + + )} + /> + + + + + + + + + + ); + + return ( + + + + {tableTitle} + + + + ); +}; + +export default GuildPspDevices; diff --git a/src/features/guild/services/guilDeleteFreeBar.js b/src/features/guild/services/guilDeleteFreeBar.js new file mode 100644 index 0000000..d65c4f1 --- /dev/null +++ b/src/features/guild/services/guilDeleteFreeBar.js @@ -0,0 +1,20 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const guildDeleteFreeBar = createAsyncThunk( + "GUILD_DELETE_FREE_BAR", + async (id, { dispatch }) => { + dispatch(LOADING_START()); + try { + const { data, status } = await axios.delete( + "/steward_free_bar/0/?key=" + id + ); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e.response.data.result }; + } + } +); diff --git a/src/features/guild/services/guild-allocated-stock-operation.js b/src/features/guild/services/guild-allocated-stock-operation.js new file mode 100644 index 0000000..b54fed3 --- /dev/null +++ b/src/features/guild/services/guild-allocated-stock-operation.js @@ -0,0 +1,18 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const guildAllocatedStockOperationService = createAsyncThunk( + "GUILD_ALLOCATED_STOCK_OPERATION_SERVICE", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + try { + const { data, status } = await axios.put("steward-allocation/0/", d); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e.response.data.result }; + } + } +); diff --git a/src/features/guild/services/guild-auth-code-submit.js b/src/features/guild/services/guild-auth-code-submit.js new file mode 100644 index 0000000..ab6800a --- /dev/null +++ b/src/features/guild/services/guild-auth-code-submit.js @@ -0,0 +1,21 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const guildAuthCodeSubmitService = createAsyncThunk( + "GUILD_AUTH_CODE_SUBMIT_SERVICE", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + try { + const { data, status } = await axios.put( + "steward-guild-allocation/0/", + d + ); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e.response.data.result }; + } + } +); diff --git a/src/features/guild/services/guild-delete-free-sale.js b/src/features/guild/services/guild-delete-free-sale.js new file mode 100644 index 0000000..171953b --- /dev/null +++ b/src/features/guild/services/guild-delete-free-sale.js @@ -0,0 +1,20 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const guildDeleteOutOfProvinceSell = createAsyncThunk( + "GUILD_DELETE_OUT_OF_PROVINCE_SELL", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + try { + const { data, status } = await axios.delete( + `steward_free_sale_bar/0/?key=${d}` + ); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e.response.data.result }; + } + } +); diff --git a/src/features/guild/services/guild-edit-free-bar.js b/src/features/guild/services/guild-edit-free-bar.js new file mode 100644 index 0000000..e39e000 --- /dev/null +++ b/src/features/guild/services/guild-edit-free-bar.js @@ -0,0 +1,18 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const guildEditFreeBar = createAsyncThunk( + "GUILD_EDIT_FREE_BAR", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + try { + const { data, status } = await axios.put("steward_free_bar/0/", d); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e.response.data.result }; + } + } +); diff --git a/src/features/guild/services/guild-get-free-bars.js b/src/features/guild/services/guild-get-free-bars.js new file mode 100644 index 0000000..9a046c3 --- /dev/null +++ b/src/features/guild/services/guild-get-free-bars.js @@ -0,0 +1,15 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const guildGetFreeBars = createAsyncThunk( + "GUILD_GET_FREE_BARS", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + const { data, status } = await axios.get("steward_free_bar/", { + params: { date: d.date }, + }); + dispatch(LOADING_END()); + return { data, status }; + } +); diff --git a/src/features/guild/services/guild-get-free-sale-bar.js b/src/features/guild/services/guild-get-free-sale-bar.js new file mode 100644 index 0000000..020a78f --- /dev/null +++ b/src/features/guild/services/guild-get-free-sale-bar.js @@ -0,0 +1,15 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const guildGetFreeSaleBarService = createAsyncThunk( + "GUILD_GET_FREE_SALE_BARS", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + const { data, status } = await axios.get("steward_free_sale_bar/", { + params: d, + }); + dispatch(LOADING_END()); + return { data, status }; + } +); diff --git a/src/features/guild/services/guild-get-guilds.js b/src/features/guild/services/guild-get-guilds.js new file mode 100644 index 0000000..54cbfc8 --- /dev/null +++ b/src/features/guild/services/guild-get-guilds.js @@ -0,0 +1,19 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { getRoleFromUrl } from "../../../utils/getRoleFromUrl"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const guildGetStewardsService = createAsyncThunk( + "GUILD_GET_GUILDS_SERVICE", + async (id, { dispatch }) => { + dispatch(LOADING_START()); + const { data, status } = await axios.get( + "guilds/?other_guilds_for_steward=true/", + { + params: { role: getRoleFromUrl() }, + } + ); + dispatch(LOADING_END()); + return { data, status }; + } +); diff --git a/src/features/guild/services/guild-get-inventory-allocated.js b/src/features/guild/services/guild-get-inventory-allocated.js new file mode 100644 index 0000000..9c4378a --- /dev/null +++ b/src/features/guild/services/guild-get-inventory-allocated.js @@ -0,0 +1,15 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const guildGetInventoryAllocatedService = createAsyncThunk( + "GUILD_GET_INVENTORY_ALLOCATED_SERVICE", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + const { data, status } = await axios.get("steward-allocation/", { + params: { date: d.date, steward: true, role_key: d.role_key || "" }, + }); + dispatch(LOADING_END()); + return { data, status }; + } +); diff --git a/src/features/guild/services/guild-get-inventory-stock.js b/src/features/guild/services/guild-get-inventory-stock.js new file mode 100644 index 0000000..5fc9aa2 --- /dev/null +++ b/src/features/guild/services/guild-get-inventory-stock.js @@ -0,0 +1,15 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const guildGetInventoryStockService = createAsyncThunk( + "GUILD_GET_INVENTORY_STOCK_SERVICE", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + const { data, status } = await axios.get("steward_warehouse/", { + params: { date: d.date, role_key: d.role_key || "" }, + }); + dispatch(LOADING_END()); + return { data, status }; + } +); diff --git a/src/features/guild/services/guild-get-profile.js b/src/features/guild/services/guild-get-profile.js new file mode 100644 index 0000000..d1e6e43 --- /dev/null +++ b/src/features/guild/services/guild-get-profile.js @@ -0,0 +1,10 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; + +export const guildGetProfile = createAsyncThunk( + "GUILD_GET_PROFILE", + async () => { + const { data, status } = await axios.get("guilds/0/?profile"); + return { data, status }; + } +); diff --git a/src/features/guild/services/guild-get-stewards.js b/src/features/guild/services/guild-get-stewards.js new file mode 100644 index 0000000..1b898b1 --- /dev/null +++ b/src/features/guild/services/guild-get-stewards.js @@ -0,0 +1,18 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const guildGetStewards = createAsyncThunk( + "GUILD_GET_STEWARDS", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + const { data, status } = await axios.get("guilds/", { + params: { + date: d.date, + steward_sub_guilds: true, + }, + }); + dispatch(LOADING_END()); + return { data, status }; + } +); diff --git a/src/features/guild/services/guild-sales-info-dashboard.js b/src/features/guild/services/guild-sales-info-dashboard.js new file mode 100644 index 0000000..ec43597 --- /dev/null +++ b/src/features/guild/services/guild-sales-info-dashboard.js @@ -0,0 +1,24 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; +import { getRoleFromUrl } from "../../../utils/getRoleFromUrl"; + +export const guildSalesInfoDashboardService = createAsyncThunk( + "GUILD_SALES_INFO_DASHBOARD_SERVICE", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + try { + const { data, status } = await axios.get("guild-sales-info-dashboard/", { + params: { + role: d.role || getRoleFromUrl(), + role_key: d.role_key || "", + }, + }); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e.response?.data?.result }; + } + } +); diff --git a/src/features/guild/services/guild-submit-free-bar.js b/src/features/guild/services/guild-submit-free-bar.js new file mode 100644 index 0000000..76b8093 --- /dev/null +++ b/src/features/guild/services/guild-submit-free-bar.js @@ -0,0 +1,18 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const guildSubmitFreeBar = createAsyncThunk( + "GUILD_SUBMIT_FREE_BAR", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + try { + const { data, status } = await axios.post("steward_free_bar/", d); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e.response.data.result }; + } + } +); diff --git a/src/features/guild/services/guild-update-allocated-stock.js b/src/features/guild/services/guild-update-allocated-stock.js new file mode 100644 index 0000000..3776626 --- /dev/null +++ b/src/features/guild/services/guild-update-allocated-stock.js @@ -0,0 +1,18 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const guildUpdateAllocatedStockService = createAsyncThunk( + "GUILD_UPDATE_ALLOCATED_STOCK_SERVICE", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + try { + const { data, status } = await axios.put("steward-allocation/0/", d); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e.response.data.result }; + } + } +); diff --git a/src/features/guild/services/guildDeleteAllocatedService.js b/src/features/guild/services/guildDeleteAllocatedService.js new file mode 100644 index 0000000..4182bee --- /dev/null +++ b/src/features/guild/services/guildDeleteAllocatedService.js @@ -0,0 +1,17 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const guildDeleteAllocatedService = createAsyncThunk( + "GUILD_DELETE_ALLOCATED_SERVICE", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + const { data, status } = await axios.delete("steward-guild-allocation/0/", { + params: { + steward_allocation_key: d.steward_allocation_key, + }, + }); + dispatch(LOADING_END()); + return { data, status }; + } +); diff --git a/src/features/guild/services/guildEditAllocateStewardService.js b/src/features/guild/services/guildEditAllocateStewardService.js new file mode 100644 index 0000000..715f194 --- /dev/null +++ b/src/features/guild/services/guildEditAllocateStewardService.js @@ -0,0 +1,21 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const GuildEditAllocateStewardService = createAsyncThunk( + "GUILD_EDIT_ALLOCATE_STEWARD_SERVICE", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + try { + const { data, status } = await axios.put( + "steward-guild-allocation/0/", + d + ); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e.response.data.result }; + } + } +); diff --git a/src/features/guild/services/guildGetAllocationData.js b/src/features/guild/services/guildGetAllocationData.js new file mode 100644 index 0000000..be6eaa8 --- /dev/null +++ b/src/features/guild/services/guildGetAllocationData.js @@ -0,0 +1,20 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const guildGetAllocationData = createAsyncThunk( + "GUILD_GET_ALLOCATION_DATA", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + const { data, status } = await axios.get( + "steward-allocation/?steward_guilds_allocations=true/", + { + params: { + date: d.date, + }, + } + ); + dispatch(LOADING_END()); + return { data, status }; + } +); diff --git a/src/features/guild/services/guildInventoryFinalSubmitService.js b/src/features/guild/services/guildInventoryFinalSubmitService.js new file mode 100644 index 0000000..971985f --- /dev/null +++ b/src/features/guild/services/guildInventoryFinalSubmitService.js @@ -0,0 +1,21 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const guildInventoryFinalSubmitService = createAsyncThunk( + "GUILD_INVENTORY_FINAL_SUBMIT_SERVICE", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + try { + const { data, status } = await axios.put( + "steward-guild-allocation/0/", + d + ); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e.response.data.result }; + } + } +); diff --git a/src/features/guild/services/senf-get-allocation-dashboard.js b/src/features/guild/services/senf-get-allocation-dashboard.js new file mode 100644 index 0000000..239d67c --- /dev/null +++ b/src/features/guild/services/senf-get-allocation-dashboard.js @@ -0,0 +1,15 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const senfGetAllocationDashboardService = createAsyncThunk( + "SENF_GET_ALLOCATION_DASHBOARD_SERVICE", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + const { data, status } = await axios.get("guild-allocation-dashbord/", { + params: d, + }); + dispatch(LOADING_END()); + return { data, status }; + } +); diff --git a/src/features/guild/services/senf-get-inventory-allocated.js b/src/features/guild/services/senf-get-inventory-allocated.js new file mode 100644 index 0000000..a5ae66a --- /dev/null +++ b/src/features/guild/services/senf-get-inventory-allocated.js @@ -0,0 +1,23 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; +import { getRoleFromUrl } from "../../../utils/getRoleFromUrl"; + +export const senfGetInventoryAllocatedService = createAsyncThunk( + "SENF_GET_INVENTORY_ALLOCATED_SERVICE", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + const { data, status } = await axios.get("steward-allocation/", { + params: { + date1: d.date1, + date2: d.date2, + type: d.type || "", + role_key: d.role_key || "", + role: getRoleFromUrl(), + search: d.search, + }, + }); + dispatch(LOADING_END()); + return { data, status }; + } +); diff --git a/src/features/guild/services/senf-get-inventory-stock.js b/src/features/guild/services/senf-get-inventory-stock.js new file mode 100644 index 0000000..0022790 --- /dev/null +++ b/src/features/guild/services/senf-get-inventory-stock.js @@ -0,0 +1,15 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const senfGetInventoryStockService = createAsyncThunk( + "SENF_GET_INVENTORY_STOCK_SERVICE", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + const { data, status } = await axios.get("guilds_warehouse/", { + params: d, + }); + dispatch(LOADING_END()); + return { data, status }; + } +); diff --git a/src/features/guild/services/steward-edit-sell-out-buyer.js b/src/features/guild/services/steward-edit-sell-out-buyer.js new file mode 100644 index 0000000..ff42078 --- /dev/null +++ b/src/features/guild/services/steward-edit-sell-out-buyer.js @@ -0,0 +1,18 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; +import axios from "axios"; + +export const stewardEditBuyerDataService = createAsyncThunk( + "SLAUGHTER_EDIT_BUYER_SERVICE", + async (d, { dispatch }) => { + try { + dispatch(LOADING_START()); + const { data, status } = await axios.put("steward_free_sale_bar/0/", d); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e.response.data.result }; + } + } +); diff --git a/src/features/guild/services/steward-get-dashboard-service.js b/src/features/guild/services/steward-get-dashboard-service.js new file mode 100644 index 0000000..b517936 --- /dev/null +++ b/src/features/guild/services/steward-get-dashboard-service.js @@ -0,0 +1,18 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; +import axios from "axios"; + +export const stawardGetSegmentDashboardService = createAsyncThunk( + "STEWARD_GET_SEGMENT_DASHBOARD_SERVICE", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + const { data, status } = await axios.get("segmentation-dashboard/", { + params: { + search: "filter", + ...d, + }, + }); + dispatch(LOADING_END()); + return { data, status }; + } +); diff --git a/src/features/guild/services/steward-get-out-dashboard.js b/src/features/guild/services/steward-get-out-dashboard.js new file mode 100644 index 0000000..50d45dd --- /dev/null +++ b/src/features/guild/services/steward-get-out-dashboard.js @@ -0,0 +1,19 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; +import axios from "axios"; +import { getRoleFromUrl } from "../../../utils/getRoleFromUrl"; + +export const stawardGetOutDashboardService = createAsyncThunk( + "STEWARD-GET-OUT_DASHBOARD_SERVICE", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + const { data, status } = await axios.get("steward_free_bar_dashboard", { + params: { + ...d, + role: getRoleFromUrl(), + }, + }); + dispatch(LOADING_END()); + return { data, status }; + } +); diff --git a/src/features/guild/services/steward-get-segmant-role.js b/src/features/guild/services/steward-get-segmant-role.js new file mode 100644 index 0000000..aa35ad1 --- /dev/null +++ b/src/features/guild/services/steward-get-segmant-role.js @@ -0,0 +1,17 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; +import axios from "axios"; + +export const stawardGetSegmantRoleService = createAsyncThunk( + "STEWARD_GET_SEGMANT_ROLE_SERVICE", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + const { data, status } = await axios.get("guilds/?&all=true", { + params: { + ...d, + }, + }); + dispatch(LOADING_END()); + return { data, status }; + } +); diff --git a/src/features/guild/services/steward-get-sell-out-service.js b/src/features/guild/services/steward-get-sell-out-service.js new file mode 100644 index 0000000..5208da9 --- /dev/null +++ b/src/features/guild/services/steward-get-sell-out-service.js @@ -0,0 +1,19 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; +import axios from "axios"; +import { getRoleFromUrl } from "../../../utils/getRoleFromUrl"; + +export const stewardGetOutSellService = createAsyncThunk( + "STEWRD_GET_OUT_SELL_SERVICE", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + const { data, status } = await axios.get("roles-products", { + params: { + role: getRoleFromUrl(), + ...d, + }, + }); + dispatch(LOADING_END()); + return { data, status }; + } +); diff --git a/src/features/guild/services/steward-segment-delete-operation.js b/src/features/guild/services/steward-segment-delete-operation.js new file mode 100644 index 0000000..b4c7a76 --- /dev/null +++ b/src/features/guild/services/steward-segment-delete-operation.js @@ -0,0 +1,20 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; +import axios from "axios"; + +export const stewardDeleteSegmentService = createAsyncThunk( + "STEWARD_DELETE_SEGMENT", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + try { + const { data, status } = await axios.delete( + `app-segmentation/0/?key=${d}` + ); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e }; + } + } +); diff --git a/src/features/guild/services/steward-segment-edit-operation.js b/src/features/guild/services/steward-segment-edit-operation.js new file mode 100644 index 0000000..d6de9b4 --- /dev/null +++ b/src/features/guild/services/steward-segment-edit-operation.js @@ -0,0 +1,18 @@ +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; +import { createAsyncThunk } from "@reduxjs/toolkit"; + +export const stewardEditSegmentService = createAsyncThunk( + "STEWARD_EDIT_SEGMENT_SERVICE", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + try { + const { data, status } = await axios.put(`app-segmentation/0/`, d); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e.response?.data?.result }; + } + } +); diff --git a/src/features/guild/services/steward-segment-submit-service.js b/src/features/guild/services/steward-segment-submit-service.js new file mode 100644 index 0000000..d184bf0 --- /dev/null +++ b/src/features/guild/services/steward-segment-submit-service.js @@ -0,0 +1,18 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const stewardSegmentSubmitService = createAsyncThunk( + "STEWARD_SUBMIT_SEGMANT", + async (d, { dispatch }) => { + try { + dispatch(LOADING_START()); + const { data, status } = await axios.post("app-segmentation/", d); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e.response.data.result }; + } + } +); diff --git a/src/features/guild/services/steward-sell-out-delete-service.js b/src/features/guild/services/steward-sell-out-delete-service.js new file mode 100644 index 0000000..6e5bf01 --- /dev/null +++ b/src/features/guild/services/steward-sell-out-delete-service.js @@ -0,0 +1,20 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; +import axios from "axios"; + +export const stewardDeleteOutSellService = createAsyncThunk( + "STEWARD_DELETE_OUT_OF_PROVINCE_SELL", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + try { + const { data, status } = await axios.delete( + `steward_free_sale_bar/0/?key=${d}` + ); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e }; + } + } +); diff --git a/src/features/guild/services/steward-sell-out-get-buyers.js b/src/features/guild/services/steward-sell-out-get-buyers.js new file mode 100644 index 0000000..a0cdcc6 --- /dev/null +++ b/src/features/guild/services/steward-sell-out-get-buyers.js @@ -0,0 +1,41 @@ +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; +import { getRoleFromUrl } from "../../../utils/getRoleFromUrl"; +import { createAsyncThunk } from "@reduxjs/toolkit"; + +export const stewardSellOutGetBuyers = createAsyncThunk( + "STEWARD_GET_BUYERS_SELL_OUT", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + const { data, status } = await axios.get("out-province-carcasses-buyer/", { + params: { + role: getRoleFromUrl(), + role_key: d?.role_key || "", + mobile: d?.mobile, + }, + }); + dispatch(LOADING_END()); + return { data, status }; + } +); + +export const stewatdSubmitBuyerDataService = createAsyncThunk( + "STEWARD_SUBMIT_BUYER_SERVICE", + async (d, { dispatch }) => { + try { + dispatch(LOADING_START()); + const { data, status } = await axios.post( + "out-province-carcasses-buyer/", + { + ...d, + } + ); + + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e.response.data.result }; + } + } +); diff --git a/src/features/guild/services/steward-sell-out-get-dashboard.js b/src/features/guild/services/steward-sell-out-get-dashboard.js new file mode 100644 index 0000000..92ec464 --- /dev/null +++ b/src/features/guild/services/steward-sell-out-get-dashboard.js @@ -0,0 +1,24 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; +import axios from "axios"; +import { getRoleFromUrl } from "../../../utils/getRoleFromUrl"; + +export const stewardSellOutGetDashboard = createAsyncThunk( + "SLAUGHTRE_SELL_DASHBOARD", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + const { data, status } = await axios.get( + `steward_free_sale_bar_dashboard`, + { + params: { + date1: d.selectedDate1, + date2: d.selectedDate2, + role: getRoleFromUrl(), + role_key: d.role_key || "", + }, + } + ); + dispatch(LOADING_END()); + return { data, status }; + } +); diff --git a/src/features/guild/services/steward-sell-out-submit-sell.js b/src/features/guild/services/steward-sell-out-submit-sell.js new file mode 100644 index 0000000..6b465d0 --- /dev/null +++ b/src/features/guild/services/steward-sell-out-submit-sell.js @@ -0,0 +1,17 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; +import axios from "axios"; + +export const stewardSellOuutSubmitSell = createAsyncThunk( + "STEWARD_SELL_OUT_SUBMIT_SERVICE", + async (d, { dispatch }) => { + try { + const { data, status } = await axios.post(`steward_free_sale_bar/`, d); + dispatch(LOADING_START()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e.response.data.result }; + } + } +); diff --git a/src/features/guild/services/steward-submit-free-bar-service.js b/src/features/guild/services/steward-submit-free-bar-service.js new file mode 100644 index 0000000..f622102 --- /dev/null +++ b/src/features/guild/services/steward-submit-free-bar-service.js @@ -0,0 +1,50 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const stewardSubmitFreeBarService = createAsyncThunk( + "STEWARD_FREE_BAR_SERVICE", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + try { + const { data, status } = await axios.post("steward_free_bar/", d); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e.response?.data?.result }; + } + } +); + +export const stewardEditFreeBarService = createAsyncThunk( + "STEWARD_EDIT_FREE_BAR_SERVICE", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + try { + const { data, status } = await axios.put(`steward_free_bar/0/`, d); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e.response?.data?.result }; + } + } +); + +export const stewardDeleteFreeBarService = createAsyncThunk( + "STEWARD_DELETE_FREE_BAR_SERVICE", + async (key, { dispatch }) => { + dispatch(LOADING_START()); + try { + const { data, status } = await axios.delete( + `steward_free_bar/0/?key=${key}` + ); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e.response?.data?.result || "خطا در حذف اطلاعات" }; + } + } +); diff --git a/src/features/inspector/components/inspector-add-vet-to-kill-house/InspectorAddVetToKillHouse.js b/src/features/inspector/components/inspector-add-vet-to-kill-house/InspectorAddVetToKillHouse.js new file mode 100644 index 0000000..58fdf19 --- /dev/null +++ b/src/features/inspector/components/inspector-add-vet-to-kill-house/InspectorAddVetToKillHouse.js @@ -0,0 +1,141 @@ +import { Autocomplete, Button, TextField, Typography } from "@mui/material"; +import { useContext, useEffect, useState } from "react"; +import { useDispatch, useSelector } from "react-redux"; +import { Grid } from "../../../../components/grid/Grid"; +import { AppContext } from "../../../../contexts/AppContext"; +import { SPACING } from "../../../../data/spacing"; +import { DRAWER } from "../../../../lib/redux/slices/appSlice"; +import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl"; +import { inspectorDeleteKillhouseVetService } from "../../services/inspector-delete-killhouse-vet"; +import { inspectorGetKillHousesService } from "../../services/inspector-get-kill-houses"; +import { inspectorSetKillhouseVetService } from "../../services/inspector-set-killhouse-vet"; +import { manageFarmGetFarmsService } from "../../services/manage-farm-get-farms"; + +export const InspectorAddVetToKillHouse = ({ userKey, item }) => { + const dispatch = useDispatch(); + const [openNotif] = useContext(AppContext); + const { inspectorGetKillHouses } = useSelector( + (state) => state.inspectorSlice + ); + + const [value, setValue] = useState(null); + const [killhouses, setKillhouses] = useState([]); + + useEffect(() => { + dispatch(inspectorGetKillHousesService()); + }, []); + + useEffect(() => { + const d = inspectorGetKillHouses + ?.filter((item) => item.killer === false) + .map((item) => { + return { title: item.name, value: item.key }; + }); + setKillhouses(d); + }, [inspectorGetKillHouses]); + + return ( + + + option.title} + renderInput={(params) => ( + + )} + value={value} + onChange={(event, newValue) => { + setValue(newValue); + }} + /> + + + + + + + کشتارگاه های ثبت شده + + + {item.killHouses?.map((it, i) => { + return ( + + + {i + 1}. {it.KillHouseName} + + + + ); + })} + + + + ); +}; diff --git a/src/features/inspector/components/inspector-archived-requests/InspectorArchivedRequests.js b/src/features/inspector/components/inspector-archived-requests/InspectorArchivedRequests.js new file mode 100644 index 0000000..914272d --- /dev/null +++ b/src/features/inspector/components/inspector-archived-requests/InspectorArchivedRequests.js @@ -0,0 +1,80 @@ +import { Grid, IconButton } from "@mui/material"; +import PlagiarismIcon from "@mui/icons-material/Plagiarism"; +import { useDispatch, useSelector } from "react-redux"; +import { useEffect, useState } from "react"; +import { inspectorGetNewRequests } from "../../services/inspector-new-requests"; +import { SPACING } from "../../../../data/spacing"; +import { SimpleTable } from "../../../../components/simple-table/SimpleTable"; +import { ROUTE_INSPECTOR_FILE } from "../../../../routes/routes"; +import { useNavigate } from "react-router-dom"; +import { formatJustDate } from "../../../../utils/formatTime"; + +export const InspectorArchivedRequests = () => { + const navigate = useNavigate(); + const dispatch = useDispatch(); + const { inspectorNewRequests } = useSelector((state) => state.inspectorSlice); + + useEffect(() => { + dispatch(inspectorGetNewRequests()); + }, []); + + const [dataTable, setDataTable] = useState([]); + + useEffect(() => { + const d = inspectorNewRequests + ?.filter((item) => item.inspector === "accepted") + ?.map((item, i) => { + return [ + i + 1, + item.orderCode, + formatJustDate(item?.createDate), + formatJustDate(item?.sendDate), + item?.process?.poultry?.poultryName, + item?.process?.poultry?.poultryMobile, + item?.process?.poultry?.poultryCity, + item?.process?.poultry?.poultryProvince, + item?.process?.poultry?.age, + item?.process?.poultry?.poultryQuantity, + + navigate( + ROUTE_INSPECTOR_FILE + item?.process?.poultry?.poultryRequestId + ) + } + > + + , + ]; + }); + setDataTable(d); + }, [inspectorNewRequests]); + + const [tableDataCol] = useState([ + "ردیف", + "کد سفارش", + "تاریخ ثبت درخواست", + "تاریخ درخواست", + "مرغدار", + "تلفن مرغدار", + "شهر", + "استان", + "سن مرغ", + "تعداد", + "مشاهده", + ]); + + return ( + <> + + + + + ); +}; diff --git a/src/features/inspector/components/inspector-edit-aviculture/InspectorEditAviculture.js b/src/features/inspector/components/inspector-edit-aviculture/InspectorEditAviculture.js new file mode 100644 index 0000000..89785c5 --- /dev/null +++ b/src/features/inspector/components/inspector-edit-aviculture/InspectorEditAviculture.js @@ -0,0 +1,493 @@ +import React from "react"; +import { PropTypes } from "prop-types"; +import { Yup } from "../../../../lib/yup/yup"; +import { Grid } from "../../../../components/grid/Grid"; +import { + Autocomplete, + Button, + FormControl, + InputLabel, + MenuItem, + Select, + TextField, +} from "@mui/material"; + +import { useFormik } from "formik"; +import { SPACING } from "../../../../data/spacing"; +import { useDispatch } from "react-redux"; +import { inspectorUpdateUserProfile } from "../../services/inspector-update-user-profile"; +import { + DRAWER, + LOADING_END, + LOADING_START, +} from "../../../../lib/redux/slices/appSlice"; +import { useContext } from "react"; +import { AppContext } from "../../../../contexts/AppContext"; +import { provinceGetUserByKey } from "../../../province/services/province-get-user-by-key"; +import { useState } from "react"; +import { cityGetCity } from "../../../city/services/city-get-city"; +import { useEffect } from "react"; +import { cityGetProvinces } from "../../../city/services/CityGetProvinces"; + +export const InspectorEditAviculture = ({ + id, + address, + postal, + name_of_bank_user, + card, + shaba, + account, + accountHolder, + type, + poultry, + halls, + uniqueId, + farmName, +}) => { + const [openNotif] = useContext(AppContext); + + const [provinceData, setProvinceData] = useState(); + const [cityData, setCityData] = useState(); + const [provinceKey, setProvinceKey] = useState(); + const [cityKey, setCityKey] = useState(); + const [isExistProvince, setIsExistProvince] = useState(true); + + useEffect(() => { + dispatch(LOADING_START()); + dispatch(cityGetProvinces())?.then((r) => { + dispatch(LOADING_END()); + setProvinceData(r.payload.data); + }); + }, []); + + useEffect(() => { + if (provinceKey) { + dispatch(LOADING_START()); + dispatch(cityGetCity(provinceKey)).then((r) => { + setCityData(r.payload.data); + setIsExistProvince(false); + dispatch(LOADING_END()); + }); + } + }, [provinceKey]); + + const dispatch = useDispatch(); + const formik = useFormik({ + initialValues: { + address: address ? address : "", + postal: postal ? postal : "", + bankName: name_of_bank_user ? name_of_bank_user : "", + cardNumber: card ? card : "", + accountNumber: account ? account : "", + shabaNumber: shaba ? shaba : "", + accountHolder: accountHolder ? accountHolder : "", + halls: halls ? halls : "", + uniqueId: uniqueId ? uniqueId : "", + farmName: farmName ? farmName : "", + }, + validationSchema: Yup.object({ + cardNumber: Yup.number().typeError("لطفا شماره کارتتان را وارد کنید!"), + accountNumber: Yup.number().typeError("لطفا شماره حسابتان را وارد کنید!"), + shabaNumber: Yup.number().typeError("لطفا شماره شبا را وارد کنید!"), + accountHolder: Yup.string().typeError("لطفا نام صاحب حساب را وارد کنید!"), + address: Yup.string().typeError("لطفا آدرس را وارد کنید!"), + postal: Yup.number().typeError("لطفا عدد وارد کنید!"), + halls: Yup.number().typeError("لطفا عدد وارد کنید!"), + uniqueId: Yup.number().typeError("لطفا عدد وارد کنید!"), + }), + }); + + useEffect(() => { + formik.validateForm(); + }, []); + + return ( + <> + + + + + + + + + + + + + + + + + + + + + + + ({ + id: i.key, + label: i.name, + })) + : [] + } + onChange={(e, value) => { + setProvinceKey(value.id); + }} + renderInput={(params) => ( + + )} + /> + + + + ({ id: i.key, label: i.name })) + : [] + } + onChange={(e, value) => { + setCityKey(value.id); + }} + renderInput={(params) => ( + + )} + /> + + + + + بانک + + + + + + + + + + + + + + + + + + + + + + ); +}; + +InspectorEditAviculture.propTypes = { + id: PropTypes.any, + address: PropTypes.any, + postal: PropTypes.any, + name_of_bank_user: PropTypes.any, + bank_name: PropTypes.any, + card: PropTypes.any, + shaba: PropTypes.any, + account: PropTypes.any, + accountHolder: PropTypes.any, + type: PropTypes.any, + poultry: PropTypes.any, + halls: PropTypes.any, + uniqueId: PropTypes.any, +}; diff --git a/src/features/inspector/components/inspector-edit-driver/InspectorEditDriver.js b/src/features/inspector/components/inspector-edit-driver/InspectorEditDriver.js new file mode 100644 index 0000000..fce4e74 --- /dev/null +++ b/src/features/inspector/components/inspector-edit-driver/InspectorEditDriver.js @@ -0,0 +1,473 @@ +import { + Button, + Chip, + Divider, + FormControl, + InputLabel, + MenuItem, + Select, + TextField, + Typography, +} from "@mui/material"; +import React, { useState } from "react"; +import { useEffect } from "react"; +import { useDispatch } from "react-redux"; +import { Grid } from "../../../../components/grid/Grid"; +import { PropTypes } from "prop-types"; + +import { + DRAWER, + LOADING_END, + LOADING_START, +} from "../../../../lib/redux/slices/appSlice"; +import { inspectorUpdateUserProfile } from "../../services/inspector-update-user-profile"; +import { useContext } from "react"; +import { AppContext } from "../../../../contexts/AppContext"; +import { provinceGetUserByKey } from "../../../province/services/province-get-user-by-key"; +import { SPACING } from "../../../../data/spacing"; +import { useFormik } from "formik"; +import { Yup } from "../../../../lib/yup/yup"; +import { NumberInput } from "../../../../components/number-format-custom/NumberFormatCustom"; +import { CarPelak } from "../../../../components/car-pelak/CarPelak"; + +export const InspectorEditDriver = ({ + id, + capocity, + healthCode, + driverName, + mobile, + name_of_bank_user, + card, + shaba, + account, + accountHolder, + type, +}) => { + const [openNotif] = useContext(AppContext); + + const dispatch = useDispatch(); + + const formikDriver = useFormik({ + initialValues: { + driver_name: driverName ? driverName : "", + driver_mobile: mobile ? mobile : "", + type_car: "ایسوزو", + type_weight: "سنگین", + capocity: capocity ? capocity : "", + health_code: healthCode ? healthCode : "", + }, + validationSchema: Yup.object({ + driver_name: Yup.string() + .matches( + /^[ض‌ص‌ث‌ق‌ف‌غ‌ع‌ه‌خ‌خ‌ح‌ج‌چ‌ش‌س‌ی‌ب‌ل‌ا‌ت‌ن‌ن‌م‌ک‌گ‌ظ‌ط‌ز‌ر‌ذ‌د‌و‌پ‌آ‌ژ ]+$/, + "فقط حروف فارسی وارد کنید" + ) + .typeError("لطفا فیلد را به درستی وارد کنید!"), + driver_mobile: Yup.string() + .test("len", "شماره تلفن باید با 0 شروع شود", (val, context) => { + return context.originalValue && context.originalValue.startsWith("0"); + }) + .test("len", "شماره تماس 11 رقم باید باشد", (val, context) => { + if (context.originalValue) { + return context.originalValue.length === 11; + } + }) + .typeError("لطفا عدد وارد کنید!"), + type_weight: Yup.string().typeError("لطفا فیلد را به درستی وارد کنید!"), + capocity: Yup.string().typeError("لطفا فیلد را به درستی وارد کنید!"), + name: Yup.string().typeError("لطفا فیلد را به درستی وارد کنید!"), + health_code: Yup.number().typeError("لطفا فیلد را به درستی وارد کنید!"), + }), + }); + + const formikUserBankInfo = useFormik({ + initialValues: { + bankName: name_of_bank_user ? name_of_bank_user : "", + cardNumber: card ? card : "", + accountNumber: account ? account : "", + shabaNumber: shaba ? shaba : "", + accountHolder: accountHolder ? accountHolder : "", + }, + validationSchema: Yup.object({ + cardNumber: Yup.number().typeError("لطفا شماره کارتتان را وارد کنید!"), + accountNumber: Yup.number().typeError("لطفا شماره حسابتان را وارد کنید!"), + shabaNumber: Yup.number().typeError("لطفا شماره شبا را وارد کنید!"), + accountHolder: Yup.string().typeError("لطفا نام صاحب حساب را وارد کنید!"), + }), + }); + + const [driverPelak, setDriverPelak] = useState([]); + + const carPelakHandleChange = (pelak1, pelak2, pelak3, pelak4) => { + setDriverPelak([pelak1, pelak2, pelak3, pelak4]); + }; + + useEffect(() => { + formikDriver.validateForm(); + formikUserBankInfo.validateForm(); + }, []); + + return ( + <> + + + + + + + + مدل خودرو + + + + + + + + مشخصات پلاک + + + + + + + + + + + بانک + + + + + + + + + + + + + + + + ); +}; + +InspectorEditDriver.propTypes = { + id: PropTypes.any, + capocity: PropTypes.any, + healthCode: PropTypes.any, + driverName: PropTypes.any, + mobile: PropTypes.any, + name_of_bank_user: PropTypes.any, + bank_name: PropTypes.any, + card: PropTypes.any, + shaba: PropTypes.any, + account: PropTypes.any, + accountHolder: PropTypes.any, + type: PropTypes.any, +}; diff --git a/src/features/inspector/components/inspector-edit-killhouse-vet/InspectorEditKillHousevet.js b/src/features/inspector/components/inspector-edit-killhouse-vet/InspectorEditKillHousevet.js new file mode 100644 index 0000000..01b2b2c --- /dev/null +++ b/src/features/inspector/components/inspector-edit-killhouse-vet/InspectorEditKillHousevet.js @@ -0,0 +1,116 @@ +import { Autocomplete, Button, TextField } from "@mui/material"; +import React from "react"; +import { useEffect } from "react"; +import { useState } from "react"; +import { useDispatch } from "react-redux"; +import { Grid } from "../../../../components/grid/Grid"; +import { PropTypes } from "prop-types"; + +import { + DRAWER, + LOADING_END, + LOADING_START, +} from "../../../../lib/redux/slices/appSlice"; +import { provinceGetKillHouses } from "../../../province/services/province-get-kill-houses"; +import { inspectorUpdateUserProfile } from "../../services/inspector-update-user-profile"; +import { useContext } from "react"; +import { AppContext } from "../../../../contexts/AppContext"; +import { provinceGetUserByKey } from "../../../province/services/province-get-user-by-key"; +import { SPACING } from "../../../../data/spacing"; + +export const InspectorEditKillHouseVet = ({ id }) => { + const [openNotif] = useContext(AppContext); + + const dispatch = useDispatch(); + const [killHouseData, setKillHouseData] = useState(); + const [killHouseKey, setKillHouseKey] = useState(); + useEffect(() => { + dispatch(LOADING_START()); + dispatch(provinceGetKillHouses()).then((r) => { + setKillHouseData(r.payload.data); + dispatch(LOADING_END()); + }); + }, []); + + return ( + <> + + + + ({ + id: i.key, + label: i.name, + })) + : [] + } + onChange={(e, value) => { + setKillHouseKey(value.id); + }} + renderInput={(params) => ( + + )} + /> + + + + + + + ); +}; + +InspectorEditKillHouseVet.propTypes = { + id: PropTypes.any, +}; diff --git a/src/features/inspector/components/inspector-edit-operator/InspectorEditOperator.js b/src/features/inspector/components/inspector-edit-operator/InspectorEditOperator.js new file mode 100644 index 0000000..1324d20 --- /dev/null +++ b/src/features/inspector/components/inspector-edit-operator/InspectorEditOperator.js @@ -0,0 +1,411 @@ +import React from "react"; +import { PropTypes } from "prop-types"; +import { Yup } from "../../../../lib/yup/yup"; +import { Grid } from "../../../../components/grid/Grid"; +import { + Autocomplete, + Button, + FormControl, + InputLabel, + MenuItem, + Select, + TextField, +} from "@mui/material"; + +import { useFormik } from "formik"; +import { SPACING } from "../../../../data/spacing"; +import { useDispatch } from "react-redux"; +import { inspectorUpdateUserProfile } from "../../services/inspector-update-user-profile"; +import { + DRAWER, + LOADING_END, + LOADING_START, +} from "../../../../lib/redux/slices/appSlice"; +import { useContext } from "react"; +import { AppContext } from "../../../../contexts/AppContext"; +import { provinceGetUserByKey } from "../../../province/services/province-get-user-by-key"; +import { useState } from "react"; +import { cityGetCity } from "../../../city/services/city-get-city"; +import { useEffect } from "react"; +import { cityGetProvinces } from "../../../city/services/CityGetProvinces"; + +export const InspectorEditOperator = ({ + id, + address, + postal, + name_of_bank_user, + card, + shaba, + account, + accountHolder, + type, +}) => { + const [openNotif] = useContext(AppContext); + + const [provinceData, setProvinceData] = useState(); + const [cityData, setCityData] = useState(); + const [provinceKey, setProvinceKey] = useState(); + const [cityKey, setCityKey] = useState(); + const [isExistProvince, setIsExistProvince] = useState(true); + + useEffect(() => { + dispatch(LOADING_START()); + dispatch(cityGetProvinces())?.then((r) => { + dispatch(LOADING_END()); + setProvinceData(r.payload.data); + }); + }, []); + + useEffect(() => { + if (provinceKey) { + dispatch(LOADING_START()); + dispatch(cityGetCity(provinceKey)).then((r) => { + setCityData(r.payload.data); + setIsExistProvince(false); + dispatch(LOADING_END()); + }); + } + }, [provinceKey]); + + const dispatch = useDispatch(); + const formik = useFormik({ + initialValues: { + address: address ? address : "", + postal: postal ? postal : "", + bankName: name_of_bank_user ? name_of_bank_user : "", + cardNumber: card ? card : "", + accountNumber: account ? account : "", + shabaNumber: shaba ? shaba : "", + accountHolder: accountHolder ? accountHolder : "", + }, + validationSchema: Yup.object({ + cardNumber: Yup.number().typeError("لطفا شماره کارتتان را وارد کنید!"), + accountNumber: Yup.number().typeError("لطفا شماره حسابتان را وارد کنید!"), + shabaNumber: Yup.number().typeError("لطفا شماره شبا را وارد کنید!"), + accountHolder: Yup.string().typeError("لطفا نام صاحب حساب را وارد کنید!"), + address: Yup.string().typeError("لطفا نام صاحب حساب را وارد کنید!"), + postal: Yup.number().typeError("لطفا نام صاحب حساب را وارد کنید!"), + }), + }); + + useEffect(() => { + formik.validateForm(); + }, []); + + return ( + <> + + + + + + + + + + + + ({ + id: i.key, + label: i.name, + })) + : [] + } + onChange={(e, value) => { + setProvinceKey(value.id); + }} + renderInput={(params) => ( + + )} + /> + + + + ({ id: i.key, label: i.name })) + : [] + } + onChange={(e, value) => { + setCityKey(value.id); + }} + renderInput={(params) => ( + + )} + /> + + + + + بانک + + + + + + + + + + + + + + + + + + + + + + ); +}; + +InspectorEditOperator.propTypes = { + id: PropTypes.any, + address: PropTypes.any, + postal: PropTypes.any, + name_of_bank_user: PropTypes.any, + bank_name: PropTypes.any, + card: PropTypes.any, + shaba: PropTypes.any, + account: PropTypes.any, + accountHolder: PropTypes.any, + type: PropTypes.any, +}; diff --git a/src/features/inspector/components/inspector-edit-user-profile/InspectorEditUserProfile.js b/src/features/inspector/components/inspector-edit-user-profile/InspectorEditUserProfile.js new file mode 100644 index 0000000..6c35e3e --- /dev/null +++ b/src/features/inspector/components/inspector-edit-user-profile/InspectorEditUserProfile.js @@ -0,0 +1,345 @@ +import React, { useState } from "react"; +import { PropTypes } from "prop-types"; +import { Yup } from "../../../../lib/yup/yup"; +import { Grid } from "../../../../components/grid/Grid"; +import { Button, TextField } from "@mui/material"; +import { DatePicker } from "@mui/x-date-pickers"; +import moment from "moment"; +import { useFormik } from "formik"; +import { SPACING } from "../../../../data/spacing"; +import { useDispatch } from "react-redux"; +import { inspectorUpdateUserProfile } from "../../services/inspector-update-user-profile"; +import { + DRAWER, + LOADING_END, + LOADING_START, +} from "../../../../lib/redux/slices/appSlice"; +import { useContext } from "react"; +import { AppContext } from "../../../../contexts/AppContext"; +import { provinceGetUserByKey } from "../../../province/services/province-get-user-by-key"; +import { useEffect } from "react"; +import { cityGetProvinces } from "../../../city/services/CityGetProvinces"; +import { cityGetCity } from "../../../city/services/city-get-city"; + +export const InspectorEditUserProfile = ({ + id, + birthday, + nationalCode, + nationalId, + firstName, + lastName, + password, + phone, +}) => { + const [openNotif] = useContext(AppContext); + + const [, setProvinceData] = useState([]); + const [, setCityData] = useState([]); + const [provinceKey] = useState(); + // const [cityKey, setCityKey] = useState(); + const [, setIsExistProvince] = useState(true); + + const dispatch = useDispatch(); + const formik = useFormik({ + initialValues: { + fname: firstName ? firstName : "", + lname: lastName ? lastName : "", + nationalcode: nationalId ? nationalId : "", + nationalId: nationalCode ? nationalCode : "", + password: password ? password : "", + phone: phone ? phone : "", + birthday: birthday + ? birthday + : moment(Date()).format("YYYY-MM-DD hh:mm:ss"), + }, + validationSchema: Yup.object({ + fname: Yup.string().typeError("لطفا فیلد را پر کنید!"), + lname: Yup.string().typeError("لطفا فیلد را پر کنید!"), + nationalcode: Yup.string().typeError( + "لطفا مقادیر را به درستی وارد کنید!" + ), + nationalId: Yup.number().test( + "len", + "کد ملی میبایست ده رقم باشد.", + (val, context) => { + if (context.originalValue) { + return context.originalValue.length === 10; + } + } + ), + password: Yup.string().typeError("لطفا مقادیر را به درستی وارد کنید!"), + }), + }); + + useEffect(() => { + formik.validateForm(); + }, []); + + useEffect(() => { + dispatch(cityGetProvinces())?.then((r) => { + setProvinceData(r.payload.data); + }); + }, []); + + useEffect(() => { + if (provinceKey) { + dispatch(LOADING_START()); + dispatch(cityGetCity(provinceKey)).then((r) => { + setCityData(r.payload.data); + setIsExistProvince(false); + dispatch(LOADING_END()); + }); + } + }, [provinceKey]); + + return ( + <> + + + + + + + + + + {/* + ({ + id: i.key, + label: i.name, + }))} + onChange={(e, value) => { + setProvinceKey(value.id); + }} + renderInput={(params) => ( + + )} + /> + + + + ({ id: i.key, label: i.name }))} + onChange={(e, value) => { + setCityKey(value.id); + }} + renderInput={(params) => ( + + )} + /> + */} + + + } + value={formik.values.birthday} + error={ + formik.touched.birthday ? Boolean(formik.errors.birthday) : null + } + onChange={(e) => { + formik.setFieldValue( + "birthday", + moment(e).format("YYYY-MM-DD hh:mm:ss") + ); + }} + onBlur={formik.handleBlur} + helperText={ + formik.touched.birthday && Boolean(formik.errors.birthday) + ? formik.errors.birthday + : null + } + /> + + + + + + + + + + + + + + + + + + + + + + ); +}; + +InspectorEditUserProfile.propTypes = { + id: PropTypes.any, + firstName: PropTypes.any, + lastName: PropTypes.any, + birthday: PropTypes.any, + nationalCode: PropTypes.any, + nationalId: PropTypes.any, + password: PropTypes.any, +}; diff --git a/src/features/inspector/components/inspector-killhouse-new-request/inspector-killhouse-new-request.js b/src/features/inspector/components/inspector-killhouse-new-request/inspector-killhouse-new-request.js new file mode 100644 index 0000000..12d6c7e --- /dev/null +++ b/src/features/inspector/components/inspector-killhouse-new-request/inspector-killhouse-new-request.js @@ -0,0 +1,504 @@ +import { + Button, + Checkbox, + // Checkbox, + FormControl, + FormControlLabel, + // FormControlLabel, + // FormGroup, + // FormHelperText, + Grid, + InputLabel, + ListItem, + ListItemIcon, + ListItemText, + MenuItem, + Select, + TextField, + Tooltip, + Typography, +} from "@mui/material"; +import { DatePicker } from "@mui/x-date-pickers"; +import { SPACING } from "../../../../data/spacing"; +import { useFormik } from "formik"; +import moment from "moment"; +import { Yup } from "../../../../lib/yup/yup"; + +import { + DRAWER, + LOADING_END, + LOADING_START, +} from "../../../../lib/redux/slices/appSlice"; +import { useEffect, useState } from "react"; +import { useDispatch, useSelector } from "react-redux"; +import { useContext } from "react"; +import { AppContext } from "../../../../contexts/AppContext"; +import { DialogAlert } from "../../../../components/dialog-alert/DialogAlert"; +import useUserProfile from "../../../authentication/hooks/useUserProfile"; +import DoneIcon from "@mui/icons-material/Done"; +import { NumberInput } from "../../../../components/number-format-custom/NumberFormatCustom"; + +import { provinceGetPricing } from "../../../province/services/province-get-pricing"; +import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl"; +import { slaughterNewRequest } from "../../../slaughter-house/services/slaughter-new-request"; +import { inspectorGetKillHousesService } from "../../services/inspector-get-kill-houses"; +import { getSlaughtersKillRequestService } from "../../../city/services/get-slaughters-kill-request"; + +export const InspectorKillHouseNewRequest = () => { + const [openNotif, , selectedDate1, , selectedDate2, ,] = + useContext(AppContext); + const dispatch = useDispatch(); + const [, userProfile] = useUserProfile(); + const { inspectorGetKillHouses } = useSelector( + (state) => state.inspectorSlice + ); + const [killhouses, setKillhouses] = useState([]); + const [onlyKillhouses, setOnlyKillhouses] = useState([]); + const [isKiller, setIsKiller] = useState(false); + + useEffect(() => { + const d = inspectorGetKillHouses?.map((item) => { + return { name: item.name, key: item.key, killer: item.killer }; + }); + setKillhouses(d); + }, [inspectorGetKillHouses]); + + useEffect(() => { + if (isKiller === "true") { + const c = inspectorGetKillHouses + ?.filter((item) => item.killer === false) + ?.map((item) => { + return { name: item.name, key: item.key, killer: item.killer }; + }); + setOnlyKillhouses(c); + } + }, [inspectorGetKillHouses, isKiller]); + + const formik = useFormik({ + initialValues: { + capacity: "", + recieveTime: "", + selectedKillhouse: "", + selectedKillerKillhouse: "", + race: "", + sellType: { + cash: true, + haveTime: false, + }, + weightType: { + under2AndHalf: false, + over2AndHalf: false, + }, + recieveDate: moment(Date()).format("YYYY-MM-DD hh:mm:ss"), + isAccepted: getRoleFromUrl() !== "KillHouse" ? true : false, + indexWeight: "", + }, + validationSchema: Yup.object({ + capacity: Yup.number() + .required("این فیلد اجباری است!") + .typeError("لطفا عدد وارد کنید!"), + selectedKillhouse: Yup.string().required("این فیلد اجباری است!"), + selectedKillerKillhouse: + isKiller === "true" + ? Yup.string().required("این فیلد اجباری است!") + : Yup.string(), + recieveTime: Yup.string() + .required("این فیلد اجباری است!") + .typeError("لطفا وزن را وارد کنید!"), + sellType: Yup.object() + .test("sellType", "نحوه فروش را انتخاب کنید!", (val, context) => { + return ( + context.originalValue && + Object.values(context.originalValue).some((item) => item === true) + ); + }) + .required("این فیلد اجباری است!"), + isAccepted: Yup.boolean() + .test("req", "باید تعهد نامه را بپذیرید!", (val, context) => { + return context.originalValue && context.originalValue === true; + }) + .required("این فیلد اجباری است!"), + // weightType: Yup.object() + // .test("weightType", "وزن را انتخاب کنید!", (val, context) => { + // return ( + // context.originalValue && + // Object.values(context.originalValue).some((item) => item === true) + // ); + // }) + // .required("این فیلد اجباری است!"), + }), + }); + + const penaltyPrice = formik.values.capacity * 1000; + const dialogContent = ( + <> + + اینجانب {userProfile?.fullname} موافقت خود را نسبت به موارد ذکر شده + اعلام می نمایم. + + + + + + + + + ); + + useEffect(() => { + dispatch(inspectorGetKillHousesService()); + formik.validateForm(); + }, []); + + // const handleSellTypeChange = (event) => { + // formik.setFieldValue("sellType", { + // ...formik.values.sellType, + // [event.target.name]: event.target.checked, + // }); + // }; + // const handleWeightTypeChange = (event) => { + // formik.setFieldValue("weightType", { + // ...formik.values.weightType, + // [event.target.name]: event.target.checked, + // }); + // }; + + const [checkedSms, setCheckedSms] = useState(true); + + const handleChangeCheckedSms = (event) => { + setCheckedSms(event.target.checked); + }; + + useEffect(() => { + dispatch(provinceGetPricing()); + }, []); + + return ( + <> + + + {/* */} + + + + انتخاب کشتارگاه یا کشتارکن + + {formik.errors.selectedKillhouse && + formik.touched.selectedKillhouse && ( +
    {formik.errors.selectedKillhouse}
    + )} +
    + + {isKiller === "true" && ( + + محل کشتار را انتخاب کنید + + {formik.errors.selectedKillerKillhouse && + formik.touched.selectedKillerKillhouse && ( +
    {formik.errors.selectedKillerKillhouse}
    + )} +
    + )} + + + + + + + بازه زمانی دریافت مرغ مرغدار + + + + + + } + value={formik.values.recieveDate} + error={ + formik.touched.recieveDate + ? Boolean(formik.errors.recieveDate) + : null + } + onChange={(e) => { + formik.setFieldValue( + "recieveDate", + moment(e).format("YYYY-MM-DD hh:mm:ss") + ); + }} + onBlur={formik.handleBlur} + helperText={ + formik.touched.recieveDate && Boolean(formik.errors.recieveDate) + ? formik.errors.recieveDate + : null + } + /> + +
    + {/* + + نحوه خرید + + + + } + label="نقدی" + /> + + } + label="زمان دار (تا یک ماه)" + /> + + + {formik.touched.sellType && Boolean(formik.errors.sellType) + ? formik.errors.sellType + : null} + + */} + {/* + + وزن پیشنهادی + + + + } + label="2 تا 2.5 کیلوگرم" + /> + + } + label="2.5 کیلوگرم به بالا" + /> + + */} + + {getRoleFromUrl() === "KillHouse" && ( + + + + + } + btnTitle={"با تعهد نامه موافق هستم!"} + isAccepted={formik.values.isAccepted} + /> + )} + + + + } + label={ + + + مایل به دریافت پیامک اطلاع رسانی هستم! + + + } + /> + +
    + + + + + + ); +}; diff --git a/src/features/inspector/components/inspector-new-requests/InspectorNewRequests.js b/src/features/inspector/components/inspector-new-requests/InspectorNewRequests.js new file mode 100644 index 0000000..d7f310d --- /dev/null +++ b/src/features/inspector/components/inspector-new-requests/InspectorNewRequests.js @@ -0,0 +1,103 @@ +import { Grid, IconButton } from "@mui/material"; +import PlagiarismIcon from "@mui/icons-material/Plagiarism"; +import { useDispatch, useSelector } from "react-redux"; +import { useEffect, useState } from "react"; +import { inspectorGetNewRequests } from "../../services/inspector-new-requests"; +import { SPACING } from "../../../../data/spacing"; +import { SimpleTable } from "../../../../components/simple-table/SimpleTable"; +import { ROUTE_INSPECTOR_FILE } from "../../../../routes/routes"; +import { useNavigate } from "react-router-dom"; +import { DRAWER } from "../../../../lib/redux/slices/appSlice"; +import { InspectorRequestOperations } from "../../../file/components/inspector-request-operations/InspectorRequestOperations"; +import EditIcon from "@mui/icons-material/Edit"; +import { formatJustDate } from "../../../../utils/formatTime"; + +export const InspectorNewRequests = () => { + const navigate = useNavigate(); + const { inspectorNewRequests } = useSelector((state) => state.inspectorSlice); + const dispatch = useDispatch(); + + useEffect(() => { + dispatch(inspectorGetNewRequests()); + }, []); + + const [dataTable, setDataTable] = useState([]); + + useEffect(() => { + const d = inspectorNewRequests + ?.filter((item) => !item.inspector || item.inspector === "pending") + ?.map((item, i) => { + return [ + i + 1, + item.orderCode, + formatJustDate(item?.createDate), + formatJustDate(item?.sendDate), + item?.process?.poultry?.poultryName, + item?.process?.poultry?.poultryMobile, + item?.process?.poultry?.poultryCity, + item?.process?.poultry?.poultryProvince, + item?.process?.poultry?.age, + item?.process?.poultry?.poultryQuantity, + { + dispatch( + DRAWER({ + title: "عملیات تایید / رد بازرس", + // right: !(window.innerWidth <= 600), + top: !(window.innerWidth <= 600), + bottom: window.innerWidth <= 600, + content: ( + + ), + }) + ); + }} + > + + , + + navigate( + ROUTE_INSPECTOR_FILE + item?.process?.poultry?.poultryRequestId + ) + } + > + + , + ]; + }); + setDataTable(d); + }, [inspectorNewRequests]); + + const [tableDataCol] = useState([ + "ردیف", + "کد سفارش", + "تاریخ ثبت درخواست", + "تاریخ درخواست", + "مرغدار", + "تلفن مرغدار", + "شهر", + "استان", + "سن مرغ", + "تعداد", + "عملیات", + "مشاهده", + ]); + + return ( + <> + + + + + ); +}; diff --git a/src/features/inspector/components/inspector-operations/InspectorOperations.js b/src/features/inspector/components/inspector-operations/InspectorOperations.js new file mode 100644 index 0000000..4df22ad --- /dev/null +++ b/src/features/inspector/components/inspector-operations/InspectorOperations.js @@ -0,0 +1,122 @@ +import { Grid } from "../../../../components/grid/Grid"; +import { SPACING } from "../../../../data/spacing"; +import { NavLink } from "../../../../components/nav-link/NavLink"; +import { useLocation } from "react-router-dom"; +import { + ROUTE_INSPECTOR_ARCHIVED_REQUESTS, + ROUTE_INSPECTOR_REJECTED_REQUESTS, + ROUTE_INSPECTOR_REQUESTS_NEW_REQUESTS, + ROUTE_PROVINCE_INSPECTOR_AWAITING_INSPECTION_REQUESTS, + ROUTE_PROVINCE_INSPECTOR_AWAITING_PAYMENT_REQUESTS, + // ROUTE_PROVINCE_FINANCIAL_REJECTED_REQUESTS, +} from "../../../../routes/routes"; +import { VscNewFolder } from "react-icons/vsc"; +import LinkItem from "../../../../components/link-item/LinkItem"; +import { GiMoneyStack } from "react-icons/gi"; +import { GrInspect } from "react-icons/gr"; +import { RiFolderWarningLine } from "react-icons/ri"; +import { FaArchive } from "react-icons/fa"; + +export const InspectorOperations = () => { + const { pathname } = useLocation(); + return ( + + + + + } + title="درخواست های جدید" + description="درخواست های در انتظار بررسی" + /> + + + + } + title="در انتظار پرداخت" + description="مشاهده درخواست های در انتظار پرداخت کشتارگاه" + /> + + + + } + title="در انتظار بازرسی" + description="درخواست های در انتظار بررسی بازرس" + /> + + + + + } + title="درخواست های رد شده" + description="مشاهده درخواست هایی که به دلایل مختلف توسط اتحادیه رد شده است" + /> + + + + + } + title="بایگانی" + description="درخواست های پایان یافته" + /> + + + + + ); +}; diff --git a/src/features/inspector/components/inspector-profile/InspectorProfile.js b/src/features/inspector/components/inspector-profile/InspectorProfile.js new file mode 100644 index 0000000..a8cce97 --- /dev/null +++ b/src/features/inspector/components/inspector-profile/InspectorProfile.js @@ -0,0 +1,57 @@ +import { Grid } from "@mui/material"; +import { Box } from "@mui/system"; +import { useEffect } from "react"; +import { useDispatch, useSelector } from "react-redux"; +import { SimpleTable } from "../../../../components/simple-table/SimpleTable"; +import { SPACING } from "../../../../data/spacing"; +import { + LOADING_END, + LOADING_START, +} from "../../../../lib/redux/slices/appSlice"; +// import { ChangeCardInfo } from "../../../authentication/components/change-card-info/ChangeCardInfo"; +import { inspectorGetProfile } from "../../services/inspector-get-profile"; + +export const InspectorProfile = () => { + const { profile } = useSelector((state) => state.inspectorSlice); + const dispatch = useDispatch(); + + useEffect(() => { + dispatch(LOADING_START()); + dispatch(inspectorGetProfile()).then((r) => { + dispatch(LOADING_END()); + }); + }, []); + + return ( + + + + + <> + + + + {/* */} + + + + + + ); +}; diff --git a/src/features/inspector/components/inspector-rejected-requests/InspectorRejectedRequests.js b/src/features/inspector/components/inspector-rejected-requests/InspectorRejectedRequests.js new file mode 100644 index 0000000..a4a128d --- /dev/null +++ b/src/features/inspector/components/inspector-rejected-requests/InspectorRejectedRequests.js @@ -0,0 +1,78 @@ +import { Grid, IconButton } from "@mui/material"; +import PlagiarismIcon from "@mui/icons-material/Plagiarism"; +import { useDispatch, useSelector } from "react-redux"; +import { useEffect, useState } from "react"; +import { inspectorGetNewRequests } from "../../services/inspector-new-requests"; +import { SPACING } from "../../../../data/spacing"; +import { SimpleTable } from "../../../../components/simple-table/SimpleTable"; +import { ROUTE_INSPECTOR_FILE } from "../../../../routes/routes"; +import { useNavigate } from "react-router-dom"; +import { formatJustDate } from "../../../../utils/formatTime"; + +export const InspectorRejectedRequests = () => { + const navigate = useNavigate(); + const dispatch = useDispatch(); + const { inspectorNewRequests } = useSelector((state) => state.inspectorSlice); + + useEffect(() => { + dispatch(inspectorGetNewRequests()); + }, []); + + const [dataTable, setDataTable] = useState([]); + + useEffect(() => { + const d = inspectorNewRequests + ?.filter((item) => item.inspector === "rejected") + ?.map((item, i) => { + return [ + i + 1, + item.orderCode, + formatJustDate(item?.createDate), + formatJustDate(item?.sendDate), + item?.process?.poultry?.poultryName, + item?.process?.poultry?.poultryMobile, + item?.process?.poultry?.poultryCity, + item?.process?.poultry?.poultryProvince, + item?.process?.poultry?.age, + item?.process?.poultry?.poultryQuantity, + + navigate( + ROUTE_INSPECTOR_FILE + item?.process?.poultry?.poultryRequestId + ) + } + > + + , + ]; + }); + setDataTable(d); + }, [inspectorNewRequests]); + + const [tableDataCol] = useState([ + "ردیف", + "کد سفارش", + "تاریخ ثبت درخواست", + "تاریخ درخواست", + "مرغدار", + "تلفن مرغدار", + "شهر", + "استان", + "سن مرغ", + "تعداد", + "مشاهده", + ]); + + return ( + + + + ); +}; diff --git a/src/features/inspector/components/manage-farm-component/ManageFarmComponent.js b/src/features/inspector/components/manage-farm-component/ManageFarmComponent.js new file mode 100644 index 0000000..73e3070 --- /dev/null +++ b/src/features/inspector/components/manage-farm-component/ManageFarmComponent.js @@ -0,0 +1,469 @@ +import { useContext, useEffect, useState } from "react"; +import { useDispatch } from "react-redux"; +import { Grid } from "../../../../components/grid/Grid"; +import { + Button, + IconButton, + List, + ListItemButton, + ListItemIcon, + ListItemText, + Popover, + Tab, + Tabs, + TextField, + Tooltip, + Typography, +} from "@mui/material"; +import { + DRAWER, + LOADING_END, + LOADING_START, +} from "../../../../lib/redux/slices/appSlice"; +import { VetFarmSubmitFarmInfoForm } from "../../../vet-farm/components/vet-farm-submit-farm-info-form/VetFarmSubmitFarmInfoForm"; +import { SPACING } from "../../../../data/spacing"; +import { InspectorAddVetToKillHouse } from "../inspector-add-vet-to-kill-house/InspectorAddVetToKillHouse"; +import ResponsiveTable from "../../../../components/responsive-table/ResponsiveTable"; +import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl"; +import axios from "axios"; +import { RiSearchLine } from "react-icons/ri"; +import { AppContext } from "../../../../contexts/AppContext"; +import TuneIcon from "@mui/icons-material/Tune"; +import AddBusinessIcon from "@mui/icons-material/AddBusiness"; +import FileDownloadIcon from "@mui/icons-material/FileDownload"; +import AddHomeWorkIcon from "@mui/icons-material/AddHomeWork"; + +export const ManageFarmComponent = () => { + const dispatch = useDispatch(); + const [openNotif] = useContext(AppContext); + + const [data, setData] = useState([]); + const [totalRows, setTotalRows] = useState(0); + const [perPage, setPerPage] = useState(10); + const [textValue, setTextValue] = useState(""); + const [page, setPage] = useState(1); + const [tableData, setTableData] = useState([]); + const [selectedTab, setSelectedTab] = useState(0); + + const handleTabChange = (event, newValue) => { + setSelectedTab(newValue); + }; + + const handleTextChange = (event) => { + setTextValue(event.target.value); + }; + + const fetchApiData = async (page) => { + dispatch(LOADING_START()); + + const vetFarmParam = + selectedTab === 0 + ? "&vet_farm=true" + : selectedTab === 2 // تب کشتارگاه حالا سومین تب است (ایندکس 2) + ? "&vet_farm=false" + : ""; // تب بدون فارم (ایندکس 1) پارامتر خاصی ندارد + + try { + const response = await axios.get( + `vet/?search=filter&value=${textValue}&role=${getRoleFromUrl()}&page=${page}&page_size=${perPage}${vetFarmParam}` + ); + setData(response.data.results); + setTotalRows(response.data.count); + } catch (error) { + console.error("Error fetching users", error); + } finally { + dispatch(LOADING_END()); + } + }; + + const handleSubmit = async (event) => { + event.preventDefault(); + setPage(1); + fetchApiData(1); + }; + + const handlePageChange = (page) => { + fetchApiData(page); + setPage(page); + }; + + const handlePerRowsChange = (perRows) => { + setPerPage(perRows); + setPage(1); + }; + + const VetFarmActions = ({ vetFarm }) => { + const [anchorEl, setAnchorEl] = useState(null); + const open = Boolean(anchorEl); + + const handleOpen = (event) => { + setAnchorEl(event.currentTarget); + }; + + const handleClose = () => { + setAnchorEl(null); + }; + + const handleRegisterFarm = () => { + dispatch( + DRAWER({ + right: !(window.innerWidth <= 600), + bottom: window.innerWidth <= 600, + title: "ثبت فارم", + content: ( + + ), + }) + ); + handleClose(); + }; + + const handleDownloadExcel = () => { + openNotif({ + vertical: "top", + horizontal: "center", + msg: "فایل اکسل در حال دانلود می باشد، این عملیات ممکن است زمان بر باشد لطفا صبر کنید.", + severity: "success", + }); + const link = `${axios.defaults.baseURL}technical_responsible_performance_excel/?key=${vetFarm?.key}`; + window.location.href = link; + handleClose(); + }; + + return ( + + + + + + + + + + + + + + ثبت فارم + + } + /> + + + + + + + خروجی اکسل + + } + /> + + + + + ); + }; + + const updateTable = () => { + fetchApiData(page !== 0 ? page : 1); + }; + const KillHouseActions = ({ vet }) => { + const [anchorEl, setAnchorEl] = useState(null); + const open = Boolean(anchorEl); + + const handleOpen = (event) => { + setAnchorEl(event.currentTarget); + }; + + const handleClose = () => { + setAnchorEl(null); + }; + + const handleRegisterKillHouse = () => { + dispatch( + DRAWER({ + right: !(window.innerWidth <= 600), + bottom: window.innerWidth <= 600, + title: "ثبت کشتارگاه", + content: ( + + ), + }) + ); + handleClose(); + }; + + return ( + + + + + + + + + + + + + + ثبت کشتارگاه + + } + /> + + + + + ); + }; + + useEffect(() => { + fetchApiData(1); + }, [dispatch, perPage, selectedTab]); + + useEffect(() => { + const d = data?.map((item, i) => { + const index = page === 1 ? i + 1 : i + perPage * (page - 1) + 1; + const baseInfo = [ + index, + item.user.fullname, + item.user.nationalId, + item.user.mobile, + item.user.province, + item.user.city, + ]; + + if (selectedTab === 0) { + return [ + ...baseInfo, + + {item?.farms?.length + ? item?.farms.map((option, idx) => ( + + + {option.poultryName} ({option.poultryFullName}) + + + {option.poultryMobile} + + + )) + : "-"} + , + , + ]; + } + + if (selectedTab === 2) { + // تب کشتارگاه (حالا سومین تب است) + return [ + ...baseInfo, + + {item?.killHouses?.length + ? item?.killHouses.map((option, idx) => ( + + + {option.KillHouseName} ({option.KillHouseUserFullName}) + + + {option.KillHouseUserMobile} + + + )) + : "-"} + , + , + ]; + } + + // تب دوم: دامپزشکان بدون فارم + return [ + ...baseInfo, + , + ]; + }); + + setTableData(d); + }, [data, page, perPage, selectedTab]); + + return ( + + + + + + + + + + +
    + + + +
    + + +
    + ); +}; diff --git a/src/features/inspector/components/province-edit-tenant/ProvinceEditTenant.js b/src/features/inspector/components/province-edit-tenant/ProvinceEditTenant.js new file mode 100644 index 0000000..74415d4 --- /dev/null +++ b/src/features/inspector/components/province-edit-tenant/ProvinceEditTenant.js @@ -0,0 +1,133 @@ +import React, { useContext } from "react"; +import { useFormik } from "formik"; +import * as Yup from "yup"; +import TextField from "@mui/material/TextField"; +import Button from "@mui/material/Button"; +import { Grid } from "../../../../components/grid/Grid"; +import { SPACING } from "../../../../data/spacing"; +import { useDispatch } from "react-redux"; +import { provinceUpdateTenantService } from "../../services/province-update-tenant"; +import { AppContext } from "../../../../contexts/AppContext"; +import { DRAWER } from "../../../../lib/redux/slices/appSlice"; + +const validationSchema = Yup.object({ + uniqueId: Yup.string().required("شناسه یکتا الزامی است."), + firstName: Yup.string().required("نام الزامی است."), + lastName: Yup.string().required("نام خانوادگی الزامی است"), + mobileNumber: Yup.string() + .matches(/^[0-9]{11}$/, "شماره موبایل نامعتبر است") + .required("موبایل الزامی است"), + nationalCode: Yup.string().required("کدملی الزامی است"), +}); + +export const ProvinceEditTenant = ({ tenant, updateData }) => { + const dispatch = useDispatch(); + const [openNotif] = useContext(AppContext); + + const formik = useFormik({ + initialValues: { + uniqueId: tenant.breedingUniqueId, + firstName: tenant.firstName, + lastName: tenant.lastName, + mobileNumber: tenant.mobile, + nationalCode: tenant.nationalId, + }, + validationSchema: validationSchema, + onSubmit: (values) => { + // Handle form submission logic here + dispatch( + provinceUpdateTenantService({ + breeding_unique_id: values.uniqueId, + first_name: values.firstName, + last_name: values.lastName, + mobile: values.mobileNumber, + national_id: values.nationalCode, + tenant_key: tenant.key, + }) + ).then((r) => { + updateData(); + openNotif({ + vertical: "top", + horizontal: "center", + msg: "عملیات با موفقیت انجام شد.", + severity: "success", + }); + dispatch(DRAWER({ right: false, bottom: false, content: null })); + }); + }, + }); + + return ( +
    + + + + + + + + + + + + + +
    + ); +}; diff --git a/src/features/inspector/components/province-user-file-info/ProvinceUserFileInfo.js b/src/features/inspector/components/province-user-file-info/ProvinceUserFileInfo.js new file mode 100644 index 0000000..e78f4f0 --- /dev/null +++ b/src/features/inspector/components/province-user-file-info/ProvinceUserFileInfo.js @@ -0,0 +1,1457 @@ +import { + Button, + FormControlLabel, + IconButton, + Switch, + Tooltip, + Typography, +} from "@mui/material"; +import React from "react"; +import { useEffect } from "react"; +import { useNavigate, useParams } from "react-router-dom"; +import { Grid } from "../../../../components/grid/Grid"; +import NavigateNextIcon from "@mui/icons-material/NavigateNext"; +import { useDispatch, useSelector } from "react-redux"; +import { provinceGetUserByKey } from "../../../province/services/province-get-user-by-key"; +import { useState } from "react"; +import { SPACING } from "../../../../data/spacing"; +import { SimpleTable } from "../../../../components/simple-table/SimpleTable"; +import EditIcon from "@mui/icons-material/Edit"; + +import { + DRAWER, + LOADING_END, + LOADING_START, +} from "../../../../lib/redux/slices/appSlice"; +import { inspectorChangeUserState } from "../../services/inspector-change-user-state"; +import { InspectorEditUserProfile } from "../inspector-edit-user-profile/InspectorEditUserProfile"; +import { InspectorEditOperator } from "../inspector-edit-operator/InspectorEditOperator"; +import { InspectorEditKillHouseVet } from "../inspector-edit-killhouse-vet/InspectorEditKillHousevet"; +import { InspectorEditDriver } from "../inspector-edit-driver/InspectorEditDriver"; +import { CitySubmitTenantForm } from "../../../city/components/city-submit-tenant-form/CitySubmitTenantForm"; +// import { inspectorUpdateUserProfile } from "../../services/inspector-update-user-profile"; +import InfoIcon from "@mui/icons-material/Info"; +import { InspectorEditAviculture } from "../inspector-edit-aviculture/InspectorEditAviculture"; +import { format } from "date-fns-jalali"; +import { ProvinceEditTenant } from "../province-edit-tenant/ProvinceEditTenant"; + +export const ProvinceUserFileInfo = () => { + const { userid } = useParams(); + const dispatch = useDispatch(); + const navigate = useNavigate(); + const [dataTable, setDataTable] = useState([]); + + const { provinceUserInfo } = useSelector((state) => state.provinceSlice); + + useEffect(() => { + dispatch(LOADING_START()); + dispatch(provinceGetUserByKey(userid)).then((r) => { + dispatch(LOADING_END()); + }); + }, []); + + const updateData = () => { + dispatch(provinceGetUserByKey(userid)).then((r) => { + dispatch(LOADING_END()); + }); + }; + + useEffect(() => { + const userRoles = provinceUserInfo?.profile?.role?.map((item, i) => { + let name = ""; + switch (item) { + case "ProvinceOperator": + name = "اپراتور تخصیص استان"; + break; + case "CityOperator": + name = "اپراتور شهرستان"; + break; + case "KillHouseVet": + name = "دامپزشک کشتارگاه"; + break; + case "VetFarm": + name = "دامپزشک"; + break; + case "Poultry": + name = "مرغدار"; + break; + case "KillHouse": + name = "کشتارگاه"; + break; + case "Vet": + name = "دامپزشک"; + break; + case "ProvinceInspector": + name = "بازرس استان"; + break; + case "ProvinceFinancial": + name = "اپراتور مالی"; + break; + case "Driver": + name = "راننده"; + break; + case "Admin": + name = "ادمین"; + break; + default: + name = "کاربر پایه"; + break; + } + return
    {name}
    ; + }); + + const userProfilePic = + provinceUserInfo?.profile?.image?.length > 5 ? ( + + img + + ) : ( + "موجود نیست" + ); + const b = [ + [ + provinceUserInfo?.profile?.fullname + ? provinceUserInfo?.profile?.fullname + : provinceUserInfo?.profile?.firstName + + " " + + provinceUserInfo?.profile?.lastName, + userRoles, + provinceUserInfo?.profile?.mobile, + provinceUserInfo?.profile?.birthday + ? format(new Date(provinceUserInfo?.profile?.birthday), "yyyy/MM/dd") + : "نامشخص", + provinceUserInfo?.profile?.city, + + {provinceUserInfo?.profile?.password} + , + userProfilePic, + { + // dispatch(inspectorUpdateUserProfile()); + dispatch( + DRAWER({ + title: "ویرایش پروفایل کاربر", + right: !(window.innerWidth <= 600), + bottom: window.innerWidth <= 600, + content: ( + + ), + }) + ); + }} + > + + , + ], + ]; + + setDataTable(b); + }, [provinceUserInfo]); + + return ( + <> + + navigate(-1)} + > + + بازگشت + + + + + + + + + {provinceUserInfo?.rolesData?.map((item, i) => { + if (Object.keys(item).includes("ProvinceOperator")) { + return ( + <> + + { + dispatch( + DRAWER({ + title: "ویرایش اطلاعات اپراتور", + right: !(window.innerWidth <= 600), + bottom: window.innerWidth <= 600, + content: ( + + ), + }) + ); + }} + > + + + , + + { + dispatch(LOADING_START()); + dispatch( + inspectorChangeUserState({ + type: + item.ProvinceOperator.trash === true + ? "Activate" + : "Deactivate", + role_data_key: + item.ProvinceOperator.key, + role: "ProvinceOperator", + }) + ).then((r) => { + dispatch(LOADING_END()); + window.location.reload(false); + }); + }} + /> + } + /> + , + ], + ]} + /> + + ); + } else if (Object.keys(item).includes("ProvinceInspector")) { + return ( + + { + dispatch( + DRAWER({ + title: "ویرایش اطلاعات بازرس استان", + right: !(window.innerWidth <= 600), + bottom: window.innerWidth <= 600, + content: ( + + ), + }) + ); + }} + > + + + , + + { + dispatch(LOADING_START()); + dispatch( + inspectorChangeUserState({ + type: + item.ProvinceInspector.trash === true + ? "Activate" + : "Deactivate", + role_data_key: item.ProvinceInspector.key, + role: "ProvinceInspector", + }) + ).then((r) => { + dispatch(LOADING_END()); + window.location.reload(false); + }); + }} + /> + } + /> + , + ], + ]} + /> + ); + } else if (Object.keys(item).includes("CityOperator")) { + return ( + <> + + { + dispatch( + DRAWER({ + title: "ویرایش اطلاعات اپراتور", + right: !(window.innerWidth <= 600), + bottom: window.innerWidth <= 600, + content: ( + + ), + }) + ); + }} + > + + + , + + { + dispatch(LOADING_START()); + dispatch( + inspectorChangeUserState({ + type: + item.CityOperator.trash === true + ? "Activate" + : "Deactivate", + role_data_key: item.CityOperator.key, + role: "CityOperator", + }) + ).then((r) => { + dispatch(LOADING_END()); + window.location.reload(false); + }); + }} + /> + } + /> + , + ], + ]} + /> + + + + ); + } else if (Object.keys(item).includes("VetFarm")) { + return ( + <> + + { + dispatch( + DRAWER({ + title: "ویرایش اطلاعات اپراتور", + right: !(window.innerWidth <= 600), + bottom: window.innerWidth <= 600, + content: ( + + ), + }) + ); + }} + > + + + , + + { + dispatch(LOADING_START()); + dispatch( + inspectorChangeUserState({ + type: + item.VetFarm.trash === true + ? "Activate" + : "Deactivate", + role_data_key: item.VetFarm.key, + role: "Vet", + }) + ).then((r) => { + dispatch(LOADING_END()); + window.location.reload(false); + }); + }} + /> + } + /> + , + ], + ]} + /> + + + + ); + } else if (Object.keys(item).includes("KillHouse")) { + return ( + <> + {" "} + + { + dispatch( + DRAWER({ + title: "ویرایش اطلاعات کشتارگاه", + right: !(window.innerWidth <= 600), + bottom: window.innerWidth <= 600, + content: ( + + ), + }) + ); + }} + > + + + , + + { + dispatch(LOADING_START()); + dispatch( + inspectorChangeUserState({ + type: + item.KillHouse?.trash === true + ? "Activate" + : "Deactivate", + role_data_key: item.KillHouse?.key, + role: "KillHouse", + }) + ).then((r) => { + dispatch(LOADING_END()); + window.location.reload(false); + }); + }} + /> + } + /> + , + ], + ]} + /> + + + ); + } else if (Object.keys(item).includes("Poultry")) { + return ( + <> + + { + dispatch( + DRAWER({ + title: "ویرایش اطلاعات مرغدار", + right: !(window.innerWidth <= 600), + bottom: window.innerWidth <= 600, + content: ( + + ), + }) + ); + }} + > + + + , + + { + dispatch(LOADING_START()); + dispatch( + inspectorChangeUserState({ + type: + item.Poultry.trash === true + ? "Activate" + : "Deactivate", + role_data_key: item.Poultry.key, + role: "Poultry", + }) + ).then((r) => { + dispatch(LOADING_END()); + window.location.reload(false); + }); + }} + /> + } + /> + , + ], + ]} + /> + + + + {Object.keys(item.Poultry?.poultryTenant).length > 0 ? ( + + اطلاعات مستاجر مرغدار + + + } + expandable + columns={[ + "شناسه یکتا", + "نام کامل", + "تلفن همراه", + "کد ملی", + ]} + data={[ + [ + item.Poultry.poultryTenant?.breedingUniqueId, + item.Poultry.poultryTenant?.fullName, + item.Poultry.poultryTenant?.mobile, + item.Poultry.poultryTenant?.nationalId, + ], + ]} + /> + ) : ( + !item.Poultry.poultryOwner.length > 0 && ( + + + + مرغدار مستاجر ندارد + + + + ) + )} + + ); + } else if (Object.keys(item).includes("ProvinceFinancial")) { + return ( + <> + + { + dispatch( + DRAWER({ + title: "ویرایش اطلاعات اپراتور مالی", + right: !(window.innerWidth <= 600), + bottom: window.innerWidth <= 600, + content: ( + + ), + }) + ); + }} + > + + + , + + { + dispatch(LOADING_START()); + dispatch( + inspectorChangeUserState({ + type: + item.ProvinceFinancial.trash === true + ? "Activate" + : "Deactivate", + role_data_key: + item.ProvinceFinancial.key, + role: "ProvinceFinancial", + }) + ).then((r) => { + dispatch(LOADING_END()); + window.location.reload(false); + }); + }} + /> + } + /> + , + ], + ]} + /> + + + + ); + } else if (Object.keys(item).includes("KillHouseVet")) { + return ( + <> + + { + dispatch( + DRAWER({ + title: "ویرایش اطلاعات دامپزشک کشتارگاه", + right: !(window.innerWidth <= 600), + bottom: window.innerWidth <= 600, + content: ( + + ), + }) + ); + }} + > + + + , + + { + dispatch(LOADING_START()); + dispatch( + inspectorChangeUserState({ + type: + item.KillHouseVet.vet.trash === true + ? "Activate" + : "Deactivate", + role_data_key: item.KillHouseVet.key, + role: "KillHouseVet", + }) + ).then((r) => { + dispatch(LOADING_END()); + window.location.reload(false); + }); + }} + /> + } + /> + , + ], + ]} + /> + + + + ); + } else if (Object.keys(item).includes("Driver")) { + return ( + <> + + { + dispatch( + DRAWER({ + title: "ویرایش اطلاعات راننده", + right: !(window.innerWidth <= 600), + bottom: window.innerWidth <= 600, + content: ( + + ), + }) + ); + }} + > + + + , + + { + dispatch(LOADING_START()); + dispatch( + inspectorChangeUserState({ + type: + item.Driver.trash === true + ? "Activate" + : "Deactivate", + role_data_key: item.Driver.key, + role: "Driver", + }) + ).then((r) => { + dispatch(LOADING_END()); + window.location.reload(false); + }); + }} + /> + } + /> + , + ], + ]} + /> + + + + ); + } + + return null; + })} + + + + + ); +}; diff --git a/src/features/inspector/components/province-users/ProvinceUsers.js b/src/features/inspector/components/province-users/ProvinceUsers.js new file mode 100644 index 0000000..93eedc5 --- /dev/null +++ b/src/features/inspector/components/province-users/ProvinceUsers.js @@ -0,0 +1,137 @@ +import { Grid } from "../../../../components/grid/Grid"; +import { SPACING } from "../../../../data/spacing"; +import { UserPagination } from "../users-pagination/UsersPagination"; + +export const ProvinceUsers = () => { + // const navigate = useNavigate(); + + // const { provinceUsers } = useSelector((state) => state.provinceSlice); + + // useEffect(() => { + // dispatch(LOADING_START()); + // dispatch(provinceGetUserProfiles()).then((r) => { + // dispatch(LOADING_END()); + // }); + // }, []); + + // const [filteredData, setFilteredData] = useState(provinceUsers); + // useEffect(() => { + // if (rolesSelected.length > 0) { + // const newUsers = provinceUsers?.filter((item, i) => { + // return item?.profile?.role.includes(...rolesSelected); + // }); + + // setFilteredData(newUsers); + // } else if (justBaseUsers) { + // const newUsers = provinceUsers?.filter((item, i) => { + // return item?.profile?.role.length === 0; + // }); + // setFilteredData(newUsers); + // } else { + // setFilteredData(provinceUsers); + // } + + // const d = filteredData?.map((item, i) => { + // return [ + // i + 1, + // item?.profile?.fullname + // ? item?.profile?.fullname + // : item?.profile?.firstName + " " + item?.profile?.lastName, + // + // {!(item?.profile?.role.length > 0) && "کاربر پایه"} + // {item?.profile?.role?.map((item, i) => { + // var name = ""; + // switch (item) { + // case "ProvinceOperator": + // name = "اپراتور تخصیص استان"; + // break; + // case "CityOperator": + // name = "اپراتور شهرستان"; + // break; + // case "KillHouseVet": + // name = "دامپزشک کشتارگاه"; + // break; + // case "VetFarm": + // name = "دامپزشک"; + // break; + // case "Poultry": + // name = "مرغدار"; + // break; + // case "KillHouse": + // name = "کشتارگاه"; + // break; + // case "Vet": + // name = "دامپزشک"; + // break; + // case "ProvinceInspector": + // name = "بازرس استان"; + // break; + // case "ProvinceFinancial": + // name = "اپراتور مالی"; + // break; + // case "Driver": + // name = "راننده"; + // break; + // case "Admin": + // name = "ادمین"; + // break; + + // default: + // break; + // } + // return [{name}]; + // })} + // , + // item?.profile?.mobile, + // item?.profile?.baseOrder, + // item?.profile?.city, + // + // {item?.profile?.password} + // , + // + // + // { + // navigate(ROUTE_PROVINCE_USER_FILE + item?.profile?.key); + // }} + // > + // + // + // + // , + // ]; + // }); + + // setDataTable(d); + // }, [provinceUsers, rolesSelected, filteredData, justBaseUsers]); + + return ( + + + {/* */} + + + + ); +}; diff --git a/src/features/inspector/components/users-pagination/UsersPagination.js b/src/features/inspector/components/users-pagination/UsersPagination.js new file mode 100644 index 0000000..0bdc521 --- /dev/null +++ b/src/features/inspector/components/users-pagination/UsersPagination.js @@ -0,0 +1,387 @@ +import React, { useContext, useEffect, useState } from "react"; +import { + Button, + IconButton, + List, + ListItemButton, + ListItemIcon, + ListItemText, + Popover, + TextField, + Tooltip, + Typography, +} from "@mui/material"; +import { useDispatch, useSelector } from "react-redux"; +import axios from "axios"; +import { AppContext } from "../../../../contexts/AppContext"; +import { + DRAWER, + LOADING_END, + LOADING_START, +} from "../../../../lib/redux/slices/appSlice"; +import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl"; +import { Grid } from "../../../../components/grid/Grid"; +import ResponsiveTable from "../../../../components/responsive-table/ResponsiveTable"; +import { useNavigate } from "react-router-dom"; +import { SET_ADMIN_TOKEN } from "../../../../lib/redux/slices/userSlice"; +import VpnKeyIcon from "@mui/icons-material/VpnKey"; +import { loginWithPassword } from "../../../authentication/services/login"; +import ContactPageIcon from "@mui/icons-material/ContactPage"; +import TuneIcon from "@mui/icons-material/Tune"; +import { + ROUTE_ADMINX_OPERATOR_USER_FILE, + ROUTE_PROVINCE_USER_FILE, + ROUTE_SUPER_ADMIN_OPERATOR_USER_FILE, +} from "../../../../routes/routes"; +import { ProvinceSubmitUser } from "../../../province/components/province-submit-user/ProvinceSubmitUser"; +import { RiFileExcel2Fill } from "react-icons/ri"; +import { SPACING } from "../../../../data/spacing"; +import { SelectCheck } from "../../../../components/select-check/SelectCheck"; +import { RiSearchLine } from "react-icons/ri"; + +export const UserPagination = () => { + const navigate = useNavigate(); + const authToken = useSelector((state) => state.userSlice.authToken); + + useContext(AppContext); + const dispatch = useDispatch(); + + const UserActions = ({ item }) => { + const [anchorEl, setAnchorEl] = useState(null); + const open = Boolean(anchorEl); + + const handleOpen = (event) => { + setAnchorEl(event.currentTarget); + }; + + const handleClose = () => { + setAnchorEl(null); + }; + + const handleNavigateToFile = () => { + navigate( + getRoleFromUrl() === "AdminX" + ? ROUTE_ADMINX_OPERATOR_USER_FILE + item?.key + : getRoleFromUrl() === "SuperAdmin" + ? ROUTE_SUPER_ADMIN_OPERATOR_USER_FILE + item?.key + : getRoleFromUrl() === "ProvinceOperator" + ? ROUTE_PROVINCE_USER_FILE + item?.key + : ROUTE_PROVINCE_USER_FILE + item?.key + ); + handleClose(); + }; + + const handleLoginToPanel = () => { + dispatch(SET_ADMIN_TOKEN(authToken)); + dispatch(LOADING_START()); + dispatch( + loginWithPassword({ + mobile: item?.mobile, + password: item?.password, + }) + ).then(() => { + dispatch(LOADING_END()); + navigate("/"); + }); + handleClose(); + }; + + const canLogin = + getRoleFromUrl() === "AdminX" || getRoleFromUrl() === "SuperAdmin"; + + return ( + + + + + + + + + + + + + + پرونده کاربر + + } + /> + + {canLogin && ( + + + + + + ورود به پنل + + } + /> + + )} + + + + ); + }; + const handleTextChange = (event) => { + setTextValue(event.target.value); + }; + + const [rolesSelected, setRolesSelected] = useState([]); + const rolesQueryParam = rolesSelected.length ? rolesSelected.join() : ""; + + const [data, setData] = useState([]); + const [totalRows, setTotalRows] = useState(0); + const [perPage, setPerPage] = useState(10); + const [textValue, setTextValue] = useState(""); + const [page, setPage] = useState(1); + const [tableData, setTableData] = useState([]); + + const fetchApiData = async (page) => { + dispatch(LOADING_START()); + const response = await axios.get( + `system_user_profile/?users_info&search=filter&value=${ + textValue || "" + }&page=${page}&page_size=${perPage}&roles=${rolesQueryParam}` + ); + dispatch(LOADING_END()); + setData(response.data.results); + setTotalRows(response.data.count); + }; + + const handlePageChange = (page) => { + fetchApiData(page); + setPage(page); + }; + + const handlePerRowsChange = (perRows) => { + setPerPage(perRows); + setPage(1); + }; + + const getPassword = (item) => { + if (getRoleFromUrl() !== "ProvinceOperator") { + return [item?.password]; + } else { + return []; + } + }; + const getPasswordColumn = () => { + if (getRoleFromUrl() !== "ProvinceOperator") { + return ["کلمه عبور"]; + } else { + return []; + } + }; + + // const updateTable = () => { + // fetchApiData(page !== 0 ? page : 1); + // }; + + useEffect(() => { + const d = data?.map((item, i) => { + return [ + page === 1 ? i + 1 : i + perPage * (page - 1) + 1, + item?.fullname + ? item?.fullname + : item?.firstName + " " + item?.lastName, + + {!(item?.role?.length > 0) && "کاربر پایه"} + {item?.role?.map((item, i) => { + let name = ""; + switch (item) { + case "ProvinceOperator": + name = "اپراتور تخصیص استان"; + break; + case "CityOperator": + name = "اپراتور شهرستان"; + break; + case "KillHouseVet": + name = "دامپزشک کشتارگاه"; + break; + case "VetFarm": + name = "دامپزشک"; + break; + case "Poultry": + name = "مرغدار"; + break; + case "KillHouse": + name = "کشتارگاه"; + break; + case "Vet": + name = "دامپزشک"; + break; + case "ProvinceInspector": + name = "بازرس استان"; + break; + case "ProvinceFinancial": + name = "اپراتور مالی"; + break; + case "Driver": + name = "راننده"; + break; + case "Admin": + name = "ادمین"; + break; + + default: + break; + } + return {name}; + })} + , + item?.mobile, + item?.baseOrder, + item?.city, + ...getPassword(item), + , + ]; + }); + + setTableData(d); + }, [data]); + + useEffect(() => { + fetchApiData(1); + }, [dispatch, perPage]); + + const handleSubmit = async (event) => { + event.preventDefault(); + dispatch(LOADING_START()); + + try { + const response = await axios.get( + `system_user_profile/?users_info&search=filter&value=${ + textValue || "" + }&page=${page}&page_size=${perPage}&roles=${rolesQueryParam}` + ); + setData(response.data.results); + setTotalRows(response.data.count); + dispatch(LOADING_END()); + } catch (error) { + console.error("Error fetching data:", error); + } + }; + + return ( + + + کاربران + + setRolesSelected(e)} + options={[ + { label: "اپراتور تخصیص استان", value: "ProvinceOperator" }, + { label: "اپراتور شهرستان", value: "CityOperator" }, + { label: "بازرس استان", value: "ProvinceInspector" }, + { label: "دامپزشک", value: "VetFarm" }, + { label: "کشتارگاه", value: "KillHouse" }, + { label: "دامپزشک کشتارگاه", value: "KillHouseVet" }, + { label: "مرغدار", value: "Poultry" }, + { label: "اپراتور مالی", value: "ProvinceFinancial" }, + { label: "راننده", value: "Driver" }, + { label: "ادمین", value: "Admin" }, + ]} + /> + +
    + + + + +
    + + + + + + + +
    + + +
    + ); +}; diff --git a/src/features/inspector/services/inspector-change-user-state.js b/src/features/inspector/services/inspector-change-user-state.js new file mode 100644 index 0000000..3dfbcc1 --- /dev/null +++ b/src/features/inspector/services/inspector-change-user-state.js @@ -0,0 +1,12 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; + +export const inspectorChangeUserState = createAsyncThunk( + "INSPECTOR_CHANGE_USER_STATE", + async (d) => { + const { data, status } = await axios.delete("system_user_profile/0/", { + params: d, + }); + return { data, status }; + } +); diff --git a/src/features/inspector/services/inspector-delete-killhouse-vet.js b/src/features/inspector/services/inspector-delete-killhouse-vet.js new file mode 100644 index 0000000..271bca5 --- /dev/null +++ b/src/features/inspector/services/inspector-delete-killhouse-vet.js @@ -0,0 +1,20 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const inspectorDeleteKillhouseVetService = createAsyncThunk( + "INSPECTOR_SET_KILLHOUSE_VET_SERVICE", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + try { + const { data, status } = await axios.delete("kill_house_vet/0/", { + params: d, + }); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e.response.data.result }; + } + } +); diff --git a/src/features/inspector/services/inspector-delete-vet-farm.js b/src/features/inspector/services/inspector-delete-vet-farm.js new file mode 100644 index 0000000..d0fde85 --- /dev/null +++ b/src/features/inspector/services/inspector-delete-vet-farm.js @@ -0,0 +1,20 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const inspectorDeleteVetFarmService = createAsyncThunk( + "INSPECTOR_DELETE_VET_FARM_SERVICE", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + try { + const { data, status } = await axios.delete("vet_farm/0/", { + params: d, + }); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e.response.data.result }; + } + } +); diff --git a/src/features/inspector/services/inspector-get-kill-houses.js b/src/features/inspector/services/inspector-get-kill-houses.js new file mode 100644 index 0000000..affe833 --- /dev/null +++ b/src/features/inspector/services/inspector-get-kill-houses.js @@ -0,0 +1,13 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { getRoleFromUrl } from "../../../utils/getRoleFromUrl"; + +export const inspectorGetKillHousesService = createAsyncThunk( + "INSPECTOR_GET_KILL_HOUSES", + async () => { + const { data, status } = await axios.get( + `kill_house/?role=${getRoleFromUrl()}` + ); + return { data, status }; + } +); diff --git a/src/features/inspector/services/inspector-get-poultry-science-report.js b/src/features/inspector/services/inspector-get-poultry-science-report.js new file mode 100644 index 0000000..65d5736 --- /dev/null +++ b/src/features/inspector/services/inspector-get-poultry-science-report.js @@ -0,0 +1,9 @@ +import axios from "axios"; +import { getRoleFromUrl } from "../../../utils/getRoleFromUrl"; + +export const inspectorGetPoultryScienceReport = async (page, pageSize) => { + const response = await axios.get( + `poultry_science_report/?role=${getRoleFromUrl()}&page=${page}&page_size=${pageSize}` + ); + return response.data; +}; diff --git a/src/features/inspector/services/inspector-get-profile.js b/src/features/inspector/services/inspector-get-profile.js new file mode 100644 index 0000000..925483c --- /dev/null +++ b/src/features/inspector/services/inspector-get-profile.js @@ -0,0 +1,10 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; + +export const inspectorGetProfile = createAsyncThunk( + "INSPECTOR_GET_PROFILE", + async () => { + const { data, status } = await axios.get("inspector_operator/0/?profile"); + return { data, status }; + } +); diff --git a/src/features/inspector/services/inspector-get-reporting.js b/src/features/inspector/services/inspector-get-reporting.js new file mode 100644 index 0000000..75c5e73 --- /dev/null +++ b/src/features/inspector/services/inspector-get-reporting.js @@ -0,0 +1,12 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; + +export const inspectorGetReporting = createAsyncThunk( + "INSPECTOR_GET_REPORTING", + async (d) => { + const { data, status } = await axios.get( + "reporting-all-poultry/?type=filter&value=" + d + ); + return { data, status }; + } +); diff --git a/src/features/inspector/services/inspector-new-requests.js b/src/features/inspector/services/inspector-new-requests.js new file mode 100644 index 0000000..0724699 --- /dev/null +++ b/src/features/inspector/services/inspector-new-requests.js @@ -0,0 +1,12 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; + +export const inspectorGetNewRequests = createAsyncThunk( + "INSPECTOR_GET_NEW_REQUESTS", + async () => { + const { data, status } = await axios.get( + "Poultry_Request/?role=ProvinceInspector" + ); + return { data, status }; + } +); diff --git a/src/features/inspector/services/inspector-set-killhouse-vet.js b/src/features/inspector/services/inspector-set-killhouse-vet.js new file mode 100644 index 0000000..4072453 --- /dev/null +++ b/src/features/inspector/services/inspector-set-killhouse-vet.js @@ -0,0 +1,18 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const inspectorSetKillhouseVetService = createAsyncThunk( + "INSPECTOR_SET_KILLHOUSE_VET_SERVICE", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + try { + const { data, status } = await axios.post("kill_house_vet/", d); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e.response.data.result }; + } + } +); diff --git a/src/features/inspector/services/inspector-update-user-profile.js b/src/features/inspector/services/inspector-update-user-profile.js new file mode 100644 index 0000000..bb7fc0a --- /dev/null +++ b/src/features/inspector/services/inspector-update-user-profile.js @@ -0,0 +1,10 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; + +export const inspectorUpdateUserProfile = createAsyncThunk( + "INSPECTOR_UPDATE_USER_PROFILE", + async (d) => { + const { data, status } = await axios.put("system_user_profile/0/", d); + return { data, status }; + } +); diff --git a/src/features/inspector/services/manage-farm-get-farms.js b/src/features/inspector/services/manage-farm-get-farms.js new file mode 100644 index 0000000..2d2a3ef --- /dev/null +++ b/src/features/inspector/services/manage-farm-get-farms.js @@ -0,0 +1,14 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const manageFarmGetFarmsService = createAsyncThunk( + "MANAGE_FARM_GET_FARMS", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + const { data, status } = await axios.get("vet/"); + dispatch(LOADING_END()); + + return { data, status }; + } +); diff --git a/src/features/inspector/services/province-update-tenant.js b/src/features/inspector/services/province-update-tenant.js new file mode 100644 index 0000000..eb19eb9 --- /dev/null +++ b/src/features/inspector/services/province-update-tenant.js @@ -0,0 +1,18 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const provinceUpdateTenantService = createAsyncThunk( + "PROVINCE_UPDATE_TENANT_SERVICE", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + try { + const { data, status } = await axios.put("poultry_tenant_update/0/", d); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e.response.data.result }; + } + } +); diff --git a/src/features/jahad/components/jahad-illegal-killing/JahadIllegalKillingComponent.js b/src/features/jahad/components/jahad-illegal-killing/JahadIllegalKillingComponent.js new file mode 100644 index 0000000..f36eecc --- /dev/null +++ b/src/features/jahad/components/jahad-illegal-killing/JahadIllegalKillingComponent.js @@ -0,0 +1,71 @@ +import { useEffect, useState } from "react"; +import { useDispatch, useSelector } from "react-redux"; +import { AdvancedTable } from "../../../../components/advanced-table/AdvancedTable"; +import { Grid } from "../../../../components/grid/Grid"; +import { formatJustDate } from "../../../../utils/formatTime"; +import { jahadIllegalKillingService } from "../../services/jahad-illegal-killing"; + +export const JahadIllegalKillingComponent = () => { + const dispatch = useDispatch(); + const { jahadIllegalKilling } = useSelector((state) => state.jahadSlice); + + const [dataTable, setDataTable] = useState([]); + + useEffect(() => { + dispatch(jahadIllegalKillingService()); + }, []); + + useEffect(() => { + const d = jahadIllegalKilling?.map((item, i) => { + const killedNumber = item.quantity - item.losses - item.leftOver; + return [ + i + 1, + item.poultry.unitName, + item.poultry.userprofile.baseOrder, + item.poultry.userprofile.mobile, + item.hall, + item.period, + formatJustDate(item?.createDate), + formatJustDate(item?.date), + item.chickenBreed, + item.age, + item.quantity, + `${item.losses} (%${((item.losses * 100) / item.quantity).toFixed(0)})`, + killedNumber + + ` (%${((killedNumber * 100) / item.quantity).toFixed(0)})`, + `${item.leftOver} (%${((item.leftOver * 100) / item.quantity).toFixed( + 0 + )})`, + item.message, + ]; + }); + + setDataTable(d); + }, [jahadIllegalKilling]); + + return ( + + + + ); +}; diff --git a/src/features/jahad/components/jahad-kill-stats/JahadKillStatsComponent.js b/src/features/jahad/components/jahad-kill-stats/JahadKillStatsComponent.js new file mode 100644 index 0000000..e8a49bc --- /dev/null +++ b/src/features/jahad/components/jahad-kill-stats/JahadKillStatsComponent.js @@ -0,0 +1,141 @@ +import React, { useEffect, useState } from "react"; +import { Bar, Line } from "react-chartjs-2"; +import { AdvancedTable } from "../../../../components/advanced-table/AdvancedTable"; +import { Grid } from "../../../../components/grid/Grid"; +import { Chart as ChartJs } from "chart.js/auto"; +import { defaults } from "chart.js"; +import { IconButton } from "@mui/material"; +import PictureAsPdfIcon from "@mui/icons-material/PictureAsPdf"; +import { useDispatch, useSelector } from "react-redux"; +import { killsDailyReportService } from "../../services/kills-daily-report-service"; +import { format } from "date-fns-jalali"; +import { SPACING } from "../../../../data/spacing"; +defaults.font.family = "iranyekan"; +console.log(ChartJs); + +export const JahadKillStatsComponent = () => { + const dispatch = useDispatch(); + + const { killsDailyReport } = useSelector((state) => state.jahadSlice); + + const [tableData, setTableData] = useState([]); + + const [barChartData] = useState({ + labels: killsDailyReport?.map((item) => + format(new Date(item.date), "yyyy/MM/dd") + ), + datasets: [ + { + label: "درخواست کشتار", + data: killsDailyReport?.map((item) => item.totalPoultryRequestQuantity), + backgroundColor: "#ff6384", + }, + { + label: "تایید شده", + data: killsDailyReport?.map((item) => item.acceptedRequestQuantity), + backgroundColor: "#36a2eb", + }, + ], + options: { + title: { + display: true, + text: "Monthly Sales and Expenses Report", + fontSize: 18, + }, + legend: { + position: "bottom", + }, + scales: { + yAxes: [ + { + ticks: { + beginAtZero: true, + }, + }, + ], + }, + }, + }); + const [chartData] = useState({ + labels: killsDailyReport?.map((item) => + format(new Date(item.date), "yyyy/MM/dd") + ), + datasets: [ + { + label: "میانگین وزن", + data: killsDailyReport?.map((item) => item.indexWeight), + borderColor: "#ff6384", + fill: false, + }, + ], + options: { + title: { + display: true, + text: "Monthly Sales Report", + fontSize: 18, + }, + legend: { + position: "bottom", + }, + tooltips: { + mode: "index", + intersect: false, + }, + }, + }); + + useEffect(() => { + dispatch(killsDailyReportService()); + }, []); + + useEffect(() => { + const d = killsDailyReport?.map((item, i) => { + return [ + item.province, + item.date, + item.indexWeight, + item.remainQuantity, + item.provinceQuantity, + item.countryQuantity, + + + + + , + ]; + }); + setTableData(d); + }, [killsDailyReport]); + + return ( + + + + + + + + + + + + + ); +}; diff --git a/src/features/jahad/components/jahad-profile/JahadProfile.js b/src/features/jahad/components/jahad-profile/JahadProfile.js new file mode 100644 index 0000000..883f878 --- /dev/null +++ b/src/features/jahad/components/jahad-profile/JahadProfile.js @@ -0,0 +1,58 @@ +import React, { useEffect } from "react"; +import { useDispatch, useSelector } from "react-redux"; +import { + LOADING_END, + LOADING_START, +} from "../../../../lib/redux/slices/appSlice"; +import { jahadGetProfile } from "../../services/jahadGetProfile"; +import { Box } from "@mui/material"; +import { Grid } from "../../../../components/grid/Grid"; +import { SPACING } from "../../../../data/spacing"; +import { SimpleTable } from "../../../../components/simple-table/SimpleTable"; + +export const JahadProfile = () => { + const dispatch = useDispatch(); + const { profile } = useSelector((state) => state.jahadSlice); + + useEffect(() => { + dispatch(LOADING_START()); + dispatch(jahadGetProfile()).then((r) => { + dispatch(LOADING_END()); + }); + }, []); + + return ( + + + + + <> + + + + {/* + + */} + + + + + + ); +}; diff --git a/src/features/jahad/services/jahad-illegal-killing.js b/src/features/jahad/services/jahad-illegal-killing.js new file mode 100644 index 0000000..1c3e7e3 --- /dev/null +++ b/src/features/jahad/services/jahad-illegal-killing.js @@ -0,0 +1,10 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; + +export const jahadIllegalKillingService = createAsyncThunk( + "JAHAD_ILLEGAL_KILLING_SERVICE", + async (d) => { + const { data, status } = await axios.get("poultry_hatching/?illegal"); + return { data, status }; + } +); diff --git a/src/features/jahad/services/jahadGetProfile.js b/src/features/jahad/services/jahadGetProfile.js new file mode 100644 index 0000000..1b86ea3 --- /dev/null +++ b/src/features/jahad/services/jahadGetProfile.js @@ -0,0 +1,10 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; + +export const jahadGetProfile = createAsyncThunk( + "JAHAD_GET_PROFILE", + async (d) => { + const { data, status } = await axios.get("jahad/0/?profile"); + return { data, status }; + } +); diff --git a/src/features/jahad/services/kills-daily-report-service.js b/src/features/jahad/services/kills-daily-report-service.js new file mode 100644 index 0000000..6b41d61 --- /dev/null +++ b/src/features/jahad/services/kills-daily-report-service.js @@ -0,0 +1,10 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; + +export const killsDailyReportService = createAsyncThunk( + "KILLS_DAILY_REPORT_SERVICE", + async (d) => { + const { data, status } = await axios.get("letter_report/?daily_report"); + return { data, status }; + } +); diff --git a/src/features/live-stock-support/components/live-stock-all-freezing-requests/LiveStockAllFreezingRequests.js b/src/features/live-stock-support/components/live-stock-all-freezing-requests/LiveStockAllFreezingRequests.js new file mode 100644 index 0000000..ba4e3dd --- /dev/null +++ b/src/features/live-stock-support/components/live-stock-all-freezing-requests/LiveStockAllFreezingRequests.js @@ -0,0 +1,323 @@ +import React, { useContext, useEffect, useState } from "react"; +import { Grid } from "../../../../components/grid/Grid"; +import { useDispatch, useSelector } from "react-redux"; +import { liveStockGetFreezingRequests } from "../../services/live-stock-get-freezing-requests"; +import { AppContext } from "../../../../contexts/AppContext"; +import moment from "moment"; +import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl"; +import ResponsiveTable from "../../../../components/responsive-table/ResponsiveTable"; +import { DatePicker } from "@mui/x-date-pickers"; +import { SPACING } from "../../../../data/spacing"; +import { + IconButton, + List, + ListItemButton, + ListItemIcon, + ListItemText, + Popover, + Tab, + Tabs, + TextField, +} from "@mui/material"; +import { formatJustDate } from "../../../../utils/formatTime"; +import { LiveStockEnterQuantityWeight } from "../live-stock-enter-quantity-weight/LiveStockEnterQuantityWeight"; +import { OPEN_MODAL } from "../../../../lib/redux/slices/appSlice"; +import { liveStockChangeFreezingState } from "../../services/live-stock-change-freezing-state"; +import TuneIcon from "@mui/icons-material/Tune"; +import CheckCircleOutlineIcon from "@mui/icons-material/CheckCircleOutline"; +import CancelOutlinedIcon from "@mui/icons-material/CancelOutlined"; + +export const LiveStockAllFreezingRequests = () => { + const dispatch = useDispatch(); + + const [value, setValue] = React.useState("0"); + + const handleChange = (event, newValue) => { + setValue(newValue); + }; + + const [tableData, setTableData] = useState([]); + const [tableDataArchived, setTableDataArchived] = useState([]); + const [openNotif] = useContext(AppContext); + + const { freezingRequests } = useSelector((state) => state.liveStockSlice); + + const [, , selectedDate1, setSelectedDate1, selectedDate2, setSelectedDate2] = + useContext(AppContext); + + const [actionMenuState, setActionMenuState] = useState({ + anchorPosition: null, + item: null, + }); + + useEffect(() => { + const currentDate = moment(new Date()).format("YYYY-MM-DD"); + setSelectedDate1(currentDate); + setSelectedDate2(currentDate); + }, []); + + const fetchApi = () => { + if (!selectedDate1 || !selectedDate2) { + return; + } + dispatch( + liveStockGetFreezingRequests({ + role: getRoleFromUrl(), + date1: selectedDate1, + date2: selectedDate2, + }) + ); + }; + + useEffect(() => { + fetchApi(); + }, [selectedDate1, selectedDate2]); + + const handleOpenActionMenu = (event, item) => { + const rect = event.currentTarget.getBoundingClientRect(); + setActionMenuState({ + anchorPosition: { + top: rect.bottom + window.scrollY, + left: rect.left + rect.width / 2 + window.scrollX, + }, + item, + }); + }; + + const handleCloseActionMenu = () => { + setActionMenuState({ + anchorPosition: null, + item: null, + }); + }; + + const handleApproveRequest = (item) => { + if (!item) { + return; + } + dispatch( + OPEN_MODAL({ + title: "تایید درخواست", + content: ( + + ), + }) + ); + handleCloseActionMenu(); + }; + + const handleRejectRequest = (item) => { + if (!item) { + return; + } + handleCloseActionMenu(); + dispatch( + liveStockChangeFreezingState({ + allocation_key: item?.key, + role: getRoleFromUrl(), + state: "rejected", + }) + ).then((r) => { + if (r.payload?.error) { + openNotif({ + vertical: "top", + horizontal: "center", + msg: r.payload.error, + severity: "error", + }); + } else { + fetchApi(); + openNotif({ + vertical: "top", + horizontal: "center", + msg: "عملیات با موفقیت انجام شد.", + severity: "success", + }); + } + handleCloseActionMenu(); + }); + }; + + useEffect(() => { + if (!freezingRequests || !Array.isArray(freezingRequests)) { + setTableData([]); + setTableDataArchived([]); + return; + } + + const d = freezingRequests + .filter((item) => item?.state === "pending") + .map((item, i) => { + return [ + i + 1, + item?.coldHouse?.name || "-", + item?.killHouseRequest?.killHouseRequestInfo?.poultryName || "-", + item?.killHouseRequest?.killHouseRequestInfo?.killHouseFullname || + "-", + item?.quantity || "-", + item?.weight || "-", + formatJustDate(item?.createDate) || "-", + "در انتظار تایید", + + handleOpenActionMenu(event, item)} + > + + + , + ]; + }); + + setTableData(d || []); + + const a = freezingRequests + .filter((item) => item?.state !== "pending") + .map((item, i) => { + let state = "تایید شده"; + if (item?.state === "rejected") { + state = "رد شده"; + } + return [ + i + 1, + item?.coldHouse?.name || "-", + item?.killHouseRequest?.killHouseRequestInfo?.poultryName || "-", + item?.killHouseRequest?.killHouseRequestInfo?.killHouseFullname || + "-", + item?.quantity || "-", + item?.weight || "-", + formatJustDate(item?.createDate) || "-", + state, + ]; + }); + + setTableDataArchived(a || []); + }, [freezingRequests]); + + const tableTitle = + value === "0" ? "تخصیص برای انجماد" : "تخصیص برای انجماد تایید / رد شده"; + + const tableFilters = ( + + + ( + + )} + value={selectedDate1} + onChange={(e) => { + setSelectedDate1(moment(e).format("YYYY-MM-DD")); + }} + /> + + + ( + + )} + value={selectedDate2} + onChange={(e) => { + setSelectedDate2(moment(e).format("YYYY-MM-DD")); + }} + /> + + + ); + + return ( + + + + + + + {value === "0" ? ( + + ) : ( + + )} + + + handleApproveRequest(actionMenuState.item)} + > + + + + + + handleRejectRequest(actionMenuState.item)} + > + + + + + + + + + ); +}; diff --git a/src/features/live-stock-support/components/live-stock-cold-house/LiveStockColdHouse.js b/src/features/live-stock-support/components/live-stock-cold-house/LiveStockColdHouse.js new file mode 100644 index 0000000..b93fe9b --- /dev/null +++ b/src/features/live-stock-support/components/live-stock-cold-house/LiveStockColdHouse.js @@ -0,0 +1,156 @@ +import React, { useContext, useEffect, useState } from "react"; +import { Grid } from "../../../../components/grid/Grid"; +import { useDispatch, useSelector } from "react-redux"; +import { liveStockGetInventoryData } from "../../services/live-stock-get-inventory-data"; +import { SimpleTable } from "../../../../components/simple-table/SimpleTable"; +import { formatJustDate } from "../../../../utils/formatTime"; +import { liveStockGetFreezingRequests } from "../../services/live-stock-get-freezing-requests"; +import moment from "moment"; +import { AppContext } from "../../../../contexts/AppContext"; +import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl"; +import { TextField, Typography } from "@mui/material"; +import { SPACING } from "../../../../data/spacing"; +import { DatePicker } from "@mui/x-date-pickers"; + +export const LiveStockColdHouseComponent = () => { + const { inventoryData } = useSelector((item) => item.liveStockSlice); + const [tableData, setTableData] = useState([]); + + const dispatch = useDispatch(); + useEffect(() => { + dispatch(liveStockGetInventoryData()); + }, []); + + const { freezingRequests } = useSelector((state) => state.liveStockSlice); + + const [, , selectedDate1, setSelectedDate1, selectedDate2, setSelectedDate2] = + useContext(AppContext); + + useEffect(() => { + const currentDate = moment(new Date()).format("YYYY-MM-DD"); + setSelectedDate1(currentDate); + setSelectedDate2(currentDate); + }, []); + + const fetchApi = () => { + if (!selectedDate1 || !selectedDate2) { + return; + } + dispatch( + liveStockGetFreezingRequests({ + role: getRoleFromUrl(), + date1: selectedDate1, + date2: selectedDate2, + }) + ); + }; + + useEffect(() => { + fetchApi(); + }, [selectedDate1, selectedDate2]); + + useEffect(() => { + if (!freezingRequests || !Array.isArray(freezingRequests)) { + setTableData([]); + return; + } + + const d = freezingRequests + .filter((item) => item?.state === "accepted") + .map((item, i) => { + return [ + i + 1, + item?.coldHouse?.name || "-", + item?.killHouseRequest?.killHouseRequestInfo?.poultryName || "-", + item?.killHouseRequest?.killHouseRequestInfo?.killHouseFullname || + "-", + item?.quantity || "-", + item?.weight || "-", + formatJustDate(item?.createDate) || "-", + "در انتظار تایید", + ]; + }); + + setTableData(d || []); + }, [freezingRequests]); + + const tableTitle = ( + + + تخصیص برای انجماد + + + + ( + + )} + value={selectedDate1} + onChange={(e) => { + setSelectedDate1(moment(e).format("YYYY-MM-DD")); + }} + /> + + + ( + + )} + value={selectedDate2} + onChange={(e) => { + setSelectedDate2(moment(e).format("YYYY-MM-DD")); + }} + /> + + + + ); + + return ( + + + + + + + + ); +}; diff --git a/src/features/live-stock-support/components/live-stock-enter-quantity-weight/LiveStockEnterQuantityWeight.js b/src/features/live-stock-support/components/live-stock-enter-quantity-weight/LiveStockEnterQuantityWeight.js new file mode 100644 index 0000000..0ab9ec4 --- /dev/null +++ b/src/features/live-stock-support/components/live-stock-enter-quantity-weight/LiveStockEnterQuantityWeight.js @@ -0,0 +1,92 @@ +import React, { useContext } from "react"; +import { useFormik } from "formik"; +import * as yup from "yup"; +import { TextField, Button } from "@mui/material"; +import { Grid } from "../../../../components/grid/Grid"; +import { liveStockChangeFreezingState } from "../../services/live-stock-change-freezing-state"; +import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl"; +import { useDispatch } from "react-redux"; +import { AppContext } from "../../../../contexts/AppContext"; +import { CLOSE_MODAL } from "../../../../lib/redux/slices/appSlice"; + +export const LiveStockEnterQuantityWeight = ({ item, fetchApi }) => { + const dispatch = useDispatch(); + const [openNotif] = useContext(AppContext); + + const validationSchema = yup.object({ + quantity: yup + .number() + .required("مقدار اجباری است") + .positive("عدد مثبت وارد کنید"), + weight: yup + .number() + .required("وزن اجباری است") + .positive("عدد مثبت وارد کنید"), + }); + const formik = useFormik({ + initialValues: { + quantity: item.quantity ? item?.quantity : "", + weight: item.weight ? item?.weight : "", + }, + validationSchema: validationSchema, + onSubmit: (values) => { + dispatch( + liveStockChangeFreezingState({ + allocation_key: item?.key, + role: getRoleFromUrl(), + state: "accepted", + accepted_quantity: parseInt(formik.values.quantity), + accepted_weight: parseInt(formik.values.weight), + }) + ).then((r) => { + if (r.payload.error) { + openNotif({ + vertical: "top", + horizontal: "center", + msg: r.payload.error, + severity: "error", + }); + } else { + fetchApi(); + dispatch(CLOSE_MODAL()); + openNotif({ + vertical: "top", + horizontal: "center", + msg: "عملیات با موفقیت انجام شد.", + severity: "success", + }); + } + }); + }, + }); + + return ( +
    + + + + + +
    + ); +}; diff --git a/src/features/live-stock-support/components/live-stock-profile/LiveStockProfile.js b/src/features/live-stock-support/components/live-stock-profile/LiveStockProfile.js new file mode 100644 index 0000000..e22ddac --- /dev/null +++ b/src/features/live-stock-support/components/live-stock-profile/LiveStockProfile.js @@ -0,0 +1,68 @@ +import React, { useEffect, useState } from "react"; +import { + LOADING_END, + LOADING_START, +} from "../../../../lib/redux/slices/appSlice"; +import { liveStockProfile } from "../../services/live-stock-profile"; +import { useDispatch } from "react-redux"; +import { Box } from "@mui/material"; +import { Grid } from "../../../../components/grid/Grid"; +import { SPACING } from "../../../../data/spacing"; +import { SimpleTable } from "../../../../components/simple-table/SimpleTable"; + +const LiveStockProfile = () => { + const [profileInfo, setProfileInfo] = useState(); + + const dispatch = useDispatch(); + + useEffect(() => { + dispatch(LOADING_START()); + dispatch(liveStockProfile()).then((r) => { + setProfileInfo(r.payload.data); + dispatch(LOADING_END()); + }); + }, []); + + return ( + + + + + <> + + + + + + + + + ); +}; + +export default LiveStockProfile; diff --git a/src/features/live-stock-support/services/live-stock-change-freezing-state.js b/src/features/live-stock-support/services/live-stock-change-freezing-state.js new file mode 100644 index 0000000..03200e7 --- /dev/null +++ b/src/features/live-stock-support/services/live-stock-change-freezing-state.js @@ -0,0 +1,21 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const liveStockChangeFreezingState = createAsyncThunk( + "LIVE_STOCK_CHANGE_FREEZING_STATE", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + try { + const { data, status } = await axios.put( + "check-cold-house-allocations/0/", + d + ); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e.response.data.result }; + } + } +); diff --git a/src/features/live-stock-support/services/live-stock-get-freezing-requests.js b/src/features/live-stock-support/services/live-stock-get-freezing-requests.js new file mode 100644 index 0000000..acfc0d7 --- /dev/null +++ b/src/features/live-stock-support/services/live-stock-get-freezing-requests.js @@ -0,0 +1,15 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const liveStockGetFreezingRequests = createAsyncThunk( + "LIVE_STOCK_GET_FREEZING_REQUESTS", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + const { data, status } = await axios.get("cold-house-allocations/", { + params: d, + }); + dispatch(LOADING_END()); + return { data, status }; + } +); diff --git a/src/features/live-stock-support/services/live-stock-get-inventory-data.js b/src/features/live-stock-support/services/live-stock-get-inventory-data.js new file mode 100644 index 0000000..c4ae9e9 --- /dev/null +++ b/src/features/live-stock-support/services/live-stock-get-inventory-data.js @@ -0,0 +1,28 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; +import { getRoleFromUrl } from "../../../utils/getRoleFromUrl"; + +export const liveStockGetInventoryData = createAsyncThunk( + "SLAUGHTER_GET_COLD_HOUSES", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + const { data, status } = await axios.get("cold-house/", { + params: { role: getRoleFromUrl(), ...d }, + }); + dispatch(LOADING_END()); + return { data, status }; + } +); + +export const liveStockGetInventoryDataDashboard = createAsyncThunk( + "SLAUGHTER_GET_COLD_HOUSES", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + const { data, status } = await axios.get("cold-house-dashboard/", { + params: { role: getRoleFromUrl(), ...d }, + }); + dispatch(LOADING_END()); + return { data, status }; + } +); diff --git a/src/features/live-stock-support/services/live-stock-profile.js b/src/features/live-stock-support/services/live-stock-profile.js new file mode 100644 index 0000000..49a515d --- /dev/null +++ b/src/features/live-stock-support/services/live-stock-profile.js @@ -0,0 +1,10 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; + +export const liveStockProfile = createAsyncThunk( + "LIVE_STOCK_PROFILE", + async () => { + const { data, status } = await axios.get("live_stock_support/0/?profile"); + return { data, status }; + } +); diff --git a/src/features/messages/components/messages-recivers/MessagesRecivers.js b/src/features/messages/components/messages-recivers/MessagesRecivers.js new file mode 100644 index 0000000..f806631 --- /dev/null +++ b/src/features/messages/components/messages-recivers/MessagesRecivers.js @@ -0,0 +1,89 @@ +import React from "react"; + +import { PropTypes } from "prop-types"; + +import ExpandMoreIcon from "@mui/icons-material/ExpandMore"; + +import { Accordion, Chip, Divider, Typography } from "@mui/material"; + +import AccordionSummary from "@mui/material/AccordionSummary"; +import AccordionDetails from "@mui/material/AccordionDetails"; +import { Grid } from "../../../../components/grid/Grid"; +import { SPACING } from "../../../../data/spacing"; +import { formatJustDate, formatJustTime } from "../../../../utils/formatTime"; + +const MessagesRecivers = ({ + heading, + message, + linkText, + link, + image, + time, + number, +}) => { + return ( + + } + aria-controls="panel1a-content" + id="panel1a-header" + > + + {heading ? number + 1 + " - " + heading : number + 1 + " بدون عنوان "} + + + + + {message ? message : "برای این پیغام توضیحی نوشته نشده است"} +
    + + تاریخ ثبت پیام: {formatJustDate(time)} - ساعت {formatJustTime(time)} + +
    +
    + {linkText && ( + <> + + + + + + + {linkText} + + + + )} + + {image?.length ? ( + + + + ) : ( + "" + )} + + {image?.length + ? image.map((item, i) => { + return [ + + + Slaughter Payment Factor + + , + ]; + }) + : ""} +
    + ); +}; +MessagesRecivers.propTypes = { + message: PropTypes.string, + heading: PropTypes.string, + link: PropTypes.string, + linkText: PropTypes.string, + image: PropTypes.any, + time: PropTypes.string, + number: PropTypes.any, +}; +export default MessagesRecivers; diff --git a/src/features/messages/components/messages-senders/MessagesSenders.js b/src/features/messages/components/messages-senders/MessagesSenders.js new file mode 100644 index 0000000..24af63f --- /dev/null +++ b/src/features/messages/components/messages-senders/MessagesSenders.js @@ -0,0 +1,103 @@ +import React, { useState } from "react"; +import { PropTypes } from "prop-types"; +import { + List, + ListItem, + ListItemText, + Divider, + Typography, + Chip, + Button, + Collapse, +} from "@mui/material"; +import ExpandMoreIcon from "@mui/icons-material/ExpandMore"; +import ExpandLessIcon from "@mui/icons-material/ExpandLess"; +import { formatJustDate, formatJustTime } from "../../../../utils/formatTime"; + +const MessagesSenders = ({ + heading, + message, + linkText, + link, + image, + time, + number, +}) => { + const [isMessageVisible, setMessageVisible] = useState(false); + + const toggleMessageVisibility = () => { + setMessageVisible(!isMessageVisible); + }; + + return ( + + + + + + + + + + {message ? message : "برای این پیام توضیحی نوشته نشده است"} + + + + + + + تاریخ ثبت پیام: {formatJustDate(time)} - ساعت {formatJustTime(time)} + + + + {linkText && ( + <> + + + + + + + {linkText} + + + + )} + + + + {image && image.length > 0 && ( +
    + + + + {image.map((item, i) => ( + + + Slaughter Payment Factor + + + ))} +
    + )} +
    + ); +}; + +MessagesSenders.propTypes = { + message: PropTypes.string, + heading: PropTypes.string, + link: PropTypes.string, + linkText: PropTypes.string, + image: PropTypes.array, + time: PropTypes.string, + number: PropTypes.number, +}; + +export default MessagesSenders; diff --git a/src/features/messages/services/messages-get-reciver-messages.js b/src/features/messages/services/messages-get-reciver-messages.js new file mode 100644 index 0000000..ee54fab --- /dev/null +++ b/src/features/messages/services/messages-get-reciver-messages.js @@ -0,0 +1,10 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; + +export const messagesGetReciverMessages = createAsyncThunk( + "MESSAGES_GET_RECIVER_MESSAGES", + async () => { + const { data, status } = await axios.get("user_message/?receiver"); + return { data, status }; + } +); diff --git a/src/features/messages/services/messages-get-sender-messages.js b/src/features/messages/services/messages-get-sender-messages.js new file mode 100644 index 0000000..a874fe4 --- /dev/null +++ b/src/features/messages/services/messages-get-sender-messages.js @@ -0,0 +1,10 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; + +export const messagesGetSenderMessages = createAsyncThunk( + "MESSAGES_GET_SENDER_MESSAGES", + async () => { + const { data, status } = await axios.get("user_message/?sender"); + return { data, status }; + } +); diff --git a/src/features/payment/components/PaymentFailed.js b/src/features/payment/components/PaymentFailed.js new file mode 100644 index 0000000..21ab049 --- /dev/null +++ b/src/features/payment/components/PaymentFailed.js @@ -0,0 +1,114 @@ +import { Button, Typography, Paper, Box, Divider } from "@mui/material"; +import { format } from "date-fns-jalali"; +import { useNavigate } from "react-router-dom"; +import { motion } from "framer-motion"; +import MoodBadIcon from "@mui/icons-material/MoodBad"; + +export const PaymentFailed = ({ params }) => { + const navigate = useNavigate(); + + return ( + + + + + + + + + + تراکنش انجام نشد! + + + + {params?.error || "خطای ناشناخته"} + + + + در صورت کسر مبلغ از حساب با پشتیبانی تماس بگیرید. + + + + + تاریخ و زمان: + + {format( + new Date(params?.date || new Date()), + "yyyy/MM/dd hh:mm:ss" + )} + + + + + + + + + + ); +}; diff --git a/src/features/payment/components/PaymentResult.js b/src/features/payment/components/PaymentResult.js new file mode 100644 index 0000000..be6ba11 --- /dev/null +++ b/src/features/payment/components/PaymentResult.js @@ -0,0 +1,16 @@ +import { useLocation } from "react-router-dom"; +import { PaymentFailed } from "./PaymentFailed"; +import { PaymentSuccess } from "./PaymentSuccess"; + +export const PaymentResult = () => { + const location = useLocation(); + const urlParams = new URLSearchParams(location.search); + const params = Object.fromEntries(urlParams.entries()); + + return ( + <> + {params?.error && } + {!params?.error && } + + ); +}; diff --git a/src/features/payment/components/PaymentSuccess.js b/src/features/payment/components/PaymentSuccess.js new file mode 100644 index 0000000..8b55e5e --- /dev/null +++ b/src/features/payment/components/PaymentSuccess.js @@ -0,0 +1,135 @@ +import { Button, Typography, Paper, Box, Divider } from "@mui/material"; +import { CheckCircleOutline, CreditCard, Paid } from "@mui/icons-material"; +import { format } from "date-fns-jalali"; +import { useNavigate } from "react-router-dom"; +import { motion } from "framer-motion"; +import DialpadIcon from "@mui/icons-material/Dialpad"; + +export const PaymentSuccess = ({ params }) => { + const navigate = useNavigate(); + + return ( + + + + + + + + تراکنش با موفقیت انجام شد. + + + + + + } + /> + } + /> + } + /> + + + + + + + + + + ); +}; + +const DetailRow = ({ label, value, icon }) => ( + + + {label}: + + + {icon} + {value} + + +); diff --git a/src/features/province-finacial/components/factor-to-print/FactorToPrint.js b/src/features/province-finacial/components/factor-to-print/FactorToPrint.js new file mode 100644 index 0000000..86a06d3 --- /dev/null +++ b/src/features/province-finacial/components/factor-to-print/FactorToPrint.js @@ -0,0 +1,192 @@ +import React from "react"; +import { PropTypes } from "prop-types"; +// import style from "./style.css"; +const style = null; +export const FactorToPrint = ({ process }) => { + return ( + <> +

    مشخصات شهرستان

    + + + + + + + + + + + + + + + + + +
    نام اپراتوراستانکدملیتلفنشهرستاننشانی
    {process.city?.cityOperatorName}{process.city?.cityOperatorProvince}{process.city?.cityOperatorNationalId}{process.city?.cityOperatorMobile}{process.city?.cityOperatorCity}{process.city?.cityOperatorAddress}
    + +

    مشخصات استان

    + + + + + + + + + + + + + + + + + +
    نام اپراتوراستانشهرستانکدملیتلفننشانی
    {process.province?.provinceOperatorName}{process.province?.provinceOperatorProvinc}{process.province?.provinceOperatorCity}{process.province?.provinceOperatorNationalId}{process.province?.provinceOperatorMobile}{process.province?.provinceOperatorAddress}
    + + {process.provinceKillRequests?.map((item, i) => { + return [ + <> +

    مشخصات کشتارگاه

    + + + + + + + + + + + + + + + + + + +
    نام کشتارگاهنشانیاستانشهرستانکدملیتلفن
    {item.killHouseName}{item.killHouseUserAddress}{item.killHouseUserProvince}{item.killHouseUserCity}{item.killHouseName}{item.killHouseMobile}
    + + {process.provinceKillRequests[i].killHouseRequests?.map( + (item, i) => { + return [ + <> + + + + + + + + + + + + + + + +
    کد باروزنمقدارمبلغ واحدمبلغ کل
    {item.barcod}{item.provinceFactorToKillHouse?.weight}{item.quantity}{item.fee + " ریال "} + {item.provinceFactorToKillHouse?.cost + " ریال "} +
    + , + ]; + } + )} + +

    مشخصات کالا یا خدمات مورد معامله

    + + + + + + + + + + + + + + + + +
    کالاتعدادواحدبهای واحدبهای کل
    مرغ{process.poultry?.poultryQuantity}قطعه + {process.allocation.fee + ? process.allocation?.fee + " ریال " + : "-"} + + {process.allocation.totalMoney + ? process.allocation.totalMoney + " ریال " + : "-"} +
    + , + ]; + })} + +
      + {process.allocation?.provinceShareChar && ( +
    • + سهم اتحادیه:{" "} + {process.allocation?.provinceShareDigit.toLocaleString() + " ریال"}{" "} + ({process.allocation?.provinceShareChar}) +
    • + )} + + {process.allocation?.cityShareChar && ( +
    • + سهم شهرستان:{" "} + {process.allocation?.cityShareDigit.toLocaleString() + " ریال"} ( + {process.allocation?.cityShareChar}) +
    • + )} + + {process.allocation?.fanavaShareShareChar && ( +
    • + سهم فن آوا:{" "} + {process.allocation?.fanavaShareDigit.toLocaleString() + " ریال"} ( + {process.allocation?.fanavaShareShareChar}) +
    • + )} + + {process.allocation?.companyShareChar && ( +
    • + سهم شرکت:{" "} + {process.allocation?.companyShareDigit.toLocaleString() + " ریال"} ( + {process.allocation?.companyShareChar}) +
    • + )} + + {process.allocation?.centralUnionShareChar && ( +
    • + سهم اتحادیه مرکزی:{" "} + {process.allocation?.centralUnionShareDigit.toLocaleString() + + " ریال"}{" "} + ({process.allocation?.centralUnionShareChar}) +
    • + )} + + {process.allocation?.poultryShareChar && ( +
    • + پرداختی مرغدار:{" "} + {process.allocation?.poultryShareDigit.toLocaleString() + " ریال"} ( + {process.allocation?.poultryShareChar}) +
    • + )} + + {process.allocation?.totalMoneyChar && ( +
    • + مبلغ کل: {process.allocation?.totalMoney.toLocaleString() + " ریال"}{" "} + ({process.allocation?.totalMoneyChar}) +
    • + )} +
    + + ); +}; + +FactorToPrint.propTypes = { + process: PropTypes.any, +}; diff --git a/src/features/province-finacial/components/factor-to-print/style.css b/src/features/province-finacial/components/factor-to-print/style.css new file mode 100644 index 0000000..95d4df7 --- /dev/null +++ b/src/features/province-finacial/components/factor-to-print/style.css @@ -0,0 +1,28 @@ +table { + font-family: arial, sans-serif; + border-collapse: collapse; + width: 100%; +} + +td, +th { + border: 1px solid #dddddd; + text-align: center; + padding: 5px; +} + +tr:nth-child(even) { + background-color: #dddddd; +} + +h4 { + text-align: center; +} + +ul { + text-align: initial; +} + +h4 { + margin: 0px; +} diff --git a/src/features/province-finacial/components/factor/Factor.js b/src/features/province-finacial/components/factor/Factor.js new file mode 100644 index 0000000..6209449 --- /dev/null +++ b/src/features/province-finacial/components/factor/Factor.js @@ -0,0 +1,591 @@ +import { IconButton, Typography } from "@mui/material"; +import { Grid } from "../../../../components/grid/Grid"; +import { SPACING } from "../../../../data/spacing"; +// import PrintIcon from "@mui/icons-material/Print"; +import { PropTypes } from "prop-types"; +// import { FactorToPrint } from "../factor-to-print/FactorToPrint"; +import { formatTime } from "../../../../utils/formatTime"; +import { + TimelineConnector, + TimelineContent, + TimelineDot, + TimelineItem, + TimelineOppositeContent, + TimelineSeparator, +} from "@mui/lab"; +import { SimpleTable } from "../../../../components/simple-table/SimpleTable"; +import NoteAddIcon from "@mui/icons-material/NoteAdd"; +import { DRAWER, OPEN_MODAL } from "../../../../lib/redux/slices/appSlice"; +import { FactorPaymentShareDrawer } from "../../../file/components/factor-payment-share-drawer/FactorPaymentShareDrawer"; +import { useDispatch } from "react-redux"; +import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl"; +import useRequestFile from "../../../file/hooks/useRequestFile"; +// import { useRef } from "react"; +// import ReactToPrint from "react-to-print"; + +export const Factor = ({ process, id }) => { + const dispatch = useDispatch(); + const myFile = useRequestFile(id); + process = process ? process : myFile?.file?.process; + + // const slaughterAllocatedRequests = useSlaughterAllocatedRequests(id); + // const { id } = useParams(); + // const componentRef = useRef(); + // const handlePrint = () => { + // var printWindow = window.open(FactorToPrint); + // printWindow.print(); + // }; + let provinceShare, + cityShare, + fanavaShare, + companyShare, + unionShare, + poultryShare; + + const isProvinceSubmitDocEnabled = + getRoleFromUrl() === "ProvinceFinancial" && + !process.allocation?.provincePaymentDocuments?.length && + !!process.allocation?.provinceShareRemaining; + const isFanavaSubmitDocEnabled = + getRoleFromUrl() === "ProvinceFinancial" && + !process.allocation?.fanavaPaymentDocuments?.length && + !!process.allocation?.fanavaShareRemaining; + const isCitySubmitDocEnabled = + getRoleFromUrl() === "ProvinceFinancial" && + !process.allocation?.cityPaymentDocuments?.length && + !!process.allocation?.cityShareRemaining; + const isCompanySubmitDocEnabled = + getRoleFromUrl() === "ProvinceFinancial" && + !process.allocation?.companyPaymentDocuments?.length && + !!process.allocation?.companyShareRemaining; + const isCentralUnionSubmitDocEnabled = + getRoleFromUrl() === "ProvinceFinancial" && + !process.allocation?.centralUnionPaymentDocuments?.length && + !!process.allocation?.centralUnionShareRemaining; + const isPoultrySubmitDocEnabled = + getRoleFromUrl() === "ProvinceFinancial" && + !process.allocation?.poultryPaymentDocuments?.length && + !!process.allocation?.poultryRemaining; + + if (process.allocation?.provinceShareDigit) { + provinceShare = [ + `سهم اتحادیه`, + process.allocation?.provinceCardNumber, + process.allocation?.provinceShaba, + process.allocation?.provinceBankInfo, + process.allocation?.provinceShareDigit + " ریال", + process.allocation?.provinceSharePayment + " ریال", + process.allocation?.provinceShareRemaining + " ریال", + process.allocation?.provincePaymentDocuments?.map((doc, i) => { + return ( + + document + + ); + }), + { + dispatch( + OPEN_MODAL({ + title: "ثبت سند مالی", + content: ( + + ), + }) + ); + }} + > + + , + ]; + } + + if (process.allocation?.fanavaShareDigit) { + fanavaShare = [ + `سهم فن آوا`, + process.allocation?.fanavaCardNumber, + process.allocation?.fanavaShaba, + process.allocation?.fanavaBankInfo, + process.allocation?.fanavaShareDigit + " ریال", + process.allocation?.fanavaSharePayment + " ریال", + process.allocation?.fanavaShareRemaining + " ریال", + process.allocation?.fanavaPaymentDocuments?.map((doc, i) => { + return ( + + document + + ); + }), + { + dispatch( + DRAWER({ + right: true, + title: "ثبت سند مالی", + content: ( + + ), + }) + ); + }} + > + + , + ]; + } + + if (process.allocation?.cityShareDigit) { + cityShare = [ + `سهم شهرستان`, + process.allocation?.cityCardNumber, + process.allocation?.cityShaba, + process.allocation?.cityBankInfo, + process.allocation?.cityShareDigit + " ریال", + process.allocation?.citySharePayment + " ریال", + process.allocation?.cityShareRemaining + " ریال", + process.allocation?.cityPaymentDocuments?.map((doc, i) => { + return ( + + document + + ); + }), + { + dispatch( + OPEN_MODAL({ + title: "ثبت سند مالی", + content: ( + + ), + }) + ); + }} + > + + , + ]; + } + + if (process.allocation?.companyShareDigit) { + companyShare = [ + `سهم شرکت`, + process.allocation?.companyCardNumber, + process.allocation?.companyShaba, + process.allocation?.companyBankInfo, + process.allocation?.companyShareDigit + " ریال", + process.allocation?.companySharePayment + " ریال", + process.allocation?.companyShareRemaining + " ریال", + process.allocation?.companyPaymentDocuments?.map((doc, i) => { + return ( + + document + + ); + }), + { + dispatch( + OPEN_MODAL({ + right: true, + title: "ثبت سند مالی", + content: ( + + ), + }) + ); + }} + > + + , + ]; + } + + if (process.allocation?.centralUnionShareDigit) { + unionShare = [ + `سهم اتحادیه مرکزی`, + process.allocation?.centralUnionCardNumber, + process.allocation?.centralUnionShaba, + process.allocation?.centralUnionBankInfo, + process.allocation?.centralUnionShareDigit + " ریال", + process.allocation?.centralUnionSharePayment + " ریال", + process.allocation?.centralUnionShareRemaining + " ریال", + process.allocation?.centralUnionPaymentDocuments?.map((doc, i) => { + return ( + + document + + ); + }), + { + dispatch( + OPEN_MODAL({ + title: "ثبت سند مالی", + content: ( + + ), + }) + ); + }} + > + + , + ]; + } + + if (process.allocation?.poultryShareDigit) { + poultryShare = [ + `سهم مرغدار`, + process.allocation?.poultryCardNumber, + process.allocation?.poultryShaba, + process.allocation?.poultryBankInfo, + process.allocation?.poultryShareDigit + " ریال", + process.allocation?.poultrySharePayment + " ریال", + process.allocation?.poultryRemaining + " ریال", + process.allocation?.poultryPaymentDocuments?.map((doc, i) => { + return ( + + document + + ); + }), + { + dispatch( + OPEN_MODAL({ + title: "ثبت سند مالی", + content: ( + + ), + }) + ); + }} + > + + , + ]; + } + + const factorTableData = [ + provinceShare, + cityShare, + fanavaShare, + companyShare, + unionShare, + poultryShare, + ].filter((item) => !!item); + + return ( + <> + + + + + + + + + + + فاکتور نهایی + + + + + + + + ﺷﻤﺎﺭﻩ ﻓﺎﮐﺘﻮﺭ: + + + {process?.poultry?.poultryOrderCode} + + + تاریخ: + + + {formatTime(process?.poultry?.poultrySendDate)} + + + {/* + ( + + )} + content={() => componentRef.current} + /> + + */} + + + + + + + + + {process.allocation?.totalMoney && ( + + )} + + + {/* + {process.allocation?.provinceShareChar && ( + + + + سهم اتحادیه:{" "} + {process.allocation?.provinceShareDigit.toLocaleString() + + " ریال"}{" "} + ({process.allocation?.provinceShareChar}) + + + )} + {process.allocation?.cityShareChar && ( + + + + سهم شهرستان:{" "} + {process.allocation?.cityShareDigit.toLocaleString() + + " ریال"}{" "} + ({process.allocation?.cityShareChar}) + + + )} + {process.allocation?.fanavaShareShareChar && ( + + + + سهم فن آوا:{" "} + {process.allocation?.fanavaShareDigit.toLocaleString() + + " ریال"}{" "} + ({process.allocation?.fanavaShareShareChar}) + + + )} + {process.allocation?.companyShareChar && ( + + + + سهم شرکت:{" "} + {process.allocation?.companyShareDigit.toLocaleString() + + " ریال"}{" "} + ({process.allocation?.companyShareChar}) + + + )} + + {process.allocation?.centralUnionShareChar && ( + + + + سهم اتحادیه مرکزی:{" "} + {process.allocation?.centralUnionShareDigit.toLocaleString() + + " ریال"}{" "} + ({process.allocation?.centralUnionShareChar}) + + + )} + {process.allocation?.poultryShareChar && ( + + + + پرداختی مرغدار:{" "} + {process.allocation?.poultryShareDigit.toLocaleString() + + " ریال"}{" "} + ({process.allocation?.poultryShareChar}) + + + )} + {process.allocation?.totalMoneyChar && ( + + + + مبلغ کل:{" "} + {process.allocation?.totalMoney.toLocaleString() + " ریال"}{" "} + ({process.allocation?.totalMoneyChar}) + + + )} + */} + + + {/* */} + + + ); +}; + +Factor.propTypes = { + process: PropTypes.any, +}; diff --git a/src/features/province-finacial/components/final-factors-requests/FinalFactorsRequests.js b/src/features/province-finacial/components/final-factors-requests/FinalFactorsRequests.js new file mode 100644 index 0000000..8a08171 --- /dev/null +++ b/src/features/province-finacial/components/final-factors-requests/FinalFactorsRequests.js @@ -0,0 +1,95 @@ +import { Card } from "@mui/material"; +import { useEffect, useState } from "react"; +import { AdvancedTable } from "../../../../components/advanced-table/AdvancedTable"; +import PlagiarismIcon from "@mui/icons-material/Plagiarism"; +import { useNavigate } from "react-router-dom"; +import { ROUTE_PROVINCE_FINANCIAL_FILE } from "../../../../routes/routes"; +import IconButton from "@mui/material/IconButton"; +import { useDispatch, useSelector } from "react-redux"; +import { DRAWER } from "../../../../lib/redux/slices/appSlice"; +import EditIcon from "@mui/icons-material/Edit"; +import { Grid } from "../../../../components/grid/Grid"; +import { provinceFinancialGetFinalFactorsService } from "../../services/province-financial-get-final-factors-service"; +import { Factor } from "../factor/Factor"; + +export const FinalFactorsRequests = () => { + const navigate = useNavigate(); + const dispatch = useDispatch(); + const { provinceFinancialGetFinalFactors } = useSelector( + (state) => state.provinceFinancialSlice + ); + const [dataTable, setDataTable] = useState([]); + + useEffect(() => { + dispatch(provinceFinancialGetFinalFactorsService()); + }, []); + + useEffect(() => { + const d = provinceFinancialGetFinalFactors?.map((item, i) => { + return [ + i + 1, + item?.poultry?.orderCode, + item?.poultry?.poultry?.unitName, + item?.poultry?.poultry?.userprofile?.mobile, + item?.poultry?.quantity + " قطعه", + { + dispatch( + DRAWER({ + title: "فاکتور نهایی", + // right: !(window.innerWidth <= 600), + top: !(window.innerWidth <= 600), + bottom: window.innerWidth <= 600, + content: ( + + + + ), + }) + ); + }} + > + + , + { + navigate( + ROUTE_PROVINCE_FINANCIAL_FILE + + item.poultry.process.poultry.poultryRequestId + ); + }} + > + + , + ]; + }); + setDataTable(d); + }, [provinceFinancialGetFinalFactors]); + + const [tableDataCol] = useState([ + "ردیف", + "کدسفارش", + "مرغدار", + "تلفن مرغدار", + "تعداد", + "عملیات", + "مشاهده", + ]); + return ( + + + + ); +}; diff --git a/src/features/province-finacial/components/province-financial-active-requests/ProvinceFinancialActiveRequests.js b/src/features/province-finacial/components/province-financial-active-requests/ProvinceFinancialActiveRequests.js new file mode 100644 index 0000000..e63e9c5 --- /dev/null +++ b/src/features/province-finacial/components/province-financial-active-requests/ProvinceFinancialActiveRequests.js @@ -0,0 +1,80 @@ +import { Card } from "@mui/material"; +import { useEffect, useState } from "react"; +import { AdvancedTable } from "../../../../components/advanced-table/AdvancedTable"; +import PlagiarismIcon from "@mui/icons-material/Plagiarism"; +import { useNavigate } from "react-router-dom"; +import { ROUTE_PROVINCE_FINANCIAL_FILE } from "../../../../routes/routes"; +import IconButton from "@mui/material/IconButton"; +import { useDispatch, useSelector } from "react-redux"; +import { provinceGetAllRequests } from "../../../province/services/province-get-all-requests"; +import { format } from "date-fns-jalali"; + +export const ProvinceFinancialActiveRequests = () => { + const navigate = useNavigate(); + const dispatch = useDispatch(); + const { provinceAllRequests } = useSelector((state) => state.provinceSlice); + const [dataTable, setDataTable] = useState([]); + + useEffect(() => { + dispatch(provinceGetAllRequests()); + }, []); + + useEffect(() => { + const filteredData = provinceAllRequests?.filter( + (item, i) => + item.state === "accept" && + item?.poultryRequest?.finalState !== "archive" + ); + const d = filteredData?.map((item, i) => { + return [ + i + 1, + item?.poultryRequest?.orderCode, + format(new Date(item?.poultryRequest?.createDate), "yyyy/MM/dd"), + format(new Date(item?.poultryRequest?.sendDate), "yyyy/MM/dd"), + item?.poultryRequest?.process?.poultry?.poultryName, + item?.poultryRequest?.process?.poultry?.poultryMobile, + item?.poultryRequest?.process?.poultry?.poultryCity, + item?.poultryRequest?.process?.poultry?.poultryProvince, + item?.poultryRequest?.process?.poultry?.age, + item?.poultryRequest?.process?.poultry?.poultryQuantity, + { + navigate( + ROUTE_PROVINCE_FINANCIAL_FILE + + item?.poultryRequest?.process?.poultry?.poultryRequestId + ); + }} + > + + , + ]; + }); + setDataTable(d); + }, [provinceAllRequests]); + + const [tableDataCol] = useState([ + "ردیف", + "کد سفارش", + "تاریخ ثبت درخواست", + "تاریخ درخواست", + "مرغدار", + "تلفن مرغدار", + "شهر", + "استان", + "سن مرغ", + "تعداد", + "مشاهده", + ]); + return ( + + + + ); +}; diff --git a/src/features/province-finacial/components/province-financial-check-payed-factor-requests/ProvinceFinancialCheckPayedFactorRequests.js b/src/features/province-finacial/components/province-financial-check-payed-factor-requests/ProvinceFinancialCheckPayedFactorRequests.js new file mode 100644 index 0000000..edb7b87 --- /dev/null +++ b/src/features/province-finacial/components/province-financial-check-payed-factor-requests/ProvinceFinancialCheckPayedFactorRequests.js @@ -0,0 +1,127 @@ +import { Card } from "@mui/material"; +import { useEffect, useState } from "react"; +import { AdvancedTable } from "../../../../components/advanced-table/AdvancedTable"; +import PlagiarismIcon from "@mui/icons-material/Plagiarism"; +import { useNavigate } from "react-router-dom"; +import { ROUTE_PROVINCE_FINANCIAL_FILE } from "../../../../routes/routes"; +import IconButton from "@mui/material/IconButton"; +import { useDispatch, useSelector } from "react-redux"; +import { DRAWER } from "../../../../lib/redux/slices/appSlice"; +import EditIcon from "@mui/icons-material/Edit"; +import { Grid } from "../../../../components/grid/Grid"; +import { provinceFinancialGetPayedFactorsService } from "../../services/province-financial-get-payed-factors-service"; +import ProvinceFinancialSlaughterCheckRequest from "../../../file/components/province-financial-slaughter-check-request/ProvinceFinancialSlaughterCheckRequest"; +import { formatJustDate } from "../../../../utils/formatTime"; + +export const ProvinceFinancialCheckPayedFactorRequests = () => { + const navigate = useNavigate(); + const dispatch = useDispatch(); + const { provinceFinancialGetPayedFactors } = useSelector( + (state) => state.provinceFinancialSlice + ); + const [dataTable, setDataTable] = useState([]); + + useEffect(() => { + dispatch(provinceFinancialGetPayedFactorsService()); + }, []); + + useEffect(() => { + const d = provinceFinancialGetPayedFactors?.map((item, i) => { + let state = ""; + if (item.state === "pending") { + state = "در انتظار تایید"; + } else if (item.state === "accepted") { + state = "تایید نهایی"; + } else if (item.state === "rejected") { + state = "رد شده"; + } + return [ + i + 1, + item?.provinceFactor?.factorBarCode, + item?.provinceFactor?.provinceCheckInfo?.killHouseAssignment + ?.killHouseRequest?.killRequest?.killHouse?.name, + item?.provinceFactor?.provinceCheckInfo?.killHouseAssignment + ?.killHouseRequest?.killRequest?.killHouse?.killHouseOperator?.user + ?.mobile, + formatJustDate(item?.provinceFactor?.createDate), + formatJustDate(item?.createDate), + item?.provinceFactor?.totalPrice.toLocaleString() + " ﷼", + Number(item?.paymentCode), + + بدون بار + , + state, + { + dispatch( + DRAWER({ + title: "انجام عملیات تایید / رد درخواست", + // right: !(window.innerWidth <= 600), + top: !(window.innerWidth <= 600), + bottom: window.innerWidth <= 600, + content: ( + + {/* */} + + + ), + }) + ); + }} + > + + , + { + navigate( + ROUTE_PROVINCE_FINANCIAL_FILE + + item?.poultryRequest?.process?.poultry?.poultryRequestId + ); + }} + > + + , + ]; + }); + setDataTable(d); + }, [provinceFinancialGetPayedFactors]); + + const [tableDataCol] = useState([ + "ردیف", + "شناسه فاکتور", + "کشتارگاه", + "تلفن کشتارگاه", + "تاریخ صدور فاکتور", + "تاریخ پرداخت فاکتور", + "مبلغ فاکتور نهایی", + "شناسه پرداخت", + "سند پرداختی", + "وضعیت", + "عملیات", + "مشاهده", + ]); + return ( + + + + ); +}; diff --git a/src/features/province-finacial/components/province-financial-check-request-info/ProvinceFinancialCheckRequestInfo.js b/src/features/province-finacial/components/province-financial-check-request-info/ProvinceFinancialCheckRequestInfo.js new file mode 100644 index 0000000..c583d78 --- /dev/null +++ b/src/features/province-finacial/components/province-financial-check-request-info/ProvinceFinancialCheckRequestInfo.js @@ -0,0 +1,65 @@ +import { SimpleTable } from "../../../../components/simple-table/SimpleTable"; + +export const ProvinceFinancialCheckRequestInfo = ({ data }) => { + const columns = [ + "خریدار", + "مرغدار", + "محل کشتار", + "دامپزشک کشتارگاه", + "راننده/ماشین", + "تعداد تخصیصی", + "وزن تخصیصی (کیلوگرم)", + "تعداد واقعی", + "وزن خالص (کیلوگرم)", + "سند خودرو بدون بار", + "سند خودرو با بار", + ]; + + const item = [ + [ + `${data.killHouseName} (${data.killHouseMobile})`, + `${data?.unitName} (${data?.mobile})`, + `${data?.killPlace}`, + `${data?.killHouseVetName} (${data?.killHouseVetMobile})`, + data.cars.driverName + + ` (${data.cars.driverMobile})/${data.cars.typeCar} با پلاک ${data.cars.pelak}`, + data?.quantity?.toLocaleString(), + data?.firstWeight?.toLocaleString(), + data?.acceptedRealQuantity + ? data?.acceptedRealQuantity?.toLocaleString() + : "وارد نشده", + data?.acceptedRealWeight + ? data?.acceptedRealWeight?.toLocaleString() + : "وارد نشده", + + بدون بار + , + + بدون بار + , + ], + ]; + + return ; +}; diff --git a/src/features/province-finacial/components/province-financial-debtor-info/ProvinceFinancialDebtorInfo.js b/src/features/province-finacial/components/province-financial-debtor-info/ProvinceFinancialDebtorInfo.js new file mode 100644 index 0000000..e3a3f8e --- /dev/null +++ b/src/features/province-finacial/components/province-financial-debtor-info/ProvinceFinancialDebtorInfo.js @@ -0,0 +1,79 @@ +import { Button, Typography } from "@mui/material"; +import React, { useEffect } from "react"; +import { Grid } from "../../../../components/grid/Grid"; +import DownloadIcon from "@mui/icons-material/Download"; +import { SPACING } from "../../../../data/spacing"; +import { PropTypes } from "prop-types"; +import { useDispatch, useSelector } from "react-redux"; +import { provinceFinancialGetTransactionInfo } from "../../services/province-financial-get-transaction-info"; +import { + LOADING_END, + LOADING_START, +} from "../../../../lib/redux/slices/appSlice"; + +export const ProvinceFinancialDebtorInfo = ({ paymentCode }) => { + const dispatch = useDispatch(); + const { transactionInfo } = useSelector( + (state) => state.provinceFinancialSlice + ); + + useEffect(() => { + dispatch(LOADING_START()); + dispatch(provinceFinancialGetTransactionInfo(paymentCode)).then(() => { + dispatch(LOADING_END()); + }); + }, []); + + return ( + + + مبلغ بدهی: {transactionInfo?.cost.toLocaleString()} + + + شناسه پرداخت: {paymentCode} + + + + توضیحات: + {transactionInfo?.description ? transactionInfo?.description : "ندارد"} + + {transactionInfo?.image?.length ? ( + + پیوست سند: + {transactionInfo?.image?.map((item, i) => { + return [ + + سند بدهکاری + , + , + ]; + })} + + ) : ( + + سند ثبت نشده است + + )} + + ); +}; + +ProvinceFinancialDebtorInfo.propTypes = { + paymentCode: PropTypes.any, +}; diff --git a/src/features/province-finacial/components/province-financial-document-register/ProvinceFinancialDocumentRegister.js b/src/features/province-finacial/components/province-financial-document-register/ProvinceFinancialDocumentRegister.js new file mode 100644 index 0000000..93b78b3 --- /dev/null +++ b/src/features/province-finacial/components/province-financial-document-register/ProvinceFinancialDocumentRegister.js @@ -0,0 +1,488 @@ +import { + Accordion, + AccordionDetails, + AccordionSummary, + Autocomplete, + Button, + Grid, + TextField, + Typography, +} from "@mui/material"; +import { useNavigate } from "react-router-dom"; +import { AdvancedTable } from "../../../../components/advanced-table/AdvancedTable"; +import { SPACING } from "../../../../data/spacing"; +import { ROUTE_PROVINCE__FINANCIAL_USER_FINACIAL_FILE } from "../../../../routes/routes"; +import ExpandMoreIcon from "@mui/icons-material/ExpandMore"; +import { useEffect, useState } from "react"; +import { useDispatch, useSelector } from "react-redux"; +import SearchIcon from "@mui/icons-material/Search"; +import { + LOADING_END, + LOADING_START, +} from "../../../../lib/redux/slices/appSlice"; +import { cityGetProvinces } from "../../../city/services/CityGetProvinces"; +import { cityGetCity } from "../../../city/services/city-get-city"; +import { useFormik } from "formik"; +import { Yup } from "../../../../lib/yup/yup"; +import { provinceFinancialGetUsersWaletinfo } from "../../services/province-financial-get-users-walet-info"; +import FilterAltIcon from "@mui/icons-material/FilterAlt"; +import { provinceFinancialSearchUserDocument } from "../../services/province-financial-search-user-document"; +import { getFaUserRole } from "../../../../utils/getFaUserRole"; + +export const ProvinceFinancialDocumentRegistration = () => { + const [expanded, setExpanded] = useState(true); + const [isFitered, setIsFitered] = useState(false); + const handleChange = () => { + setExpanded(!expanded); + }; + + const dispatch = useDispatch(); + + const [provinceData, setProvinceData] = useState(); + const [cityData, setCityData] = useState(); + const [provinceKey, setProvinceKey] = useState(); + const [citylabel, setcitylabel] = useState(); + const [isExistProvince, setIsExistProvince] = useState(true); + + const [dataTable, setDataTable] = useState([]); + const users = useSelector( + (state) => state.provinceFinancialSlice.userWaletInfo + ); + + const formik = useFormik({ + initialValues: { + username: "", + fullname: "", + mobile: "", + nationalcode: "", + }, + validationSchema: Yup.object({ + fullname: Yup.string().typeError("لطفا فیلد را پر کنید!"), + username: Yup.number().typeError("لطفا عدد وارد کنید!"), + mobile: Yup.number() + .test("len", "شماره تلفن باید با 0 شروع شود", (val, context) => { + if (context.originalValue?.length > 0) { + return ( + context.originalValue && context.originalValue.startsWith("0") + ); + } + }) + .test("len", "شماره تماس 11 رقم باید باشد", (val, context) => { + if (context.originalValue?.length > 0) { + if (context.originalValue) { + return context.originalValue.length === 11; + } + } + }) + .typeError("لطفا عدد وارد کنید!"), + nationalcode: Yup.number(), + }), + }); + + useEffect(() => { + formik.validateForm(); + dispatch(LOADING_START()); + dispatch(provinceFinancialGetUsersWaletinfo()).then(() => { + dispatch(cityGetProvinces())?.then((r) => { + setProvinceData(r.payload.data); + dispatch(LOADING_END()); + }); + }); + }, []); + + const handleSearch = () => { + const values = Object.values(formik.values).filter( + (item) => item.length > 0 + ); + let finalValue = ""; + + for (let index = 0; index < values.length; index++) { + finalValue = finalValue + values[index] + ","; + } + finalValue = finalValue.substring(0, finalValue.length - 1); + + if (citylabel) { + if (finalValue) { + finalValue = finalValue + "," + citylabel; + } else { + finalValue = citylabel; + } + } + + dispatch(LOADING_START()); + + dispatch(provinceFinancialSearchUserDocument(finalValue)).then((r) => { + dispatch(LOADING_END()); + const data = r.payload.data; + const d = data?.map((item, i) => { + const name = getFaUserRole(item.role); + + return [ + i + 1, + item.fullname, + name, + item.mobile, + item.nationalId, + item.province, + item.city, + item.creditor.toLocaleString() + " ریال", + item.debtor.toLocaleString() + " ریال", + item.penalty.toLocaleString() + " ریال", + Math.abs(item.depositable).toLocaleString(), + , + ]; + }); + + setDataTable(d); + }); + }; + + useEffect(() => { + const d = users?.map((item, i) => { + const name = getFaUserRole(item.role); + + return [ + i + 1, + item.fullname, + name, + item.mobile, + item.nationalId, + item.province, + item.city, + item.creditor.toLocaleString() + " ریال", + item.debtor.toLocaleString() + " ریال", + item.penalty.toLocaleString() + " ریال", + Math.abs(item.depositable).toLocaleString(), + , + ]; + }); + + setDataTable(d); + }, [users]); + + const handleShowTransactions = () => { + setIsFitered(!isFitered); + }; + + useEffect(() => { + if (isFitered) { + const filteredData = users.filter( + (item) => item.creditor > 1 || item.debtor > 1 || item.penalty > 1 + ); + + const d = filteredData?.map((item, i) => { + const name = getFaUserRole(item.role); + return [ + i + 1, + item.fullname, + name, + item.mobile, + item.nationalId, + item.province, + item.city, + item.creditor.toLocaleString() + " ریال", + item.debtor.toLocaleString() + " ریال", + item.penalty.toLocaleString() + " ریال", + Math.abs(item.depositable).toLocaleString() + " ریال", + , + ]; + }); + setDataTable(d); + } else { + const d = users?.map((item, i) => { + const name = getFaUserRole(item.role); + + return [ + i + 1, + item.fullname, + name, + item.mobile, + item.nationalId, + item.province, + item.city, + item.creditor.toLocaleString() + " ریال", + item.debtor.toLocaleString() + " ریال", + item.penalty.toLocaleString() + " ریال", + Math.abs(item.depositable).toLocaleString() + " ریال", + + , + ]; + }); + + setDataTable(d); + } + }, [isFitered]); + + const handleValidForm = () => { + if (formik.isValid) { + if ( + Object.values(formik.values).filter((item) => item.length > 0) + .length === 0 && + !citylabel + ) { + return true; + } else { + return false; + } + } else { + return true; + } + }; + + useEffect(() => { + if (provinceKey) { + dispatch(LOADING_START()); + dispatch(cityGetCity(provinceKey)).then((r) => { + setCityData(r.payload.data); + setIsExistProvince(false); + dispatch(LOADING_END()); + }); + } + }, [provinceKey]); + + const navigate = useNavigate(); + return ( + <> + + + + } + aria-controls="panel1a-content" + id="panel1a-header" + > + جستجو + + + + + + + + + + + + + + + + + + ({ + id: i.key, + label: i.name, + })) + : [] + } + onChange={(e, value) => { + setProvinceKey(value.id); + }} + renderInput={(params) => ( + + )} + /> + + + ({ id: i.key, label: i.name })) + : [] + } + onChange={(e, value) => { + setcitylabel(value.label); + }} + renderInput={(params) => ( + + )} + /> + + + + + + + + + + + + + + + ); +}; diff --git a/src/features/province-finacial/components/province-financial-financial-history/ProvinceFinancialFinancialHistory.js b/src/features/province-finacial/components/province-financial-financial-history/ProvinceFinancialFinancialHistory.js new file mode 100644 index 0000000..477356a --- /dev/null +++ b/src/features/province-finacial/components/province-financial-financial-history/ProvinceFinancialFinancialHistory.js @@ -0,0 +1,101 @@ +import React, { useEffect, useState } from "react"; +import { useDispatch, useSelector } from "react-redux"; +import { Grid } from "../../../../components/grid/Grid"; +import { SimpleTable } from "../../../../components/simple-table/SimpleTable"; +import { SPACING } from "../../../../data/spacing"; +import { provinceFinancialGetFinancialHistory } from "../../services/province-financial-get-financial-history"; +import { PropTypes } from "prop-types"; + +export default function ProvinceFinancialFinancialHistory({ profileid }) { + const [dataTable, setTableData] = useState(); + const { financialHistory } = useSelector( + (state) => state.provinceFinancialSlice + ); + + const dispatch = useDispatch(); + useEffect(() => { + dispatch(provinceFinancialGetFinancialHistory(profileid)); + }, []); + + useEffect(() => { + const d = financialHistory?.map((item, i) => { + return [ + i + 1, + item.totalCreditor - item.totalDebtors < 0 ? "بدهی" : "طلبکار", + item.nationalId, + item.totalCreditor, + item.totalDebtors, + item.cost, + item.paymentCode, + item.image.length + ? item.image.map((item, i) => { + return [ + + + دانلود + + , + ]; + }) + : "بدون پیوست", + item.description, + // , + ]; + }); + setTableData(d); + }, [financialHistory]); + return ( + + + + ); +} + +ProvinceFinancialFinancialHistory.propTypes = { + profileid: PropTypes.string, +}; diff --git a/src/features/province-finacial/components/province-financial-new-complaint/ProvinceFinancialNewComplaint.js b/src/features/province-finacial/components/province-financial-new-complaint/ProvinceFinancialNewComplaint.js new file mode 100644 index 0000000..5a2eeea --- /dev/null +++ b/src/features/province-finacial/components/province-financial-new-complaint/ProvinceFinancialNewComplaint.js @@ -0,0 +1,116 @@ +import { + Button, + FormControl, + InputLabel, + MenuItem, + Select, + TextField, + Typography, +} from "@mui/material"; +import { useFormik } from "formik"; +import React, { useEffect } from "react"; +import { Grid } from "../../../../components/grid/Grid"; +import { ImageUpload } from "../../../../components/image-upload/ImageUpload"; +import { SPACING } from "../../../../data/spacing"; +import { Yup } from "../../../../lib/yup/yup"; +import { fixBase64 } from "../../../../utils/toBase64"; + +export const ProvinceFinancialNewComplaint = () => { + const [age, setAge] = React.useState(""); + + const [complaintImages, setComplaintImages] = React.useState([]); + const [complaintImagesBase64, setComplaintImagesBase64] = React.useState([]); + + const complaintImageHandler = (imageList, addUpdateIndex) => { + setComplaintImages(imageList); + setComplaintImagesBase64(imageList.map((img) => fixBase64(img.data_url))); + }; + + const handleChange = (event) => { + setAge(event.target.value); + }; + + const formik = useFormik({ + initialValues: { + description: "", + }, + validationSchema: Yup.object({ + description: Yup.string() + .required("این فیلد اجباری است!") + .typeError("لطفا فیلد را پر کنید!"), + }), + }); + + useEffect(() => { + formik.validateForm(); + }, []); + + return ( + + + + موضوع + + + + + + پیوست تصویر + + + + + + + ); +}; diff --git a/src/features/province-finacial/components/province-financial-new-requests/ProvinceFinancialNewRequests.js b/src/features/province-finacial/components/province-financial-new-requests/ProvinceFinancialNewRequests.js new file mode 100644 index 0000000..53c5455 --- /dev/null +++ b/src/features/province-finacial/components/province-financial-new-requests/ProvinceFinancialNewRequests.js @@ -0,0 +1,75 @@ +import { Card } from "@mui/material"; +import { useEffect, useState } from "react"; +import { AdvancedTable } from "../../../../components/advanced-table/AdvancedTable"; +import PlagiarismIcon from "@mui/icons-material/Plagiarism"; +import { useNavigate } from "react-router-dom"; +import { ROUTE_PROVINCE_FILE } from "../../../../routes/routes"; +import IconButton from "@mui/material/IconButton"; +import { useDispatch, useSelector } from "react-redux"; +import { provinceGetAllRequests } from "../../../province/services/province-get-all-requests"; +import { format } from "date-fns-jalali"; + +export const ProvinceFinancialNewRequests = () => { + const navigate = useNavigate(); + const dispatch = useDispatch(); + const { provinceAllRequests } = useSelector((state) => state.provinceSlice); + const [dataTable, setDataTable] = useState([]); + + useEffect(() => { + dispatch(provinceGetAllRequests()); + }, []); + + useEffect(() => { + const filteredData = provinceAllRequests?.filter( + (item, i) => item.state === "pending" + ); + + const d = filteredData?.map((item, i) => { + return [ + i + 1, + item?.poultryRequest?.orderCode, + format(new Date(item?.poultryRequest?.createDate), "yyyy/MM/dd"), + format(new Date(item?.poultryRequest?.sendDate), "yyyy/MM/dd"), + item?.poultryRequest?.process?.poultry?.poultryName, + item?.poultryRequest?.process?.poultry?.poultryMobile, + item?.poultryRequest?.process?.poultry?.poultryCity, + item?.poultryRequest?.process?.poultry?.poultryProvince, + item?.poultryRequest?.process?.poultry?.age, + item?.poultryRequest?.process?.poultry?.poultryQuantity, + { + navigate( + ROUTE_PROVINCE_FILE + + item?.poultryRequest?.process?.poultry?.poultryRequestId + ); + }} + > + + , + ]; + }); + setDataTable(d); + }, [provinceAllRequests]); + + const [tableDataCol] = useState([ + "ردیف", + "کد سفارش", + "تاریخ ثبت درخواست", + "تاریخ درخواست", + "مرغدار", + "تلفن مرغدار", + "شهر", + "استان", + "سن مرغ", + "تعداد", + "مشاهده", + ]); + return ( + + + + ); +}; diff --git a/src/features/province-finacial/components/province-financial-number/FinancialDocumentNumber.js b/src/features/province-finacial/components/province-financial-number/FinancialDocumentNumber.js new file mode 100644 index 0000000..9a51e55 --- /dev/null +++ b/src/features/province-finacial/components/province-financial-number/FinancialDocumentNumber.js @@ -0,0 +1,14 @@ +import { Grid } from "@mui/material"; +import React from "react"; +import { SimpleTable } from "../../../../components/simple-table/SimpleTable"; + +export const FinancialDocumentNumber = () => { + return ( + + + + ); +}; diff --git a/src/features/province-finacial/components/province-financial-operations/ProvinceFinancialOperations.js b/src/features/province-finacial/components/province-financial-operations/ProvinceFinancialOperations.js new file mode 100644 index 0000000..cba837f --- /dev/null +++ b/src/features/province-finacial/components/province-financial-operations/ProvinceFinancialOperations.js @@ -0,0 +1,211 @@ +import { Grid } from "../../../../components/grid/Grid"; +import { SPACING } from "../../../../data/spacing"; +import { NavLink } from "../../../../components/nav-link/NavLink"; +import { useLocation } from "react-router-dom"; +import { + ROUTE_PROVINCE_FINANCIAL_ACTIVE_REQUESTS, + ROUTE_PROVINCE_FINANCIAL_ARCHIVED_REQUESTS, + ROUTE_PROVINCE_FINANCIAL_AWAITING_INSPECTION_REQUESTS, + ROUTE_PROVINCE_FINANCIAL_AWAITING_PAYMENT_REQUESTS, + ROUTE_PROVINCE_FINANCIAL_CHECK_PAYED_FACTOR_REQUESTS, + ROUTE_PROVINCE_FINANCIAL_FINAL_FACTORS_REQUESTS, + ROUTE_PROVINCE_FINANCIAL_PENDING_REQUESTS, + ROUTE_PROVINCE_FINANCIAL_TRANSACTIONS, + // ROUTE_PROVINCE_FINANCIAL_REJECTED_REQUESTS, +} from "../../../../routes/routes"; +import LinkItem from "../../../../components/link-item/LinkItem"; +import { MdOutlinePendingActions } from "react-icons/md"; +import { GiMoneyStack } from "react-icons/gi"; +import { CiMoneyCheck1 } from "react-icons/ci"; +import { VscFolderActive } from "react-icons/vsc"; +import { GrInspect } from "react-icons/gr"; +import { FaArchive, FaExchangeAlt } from "react-icons/fa"; +import { LineWithText } from "../../../../components/line-with-text/LineWithText"; + +export const ProvinceFinancialOperations = () => { + const { pathname } = useLocation(); + + return ( + + {/* + + */} + + + + + + + + } + title="صدور فاکتور" + description="درخواست های در انتظار تایید و صدور فاکتور" + /> + + + + } + title="در انتظار پرداخت" + description="مشاهده درخواست های در انتظار پرداخت کشتارگاه" + /> + + + + } + title="فاکتورهای پرداخت شده" + description="بررسی فاکتورهای پرداخت شده" + /> + + + + } + title="تراکنش ها" + /> + + + + + + + + + + + } + title="اسناد مالی" + description="مشاهده و بررسی فاکتور های نهایی" + /> + + + } + title="درخواست های فعال" + description="مشاهده درخواست های در جریان" + /> + + + + } + title="در انتظار بازرسی" + description="درخواست های در انتظار بررسی بازرس" + /> + + + {/* + + */} + + + + } + title="بایگانی" + description="درخواست های پایان یافته" + /> + + + + + ); +}; diff --git a/src/features/province-finacial/components/province-financial-pending-requests/ProvinceFinancialPendingRequests.js b/src/features/province-finacial/components/province-financial-pending-requests/ProvinceFinancialPendingRequests.js new file mode 100644 index 0000000..2f001b4 --- /dev/null +++ b/src/features/province-finacial/components/province-financial-pending-requests/ProvinceFinancialPendingRequests.js @@ -0,0 +1,148 @@ +import { TextField } from "@mui/material"; +import { useContext, useEffect, useState } from "react"; +import PlagiarismIcon from "@mui/icons-material/Plagiarism"; +import { useNavigate } from "react-router-dom"; +import { ROUTE_PROVINCE_FINANCIAL_FILE } from "../../../../routes/routes"; +import IconButton from "@mui/material/IconButton"; +import { useDispatch, useSelector } from "react-redux"; +import { provinceFinancialGetPendingRequestsService } from "../../services/province-financial-get-pending-requests"; +import { DRAWER } from "../../../../lib/redux/slices/appSlice"; +import { FinancialCheckRequestOperation } from "../../../file/components/financial-check-request-operation/FinancialCheckRequestOperation"; +import EditIcon from "@mui/icons-material/Edit"; +import { Grid } from "../../../../components/grid/Grid"; +import { ProvinceFinancialCheckRequestInfo } from "../province-financial-check-request-info/ProvinceFinancialCheckRequestInfo"; +import { formatJustDate } from "../../../../utils/formatTime"; +import { SPACING } from "../../../../data/spacing"; +import moment from "moment/moment"; +import { AppContext } from "../../../../contexts/AppContext"; +import { DatePicker } from "@mui/x-date-pickers"; +import ResponsiveTable from "../../../../components/responsive-table/ResponsiveTable"; + +export const ProvinceFinancialPendingRequests = () => { + const navigate = useNavigate(); + const dispatch = useDispatch(); + const { provinceFinancialGetPendingRequests } = useSelector( + (state) => state.provinceFinancialSlice + ); + const [dataTable, setDataTable] = useState([]); + + const [, , selectedDate1, setSelectedDate1, selectedDate2, setSelectedDate2] = + useContext(AppContext); + + useEffect(() => { + const currentDate = moment(new Date()).format("YYYY-MM-DD"); + setSelectedDate1(currentDate); + setSelectedDate2(currentDate); + }, []); + + useEffect(() => { + dispatch( + provinceFinancialGetPendingRequestsService({ + selectedDate1, + selectedDate2, + }) + ); + }, [selectedDate1, selectedDate2]); + + useEffect(() => { + const d = provinceFinancialGetPendingRequests?.map((item, i) => { + return [ + i + 1, + item?.barCode, + formatJustDate(item?.sendDate), + `${item?.fullName} (${item?.mobile})`, + item?.unitName, + `${item?.killHouseName} (${item.killHouseMobile})`, + `${item?.killPlace}`, + `${item?.province}/${item?.city}`, + item?.age, + item?.acceptedRealQuantity?.toLocaleString(), + item?.killHouseNetWeight?.toLocaleString() + " کیلوگرم", + { + dispatch( + DRAWER({ + title: "انجام عملیات تایید / رد درخواست", + // right: !(window.innerWidth <= 600), + top: !(window.innerWidth <= 600), + bottom: window.innerWidth <= 600, + content: ( + + + + + ), + }) + ); + }} + > + + , + { + navigate( + ROUTE_PROVINCE_FINANCIAL_FILE + + item?.poultryRequest?.process?.poultry?.poultryRequestId + ); + }} + > + + , + ]; + }); + setDataTable(d || []); + }, [provinceFinancialGetPendingRequests]); + + const [tableDataCol] = useState([ + "ردیف", + "کد بار", + "تاریخ کشتار", + "مرغدار", + "نام مرغداری", + "خریدار", + "محل کشتار", + "استان/شهر", + "سن مرغ", + "تعداد", + "وزن بار", + "عملیات", + "مشاهده", + ]); + return ( + + + + } + value={selectedDate1} + onChange={(e) => { + setSelectedDate1(moment(e).format("YYYY-MM-DD")); + }} + /> + + + } + value={selectedDate2} + onChange={(e) => { + setSelectedDate2(moment(e).format("YYYY-MM-DD")); + }} + /> + + + + + ); +}; diff --git a/src/features/province-finacial/components/province-financial-profile/ProvinceFinancialProfile.js b/src/features/province-finacial/components/province-financial-profile/ProvinceFinancialProfile.js new file mode 100644 index 0000000..5eab435 --- /dev/null +++ b/src/features/province-finacial/components/province-financial-profile/ProvinceFinancialProfile.js @@ -0,0 +1,59 @@ +import { Box } from "@mui/system"; +import { useEffect } from "react"; +import { useDispatch, useSelector } from "react-redux"; +import { Grid } from "../../../../components/grid/Grid"; +import { SimpleTable } from "../../../../components/simple-table/SimpleTable"; +import { SPACING } from "../../../../data/spacing"; +import { + LOADING_END, + LOADING_START, +} from "../../../../lib/redux/slices/appSlice"; +import { ChangeCardInfo } from "../../../authentication/components/change-card-info/ChangeCardInfo"; +import { provinceGetProfile } from "../../../province/services/province-get-profile"; + +export const ProvinceFinancialProfile = () => { + const dispatch = useDispatch(); + const { profile } = useSelector((state) => state.provinceSlice); + + useEffect(() => { + dispatch(LOADING_START()); + dispatch(provinceGetProfile()).then((r) => { + dispatch(LOADING_END()); + }); + }, []); + + return ( + + + + + <> + + + + + + + + + + + + ); +}; diff --git a/src/features/province-finacial/components/province-financial-register-debt/ProvinceFinancialRegisterDebt.js b/src/features/province-finacial/components/province-financial-register-debt/ProvinceFinancialRegisterDebt.js new file mode 100644 index 0000000..f34420b --- /dev/null +++ b/src/features/province-finacial/components/province-financial-register-debt/ProvinceFinancialRegisterDebt.js @@ -0,0 +1,153 @@ +import { Autocomplete, Button, TextField } from "@mui/material"; +import { useFormik } from "formik"; +import React, { useEffect } from "react"; +import { Grid } from "../../../../components/grid/Grid"; +import { SPACING } from "../../../../data/spacing"; +import { Yup } from "../../../../lib/yup/yup"; + +export const ProvinceFinancialRegisterDebt = () => { + const formik = useFormik({ + initialValues: { + price: "", + description: "", + }, + validationSchema: Yup.object({ + description: Yup.string() + .required("لطفا پیغام خود را بنویسید!") + .typeError("لطفا فیلد را پر کنید!"), + price: Yup.number() + .required("لطفا عدد وارد کنید!") + .typeError("لطفا فیلد را پر کنید!"), + }), + }); + + useEffect(() => { + formik.validateForm(); + }, []); + + return ( + + + + ({ + // id: i.key, + // label: i.name, + // })) + // : [] + // } + // onChange={(e, value) => { + // setPoultryProvinceKey(value.id); + // }} + renderInput={(params) => ( + + )} + /> + + + + + + + + + {/* + + */} + + + + + + + ); +}; diff --git a/src/features/province-finacial/components/province-financial-settlement-slaughter-form/ProvinceFinancialSettlementSlaughterForm.js b/src/features/province-finacial/components/province-financial-settlement-slaughter-form/ProvinceFinancialSettlementSlaughterForm.js new file mode 100644 index 0000000..10aea63 --- /dev/null +++ b/src/features/province-finacial/components/province-financial-settlement-slaughter-form/ProvinceFinancialSettlementSlaughterForm.js @@ -0,0 +1,85 @@ +import { Button } from "@mui/material"; +import { useFormik } from "formik"; +import { useContext, useEffect } from "react"; +import { useDispatch } from "react-redux"; +import { Grid } from "../../../../components/grid/Grid"; +import { NumberInput } from "../../../../components/number-format-custom/NumberFormatCustom"; +import { AppContext } from "../../../../contexts/AppContext"; +import { SPACING } from "../../../../data/spacing"; +import { DRAWER } from "../../../../lib/redux/slices/appSlice"; +import { provinceFinancialGetSlaughterSattlementService } from "../../services/province-financial-get-slaughter-sattlement-service"; +import { provinceFinancialSettlmentService } from "../../services/province-financial-settlment"; + +const validate = (values, maxValue) => { + const errors = {}; + if (!values.price) { + errors.price = "این فیلد اجباری است."; + } else if (!/^[0-9]*$/i.test(values.price)) { + errors.price = "لطفا عدد وارد کنید."; + } else if (parseInt(values.price) > parseInt(maxValue)) { + errors.price = `عدد نمی تواند بزرگتر از ${maxValue} ﷼ باشد.`; + } + return errors; +}; + +export const ProvinceFinancialSettlementSlaughterForm = ({ item }) => { + const [openNotif] = useContext(AppContext); + const dispatch = useDispatch(); + const formik = useFormik({ + initialValues: { + price: item.amount, + }, + validate: (values) => validate(values, item.amount), + onSubmit: (values) => { + dispatch( + provinceFinancialSettlmentService({ + amount: values.price, + key: item.key, + }) + ).then((r) => { + dispatch(provinceFinancialGetSlaughterSattlementService()); + openNotif({ + vertical: "top", + horizontal: "center", + msg: "عملیات با موفقیت انجام شد.", + severity: "success", + }); + dispatch( + DRAWER({ right: false, bottom: false, content: null, size: null }) + ); + }); + }, + }); + + useEffect(() => { + formik.setFieldValue("price", item.amount); + }, []); + return ( +
    + + + + + + +
    + ); +}; diff --git a/src/features/province-finacial/components/province-financial-settlement-slaughter/ProvinceFinancialSettlementSlaughter.js b/src/features/province-finacial/components/province-financial-settlement-slaughter/ProvinceFinancialSettlementSlaughter.js new file mode 100644 index 0000000..be8ca9e --- /dev/null +++ b/src/features/province-finacial/components/province-financial-settlement-slaughter/ProvinceFinancialSettlementSlaughter.js @@ -0,0 +1,68 @@ +import { IconButton } from "@mui/material"; +import { useEffect, useState } from "react"; +import { useDispatch, useSelector } from "react-redux"; +// import { useNavigate } from "react-router-dom"; +import { AdvancedTable } from "../../../../components/advanced-table/AdvancedTable"; +import { Grid } from "../../../../components/grid/Grid"; +import { SPACING } from "../../../../data/spacing"; +import { DRAWER } from "../../../../lib/redux/slices/appSlice"; +import { provinceFinancialGetSlaughterSattlementService } from "../../services/province-financial-get-slaughter-sattlement-service"; +import { ProvinceFinancialSettlementSlaughterForm } from "../province-financial-settlement-slaughter-form/ProvinceFinancialSettlementSlaughterForm"; +import EditIcon from "@mui/icons-material/Edit"; + +export const ProvinceFinancialSettlementSlaughter = () => { + // const navigate = useNavigate(); + const dispatch = useDispatch(); + const { provinceFinancialGetSlaughterSattlement } = useSelector( + (state) => state.provinceFinancialSlice + ); + const [dataTable, setDataTable] = useState([]); + + useEffect(() => { + dispatch(provinceFinancialGetSlaughterSattlementService()); + }, []); + + useEffect(() => { + const d = provinceFinancialGetSlaughterSattlement?.map((item, i) => { + return [ + item.killHouse.name, + item.killHouse.killHouseOperator.user.fullname, + item.killHouse.killHouseOperator.user.mobile, + item.killHouse.killHouseOperator.user.city, + item.killHouse.killHouseOperator.user.province, + item.amount.toLocaleString() + " ﷼", + { + dispatch( + DRAWER({ + title: "انجام عملیات تسویه حساب", + right: !(window.innerWidth <= 600), + // top: !(window.innerWidth <= 600), + bottom: window.innerWidth <= 600, + content: ( + + ), + }) + ); + }} + > + + , + ]; + }); + + setDataTable(d); + }, [provinceFinancialGetSlaughterSattlement]); + + return ( + + + + ); +}; diff --git a/src/features/province-finacial/components/province-financial-submit-debt-document/ProvinceFinancialSubmitDebtDocument.js b/src/features/province-finacial/components/province-financial-submit-debt-document/ProvinceFinancialSubmitDebtDocument.js new file mode 100644 index 0000000..afe372c --- /dev/null +++ b/src/features/province-finacial/components/province-financial-submit-debt-document/ProvinceFinancialSubmitDebtDocument.js @@ -0,0 +1,233 @@ +import { + Button, + FormControl, + FormHelperText, + InputAdornment, + InputLabel, + MenuItem, + Select, + TextField, + Typography, +} from "@mui/material"; +import { useFormik } from "formik"; +import React, { useContext, useEffect } from "react"; +import { Grid } from "../../../../components/grid/Grid"; +import { ImageUpload } from "../../../../components/image-upload/ImageUpload"; +import { SPACING } from "../../../../data/spacing"; +import { Yup } from "../../../../lib/yup/yup"; +import { fixBase64 } from "../../../../utils/toBase64"; +import { PropTypes } from "prop-types"; +import { useDispatch } from "react-redux"; +import { + DRAWER, + LOADING_END, + LOADING_START, +} from "../../../../lib/redux/slices/appSlice"; +import { ProvinceFinancialSubmitFinancialTransaction } from "../../services/province-financial-submit-financial-transaction"; +import { AppContext } from "../../../../contexts/AppContext"; +import { NumberInput } from "../../../../components/number-format-custom/NumberFormatCustom"; + +const ProvinceFinancialSubmitDebtDocument = ({ profileid, walletkey }) => { + const [documentImages, setDocumentImages] = React.useState([]); + const [documentImagesBase64, setDocumentImagesBase64] = React.useState([]); + + const [openNotif] = useContext(AppContext); + + const dispatch = useDispatch(); + + const documentImageHandler = (imageList, addUpdateIndex) => { + setDocumentImages(imageList); + setDocumentImagesBase64(imageList.map((img) => fixBase64(img.data_url))); + }; + + const formik = useFormik({ + initialValues: { + debt: "", + // paymentId: "", + description: "", + transactionType: "", + }, + validationSchema: Yup.object({ + debt: Yup.number() + .required("این فیلد اجباری است!") + .typeError("لطفا عدد وارد کنید!"), + // paymentId: Yup.string() + // .required("این فیلد اجباری است!") + // .typeError("لطفا فیلد را به درستی پر کنید!"), + description: Yup.string().typeError("لطفا فیلد را به درستی پر کنید!"), + transactionType: Yup.string() + .required("این فیلد اجباری است!") + .typeError("لطفا فیلد را به درستی پر کنید!"), + }), + }); + + useEffect(() => { + formik.validateForm(); + }, []); + + return ( + + + + نوع تراکنش + + + {formik.touched.transactionType && + Boolean(formik.errors.transactionType) + ? formik.errors.transactionType + : null} + + + + ریال + ), + }} + value={formik.values.debt} + error={formik.touched.debt ? Boolean(formik.errors.debt) : null} + onChange={formik.handleChange} + onBlur={formik.handleBlur} + helperText={ + formik.touched.debt && Boolean(formik.errors.debt) + ? formik.errors.debt + : null + } + /> + + {/* */} + + + + پیوست تصویر + + + + + + ); +}; + +export default ProvinceFinancialSubmitDebtDocument; + +ProvinceFinancialSubmitDebtDocument.propTypes = { + profileid: PropTypes.any, + walletkey: PropTypes.any, +}; diff --git a/src/features/province-finacial/components/province-financial-submit-financial-document/ProvinceFinancialSubmitFinancialDocument.js b/src/features/province-finacial/components/province-financial-submit-financial-document/ProvinceFinancialSubmitFinancialDocument.js new file mode 100644 index 0000000..08660dc --- /dev/null +++ b/src/features/province-finacial/components/province-financial-submit-financial-document/ProvinceFinancialSubmitFinancialDocument.js @@ -0,0 +1,234 @@ +import { Button, TextField, Typography } from "@mui/material"; +import { useFormik } from "formik"; +import React, { useContext, useEffect } from "react"; +import { Grid } from "../../../../components/grid/Grid"; +import { ImageUpload } from "../../../../components/image-upload/ImageUpload"; +import { SPACING } from "../../../../data/spacing"; +import { Yup } from "../../../../lib/yup/yup"; +import { fixBase64 } from "../../../../utils/toBase64"; +import { PropTypes } from "prop-types"; +import Num2persian from "num2persian"; +import { useDispatch } from "react-redux"; +import { + DRAWER, + LOADING_END, + LOADING_START, +} from "../../../../lib/redux/slices/appSlice"; +import { ProvinceFinancialSubmitNewFinancialDocument } from "../../services/province-financial-submit-financial-document"; +import { AppContext } from "../../../../contexts/AppContext"; + +export const ProvinceFinancialSubmitFinancialDocument = ({ + payable, + transactionsList, + userId, + paymentType, + userKey, +}) => { + const [openNotif] = useContext(AppContext); + + const [documentImages, setDocumentImages] = React.useState([]); + const [documentImagesBase64, setDocumentImagesBase64] = React.useState([]); + const dispatch = useDispatch(); + + const documentImageHandler = (imageList, addUpdateIndex) => { + setDocumentImages(imageList); + setDocumentImagesBase64(imageList.map((img) => fixBase64(img.data_url))); + }; + + const formik = useFormik({ + initialValues: { + paymentId: "", + description: "", + // paymentType: "", + }, + validationSchema: Yup.object({ + paymentId: Yup.string() + .required("این فیلد اجباری است!") + .typeError("لطفا فیلد را به درستی پر کنید!"), + description: Yup.string() + .required("این فیلد اجباری است!") + .typeError("لطفا فیلد را به درستی پر کنید!"), + // paymentType: Yup.string() + // .required("این فیلد اجباری است!") + // .typeError("لطفا فیلد را به درستی پر کنید!"), + }), + }); + + useEffect(() => { + formik.validateForm(); + }, []); + + return ( + + + + prop.palette.grey["A700"]} + > + مبلغ: + + + {Math.abs(payable).toLocaleString()} + + + + + prop.palette.grey["A700"]} + > + به حروف: + + + {Num2persian(Math.abs(payable))} ریال + + + + + {/* + روش پرداخت + + + {formik.touched.paymentType && Boolean(formik.errors.paymentType) + ? formik.errors.paymentType + : null} + + */} + + + + + + پیوست تصویر + + + + + + + + ); +}; + +ProvinceFinancialSubmitFinancialDocument.propTypes = { + payable: PropTypes.any, + transactionsList: PropTypes.any, + userId: PropTypes.any, + paymentType: PropTypes.any, + userKey: PropTypes.any, +}; diff --git a/src/features/province-finacial/components/province-financial-user-financial/ProvinceFinancialUserFinancial.js b/src/features/province-finacial/components/province-financial-user-financial/ProvinceFinancialUserFinancial.js new file mode 100644 index 0000000..f2d1b51 --- /dev/null +++ b/src/features/province-finacial/components/province-financial-user-financial/ProvinceFinancialUserFinancial.js @@ -0,0 +1,683 @@ +import { Button, IconButton, Tooltip, Typography } from "@mui/material"; +import React, { useEffect, useState } from "react"; +import { useNavigate, useParams } from "react-router-dom"; +import { Grid } from "../../../../components/grid/Grid"; +import NavigateNextIcon from "@mui/icons-material/NavigateNext"; +import { SPACING } from "../../../../data/spacing"; +import { SimpleTable } from "../../../../components/simple-table/SimpleTable"; +import BlockIcon from "@mui/icons-material/Block"; +import InfoIcon from "@mui/icons-material/Info"; +import List from "@mui/material/List"; +import Card from "@mui/material/Card"; +import CardHeader from "@mui/material/CardHeader"; +import ListItemText from "@mui/material/ListItemText"; +import ListItemIcon from "@mui/material/ListItemIcon"; +import Checkbox from "@mui/material/Checkbox"; +import CheckBoxOutlineBlankIcon from "@mui/icons-material/CheckBoxOutlineBlank"; +import Divider from "@mui/material/Divider"; +import { + CLOSE_MODAL, + DRAWER, + LOADING_END, + LOADING_START, + OPEN_MODAL, +} from "../../../../lib/redux/slices/appSlice"; +import { useDispatch, useSelector } from "react-redux"; +import ProvinceFinancialSubmitDebtDocument from "../province-financial-submit-debt-document/ProvinceFinancialSubmitDebtDocument"; +import { ProvinceFinancialSubmitFinancialDocument } from "../province-financial-submit-financial-document/ProvinceFinancialSubmitFinancialDocument"; +import { Box } from "@mui/system"; +import { ProvinceFinancialDebtorInfo } from "../province-financial-debtor-info/ProvinceFinancialDebtorInfo"; +import { provinceFinancialGetUserFinancialInfo } from "../../services/province-financial-get-user-financial-info"; +import { formatJustDate } from "../../../../utils/formatTime"; +import Num2persian from "num2persian"; +import ProvinceFinancialFinancialHistory from "../province-financial-financial-history/ProvinceFinancialFinancialHistory"; +import { ROUTE_PROVINCE_FINANCIAL_FILE } from "../../../../routes/routes"; +import { provinceFinancialChangeTransactionState } from "../../services/province-financial-change-transaction-state"; + +function not(a, b) { + return a.filter((value) => b.indexOf(value) === -1); +} + +function intersection(a, b) { + return a.filter((value) => b.indexOf(value) !== -1); +} + +function union(a, b) { + return [...a, ...not(b, a)]; +} + +const ProvinceFinancialUserFinancial = () => { + const { userFinancialInfo } = useSelector( + (state) => state.provinceFinancialSlice + ); + + const [leftObject, setLeftObject] = useState({ + creditor: "", + debtor: "", + payable: "", + }); + const [rightObject, setRighObject] = useState({ + creditor: "", + debtor: "", + payable: "", + }); + + const [selectedTransactions, setSelectedTransactions] = useState([]); + const dispatch = useDispatch(); + const navigate = useNavigate(); + const { userid } = useParams(); + const { profileid } = useParams(); + + const [checked, setChecked] = React.useState([]); + const [left, setLeft] = React.useState([]); + const [right, setRight] = React.useState([]); + + const leftChecked = intersection(checked, left); + const rightChecked = intersection(checked, right); + + const [dispatched, setDispatched] = useState(false); + + useEffect(() => { + dispatch(LOADING_START()); + dispatch(provinceFinancialGetUserFinancialInfo(userid)).then(() => { + dispatch(LOADING_END()); + setDispatched(!dispatched); + }); + }, []); + + useEffect(() => { + setRight(userFinancialInfo); + }, [dispatched]); + + const handleToggle = (value) => () => { + const currentIndex = checked.indexOf(value); + const newChecked = [...checked]; + + if (currentIndex === -1) { + newChecked.push(value); + } else { + newChecked.splice(currentIndex, 1); + } + + setChecked(newChecked); + }; + + const isValidSelect = (rightChecked) => { + if (rightChecked?.length === 0) { + return true; + } else { + for (let index = 0; index < rightChecked?.length; index++) { + if (rightChecked[index].transactionType === "creditor") { + return true; + } else { + return false; + } + } + } + }; + + const numberOfChecked = (items) => intersection(checked, items).length; + + const handleToggleAll = (items) => () => { + const checkable = items.filter( + (item) => + item.transactionType === "penalty" || + item.transactionType === "negative" || + item.transactionType === "positive" || + item.transactionType === "debtor" || + item.transactionType === "deposit" + ); + if (numberOfChecked(checkable) === checkable?.length) { + setChecked(not(checked, checkable)); + } else { + setChecked(union(checked, checkable)); + } + }; + + const handleCheckedRight = () => { + setRight(right.concat(leftChecked)); + setLeft(not(left, leftChecked)); + setChecked(not(checked, leftChecked)); + }; + + const handleCheckedLeft = () => { + setLeft(left.concat(rightChecked)); + setRight(not(right, rightChecked)); + setChecked(not(checked, rightChecked)); + }; + + useEffect(() => { + //hint: left is right!! because of rtl in persian :) + let rightCreditorfilter = right?.filter( + (item) => item?.transactionType === "creditor" + ); + + let rightCreditor = 0; + for (let index = 0; index < rightCreditorfilter?.length; index++) { + rightCreditor = rightCreditor + rightCreditorfilter[index].transferAmount; + } + + let rightDebtorfilter = right?.filter( + (item) => item.transactionType === "debtor" + ); + + let rightDebtor = 0; + for (let index = 0; index < rightDebtorfilter?.length; index++) { + rightDebtor = rightDebtor + rightDebtorfilter[index].transferAmount; + } + + let rightPenaltyfilter = right?.filter( + (item) => item.transactionType === "penalty" + ); + + let rightPenalty = 0; + for (let index = 0; index < rightPenaltyfilter?.length; index++) { + rightPenalty = rightPenalty + rightPenaltyfilter[index].transferAmount; + } + + let rightDepositfilter = right?.filter( + (item) => item.transactionType === "deposit" + ); + + let rightDeposit = 0; + for (let index = 0; index < rightDepositfilter?.length; index++) { + rightDeposit = rightDeposit + rightDepositfilter[index].transferAmount; + } + + let rightPositivefilter = right?.filter( + (item) => item.transactionType === "positive" + ); + + let rightPositive = 0; + for (let index = 0; index < rightPositivefilter?.length; index++) { + rightPositive = rightPositive + rightPositivefilter[index].transferAmount; + } + + let rightNegativefilter = right?.filter( + (item) => item.transactionType === "negative" + ); + + let rightNegative = 0; + for (let index = 0; index < rightNegativefilter?.length; index++) { + rightNegative = rightNegative + rightNegativefilter[index].transferAmount; + } + + // end calculation right object + + let leftCreditorfilter = left?.filter( + (item) => item.transactionType === "creditor" + ); + + let leftCreditor = 0; + for (let index = 0; index < leftCreditorfilter?.length; index++) { + leftCreditor = leftCreditor + leftCreditorfilter[index].transferAmount; + } + + let leftDebtorfilter = left?.filter( + (item) => item.transactionType === "debtor" + ); + + let leftDebtor = 0; + for (let index = 0; index < leftDebtorfilter.length; index++) { + leftDebtor = leftDebtor + leftDebtorfilter[index].transferAmount; + } + + let leftPenaltyfilter = left?.filter( + (item) => item.transactionType === "penalty" + ); + + let leftPenalty = 0; + for (let index = 0; index < leftPenaltyfilter?.length; index++) { + leftPenalty = leftPenalty + leftPenaltyfilter[index].transferAmount; + } + + let leftDepositfilter = left?.filter( + (item) => item.transactionType === "deposit" + ); + + let leftDeposit = 0; + for (let index = 0; index < leftDepositfilter.length; index++) { + leftDeposit = leftDeposit + leftDepositfilter[index].transferAmount; + } + + let leftPositivefilter = left?.filter( + (item) => item.transactionType === "positive" + ); + + let leftPositive = 0; + for (let index = 0; index < leftPositivefilter?.length; index++) { + leftPositive = leftPositive + leftPositivefilter[index].transferAmount; + } + + let leftNegativefilter = left?.filter( + (item) => item.transactionType === "negative" + ); + + let leftNegative = 0; + for (let index = 0; index < leftNegativefilter?.length; index++) { + leftNegative = leftNegative + leftNegativefilter[index].transferAmount; + } + + //end calculation left object + + setLeftObject({ + creditor: leftCreditor + leftDeposit + leftPositive, + debtor: leftDebtor + leftPenalty + leftNegative, + payable: + leftCreditor + + leftDeposit + + leftPositive - + (leftDebtor + leftPenalty + leftNegative), + }); + + setRighObject({ + creditor: rightCreditor + rightDeposit + rightPositive, + debtor: rightDebtor + rightPenalty + rightNegative, + payable: Math.abs( + rightCreditor + + rightDeposit + + rightPositive - + (rightDebtor + rightPenalty + rightNegative) + ), + }); + + const selects = left.map((item) => { + return item.key; + }); + setSelectedTransactions(selects); + }, [left, right]); + + const customList = (title, items) => ( + + + } + title={title} + subheader={`${numberOfChecked(items)}/${items?.length} انتخاب شده`} + /> + + + + + انتخاب سند + نوع سند + کد پیگیری + مبلغ + زمان ثبت + + + + {items?.map((value, i) => { + const labelId = `transfer-list-all-item-${value}-label`; + return ( + + + + + + ) : ( + + ) + } + color={"secondary"} + disabled={value.transactionType === "creditor"} + onClick={handleToggle(value)} + checked={checked.indexOf(value) !== -1} + tabIndex={-1} + disableRipple + inputProps={{ + "aria-labelledby": labelId, + }} + /> + + + + + + { + dispatch( + DRAWER({ right: false, bottom: false, content: null }) + ); + dispatch( + OPEN_MODAL({ + title: "تراکنش را تایید میکنید؟", + content: ( + + + + + ), + }) + ); + }} + > + + + + + {value.fileId > 0 ? ( + + ) : ( + + )} + + {/* { + dispatch( + DRAWER({ + right: !(window.innerWidth <= 600), + bottom: window.innerWidth <= 600, + content: , + title: "اطلاعات سند بدهکاری", + }) + ); + }} + > + {value.paymentCode} + */} + + + + + + + + ); + })} + + + + ); + + return ( + + + navigate(-1)} + > + + بازگشت + + + + + + + { + dispatch( + DRAWER({ + right: !(window.innerWidth <= 600), + bottom: window.innerWidth <= 600, + content: ( + 1 + ? "positive" + : "zero" + } + payable={leftObject.payable} + transactionsList={selectedTransactions} + userId={profileid} + userKey={userid} + /> + ), + title: "ایجاد سند مالی", + }) + ); + }} + > + {leftObject.payable > 0 ? ( + <>ایجاد سند مالی (طلبکار) + ) : leftObject.payable < 0 ? ( + <>ایجاد سند مالی (بدهکار) + ) : ( + <>ایجاد سند مالی + )} + , + ], + ]} + /> + + + + + + + {customList("انتخاب شده ها", left)} + + + + + + + + + {customList("انتخاب شده", right)} + + + + + + + ); +}; + +export default ProvinceFinancialUserFinancial; diff --git a/src/features/province-finacial/services/province-financial-change-transaction-state.js b/src/features/province-finacial/services/province-financial-change-transaction-state.js new file mode 100644 index 0000000..e02c06e --- /dev/null +++ b/src/features/province-finacial/services/province-financial-change-transaction-state.js @@ -0,0 +1,10 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; + +export const provinceFinancialChangeTransactionState = createAsyncThunk( + "PROVINCE_FINANCIAL_CHANGE_TRANSACTION_STATE", + async (d) => { + const { data, status } = await axios.put("typecheck/0/", d); + return { data, status }; + } +); diff --git a/src/features/province-finacial/services/province-financial-get-active-requests.js b/src/features/province-finacial/services/province-financial-get-active-requests.js new file mode 100644 index 0000000..f8865af --- /dev/null +++ b/src/features/province-finacial/services/province-financial-get-active-requests.js @@ -0,0 +1,10 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; + +export const provinceFinancialGetActiveRequests = createAsyncThunk( + "PROVINCE_FINANCIAL_GET_REQUESTS", + async () => { + const { data, status } = await axios.get("province_check_info"); + return { data, status }; + } +); diff --git a/src/features/province-finacial/services/province-financial-get-final-factors-service.js b/src/features/province-finacial/services/province-financial-get-final-factors-service.js new file mode 100644 index 0000000..82bdc84 --- /dev/null +++ b/src/features/province-finacial/services/province-financial-get-final-factors-service.js @@ -0,0 +1,10 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; + +export const provinceFinancialGetFinalFactorsService = createAsyncThunk( + "PROVINCE_FINANCIAL_GET_FINAL_FACTORS_SERVICE", + async (d) => { + const { data, status } = await axios.get("deposit_allocation/"); + return { data, status }; + } +); diff --git a/src/features/province-finacial/services/province-financial-get-financial-history.js b/src/features/province-finacial/services/province-financial-get-financial-history.js new file mode 100644 index 0000000..6c5f055 --- /dev/null +++ b/src/features/province-finacial/services/province-financial-get-financial-history.js @@ -0,0 +1,12 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; + +export const provinceFinancialGetFinancialHistory = createAsyncThunk( + "PROVINCE_FINANCIAL_GET_FINANCIQAL_HISTORY", + async (d) => { + const { data, status } = await axios.get( + "financialdocument/?user_id=" + d + "&all" + ); + return { data, status }; + } +); diff --git a/src/features/province-finacial/services/province-financial-get-payed-factors-service.js b/src/features/province-finacial/services/province-financial-get-payed-factors-service.js new file mode 100644 index 0000000..76cce5d --- /dev/null +++ b/src/features/province-finacial/services/province-financial-get-payed-factors-service.js @@ -0,0 +1,13 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { getRoleFromUrl } from "../../../utils/getRoleFromUrl"; + +export const provinceFinancialGetPayedFactorsService = createAsyncThunk( + "PROVINCE_FINANCIAL_GET_PAYED_FACTORS_SERVICE", + async (d) => { + const { data, status } = await axios.get("kill_house_factor_province/", { + params: { role: getRoleFromUrl() }, + }); + return { data, status }; + } +); diff --git a/src/features/province-finacial/services/province-financial-get-pending-requests.js b/src/features/province-finacial/services/province-financial-get-pending-requests.js new file mode 100644 index 0000000..c792658 --- /dev/null +++ b/src/features/province-finacial/services/province-financial-get-pending-requests.js @@ -0,0 +1,21 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const provinceFinancialGetPendingRequestsService = createAsyncThunk( + "PROVINCE_FINANCIAL_GET_PENDING_REQUESTS", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + const { data, status } = await axios.get( + "kill_house_assignment_information/?role=ProvinceFinancial", + { + params: { + date1: d.selectedDate1, + date2: d.selectedDate2, + }, + } + ); + dispatch(LOADING_END()); + return { data, status }; + } +); diff --git a/src/features/province-finacial/services/province-financial-get-registered-compaints.js b/src/features/province-finacial/services/province-financial-get-registered-compaints.js new file mode 100644 index 0000000..8353b5e --- /dev/null +++ b/src/features/province-finacial/services/province-financial-get-registered-compaints.js @@ -0,0 +1,12 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; + +export const provinceFinancialGetRegisteredComplaints = createAsyncThunk( + "PROVINCE_FINANCIAL_GET_COMLATIONS", + async (id) => { + const { data, status } = await axios.get( + "kill_house_complaint/?role=ProvinceFinancial" + ); + return { data, status }; + } +); diff --git a/src/features/province-finacial/services/province-financial-get-requests.js b/src/features/province-finacial/services/province-financial-get-requests.js new file mode 100644 index 0000000..93ffeed --- /dev/null +++ b/src/features/province-finacial/services/province-financial-get-requests.js @@ -0,0 +1,12 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; + +export const provinceFinancialGetRequests = createAsyncThunk( + "PROVINCE_FINANCIAL_GET_REQUESTS", + async () => { + const { data, status } = await axios.get( + "kill_house_assignment_information/?role=ProvinceFinancial" + ); + return { data, status }; + } +); diff --git a/src/features/province-finacial/services/province-financial-get-slaughter-sattlement-service.js b/src/features/province-finacial/services/province-financial-get-slaughter-sattlement-service.js new file mode 100644 index 0000000..c89e650 --- /dev/null +++ b/src/features/province-finacial/services/province-financial-get-slaughter-sattlement-service.js @@ -0,0 +1,10 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; + +export const provinceFinancialGetSlaughterSattlementService = createAsyncThunk( + "PROVINCE_FINANCIAL_GET_SLAUGHTER_SATTLEMENT_SERVICE", + async (d) => { + const { data, status } = await axios.get("kill_house_creditors/"); + return { data, status }; + } +); diff --git a/src/features/province-finacial/services/province-financial-get-transaction-info.js b/src/features/province-finacial/services/province-financial-get-transaction-info.js new file mode 100644 index 0000000..8ac4bee --- /dev/null +++ b/src/features/province-finacial/services/province-financial-get-transaction-info.js @@ -0,0 +1,12 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; + +export const provinceFinancialGetTransactionInfo = createAsyncThunk( + "PROVINCE_FINANCIAL_GET_TRANSACTION_INFO", + async (d) => { + const { data, status } = await axios.get( + "financial_transaction/?payment_code=" + d + ); + return { data, status }; + } +); diff --git a/src/features/province-finacial/services/province-financial-get-user-financial-info.js b/src/features/province-finacial/services/province-financial-get-user-financial-info.js new file mode 100644 index 0000000..fd2d65a --- /dev/null +++ b/src/features/province-finacial/services/province-financial-get-user-financial-info.js @@ -0,0 +1,10 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; + +export const provinceFinancialGetUserFinancialInfo = createAsyncThunk( + "PROVINCE_FINANCIAL_GET_USER_FINANCIAL_INFO", + async (d) => { + const { data, status } = await axios.get("wallet/?wallet_key=" + d); + return { data, status }; + } +); diff --git a/src/features/province-finacial/services/province-financial-get-users-walet-info.js b/src/features/province-finacial/services/province-financial-get-users-walet-info.js new file mode 100644 index 0000000..b0a725c --- /dev/null +++ b/src/features/province-finacial/services/province-financial-get-users-walet-info.js @@ -0,0 +1,10 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; + +export const provinceFinancialGetUsersWaletinfo = createAsyncThunk( + "PROVINCE_FINANCIAL_GET_USERS_WALET_INFO", + async () => { + const { data, status } = await axios.get("show_users"); + return { data, status }; + } +); diff --git a/src/features/province-finacial/services/province-financial-search-user-document.js b/src/features/province-finacial/services/province-financial-search-user-document.js new file mode 100644 index 0000000..763e92b --- /dev/null +++ b/src/features/province-finacial/services/province-financial-search-user-document.js @@ -0,0 +1,12 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; + +export const provinceFinancialSearchUserDocument = createAsyncThunk( + "PROVINCE_FINANCIAL_SEARCH_USER_DOCUMENT", + async (d) => { + const { data, status } = await axios.get( + "searchwallet/?type=filter&value=" + d + ); + return { data, status }; + } +); diff --git a/src/features/province-finacial/services/province-financial-settlment.js b/src/features/province-finacial/services/province-financial-settlment.js new file mode 100644 index 0000000..549bf69 --- /dev/null +++ b/src/features/province-finacial/services/province-financial-settlment.js @@ -0,0 +1,13 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const provinceFinancialSettlmentService = createAsyncThunk( + "PROVINCE_FINANCIAL_SETTLMENT_SERVICE", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + const { data, status } = await axios.put("kill_house_creditors/0/", d); + dispatch(LOADING_END()); + return { data, status }; + } +); diff --git a/src/features/province-finacial/services/province-financial-submit-financial-document.js b/src/features/province-finacial/services/province-financial-submit-financial-document.js new file mode 100644 index 0000000..06cd0e9 --- /dev/null +++ b/src/features/province-finacial/services/province-financial-submit-financial-document.js @@ -0,0 +1,10 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; + +export const ProvinceFinancialSubmitNewFinancialDocument = createAsyncThunk( + "PROVINCE_FINANCIAL_SUBMIT_FINANCIAL_DOCUMENT", + async (d) => { + const { data, status } = await axios.post("financialdocument/", d); + return { data, status }; + } +); diff --git a/src/features/province-finacial/services/province-financial-submit-financial-transaction.js b/src/features/province-finacial/services/province-financial-submit-financial-transaction.js new file mode 100644 index 0000000..801e377 --- /dev/null +++ b/src/features/province-finacial/services/province-financial-submit-financial-transaction.js @@ -0,0 +1,10 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; + +export const ProvinceFinancialSubmitFinancialTransaction = createAsyncThunk( + "PROVINCE_FINANCIAL_SUBMIT_FINANCIAL_TRANSACTION", + async (d) => { + const { data, status } = await axios.post("financial_transaction/", d); + return { data, status }; + } +); diff --git a/src/features/province-jahad/components/product-selector/ProductSelector.js b/src/features/province-jahad/components/product-selector/ProductSelector.js new file mode 100644 index 0000000..9be4c62 --- /dev/null +++ b/src/features/province-jahad/components/product-selector/ProductSelector.js @@ -0,0 +1,130 @@ +import React, { useState, useEffect } from "react"; +import { + Typography, + Box, + ButtonBase, + useMediaQuery, + useTheme, +} from "@mui/material"; +import { + Spa as SpaIcon, + Grass as GrassIcon, + Grain as GrainIcon, + BlurOn as BlurOnIcon, + Texture as TextureIcon, +} from "@mui/icons-material"; +import { motion } from "framer-motion"; + +const products = { + bran: { label: "سبوس", icon: }, + barley: { label: "جو", icon: }, + soy: { label: "سویا", icon: }, + corn: { label: "ذرت", icon: }, + sheep_concentrate: { + label: "کنسانتره گوسفندی", + icon: , + }, + high_cow_concentrate: { + label: "کنسانتره گاو شیری پرتولید", + icon: , + }, + medium_cow_concentrate: { + label: "کنسانتره گاو شیری متوسط", + icon: , + }, + fattening_calf_concentrate: { + label: "کنسانتره گوساله پرواری", + icon: , + }, +}; + +const LOCAL_STORAGE_KEY = "selectedProduct"; + +const MotionBox = motion(Box); + +const ProductSelector = ({ onSelect }) => { + const theme = useTheme(); + const isMobile = useMediaQuery(theme.breakpoints.down("sm")); + const [selected, setSelected] = useState("bran"); + + useEffect(() => { + const saved = localStorage.getItem(LOCAL_STORAGE_KEY); + if (saved) { + const parsed = JSON.parse(saved); + if (parsed.key && products[parsed.key]) { + setSelected(parsed.key); + onSelect(parsed); + } + } else { + onSelect({ key: "bran", label: products["bran"].label }); + } + }, [onSelect]); + + const handleSelect = (key) => { + const selectedProduct = { key, label: products[key].label }; + setSelected(key); + localStorage.setItem(LOCAL_STORAGE_KEY, JSON.stringify(selectedProduct)); + onSelect(selectedProduct); + }; + + return ( + + + انتخاب محصول + + + + {Object.entries(products).map(([key, { label, icon }]) => { + const isSelected = selected === key; + + return ( + + handleSelect(key)} + sx={{ + borderRadius: "30px", + border: `1px solid ${ + isSelected ? theme.palette.primary.main : "#ddd" + }`, + backgroundColor: isSelected ? "#e3f2fd" : "#fff", + px: 2, + py: 1, + display: "flex", + alignItems: "center", + gap: 1, + whiteSpace: "nowrap", + boxShadow: isSelected ? "0 2px 5px rgba(0,0,0,0.1)" : "none", + transition: "all 0.2s ease-in-out", + minWidth: 150, + justifyContent: "center", + }} + > + {icon} + {label} + + + ); + })} + + + ); +}; + +export default ProductSelector; diff --git a/src/features/province-jahad/components/province-jahad-allocation-operations/ProvinceJahadAllocationOperations.js b/src/features/province-jahad/components/province-jahad-allocation-operations/ProvinceJahadAllocationOperations.js new file mode 100644 index 0000000..4aa94e8 --- /dev/null +++ b/src/features/province-jahad/components/province-jahad-allocation-operations/ProvinceJahadAllocationOperations.js @@ -0,0 +1,202 @@ +import { + Button, + IconButton, + Popover, + Tooltip, + Typography, +} from "@mui/material"; +import { useContext, useState } from "react"; +import DeleteIcon from "@mui/icons-material/Delete"; +import TuneIcon from "@mui/icons-material/Tune"; +import EditIcon from "@mui/icons-material/Edit"; +import { Grid } from "../../../../components/grid/Grid"; +import { useDispatch } from "react-redux"; +import { ProvinceJahadSubmitAllocation } from "../province-jahad-submit-allocation/ProvinceJahadSubmitAllocation"; +import { CLOSE_MODAL, OPEN_MODAL } from "../../../../lib/redux/slices/appSlice"; + +import { provinceJahadDeleteAllocationService } from "../../services/province-jahad-submit-allocation"; +import { AppContext } from "../../../../contexts/AppContext"; + +export const ProvinceJahadAllocationOperations = ({ + item, + // fileUrl, + updateTable, + getDashboardData, +}) => { + const [anchorEl, setAnchorEl] = useState(null); + const dispatch = useDispatch(); + const handleClick = (event) => { + setAnchorEl(event.currentTarget); + }; + + const [openNotif] = useContext(AppContext); + + const handleClose = () => { + setAnchorEl(null); + }; + + const open = Boolean(anchorEl); + const id = open ? "popover" : undefined; + + return ( + + + + + +
    + + { + handleClose(); + dispatch( + OPEN_MODAL({ + title: "ویرایش", + content: ( + + ), + }) + ); + }} + > + + + + + + { + dispatch( + OPEN_MODAL({ + title: "حذف تخصیص", + content: ( + + + آیا از حذف تخصیص اطمینان دارید؟ + + + + + + + + + + + ), + }) + ); + }} + > + + + + + {/* {getRoleFromUrl() === "Cooperative" && ( + <> + + + )} */} +
    +
    +
    + ); +}; diff --git a/src/features/province-jahad/components/province-jahad-bran-distributions-allocation/ProvinceJahadBranDistributionsAllocation.js b/src/features/province-jahad/components/province-jahad-bran-distributions-allocation/ProvinceJahadBranDistributionsAllocation.js new file mode 100644 index 0000000..b777ed9 --- /dev/null +++ b/src/features/province-jahad/components/province-jahad-bran-distributions-allocation/ProvinceJahadBranDistributionsAllocation.js @@ -0,0 +1,182 @@ +import React, { useEffect, useState } from "react"; +import { Tab, Tabs } from "@mui/material"; +import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl"; +import { Grid } from "../../../../components/grid/Grid"; +import ResponsiveTable from "../../../../components/responsive-table/ResponsiveTable"; +import { + provinceJahadGetDistributionInfoService, + provinceJahadGetInventoryDataService, +} from "../../services/province-jahad-get-distribution-info"; +import { SPACING } from "../../../../data/spacing"; +import { useDispatch } from "react-redux"; +import { ProvinceJahadBranDistributionsInventoryAllocations } from "../province-jahad-bran-distributions-inventory-allocation/ProvinceJahadBranDistributionsInventoryAllocation"; +import { ProvinceJahadBranDistributionsUnionAllocations } from "../province-jahad-bran-distributions-union-allocation/ProvinceJahadBranDistributionsUnionAllocation"; + +export const ProvinceJahadBranDistributionsAllocation = ({ product }) => { + const [dashboardData, setDashboardData] = useState([]); + const [inventoryData, setInventoryData] = useState([]); + + const dispatch = useDispatch(); + const getDashboardData = () => { + dispatch( + provinceJahadGetDistributionInfoService({ + name: product?.key, + search: "filter", + role: getRoleFromUrl(), + }) + ).then((r) => { + setDashboardData(r.payload.data); + }); + dispatch( + provinceJahadGetInventoryDataService({ + name: product?.key, + search: "filter", + role: getRoleFromUrl(), + }) + ).then((r) => { + setInventoryData(r.payload.data); + }); + }; + + // const updateTable = (event) => { + // event.preventDefault(); + // if (childRef.current) { + // childRef.current.handleSubmit(event); + // } + // }; + + useEffect(() => { + getDashboardData(); + }, [dispatch]); + + const [selectedTab, setSelectedTab] = useState(0); + + const handleTabChange = (event, newValue) => { + setSelectedTab(newValue); + }; + + return ( + + + + + + + + + + + + {selectedTab === 0 && ( + + )} + + {selectedTab === 1 && ( + + )} + + ); +}; diff --git a/src/features/province-jahad/components/province-jahad-bran-distributions-allocations-operation/ProvinceJahadBranDistributionsAllocationsOperations.JS b/src/features/province-jahad/components/province-jahad-bran-distributions-allocations-operation/ProvinceJahadBranDistributionsAllocationsOperations.JS new file mode 100644 index 0000000..0059af6 --- /dev/null +++ b/src/features/province-jahad/components/province-jahad-bran-distributions-allocations-operation/ProvinceJahadBranDistributionsAllocationsOperations.JS @@ -0,0 +1,5 @@ +import React from "react"; + +export const ProvinceJahadBranDistributionsAllocationsOperations = () => { + return
    provinceJahadBranDistributionsAllocationsOperations
    ; +}; diff --git a/src/features/province-jahad/components/province-jahad-bran-distributions-inventory-allocation/ProvinceJahadBranDistributionsInventoryAllocation.js b/src/features/province-jahad/components/province-jahad-bran-distributions-inventory-allocation/ProvinceJahadBranDistributionsInventoryAllocation.js new file mode 100644 index 0000000..3292a89 --- /dev/null +++ b/src/features/province-jahad/components/province-jahad-bran-distributions-inventory-allocation/ProvinceJahadBranDistributionsInventoryAllocation.js @@ -0,0 +1,325 @@ +import React, { useEffect, useState, useContext } from "react"; +import { useDispatch, useSelector } from "react-redux"; +import axios from "axios"; +import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl"; +import { + LOADING_END, + LOADING_START, + OPEN_MODAL, +} from "../../../../lib/redux/slices/appSlice"; +import { Grid } from "../../../../components/grid/Grid"; +import ResponsiveTable from "../../../../components/responsive-table/ResponsiveTable"; +import { formatTime } from "../../../../utils/formatTime"; +import { getFaUserRole } from "../../../../utils/getFaUserRole"; +import { AppContext } from "../../../../contexts/AppContext"; +import moment from "moment"; +import { DatePicker } from "@mui/x-date-pickers"; +import { Button, Checkbox, TextField, Tooltip } from "@mui/material"; +import { ProvinceJahadSubmitAllocation } from "../province-jahad-submit-allocation/ProvinceJahadSubmitAllocation"; +import { RiFileExcel2Fill, RiSearchLine } from "react-icons/ri"; +import { ProvinceJahadAllocationOperations } from "../province-jahad-allocation-operations/ProvinceJahadAllocationOperations"; +import ToggleOffOutlinedIcon from "@mui/icons-material/ToggleOffOutlined"; +import ToggleOnIcon from "@mui/icons-material/ToggleOn"; + +export const ProvinceJahadBranDistributionsInventoryAllocations = ({ + inventoryData, + getDashboardData, + maxAllow, + product, +}) => { + const [, , selectedDate1, setSelectedDate1, selectedDate2, setSelectedDate2] = + useContext(AppContext); + const userKey = useSelector((state) => state.userSlice.userProfile.key); + + const dispatch = useDispatch(); + useEffect(() => { + const currentDate = moment(new Date()).format("YYYY-MM-DD"); + setSelectedDate1(currentDate); + setSelectedDate2(currentDate); + }, []); + + const [textValue, setTextValue] = useState(""); + + const [withDate, setWithDate] = useState(false); + const handleTextChange = (event) => { + setTextValue(event.target.value); + }; + + const [data, setData] = useState([]); + const [totalRows, setTotalRows] = useState(0); + const [perPage, setPerPage] = useState(10); + const [page, setPage] = useState(1); + const [tableData, setTableData] = useState([]); + + const fetchApiData = async (page) => { + let response; + dispatch(LOADING_START()); + response = await axios.get( + `LiveStock/jahad/live-stock-allocation/?search=filter&value=${textValue}&role=${getRoleFromUrl()}${ + withDate ? `&date1=${selectedDate1}&date2=${selectedDate2}` : `` + }&page=${page}&page_size=${perPage}&name=${product?.key}` + ); + dispatch(LOADING_END()); + setData(response.data.results); + setTotalRows(response.data.count); + }; + + const handlePageChange = (page) => { + fetchApiData(page); + setPage(page); + }; + + const handlePerRowsChange = (perRows) => { + setPerPage(perRows); + setPage(1); + }; + + // const getCooperativeState = (item) => { + // if (getRoleFromUrl() === "Cooperative") { + // return [item?.state === "accepted" ? "تایید شده" : "در انتظار تایید"]; + // } else { + // return []; + // } + // }; + // const getCooperativeStateLabel = () => { + // if (getRoleFromUrl() === "Cooperative") { + // return ["وضعیت"]; + // } else { + // return []; + // } + // }; + + useEffect(() => { + const d = data?.map((item, i) => { + const from = + item?.allocateFrom === "LiveStockProvinceJahad" + ? item?.jahad?.name + : item?.union?.name; + const fromRole = getFaUserRole(item?.allocateFrom); + const to = + item?.allocateTo === "Union" + ? item?.union?.name + : item?.cooperative?.name; + const toRole = getFaUserRole(item?.allocateTo); + return [ + page === 1 ? i + 1 : i + perPage * (page - 1) + 1, + item?.weight?.toLocaleString(), + // ...getCooperativeState(item), + `${fromRole} (${from})`, + `${toRole} (${to})`, + item?.allocateFrom === "LiveStockProvinceJahad" + ? item?.jahad?.user?.fullname + : item?.union?.user?.fullname, + formatTime(item?.date), + item?.place, + item?.description, + , + ]; + }); + + setTableData(d); + }, [data]); + + useEffect(() => { + fetchApiData(1); + }, [dispatch, selectedDate1, selectedDate2, perPage, withDate]); + + const handleSubmit = async (event) => { + event.preventDefault(); + dispatch(LOADING_START()); + + try { + const response = await axios.get( + `LiveStock/jahad/live-stock-allocation/?role=${getRoleFromUrl()}&search=filter&value=${textValue}${ + withDate ? `&date1=${selectedDate1}&date2=${selectedDate2}` : `` + }&page=${1}&page_size=${perPage}&name=${product?.key}` + ); + setData(response.data.results); + setTotalRows(response.data.count); + dispatch(LOADING_END()); + } catch (error) { + console.error("Error fetching data:", error); + } + }; + + const updateTable = () => { + fetchApiData(page !== 0 ? page : 1); + }; + + const getColumns = () => { + if ( + getRoleFromUrl() === "LiveStockProvinceJahad" || + getRoleFromUrl() === "Union" + ) { + return [ + "ردیف", + "وزن (کیلوگرم)", + "مبدا", + "مقصد", + "ثبت کننده", + "تاریخ ثبت", + "مکان دریافت", + "توضیحات", + "عملیات", + ]; + } else { + return [ + "ردیف", + "وزن (کیلوگرم)", + // ...getCooperativeStateLabel(), + "مبدا", + "مقصد", + "ثبت کننده", + "تاریخ ثبت", + "مکان دریافت", + "توضیحات", + ]; + } + }; + + return ( + + + {(getRoleFromUrl() === "LiveStockProvinceJahad" || + getRoleFromUrl() === "Union") && ( + + )} + + + } + checkedIcon={} + checked={withDate} + onChange={() => setWithDate(!withDate)} + color="primary" + size="large" + /> + + ( + + )} + value={selectedDate1} + onChange={(e) => { + setSelectedDate1(moment(e).format("YYYY-MM-DD")); + }} + /> + + + ( + + )} + value={selectedDate2} + onChange={(e) => { + setSelectedDate2(moment(e).format("YYYY-MM-DD")); + }} + /> + + + +
    + + + +
    + + + + + +
    + + +
    + ); +}; diff --git a/src/features/province-jahad/components/province-jahad-bran-distributions-policy/ProvinceJahadBranDistributionsPolicy.js b/src/features/province-jahad/components/province-jahad-bran-distributions-policy/ProvinceJahadBranDistributionsPolicy.js new file mode 100644 index 0000000..3a093c7 --- /dev/null +++ b/src/features/province-jahad/components/province-jahad-bran-distributions-policy/ProvinceJahadBranDistributionsPolicy.js @@ -0,0 +1,324 @@ +import React, { useContext, useEffect, useState } from "react"; +import { + Button, + FormControlLabel, + IconButton, + Switch, + TextField, + Tooltip, +} from "@mui/material"; +import axios from "axios"; +import { RiSearchLine } from "react-icons/ri"; +import { + DRAWER, + LOADING_END, + LOADING_START, +} from "../../../../lib/redux/slices/appSlice"; +import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl"; +import { Grid } from "../../../../components/grid/Grid"; +import ResponsiveTable from "../../../../components/responsive-table/ResponsiveTable"; +import { useDispatch } from "react-redux"; +import { provinceJahadEditRancher } from "../../services/province-jahad-rancher-activation"; +import { AppContext } from "../../../../contexts/AppContext"; +import { provinceJahadGetProductInfoService } from "../../services/province-jahad-get-product-info"; +import { ProvinceJahadEditProduct } from "../province-jahad-edit-product/ProvinceJahadEditProduct"; +import RemoveRedEyeIcon from "@mui/icons-material/RemoveRedEye"; +export const ProvinceJahadBranDistributionsPolicy = ({ product }) => { + const dispatch = useDispatch(); + const handleTextChange = (event) => { + setTextValue(event.target.value); + }; + const [dashboardData, setDashboardData] = useState([]); + + const getDashboardData = () => { + dispatch( + provinceJahadGetProductInfoService({ product: product?.key }) + ).then((r) => { + setDashboardData(r.payload.data); + }); + }; + + useEffect(() => { + if (getRoleFromUrl() === "LiveStockProvinceJahad") { + getDashboardData(); + } + }, []); + + const [openNotif] = useContext(AppContext); + + const [data, setData] = useState([]); + const [totalRows, setTotalRows] = useState(0); + const [perPage, setPerPage] = useState(10); + const [textValue, setTextValue] = useState(""); + const [page, setPage] = useState(1); + const [tableData, setTableData] = useState([]); + + const fetchApiData = async (page) => { + let response; + dispatch(LOADING_START()); + response = await axios.get( + `/LiveStock/rancher/rancher-view/?search=filter&value=${textValue}&role=${getRoleFromUrl()}&page=${page}&page_size=${perPage}&name=${ + product?.key + }` + ); + + dispatch(LOADING_END()); + setData(response.data.results); + setTotalRows(response.data.count); + }; + + const handlePageChange = (page) => { + fetchApiData(page); + setPage(page); + }; + + const handlePerRowsChange = (perRows) => { + setPerPage(perRows); + setPage(1); + }; + + const updateTable = () => { + fetchApiData(page !== 0 ? page : 1); + }; + + useEffect(() => { + const d = data?.map((item, i) => { + return [ + page === 1 ? i + 1 : i + perPage * (page - 1) + 1, + item?.herdCode, + item?.epidemiologicalCode, + item?.postalCode, + item?.unitId, + item?.herdName, + item?.nationalId, + item?.user?.fullname.replace(":", " "), + item?.mobile, + item?.contractorCode || "-", + item?.city, + // item?.lightLivestock?.toLocaleString(), + // item?.heavyLivestock?.toLocaleString(), + // Math.round( + // item?.lightLivestock + item?.heavyLivestock + // )?.toLocaleString(), + // item?.weightQuotaLight?.toLocaleString(), + // item?.weightQuotaHeavy?.toLocaleString(), + // Math.round( + // item?.weightQuotaLight + item?.weightQuotaHeavy + // )?.toLocaleString(), + { + dispatch( + provinceJahadEditRancher({ + key: item?.key, + allow_buy: !item?.allowBuy, + }) + ).then((r) => { + if (r.payload.error) { + openNotif({ + vertical: "top", + horizontal: "center", + msg: r.payload.error, + severity: "error", + }); + } else { + updateTable(); + openNotif({ + vertical: "top", + horizontal: "center", + msg: "عملیات با موفقیت انجام شد.", + severity: "success", + }); + } + }); + }} + color="primary" + /> + } + label={item?.allowBuy ? "فعال" : "غیرفعال"} + style={{ + justifyContent: "center", + alignItems: "center", + display: "flex", + }} + />, + ]; + }); + + setTableData(d); + }, [data]); + + useEffect(() => { + fetchApiData(1); + }, [dispatch, perPage]); + + const handleSubmit = async (event) => { + event.preventDefault(); + dispatch(LOADING_START()); + + try { + const response = await axios.get( + `/LiveStock/rancher/rancher-view/?search=filter&value=${textValue}&role=${getRoleFromUrl()}&page=${page}&page_size=${perPage}&name=${ + product?.key + }` + ); + setData(response.data.results); + setTotalRows(response.data.count); + dispatch(LOADING_END()); + } catch (error) { + console.error("Error fetching data:", error); + } + }; + + return ( + + {getRoleFromUrl() === "LiveStockProvinceJahad" && ( + + + { + dispatch( + DRAWER({ + title: "ویرایش محصول", + right: !(window.innerWidth <= 600), + bottom: window.innerWidth <= 600, + content: ( + + ), + }) + ); + }} + > + + + , + ], + ]} + title={`محدودیت های توزیع ${product?.label}`} + /> + + )} + + + +
    + + + +
    + {/* + + + + */} +
    + + +
    + ); +}; diff --git a/src/features/province-jahad/components/province-jahad-bran-distributions-union-allocation/ProvinceJahadBranDistributionsUnionAllocation.js b/src/features/province-jahad/components/province-jahad-bran-distributions-union-allocation/ProvinceJahadBranDistributionsUnionAllocation.js new file mode 100644 index 0000000..51f5dc4 --- /dev/null +++ b/src/features/province-jahad/components/province-jahad-bran-distributions-union-allocation/ProvinceJahadBranDistributionsUnionAllocation.js @@ -0,0 +1,311 @@ +import React, { useEffect, useState, useContext } from "react"; +import { useDispatch, useSelector } from "react-redux"; +import axios from "axios"; +import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl"; +import { + LOADING_END, + LOADING_START, + OPEN_MODAL, +} from "../../../../lib/redux/slices/appSlice"; +import { Grid } from "../../../../components/grid/Grid"; +import ResponsiveTable from "../../../../components/responsive-table/ResponsiveTable"; +import { formatTime } from "../../../../utils/formatTime"; +import { AppContext } from "../../../../contexts/AppContext"; +import moment from "moment"; +import { DatePicker } from "@mui/x-date-pickers"; +import { Button, Checkbox, TextField, Tooltip } from "@mui/material"; +import { ProvinceJahadSubmitAllocation } from "../province-jahad-submit-allocation/ProvinceJahadSubmitAllocation"; +import { RiFileExcel2Fill, RiSearchLine } from "react-icons/ri"; +import { ProvinceJahadAllocationOperations } from "../province-jahad-allocation-operations/ProvinceJahadAllocationOperations"; +import ToggleOffOutlinedIcon from "@mui/icons-material/ToggleOffOutlined"; +import ToggleOnIcon from "@mui/icons-material/ToggleOn"; + +export const ProvinceJahadBranDistributionsUnionAllocations = ({ + inventoryData, + getDashboardData, + product, + maxAllow, +}) => { + const [, , selectedDate1, setSelectedDate1, selectedDate2, setSelectedDate2] = + useContext(AppContext); + const userKey = useSelector((state) => state.userSlice.userProfile.key); + + const dispatch = useDispatch(); + useEffect(() => { + const currentDate = moment(new Date()).format("YYYY-MM-DD"); + setSelectedDate1(currentDate); + setSelectedDate2(currentDate); + }, []); + + const [textValue, setTextValue] = useState(""); + + const [withDate, setWithDate] = useState(false); + const handleTextChange = (event) => { + setTextValue(event.target.value); + }; + + const [data, setData] = useState([]); + const [totalRows, setTotalRows] = useState(0); + const [perPage, setPerPage] = useState(10); + const [page, setPage] = useState(1); + const [tableData, setTableData] = useState([]); + + const fetchApiData = async (page) => { + let response; + dispatch(LOADING_START()); + response = await axios.get( + `/LiveStock/jahad/live-stock-warehouse-charge-allocation/?search=filter&value=${textValue}&role=${getRoleFromUrl()}${ + withDate ? `&date1=${selectedDate1}&date2=${selectedDate2}` : `` + }&page=${page}&page_size=${perPage}&name=${product?.key}` + ); + dispatch(LOADING_END()); + setData(response.data.results); + setTotalRows(response.data.count); + }; + + const handlePageChange = (page) => { + fetchApiData(page); + setPage(page); + }; + + const handlePerRowsChange = (perRows) => { + setPerPage(perRows); + setPage(1); + }; + + const getRegisterarData = (item) => { + if (getRoleFromUrl() === "Cooperative") { + return { + key: [], + value: [], + }; + } else { + return { + key: "ثبت کننده", + value: [item?.jahad?.user?.fullname || item?.union?.user?.fullname], + }; + } + }; + + useEffect(() => { + const d = data?.map((item, i) => { + return [ + page === 1 ? i + 1 : i + perPage * (page - 1) + 1, + item?.weight?.toLocaleString(), + getRegisterarData(item)?.value, + formatTime(item?.date), + item?.place, + item?.description, + , + ]; + }); + + setTableData(d); + }, [data]); + + useEffect(() => { + fetchApiData(1); + }, [dispatch, selectedDate1, selectedDate2, perPage, withDate]); + + const handleSubmit = async (event) => { + event.preventDefault(); + dispatch(LOADING_START()); + + try { + const response = await axios.get( + `LiveStock/jahad/live-stock-warehouse-charge-allocation/?role=${getRoleFromUrl()}&search=filter&value=${textValue}${ + withDate ? `&date1=${selectedDate1}&date2=${selectedDate2}` : `` + }&page=${1}&page_size=${perPage}&name=${product?.key}` + ); + setData(response.data.results); + setTotalRows(response.data.count); + dispatch(LOADING_END()); + } catch (error) { + console.error("Error fetching data:", error); + } + }; + + const updateTable = () => { + fetchApiData(page !== 0 ? page : 1); + }; + + const columns = [ + "ردیف", + "وزن (کیلوگرم)", + getRegisterarData()?.key, + "تاریخ ثبت", + "مبدا", + "توضیحات", + "عملیات", + ]; + return ( + + + {getRoleFromUrl() === "LiveStockProvinceJahad" && ( + + )} + + {getRoleFromUrl() === "Cooperative" && ( + + )} + + } + checkedIcon={} + checked={withDate} + onChange={() => setWithDate(!withDate)} + color="primary" + size="large" + /> + + ( + + )} + value={selectedDate1} + onChange={(e) => { + setSelectedDate1(moment(e).format("YYYY-MM-DD")); + }} + /> + + + ( + + )} + value={selectedDate2} + onChange={(e) => { + setSelectedDate2(moment(e).format("YYYY-MM-DD")); + }} + /> + + + +
    + + + +
    + + + + + +
    + +
    + ); +}; diff --git a/src/features/province-jahad/components/province-jahad-bran-distributions/ProvinceJahadBranDistributions.js b/src/features/province-jahad/components/province-jahad-bran-distributions/ProvinceJahadBranDistributions.js new file mode 100644 index 0000000..f3ae485 --- /dev/null +++ b/src/features/province-jahad/components/province-jahad-bran-distributions/ProvinceJahadBranDistributions.js @@ -0,0 +1,132 @@ +import React from "react"; +import { Grid } from "../../../../components/grid/Grid"; +import { SPACING } from "../../../../data/spacing"; +import { NavLink } from "../../../../components/nav-link/NavLink"; +import LinkItem from "../../../../components/link-item/LinkItem"; +import { + VscAdd, + VscOutput, + VscSymbolProperty, + VscTable, +} from "react-icons/vsc"; +import { + ROUTE_COOPERATIVE_PRODUCT_DISTRIBUTION_ALLOCATION, + ROUTE_COOPERATIVE_PRODUCT_DISTRIBUTION_POLICY, + ROUTE_PROVINCE_JAHAD_PRODUCT_DISTRIBUTION, + ROUTE_PROVINCE_JAHAD_PRODUCT_DISTRIBUTION_ALLOCATION, + ROUTE_PROVINCE_JAHAD_PRODUCT_DISTRIBUTION_POLICY, + ROUTE_PROVINCE_JAHAD_PRODUCT_SHARES, + ROUTE_PROVINCE_JAHAD_SELL_REPORT, + ROUTE_UNION_PRODUCT_DISTRIBUTION, + ROUTE_UNION_PRODUCT_DISTRIBUTION_ALLOCATION, + ROUTE_UNION_PRODUCT_DISTRIBUTION_POLICY, + ROUTE_UNION_SELL_REPORT, +} from "../../../../routes/routes"; +import { useLocation } from "react-router-dom"; +import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl"; + +export const ProvinceJahadBranDistributions = ({ product }) => { + const { pathname } = useLocation(); + + const getProductColor = + product?.key === "bran" + ? "rgba(224, 224, 224, 0.5)" + : product?.key === "barley" + ? "rgba(245, 194, 149, 0.5)" + : product?.key === "soy" + ? "rgba(164, 239, 204, 0.5)" + : product?.key === "corn" + ? "rgba(193, 239, 164, 0.5)" + : "rgba(132, 243, 233, 0.5)"; + + return ( + + + + + } + title={`انبار و تخصیص ${product?.label}`} + description={`انبار و تخصیص ${product?.label}`} + /> + + + {(getRoleFromUrl() === "LiveStockProvinceJahad" || + getRoleFromUrl() === "Union") && ( + + } + title={`مدیریت توزیع ${product?.label}`} + description={`مدیریت توزیع ${product?.label}`} + /> + + )} + + {(getRoleFromUrl() === "LiveStockProvinceJahad" || + getRoleFromUrl() === "Union") && ( + + } + title={`گزارش فروش ${product?.label}`} + description={`گزارش فروش ${product?.label}`} + /> + + )} + + {getRoleFromUrl() === "LiveStockProvinceJahad" && ( + + } + title={`سهم بندی ${product?.label}`} + description={`سهم بندی ${product?.label}`} + /> + + )} + + + + ); +}; diff --git a/src/features/province-jahad/components/province-jahad-cooperatives-modal/ProvinceJahadCooperativesModal.js b/src/features/province-jahad/components/province-jahad-cooperatives-modal/ProvinceJahadCooperativesModal.js new file mode 100644 index 0000000..2ec5e6f --- /dev/null +++ b/src/features/province-jahad/components/province-jahad-cooperatives-modal/ProvinceJahadCooperativesModal.js @@ -0,0 +1,29 @@ +import React, { useEffect, useState } from "react"; +import { Grid } from "../../../../components/grid/Grid"; +import { SimpleTable } from "../../../../components/simple-table/SimpleTable"; +import { provinceJahadGetCooperativesPosInfoService } from "../../services/province-jahad-get-cooperatives-pos"; +import { useDispatch } from "react-redux"; + +export const ProvinceJahadCooperativesModal = ({ item }) => { + const dispatch = useDispatch(); + const [tableData, setTableData] = useState([]); + + useEffect(() => { + dispatch(provinceJahadGetCooperativesPosInfoService(item.key)).then((r) => { + const d = r.payload.data?.map((item, i) => { + return [i + 1, item?.companyName, item?.posId]; + }); + + setTableData(d); + }); + }, []); + + return ( + + + + ); +}; diff --git a/src/features/province-jahad/components/province-jahad-cooperatives-operations/ProvinceJahadCooperativesOperations.js b/src/features/province-jahad/components/province-jahad-cooperatives-operations/ProvinceJahadCooperativesOperations.js new file mode 100644 index 0000000..5fc2479 --- /dev/null +++ b/src/features/province-jahad/components/province-jahad-cooperatives-operations/ProvinceJahadCooperativesOperations.js @@ -0,0 +1,141 @@ +import { + FormControlLabel, + IconButton, + Popover, + Switch, + Tooltip, +} from "@mui/material"; +import { useContext, useState } from "react"; +// import DeleteIcon from "@mui/icons-material/Delete"; +import TuneIcon from "@mui/icons-material/Tune"; +import EditIcon from "@mui/icons-material/Edit"; +import { Grid } from "../../../../components/grid/Grid"; +import { useDispatch } from "react-redux"; +import { DRAWER } from "../../../../lib/redux/slices/appSlice"; +import { ProvinceJahadEditCooperative } from "../province-jahad-edit-cooperative/ProvinceJahadEditCooperative"; +import { AppContext } from "../../../../contexts/AppContext"; +import { provinceJahadEditCooperativeService } from "../../services/province-jahad-submit-cooperatives"; + +export const ProvinceJahadCooperativesOperations = ({ + item, + // fileUrl, + updateTable, + getDashboardData, +}) => { + const [anchorEl, setAnchorEl] = useState(null); + const dispatch = useDispatch(); + const handleClick = (event) => { + setAnchorEl(event.currentTarget); + }; + const [openNotif] = useContext(AppContext); + const handleClose = () => { + setAnchorEl(null); + }; + + const open = Boolean(anchorEl); + const id = open ? "popover" : undefined; + + return ( + + + + + +
    + + { + handleClose(); + dispatch( + DRAWER({ + title: "ویرایش اطلاعات ", + right: !(window.innerWidth <= 600), + bottom: window.innerWidth <= 600, + content: ( + + ), + }) + ); + }} + > + + + + + { + dispatch( + provinceJahadEditCooperativeService({ + cooperative_key: item?.key, + active: !item?.active, + }) + ).then((r) => { + if (r.payload.error) { + openNotif({ + vertical: "top", + horizontal: "center", + msg: r.payload.error, + severity: "error", + }); + } else { + updateTable(); + openNotif({ + vertical: "top", + horizontal: "center", + msg: "عملیات با موفقیت انجام شد.", + severity: "success", + }); + } + }); + }} + color="primary" + /> + } + label={item?.active ? "فعال" : "غیرفعال"} + style={{ + justifyContent: "center", + alignItems: "center", + display: "flex", + }} + /> + + {/* + + + + */} +
    +
    +
    + ); +}; diff --git a/src/features/province-jahad/components/province-jahad-cooperatives/ProvinceJahadCooperatives.js b/src/features/province-jahad/components/province-jahad-cooperatives/ProvinceJahadCooperatives.js new file mode 100644 index 0000000..399f05f --- /dev/null +++ b/src/features/province-jahad/components/province-jahad-cooperatives/ProvinceJahadCooperatives.js @@ -0,0 +1,205 @@ +import React, { useEffect, useState } from "react"; +import { Button, IconButton, TextField, Tooltip } from "@mui/material"; +import axios from "axios"; +import { RiFileExcel2Fill, RiSearchLine } from "react-icons/ri"; +import { + DRAWER, + LOADING_END, + LOADING_START, + OPEN_MODAL, +} from "../../../../lib/redux/slices/appSlice"; +import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl"; +import { Grid } from "../../../../components/grid/Grid"; +import ResponsiveTable from "../../../../components/responsive-table/ResponsiveTable"; +import { useDispatch, useSelector } from "react-redux"; +import { ProvinceJahadCooperativesOperations } from "../province-jahad-cooperatives-operations/ProvinceJahadCooperativesOperations"; +import { ProvinceJahadEditCooperative } from "../province-jahad-edit-cooperative/ProvinceJahadEditCooperative"; +import TabletAndroidIcon from "@mui/icons-material/TabletAndroid"; +import { ProvinceJahadCooperativesModal } from "../province-jahad-cooperatives-modal/ProvinceJahadCooperativesModal"; + +export const ProvinceJahadCooperatives = () => { + const dispatch = useDispatch(); + const handleTextChange = (event) => { + setTextValue(event.target.value); + }; + + const userKey = useSelector((state) => state.userSlice.userProfile.key); + + const [data, setData] = useState([]); + const [totalRows, setTotalRows] = useState(0); + const [perPage, setPerPage] = useState(10); + const [textValue, setTextValue] = useState(""); + const [page, setPage] = useState(1); + const [tableData, setTableData] = useState([]); + + const fetchApiData = async (page) => { + let response; + dispatch(LOADING_START()); + response = await axios.get( + `/LiveStock/cooperative/cooperative-views/?search=filter&value=${textValue}&role=${getRoleFromUrl()}&page=${page}&page_size=${perPage}` + ); + + dispatch(LOADING_END()); + setData(response.data.results); + setTotalRows(response.data.count); + }; + + const handlePageChange = (page) => { + fetchApiData(page); + setPage(page); + }; + + const handlePerRowsChange = (perRows) => { + setPerPage(perRows); + setPage(1); + }; + + const updateTable = () => { + fetchApiData(page !== 0 ? page : 1); + }; + + useEffect(() => { + const d = data?.map((item, i) => { + return [ + page === 1 ? i + 1 : i + perPage * (page - 1) + 1, + item?.name, + item?.user.fullname, + item?.address?.province?.name, + item?.address?.city?.name, + item?.user.mobile, + item?.nationalId, + item?.account || "-", + item?.user?.password || "-", + + { + dispatch( + OPEN_MODAL({ + title: `لیست دستگاه‌های POS تعاونی ${item?.name}`, + content: , + }) + ); + }} + > + + + , + , + ]; + }); + + setTableData(d); + }, [data]); + + useEffect(() => { + fetchApiData(1); + }, [dispatch, perPage]); + + const handleSubmit = async (event) => { + event.preventDefault(); + dispatch(LOADING_START()); + + try { + const response = await axios.get( + `/LiveStock/cooperative/cooperative-views/?search=filter&value=${textValue}&role=${getRoleFromUrl()}&page=${page}&page_size=${perPage}` + ); + setData(response.data.results); + setTotalRows(response.data.count); + dispatch(LOADING_END()); + } catch (error) { + console.error("Error fetching data:", error); + } + }; + + return ( + + + + +
    + + + +
    + + + + + +
    + + +
    + ); +}; diff --git a/src/features/province-jahad/components/province-jahad-edit-cooperative/ProvinceJahadEditCooperative.js b/src/features/province-jahad/components/province-jahad-edit-cooperative/ProvinceJahadEditCooperative.js new file mode 100644 index 0000000..790bd3e --- /dev/null +++ b/src/features/province-jahad/components/province-jahad-edit-cooperative/ProvinceJahadEditCooperative.js @@ -0,0 +1,325 @@ +import React, { useContext, useEffect, useState } from "react"; +import { useFormik } from "formik"; +import * as Yup from "yup"; +import { + Grid, + TextField, + Button, + Autocomplete, + Typography, +} from "@mui/material"; +import { SPACING } from "../../../../data/spacing"; +import { AppContext } from "../../../../contexts/AppContext"; +import { useDispatch } from "react-redux"; +import { + DRAWER, + LOADING_END, + LOADING_START, +} from "../../../../lib/redux/slices/appSlice"; +import { + provinceJahadEditCooperativeService, + provinceJahadSubmitCooperativeService, +} from "../../services/province-jahad-submit-cooperatives"; +import { cityGetProvinces } from "../../../city/services/CityGetProvinces"; +import { cityGetCity } from "../../../city/services/city-get-city"; + +export const ProvinceJahadEditCooperative = ({ + updateTable, + item, + getDashboardData, +}) => { + const [provinceData, setProvinceData] = useState([]); + const [cityData, setCityData] = useState([]); + const [provinceKey, setProvinceKey] = useState(); + const [cityKey, setCityKey] = useState(); + const [isExistProvince, setIsExistProvince] = useState(true); + const [openNotif] = useContext(AppContext); + + const dispatch = useDispatch(); + + const validationSchema = Yup.object().shape({ + name: Yup.string().required("این فیلد الزامی است"), + first_name: Yup.string().required("این فیلد الزامی است"), + last_name: Yup.string().required("این فیلد الزامی است"), + address: Yup.string().required("این فیلد الزامی است"), + nationalId: Yup.string() + .matches(/^\d+$/, "لطفا فقط عدد وارد کنید") + .length(10, "کد ملی باید ۱۰ رقم باشد") + .required("این فیلد الزامی است"), + postalCode: Yup.string() + .matches(/^\d+$/, "لطفا فقط عدد وارد کنید") + .length(10, "کد پستی باید ۱۰ رقم باشد") + .required("این فیلد الزامی است"), + mobile: Yup.string() + .matches(/^\d+$/, "لطفا فقط عدد وارد کنید") + .length(11, "شماره موبایل باید ۱۱ رقم باشد") + .required("این فیلد الزامی است"), + account: Yup.number() + .required("این فیلد اجباری است!") + .typeError("صرفا اعداد شماره شبا را وارد کنید!"), + }); + + useEffect(() => { + dispatch(LOADING_START()); + dispatch(cityGetProvinces())?.then((r) => { + dispatch(LOADING_END()); + setProvinceData(r.payload.data); + }); + }, []); + + useEffect(() => { + dispatch(LOADING_END()); + if (provinceKey) { + dispatch(LOADING_START()); + dispatch(cityGetCity(provinceKey)).then((r) => { + setCityData(r.payload.data); + setIsExistProvince(false); + dispatch(LOADING_END()); + }); + } + }, [provinceKey]); + + const formik = useFormik({ + initialValues: { + name: item?.name || "", + first_name: item?.user?.firstName || "", + last_name: item?.user?.lastName || "", + mobile: item?.user?.mobile || "", + address: item?.address?.address || "", + nationalId: item?.nationalId || "", + postalCode: item?.address?.postalCode || "", + account: item?.account?.replace(/ir/gi, "") ?? "", + }, + validationSchema, + enableReinitialize: true, + onSubmit: (values) => { + if (item) { + dispatch( + provinceJahadEditCooperativeService({ + cooperative_key: item?.key, + first_name: values.first_name, + last_name: values.last_name, + name: values.name, + address: values.address, + mobile: values.mobile, + account: "IR" + values.account, + national_id: values.nationalId, + postal_code: values.postalCode, + city: cityKey || item?.address?.city?.name, + }) + ).then((r) => { + if (r.payload.error) { + openNotif({ + vertical: "top", + horizontal: "center", + msg: r.payload.error, + severity: "error", + }); + } else { + openNotif({ + vertical: "top", + horizontal: "center", + msg: "عملیات با موفقیت انجام شد.", + severity: "success", + }); + dispatch(DRAWER({ right: false, bottom: false, content: null })); + + updateTable(); + getDashboardData(); + } + }); + } else { + dispatch( + provinceJahadSubmitCooperativeService({ + first_name: values.first_name, + last_name: values.last_name, + name: values.name, + mobile: values.mobile, + address: values.address, + national_id: values.nationalId, + postal_code: values.postalCode, + account: "IR" + values.account, + city: cityKey, + }) + ).then((r) => { + if (r.payload.error) { + openNotif({ + vertical: "top", + horizontal: "center", + msg: r.payload.error, + severity: "error", + }); + } else { + openNotif({ + vertical: "top", + horizontal: "center", + msg: "عملیات با موفقیت انجام شد.", + severity: "success", + }); + dispatch(DRAWER({ right: false, bottom: false, content: null })); + + updateTable(); + getDashboardData(); + } + }); + } + }, + }); + + const isFormValid = () => { + if (item) { + return formik.isValid; + } else { + return formik.isValid && cityKey; + } + }; + + return ( + +
    + + + + ({ + id: i.key, + label: i.name, + }))} + onChange={(e, value) => { + setProvinceKey(value.id); + }} + renderInput={(params) => ( + + )} + /> + + ({ + id: i.key, + label: i.name, + }))} + onChange={(e, value) => { + setCityKey(value.label); + }} + renderInput={(params) => ( + + )} + /> + {item && !cityKey && ( + + شهر: {item?.address?.city?.name} + + )} + + + + + + + + + + + + + + + + +
    +
    + ); +}; diff --git a/src/features/province-jahad/components/province-jahad-edit-product/ProvinceJahadEditProduct.js b/src/features/province-jahad/components/province-jahad-edit-product/ProvinceJahadEditProduct.js new file mode 100644 index 0000000..82c3a3a --- /dev/null +++ b/src/features/province-jahad/components/province-jahad-edit-product/ProvinceJahadEditProduct.js @@ -0,0 +1,310 @@ +import React, { useContext, useEffect } from "react"; +import { Button, TextField } from "@mui/material"; +import { useFormik } from "formik"; +import * as Yup from "yup"; +import { Grid } from "../../../../components/grid/Grid"; +import { useDispatch } from "react-redux"; +import { AppContext } from "../../../../contexts/AppContext"; +import { provinceJahadUpdateProductService } from "../../services/province-jahad-update-product"; +import { DRAWER } from "../../../../lib/redux/slices/appSlice"; +import { NumberInput } from "../../../../components/number-format-custom/NumberFormatCustom"; + +export const ProvinceJahadEditProduct = ({ item, updateTable }) => { + const dispatch = useDispatch(); + + const [openNotif] = useContext(AppContext); + const validationSchema = Yup.object({ + light_weight: Yup.number().required("این فیلد اجباری است!"), + heavy_weight: Yup.number().required("این فیلد اجباری است!"), + light_wight_industrial: Yup.number().required("این فیلد اجباری است!"), + heavy_wight_industrial: Yup.number().required("این فیلد اجباری است!"), + light_wight_dha: Yup.number().required("این فیلد اجباری است!"), + heavy_wight_dha: Yup.number().required("این فیلد اجباری است!"), + price: Yup.number() + .required("این فیلد اجباری است!") + .positive("عدد مثبت وارد کنید!"), + unionPrice: Yup.number() + .required("این فیلد اجباری است!") + .positive("عدد مثبت وارد کنید!"), + cooperativePrice: Yup.number() + .required("این فیلد اجباری است!") + .positive("عدد مثبت وارد کنید!"), + shippingPrice: Yup.number() + .required("این فیلد اجباری است!") + .positive("عدد مثبت وارد کنید!"), + }); + + const formik = useFormik({ + initialValues: { + light_weight: item.lightWight || 0, + heavy_weight: item.heavyWight || 0, + light_wight_industrial: item.lightWightIndustrial || 0, + heavy_wight_industrial: item.heavyWightIndustrial || 0, + light_wight_dha: item.lightWightDha || 0, + heavy_wight_dha: item.heavyWightDha || 0, + price: item.price || 0, + unionPrice: item.unionPrice || 0, + cooperativePrice: item.cooperativePrice || 0, + shippingPrice: item.shippingPrice || 0, + }, + validationSchema: validationSchema, + onSubmit: (values) => { + dispatch( + provinceJahadUpdateProductService({ + key: item?.key, + light_wight: values.light_weight, + heavy_wight: values.heavy_weight, + light_wight_industrial: values.light_wight_industrial, + heavy_wight_industrial: values.heavy_wight_industrial, + light_wight_dha: values.light_wight_dha, + heavy_wight_dha: values.heavy_wight_dha, + price: values.price, + union_price: values.unionPrice, + cooperative_price: values.cooperativePrice, + shipping_price: values.shippingPrice, + }) + ).then((r) => { + if (r.payload.error) { + openNotif({ + vertical: "top", + horizontal: "center", + msg: r.payload.error, + severity: "error", + }); + } else { + updateTable(); + openNotif({ + vertical: "top", + horizontal: "center", + msg: "عملیات با موفقیت انجام شد.", + severity: "success", + }); + dispatch(DRAWER({ right: false, bottom: false, content: null })); + } + }); + }, + }); + + useEffect(() => { + formik.validateForm(); + }, [dispatch]); + + return ( + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ); +}; diff --git a/src/features/province-jahad/components/province-jahad-edit-rancher/ProvinceJahadEditRancher.js b/src/features/province-jahad/components/province-jahad-edit-rancher/ProvinceJahadEditRancher.js new file mode 100644 index 0000000..a60e54d --- /dev/null +++ b/src/features/province-jahad/components/province-jahad-edit-rancher/ProvinceJahadEditRancher.js @@ -0,0 +1,359 @@ +import React, { useContext, useEffect, useState } from "react"; +import { + Grid, + TextField, + Button, + Autocomplete, + Typography, +} from "@mui/material"; +import { useFormik } from "formik"; +import * as Yup from "yup"; +import { AppContext } from "../../../../contexts/AppContext"; +import { + DRAWER, + LOADING_END, + LOADING_START, +} from "../../../../lib/redux/slices/appSlice"; +import { cityGetProvinces } from "../../../city/services/CityGetProvinces"; +import { cityGetCity } from "../../../city/services/city-get-city"; +import { useDispatch } from "react-redux"; +import { + provinceJahadEditRancher, + provinceJahadSubmitRancher, +} from "../../services/province-jahad-rancher-activation"; +import { SPACING } from "../../../../data/spacing"; + +const validationSchema = Yup.object({ + mobile: Yup.string() + .required("این فیلد اجباری است!") + .min(11, "شماره موبایل باید 11 رقم باشد") + .max(11, "شماره موبایل باید 11 رقم باشد") + .matches(/^09\d{9}$/, "شماره موبایل باید با 09 شروع شود و 11 رقم باشد"), + first_name: Yup.string().required("این فیلد اجباریست!"), + last_name: Yup.string().required("این فیلد اجباریست!"), + national_id: Yup.string() + .required("این فیلد اجباریست!") + .matches(/^\d{10}$/, "کد ملی باید 10 رقم باشد!"), + postal_code: Yup.string().required("این فیلد اجباریست!"), + name: Yup.string().required("این فیلد اجباریست!"), + epidemiological_code: Yup.string().required("این فیلد اجباریست!"), + herd_code: Yup.string().required("این فیلد اجباریست!"), + herd_name: Yup.string().required("این فیلد اجباریست!"), +}); + +export const ProvinceJahadEditRancher = ({ item, updateTable }) => { + const [provinceData, setProvinceData] = useState([]); + const [cityData, setCityData] = useState([]); + const [provinceKey, setProvinceKey] = useState(); + const [cityKey, setCityKey] = useState(); + const [isExistProvince, setIsExistProvince] = useState(true); + const [openNotif] = useContext(AppContext); + + const dispatch = useDispatch(); + + const formik = useFormik({ + initialValues: { + mobile: item?.mobile || "", + first_name: item?.user?.firstName || "", + last_name: item?.user?.lastName || "", + national_id: item?.nationalId || "", + postal_code: item?.postalCode || "", + name: item?.name || "", + epidemiological_code: item?.epidemiologicalCode || "", + herd_code: item?.herdCode || "", + herd_name: item?.herdName || "", + }, + validationSchema: validationSchema, + onSubmit: (values) => { + if (item) { + dispatch( + provinceJahadEditRancher({ + key: item?.key, + city: cityKey || item?.city, + mobile: values.mobile, + first_name: values.first_name, + last_name: values.last_name, + national_id: values.national_id, + postal_code: values.postal_code, + name: values.name, + epidemiological_code: values.epidemiological_code, + herd_code: values.herd_code, + herd_name: values.herd_name, + }) + ).then((r) => { + if (r.payload.error) { + openNotif({ + vertical: "top", + horizontal: "center", + msg: r.payload.error, + severity: "error", + }); + } else { + openNotif({ + vertical: "top", + horizontal: "center", + msg: "عملیات با موفقیت انجام شد.", + severity: "success", + }); + dispatch(DRAWER({ right: false, bottom: false, content: null })); + + updateTable(); + } + }); + } else { + dispatch( + provinceJahadSubmitRancher({ + city: cityKey, + mobile: values.mobile, + first_name: values.first_name, + last_name: values.last_name, + national_id: values.national_id, + postal_code: values.postal_code, + name: values.name, + epidemiological_code: values.epidemiological_code, + herd_code: values.herd_code, + herd_name: values.herd_name, + }) + ).then((r) => { + if (r.payload.error) { + openNotif({ + vertical: "top", + horizontal: "center", + msg: r.payload.error, + severity: "error", + }); + } else { + openNotif({ + vertical: "top", + horizontal: "center", + msg: "عملیات با موفقیت انجام شد.", + severity: "success", + }); + dispatch(DRAWER({ right: false, bottom: false, content: null })); + + updateTable(); + } + }); + } + }, + }); + + const isFormValid = () => { + if (item) { + return formik.isValid; + } else { + return formik.isValid && cityKey; + } + }; + + useEffect(() => { + dispatch(LOADING_START()); + dispatch(cityGetProvinces())?.then((r) => { + dispatch(LOADING_END()); + setProvinceData(r.payload.data); + }); + }, []); + + useEffect(() => { + dispatch(LOADING_END()); + if (provinceKey) { + dispatch(LOADING_START()); + dispatch(cityGetCity(provinceKey)).then((r) => { + setCityData(r.payload.data); + setIsExistProvince(false); + dispatch(LOADING_END()); + }); + } + }, [provinceKey]); + + return ( + + + + + + + + + + + + + + + + + + + + + + ({ + id: i.key, + label: i.name, + }))} + onChange={(e, value) => { + setProvinceKey(value.id); + }} + renderInput={(params) => ( + + )} + /> + + ({ + id: i.key, + label: i.name, + }))} + onChange={(e, value) => { + setCityKey(value.label); + }} + renderInput={(params) => ( + + )} + /> + {item && !cityKey && ( + + شهر: {item?.city} + + )} + + + + + + + + + + + + + + + + + + + + + + ); +}; diff --git a/src/features/province-jahad/components/province-jahad-edit-share/ProvinceJahadEditShare.js b/src/features/province-jahad/components/province-jahad-edit-share/ProvinceJahadEditShare.js new file mode 100644 index 0000000..b73edce --- /dev/null +++ b/src/features/province-jahad/components/province-jahad-edit-share/ProvinceJahadEditShare.js @@ -0,0 +1,148 @@ +import React, { useContext } from "react"; +import { useFormik } from "formik"; +import * as Yup from "yup"; +import { Grid, TextField, Button } from "@mui/material"; +import { SPACING } from "../../../../data/spacing"; +import { AppContext } from "../../../../contexts/AppContext"; +import { useDispatch } from "react-redux"; +import { DRAWER } from "../../../../lib/redux/slices/appSlice"; +import { provinceJahadSubmitShareService } from "../../services/province-jahad-submit-share"; + +export const ProvinceJahadEditShare = ({ updateTable, item }) => { + const [openNotif] = useContext(AppContext); + const dispatch = useDispatch(); + const validationSchema = Yup.object().shape({ + price: Yup.string().required("این فیلد الزامی است"), + shipping_price: Yup.string().required("این فیلد الزامی است"), + union_price: Yup.string().required("این فیلد الزامی است"), + cooperative_price: Yup.string().required("این فیلد الزامی است"), + company_price: Yup.string().required("این فیلد الزامی است"), + }); + + const formik = useFormik({ + initialValues: { + price: item?.price || "", + shipping_price: item?.shippingPrice || "", + union_price: item?.unionPrice || "", + company_price: item?.companyPrice || "", + cooperative_price: item?.cooperativePrice || "", + }, + validationSchema, + enableReinitialize: true, + onSubmit: (values) => { + dispatch( + provinceJahadSubmitShareService({ + share_key: item?.key, + shipping_price: values.shipping_price, + union_price: values.union_price, + company_price: values.company_price, + price: values.price, + cooperative_price: values.cooperative_price, + }) + ).then((r) => { + if (r.payload.error) { + openNotif({ + vertical: "top", + horizontal: "center", + msg: r.payload.error, + severity: "error", + }); + } else { + openNotif({ + vertical: "top", + horizontal: "center", + msg: "عملیات با موفقیت انجام شد.", + severity: "success", + }); + dispatch(DRAWER({ right: false, bottom: false, content: null })); + + updateTable(); + } + }); + }, + }); + + return ( + +
    + + + + + + + + + + + + +
    +
    + ); +}; diff --git a/src/features/province-jahad/components/province-jahad-herds-operations/ProvinceJahadHerdsOperations.js b/src/features/province-jahad/components/province-jahad-herds-operations/ProvinceJahadHerdsOperations.js new file mode 100644 index 0000000..62a7595 --- /dev/null +++ b/src/features/province-jahad/components/province-jahad-herds-operations/ProvinceJahadHerdsOperations.js @@ -0,0 +1,276 @@ +import { + FormControlLabel, + IconButton, + Popover, + Switch, + Tooltip, + Button, + Typography, +} from "@mui/material"; +import { useContext, useState } from "react"; +import TuneIcon from "@mui/icons-material/Tune"; +import EditIcon from "@mui/icons-material/Edit"; +import { Grid } from "../../../../components/grid/Grid"; +import { useDispatch } from "react-redux"; +import { + DRAWER, + OPEN_MODAL, + CLOSE_MODAL, +} from "../../../../lib/redux/slices/appSlice"; +import { ProvicneJahadSubmitHerd } from "../province-jahad-submit-herd/ProvicneJahadSubmitHerd"; +import { AppContext } from "../../../../contexts/AppContext"; +import UnarchiveIcon from "@mui/icons-material/Unarchive"; +import ArchiveIcon from "@mui/icons-material/Archive"; +import { + provinceJahadEditHerdService, + provinceJahadDeleteHerdService, +} from "../../services/province-jahad-submit-herd"; + +export const ProvinceJahadHerdsOperations = ({ + item, + // fileUrl, + updateTable, + getDashboardData, + dataType, +}) => { + const [anchorEl, setAnchorEl] = useState(null); + const dispatch = useDispatch(); + const [openNotif] = useContext(AppContext); + + const handleClick = (event) => { + setAnchorEl(event.currentTarget); + }; + const handleClose = () => { + setAnchorEl(null); + }; + + const open = Boolean(anchorEl); + const id = open ? "popover" : undefined; + + const handleArchive = () => { + dispatch( + provinceJahadDeleteHerdService({ + live_stock_key: item?.key, + }) + ).then((r) => { + if (r.payload.error) { + openNotif({ + vertical: "top", + horizontal: "center", + msg: r.payload.error, + severity: "error", + }); + } else { + updateTable(); + openNotif({ + vertical: "top", + horizontal: "center", + msg: "عملیات با موفقیت انجام شد.", + severity: "success", + }); + dispatch(CLOSE_MODAL()); + } + }); + handleClose(); + }; + + const handleUnarchive = () => { + dispatch( + provinceJahadEditHerdService({ + live_stock_key: item?.key, + return_from_archive: true, + }) + ).then((r) => { + if (r.payload.error) { + openNotif({ + vertical: "top", + horizontal: "center", + msg: r.payload.error, + severity: "error", + }); + } else { + updateTable(); + dispatch(CLOSE_MODAL()); + openNotif({ + vertical: "top", + horizontal: "center", + msg: "عملیات با موفقیت انجام شد.", + severity: "success", + }); + } + }); + handleClose(); + }; + + const showConfirmationModal = (action) => { + handleClose(); + dispatch( + OPEN_MODAL({ + title: "آیا مطمئن هستید؟", + content: ( + + + + {action === "archive" + ? "آیا می‌خواهید این گله را به بایگانی منتقل کنید؟" + : "آیا می‌خواهید این گله را از بایگانی خارج کنید؟"} + + + + + + + + + + ), + }) + ); + }; + + return ( + + + + + +
    + + { + handleClose(); + dispatch( + DRAWER({ + title: "ویرایش اطلاعات", + right: !(window.innerWidth <= 600), + bottom: window.innerWidth <= 600, + content: ( + + ), + }) + ); + }} + > + + + + + { + dispatch( + provinceJahadEditHerdService({ + live_stock_key: item?.key, + active: !item?.active, + }) + ).then((r) => { + if (r.payload.error) { + openNotif({ + vertical: "top", + horizontal: "center", + msg: r.payload.error, + severity: "error", + }); + } else { + updateTable(); + openNotif({ + vertical: "top", + horizontal: "center", + msg: "عملیات با موفقیت انجام شد.", + severity: "success", + }); + } + }); + }} + color="primary" + /> + } + label={item?.active ? "فعال" : "غیرفعال"} + style={{ + justifyContent: "center", + alignItems: "center", + display: "flex", + }} + /> + {dataType === "archive" ? ( + + showConfirmationModal("unarchive")} + style={{ marginTop: "10px" }} + > + + + + ) : ( + + showConfirmationModal("archive")} + style={{ marginTop: "10px" }} + > + + + + )} +
    +
    +
    + ); +}; diff --git a/src/features/province-jahad/components/province-jahad-herds/ProvinceJahadHerds.js b/src/features/province-jahad/components/province-jahad-herds/ProvinceJahadHerds.js new file mode 100644 index 0000000..06352b1 --- /dev/null +++ b/src/features/province-jahad/components/province-jahad-herds/ProvinceJahadHerds.js @@ -0,0 +1,277 @@ +import React, { useEffect, useState } from "react"; +import { Button, Tab, Tabs, TextField, Tooltip } from "@mui/material"; +import axios from "axios"; +import { RiFileExcel2Fill, RiSearchLine } from "react-icons/ri"; +import { + DRAWER, + LOADING_END, + LOADING_START, +} from "../../../../lib/redux/slices/appSlice"; +import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl"; +import { Grid } from "../../../../components/grid/Grid"; +import ResponsiveTable from "../../../../components/responsive-table/ResponsiveTable"; +import { useDispatch, useSelector } from "react-redux"; +import { provinceJahadGetHerdInfoDashboardService } from "../../services/province-jahad-get-herd-dashbored"; +import { ProvinceJahadHerdsOperations } from "../province-jahad-herds-operations/ProvinceJahadHerdsOperations"; +import { ProvicneJahadSubmitHerd } from "../province-jahad-submit-herd/ProvicneJahadSubmitHerd"; +import { convertDaysToYMD } from "../../../../utils/formatTime"; + +export const ProvinceJahadHerds = () => { + const dispatch = useDispatch(); + const userKey = useSelector((state) => state.userSlice.userProfile.key); + + const [data, setData] = useState([]); + const [totalRows, setTotalRows] = useState(0); + const [perPage, setPerPage] = useState(10); + const [textValue, setTextValue] = useState(""); + const [page, setPage] = useState(1); + const [tableData, setTableData] = useState([]); + const [dashboardData, setDashboardData] = useState([]); + const [value, setValue] = useState("0"); + + const fetchApiData = async (page) => { + let response; + dispatch(LOADING_START()); + response = await axios.get( + `/LiveStock/live-stock/live-stock-view/?search=filter&value=${textValue}&role=${getRoleFromUrl()}&page=${page}&page_size=${perPage}&type=${ + value === "0" ? "pending" : "archive" + }` + ); + + dispatch(LOADING_END()); + setData(response.data.results); + setTotalRows(response.data.count); + }; + const handleTextChange = (event) => { + setTextValue(event.target.value); + }; + const handleChange = (event, newValue) => { + setValue(newValue); + }; + const handlePageChange = (page) => { + fetchApiData(page); + setPage(page); + }; + + const handlePerRowsChange = (perRows) => { + setPerPage(perRows); + setPage(1); + }; + + const updateTable = () => { + fetchApiData(page !== 0 ? page : 1); + }; + + const getDashboardData = () => { + dispatch( + provinceJahadGetHerdInfoDashboardService({ + search: textValue, + type: value === "0" ? "pending" : "archive", + }) + ).then((r) => { + setDashboardData(r.payload.data); + }); + }; + + useEffect(() => { + const d = data?.map((item, i) => { + return [ + page === 1 ? i + 1 : i + perPage * (page - 1) + 1, + item?.rancher?.fullname || "-", + item?.rancher?.nationalId, + item?.rancher?.mobile || "-", + item?.rancher?.city || "-", + item?.nationalIdLivestockCode || "-", + item?.herdCode || "-", + item?.type || "-", + item?.birthDay || "-", + item?.gender || "-", + convertDaysToYMD(item?.age) || "-", + item?.contractorCode || "-", + item?.uniqueIdentifier || "-", + item?.agent || "-", + item?.registeringUser || "-", + item?.registeringDate || "-", + , + ]; + }); + + setTableData(d); + }, [data]); + + useEffect(() => { + fetchApiData(1); + }, [dispatch, perPage, value]); + + useEffect(() => { + getDashboardData(); + }, []); + + const handleSubmit = async (event) => { + event.preventDefault(); + dispatch(LOADING_START()); + + try { + const response = await axios.get( + `/LiveStock/live-stock/live-stock-view/?search=filter&value=${textValue}&role=${getRoleFromUrl()}&page=1&page_size=${perPage}&type=${ + value === "0" ? "pending" : "archive" + }` + ); + setData(response.data.results); + setTotalRows(response.data.count); + getDashboardData(); + dispatch(LOADING_END()); + } catch (error) { + console.error("Error fetching data:", error); + } + }; + + return ( + + + + + + + + + + + +
    + + + +
    + + + + + +
    + + + + + +
    + ); +}; diff --git a/src/features/province-jahad/components/province-jahad-rancher-details/ProvinceJahadRancherDetails.js b/src/features/province-jahad/components/province-jahad-rancher-details/ProvinceJahadRancherDetails.js new file mode 100644 index 0000000..e1121a7 --- /dev/null +++ b/src/features/province-jahad/components/province-jahad-rancher-details/ProvinceJahadRancherDetails.js @@ -0,0 +1,49 @@ +import React, { useEffect, useState } from "react"; +import { Grid } from "../../../../components/grid/Grid"; +import { SimpleTable } from "../../../../components/simple-table/SimpleTable"; +import { useDispatch } from "react-redux"; +import { provinceJahadGetRancherDetailsService } from "../../services/province-jahad-get-rancher-details"; + +export const ProvinceJahadRancherDetails = ({ item }) => { + const dispatch = useDispatch(); + const [tableData, setTableData] = useState(); + + useEffect(() => { + dispatch( + provinceJahadGetRancherDetailsService({ herd_code: item?.herdCode }) + ).then((r) => { + setTableData(r.payload.data); + }); + }, []); + + return ( + + + + ); +}; diff --git a/src/features/province-jahad/components/province-jahad-rancher-operations/ProvinceJahadRancherOperations.js b/src/features/province-jahad/components/province-jahad-rancher-operations/ProvinceJahadRancherOperations.js new file mode 100644 index 0000000..4c45039 --- /dev/null +++ b/src/features/province-jahad/components/province-jahad-rancher-operations/ProvinceJahadRancherOperations.js @@ -0,0 +1,272 @@ +import { + Button, + FormControlLabel, + IconButton, + Popover, + Switch, + Tooltip, +} from "@mui/material"; +import { useContext, useState } from "react"; +import TuneIcon from "@mui/icons-material/Tune"; +import EditIcon from "@mui/icons-material/Edit"; +import { Grid } from "../../../../components/grid/Grid"; +import { + CLOSE_MODAL, + DRAWER, + OPEN_MODAL, +} from "../../../../lib/redux/slices/appSlice"; +import { useDispatch } from "react-redux"; +import DeleteIcon from "@mui/icons-material/Delete"; +import { AppContext } from "../../../../contexts/AppContext"; +import { ProvinceJahadRancherDetails } from "../province-jahad-rancher-details/ProvinceJahadRancherDetails"; +import RemoveRedEyeIcon from "@mui/icons-material/RemoveRedEye"; +import { ProvinceJahadEditRancher } from "../province-jahad-edit-rancher/ProvinceJahadEditRancher"; +import { ProvicneJahadSubmitHerd } from "../province-jahad-submit-herd/ProvicneJahadSubmitHerd"; +import AddIcon from "@mui/icons-material/Add"; +import { ProvinceJahadSubmitDhi } from "../province-jahad-submit-dhi/ProvinceJahadSubmitDhi"; +import { provinceJahadEditRancher } from "../../services/province-jahad-rancher-activation"; +import { provinceJahadDeleteRancherService } from "../../services/province-jahad-unions-delete-rancher"; + +export const ProvinceJahadRancherOperations = ({ + item, + updateTable, + getDashboardData, +}) => { + const dispatch = useDispatch(); + const [popoverOpen, setPopoverOpen] = useState(false); + const [anchorEl, setAnchorEl] = useState(null); + const [openNotif] = useContext(AppContext); + + const openPopover = (event) => { + setPopoverOpen(true); + setAnchorEl(event.currentTarget); + }; + + const closePopover = () => { + setPopoverOpen(false); + setAnchorEl(null); + }; + + return ( + + + + + +
    + + + { + closePopover(); + dispatch( + OPEN_MODAL({ + title: `جزئیات گله`, + content: , + }) + ); + }} + > + + + + + + + + + + { + closePopover(); + dispatch( + DRAWER({ + title: "ایجاد گله برای دامدار", + right: !(window.innerWidth <= 600), + bottom: window.innerWidth <= 600, + content: ( + + ), + }) + ); + }} + > + + + + + + { + closePopover(); + dispatch( + DRAWER({ + right: true, + top: false, + content: ( + + ), + title: "ویرایش دامدار ", + }) + ); + }} + > + + + + { + dispatch( + provinceJahadEditRancher({ + key: item?.key, + type: item?.type === "rural" ? "industrial" : "rural", + }) + ).then((r) => { + if (r.payload.error) { + openNotif({ + vertical: "top", + horizontal: "center", + msg: r.payload.error, + severity: "error", + }); + } else { + updateTable(); + openNotif({ + vertical: "top", + horizontal: "center", + msg: "عملیات با موفقیت انجام شد.", + severity: "success", + }); + } + }); + }} + color="primary" + /> + } + label={item?.type === "rural" ? "روستایی" : "صنعتی"} + style={{ + justifyContent: "center", + alignItems: "center", + display: "flex", + }} + /> + + + { + closePopover(); + dispatch( + OPEN_MODAL({ + title: "آیا مطمئن هستید؟", + content: ( + + + + + ), + }) + ); + }} + > + + + + +
    +
    +
    + ); +}; diff --git a/src/features/province-jahad/components/province-jahad-ranchers/ProvinceJahadRanchers.js b/src/features/province-jahad/components/province-jahad-ranchers/ProvinceJahadRanchers.js new file mode 100644 index 0000000..e82319a --- /dev/null +++ b/src/features/province-jahad/components/province-jahad-ranchers/ProvinceJahadRanchers.js @@ -0,0 +1,257 @@ +import React, { useEffect, useState } from "react"; +import { Button, TextField, Tooltip } from "@mui/material"; +import axios from "axios"; +import { RiFileExcel2Fill, RiSearchLine } from "react-icons/ri"; +import { + DRAWER, + LOADING_END, + LOADING_START, +} from "../../../../lib/redux/slices/appSlice"; +import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl"; +import { Grid } from "../../../../components/grid/Grid"; +import ResponsiveTable from "../../../../components/responsive-table/ResponsiveTable"; +import { useDispatch, useSelector } from "react-redux"; +import { provinceJahadGetRancherInfoDashboardService } from "../../services/province-jahad-get-rancher-dashbored"; +import { ProvinceJahadRancherOperations } from "../province-jahad-rancher-operations/ProvinceJahadRancherOperations"; +import { ProvinceJahadEditRancher } from "../province-jahad-edit-rancher/ProvinceJahadEditRancher"; + +export const ProvinceJahadRanchers = () => { + const dispatch = useDispatch(); + const handleTextChange = (event) => { + setTextValue(event.target.value); + }; + + const userKey = useSelector((state) => state.userSlice.userProfile.key); + + const [data, setData] = useState([]); + const [totalRows, setTotalRows] = useState(0); + const [perPage, setPerPage] = useState(10); + const [textValue, setTextValue] = useState(""); + const [page, setPage] = useState(1); + const [tableData, setTableData] = useState([]); + const [dashboardData, setDashboardData] = useState([]); + + const fetchApiData = async (page) => { + let response; + dispatch(LOADING_START()); + response = await axios.get( + `/LiveStock/rancher/rancher-view/?search=filter&value=${textValue}&role=${getRoleFromUrl()}&page=${page}&page_size=${perPage}` + ); + + dispatch(LOADING_END()); + setData(response.data.results); + setTotalRows(response.data.count); + }; + + const handlePageChange = (page) => { + fetchApiData(page); + setPage(page); + }; + + const handlePerRowsChange = (perRows) => { + setPerPage(perRows); + setPage(1); + }; + + const updateTable = () => { + fetchApiData(page !== 0 ? page : 1); + }; + const getDashboardData = () => { + dispatch( + provinceJahadGetRancherInfoDashboardService({ + search: textValue, + }) + ).then((r) => { + setDashboardData(r.payload.data); + }); + }; + useEffect(() => { + getDashboardData(); + }, []); + + useEffect(() => { + const d = data?.map((item, i) => { + return [ + page === 1 ? i + 1 : i + perPage * (page - 1) + 1, + item?.type === "rural" ? "روستایی" : "صنعتی", + item?.name, + item?.herdCode, + item?.epidemiologicalCode, + item?.postalCode, + item?.unitId, + item?.herdName, + item?.nationalId, + // item?.user?.fullname, + item?.mobile, + item?.contractorCode || "-", + item?.city, + item?.registeringUser || "-", + item?.type === "rural" ? "-" : item?.dhiAmount?.toLocaleString(), + , + ]; + }); + + setTableData(d); + }, [data]); + + useEffect(() => { + fetchApiData(1); + }, [dispatch, perPage]); + + const handleSubmit = async (event) => { + event.preventDefault(); + dispatch(LOADING_START()); + + try { + const response = await axios.get( + `/LiveStock/rancher/rancher-view/?search=filter&value=${textValue}&role=${getRoleFromUrl()}&page=${page}&page_size=${perPage}` + ); + setData(response.data.results); + setTotalRows(response.data.count); + dispatch( + provinceJahadGetRancherInfoDashboardService({ + search: textValue, + }) + ).then((r) => { + setDashboardData(r.payload.data); + }); + dispatch(LOADING_END()); + } catch (error) { + console.error("Error fetching data:", error); + } + }; + + return ( + + + + +
    + + + +
    + + + + + +
    + + + + +
    + ); +}; diff --git a/src/features/province-jahad/components/province-jahad-sell-report-transactions/ProvinceJahadSellReportTransactions.js b/src/features/province-jahad/components/province-jahad-sell-report-transactions/ProvinceJahadSellReportTransactions.js new file mode 100644 index 0000000..4295ff5 --- /dev/null +++ b/src/features/province-jahad/components/province-jahad-sell-report-transactions/ProvinceJahadSellReportTransactions.js @@ -0,0 +1,338 @@ +import React, { useContext, useEffect, useState } from "react"; +import { + Button, + Checkbox, + FormControl, + FormControlLabel, + InputLabel, + MenuItem, + Select, + TextField, + Tooltip, +} from "@mui/material"; +import { DatePicker } from "@mui/x-date-pickers"; +import moment from "moment"; +import { useDispatch } from "react-redux"; +import axios from "axios"; +import { RiFileExcel2Fill, RiSearchLine } from "react-icons/ri"; +import { AppContext } from "../../../../contexts/AppContext"; +import { + LOADING_END, + LOADING_START, + OPEN_MODAL, +} from "../../../../lib/redux/slices/appSlice"; +import { Grid } from "../../../../components/grid/Grid"; +import ResponsiveTable from "../../../../components/responsive-table/ResponsiveTable"; +import { SimpleTable } from "../../../../components/simple-table/SimpleTable"; +import { formatTime } from "../../../../utils/formatTime"; + +export const ProvinceJahadSellReportTransactions = ({ + cooperative_key, + product, +}) => { + const [, , selectedDate1, setSelectedDate1, selectedDate2, setSelectedDate2] = + useContext(AppContext); + const [withDate, setWithDate] = useState(false); + + const [transactionType, setTransactionType] = useState("all"); + + const handleChange = (event) => { + setTransactionType(event.target.value); + }; + + const dispatch = useDispatch(); + useEffect(() => { + const currentDate = moment(new Date()).format("YYYY-MM-DD"); + setSelectedDate1(currentDate); + setSelectedDate2(currentDate); + }, []); + + const handleTextChange = (event) => { + setTextValue(event.target.value); + }; + + const [data, setData] = useState([]); + const [totalRows, setTotalRows] = useState(0); + const [perPage, setPerPage] = useState(10); + const [textValue, setTextValue] = useState(""); + const [page, setPage] = useState(1); + const [tableData, setTableData] = useState([]); + + const fetchApiData = async (page) => { + let response; + dispatch(LOADING_START()); + response = await axios.get( + `live-stock-transactions/?search=filter&value=${textValue}${ + withDate ? `&date1=${selectedDate1}&date2=${selectedDate2}` : `` + }&page=${page}&page_size=${perPage}&cooperative_key=${cooperative_key}&state=${transactionType}&name=${ + product?.key + }` + ); + dispatch(LOADING_END()); + setData(response.data.results); + setTotalRows(response.data.count); + }; + + const handlePageChange = (page) => { + fetchApiData(page); + setPage(page); + }; + + const handlePerRowsChange = (perRows) => { + setPerPage(perRows); + setPage(1); + }; + + // const updateTable = () => { + // fetchApiData(page !== 0 ? page : 1); + // }; + + const convertToJson = (data) => { + if (data) { + return JSON.parse(data); + } + }; + + useEffect(() => { + const d = data?.map((item, i) => { + const products = item?.products?.map((option, index) => { + return [ + index + 1, + option?.name, + option?.curWeight?.toLocaleString(), + option?.price?.toLocaleString(), + option?.curPrice?.toLocaleString(), + ]; + }); + + return [ + page === 1 ? i + 1 : i + perPage * (page - 1) + 1, + formatTime(item?.date), + item?.fullname || "-", + item?.natcode || "-", + item?.mobile || "-", + `${item?.pos?.cooperative?.name} شهرستان ${item?.pos?.cooperative?.user?.cityName} (${item?.pos?.cooperative?.user?.fullname})`, + item?.pos?.cooperative?.user?.mobile, + item?.paid ? "پرداخت شده" : `پرداخت نشده (${item?.result})`, + convertToJson(item?.additional).isTaavoni ? "تعاونی" : "کارخانه", + item?.products + ? item?.products.map((option) => option.name).join("-") + : "-", + convertToJson(item?.additional)?.ownerNatcode?.toLocaleString() || 0, + convertToJson(item?.additional)?.cur_heavy?.toLocaleString() || 0, + convertToJson(item?.additional)?.cur_light?.toLocaleString() || 0, + item?.products + .reduce( + (accumulator, currentValue) => + accumulator + currentValue?.curWeight, + 0 + ) + .toLocaleString(), + item?.price?.toLocaleString(), + convertToJson(item?.additional)?.cooperative_price?.toLocaleString() || + 0, + convertToJson(item?.additional)?.union_price?.toLocaleString() || 0, + , + ]; + }); + + setTableData(d); + }, [data]); + + useEffect(() => { + fetchApiData(1); + }, [ + dispatch, + selectedDate1, + selectedDate2, + perPage, + withDate, + transactionType, + ]); + + const handleSubmit = async (event) => { + event.preventDefault(); + dispatch(LOADING_START()); + + try { + const response = await axios.get( + `live-stock-transactions/?search=filter&value=${textValue}${ + withDate ? `&date1=${selectedDate1}&date2=${selectedDate2}` : `` + }&page=${1}&page_size=${perPage}&cooperative_key=${cooperative_key}&state=${transactionType}` + ); + setData(response.data.results); + setTotalRows(response.data.count); + dispatch(LOADING_END()); + } catch (error) { + console.error("Error fetching data:", error); + } + }; + + return ( + + + + + فیلتر تراکنش + + + + + + + setWithDate(!withDate)} + color="primary" + /> + } + /> + + + ( + + )} + value={selectedDate1} + onChange={(e) => { + setSelectedDate1(moment(e).format("YYYY-MM-DD")); + }} + /> + + + ( + + )} + value={selectedDate2} + onChange={(e) => { + setSelectedDate2(moment(e).format("YYYY-MM-DD")); + }} + /> + + + +
    + + + +
    + + + + + +
    + + +
    + ); +}; diff --git a/src/features/province-jahad/components/province-jahad-sell-report/ProvinceJahadSellReport.js b/src/features/province-jahad/components/province-jahad-sell-report/ProvinceJahadSellReport.js new file mode 100644 index 0000000..5ba7230 --- /dev/null +++ b/src/features/province-jahad/components/province-jahad-sell-report/ProvinceJahadSellReport.js @@ -0,0 +1,372 @@ +import React, { useContext, useEffect, useState } from "react"; +import { + Button, + Checkbox, + IconButton, + TextField, + Tooltip, +} from "@mui/material"; +import { DatePicker } from "@mui/x-date-pickers"; +import moment from "moment"; +import { useDispatch, useSelector } from "react-redux"; +import axios from "axios"; +import { RiFileExcel2Fill, RiSearchLine } from "react-icons/ri"; +import { AppContext } from "../../../../contexts/AppContext"; +import { + DRAWER, + LOADING_END, + LOADING_START, +} from "../../../../lib/redux/slices/appSlice"; +import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl"; +import { Grid } from "../../../../components/grid/Grid"; +import ResponsiveTable from "../../../../components/responsive-table/ResponsiveTable"; +import { ProvinceJahadSellReportTransactions } from "../province-jahad-sell-report-transactions/ProvinceJahadSellReportTransactions"; +import RemoveRedEyeIcon from "@mui/icons-material/RemoveRedEye"; + +import ToggleOffOutlinedIcon from "@mui/icons-material/ToggleOffOutlined"; +import ToggleOnIcon from "@mui/icons-material/ToggleOn"; +import { provinceJahadSellReportInfoDashboardService } from "../../services/province-get-jahad-sell-report-dashboard"; + +export const ProvinceJahadSellReport = ({ product }) => { + const [, , selectedDate1, setSelectedDate1, selectedDate2, setSelectedDate2] = + useContext(AppContext); + const [withDate, setWithDate] = useState(false); + const userKey = useSelector((state) => state.userSlice.userProfile.key); + + const dispatch = useDispatch(); + useEffect(() => { + const currentDate = moment(new Date()).format("YYYY-MM-DD"); + setSelectedDate1(currentDate); + setSelectedDate2(currentDate); + }, []); + + const handleTextChange = (event) => { + setTextValue(event.target.value); + }; + + const [data, setData] = useState([]); + const [totalRows, setTotalRows] = useState(0); + const [perPage, setPerPage] = useState(10); + const [textValue, setTextValue] = useState(""); + const [page, setPage] = useState(1); + const [tableData, setTableData] = useState([]); + const [dashboardData, setDashboardData] = useState([]); + + const getDashboardData = () => { + dispatch( + provinceJahadSellReportInfoDashboardService({ + date1: selectedDate1, + date2: selectedDate2, + search: "filter", + role: getRoleFromUrl(), + value: textValue, + name: product?.key, + }) + ).then((r) => { + setDashboardData(r.payload.data); + }); + }; + + const fetchApiData = async (page) => { + let response; + dispatch(LOADING_START()); + response = await axios.get( + `cooperative-warehouse/?search=filter&value=${textValue}&role=${getRoleFromUrl()}${ + withDate ? `&date1=${selectedDate1}&date2=${selectedDate2}` : `` + }&page=${page}&page_size=${perPage}&name=${product?.key}` + ); + dispatch(LOADING_END()); + getDashboardData(); + + setData(response.data.results); + setTotalRows(response.data.count); + }; + + const handlePageChange = (page) => { + fetchApiData(page); + setPage(page); + }; + + const handlePerRowsChange = (perRows) => { + setPerPage(perRows); + setPage(1); + }; + + // const updateTable = () => { + // fetchApiData(page !== 0 ? page : 1); + // }; + + useEffect(() => { + const d = data?.map((item, i) => { + return [ + page === 1 ? i + 1 : i + perPage * (page - 1) + 1, + product?.label, + item?.name, + item?.user?.fullname, + item?.user?.provinceName, + item?.user?.cityName, + item?.user?.mobile, + item?.user?.nationalId, + item?.info?.totalReceiptWeight?.toLocaleString() || 0, + item?.info?.totalWeight?.toLocaleString() || 0, + item?.info?.totalAllocatedWeight?.toLocaleString() || 0, + item?.info?.totalRemainWeight?.toLocaleString() || 0, + item?.info?.transactions?.toLocaleString() || 0, + item?.info?.totalTransactionsPrice?.toLocaleString() || 0, + item?.info?.totalTransactionsWeight?.toLocaleString() || 0, + + + { + dispatch( + DRAWER({ + top: true, + title: "تراکنش ها", + content: ( + + + + + + ), + }) + ); + }} + > + + + + + + + + + , + ]; + }); + + setTableData(d); + }, [data]); + + useEffect(() => { + fetchApiData(1); + }, [dispatch, selectedDate1, selectedDate2, perPage, withDate]); + + const handleSubmit = async (event) => { + event.preventDefault(); + dispatch(LOADING_START()); + + try { + const response = await axios.get( + `cooperative-warehouse/?role=${getRoleFromUrl()}&search=filter&value=${textValue}${ + withDate ? `&date1=${selectedDate1}&date2=${selectedDate2}` : `` + }&page=${1}&page_size=${perPage}&name=${product?.key}` + ); + setData(response.data.results); + setTotalRows(response.data.count); + dispatch(LOADING_END()); + getDashboardData(); + } catch (error) { + console.error("Error fetching data:", error); + } + }; + + return ( + + + + } + checkedIcon={} + checked={withDate} + onChange={() => setWithDate(!withDate)} + color="primary" + size="large" + /> + + ( + + )} + value={selectedDate1} + onChange={(e) => { + setSelectedDate1(moment(e).format("YYYY-MM-DD")); + }} + /> + + + ( + + )} + value={selectedDate2} + onChange={(e) => { + setSelectedDate2(moment(e).format("YYYY-MM-DD")); + }} + /> + + + +
    + + + +
    + + + + + + + + + + + +
    + + + + +
    + ); +}; diff --git a/src/features/province-jahad/components/province-jahad-share-operations/ProvinceJahadSharesOperations.js b/src/features/province-jahad/components/province-jahad-share-operations/ProvinceJahadSharesOperations.js new file mode 100644 index 0000000..bef81dc --- /dev/null +++ b/src/features/province-jahad/components/province-jahad-share-operations/ProvinceJahadSharesOperations.js @@ -0,0 +1,86 @@ +import { IconButton, Popover, Tooltip } from "@mui/material"; +import { useState } from "react"; +// import DeleteIcon from "@mui/icons-material/Delete"; +import TuneIcon from "@mui/icons-material/Tune"; +import EditIcon from "@mui/icons-material/Edit"; +import { Grid } from "../../../../components/grid/Grid"; +import { useDispatch } from "react-redux"; +import { DRAWER } from "../../../../lib/redux/slices/appSlice"; +import { ProvinceJahadEditShare } from "../province-jahad-edit-share/ProvinceJahadEditShare"; + +export const ProvinceJahadSharesOperations = ({ item, updateTable }) => { + const [anchorEl, setAnchorEl] = useState(null); + const dispatch = useDispatch(); + const handleClick = (event) => { + setAnchorEl(event.currentTarget); + }; + + const handleClose = () => { + setAnchorEl(null); + }; + + const open = Boolean(anchorEl); + const id = open ? "popover" : undefined; + + return ( + + + + + +
    + + { + handleClose(); + dispatch( + DRAWER({ + title: "ویرایش اطلاعات ", + right: !(window.innerWidth <= 600), + bottom: window.innerWidth <= 600, + content: ( + + ), + }) + ); + }} + > + + + + + {/* + + + + */} +
    +
    +
    + ); +}; diff --git a/src/features/province-jahad/components/province-jahad-shares/ProvinceJahadShares.js b/src/features/province-jahad/components/province-jahad-shares/ProvinceJahadShares.js new file mode 100644 index 0000000..9fc1aae --- /dev/null +++ b/src/features/province-jahad/components/province-jahad-shares/ProvinceJahadShares.js @@ -0,0 +1,152 @@ +import { Grid } from "../../../../components/grid/Grid"; +import React, { useEffect, useState } from "react"; +import { Button, TextField } from "@mui/material"; +import { useDispatch } from "react-redux"; +import axios from "axios"; +import { RiSearchLine } from "react-icons/ri"; +import { + LOADING_END, + LOADING_START, +} from "../../../../lib/redux/slices/appSlice"; +import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl"; +import ResponsiveTable from "../../../../components/responsive-table/ResponsiveTable"; +import { ProvinceJahadSharesOperations } from "../province-jahad-share-operations/ProvinceJahadSharesOperations"; + +export const ProvinceJahadShares = ({ product }) => { + const dispatch = useDispatch(); + + const handleTextChange = (event) => { + setTextValue(event.target.value); + }; + + const [data, setData] = useState([]); + const [totalRows, setTotalRows] = useState(0); + const [perPage, setPerPage] = useState(10); + const [textValue, setTextValue] = useState(""); + const [page, setPage] = useState(1); + const [tableData, setTableData] = useState([]); + + const fetchApiData = async (page) => { + let response; + dispatch(LOADING_START()); + response = await axios.get( + `LiveStock/jahad/cooperative-shares/?search=filter&value=${textValue}&role=${getRoleFromUrl()}&page=${page}&page_size=${perPage}&name=${ + product?.label + }` + ); + dispatch(LOADING_END()); + setData(response.data.results); + setTotalRows(response.data.count); + }; + + const handlePageChange = (page) => { + fetchApiData(page); + setPage(page); + }; + + const handlePerRowsChange = (perRows) => { + setPerPage(perRows); + setPage(1); + }; + + const updateTable = () => { + fetchApiData(page !== 0 ? page : 1); + }; + + useEffect(() => { + const d = data?.map((item, i) => { + return [ + page === 1 ? i + 1 : i + perPage * (page - 1) + 1, + `${item?.cooperative?.name} (${item?.cooperative?.user?.fullname})`, + item?.price?.toLocaleString(), + item?.unionPrice?.toLocaleString(), + item?.cooperativePrice?.toLocaleString(), + item?.companyPrice?.toLocaleString(), + item?.shippingPrice?.toLocaleString(), + , + ]; + }); + + setTableData(d); + }, [data]); + + useEffect(() => { + fetchApiData(1); + }, [dispatch, perPage]); + + const handleSubmit = async (event) => { + event.preventDefault(); + dispatch(LOADING_START()); + + try { + const response = await axios.get( + `LiveStock/jahad/cooperative-shares/?role=${getRoleFromUrl()}&search=filter&value=${textValue}&page=${1}&page_size=${perPage}&name=${ + product?.label + }` + ); + setData(response.data.results); + setTotalRows(response.data.count); + dispatch(LOADING_END()); + } catch (error) { + console.error("Error fetching data:", error); + } + }; + + return ( + + + +
    + + + +
    +
    + + +
    + ); +}; diff --git a/src/features/province-jahad/components/province-jahad-submit-allocation/ProvinceJahadSubmitAllocation.js b/src/features/province-jahad/components/province-jahad-submit-allocation/ProvinceJahadSubmitAllocation.js new file mode 100644 index 0000000..eaaaf07 --- /dev/null +++ b/src/features/province-jahad/components/province-jahad-submit-allocation/ProvinceJahadSubmitAllocation.js @@ -0,0 +1,301 @@ +import React, { useContext, useEffect, useState } from "react"; +import { useFormik } from "formik"; +import * as Yup from "yup"; +import { + RadioGroup, + FormControlLabel, + Radio, + FormControl, + Button, + Typography, + Autocomplete, + TextField, +} from "@mui/material"; +import { Grid } from "../../../../components/grid/Grid"; +import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl"; +import { NumberInput } from "../../../../components/number-format-custom/NumberFormatCustom"; +import { useDispatch } from "react-redux"; +import { provinceJahadSubmitAllocationGetUsers } from "../../services/province-jahad-submit-allocation-get-users"; +import { + provinceJahadEditAllocationService, + provinceJahadSubmitAllocationService, +} from "../../services/province-jahad-submit-allocation"; +import { AppContext } from "../../../../contexts/AppContext"; +import { CLOSE_MODAL } from "../../../../lib/redux/slices/appSlice"; + +export const ProvinceJahadSubmitAllocation = ({ + type, + productKey, + updateTable, + getDashboardData, + item, + // getRemainWeight, + maxAllow, +}) => { + const validationSchema = Yup.object({ + allocationType: Yup.string().required("لطفا یک گزینه را انتخاب کنید"), + weight: Yup.number() + .required("این فیلد اجباریست!") + .positive("عدد مثبت وارد کنید!"), + place: Yup.string().required("این فیلد اجباریست!"), + description: Yup.string(), + }); + + const [users, setUsers] = useState([]); + + const dispatch = useDispatch(); + + const [openNotif] = useContext(AppContext); + + const formik = useFormik({ + initialValues: { + allocationType: + type === "charge" ? "LiveStockProvinceJahad" : "Cooperative", + buyer_key: null, + weight: item?.weight || "", + place: item?.place || "", + description: item?.description || "", + }, + validationSchema: validationSchema, + onSubmit: (values) => { + if (item) { + let req = { + allocation_key: item?.key, + weight: values.weight, + place: values.place, + description: values.description, + }; + + req = Object.fromEntries( + Object.entries(req).filter(([_, value]) => value !== null) + ); + + dispatch(provinceJahadEditAllocationService(req)).then((r) => { + if (r.payload.error) { + openNotif({ + vertical: "top", + horizontal: "center", + msg: r.payload.error, + severity: "error", + }); + } else { + openNotif({ + vertical: "top", + horizontal: "center", + msg: "عملیات با موفقیت انجام شد.", + severity: "success", + }); + dispatch(CLOSE_MODAL()); + updateTable(); + getDashboardData(); + } + }); + } else { + let req = { + allocator: getRoleFromUrl(), + receiver: + getRoleFromUrl() === "Cooperative" + ? "Cooperative" + : values.allocationType, + product_key: productKey, + buyer_key: values.buyer_key, + weight: values.weight, + place: values.place, + description: values.description, + }; + + req = Object.fromEntries( + Object.entries(req).filter(([_, value]) => value !== null) + ); + + if (maxAllow && values.weight > maxAllow) { + openNotif({ + vertical: "top", + horizontal: "center", + msg: "مقدار وارد شده از سهیه دریافتی بیشتر است!", + severity: "error", + }); + return; + } + + dispatch(provinceJahadSubmitAllocationService(req)).then((r) => { + if (r.payload.error) { + openNotif({ + vertical: "top", + horizontal: "center", + msg: r.payload.error, + severity: "error", + }); + } else { + openNotif({ + vertical: "top", + horizontal: "center", + msg: "عملیات با موفقیت انجام شد.", + severity: "success", + }); + dispatch(CLOSE_MODAL()); + updateTable(); + getDashboardData(); + } + }); + } + }, + }); + + useEffect(() => { + if (type !== "charge" && !item) { + formik.setFieldValue("buyer_key", null); + dispatch( + provinceJahadSubmitAllocationGetUsers({ + type: formik.values.allocationType, + }) + ).then((r) => { + setUsers(r.payload.data); + }); + } + }, [formik.values.allocationType]); + + useEffect(() => { + formik.validateForm(); + }, []); + + const isFormValid = () => { + if (type === "charge") { + return formik.isValid; + } else if (item) { + return ( + formik.values.weight && formik.values.place && formik.values.description + ); + } else { + return formik.isValid && formik.values.buyer_key; + } + }; + + return ( + + {type !== "charge" && + !item && + getRoleFromUrl() === "LiveStockProvinceJahad" && ( + + + + } + label="تخصیص به تعاونی" + /> + } + label="تخصیص به اتحادیه" + /> + + {formik.touched.allocationType && + formik.errors.allocationType && ( + + {formik.errors.allocationType} + + )} + + + )} + + + + + + {type !== "charge" && !item && ( + + { + return { + data: i, + label: `${i?.name}`, + }; + }) + : [] + } + onChange={(event, value) => { + formik.setFieldValue("buyer_key", value?.data?.key); + }} + renderInput={(params) => ( + + )} + /> + + )} + + + + + ); +}; diff --git a/src/features/province-jahad/components/province-jahad-submit-dhi/ProvinceJahadSubmitDhi.js b/src/features/province-jahad/components/province-jahad-submit-dhi/ProvinceJahadSubmitDhi.js new file mode 100644 index 0000000..50d4b17 --- /dev/null +++ b/src/features/province-jahad/components/province-jahad-submit-dhi/ProvinceJahadSubmitDhi.js @@ -0,0 +1,87 @@ +import React, { useContext } from "react"; +import { TextField, Button, Typography } from "@mui/material"; +import { useFormik } from "formik"; +import * as Yup from "yup"; +import { Grid } from "../../../../components/grid/Grid"; +import { useDispatch } from "react-redux"; +import { AppContext } from "../../../../contexts/AppContext"; +import { provinceJahadEditRancher } from "../../services/province-jahad-rancher-activation"; +import { CLOSE_MODAL } from "../../../../lib/redux/slices/appSlice"; + +const validationSchema = Yup.object({ + amount: Yup.number() + .required("تعداد الزامی است") + .integer("تعداد باید یک عدد صحیح باشد"), +}); + +export const ProvinceJahadSubmitDhi = ({ + updateTable, + item, + getDashboardData, +}) => { + const dispatch = useDispatch(); + const [openNotif] = useContext(AppContext); + const formik = useFormik({ + initialValues: { + amount: item?.dhiAmount || "", + }, + validationSchema: validationSchema, + onSubmit: (values) => { + dispatch( + provinceJahadEditRancher({ + key: item?.key, + dhi_amount: values.amount, + }) + ).then((r) => { + if (r.payload.error) { + openNotif({ + vertical: "top", + horizontal: "center", + msg: r.payload.error, + severity: "error", + }); + } else { + openNotif({ + vertical: "top", + horizontal: "center", + msg: "عملیات با موفقیت انجام شد.", + severity: "success", + }); + dispatch(CLOSE_MODAL()); + getDashboardData(); + updateTable(); + } + }); + }, + }); + + return ( + + + در صورت وارد کردن مقدار 0 دامدار از پروژه DHI خارج میشود. + + + + + ); +}; diff --git a/src/features/province-jahad/components/province-jahad-submit-herd/ProvicneJahadSubmitHerd.js b/src/features/province-jahad/components/province-jahad-submit-herd/ProvicneJahadSubmitHerd.js new file mode 100644 index 0000000..5fb57bf --- /dev/null +++ b/src/features/province-jahad/components/province-jahad-submit-herd/ProvicneJahadSubmitHerd.js @@ -0,0 +1,338 @@ +import React, { useContext, useState } from "react"; +import { useFormik } from "formik"; +import * as Yup from "yup"; +import { + TextField, + FormControlLabel, + Radio, + RadioGroup, + Button, + FormControl, + FormLabel, + IconButton, + FormHelperText, + Typography, +} from "@mui/material"; +import { Grid } from "../../../../components/grid/Grid"; +import { AppContext } from "../../../../contexts/AppContext"; +import { useDispatch } from "react-redux"; +import { + provinceJahadEditHerdService, + provinceJahadSubmitHerdService, +} from "../../services/province-jahad-submit-herd"; +import { DRAWER } from "../../../../lib/redux/slices/appSlice"; +import SearchIcon from "@mui/icons-material/Search"; +import { provinceJahadGetSingleRancherService } from "../../services/province-jahad-get-single-rancher"; +import { SPACING } from "../../../../data/spacing"; + +export const ProvicneJahadSubmitHerd = ({ + item, + updateTable, + getDashboardData, + rancherKey, +}) => { + const [openNotif] = useContext(AppContext); + const dispatch = useDispatch(); + const [searchedRancherKey, setSearchedRancherKey] = useState(null); + const formik = useFormik({ + initialValues: { + herd_code: item?.herdCode || "", + type: item?.type || "", + contractor_code: item?.contractorCode || "", + agent: item?.agent || "", + unique_identifier: item?.uniqueIdentifier || "", + gender: item?.gender || "نر", + userInfoCheck: null, + }, + validationSchema: Yup.object({ + ...(item && { + herd_code: Yup.string().required("این فیلد اجباریست!"), + contractor_code: Yup.string().required("این فیلد اجباریست!"), + }), + type: Yup.string().required("این فیلد اجباریست!"), + agent: Yup.string().required("این فیلد اجباریست!"), + unique_identifier: Yup.string().required("این فیلد اجباریست!"), + gender: Yup.string().required("این فیلد اجباریست!"), + }), + onSubmit: (values) => { + if (item) { + dispatch( + provinceJahadEditHerdService({ + live_stock_key: item?.key, + unique_identifier: values.unique_identifier, + agent: values.agent, + contractor_code: values.contractor_code, + gender: values.gender, + type: values.type, + herd_code: values.herd_code, + }) + ).then((r) => { + if (r.payload.error) { + openNotif({ + vertical: "top", + horizontal: "center", + msg: r.payload.error, + severity: "error", + }); + } else { + openNotif({ + vertical: "top", + horizontal: "center", + msg: "عملیات با موفقیت انجام شد.", + severity: "success", + }); + dispatch(DRAWER({ right: false, bottom: false, content: null })); + + updateTable(); + getDashboardData(); + } + }); + } else { + dispatch( + provinceJahadSubmitHerdService({ + unique_identifier: values.unique_identifier, + agent: values.agent, + gender: values.gender, + type: values.type, + rancher_key: rancherKey || searchedRancherKey?.key, + }) + ).then((r) => { + if (r.payload.error) { + openNotif({ + vertical: "top", + horizontal: "center", + msg: r.payload.error, + severity: "error", + }); + } else { + openNotif({ + vertical: "top", + horizontal: "center", + msg: "عملیات با موفقیت انجام شد.", + severity: "success", + }); + dispatch(DRAWER({ right: false, bottom: false, content: null })); + + updateTable(); + getDashboardData(); + } + }); + } + }, + }); + + return ( + <> + {!rancherKey && !searchedRancherKey ? ( + + جستجو کاربر + + + + { + dispatch( + provinceJahadGetSingleRancherService({ + value: formik.values.userInfoCheck, + }) + ).then((r) => { + if (r.error) { + openNotif({ + vertical: "top", + horizontal: "center", + msg: "کاربر یافت نشد", + severity: "error", + }); + } else { + setSearchedRancherKey(r.payload.data); + } + }); + }} + > + + + + + شماره موبایل، کد گله یا کد ملی دامدار را وارد کنید + + + ) : ( + + {searchedRancherKey && ( + + + نام دامدای: + + {searchedRancherKey?.name} + + + + کد گله: + + {searchedRancherKey?.herdCode} + + + + کد اپیدمیولوژیک: + + {searchedRancherKey?.epidemiologicalCode} + + + + نام گله: + + {searchedRancherKey?.herdName} + + + + )} + + {item && ( + + )} + + + + {item && ( + + )} + + + + + + + جنسیت + + } label="نر" /> + } label="ماده" /> + + {formik.touched.gender && formik.errors.gender && ( +
    {formik.errors.gender}
    + )} +
    + + +
    + )} + + ); +}; diff --git a/src/features/province-jahad/components/province-jahad-transactions/ProvinceJahadTransactions.js b/src/features/province-jahad/components/province-jahad-transactions/ProvinceJahadTransactions.js new file mode 100644 index 0000000..c54c2f8 --- /dev/null +++ b/src/features/province-jahad/components/province-jahad-transactions/ProvinceJahadTransactions.js @@ -0,0 +1,422 @@ +import React, { useContext, useEffect, useState } from "react"; +import { + Button, + Checkbox, + FormControl, + IconButton, + InputLabel, + MenuItem, + Select, + TextField, + Tooltip, +} from "@mui/material"; +import { DatePicker } from "@mui/x-date-pickers"; +import moment from "moment"; +import { useDispatch, useSelector } from "react-redux"; +import axios from "axios"; +import { RiFileExcel2Fill, RiSearchLine } from "react-icons/ri"; +import { AppContext } from "../../../../contexts/AppContext"; +import { + LOADING_END, + LOADING_START, + OPEN_MODAL, +} from "../../../../lib/redux/slices/appSlice"; +import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl"; +import { Grid } from "../../../../components/grid/Grid"; +import ResponsiveTable from "../../../../components/responsive-table/ResponsiveTable"; +import { SimpleTable } from "../../../../components/simple-table/SimpleTable"; +import { formatTime } from "../../../../utils/formatTime"; +import RemoveRedEyeIcon from "@mui/icons-material/RemoveRedEye"; +import ToggleOffOutlinedIcon from "@mui/icons-material/ToggleOffOutlined"; +import ToggleOnIcon from "@mui/icons-material/ToggleOn"; +import { provinceJahadGetTransactionInfoDashboardService } from "../../services/province-jahad-get-transaction-dashboard"; + +export const ProvinceJahadTransactions = ({ product }) => { + const [, , selectedDate1, setSelectedDate1, selectedDate2, setSelectedDate2] = + useContext(AppContext); + const userKey = useSelector((state) => state.userSlice.userProfile.key); + const [dashboardData, setDashboardData] = useState([]); + const [transactionType, setTransactionType] = useState("all"); + const [productType, setProductType] = useState("bran"); + + const handleChange = (event) => { + setTransactionType(event.target.value); + }; + const handleChangeProduct = (event) => { + setProductType(event.target.value); + }; + + const dispatch = useDispatch(); + useEffect(() => { + const currentDate = moment(new Date()).format("YYYY-MM-DD"); + setSelectedDate1(currentDate); + setSelectedDate2(currentDate); + }, []); + + const handleTextChange = (event) => { + setTextValue(event.target.value); + }; + + const [data, setData] = useState([]); + const [totalRows, setTotalRows] = useState(0); + const [perPage, setPerPage] = useState(10); + const [textValue, setTextValue] = useState(""); + const [page, setPage] = useState(1); + const [tableData, setTableData] = useState([]); + const [withDate, setWithDate] = useState(false); + + const getDashboardData = () => { + dispatch( + provinceJahadGetTransactionInfoDashboardService({ + date1: withDate ? selectedDate1 : "", + date2: withDate ? selectedDate2 : "", + search: "filter", + role: getRoleFromUrl(), + value: textValue, + name: productType || product?.key, + state: transactionType, + }) + ).then((r) => { + setDashboardData(r.payload.data); + }); + }; + const fetchApiData = async (page) => { + let response; + dispatch(LOADING_START()); + response = await axios.get( + `live-stock-transactions/?search=filter&value=${textValue}&role=${getRoleFromUrl()}${ + withDate ? `&date1=${selectedDate1}&date2=${selectedDate2}` : `` + }&page=${page}&page_size=${perPage}&state=${transactionType}&name=${productType}` + ); + getDashboardData(); + dispatch(LOADING_END()); + setData(response.data.results); + setTotalRows(response.data.count); + }; + + const handlePageChange = (page) => { + fetchApiData(page); + setPage(page); + }; + + const handlePerRowsChange = (perRows) => { + setPerPage(perRows); + setPage(1); + }; + + // const updateTable = () => { + // fetchApiData(page !== 0 ? page : 1); + // }; + + const convertToJson = (data) => { + if (data) { + return JSON.parse(data); + } + }; + + useEffect(() => { + const d = data?.map((item, i) => { + const products = item?.products?.map((option, index) => { + return [ + index + 1, + option?.name, + option?.curWeight?.toLocaleString(), + option?.price?.toLocaleString(), + option?.curPrice?.toLocaleString(), + ]; + }); + + return [ + page === 1 ? i + 1 : i + perPage * (page - 1) + 1, + formatTime(item?.date), + item?.fullname || "-", + item?.natcode || "-", + item?.mobile || "-", + `${item?.pos?.cooperative?.name} شهرستان ${item?.pos?.cooperative?.user?.cityName} (${item?.pos?.cooperative?.user?.fullname})`, + item?.pos?.cooperative?.user?.mobile, + item?.paid ? "پرداخت شده" : `پرداخت نشده (${item?.result})`, + convertToJson(item?.additional).isTaavoni ? "تعاونی" : "کارخانه", + item?.products + ? item?.products.map((option) => option.name).join("-") + : "-", + convertToJson(item?.additional)?.ownerNatcode?.toLocaleString() || 0, + + item?.shares?.curHeavy?.toLocaleString() || 0, + item?.shares?.curLight?.toLocaleString() || 0, + item?.shares?.curWeight?.toLocaleString() || 0, + // item?.products + // .reduce( + // (accumulator, currentValue) => + // accumulator + currentValue?.curWeight, + // 0 + // ) + // .toLocaleString(), + item?.price?.toLocaleString(), + convertToJson(item?.additional)?.cooperative_price?.toLocaleString() || + 0, + item?.shares?.totalUnionPrice?.toLocaleString() || 0, + item?.shares?.totalCompanyPrice?.toLocaleString() || 0, + + + { + dispatch( + OPEN_MODAL({ + title: "جزئیات محصول", + content: ( + + + + ), + }) + ); + }} + > + + + , + ]; + }); + + setTableData(d); + }, [data]); + + useEffect(() => { + fetchApiData(1); + }, [ + dispatch, + selectedDate1, + selectedDate2, + perPage, + transactionType, + withDate, + productType, + ]); + + const handleSubmit = async (event) => { + event.preventDefault(); + dispatch(LOADING_START()); + + try { + const response = await axios.get( + `live-stock-transactions/?role=${getRoleFromUrl()}&search=filter&value=${textValue}${ + withDate ? `&date1=${selectedDate1}&date2=${selectedDate2}` : `` + }&page=${1}&page_size=${perPage}&state=${transactionType}&name=${productType}` + ); + setData(response.data.results); + setTotalRows(response.data.count); + getDashboardData(); + dispatch(LOADING_END()); + } catch (error) { + console.error("Error fetching data:", error); + } + }; + + return ( + + + + + انتخاب محصول + + + + + + فیلتر تراکنش + + + + + } + checkedIcon={} + checked={withDate} + onChange={() => setWithDate(!withDate)} + color="primary" + size="large" + /> + + ( + + )} + value={selectedDate1} + onChange={(e) => { + setSelectedDate1(moment(e).format("YYYY-MM-DD")); + }} + /> + + + ( + + )} + value={selectedDate2} + onChange={(e) => { + setSelectedDate2(moment(e).format("YYYY-MM-DD")); + }} + /> + + {" "} + +
    + + + +
    + + + + + + + + + + +
    + + +
    + ); +}; diff --git a/src/features/province-jahad/components/province-jahad-union-submit-real-weight/ProvinceJahadUnionSubmitRealWeight.js b/src/features/province-jahad/components/province-jahad-union-submit-real-weight/ProvinceJahadUnionSubmitRealWeight.js new file mode 100644 index 0000000..bfe8ce7 --- /dev/null +++ b/src/features/province-jahad/components/province-jahad-union-submit-real-weight/ProvinceJahadUnionSubmitRealWeight.js @@ -0,0 +1,132 @@ +import React, { useContext, useEffect } from "react"; +import { TextField } from "@mui/material"; +import { Button } from "@mui/material"; +import { useFormik } from "formik"; +import * as Yup from "yup"; +import { Grid } from "../../../../components/grid/Grid"; +import { useDispatch } from "react-redux"; +import { AppContext } from "../../../../contexts/AppContext"; +import { provinceJahadEditAllocationService } from "../../services/province-jahad-submit-allocation"; +import { CLOSE_MODAL } from "../../../../lib/redux/slices/appSlice"; +import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl"; + +export const ProvinceJahadUnionSubmitRealWeight = ({ + item, + updateTable, + getDashboardData, +}) => { + const validationSchema = Yup.object({ + factory: Yup.string(), + weight: Yup.number() + .required("وزن الزامی است") + .positive("وزن باید مثبت باشد"), + billOfLadingCode: Yup.string(), + }); + + const dispatch = useDispatch(); + const [openNotif] = useContext(AppContext); + + const formik = useFormik({ + initialValues: { + factory: "", + weight: item?.weight || "", + billOfLadingCode: "", + }, + validationSchema: validationSchema, + onSubmit: (values) => { + let req = { + state: "accepted", + code: values.billOfLadingCode, + place: values.factory, + role: getRoleFromUrl(), + allocation_key: item?.key, + }; + + dispatch(provinceJahadEditAllocationService(req)).then((r) => { + if (r.payload.error) { + openNotif({ + vertical: "top", + horizontal: "center", + msg: r.payload.error, + severity: "error", + }); + } else { + openNotif({ + vertical: "top", + horizontal: "center", + msg: "عملیات با موفقیت انجام شد.", + severity: "success", + }); + dispatch(CLOSE_MODAL()); + updateTable(); + getDashboardData(); + } + }); + }, + }); + + useEffect(() => { + formik.validateForm(); + }, []); + + return ( + + + + + + + + + + + + + + + + ); +}; diff --git a/src/features/province-jahad/components/province-jahad-unions-operations/ProvinceJahadUnionsOperations.js b/src/features/province-jahad/components/province-jahad-unions-operations/ProvinceJahadUnionsOperations.js new file mode 100644 index 0000000..806726b --- /dev/null +++ b/src/features/province-jahad/components/province-jahad-unions-operations/ProvinceJahadUnionsOperations.js @@ -0,0 +1,192 @@ +import { + Button, + FormControlLabel, + IconButton, + Popover, + Switch, + Tooltip, +} from "@mui/material"; +import { useContext, useState } from "react"; +import TuneIcon from "@mui/icons-material/Tune"; +import EditIcon from "@mui/icons-material/Edit"; +import { Grid } from "../../../../components/grid/Grid"; +import { + CLOSE_MODAL, + DRAWER, + OPEN_MODAL, +} from "../../../../lib/redux/slices/appSlice"; +import { useDispatch } from "react-redux"; +import DeleteIcon from "@mui/icons-material/Delete"; +import { AppContext } from "../../../../contexts/AppContext"; +import { provinceJahadDeleteUnionsService } from "../../services/province-jahad-unions-delete-union"; +import { ProvinceJahadUnionsSubmit } from "../province-jahad-unions-submit/ProvinceJahadUnionsSubmit"; +import { provinceJahadUpdateUnionService } from "../../services/province-jahad-edit-union"; + +export const ProvinceJahadUnionsOperations = ({ item, updateTable }) => { + const dispatch = useDispatch(); + const [popoverOpen, setPopoverOpen] = useState(false); + const [anchorEl, setAnchorEl] = useState(null); + const [openNotif] = useContext(AppContext); + + const openPopover = (event) => { + setPopoverOpen(true); + setAnchorEl(event.currentTarget); + }; + + const closePopover = () => { + setPopoverOpen(false); + setAnchorEl(null); + }; + + return ( + + + + + +
    + + + { + closePopover(); + dispatch( + DRAWER({ + right: true, + top: false, + content: ( + + ), + title: "ویرایش اتحادیه ", + }) + ); + }} + > + + + + { + dispatch( + provinceJahadUpdateUnionService({ + union_key: item?.key, + active: !item?.active, + }) + ).then((r) => { + if (r.payload.error) { + openNotif({ + vertical: "top", + horizontal: "center", + msg: r.payload.error, + severity: "error", + }); + } else { + updateTable(); + openNotif({ + vertical: "top", + horizontal: "center", + msg: "عملیات با موفقیت انجام شد.", + severity: "success", + }); + } + }); + }} + color="primary" + /> + } + label={item?.active ? "فعال" : "غیرفعال"} + style={{ + justifyContent: "center", + alignItems: "center", + display: "flex", + }} + /> + + + { + closePopover(); + dispatch( + OPEN_MODAL({ + title: "آیا مطمئن هستید؟", + content: ( + + + + + ), + }) + ); + }} + > + + + + +
    +
    +
    + ); +}; diff --git a/src/features/province-jahad/components/province-jahad-unions-submit/ProvinceJahadUnionsSubmit.js b/src/features/province-jahad/components/province-jahad-unions-submit/ProvinceJahadUnionsSubmit.js new file mode 100644 index 0000000..843bd34 --- /dev/null +++ b/src/features/province-jahad/components/province-jahad-unions-submit/ProvinceJahadUnionsSubmit.js @@ -0,0 +1,303 @@ +import React, { useContext, useEffect, useState } from "react"; +import { useFormik } from "formik"; +import * as Yup from "yup"; +import { + Grid, + TextField, + Button, + Autocomplete, + Typography, +} from "@mui/material"; + +import { useDispatch } from "react-redux"; +import { AppContext } from "../../../../contexts/AppContext"; +import { + DRAWER, + LOADING_END, + LOADING_START, +} from "../../../../lib/redux/slices/appSlice"; +import { cityGetProvinces } from "../../../city/services/CityGetProvinces"; +import { cityGetCity } from "../../../city/services/city-get-city"; +import { + provinceJahadSubmitUnionService, + provinceJahadUpdateUnionService, +} from "../../services/province-jahad-edit-union"; +import { SPACING } from "../../../../data/spacing"; + +export const ProvinceJahadUnionsSubmit = ({ updateTable, item }) => { + const [provinceData, setProvinceData] = useState([]); + const [cityData, setCityData] = useState([]); + const [provinceKey, setProvinceKey] = useState(); + const [cityKey, setCityKey] = useState(); + const [isExistProvince, setIsExistProvince] = useState(true); + const [openNotif] = useContext(AppContext); + + const dispatch = useDispatch(); + + const validationSchema = Yup.object().shape({ + name: Yup.string().required("این فیلد الزامی است"), + first_name: Yup.string().required("این فیلد الزامی است"), + last_name: Yup.string().required("این فیلد الزامی است"), + address: Yup.string().required("این فیلد الزامی است"), + nationalId: Yup.string() + .matches(/^\d+$/, "لطفا فقط عدد وارد کنید") + .length(10, "کد ملی باید ۱۰ رقم باشد") + .required("این فیلد الزامی است"), + postalCode: Yup.string() + .matches(/^\d+$/, "لطفا فقط عدد وارد کنید") + .length(10, "کد پستی باید ۱۰ رقم باشد") + .required("این فیلد الزامی است"), + mobile: Yup.string() + .matches(/^\d+$/, "لطفا فقط عدد وارد کنید") + .length(11, "شماره موبایل باید ۱۱ رقم باشد") + .required("این فیلد الزامی است"), + }); + + useEffect(() => { + dispatch(LOADING_START()); + dispatch(cityGetProvinces())?.then((r) => { + dispatch(LOADING_END()); + setProvinceData(r.payload.data); + }); + }, []); + + useEffect(() => { + dispatch(LOADING_END()); + if (provinceKey) { + dispatch(LOADING_START()); + dispatch(cityGetCity(provinceKey)).then((r) => { + setCityData(r.payload.data); + setIsExistProvince(false); + dispatch(LOADING_END()); + }); + } + }, [provinceKey]); + + const formik = useFormik({ + initialValues: { + name: item?.name || "", + first_name: item?.user?.firstName || "", + last_name: item?.user?.lastName || "", + mobile: item?.user?.mobile || "", + address: item?.address?.address || "", + nationalId: item?.nationalId || "", + postalCode: item?.address?.postalCode || "", + }, + validationSchema, + enableReinitialize: true, + onSubmit: (values) => { + if (item) { + dispatch( + provinceJahadUpdateUnionService({ + union_key: item?.key, + first_name: values.first_name, + last_name: values.last_name, + name: values.name, + address: values.address, + mobile: values.mobile, + national_id: values.nationalId, + postal_code: values.postalCode, + city: cityKey || item?.address?.city?.name, + }) + ).then((r) => { + if (r.payload.error) { + openNotif({ + vertical: "top", + horizontal: "center", + msg: r.payload.error, + severity: "error", + }); + } else { + openNotif({ + vertical: "top", + horizontal: "center", + msg: "عملیات با موفقیت انجام شد.", + severity: "success", + }); + dispatch(DRAWER({ right: false, bottom: false, content: null })); + + updateTable(); + } + }); + } else { + dispatch( + provinceJahadSubmitUnionService({ + first_name: values.first_name, + last_name: values.last_name, + name: values.name, + address: values.address, + mobile: values.mobile, + national_id: values.nationalId, + postal_code: values.postalCode, + city: cityKey || item?.address?.city?.name, + }) + ).then((r) => { + if (r.payload.error) { + openNotif({ + vertical: "top", + horizontal: "center", + msg: r.payload.error, + severity: "error", + }); + } else { + openNotif({ + vertical: "top", + horizontal: "center", + msg: "عملیات با موفقیت انجام شد.", + severity: "success", + }); + dispatch(DRAWER({ right: false, bottom: false, content: null })); + + updateTable(); + } + }); + } + }, + }); + + const isFormValid = () => { + if (item) { + return formik.isValid; + } else { + return formik.isValid && cityKey; + } + }; + + return ( + +
    + + + + ({ + id: i.key, + label: i.name, + }))} + onChange={(e, value) => { + setProvinceKey(value.id); + }} + renderInput={(params) => ( + + )} + /> + + ({ + id: i.key, + label: i.name, + }))} + onChange={(e, value) => { + setCityKey(value.label); + }} + renderInput={(params) => ( + + )} + /> + {item && !cityKey && ( + + شهر: {item?.address?.city?.name} + + )} + + + + + + + + + + + + + + + +
    +
    + ); +}; diff --git a/src/features/province-jahad/components/province-jahad-unions/ProvinceJahadUnions.js b/src/features/province-jahad/components/province-jahad-unions/ProvinceJahadUnions.js new file mode 100644 index 0000000..b4c986f --- /dev/null +++ b/src/features/province-jahad/components/province-jahad-unions/ProvinceJahadUnions.js @@ -0,0 +1,169 @@ +import React, { useEffect, useState } from "react"; +import { Button, TextField } from "@mui/material"; +import axios from "axios"; +import { RiSearchLine } from "react-icons/ri"; +import { + DRAWER, + LOADING_END, + LOADING_START, +} from "../../../../lib/redux/slices/appSlice"; +import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl"; +import { Grid } from "../../../../components/grid/Grid"; +import ResponsiveTable from "../../../../components/responsive-table/ResponsiveTable"; +import { useDispatch } from "react-redux"; +import { ProvinceJahadUnionsOperations } from "../province-jahad-unions-operations/ProvinceJahadUnionsOperations"; +import { ProvinceJahadUnionsSubmit } from "../province-jahad-unions-submit/ProvinceJahadUnionsSubmit"; + +export const ProvinceJahadUnions = () => { + const dispatch = useDispatch(); + const handleTextChange = (event) => { + setTextValue(event.target.value); + }; + + const [data, setData] = useState([]); + const [totalRows, setTotalRows] = useState(0); + const [perPage, setPerPage] = useState(10); + const [textValue, setTextValue] = useState(""); + const [page, setPage] = useState(1); + const [tableData, setTableData] = useState([]); + + const fetchApiData = async (page) => { + let response; + dispatch(LOADING_START()); + response = await axios.get( + `LiveStock/union/union-view/?search=filter&value=${textValue}&role=${getRoleFromUrl()}&page=${page}&page_size=${perPage}` + ); + + dispatch(LOADING_END()); + setData(response.data.results); + setTotalRows(response.data.count); + }; + + const handlePageChange = (page) => { + fetchApiData(page); + setPage(page); + }; + + const handlePerRowsChange = (perRows) => { + setPerPage(perRows); + setPage(1); + }; + + const updateTable = () => { + fetchApiData(page !== 0 ? page : 1); + }; + + useEffect(() => { + const d = data?.map((item, i) => { + return [ + page === 1 ? i + 1 : i + perPage * (page - 1) + 1, + item?.name, + item?.user.fullname, + item?.user.provinceName, + item?.user.cityName, + item?.user.mobile, + item?.nationalId, + , + ]; + }); + + setTableData(d); + }, [data]); + + useEffect(() => { + fetchApiData(1); + }, [dispatch, perPage]); + + const handleSubmit = async (event) => { + event.preventDefault(); + dispatch(LOADING_START()); + + try { + const response = await axios.get( + `LiveStock/union/union-view/?search=filter&value=${textValue}&role=${getRoleFromUrl()}&page=${page}&page_size=${perPage}` + ); + setData(response.data.results); + setTotalRows(response.data.count); + dispatch(LOADING_END()); + } catch (error) { + console.error("Error fetching data:", error); + } + }; + + return ( + + + + + +
    + + + +
    +
    + + +
    + ); +}; diff --git a/src/features/province-jahad/components/province-jahad-users/ProvinceJahadUsers.js b/src/features/province-jahad/components/province-jahad-users/ProvinceJahadUsers.js new file mode 100644 index 0000000..8b2c9e7 --- /dev/null +++ b/src/features/province-jahad/components/province-jahad-users/ProvinceJahadUsers.js @@ -0,0 +1,5 @@ +import React from "react"; + +export const ProvinceJahadUsers = () => { + return
    این بخش در دست توسعه است
    ; +}; diff --git a/src/features/province-jahad/services/province-get-jahad-sell-report-dashboard.js b/src/features/province-jahad/services/province-get-jahad-sell-report-dashboard.js new file mode 100644 index 0000000..4e2acf6 --- /dev/null +++ b/src/features/province-jahad/services/province-get-jahad-sell-report-dashboard.js @@ -0,0 +1,20 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const provinceJahadSellReportInfoDashboardService = createAsyncThunk( + "PROVINCE_JAHAD_GET_SELL_REPORT_INFO_DASHBOARD_SERVICE", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + const { data, status } = await axios.get( + "/cooperative-warehouse-dashboard", + { + params: { + ...d, + }, + } + ); + dispatch(LOADING_END()); + return { data, status }; + } +); diff --git a/src/features/province-jahad/services/province-jahad-delete-herd.js b/src/features/province-jahad/services/province-jahad-delete-herd.js new file mode 100644 index 0000000..2a9e04e --- /dev/null +++ b/src/features/province-jahad/services/province-jahad-delete-herd.js @@ -0,0 +1,20 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const provinceJahadDeleteHerdService = createAsyncThunk( + "PROVINCE-JAHAD-DELETE-HERD-SERVICE", + async (id, { dispatch }) => { + dispatch(LOADING_START()); + try { + const { data, status } = await axios.delete( + "/LiveStock/union/union-view/0/?key=" + id + ); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e.response.data.result }; + } + } +); diff --git a/src/features/province-jahad/services/province-jahad-edit-union.js b/src/features/province-jahad/services/province-jahad-edit-union.js new file mode 100644 index 0000000..df43b86 --- /dev/null +++ b/src/features/province-jahad/services/province-jahad-edit-union.js @@ -0,0 +1,39 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const provinceJahadUpdateUnionService = createAsyncThunk( + "PROVINCE_JAHAD_UPDATE_PRODUCT_SERVICE", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + try { + const { data, status } = await axios.put( + "LiveStock/union/union-view/0/", + d + ); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e.response.data.result }; + } + } +); + +export const provinceJahadSubmitUnionService = createAsyncThunk( + "PROVINCE_JAHAD_SUBMIT_PRODUCT_SERVICE", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + try { + const { data, status } = await axios.post( + "LiveStock/union/union-view/", + d + ); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e.response.data.result }; + } + } +); diff --git a/src/features/province-jahad/services/province-jahad-get-cooperatives-pos.js b/src/features/province-jahad/services/province-jahad-get-cooperatives-pos.js new file mode 100644 index 0000000..c2befac --- /dev/null +++ b/src/features/province-jahad/services/province-jahad-get-cooperatives-pos.js @@ -0,0 +1,15 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const provinceJahadGetCooperativesPosInfoService = createAsyncThunk( + "PROVINCE_JAHAD_GET_COOPERATIVES_POS_INFO", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + const { data, status } = await axios.get( + `/cooperative-pos/?cooperative_key=${d}` + ); + dispatch(LOADING_END()); + return { data, status }; + } +); diff --git a/src/features/province-jahad/services/province-jahad-get-distribution-info.js b/src/features/province-jahad/services/province-jahad-get-distribution-info.js new file mode 100644 index 0000000..6cdfa3c --- /dev/null +++ b/src/features/province-jahad/services/province-jahad-get-distribution-info.js @@ -0,0 +1,33 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const provinceJahadGetDistributionInfoService = createAsyncThunk( + "PROVINCE_JAHAD_GET_DISTRIBUTION_INFO", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + const { data, status } = await axios.get( + `LiveStock/jahad/dashboard-live-stock-allocation/`, + { + params: d, + } + ); + dispatch(LOADING_END()); + return { data, status }; + } +); + +export const provinceJahadGetInventoryDataService = createAsyncThunk( + "PROVINCE_JAHAD_GET_INVENTORY_INFO", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + const { data, status } = await axios.get( + `LiveStock/jahad/live-stock-role-products/`, + { + params: d, + } + ); + dispatch(LOADING_END()); + return { data, status }; + } +); diff --git a/src/features/province-jahad/services/province-jahad-get-herd-dashbored.js b/src/features/province-jahad/services/province-jahad-get-herd-dashbored.js new file mode 100644 index 0000000..ccc044f --- /dev/null +++ b/src/features/province-jahad/services/province-jahad-get-herd-dashbored.js @@ -0,0 +1,24 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; +import { getRoleFromUrl } from "../../../utils/getRoleFromUrl"; + +export const provinceJahadGetHerdInfoDashboardService = createAsyncThunk( + "PROVINCE_JAHAD_GET_HERD_INFO_DASHBOARD_SERVICE", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + const { data, status } = await axios.get( + "/LiveStock/live-stock/dashboard_live_stock/", + { + params: { + role: getRoleFromUrl(), + search: "filter", + value: d.search, + type: d.type, + }, + } + ); + dispatch(LOADING_END()); + return { data, status }; + } +); diff --git a/src/features/province-jahad/services/province-jahad-get-product-info.js b/src/features/province-jahad/services/province-jahad-get-product-info.js new file mode 100644 index 0000000..ce94369 --- /dev/null +++ b/src/features/province-jahad/services/province-jahad-get-product-info.js @@ -0,0 +1,20 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const provinceJahadGetProductInfoService = createAsyncThunk( + "PROVINCE_JAHAD_GET_PRODUCT_INFO", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + const { data, status } = await axios.get( + `LiveStock/jahad/live-stock-product/`, + { + params: { + name: d.product, + }, + } + ); + dispatch(LOADING_END()); + return { data, status }; + } +); diff --git a/src/features/province-jahad/services/province-jahad-get-rancher-dashbored.js b/src/features/province-jahad/services/province-jahad-get-rancher-dashbored.js new file mode 100644 index 0000000..4eb95f3 --- /dev/null +++ b/src/features/province-jahad/services/province-jahad-get-rancher-dashbored.js @@ -0,0 +1,23 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; +import { getRoleFromUrl } from "../../../utils/getRoleFromUrl"; + +export const provinceJahadGetRancherInfoDashboardService = createAsyncThunk( + "PROVINCE_JAHAD_GET_RANCHERD_INFO_DASHBOARD_SERVICE", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + const { data, status } = await axios.get( + "/LiveStock/rancher/dashboard_rancher", + { + params: { + role: getRoleFromUrl(), + search: "filter", + value: d.search, + }, + } + ); + dispatch(LOADING_END()); + return { data, status }; + } +); diff --git a/src/features/province-jahad/services/province-jahad-get-rancher-details.js b/src/features/province-jahad/services/province-jahad-get-rancher-details.js new file mode 100644 index 0000000..31e321a --- /dev/null +++ b/src/features/province-jahad/services/province-jahad-get-rancher-details.js @@ -0,0 +1,20 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const provinceJahadGetRancherDetailsService = createAsyncThunk( + "PROVINCE_JAHAD_GET_PRODUCT_INFO", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + const { data, status } = await axios.get( + `LiveStock/rancher/get_detail_rancher/`, + { + params: { + herd_code: d.herd_code, + }, + } + ); + dispatch(LOADING_END()); + return { data, status }; + } +); diff --git a/src/features/province-jahad/services/province-jahad-get-single-rancher.js b/src/features/province-jahad/services/province-jahad-get-single-rancher.js new file mode 100644 index 0000000..2571fdc --- /dev/null +++ b/src/features/province-jahad/services/province-jahad-get-single-rancher.js @@ -0,0 +1,23 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; +import { getRoleFromUrl } from "../../../utils/getRoleFromUrl"; + +export const provinceJahadGetSingleRancherService = createAsyncThunk( + "PROVINCE_JAHAD_GET_SINGLE_RANCHER", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + const { data, status } = await axios.get( + `LiveStock/rancher/rancher-view/`, + { + params: { + value: d.value, + search: "filter", + role: getRoleFromUrl(), + }, + } + ); + dispatch(LOADING_END()); + return { data, status }; + } +); diff --git a/src/features/province-jahad/services/province-jahad-get-transaction-dashboard.js b/src/features/province-jahad/services/province-jahad-get-transaction-dashboard.js new file mode 100644 index 0000000..d9acc47 --- /dev/null +++ b/src/features/province-jahad/services/province-jahad-get-transaction-dashboard.js @@ -0,0 +1,20 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; +import axios from "axios"; + +export const provinceJahadGetTransactionInfoDashboardService = createAsyncThunk( + "PROVINCE_JAHAD_GET_TRANSACTION_INFO_DASHBOARD_SERVICE", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + const { data, status } = await axios.get( + "/live-stock-transactions-dashboard", + { + params: { + ...d, + }, + } + ); + dispatch(LOADING_END()); + return { data, status }; + } +); diff --git a/src/features/province-jahad/services/province-jahad-rancher-activation.js b/src/features/province-jahad/services/province-jahad-rancher-activation.js new file mode 100644 index 0000000..7c29d94 --- /dev/null +++ b/src/features/province-jahad/services/province-jahad-rancher-activation.js @@ -0,0 +1,39 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const provinceJahadEditRancher = createAsyncThunk( + "PROVINCE_JAHAD_RANCHER_ACTIVATION", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + try { + const { data, status } = await axios.put( + "LiveStock/rancher/rancher-view/0/", + d + ); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e.response.data.result }; + } + } +); + +export const provinceJahadSubmitRancher = createAsyncThunk( + "PROVINCE_JAHAD_SUBMIT_RANCHER", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + try { + const { data, status } = await axios.post( + "LiveStock/rancher/rancher-view/", + d + ); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e.response.data.result }; + } + } +); diff --git a/src/features/province-jahad/services/province-jahad-submit-allocation-get-users.js b/src/features/province-jahad/services/province-jahad-submit-allocation-get-users.js new file mode 100644 index 0000000..a7d479e --- /dev/null +++ b/src/features/province-jahad/services/province-jahad-submit-allocation-get-users.js @@ -0,0 +1,18 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const provinceJahadSubmitAllocationGetUsers = createAsyncThunk( + "SLAUGHTER_GET_GUILDS_FOR_ALLOCATE_SERVICE", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + const { data, status } = await axios.get( + "LiveStock/jahad/get_user_live_stock/", + { + params: d, + } + ); + dispatch(LOADING_END()); + return { data, status }; + } +); diff --git a/src/features/province-jahad/services/province-jahad-submit-allocation.js b/src/features/province-jahad/services/province-jahad-submit-allocation.js new file mode 100644 index 0000000..21dfbe5 --- /dev/null +++ b/src/features/province-jahad/services/province-jahad-submit-allocation.js @@ -0,0 +1,56 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const provinceJahadSubmitAllocationService = createAsyncThunk( + "PROVINCE_JAHAD_SUBMIT_ALLOCATION_SERVICE", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + try { + const { data, status } = await axios.post( + "LiveStock/jahad/live-stock-allocation/", + d + ); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e.response.data.result }; + } + } +); + +export const provinceJahadEditAllocationService = createAsyncThunk( + "PROVINCE_JAHAD_EDIT_ALLOCATION_SERVICE", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + try { + const { data, status } = await axios.put( + "/LiveStock/jahad/live-stock-allocation/0/", + d + ); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e.response.data.result }; + } + } +); + +export const provinceJahadDeleteAllocationService = createAsyncThunk( + "PROVINCE_JAHAD_DELETE_ALLOCATION", + async (id, { dispatch }) => { + dispatch(LOADING_START()); + try { + const { data, status } = await axios.delete( + "LiveStock/jahad/live-stock-allocation/0/?allocation_key=" + id + ); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e.response.data.result }; + } + } +); diff --git a/src/features/province-jahad/services/province-jahad-submit-cooperatives.js b/src/features/province-jahad/services/province-jahad-submit-cooperatives.js new file mode 100644 index 0000000..cd77368 --- /dev/null +++ b/src/features/province-jahad/services/province-jahad-submit-cooperatives.js @@ -0,0 +1,39 @@ +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; +import { createAsyncThunk } from "@reduxjs/toolkit"; + +export const provinceJahadEditCooperativeService = createAsyncThunk( + "PROVINCE_JAHAD_SUBMIT_COOPERATIVE_SERVICE", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + try { + const { data, status } = await axios.put( + "/LiveStock/cooperative/cooperative-views/0/", + d + ); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e.response.data.result }; + } + } +); + +export const provinceJahadSubmitCooperativeService = createAsyncThunk( + "PROVINCE_JAHAD_SUBMIT_COOPERATIVE_SERVICE", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + try { + const { data, status } = await axios.post( + "/LiveStock/cooperative/cooperative-views/", + d + ); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e.response.data.result }; + } + } +); diff --git a/src/features/province-jahad/services/province-jahad-submit-herd.js b/src/features/province-jahad/services/province-jahad-submit-herd.js new file mode 100644 index 0000000..2f224e7 --- /dev/null +++ b/src/features/province-jahad/services/province-jahad-submit-herd.js @@ -0,0 +1,56 @@ +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; +import { createAsyncThunk } from "@reduxjs/toolkit"; + +export const provinceJahadEditHerdService = createAsyncThunk( + "PROVINCE_JAHAD_EDIT_HERD_SERVICE", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + try { + const { data, status } = await axios.put( + "/LiveStock/live-stock/live-stock-view/0/", + d + ); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e.response.data.result }; + } + } +); + +export const provinceJahadSubmitHerdService = createAsyncThunk( + "PROVINCE_JAHAD_SUBMIT_HERD_SERVICE", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + try { + const { data, status } = await axios.post( + "/LiveStock/live-stock/live-stock-view/", + d + ); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e.response.data.result }; + } + } +); + +export const provinceJahadDeleteHerdService = createAsyncThunk( + "PROVINCE-JAHAD-DELETE-HERD-SERVICE", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + try { + const { data, status } = await axios.delete( + `/LiveStock/live-stock/live-stock-view/0/?live_stock_key=${d.live_stock_key}` + ); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e.response?.data?.result || "خطا در بایگانی گله" }; + } + } +); diff --git a/src/features/province-jahad/services/province-jahad-submit-share.js b/src/features/province-jahad/services/province-jahad-submit-share.js new file mode 100644 index 0000000..52d202e --- /dev/null +++ b/src/features/province-jahad/services/province-jahad-submit-share.js @@ -0,0 +1,21 @@ +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; +import { createAsyncThunk } from "@reduxjs/toolkit"; + +export const provinceJahadSubmitShareService = createAsyncThunk( + "PROVINCE_JAHAD_SUBMIT_SHARE_SERVICE", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + try { + const { data, status } = await axios.put( + "/LiveStock/jahad/cooperative-shares/0/", + d + ); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e.response.data.result }; + } + } +); diff --git a/src/features/province-jahad/services/province-jahad-unions-delete-rancher.js b/src/features/province-jahad/services/province-jahad-unions-delete-rancher.js new file mode 100644 index 0000000..40c2a54 --- /dev/null +++ b/src/features/province-jahad/services/province-jahad-unions-delete-rancher.js @@ -0,0 +1,20 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const provinceJahadDeleteRancherService = createAsyncThunk( + "PROVINCE-JAHAD-DELETE-RANCHER-SERVICE", + async (id, { dispatch }) => { + dispatch(LOADING_START()); + try { + const { data, status } = await axios.delete( + "/LiveStock/rancher/rancher-view/0/?rancher_key=" + id + ); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e.response.data.result }; + } + } +); diff --git a/src/features/province-jahad/services/province-jahad-unions-delete-union.js b/src/features/province-jahad/services/province-jahad-unions-delete-union.js new file mode 100644 index 0000000..5c7c71d --- /dev/null +++ b/src/features/province-jahad/services/province-jahad-unions-delete-union.js @@ -0,0 +1,20 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const provinceJahadDeleteUnionsService = createAsyncThunk( + "PROVINCE-JAHAD-DELETE-UNIONS-SERVICE", + async (id, { dispatch }) => { + dispatch(LOADING_START()); + try { + const { data, status } = await axios.delete( + "/LiveStock/union/union-view/0/?key=" + id + ); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e.response.data.result }; + } + } +); diff --git a/src/features/province-jahad/services/province-jahad-unions-submit.js b/src/features/province-jahad/services/province-jahad-unions-submit.js new file mode 100644 index 0000000..d941eb0 --- /dev/null +++ b/src/features/province-jahad/services/province-jahad-unions-submit.js @@ -0,0 +1,21 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const provinceJahadUnionsSubmitService = createAsyncThunk( + "PROVINCE_JAHAD_UNIONS_SUBMIT_SERVICE", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + try { + const { data, status } = await axios.put( + "/LiveStock/union/union-view/0/", + d + ); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e.response.data.result }; + } + } +); diff --git a/src/features/province-jahad/services/province-jahad-update-dhi-amount.js b/src/features/province-jahad/services/province-jahad-update-dhi-amount.js new file mode 100644 index 0000000..e69de29 diff --git a/src/features/province-jahad/services/province-jahad-update-product.js b/src/features/province-jahad/services/province-jahad-update-product.js new file mode 100644 index 0000000..de81814 --- /dev/null +++ b/src/features/province-jahad/services/province-jahad-update-product.js @@ -0,0 +1,21 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const provinceJahadUpdateProductService = createAsyncThunk( + "PROVINCE_JAHAD_UPDATE_PRODUCT_SERVICE", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + try { + const { data, status } = await axios.put( + "LiveStock/jahad/live-stock-product/0/", + d + ); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e.response.data.result }; + } + } +); diff --git a/src/features/province/components/broadcast-management-operations/BroadcastManagementOperations.js b/src/features/province/components/broadcast-management-operations/BroadcastManagementOperations.js new file mode 100644 index 0000000..4a101b0 --- /dev/null +++ b/src/features/province/components/broadcast-management-operations/BroadcastManagementOperations.js @@ -0,0 +1,74 @@ +import { MdCorporateFare } from "react-icons/md"; +import { Grid } from "../../../../components/grid/Grid"; +import LinkItem from "../../../../components/link-item/LinkItem"; +import { NavLink } from "../../../../components/nav-link/NavLink"; +import { SPACING } from "../../../../data/spacing"; +import { + ROUTE_ADMINX_ROUTE_AGENT_SHARE, + ROUTE_ADMINX_ROUTE_STEWARD_SHARE, + ROUTE_PROVINCE_ROUTE_AGENT_SHARE, + ROUTE_PROVINCE_ROUTE_STEWARD_SHARE, + ROUTE_SUPER_ADMIN_ROUTE_AGENT_SHARE, + ROUTE_SUPER_ADMIN_ROUTE_STEWARD_SHARE, +} from "../../../../routes/routes"; +import { Typography } from "@mui/material"; +import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl"; + +const getRouteByRole = (isAgentRoute) => { + const role = getRoleFromUrl(); + + if (role === "SuperAdmin") { + if (isAgentRoute) { + return ROUTE_SUPER_ADMIN_ROUTE_AGENT_SHARE; + } + return ROUTE_SUPER_ADMIN_ROUTE_STEWARD_SHARE; + } + + if (role === "AdminX") { + if (isAgentRoute) { + return ROUTE_ADMINX_ROUTE_AGENT_SHARE; + } + return ROUTE_ADMINX_ROUTE_STEWARD_SHARE; + } + + if (isAgentRoute) { + return ROUTE_PROVINCE_ROUTE_AGENT_SHARE; + } + return ROUTE_PROVINCE_ROUTE_STEWARD_SHARE; +}; + +export const BroadcastManagementOperations = () => { + return ( + + + } + title={ + <> + گزارش پخش روزانه + کشتارگاه به مباشر/ صنف + + } + /> + + + + } + title={ + <> + گزارش پخش روزانه + مباشر به صنف + + } + /> + + + ); +}; diff --git a/src/features/province/components/chain-archive-chains/ChainsArchiveChains.js b/src/features/province/components/chain-archive-chains/ChainsArchiveChains.js new file mode 100644 index 0000000..5b6c8a9 --- /dev/null +++ b/src/features/province/components/chain-archive-chains/ChainsArchiveChains.js @@ -0,0 +1,264 @@ +import { Button, TextField, Tooltip, Typography } from "@mui/material"; +import axios from "axios"; +import { useEffect, useState } from "react"; +import { RiFileExcel2Fill, RiSearchLine } from "react-icons/ri"; +import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl"; +import { CityHatchingsArchiveOperations } from "../../../city/components/city-hatchings-archive-operations/CityHatchingsArchiveOperations"; +import { formatTime } from "../../../../utils/formatTime"; +import { Grid } from "../../../../components/grid/Grid"; +import { SPACING } from "../../../../data/spacing"; +import ResponsiveTable from "../../../../components/responsive-table/ResponsiveTable"; +import { getFaUserRole } from "../../../../utils/getFaUserRole"; +import { useSelector } from "react-redux"; + +const OperationsCell = ({ item, updateArchive, readOnly }) => ( + +); + +export const ChainsArchiveChains = ({ readOnly }) => { + readOnly = readOnly || false; + const [data, setData] = useState([]); + const [tableData, setTableData] = useState([]); + const [totalRows, setTotalRows] = useState(0); + const [perPage, setPerPage] = useState(10); + const [page, setPage] = useState(1); + + const [textValue, setTextValue] = useState(""); + const userKey = useSelector((state) => state.userSlice.userProfile.key); + + const handleTextChange = (event) => { + setTextValue(event.target.value); + }; + + const fetchApiData = async (page, textValue) => { + let response; + if (textValue) { + response = await axios.get( + `poultry_hatching/?archive=true&search=filter&value=${textValue}&role=${getRoleFromUrl()}&page=${page}&page_size=&chain=true` + ); + } else { + response = await axios.get( + `poultry_hatching/?archive=true&role=${getRoleFromUrl()}&page=${page}&page_size=${perPage}&chain=true` + ); + } + setData(response.data.results); + setTotalRows(response.data.count); + }; + + const handlePageChange = (pageNum) => { + setPage(pageNum); + fetchApiData(pageNum, textValue); + }; + + const handlePerRowsChange = (newPerPage) => { + setPerPage(Number(newPerPage)); + setPage(1); + }; + + useEffect(() => { + if (perPage) { + fetchApiData(1, textValue); + } + }, [perPage]); + + useEffect(() => { + fetchApiData(1, ""); + }, []); + + const columns = [ + "عملیات", + "ردیف", + "شرکت زنجیره", + "وضعیت", + "نام فارم", + "مرغدار", + "شهر/تعاونی", + "دامپزشک فارم", + "سالن", + "دوره جوجه ریزی", + "تاریخ ثبت جوجه ریزی", + "تاریخ جوجه ریزی", + "نژاد", + "سن", + "تعداد جوجه ریزی", + "تلفات دوره", + "حجم خارج از استان", + "وزن کشتار شده دولتی", + "وزن کشتار شده آزاد ", + "وزن خارج از استان", + "حخم کشتار زنجیره (قطعه)", + "وزن کشتار زنجیره (کیلوگرم)", + "کشتار شده", + "مانده در سالن", + "کشتار فعال", + "تعداد درخواست کشتار", + "آخرین تغییر", + ]; + + useEffect(() => { + if (!data || !Array.isArray(data)) { + setTableData([]); + return; + } + + const transformedData = data.map((item, i) => { + const killedNumber = item?.quantity - item?.losses - item?.leftOver; + const lastChange = + item?.lastChange && + item?.lastChange?.date && + `${item?.lastChange?.fullName} (${getFaUserRole( + item?.lastChange?.role + )}) در تاریخ ${formatTime(item?.lastChange?.date)}`; + + return [ + fetchApiData(pageNum || page, textValue)} + readOnly={readOnly} + />, + page === 1 ? i + 1 : i + perPage * (page - 1) + 1, + item?.chainCompany?.name && item?.chainCompany?.user?.mobile + ? `${item.chainCompany.name} (${item.chainCompany.user.mobile})` + : "-", + + {item?.violation ? "متخلف" : "عادی"} + , + item?.poultry?.unitName || "-", + item?.poultry?.userprofile?.fullName && + item?.poultry?.userprofile?.mobile + ? `${item.poultry.userprofile.fullName} (${item.poultry.userprofile.mobile})` + : "-", + item?.poultry?.address?.city?.name + ? `${item.poultry.address.city.name}/${ + item?.poultry?.cityOperator + ? item.poultry.cityOperator + : "بدون تعاونی" + }` + : "-", + item?.vetFarm?.vetFarmMobile + ? `${item.vetFarm.vetFarmFullName} (${item.vetFarm.vetFarmMobile})` + : "-", + item?.hall || "-", + item?.period || "-", + formatTime(item?.createDate) || "-", + formatTime(item?.date) || "-", + item?.chickenBreed || "-", + item?.age || "-", + item?.quantity ? item.quantity.toLocaleString() : "-", + item?.losses && item?.quantity + ? `${item.losses} (%${((item.losses * 100) / item.quantity).toFixed( + 0 + )})` + : "-", + item?.outProvinceKilledQuantity + ? item.outProvinceKilledQuantity.toLocaleString() + : "-", + item?.governmentalKilledQuantity + ? item.governmentalKilledQuantity.toLocaleString() + : "-", + item?.freeKilledQuantity + ? item.freeKilledQuantity.toLocaleString() + : "-", + item?.outProvinceKilledWeight + ? item.outProvinceKilledWeight.toLocaleString() + : "-", + item?.chainKilledQuantity + ? item.chainKilledQuantity.toLocaleString() + : "-", + item?.chainKilledWeight ? item.chainKilledWeight.toLocaleString() : "-", + item?.quantity && killedNumber !== undefined + ? `${killedNumber.toLocaleString()} (%${( + (killedNumber * 100) / + item.quantity + ).toFixed(0)})` + : "-", + item?.leftOver && item?.quantity + ? `${item.leftOver.toLocaleString()} (%${( + (item.leftOver * 100) / + item.quantity + ).toFixed(0)})` + : "-", + item?.activeKill?.activeKill ? "دارد" : "ندارد", + item?.activeKill?.countOfRequest || "-", + lastChange || "-", + ]; + }); + + setTableData(transformedData); + }, [data, page, perPage, textValue, readOnly]); + + const handleSubmit = async (event) => { + event.preventDefault(); + setPage(1); + fetchApiData(1, textValue); + }; + + const tableTitle = ( + + + آرشیو جوجه ریزی +
    + + + + + + + + +
    +
    + ); + + return ( + + + + ); +}; diff --git a/src/features/province/components/chain-bar-management-edit-health-code/ChainBarManagementEditHealthCode.js b/src/features/province/components/chain-bar-management-edit-health-code/ChainBarManagementEditHealthCode.js new file mode 100644 index 0000000..2473d14 --- /dev/null +++ b/src/features/province/components/chain-bar-management-edit-health-code/ChainBarManagementEditHealthCode.js @@ -0,0 +1,112 @@ +import { Button, IconButton, TextField, Typography } from "@mui/material"; +import { useContext, useState } from "react"; +import { useDispatch } from "react-redux"; +import { AppContext } from "../../../../contexts/AppContext"; +import { Grid } from "../../../../components/grid/Grid"; +import EditIcon from "@mui/icons-material/Edit"; +import { provinceChainsEditAllocation } from "../../services/province-chains-edit-allocation"; +import { CLOSE_MODAL, OPEN_MODAL } from "../../../../lib/redux/slices/appSlice"; + +export const ChainBarManagementEditHealthCode = ({ + healthCode, + item, + updateTable, +}) => { + const dispatch = useDispatch(); + const [openNotif] = useContext(AppContext); + + const handleOpenModal = () => { + dispatch( + OPEN_MODAL({ + title: "ویرایش کد بهداشتی", + size: "auto", + content: ( + { + dispatch( + provinceChainsEditAllocation({ + chain_allcation_key: item?.key, + health_code: newValue, + }) + ).then((r) => { + if (r.payload?.error) { + openNotif({ + vertical: "top", + horizontal: "center", + msg: r.payload.error, + severity: "error", + }); + } else { + openNotif({ + vertical: "top", + horizontal: "center", + msg: "عملیات با موفقیت انجام شد.", + severity: "success", + }); + updateTable(); + dispatch(CLOSE_MODAL()); + } + }); + }} + onCancel={() => dispatch(CLOSE_MODAL())} + /> + ), + }) + ); + }; + + return ( + + {healthCode || "-"} + + + + + ); +}; + +const EditHealthCodeModal = ({ initialValue, onSubmit, onCancel }) => { + const [value, setValue] = useState(initialValue); + + return ( + + setValue(event.target.value)} + fullWidth + size="small" + /> + + + + + + ); +}; diff --git a/src/features/province/components/chain-bar-management-operations/ChainBarManagementOperations.js b/src/features/province/components/chain-bar-management-operations/ChainBarManagementOperations.js new file mode 100644 index 0000000..eb918cd --- /dev/null +++ b/src/features/province/components/chain-bar-management-operations/ChainBarManagementOperations.js @@ -0,0 +1,209 @@ +import { + IconButton, + Popover, + List, + ListItemButton, + ListItemIcon, + ListItemText, + Typography, +} from "@mui/material"; +import React, { useContext, useState } from "react"; +import { useDispatch } from "react-redux"; +import SettingsIcon from "@mui/icons-material/Settings"; +import TuneIcon from "@mui/icons-material/Tune"; +import DeleteIcon from "@mui/icons-material/Delete"; +import EditIcon from "@mui/icons-material/Edit"; +import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl"; +import { ChainsAllocation } from "../chains-allocation/ChainsAllocation"; +import { provinceChainsDeleteAllocation } from "../../services/province-chains-delete-allocation"; +import { AppContext } from "../../../../contexts/AppContext"; +import { ProvinceCheckChainAllocation } from "../province-check-chain-allocation/ProvinceCheckChainAllocation"; +import { DRAWER } from "../../../../lib/redux/slices/appSlice"; + +export const ChainBarManagementOperations = ({ item, fetchApiData }) => { + const dispatch = useDispatch(); + const [openNotif] = useContext(AppContext); + + const [anchorEl, setAnchorEl] = useState(null); + + const handleClick = (event) => { + setAnchorEl(event.currentTarget); + }; + + const handleClose = () => { + setAnchorEl(null); + }; + + const open = Boolean(anchorEl); + const id = open ? "popover" : undefined; + const role = getRoleFromUrl(); + + const handleApprove = () => { + handleClose(); + dispatch( + DRAWER({ + title: "تایید/ رد درخواست", + right: !(window.innerWidth <= 600), + bottom: window.innerWidth <= 600, + content: ( + + ), + }) + ); + }; + + const handleEdit = () => { + handleClose(); + dispatch( + DRAWER({ + title: "ویرایش بار", + right: !(window.innerWidth <= 600), + bottom: window.innerWidth <= 600, + content: ( + + ), + }) + ); + }; + + const handleDelete = () => { + handleClose(); + dispatch(provinceChainsDeleteAllocation(item?.key)).then((r) => { + if (r.payload.error) { + openNotif({ + vertical: "top", + horizontal: "center", + msg: r.payload.error, + severity: "error", + }); + } else { + openNotif({ + vertical: "top", + horizontal: "center", + msg: "عملیات با موفقیت انجام شد.", + severity: "success", + }); + + fetchApiData(1); + } + }); + }; + + const canManage = + role === "ProvinceOperator" || role === "SuperAdmin" || role === "AdminX"; + + const options = [ + { + key: "approve", + label: "تایید / رد درخواست", + color: "primary.main", + icon: , + action: handleApprove, + disabled: item?.state !== "pending", + }, + { + key: "edit", + label: "ویرایش بار", + color: "info.main", + icon: , + action: handleEdit, + disabled: + !canManage || + item?.state === "rejected" || + Boolean(item?.quarantineCode), + }, + { + key: "delete", + label: "حذف بار", + color: "error.main", + icon: , + action: handleDelete, + disabled: + !canManage || + item?.state === "rejected" || + Boolean(item?.quarantineCode), + }, + ]; + + return ( +
    + + + + + + {options.map((option) => ( + { + if (option.disabled) { + return; + } + option.action(); + }} + disabled={Boolean(option.disabled)} + sx={{ + borderRadius: 1, + mb: 0.5, + color: option.disabled ? "text.disabled" : option.color, + "&:last-of-type": { + mb: 0, + }, + }} + > + + {option.icon} + + + {option.label} + + } + /> + + ))} + + +
    + ); +}; diff --git a/src/features/province/components/chain-bar-management/ChainBarManagement.js b/src/features/province/components/chain-bar-management/ChainBarManagement.js new file mode 100644 index 0000000..b786a91 --- /dev/null +++ b/src/features/province/components/chain-bar-management/ChainBarManagement.js @@ -0,0 +1,506 @@ +import React, { useContext, useEffect, useState } from "react"; +import { Button, Tab, Tabs, TextField, Tooltip } from "@mui/material"; +import { DatePicker } from "@mui/x-date-pickers"; +import moment from "moment"; +import { useDispatch, useSelector } from "react-redux"; +import axios from "axios"; +import { RiFileExcel2Fill, RiSearchLine } from "react-icons/ri"; +import { + ROUTE_ADMINX_CHAINS, + ROUTE_PARENT_COMPANY_ALLOCATIONS, + ROUTE_PROVINCE_CHAINS, + ROUTE_SUPER_ADMIN_CHAINS, +} from "../../../../routes/routes"; +import { + LOADING_END, + LOADING_START, +} from "../../../../lib/redux/slices/appSlice"; +import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl"; +import { AppContext } from "../../../../contexts/AppContext"; +import { Grid } from "../../../../components/grid/Grid"; +import { SPACING } from "../../../../data/spacing"; +import { useLocation } from "react-router-dom"; +import ResponsiveTable from "../../../../components/responsive-table/ResponsiveTable"; +import { ChainBarManagementEditHealthCode } from "../chain-bar-management-edit-health-code/ChainBarManagementEditHealthCode"; +import { ChainBarManagementOperations } from "../chain-bar-management-operations/ChainBarManagementOperations"; +import { format } from "date-fns-jalali"; +import { ChainSubmitQuarantineCode } from "../chain-submit-quarantine-code/ChainSubmitQuarantineCode"; +import { formatJustDate } from "../../../../utils/formatTime"; + +export const ChainBarManagement = ({ province }) => { + const [ + openNotif, + , + selectedDate1, + setSelectedDate1, + selectedDate2, + setSelectedDate2, + ] = useContext(AppContext); + const dispatch = useDispatch(); + useEffect(() => { + const currentDate = moment(new Date()).format("YYYY-MM-DD"); + setSelectedDate1(currentDate); + setSelectedDate2(currentDate); + }, []); + + const { pathname } = useLocation(); + + const userKey = useSelector((state) => state.userSlice?.userProfile?.key); + + const handleTextChange = (event) => { + setTextValue(event.target.value); + }; + + const [value, setValue] = useState(0); + + const handleChange = (event, newValue) => { + setValue(newValue); + }; + + const [data, setData] = useState([]); + const [totalRows, setTotalRows] = useState(0); + const [perPage, setPerPage] = useState(10); + const [textValue, setTextValue] = useState(""); + const [page, setPage] = useState(1); + const [tableData, setTableData] = useState([]); + const [tableDataRejected, setTableDataRejected] = useState([]); + const [has500Error, setHas500Error] = useState(false); + + const fetchApiData = async (page) => { + // Prevent request if there was a 500 error + if (has500Error) { + return; + } + + dispatch(LOADING_START()); + try { + const response = await axios.get( + `${ + province ? province + "parent-company-" : "" + }chain-allocation/?search=filter&value=${textValue}&page=${page}&page_size=${perPage}&role=${getRoleFromUrl()}&date1=${selectedDate1}&date2=${selectedDate2}${ + value === 1 ? "&state=rejected" : "" + }` + ); + // Reset error state on successful response + setHas500Error(false); + setData(response.data?.results || []); + setTotalRows(response.data?.count || 0); + } catch (error) { + console.error("Error fetching data:", error); + const errorMessage = error?.message || ""; + const status = error?.response?.status; + const is500Error = errorMessage.includes("500") || status === 500; + + if (is500Error) { + setHas500Error(true); + openNotif({ + vertical: "top", + horizontal: "center", + msg: "مشکلی در دریافت اطلاعات پیش آمده است!", + severity: "error", + }); + } else { + openNotif({ + vertical: "top", + horizontal: "center", + msg: "مشکلی در دریافت اطلاعات پیش آمده است!", + severity: "error", + }); + } + setData([]); + setTotalRows(0); + } finally { + dispatch(LOADING_END()); + } + }; + + const handlePageChange = (page) => { + fetchApiData(page); + setPage(page); + }; + + const handlePerRowsChange = (perRows) => { + setPerPage(perRows); + setPage(1); + }; + + const updateTable = () => { + fetchApiData(page !== 0 ? page : 1); + }; + + useEffect(() => { + if (!data || !Array.isArray(data)) { + setTableData([]); + setTableDataRejected([]); + return; + } + + const d = data.map((item, i) => { + return [ + page === 1 ? i + 1 : i + perPage * (page - 1) + 1, + , + item?.state === "accepted" + ? "تایید شده" + : item?.state === "pending" + ? "در انتظار تایید" + : "رد شده", + item?.date ? formatJustDate(item.date) : "-", + item?.outProvince ? "خارج استان" : "داخل استان", + `${item?.registerer?.fullname || ""} (${ + item?.registerer?.mobile || "" + })`, + item?.killHouse?.killHouseOperator?.user?.fullname + ? `${item.killHouse.killHouseOperator.user.fullname} (${ + item?.killHouse?.killHouseOperator?.user?.mobile || "" + })` + : `${item?.buyerName || ""} (${item?.buyerMobile || ""})`, + `${item?.poultryHatching?.poultry?.unitName || ""} (${ + item?.poultryHatching?.poultry?.user?.mobile || "" + })`, + `${item?.chainCompany?.name || ""} (${ + item?.chainCompany?.user?.mobile || "" + })`, + <> + {" "} + {getRoleFromUrl() === "ParentCompany" ? ( + item?.healthCode || "" + ) : ( + + )} + , + <> + {getRoleFromUrl() === "VetFarm" || + getRoleFromUrl() === "ProvinceOperator" || + getRoleFromUrl() === "SuperAdmin" || + getRoleFromUrl() === "Supporter" || + getRoleFromUrl() === "AdminX" || + getRoleFromUrl() === "CityVet" || + getRoleFromUrl() === "VetSupervisor" ? ( + <> + + {item?.quarantineCodeRegisterar?.date + ? (() => { + try { + const date = new Date(item?.registerar?.date); + return isNaN(date.getTime()) + ? "" + : `${format(date, "yyyy/MM/dd")} ${ + item?.quarantineCodeRegisterar?.name || "" + }`; + } catch (error) { + console.error( + "Error formatting quarantineCodeRegisterar date:", + error + ); + return ""; + } + })() + : ""} + + ) : item?.quarantineCode ? ( + item.quarantineCode + ) : ( + "-" + )} + , + item?.driverName + ? `${item.driverName} (${item?.driverMobile || ""})` + : "-", + item?.typeCar || "", + item?.pelak || "", + item?.quantity || 0, + item?.indexWeight || 0, + item?.weight || 0, + ]; + }); + setTableData(d); + + const r = data.map((item, i) => { + return [ + page === 1 ? i + 1 : i + perPage * (page - 1) + 1, + item?.state === "rejected" + ? "رد شده" + : item?.state === "deleted" + ? "حذف شده" + : "در انتظار تایید", + item?.remover + ? `${item.remover?.fullname || ""} (${item.remover?.mobile || ""})` + : `${item?.registerer?.fullname || ""} (${ + item?.registerer?.mobile || "" + })`, + item?.date ? formatJustDate(item.date) : "-", + item?.outProvince ? "خارج استان" : "داخل استان", + item?.registerer?.fullname + ? `${item.registerer.fullname} (${item?.registerer?.mobile || ""})` + : "-", + item?.killHouse?.killHouseOperator?.user?.fullname + ? `${item.killHouse.killHouseOperator.user.fullname} (${ + item?.killHouse?.killHouseOperator?.user?.mobile || "" + })` + : `${item?.buyerName || ""} (${item?.buyerMobile || ""})`, + `${item?.poultryHatching?.poultry?.unitName || ""} (${ + item?.poultryHatching?.poultry?.user?.mobile || "" + })`, + `${item?.chainCompany?.name || ""} (${ + item?.chainCompany?.user?.mobile || "" + })`, + item?.healthCode || "", + item?.quarantineCode || "", + item?.driverName + ? `${item.driverName} (${item?.driverMobile || ""})` + : "-", + item?.typeCar || "", + item?.pelak || "", + item?.quantity || 0, + item?.indexWeight || 0, + item?.weight || 0, + ]; + }); + + setTableDataRejected(r); + }, [data, page, perPage]); + + useEffect(() => { + fetchApiData(1); + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [dispatch, selectedDate1, selectedDate2, perPage, value]); + + // Reset error state when dates, filters, or tab value changes + useEffect(() => { + setHas500Error(false); + }, [selectedDate1, selectedDate2, textValue, value]); + + const handleSubmit = async (event) => { + event.preventDefault(); + // Reset error state on manual submit (user retry) + setHas500Error(false); + dispatch(LOADING_START()); + + try { + const response = await axios.get( + `${ + province ? province + "parent-company-" : "" + }chain-allocation/?search=filter&value=${textValue}&page=${page}&page_size=${perPage}&role=${getRoleFromUrl()}&date1=${selectedDate1}&date2=${selectedDate2}${ + value === 1 ? "&state=rejected" : "" + }` + ); + // Reset error state on successful response + setHas500Error(false); + setData(response.data?.results || []); + setTotalRows(response.data?.count || 0); + dispatch(LOADING_END()); + } catch (error) { + console.error("Error fetching data:", error); + const errorMessage = error?.message || ""; + const status = error?.response?.status; + const is500Error = errorMessage.includes("500") || status === 500; + + if (is500Error) { + setHas500Error(true); + openNotif({ + vertical: "top", + horizontal: "center", + msg: "مشکلی در دریافت اطلاعات پیش آمده است!", + severity: "error", + }); + } else { + openNotif({ + vertical: "top", + horizontal: "center", + msg: "مشکلی در دریافت اطلاعات پیش آمده است!", + severity: "error", + }); + } + setData([]); + setTotalRows(0); + dispatch(LOADING_END()); + } + }; + + const tableTitle = ( + + + + } + value={selectedDate1} + onChange={(e) => { + setSelectedDate1(moment(e).format("YYYY-MM-DD")); + }} + /> + + + } + value={selectedDate2} + onChange={(e) => { + setSelectedDate2(moment(e).format("YYYY-MM-DD")); + }} + /> + +
    + + + {value === 0 ? ( + + + + + + ) : ( + + + + + + )} + +
    +
    + ); + + return ( + + + {(pathname === ROUTE_PROVINCE_CHAINS || + pathname === ROUTE_SUPER_ADMIN_CHAINS || + pathname === ROUTE_ADMINX_CHAINS || + pathname === ROUTE_PARENT_COMPANY_ALLOCATIONS) && ( + + + + + )} + + + {tableTitle} + + + ); +}; diff --git a/src/features/province/components/chain-edit-bar/ChainEditBar.js b/src/features/province/components/chain-edit-bar/ChainEditBar.js new file mode 100644 index 0000000..2e391cf --- /dev/null +++ b/src/features/province/components/chain-edit-bar/ChainEditBar.js @@ -0,0 +1,108 @@ +import React, { useContext, useEffect } from "react"; +import { Grid } from "../../../../components/grid/Grid"; +import { AppContext } from "../../../../contexts/AppContext"; +import { Button, TextField } from "@mui/material"; +import { Yup } from "../../../../lib/yup/yup"; +import { useFormik } from "formik"; +import { useDispatch } from "react-redux"; +import { CLOSE_MODAL } from "../../../../lib/redux/slices/appSlice"; +import { provinceChainsEditBar } from "../../services/province-chains-edit-bar"; + +export const ChainEditBar = ({ item, updateTable }) => { + const dispatch = useDispatch(); + const [openNotif] = useContext(AppContext); + + const formik = useFormik({ + initialValues: { + weight: item?.weight ? item?.weight : "", + quantity: item?.quantity ? item?.quantity : "", + }, + validationSchema: Yup.object({ + weight: Yup.number().required("این فیلد اجباری است!"), + quantity: Yup.number().required("این فیلد اجباری است!"), + }), + }); + + useEffect(() => { + formik.validateForm(); + }, []); + + return ( + + + + + + + + + + + + ); +}; diff --git a/src/features/province/components/chain-replace-active-chain/ChainReplaceActiveChain.js b/src/features/province/components/chain-replace-active-chain/ChainReplaceActiveChain.js new file mode 100644 index 0000000..6691735 --- /dev/null +++ b/src/features/province/components/chain-replace-active-chain/ChainReplaceActiveChain.js @@ -0,0 +1,89 @@ +import React, { useContext, useEffect, useState } from "react"; +import { Grid } from "../../../../components/grid/Grid"; +import { SPACING } from "../../../../data/spacing"; +import { useDispatch } from "react-redux"; +import { Autocomplete, Button, TextField } from "@mui/material"; +import { AppContext } from "../../../../contexts/AppContext"; +import { provinceChainsReplaceActiveChain } from "../../services/province-chains-replace-active-chain"; +import { provinceChainsGetCompanies } from "../../services/province-chains-get-companies"; + +export const ChainsReplaceActiveChain = ({ item, updateTable }) => { + const dispatch = useDispatch(); + const [dataCompany, setDataCompany] = useState([]); + const [selectedCompany, setSelectedCompany] = useState(""); + const [openNotif] = useContext(AppContext); + + useEffect(() => { + dispatch(provinceChainsGetCompanies()).then((r) => { + setDataCompany(r.payload.data); + }); + }, []); + + return ( + + + + ({ + id: i.key, + label: `${i.name} (${i.user.mobile})`, + })) + : [] + } + onChange={(e, value) => { + setSelectedCompany(value.id); + }} + renderInput={(params) => ( + + )} + /> + + + + + + + + ); +}; diff --git a/src/features/province/components/chain-submit-quarantine-code/ChainSubmitQuarantineCode.js b/src/features/province/components/chain-submit-quarantine-code/ChainSubmitQuarantineCode.js new file mode 100644 index 0000000..da41dae --- /dev/null +++ b/src/features/province/components/chain-submit-quarantine-code/ChainSubmitQuarantineCode.js @@ -0,0 +1,220 @@ +import React, { useContext, useEffect, useRef, useState } from "react"; +import { + Button, + Grid, + IconButton, + TextField, + Tooltip, + Typography, +} from "@mui/material"; +import { useDispatch } from "react-redux"; +import PageviewIcon from "@mui/icons-material/Pageview"; +import EditIcon from "@mui/icons-material/Edit"; +import AddCircleOutlineIcon from "@mui/icons-material/AddCircleOutline"; +import { PropTypes } from "prop-types"; +import { AppContext } from "../../../../contexts/AppContext"; +import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl"; +import { provinceChainsEditBar } from "../../services/province-chains-edit-bar"; +import { CLOSE_MODAL, OPEN_MODAL } from "../../../../lib/redux/slices/appSlice"; + +export const ChainSubmitQuarantineCode = ({ item, updateTable, isLocked }) => { + const dispatch = useDispatch(); + const [openNotif] = useContext(AppContext); + + const handleOpenModal = () => { + dispatch( + OPEN_MODAL({ + title: "ثبت کد قرنطینه", + size: "auto", + content: ( + { + dispatch( + provinceChainsEditBar({ + chain_allcation_key: item.key, + quarantine_code: newCode, + role: getRoleFromUrl(), + }) + ).then((r) => { + if (r.payload.error) { + openNotif({ + vertical: "top", + horizontal: "center", + msg: r.payload.error, + severity: "error", + }); + } else { + openNotif({ + vertical: "top", + horizontal: "center", + msg: "عملیات با موفقیت انجام شد.", + severity: "success", + }); + updateTable(); + dispatch(CLOSE_MODAL()); + } + }); + }} + onCancel={() => dispatch(CLOSE_MODAL())} + /> + ), + }) + ); + }; + + return ( + + {item.quarantineCode ? ( + + ) : ( + + + + )} + {!isLocked && ( + + + + )} + + ); +}; + +const ViewCodeComponent = ({ clearanceCode }) => { + const formRef = useRef(null); + + const handleImageClick = () => { + if (formRef.current) { + formRef.current.submit(); + } + }; + return ( + + +
    + + + + +
    + + {clearanceCode} + +
    + ); +}; + +const SubmitQuarantineModal = ({ code, isLocked, onSubmit, onCancel }) => { + const [value, setValue] = useState(code); + const [error, setError] = useState(""); + + useEffect(() => { + setValue(code); + }, [code]); + + const validate = (val) => { + if (!val) { + setError("این فیلد اجباری است"); + return false; + } + const pattern = /^(?=.*[A-Za-z])(?=.*\d)[A-Za-z\d]+$/; + if (!pattern.test(val)) { + setError("باید شامل اعداد و حروف انگلیسی باشد"); + return false; + } + setError(""); + return true; + }; + + const handleChange = (event) => { + const newValue = event.target.value.toUpperCase(); + setValue(newValue); + validate(newValue); + }; + + const handleSubmit = () => { + if (validate(value)) { + onSubmit(value); + } + }; + + return ( + + + + + + + + ); +}; + +ChainSubmitQuarantineCode.propTypes = { + item: PropTypes.any, + updateTable: PropTypes.any, + isLocked: PropTypes.any, +}; diff --git a/src/features/province/components/chains-active-chains-operations/ChainsActiveChainsOperations.js b/src/features/province/components/chains-active-chains-operations/ChainsActiveChainsOperations.js new file mode 100644 index 0000000..ed17aff --- /dev/null +++ b/src/features/province/components/chains-active-chains-operations/ChainsActiveChainsOperations.js @@ -0,0 +1,257 @@ +import { + IconButton, + Popover, + List, + ListItemButton, + ListItemIcon, + ListItemText, + Typography, +} from "@mui/material"; +import { useContext, useState } from "react"; +import ArchiveIcon from "@mui/icons-material/Archive"; +import DeleteIcon from "@mui/icons-material/Delete"; +import TuneIcon from "@mui/icons-material/Tune"; +import FindReplaceIcon from "@mui/icons-material/FindReplace"; +import { useDispatch } from "react-redux"; +import { AppContext } from "../../../../contexts/AppContext"; +import { provinceChainsDeleteChain } from "../../services/province-chains-delete-chain"; +import { ChainsReplaceActiveChain } from "../chain-replace-active-chain/ChainReplaceActiveChain"; +import { DRAWER } from "../../../../lib/redux/slices/appSlice"; +import { CityArchiveHatchingDrawer } from "../../../city/components/city-archive-hatching-drawer/CityArchiveHatchingDrawer"; +import AddTaskIcon from "@mui/icons-material/AddTask"; +import { ChainsAllocation } from "../chains-allocation/ChainsAllocation"; + +export const ChainsActiveChainsOperations = ({ item, updateTable }) => { + const [anchorEl, setAnchorEl] = useState(null); + const dispatch = useDispatch(); + const [openNotif] = useContext(AppContext); + const handleClick = (event) => { + setAnchorEl(event.currentTarget); + }; + + const handleClose = () => { + setAnchorEl(null); + }; + + const open = Boolean(anchorEl); + const id = open ? "popover" : undefined; + + return ( +
    + + + + + + { + handleClose(); + dispatch( + DRAWER({ + title: "تخصیص به زنجیره", + right: !(window.innerWidth <= 600), + bottom: window.innerWidth <= 600, + content: ( + + ), + }) + ); + }} + sx={{ + borderRadius: 1, + mb: 0.5, + color: "primary.main", + "&:last-of-type": { + mb: 0, + }, + }} + > + + + + + تخصیص به زنجیره + + } + /> + + + { + handleClose(); + dispatch( + DRAWER({ + right: !(window.innerWidth <= 600), + bottom: window.innerWidth <= 600, + title: "جایگزین کردن مرغداری ", + content: ( + + ), + }) + ); + }} + sx={{ + borderRadius: 1, + mb: 0.5, + color: "info.main", + "&:last-of-type": { + mb: 0, + }, + }} + > + + + + + جایگزین کردن + + } + /> + + + { + handleClose(); + dispatch( + DRAWER({ + title: "انتقال به آرشیو", + right: !(window.innerWidth <= 600), + bottom: window.innerWidth <= 600, + content: ( + + ), + }) + ); + }} + sx={{ + borderRadius: 1, + mb: 0.5, + color: "secondary.main", + "&:last-of-type": { + mb: 0, + }, + }} + > + + + + + انتقال به بایگانی + + } + /> + + + { + handleClose(); + dispatch( + provinceChainsDeleteChain({ + type: "delete", + hatching_key: item?.key, + }) + ).then((r) => { + if (r.payload.error) { + openNotif({ + vertical: "top", + horizontal: "center", + msg: r.payload.error, + severity: "error", + }); + } else { + updateTable(); + openNotif({ + vertical: "top", + horizontal: "center", + msg: "عملیات با موفقیت انجام شد.", + severity: "success", + }); + } + }); + }} + sx={{ + borderRadius: 1, + mb: 0.5, + color: "error.main", + "&:last-of-type": { + mb: 0, + }, + }} + > + + + + + خروج از زنجیره + + } + /> + + + +
    + ); +}; diff --git a/src/features/province/components/chains-active-chains/ChainsActiveChains.js b/src/features/province/components/chains-active-chains/ChainsActiveChains.js new file mode 100644 index 0000000..229ca9d --- /dev/null +++ b/src/features/province/components/chains-active-chains/ChainsActiveChains.js @@ -0,0 +1,437 @@ +import React, { useContext, useEffect, useState } from "react"; +import { + Button, + FormControl, + InputLabel, + MenuItem, + Select, + TextField, + Tooltip, + Typography, +} from "@mui/material"; +import { useDispatch, useSelector } from "react-redux"; +import axios from "axios"; +import { RiFileExcel2Fill, RiSearchLine } from "react-icons/ri"; +import ResponsiveTable from "../../../../components/responsive-table/ResponsiveTable"; +import { Grid } from "../../../../components/grid/Grid"; +import { + DRAWER, + LOADING_END, + LOADING_START, +} from "../../../../lib/redux/slices/appSlice"; +import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl"; +import { AppContext } from "../../../../contexts/AppContext"; +import { SPACING } from "../../../../data/spacing"; +import { getFaUserRole } from "../../../../utils/getFaUserRole"; +import { ChainsActiveChainsOperations } from "../chains-active-chains-operations/ChainsActiveChainsOperations"; +import { ChainsSubmitActiveChain } from "../chains-submit-active-chain/ChainsSubmitActiveChain"; +import { convertToIranianTime } from "../../../../utils/formatTime"; +export const ChainsActiveChains = () => { + const dispatch = useDispatch(); + const [selectedAge1, setSelectedAge1] = useState(0); + const [selectedAge2, setSelectedAge2] = useState(0); + const userKey = useSelector((state) => state.userSlice.userProfile.key); + + const handleTextChange = (event) => { + setTextValue(event.target.value); + }; + const [openNotif] = useContext(AppContext); + + const [data, setData] = useState([]); + const [totalRows, setTotalRows] = useState(0); + const [perPage, setPerPage] = useState(10); + const [textValue, setTextValue] = useState(""); + const [page, setPage] = useState(1); + const [tableData, setTableData] = useState([]); + + const fetchApiData = async (page) => { + let response; + dispatch(LOADING_START()); + response = await axios.get( + `poultry_hatching?search=filter&value=${textValue}&role=${getRoleFromUrl()}&page=${page}&page_size=${perPage}&chain=true` + ); + + dispatch(LOADING_END()); + setData(response.data.results); + setTotalRows(response.data.count); + }; + + const handlePageChange = (page) => { + fetchApiData(page); + setPage(page); + }; + + const handlePerRowsChange = (perRows) => { + setPerPage(perRows); + setPage(1); + }; + + const updateTable = () => { + fetchApiData(page !== 0 ? page : 1); + }; + const killedNumber = (item) => { + let killedNumber = ""; + killedNumber = item.quantity - item.losses - item.leftOver; + return killedNumber; + }; + useEffect(() => { + const d = data?.map((item, i) => { + let lastChange; + return [ + , + page === 1 ? i + 1 : i + perPage * (page - 1) + 1, + `${item?.chainCompany?.name} (${item?.chainCompany?.user.mobile})`, + item.violation ? "متخلف" : "عادی", + item.poultry.unitName, + `${item.poultry.userprofile.fullName} (${item.poultry.userprofile.mobile})`, + + `${item?.poultry?.address.city.name}/${ + item?.poultry?.cityOperator + ? item?.poultry?.cityOperator + : "بدون تعاونی" + }`, + item?.vetFarm?.vetFarmMobile + ? `${item?.vetFarm?.vetFarmFullName} (${item?.vetFarm?.vetFarmMobile})` + : "-", + item.hall, + item.period, + convertToIranianTime(item?.createDate), + convertToIranianTime(item?.date), + item.chickenBreed, + item.age, + item?.quantity?.toLocaleString(), + `${item.losses} (%${((item.losses * 100) / item.quantity).toFixed(0)})`, + `${item?.totalCommitmentQuantity?.toLocaleString()}`, + `${item?.governmentalQuantity?.toLocaleString()}`, + `${item?.governmentalKilledQuantity?.toLocaleString()}`, + `${item?.freeQuantity?.toLocaleString()}`, + `${item?.freeKilledQuantity?.toLocaleString()}`, + `${item?.outProvinceKilledQuantity?.toLocaleString()}`, + `${item?.outProvinceKilledWeight?.toLocaleString()}`, + item?.chainKilledQuantity?.toLocaleString(), + item?.chainKilledWeight?.toLocaleString(), + killedNumber(item)?.toLocaleString() + + ` (%${((killedNumber(item) * 100) / item.quantity).toFixed(0)})`, + `${item?.leftOver?.toLocaleString()} (%${( + (item.leftOver * 100) / + item.quantity + ).toFixed(0)})`, + + item?.totalCommitment?.toLocaleString() + " کیلوگرم ", + item?.governmentalKilledQuantity?.toLocaleString() + " کیلوگرم ", + item?.freeKilledQuantity?.toLocaleString() + " کیلوگرم ", + item?.totalAverageKilledWeight?.toLocaleString() + " کیلوگرم ", + item?.totalKilledWeight?.toLocaleString() + " کیلوگرم ", + item?.activeKill?.activeKill ? "دارد" : "ندارد", + item?.activeKill?.countOfRequest ? item.activeKill.countOfRequest : "-", + (lastChange = item.lastChange + ? `${item.lastChange.fullName} (${getFaUserRole( + item.lastChange.role + )}) در تاریخ ${item.lastChange.date}` + : "-"), + (lastChange = + item.latestHatchingChange && + item.latestHatchingChange.date && + `${item.latestHatchingChange.fullName} (${getFaUserRole( + item.latestHatchingChange.role + )}) در تاریخ ${item.latestHatchingChange.date}`), + item.latestHatchingChange ? lastChange : "-", + ]; + }); + + setTableData(d); + }, [data]); + + useEffect(() => { + fetchApiData(1); + }, [dispatch, perPage]); + + const handleSubmit = async (event) => { + event.preventDefault(); + dispatch(LOADING_START()); + + try { + const response = await axios.get( + `poultry_hatching/?role=${getRoleFromUrl()}&search=filter&value=${textValue}&chain=true` + ); + + setData(response.data.results); + setTotalRows(response.data.count); + dispatch(LOADING_END()); + } catch (error) { + console.error("Error fetching data:", error); + } + }; + + const handleRemoveFilter = async (event) => { + event.preventDefault(); + setSelectedAge1(null); + setSelectedAge2(null); + + try { + const response = await axios.get( + `poultry_hatching/?role=${getRoleFromUrl()}&chain=true&search=filter&value=` + ); + setData(response.data.results); + setTotalRows(response.data.count); + } catch (error) { + console.error("Error fetching data:", error); + } + }; + + const handleSubmitSearchByAge = async (event) => { + event.preventDefault(); + + dispatch(LOADING_START()); + + try { + const response = await axios.get( + `poultry_hatching?role=${getRoleFromUrl()}&age1=${selectedAge1}&age2=${selectedAge2}&chain=true` + ); + setData(response.data.results); + setTotalRows(response.data.count); + dispatch(LOADING_END()); + } catch (error) { + console.error("Error fetching data:", error); + } + }; + + const selectAges = Array.from({ length: 75 }, (_, i) => i + 1); + + const tableTitle = ( + + + زنجیره های فعال + +
    + + + + {/* */} + + {/* */} + + +
    + + + جستجو براساس سن: + + + + از سن + + + + + + تا سن + + + + + + {/* */} + + {/* */} + + + +
    + ); + + return ( + + + + + {tableTitle} + + + ); +}; diff --git a/src/features/province/components/chains-allocation/ChainsAllocation.js b/src/features/province/components/chains-allocation/ChainsAllocation.js new file mode 100644 index 0000000..88c6952 --- /dev/null +++ b/src/features/province/components/chains-allocation/ChainsAllocation.js @@ -0,0 +1,720 @@ +import React, { useContext, useEffect, useState } from "react"; +import { Grid } from "../../../../components/grid/Grid"; +import { DatePicker } from "@mui/x-date-pickers"; +import { AppContext } from "../../../../contexts/AppContext"; +import moment from "moment"; +import { + Button, + Divider, + InputLabel, + MenuItem, + Select, + TextField, + Typography, +} from "@mui/material"; +import { Yup } from "../../../../lib/yup/yup"; +import { useFormik } from "formik"; +import { useDispatch } from "react-redux"; +import { provinceChainsSubmitAllocation } from "../../services/province-chains-submut-allocation"; +import { + DRAWER, + LOADING_END, + LOADING_START, +} from "../../../../lib/redux/slices/appSlice"; +import Radio from "@mui/material/Radio"; +import RadioGroup from "@mui/material/RadioGroup"; +import FormControlLabel from "@mui/material/FormControlLabel"; +import FormControl from "@mui/material/FormControl"; +import FormLabel from "@mui/material/FormLabel"; +import { CarPelak } from "../../../../components/car-pelak/CarPelak"; +import { SPACING } from "../../../../data/spacing"; +import { provinceGetKillHousesForAllocation } from "../../services/province-get-killhouses-for-allocation"; +import { provinceChainsEditAllocation } from "../../services/province-chains-edit-allocation"; +import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl"; + +export const ChainsAllocation = ({ item, updateTable, isEdit }) => { + const dispatch = useDispatch(); + const [openNotif] = useContext(AppContext); + const [value, setValue] = React.useState( + isEdit ? (item?.outProvince ? "out" : "native") : "out" + ); + const [selectedKillhouse, setSelectedKillHouse] = React.useState(); + + useEffect(() => { + if (value === "native") { + dispatch(LOADING_START()); + dispatch(provinceGetKillHousesForAllocation()).then((r) => { + dispatch(LOADING_END()); + const d = r?.payload.data.map((item) => { + return { name: item.name, key: item.key }; + }); + setKillhouses(d); + setSelectedKillHouse(""); + }); + } + }, [value]); + + const [killhouses, setKillhouses] = useState([]); + + const handleChange = (event) => { + setValue(event.target.value); + }; + + const [driverPelak, setDriverPelak] = useState([]); + + const carPelakHandleChange = (pelak1, pelak2, pelak3, pelak4) => { + setDriverPelak([pelak1, pelak2, pelak3, pelak4]); + }; + + const formik = useFormik({ + initialValues: { + weight: isEdit ? item?.indexWeight : "", + quantity: isEdit ? item?.quantity : "", + driverName: isEdit ? item?.driverName : "", + driverMobile: isEdit ? item?.driverMobile : "", + driverCar: isEdit ? item?.typeCar : "", + healthCode: isEdit ? item?.healthCode : "", + }, + validationSchema: Yup.object({ + weight: Yup.number().required("این فیلد اجباری است!"), + quantity: Yup.number().required("این فیلد اجباری است!"), + driverName: Yup.string().required("این فیلد اجباری است!"), + healthCode: Yup.string().required("این فیلد اجباری است!"), + driverMobile: Yup.string() + .required("شماره موبایل کشتارگاه الزامی است") + .min(11, "شماره موبایل باید 11 رقم باشد") + .max(11, "شماره موبایل باید 11 رقم باشد") + .matches(/^09\d{9}$/, "شماره موبایل باید با 09 شروع شود و 11 رقم باشد"), + driverCar: Yup.string().required("این فیلد اجباری است!"), + // driverhealthCode: Yup.string().required("این فیلد اجباری است!"), + }), + }); + + const [, , selectedDate1, setSelectedDate1, ,] = useContext(AppContext); + + useEffect(() => { + const currentDate = moment(new Date()).format("YYYY-MM-DD"); + setSelectedDate1(currentDate); + }, []); + + const formikbuyer = useFormik({ + initialValues: { + name: isEdit ? item?.buyerName : "", + mobile: isEdit ? item?.buyerMobile : "", + province: isEdit ? item?.province : "", + city: isEdit ? item?.city : "", + }, + validationSchema: Yup.object({ + name: Yup.string().required("نام اجباری است"), + mobile: Yup.string() + .required("شماره موبایل کشتارگاه الزامی است") + .min(11, "شماره موبایل باید 11 رقم باشد") + .max(11, "شماره موبایل باید 11 رقم باشد") + .matches(/^09\d{9}$/, "شماره موبایل باید با 09 شروع شود و 11 رقم باشد"), + province: Yup.string().required("استان اجباری است"), + city: Yup.string().required("شهرستان اجباری است"), + }), + }); + + useEffect(() => { + formik.validateForm(); + formikbuyer.validateForm(); + }, []); + + const isFormValid = () => { + if (value === "native") { + return formik.isValid && selectedKillhouse && driverPelak[1]; + } else { + return formik.isValid && formikbuyer.isValid && driverPelak[1]; + } + }; + + useEffect(() => { + let newVal = formik.values.weight; + const mystring = formik.values.weight.toString().split(".").join(""); + if (formik.values.weight) { + if (mystring.length <= 3) { + if (mystring.length === 2) { + newVal = mystring[0] + "." + mystring[1]; + } + if (mystring.length === 3) { + newVal = mystring[0] + "." + mystring[1] + mystring[2]; + } + } + } + if (isNaN(Number.parseFloat(newVal))) { + formik.setFieldValue("weight", ""); + } else { + formik.setFieldValue("weight", Number.parseFloat(newVal)); + } + }, [formik.values.weight]); + + return ( + + {!isEdit && ( + <> + + شرکت زنجیره:{"‌‌ ‌"} + + {item?.companyName} + + + + مرغدار:{"‌‌ ‌"} + + {item.poultry.userprofile.fullName} ( + {item.poultry.userprofile.mobile}) + + + + نژاد:{"‌‌ ‌"} + + {item.chickenBreed} + + + + سن جوجه:{"‌‌ ‌"} + + {item.age} + + + + )} + {isEdit && ( + <> + + مرغدار:{"‌‌ ‌"} + + {item?.poultryHatching?.poultry?.unitName} ( + {item?.poultryHatching?.poultry?.user?.mobile}) + + + + شرکت زنجیره:{"‌‌ ‌"} + + {item?.chainCompany?.name} + + + + )} + + + + } + value={selectedDate1} + onChange={(e) => { + setSelectedDate1(moment(e).format("YYYY-MM-DD")); + }} + /> + + + + + + + + {formik.values.weight && formik.values.quantity && ( + + + وزن کل: {"‌‌ ‌"} + + + {parseInt(formik.values.quantity * formik.values.weight)} کیلوگرم + + + )} + + + نوع فروش + + } + label="خارج استان" + /> + } + label="درون استان" + /> + + + + {value === "out" ? ( + + اطلاعات خریدار + + + + + + ) : ( + + + کشتارگاه را انتخاب کنید + + {formik.errors.selectedKillhouse && + formik.touched.selectedKillhouse && ( +
    {formik.errors.selectedKillhouse}
    + )} +
    +
    + )} + + اطلاعات خودرو حمل + + + + + + + {/* */} + + +
    + ); +}; diff --git a/src/features/province/components/chains-companies-submit/ChainsCompaniesSubmit.js b/src/features/province/components/chains-companies-submit/ChainsCompaniesSubmit.js new file mode 100644 index 0000000..09935b2 --- /dev/null +++ b/src/features/province/components/chains-companies-submit/ChainsCompaniesSubmit.js @@ -0,0 +1,373 @@ +import React, { useContext, useEffect, useState } from "react"; +import { Grid } from "../../../../components/grid/Grid"; +import { SPACING } from "../../../../data/spacing"; +import { Yup } from "../../../../lib/yup/yup"; +import { useFormik } from "formik"; +import { Button, TextField, Autocomplete, Typography } from "@mui/material"; +import { provinceChainsSubmitCompany } from "../../services/province-chains-submit-company"; +import { useDispatch } from "react-redux"; +import { AppContext } from "../../../../contexts/AppContext"; +import { DRAWER } from "../../../../lib/redux/slices/appSlice"; +import { provinceChainsEditCompany } from "../../services/province-chains-edit-company"; +import { provinceChainsGetCompanies } from "../../services/province-chains-get-companies"; +import { + slaughterGetCitiesService, + slaughterGetProvinceService, +} from "../../../slaughter-house/services/slaughter-get-provinces"; + +export const ChainsCompaniesSubmit = ({ item }) => { + const dispatch = useDispatch(); + const [openNotif] = useContext(AppContext); + const [provinceData, setProvinceData] = useState([]); + const [cityData, setCityData] = useState([]); + + const formik = useFormik({ + initialValues: { + mobile: item?.user?.mobile ? item?.user?.mobile : "", + name: item?.name ? item?.name : "", + firstname: item?.user?.firstName ? item?.user?.firstName : "", + lastname: item?.user?.lastName ? item?.user?.lastName : "", + natioanlId: item?.user?.nationalId ? item?.user?.nationalId : "", + postal: item?.postalCode ? item?.postalCode : "", + province: item?.province ? item?.province : "", + city: item?.city ? item?.city : "", + address: item?.address ? item?.address : "", + }, + validationSchema: Yup.object({ + mobile: Yup.number() + .required("این فیلد اجباری است!") + .typeError("لطفا فیلد را به صورت عددی وارد کنید!") + .test("len", "شماره تلفن باید با 0 شروع شود", (val, context) => { + return context.originalValue && context.originalValue.startsWith("0"); + }) + .test("len", "شماره تماس 11 رقم باید باشد", (val, context) => { + if (context.originalValue) { + return context.originalValue.length === 11; + } + }), + name: Yup.string() + .required("این فیلد اجباری است!") + .typeError("لطفا فیلد را پر کنید!"), + firstname: Yup.string() + .required("این فیلد اجباری است!") + .typeError("لطفا فیلد را پر کنید!"), + lastname: Yup.string() + .required("این فیلد اجباری است!") + .typeError("لطفا فیلد را پر کنید!"), + province: Yup.string() + .required("این فیلد اجباری است!") + .typeError("لطفا فیلد را به درستی وارد کنید!"), + city: Yup.string() + .required("این فیلد اجباری است!") + .typeError("لطفا فیلد را به درستی وارد کنید!"), + address: Yup.string() + .required("این فیلد اجباری است!") + .typeError("لطفا فیلد را پر کنید!"), + natioanlId: Yup.number() + .required("این فیلد اجباری است!") + .typeError("لطفا فیلد را پر کنید!"), + postal: Yup.number() + .required("این فیلد اجباری است!") + .typeError("لطفا فیلد را پر کنید!"), + }), + }); + + useEffect(() => { + formik.validateForm(); + }, []); + + useEffect(() => { + dispatch(slaughterGetProvinceService()).then((r) => { + setProvinceData(r.payload.data); + }); + }, []); + + useEffect(() => { + if (formik.values.province) { + setCityData( + [], + dispatch(slaughterGetCitiesService(formik.values.province)).then( + (r) => { + setCityData(r.payload.data); + } + ) + ); + } + }, [formik.values.province]); + + return ( + + + + + + + + + + + + + + + + + + ({ id: i.name, label: i.name })) + : [] + } + onChange={(e, value) => { + formik.setFieldValue("province", value ? value.id : ""); + formik.setFieldValue("city", ""); + }} + renderInput={(params) => ( + + )} + /> + {item && ( + + استان: {formik.values.province} + + )} + + + ({ id: i.name, label: i.name })) + : [] + } + onChange={(e, value) => { + formik.setFieldValue("city", value ? value.id : ""); + }} + renderInput={(params) => ( + + )} + /> + {item && ( + + شهر: {formik.values.city} + + )} + + + + + + + + + + + + + + + + + + + ); +}; diff --git a/src/features/province/components/chains-companies/ProvinceChainsCompanies.js b/src/features/province/components/chains-companies/ProvinceChainsCompanies.js new file mode 100644 index 0000000..5d344a6 --- /dev/null +++ b/src/features/province/components/chains-companies/ProvinceChainsCompanies.js @@ -0,0 +1,231 @@ +import React, { useContext, useEffect, useState } from "react"; +import { + Button, + IconButton, + TextField, + Tooltip, + Typography, +} from "@mui/material"; +import moment from "moment"; +import { useDispatch, useSelector } from "react-redux"; +import axios from "axios"; +import { RiFileExcel2Fill, RiSearchLine } from "react-icons/ri"; +import { AppContext } from "../../../../contexts/AppContext"; +import EditIcon from "@mui/icons-material/Edit"; + +import { + DRAWER, + LOADING_END, + LOADING_START, +} from "../../../../lib/redux/slices/appSlice"; +import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl"; +import { Grid } from "../../../../components/grid/Grid"; +import ResponsiveTable from "../../../../components/responsive-table/ResponsiveTable"; +import { ChainsCompaniesSubmit } from "../chains-companies-submit/ChainsCompaniesSubmit"; + +export const ProvinceChainsCompanies = () => { + const [, , selectedDate1, setSelectedDate1, selectedDate2, setSelectedDate2] = + useContext(AppContext); + const userKey = useSelector((state) => state.userSlice.userProfile.key); + + const dispatch = useDispatch(); + + useEffect(() => { + const currentDate = moment(new Date()).format("YYYY-MM-DD"); + setSelectedDate1(currentDate); + setSelectedDate2(currentDate); + }, [setSelectedDate1, setSelectedDate2]); + + const [data, setData] = useState([]); + const [totalRows, setTotalRows] = useState(0); + const [perPage, setPerPage] = useState(10); + const [textValue, setTextValue] = useState(""); + const [page, setPage] = useState(1); + const [tableData, setTableData] = useState([]); + + const handleTextChange = (event) => { + setTextValue(event.target.value); + }; + + const isAvalableEdit = () => { + if ( + getRoleFromUrl() === "AdminX" || + getRoleFromUrl() === "SuperAdmin" || + getRoleFromUrl() === "ProvinceOperator" + ) { + return false; + } else { + return true; + } + }; + + const fetchApiData = async (page = 1) => { + try { + dispatch(LOADING_START()); + const response = await axios.get( + `chain-company/?search=filter&value=${textValue}&page=${page}&page_size=${perPage}&role=${getRoleFromUrl()}&state=total_companies` + ); + dispatch(LOADING_END()); + setData(response.data.results); + setTotalRows(response.data.count); + } catch (error) { + dispatch(LOADING_END()); + console.error("Error fetching data:", error); + } + }; + + const handlePageChange = (newPage) => { + setPage(newPage); + fetchApiData(newPage); + }; + + const handlePerRowsChange = (newPerPage) => { + setPerPage(newPerPage); + setPage(1); + }; + + useEffect(() => { + fetchApiData(); + }, [selectedDate1, selectedDate2, perPage]); + + useEffect(() => { + const formattedData = data?.map((item, i) => [ + page === 1 ? i + 1 : i + perPage * (page - 1) + 1, + item.name, + item.user.firstName, + item.user.lastName, + item.user.mobile, + item.province, + item.city, + item.address, + item.postalCode, + item.requestsInfo?.numberOfRequests?.toLocaleString(), + item.requestsInfo?.totalQuantity?.toLocaleString(), + item.requestsInfo?.totalWeight?.toLocaleString(), + + + dispatch( + DRAWER({ + title: "ویرایش شرکت زنجیره", + right: !(window.innerWidth <= 600), + bottom: window.innerWidth <= 600, + content: , + }) + ) + } + > + + + , + ]); + setTableData(formattedData); + }, [data, page, perPage]); + + const handleSubmit = async (event) => { + event.preventDefault(); + fetchApiData(1); + }; + + return ( + + + {(getRoleFromUrl() === "ProvinceOperator" || + getRoleFromUrl() === "SuperAdmin") && ( + + )} + + + + + خریداران + +
    + + + + + + + + + + +
    +
    +
    + + +
    + ); +}; diff --git a/src/features/province/components/chains-submit-active-chain/ChainsSubmitActiveChain.js b/src/features/province/components/chains-submit-active-chain/ChainsSubmitActiveChain.js new file mode 100644 index 0000000..8f4b361 --- /dev/null +++ b/src/features/province/components/chains-submit-active-chain/ChainsSubmitActiveChain.js @@ -0,0 +1,132 @@ +import React, { useContext, useEffect, useState } from "react"; +import { Grid } from "../../../../components/grid/Grid"; +import { SPACING } from "../../../../data/spacing"; +import { useDispatch } from "react-redux"; +import { provinceGetPoultry } from "../../../aviculture/services/province-get-poultry"; +import { Autocomplete, Button, TextField } from "@mui/material"; +import { provinceChainsGetCompanies } from "../../services/province-chains-get-companies"; +import { provinceChainsSubmitActiveChain } from "../../services/province-chains-submit-active-chain"; +import { AppContext } from "../../../../contexts/AppContext"; +import { DRAWER } from "../../../../lib/redux/slices/appSlice"; + +export const ChainsSubmitActiveChain = ({ updateTable }) => { + const dispatch = useDispatch(); + const [poultries, setPoultries] = useState([]); + const [data, setData] = useState([]); + const [dataCompany, setDataCompany] = useState([]); + const [selectedPoultries, setSelectedPoultries] = useState([]); + const [selectedCompany, setSelectedCompany] = useState(""); + const [openNotif] = useContext(AppContext); + + useEffect(() => { + dispatch( + provinceGetPoultry({ + chain: true, + }) + ).then((r) => { + setData(r.payload.data); + }); + dispatch(provinceChainsGetCompanies()).then((r) => { + setDataCompany(r.payload.data); + }); + }, []); + + useEffect(() => { + setPoultries( + data?.map((item) => { + return { + label: `${item.unitName} (${item?.user.mobile})`, + value: `${item.chainCompany?.hatchingKey}`, + }; + }) + ); + }, [data]); + + return ( + + + + option.label} + onChange={(e, value) => { + setSelectedPoultries(value); + }} + renderInput={(params) => ( + + )} + /> + + + + ({ + id: i.key, + label: `${i.name} (${i.user.mobile})`, + })) + : [] + } + onChange={(e, value) => { + setSelectedCompany(value.id); + }} + renderInput={(params) => ( + + )} + /> + + + + + + + + ); +}; diff --git a/src/features/province/components/chains/ProvinceChains.js b/src/features/province/components/chains/ProvinceChains.js new file mode 100644 index 0000000..66b8b56 --- /dev/null +++ b/src/features/province/components/chains/ProvinceChains.js @@ -0,0 +1,54 @@ +import React from "react"; +import { Grid } from "../../../../components/grid/Grid"; +import { Tab, Tabs } from "@mui/material"; +import { ProvinceChainsCompanies } from "../chains-companies/ProvinceChainsCompanies"; +import { ChainsActiveChains } from "../chains-active-chains/ChainsActiveChains"; +import { ChainsArchiveChains } from "../chain-archive-chains/ChainsArchiveChains"; +import { ChainBarManagement } from "../chain-bar-management/ChainBarManagement"; + +export const ProvinceChains = () => { + const [value, setValue] = React.useState("0"); + + const handleChange = (event, newValue) => { + setValue(newValue); + }; + return ( + + + + + + + + + + {value === "0" && } + + + {value === "1" && } + + + {value === "2" && } + + + {value === "3" && } + + + + ); +}; diff --git a/src/features/province/components/create-guilds/CreateGuilds.js b/src/features/province/components/create-guilds/CreateGuilds.js new file mode 100644 index 0000000..32fe136 --- /dev/null +++ b/src/features/province/components/create-guilds/CreateGuilds.js @@ -0,0 +1,574 @@ +import React, { useContext, useEffect, useState, useCallback } from "react"; +import { useFormik } from "formik"; +import { useDispatch } from "react-redux"; +import { + Button, + Box, + Typography, + Dialog, + DialogTitle, + DialogContent, + DialogActions, +} from "@mui/material"; +import { Add as AddIcon } from "@mui/icons-material"; +import { Grid } from "../../../../components/grid/Grid"; +import { SPACING } from "../../../../data/spacing"; +import { CLOSE_MODAL } from "../../../../lib/redux/slices/appSlice"; +import { AppContext } from "../../../../contexts/AppContext"; +import { updateGuildByNationalIdNewService } from "../../services/update-guild-by-national-id-new"; +import { deactivateGuildService } from "../../services/deactivate-guild"; +import { provinceGetCitiesService } from "../../services/province-get-cities"; +import { provinceGetFieldOfWorks } from "../../services/ProvinceGetFieldOfWorks"; +import { provinceGetTypeActivity } from "../../services/provinceGetTypeActivity"; +import { provinceGetRegisterCodeStateService } from "../../services/province-get-register-code-state"; +import { mainGetGuildsForUpdateOrCreateService } from "../../services/main-get-guilds-for-update-or-create"; +import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl"; +import { PersonalInfoSection } from "./components/PersonalInfoSection"; +import { InquiryForm } from "./components/InquiryForm"; +import { UpdateFromExternalButton } from "./components/UpdateFromExternalButton"; +import { ConfirmationDialog } from "./components/ConfirmationDialog"; +import { FormActions } from "./components/FormActions"; +import { GuildInfoAccordionItem } from "./components/GuildInfoAccordionItem"; +import { getValidationSchema, getInitialValues } from "./utils/formUtils"; +import { + mapResponseDataToFormFields, + prepareSubmitData, +} from "./utils/dataMapping"; +import { handleSubmitSuccess, handleSubmitError } from "./utils/submitHandlers"; + +const DeleteConfirmationDialog = ({ open, onClose, onConfirm, isDeleting }) => { + return ( + + آیا مطمئن هستید؟ + + + آیا از حذف این صنف مطمئن هستید؟ این عمل قابل بازگشت نیست. + + + + + + + + ); +}; + +export const CreateGuilds = ({ guild, updateTable }) => { + const dispatch = useDispatch(); + const [openNotif] = useContext(AppContext); + const [hasRegisterCode, setHasRegisterCode] = useState(); + const [inquiryNationalCode, setInquiryNationalCode] = useState(""); + const [isInquiryDone, setIsInquiryDone] = useState(false); + const [dbRegister, setDbRegister] = useState(null); + const [hasInquiry, setHasInquiry] = useState(null); + const [guildActive, setGuildActive] = useState(null); + const [guildsList, setGuildsList] = useState(() => (guild ? [guild] : [])); + const [expandedAccordion, setExpandedAccordion] = useState(0); + const [guildsFormValues, setGuildsFormValues] = useState(() => { + // Initialize with guild data if editing + if (guild) { + return [getInitialValues(guild)]; + } + return []; + }); + const [cities, setCities] = useState([]); + const [typeActivities, setTypeActivities] = useState([]); + const [deleteDialogOpen, setDeleteDialogOpen] = useState(false); + const [deleteDialogIndex, setDeleteDialogIndex] = useState(null); + const [isDeletingGuild, setIsDeletingGuild] = useState(false); + + const originalPhoneNumber = guild?.phoneNumber || null; + + const currentRole = getRoleFromUrl(); + const isAdmin = currentRole === "AdminX"; + const isSuperAdmin = currentRole === "SuperAdmin"; + const isKillHouse = currentRole === "KillHouse"; + + const formik = useFormik({ + initialValues: getInitialValues(guild), + validationSchema: getValidationSchema(!!guild), + validateOnMount: true, + onSubmit: (values) => { + const guildsDataArray = guildsList.map((guildItem, index) => { + const guildValues = guildsFormValues[index] || values; + const combinedValues = { + ...values, // Personal info (shared) + ...guildValues, // Guild-specific info (overrides if same keys exist) + }; + return prepareSubmitData( + combinedValues, + guildItem, + originalPhoneNumber, + hasInquiry + ); + }); + + dispatch(updateGuildByNationalIdNewService(guildsDataArray)).then( + (result) => { + if (result.payload.error) { + handleSubmitError(openNotif, result.payload.error); + } else { + handleSubmitSuccess( + dispatch, + openNotif, + updateTable, + values, + result.payload?.data + ); + } + } + ); + }, + }); + + useEffect(() => { + dispatch(provinceGetRegisterCodeStateService()).then((r) => { + const isActive = r.payload.data?.[0]?.active; + setHasRegisterCode(isActive); + if (isActive === false) { + formik.setFieldValue("isAccepted", true); + } + }); + dispatch(provinceGetCitiesService()).then((r) => { + setCities(r.payload.data || []); + }); + dispatch(provinceGetFieldOfWorks()); + dispatch(provinceGetTypeActivity()).then((r) => { + setTypeActivities(r.payload.data || []); + }); + }, []); + + useEffect(() => { + formik.validateForm(); + }, []); + + const mapResponseToFormFields = useCallback( + (responseData) => { + const guildsData = Array.isArray(responseData.guilds) + ? responseData.guilds + : []; + + mapResponseDataToFormFields(responseData, inquiryNationalCode, formik); + + if (responseData.dbRegister === false) { + setDbRegister(false); + setHasInquiry(null); + } else { + setHasInquiry(responseData.hasInquiry ?? null); + const firstGuild = guildsData.length > 0 ? guildsData[0] : null; + const activeStatus = firstGuild?.active ?? responseData.active ?? null; + setGuildActive(activeStatus); + formik.setFieldValue("active", activeStatus); + setDbRegister(true); + } + + if (guildsData.length > 0) { + setGuildsList(guildsData); + const initialGuildValues = guildsData.map((guildItem) => { + const combinedGuild = { + ...guildItem, + user: responseData.user || {}, + }; + return getInitialValues(combinedGuild); + }); + setGuildsFormValues(initialGuildValues); + setExpandedAccordion(0); + } else { + setGuildsList([]); + setGuildsFormValues([]); + } + + setTimeout(() => { + formik.validateField("mobile"); + formik.validateField("national_id"); + }, 0); + }, + [formik, inquiryNationalCode] + ); + + const handleInquiry = useCallback(() => { + if (!inquiryNationalCode) { + openNotif({ + vertical: "top", + horizontal: "center", + msg: "لطفا کد ملی را وارد کنید", + severity: "error", + }); + return; + } + + if (!isAdmin && inquiryNationalCode.length !== 10) { + openNotif({ + vertical: "top", + horizontal: "center", + msg: "لطفا کد ملی 10 رقمی معتبر وارد کنید", + severity: "error", + }); + return; + } + + dispatch( + mainGetGuildsForUpdateOrCreateService({ + national_code: inquiryNationalCode, + update: false, + }) + ).then((r) => { + if (r.payload.error) { + setHasInquiry(false); + if (isAdmin) { + setIsInquiryDone(true); + formik.setFieldValue("national_id", inquiryNationalCode); + } + openNotif({ + vertical: "top", + horizontal: "center", + msg: r.payload.error, + severity: "error", + }); + if (!isAdmin) { + return; + } + } + + if (r.payload.data) { + mapResponseToFormFields(r.payload.data); + setIsInquiryDone(true); + + if (r.payload.data.dbRegister === false) { + setHasInquiry(true); + } + + const successMsg = + r.payload.data.dbRegister === false + ? "اطلاعات از سامانه خارجی دریافت شد" + : "اطلاعات از پایگاه داده دریافت شد"; + + openNotif({ + vertical: "top", + horizontal: "center", + msg: successMsg, + severity: "success", + }); + } else { + setHasInquiry(false); + setIsInquiryDone(true); + if (isAdmin) { + formik.setFieldValue("national_id", inquiryNationalCode); + } + } + }); + }, [ + dispatch, + inquiryNationalCode, + openNotif, + mapResponseToFormFields, + isAdmin, + formik, + ]); + + const handleUpdateFromExternal = useCallback(() => { + if (!formik.values.national_id || formik.values.national_id.length !== 10) { + openNotif({ + vertical: "top", + horizontal: "center", + msg: "لطفا کد ملی 10 رقمی معتبر وارد کنید", + severity: "error", + }); + return; + } + + dispatch( + mainGetGuildsForUpdateOrCreateService({ + national_code: formik.values.national_id, + update: true, + }) + ).then((r) => { + if (r.payload.error) { + setHasInquiry(false); + openNotif({ + vertical: "top", + horizontal: "center", + msg: r.payload.error, + severity: "error", + }); + return; + } + + if (r.payload.data) { + const updateResponse = { + ...r.payload.data, + dbRegister: false, + }; + mapResponseToFormFields(updateResponse); + setHasInquiry(true); + + openNotif({ + vertical: "top", + horizontal: "center", + msg: "اطلاعات از سامانه خارجی بروزرسانی شد", + severity: "success", + }); + } else { + setHasInquiry(false); + } + }); + }, [dispatch, formik.values.national_id, openNotif, mapResponseToFormFields]); + + const handleAddGuild = () => { + const newIndex = guildsList.length; + setGuildsList([...guildsList, null]); + setGuildsFormValues([...guildsFormValues, getInitialValues(null)]); + setExpandedAccordion(newIndex); + }; + + const handleDeleteGuild = (index) => { + const guildToDelete = guildsList[index]; + if (guildToDelete?.key) { + setDeleteDialogIndex(index); + setDeleteDialogOpen(true); + return; + } + if (guildsList.length > 1) { + setGuildsList(guildsList.filter((_, i) => i !== index)); + setGuildsFormValues(guildsFormValues.filter((_, i) => i !== index)); + if (expandedAccordion === index) { + setExpandedAccordion(0); + } else if (expandedAccordion > index) { + setExpandedAccordion(expandedAccordion - 1); + } + } + }; + + const handleConfirmDelete = () => { + if (deleteDialogIndex === null) return; + + const guildToDelete = guildsList[deleteDialogIndex]; + if (!guildToDelete?.key) return; + + setIsDeletingGuild(true); + dispatch(deactivateGuildService(guildToDelete.key)).then((r) => { + setIsDeletingGuild(false); + setDeleteDialogOpen(false); + setDeleteDialogIndex(null); + + if (r.payload?.error) { + openNotif({ + vertical: "top", + horizontal: "center", + msg: r.payload.error, + severity: "error", + }); + } else { + openNotif({ + vertical: "top", + horizontal: "center", + msg: "صنف با موفقیت حذف شد", + severity: "success", + }); + // Remove from list after successful deletion + if (guildsList.length > 1) { + setGuildsList(guildsList.filter((_, i) => i !== deleteDialogIndex)); + setGuildsFormValues( + guildsFormValues.filter((_, i) => i !== deleteDialogIndex) + ); + // If deleted accordion was expanded, expand the first one + if (expandedAccordion === deleteDialogIndex) { + setExpandedAccordion(0); + } else if (expandedAccordion > deleteDialogIndex) { + // Adjust expanded index if deleted item was before it + setExpandedAccordion(expandedAccordion - 1); + } + } + if (updateTable) { + updateTable(); + } + } + }); + }; + + const handleCloseDeleteDialog = () => { + if (!isDeletingGuild) { + setDeleteDialogOpen(false); + setDeleteDialogIndex(null); + } + }; + + const handleGuildValuesChange = useCallback((index, fieldName, value) => { + setGuildsFormValues((prev) => { + const newValues = [...prev]; + if (!newValues[index]) { + newValues[index] = getInitialValues(null); + } + newValues[index] = { + ...newValues[index], + [fieldName]: value, + }; + return newValues; + }); + }, []); + + const handleAccordionChange = (index) => (event, isExpanded) => { + setExpandedAccordion(isExpanded ? index : false); + }; + + const shouldShowUpdateButton = + formik?.values?.national_id && + (isAdmin || + (dbRegister !== false && + (guild || + (!guild && + ((dbRegister === true && hasInquiry === false) || + (isAdmin && isInquiryDone)))))); + + const shouldShowInquiryForm = !guild && !isInquiryDone; + const shouldShowFormContent = guild || isInquiryDone; + + return ( +
    + + {shouldShowUpdateButton && ( + + )} + + {shouldShowInquiryForm && ( + + )} + + {shouldShowFormContent && ( + <> + + + + + + + + اطلاعات صنفی + + + + + {guildsList.map((guildItem, index) => ( + + handleDeleteGuild(index)} + canDelete={ + (guildsList.length > 1 || !guild) && isAdmin + } + guildFormValues={guildsFormValues[index]} + onGuildValuesChange={handleGuildValuesChange} + expanded={expandedAccordion === index} + onChange={handleAccordionChange(index)} + /> + + ))} + + {isAdmin && ( + + + + )} + + + + + {hasRegisterCode && + (!(!guild && hasInquiry === true) || + isAdmin || + isSuperAdmin || + isKillHouse) && ( + formik.setFieldValue("isAccepted", true)} + onReject={() => formik.setFieldValue("isAccepted", false)} + /> + )} + + dispatch(CLOSE_MODAL())} + showCloseButton={ + !guild && + hasInquiry === true && + !isAdmin && + !isSuperAdmin && + !isKillHouse + } + isKillHouse={isKillHouse} + onSubmit={formik.handleSubmit} + /> + + + )} + + + + ); +}; diff --git a/src/features/province/components/create-guilds/components/ConfirmationDialog.js b/src/features/province/components/create-guilds/components/ConfirmationDialog.js new file mode 100644 index 0000000..9274cf3 --- /dev/null +++ b/src/features/province/components/create-guilds/components/ConfirmationDialog.js @@ -0,0 +1,45 @@ +import React from "react"; +import { + Button, + Typography, + ListItem, + ListItemIcon, + ListItemText, +} from "@mui/material"; +import { Grid } from "../../../../../components/grid/Grid"; +import { SPACING } from "../../../../../data/spacing"; +import { DialogAlert } from "../../../../../components/dialog-alert/DialogAlert"; +import { Done } from "@mui/icons-material"; + +export const ConfirmationDialog = ({ isAccepted, onAccept, onReject }) => { + return ( + + + + + + + + + + + } + actions={ + + + + + } + btnTitle="تایید صحت اطلاعات" + isAccepted={isAccepted} + /> + + ); +}; diff --git a/src/features/province/components/create-guilds/components/FormActions.js b/src/features/province/components/create-guilds/components/FormActions.js new file mode 100644 index 0000000..3fdabae --- /dev/null +++ b/src/features/province/components/create-guilds/components/FormActions.js @@ -0,0 +1,69 @@ +import React from "react"; +import { Button, Typography, Checkbox, FormControlLabel } from "@mui/material"; +import { Grid } from "../../../../../components/grid/Grid"; + +export const FormActions = ({ + formik, + onClose, + showCloseButton, + isKillHouse, + onSubmit, +}) => { + if (showCloseButton) { + return ( + + + + ); + } + + // For KillHouse: check if area_activity contains "مرغ" + const isAreaActivityValid = isKillHouse + ? formik.values.area_activity && formik.values.area_activity.includes("مرغ") + : true; + + return ( + <> + + + } + label="احراز شماره موبایل" + /> + + + + {isKillHouse && !isAreaActivityValid && ( + + رسته واحد صنفی باید شامل کلمه "مرغ" باشد + + )} + + + ); +}; diff --git a/src/features/province/components/create-guilds/components/GuildInfoAccordionItem.js b/src/features/province/components/create-guilds/components/GuildInfoAccordionItem.js new file mode 100644 index 0000000..4fbec3d --- /dev/null +++ b/src/features/province/components/create-guilds/components/GuildInfoAccordionItem.js @@ -0,0 +1,97 @@ +import React from "react"; +import { + Accordion, + AccordionSummary, + AccordionDetails, + Typography, + IconButton, +} from "@mui/material"; +import { + ExpandMore as ExpandMoreIcon, + Delete as DeleteIcon, +} from "@mui/icons-material"; +import { GuildInfoSection } from "./GuildInfoSection"; + +export const GuildInfoAccordionItem = ({ + guildIndex, + guildData, + guildActive, + isAdmin, + cities, + typeActivities, + onDelete, + canDelete, + guildFormValues, + onGuildValuesChange, + expanded, + onChange, +}) => { + // Create a formik-like object for this guild's values + const guildFormik = { + values: guildFormValues || {}, + setFieldValue: (fieldName, value) => { + onGuildValuesChange(guildIndex, fieldName, value); + }, + handleChange: (e) => { + onGuildValuesChange(guildIndex, e.target.name, e.target.value); + }, + handleBlur: () => {}, + errors: {}, + touched: {}, + }; + const getGuildTitle = () => { + if (guildData?.guildsName) { + return guildData.guildsName; + } + if (guildData?.title) { + return guildData.title; + } + if (guildFormik.values.guild_name) { + return guildFormik.values.guild_name; + } + return `واحد صنفی ${guildIndex + 1}`; + }; + + return ( + + } + sx={{ + "& .MuiAccordionSummary-content": { + alignItems: "center", + justifyContent: "space-between", + }, + }} + > + + {getGuildTitle()} + + {canDelete && ( + { + e.stopPropagation(); + onDelete(); + }} + color="error" + size="small" + sx={{ mr: 1 }} + > + + + )} + + + + + + ); +}; diff --git a/src/features/province/components/create-guilds/components/GuildInfoSection.js b/src/features/province/components/create-guilds/components/GuildInfoSection.js new file mode 100644 index 0000000..27b354a --- /dev/null +++ b/src/features/province/components/create-guilds/components/GuildInfoSection.js @@ -0,0 +1,566 @@ +import React from "react"; +import { + TextField, + Typography, + RadioGroup, + FormControl, + Radio, + FormControlLabel, + Select, + MenuItem, + InputLabel, + Checkbox, +} from "@mui/material"; +import { DatePicker } from "@mui/x-date-pickers"; +import moment from "moment"; +import BusinessIcon from "@mui/icons-material/Business"; +import PublicIcon from "@mui/icons-material/Public"; +import LocationCityIcon from "@mui/icons-material/LocationCity"; +import DateRangeIcon from "@mui/icons-material/DateRange"; +import ConfirmationNumberIcon from "@mui/icons-material/ConfirmationNumber"; +import AccountBalanceIcon from "@mui/icons-material/AccountBalance"; +import LocalPostOfficeIcon from "@mui/icons-material/LocalPostOffice"; +import PhoneIcon from "@mui/icons-material/Phone"; +import BadgeIcon from "@mui/icons-material/Badge"; +import CheckCircleIcon from "@mui/icons-material/CheckCircle"; +import HomeIcon from "@mui/icons-material/Home"; +import CorporateFareIcon from "@mui/icons-material/CorporateFare"; +import { Grid } from "../../../../../components/grid/Grid"; +import { SPACING } from "../../../../../data/spacing"; +import { LabelField } from "../../../../../components/label-field/LabelField"; +import { InfoBox } from "./InfoBox"; +import { STATUS_VALUES } from "../constants"; +import { + convertPersianToGregorian, + convertGregorianToPersian, +} from "../utils/dateUtils"; + +export const GuildInfoSection = ({ + formik, + guild, + guildActive, + isAdmin, + cities, + typeActivities, + hideTitle = false, + noGridWrapper = false, +}) => { + const getForeignerDisplay = (isForeigner) => { + if (isForeigner === STATUS_VALUES.NO || isForeigner === false) + return STATUS_VALUES.NO; + if (isForeigner === STATUS_VALUES.YES || isForeigner === true) + return STATUS_VALUES.YES; + return "-"; + }; + + const getLicenseExpireDateDisplay = () => { + return formik.values.license_expire_date || "-"; + }; + + const getActiveStatusDisplay = () => { + const activeValue = + formik.values.active !== null + ? formik.values.active + : guild?.active === true || guildActive === true; + return activeValue === true ? "فعال" : "غیر فعال"; + }; + + const content = ( + + {!hideTitle && ( + + + اطلاعات صنفی + + + )} + + + + {isAdmin ? ( + + ) : ( + + )} + + + {isAdmin ? ( + + + رسته واحد صنفی + + + + ) : ( + + )} + + + {isAdmin ? ( + + ) : ( + + )} + + + {isAdmin ? ( + + شهرستان + + + ) : ( + + )} + + + {isAdmin ? ( + { + if (newValue) { + const gregorianDate = moment(newValue).format("YYYY-MM-DD"); + const persianDate = + convertGregorianToPersian(gregorianDate); + formik.setFieldValue("license_expire_date", persianDate); + } else { + formik.setFieldValue("license_expire_date", ""); + } + }} + renderInput={(params) => ( + + )} + /> + ) : ( + + )} + + + {isAdmin ? ( + + ) : ( + + )} + + + {isAdmin ? ( + + ) : ( + + )} + + + {isAdmin ? ( + + + { + formik.setFieldValue( + "active", + e.target.value === "true" ? true : false + ); + }} + sx={{ justifyContent: "space-around" }} + > + } + label="فعال" + /> + } + label="غیر فعال" + /> + + + + ) : ( + + )} + + + + + {isAdmin ? ( + + ) : ( + + )} + + + {isAdmin ? ( + + ) : ( + + )} + + + {isAdmin ? ( + + + { + formik.setFieldValue( + "is_foreigner", + e.target.value === "بلی" ? "بلی" : "خیر" + ); + }} + sx={{ justifyContent: "space-around" }} + > + } + label="بلی" + /> + } + label="خیر" + /> + + + + ) : ( + + )} + + + {isAdmin ? ( + + ) : ( + + )} + + + {isAdmin ? ( + + ) : ( + + )} + + + {isAdmin ? ( + + ) : ( + + )} + + + {isAdmin ? ( + + ) : ( + + )} + + + + + {isAdmin ? ( + <> + + formik.setFieldValue("steward", e.target.checked) + } + name="steward" + color="primary" + /> + } + label="مباشر" + /> + + formik.setFieldValue("guild", e.target.checked) + } + name="guild" + color="primary" + /> + } + label="صنف" + /> + + ) : ( + <> + + + + )} + + + ); + + if (noGridWrapper) { + return <>{content}; + } + + return ( + + {content} + + ); +}; diff --git a/src/features/province/components/create-guilds/components/InfoBox.js b/src/features/province/components/create-guilds/components/InfoBox.js new file mode 100644 index 0000000..197787d --- /dev/null +++ b/src/features/province/components/create-guilds/components/InfoBox.js @@ -0,0 +1,23 @@ +import React from "react"; +import { Box, Typography } from "@mui/material"; + +export const InfoBox = ({ icon: Icon, label, value, iconSx }) => ( + + + + + {label} + + {value || "-"} + + +); + diff --git a/src/features/province/components/create-guilds/components/InquiryForm.js b/src/features/province/components/create-guilds/components/InquiryForm.js new file mode 100644 index 0000000..aed5934 --- /dev/null +++ b/src/features/province/components/create-guilds/components/InquiryForm.js @@ -0,0 +1,34 @@ +import React from "react"; +import { TextField, Button } from "@mui/material"; + +export const InquiryForm = ({ + inquiryNationalCode, + setInquiryNationalCode, + onInquiry, + isAdmin, +}) => { + return ( + <> + setInquiryNationalCode(e.target.value)} + placeholder={ + isAdmin ? "کد ملی را وارد کنید" : "کد ملی 10 رقمی را وارد کنید" + } + inputProps={isAdmin ? {} : { maxLength: 10 }} + /> + + + ); +}; diff --git a/src/features/province/components/create-guilds/components/PersonalInfoSection.js b/src/features/province/components/create-guilds/components/PersonalInfoSection.js new file mode 100644 index 0000000..cf634a3 --- /dev/null +++ b/src/features/province/components/create-guilds/components/PersonalInfoSection.js @@ -0,0 +1,369 @@ +import React from "react"; +import { + TextField, + Typography, + RadioGroup, + FormControl, + Radio, + FormControlLabel, +} from "@mui/material"; +import { DatePicker } from "@mui/x-date-pickers"; +import moment from "moment"; +import PersonIcon from "@mui/icons-material/Person"; +import PhoneIcon from "@mui/icons-material/Phone"; +import BadgeIcon from "@mui/icons-material/Badge"; +import CakeIcon from "@mui/icons-material/Cake"; +import FaceIcon from "@mui/icons-material/Face"; +import LocationCityIcon from "@mui/icons-material/LocationCity"; +import FavoriteIcon from "@mui/icons-material/Favorite"; +import { Grid } from "../../../../../components/grid/Grid"; +import { SPACING } from "../../../../../data/spacing"; +import { LabelField } from "../../../../../components/label-field/LabelField"; +import { InfoBox } from "./InfoBox"; +import { GENDER_VALUES, ALIVE_STATUS } from "../constants"; +import { + convertPersianToGregorian, + convertGregorianToPersian, +} from "../utils/dateUtils"; + +export const PersonalInfoSection = ({ + formik, + guild, + hasInquiry, + isAdmin, + isSuperAdmin, + isKillHouse, +}) => { + const getGenderDisplay = (gender) => { + if (gender === "True" || gender === true) return GENDER_VALUES.MALE; + if (gender === "False" || gender === false) return GENDER_VALUES.FEMALE; + return "-"; + }; + + const getAliveStatusDisplay = (isAlive) => { + if (isAlive === ALIVE_STATUS.YES || isAlive === true) + return ALIVE_STATUS.YES; + if (isAlive === ALIVE_STATUS.NO || isAlive === false) + return ALIVE_STATUS.NO; + return "-"; + }; + + const getBirthDateDisplay = () => { + return formik.values.birth_date || "-"; + }; + + return ( + + + + + اطلاعات شخصی + + + + + + {guild || isAdmin ? ( + + ) : ( + + )} + + + {isAdmin ? ( + + ) : ( + + )} + + + {isAdmin ? ( + + ) : ( + + )} + + + {isAdmin ? ( + + ) : ( + + )} + + + {isAdmin ? ( + + + { + formik.setFieldValue( + "is_alive", + e.target.value === "بلی" ? "بلی" : "خیر" + ); + }} + sx={{ justifyContent: "space-around" }} + > + } + label="بلی" + /> + } + label="خیر" + /> + + + + ) : ( + + )} + + + + + {isAdmin ? ( + { + if (newValue) { + const gregorianDate = + moment(newValue).format("YYYY-MM-DD"); + const persianDate = + convertGregorianToPersian(gregorianDate); + formik.setFieldValue("birth_date", persianDate); + } else { + formik.setFieldValue("birth_date", ""); + } + }} + renderInput={(params) => ( + + )} + /> + ) : ( + + )} + + + {isAdmin ? ( + + ) : ( + + )} + + + {isAdmin ? ( + + + { + formik.setFieldValue("gender", e.target.value); + }} + sx={{ justifyContent: "space-around" }} + > + } + label="مرد" + /> + } + label="زن" + /> + + + + ) : ( + + )} + + + {isAdmin ? ( + + ) : ( + + )} + + + {!guild && + hasInquiry && + !isAdmin && + !isSuperAdmin && + !isKillHouse ? ( + + ) : isKillHouse && + formik.values.mobile && + /^[0-9]{11}$/.test(formik.values.mobile) ? ( + + ) : ( + + )} + + + + + + ); +}; diff --git a/src/features/province/components/create-guilds/components/UpdateFromExternalButton.js b/src/features/province/components/create-guilds/components/UpdateFromExternalButton.js new file mode 100644 index 0000000..a13e138 --- /dev/null +++ b/src/features/province/components/create-guilds/components/UpdateFromExternalButton.js @@ -0,0 +1,19 @@ +import React from "react"; +import { Button } from "@mui/material"; +import { Refresh } from "@mui/icons-material"; +import { Grid } from "../../../../../components/grid/Grid"; + +export const UpdateFromExternalButton = ({ onUpdate, disabled }) => { + return ( + + + + ); +}; diff --git a/src/features/province/components/create-guilds/constants.js b/src/features/province/components/create-guilds/constants.js new file mode 100644 index 0000000..0a1b96b --- /dev/null +++ b/src/features/province/components/create-guilds/constants.js @@ -0,0 +1,17 @@ +export const STATUS_VALUES = { + YES: "بلی", + NO: "خیر", + TRUE: "True", + FALSE: "False", +}; + +export const GENDER_VALUES = { + MALE: "مرد", + FEMALE: "زن", +}; + +export const ALIVE_STATUS = { + YES: "بلی", + NO: "خیر", +}; + diff --git a/src/features/province/components/create-guilds/utils/dataMapping.js b/src/features/province/components/create-guilds/utils/dataMapping.js new file mode 100644 index 0000000..aa02a38 --- /dev/null +++ b/src/features/province/components/create-guilds/utils/dataMapping.js @@ -0,0 +1,232 @@ +import { getRoleFromUrl } from "../../../../../utils/getRoleFromUrl"; +import { normalizeExternalApiDate, normalizeDatabaseDate } from "./dateUtils"; +import { formatDateForSubmit } from "./dateUtils"; + +export const prepareSubmitData = ( + values, + guild, + originalPhoneNumber, + hasInquiry +) => { + const baseData = { + national_id: values.national_id, + mobile: values.mobile, + mobilenumber: values.mobile, + steward: !!values.steward, + guild: !!values.guild, + active_register_code: !!values.verify_mobile, + firstName: values.first_name || "", + lastName: values.last_name || "", + fatherName: values.father_name || "", + gender: values.gender || "", + identityNo: values.national_code || "", + isLive: values.is_alive === "بلی" || values.is_alive === true, + birthDate: formatDateForSubmit( + values.birth_date || "", + hasInquiry === true + ), + city: values.city || "", + address: values.address || "", + postalcode: values.postal_code || "", + licenseNumber: values.license_number || "", + licenseExpireDate: formatDateForSubmit( + values.license_expire_date || "", + hasInquiry === true + ), + licenseIssueDate: formatDateForSubmit( + values.license_issue_date || "", + hasInquiry === true + ), + licenseType: values.license_type || "", + licenseStatus: values.license_status || "", + isicname: values.area_activity || "", + corporationName: values.corporation_name || "", + nationalId: values.guild_national_id || "", + unionName: values.union_name || "", + phonenumber: values.phone_number || "", + hasPartner: values.has_partner === true || values.has_partner === "بلی", + isForeigner: values.is_foreigner === true || values.is_foreigner === "بلی", + title: values.guild_name || "", + role: getRoleFromUrl(), + has_inquiry: hasInquiry !== null ? hasInquiry : false, + ...(values.active !== null && { active: values.active }), + }; + + if (guild) { + baseData.guilds_key = guild.key; + if (values.mobile !== originalPhoneNumber) { + baseData.mobile = values.mobile; + baseData.mobilenumber = values.mobile; + } + } + + return baseData; +}; + +export const mapResponseDataToFormFields = ( + responseData, + inquiryNationalCode, + formik +) => { + const isExternalApi = responseData.dbRegister === false; + + // New structure: user is at top level, guilds is an array + const userData = responseData.user || {}; + // For personal info, we use the first guild's data if available, or empty + const firstGuild = + Array.isArray(responseData.guilds) && responseData.guilds.length > 0 + ? responseData.guilds[0] + : {}; + const guildData = firstGuild || {}; + const layerTwo = guildData.layerTwo || {}; + const addressData = firstGuild?.address || guildData.address || {}; + const provinceData = addressData.province || {}; + const cityData = addressData.city || {}; + + const nationalIdValue = isExternalApi + ? String( + layerTwo.nationalcode || userData.nationalCode || inquiryNationalCode + ).trim() + : String(userData.nationalId || inquiryNationalCode).trim(); + + const birthDatePersian = isExternalApi + ? normalizeExternalApiDate(userData.birthDate || "") + : normalizeDatabaseDate(userData.birthday || ""); + + const licenseExpireDatePersian = isExternalApi + ? normalizeExternalApiDate(guildData.licenseExpireDate || "") + : normalizeDatabaseDate(firstGuild.licenseExpireDate || ""); + + const licenseIssueDatePersian = isExternalApi + ? normalizeExternalApiDate(layerTwo.licenseIssueDate || "") + : normalizeDatabaseDate(responseData.licenseIssueDate || ""); + + const genderValue = isExternalApi + ? userData.gender === true + ? "True" + : userData.gender === false + ? "False" + : "" + : userData.gender || ""; + + const isAliveValue = isExternalApi + ? userData.isLive === true + ? "بلی" + : userData.isLive === false + ? "خیر" + : "" + : userData.isAlive === false + ? "خیر" + : userData.isAlive === true + ? "بلی" + : ""; + + const isForeignerValue = isExternalApi + ? layerTwo.isForeigner === "خیر" + ? false + : layerTwo.isForeigner === "بلی" + ? true + : "" + : responseData.isForeignNational === false + ? false + : responseData.isForeignNational === true + ? true + : ""; + + const hasStewardValue = isExternalApi + ? layerTwo.hasSteward === "خیر" + ? false + : layerTwo.hasSteward === "بلی" + ? true + : "" + : responseData.steward === false + ? false + : responseData.steward === true + ? true + : ""; + + const hasPartnerValue = isExternalApi + ? layerTwo.hasPartner === "خیر" + ? false + : layerTwo.hasPartner === "بلی" + ? true + : "" + : responseData.hasPartner === false + ? false + : responseData.hasPartner === true + ? true + : ""; + + const values = { + first_name: userData.firstName || "", + last_name: userData.lastName || "", + national_id: nationalIdValue, + national_code: isExternalApi + ? userData.identityNo || "" + : userData.nationalCode || "", + birth_date: birthDatePersian, + father_name: userData.fatherName || "", + gender: genderValue, + person_city: userData.city || "", + is_alive: isAliveValue, + // Guild fields - will be set per guild in accordion, so we set empty or first guild's data + guild_name: isExternalApi + ? guildData.title || "" + : firstGuild.guildsName || "", + area_activity: isExternalApi + ? guildData.isicname || "" + : firstGuild.areaActivity || "", + state: isExternalApi ? guildData.state || "" : provinceData.name || "", + city: isExternalApi ? guildData.city || "" : cityData.name || "", + address: isExternalApi + ? guildData.address || "" + : addressData.address || "", + license_expire_date: licenseExpireDatePersian, + license_status: isExternalApi + ? guildData.licenseStatus || "" + : firstGuild.licenseStatus || "", + license_type: isExternalApi + ? guildData.licenseType || "" + : firstGuild.licenseType || "", + license_number: isExternalApi + ? guildData.licenseNumber || "" + : firstGuild.licenseNumber || "", + union_name: isExternalApi + ? layerTwo.unionName || "" + : firstGuild.unionName || "", + postal_code: isExternalApi + ? layerTwo.postalcode || "" + : addressData.postalCode || "", + phone_number: isExternalApi + ? layerTwo.phonenumber || "" + : firstGuild.phoneNumber || "", + mobile: isExternalApi ? layerTwo.mobilenumber || "" : userData.mobile || "", + guild_national_id: isExternalApi + ? layerTwo.nationalId || "" + : firstGuild.nationalCode || "", + is_foreigner: isForeignerValue, + corporation_name: isExternalApi + ? layerTwo.corporationName || "" + : firstGuild.companyName || "", + has_steward: hasStewardValue, + has_partner: hasPartnerValue, + steward: isExternalApi ? false : firstGuild.isSteward || false, + guild: isExternalApi + ? typeof guildData.guild === "boolean" + ? guildData.guild + : false + : typeof firstGuild.guild === "boolean" + ? firstGuild.guild + : false, + license_issue_date: licenseIssueDatePersian, + ...(isExternalApi + ? {} + : { + company_name: firstGuild.companyName || "", + company_identifier: firstGuild.companyIdentifier || "", + type_activity_name: firstGuild.typeActivity || "", + }), + }; + + formik.setValues({ ...formik.values, ...values }); +}; diff --git a/src/features/province/components/create-guilds/utils/dateUtils.js b/src/features/province/components/create-guilds/utils/dateUtils.js new file mode 100644 index 0000000..76b0982 --- /dev/null +++ b/src/features/province/components/create-guilds/utils/dateUtils.js @@ -0,0 +1,158 @@ +import { + convertToIranianTime, + convertPersianToEnglishNumerals, +} from "../../../../../utils/formatTime"; +import { fromJalali } from "../../../../../utils/jalali"; + +export const convertGregorianToPersian = (gregorianDateString) => { + if (!gregorianDateString || typeof gregorianDateString !== "string") { + return ""; + } + + // Check if the date is already in Persian format (YYYY/MM/DD with year < 1500) + const persianPattern = /^\d{4}\/\d{2}\/\d{2}$/; + if (persianPattern.test(gregorianDateString)) { + const year = parseInt(gregorianDateString.split("/")[0]); + // If year is < 1500, it's likely Persian, return as is + if (year < 1500) { + return gregorianDateString; + } + } + + // Try to convert using convertToIranianTime + try { + return convertToIranianTime(gregorianDateString); + } catch (error) { + console.error("Error converting Gregorian date to Persian:", error); + return gregorianDateString; // Return original on error + } +}; + +export const convertPersianToGregorian = (persianDateString) => { + if (!persianDateString || typeof persianDateString !== "string") { + return ""; + } + + const normalizedDateString = + convertPersianToEnglishNumerals(persianDateString); + + const gregorianPattern = /^\d{4}[-/]\d{2}[-/]\d{2}$/; + if (gregorianPattern.test(normalizedDateString)) { + const year = parseInt(normalizedDateString.split(/[-/]/)[0]); + if (year > 1500) { + return normalizedDateString.replace(/\//g, "-"); + } + } + + const parts = normalizedDateString.split("/"); + if (parts.length !== 3) { + return persianDateString; + } + + const py = parseInt(parts[0]); + const pm = parseInt(parts[1]); + const pd = parseInt(parts[2]); + + if (isNaN(py) || isNaN(pm) || isNaN(pd)) { + return persianDateString; + } + + try { + const gregorianDate = fromJalali(py, pm, pd); + const year = gregorianDate.getFullYear(); + const month = String(gregorianDate.getMonth() + 1).padStart(2, "0"); + const day = String(gregorianDate.getDate()).padStart(2, "0"); + return `${year}-${month}-${day}`; + } catch (error) { + console.error("Error converting Persian date to Gregorian:", error); + return persianDateString; + } +}; + +export const normalizeExternalApiDate = (dateString) => { + if (!dateString || typeof dateString !== "string") { + return ""; + } + return convertPersianToEnglishNumerals(dateString); +}; + +export const normalizeDatabaseDate = (dateString) => { + if (!dateString || typeof dateString !== "string") { + return ""; + } + const first10Chars = dateString.substring(0, 10); + const normalizedDate = first10Chars.replace(/-/g, "/"); + return convertToIranianTime(normalizedDate); +}; + +export const formatDateForSubmitExternal = (dateString) => { + if (!dateString || typeof dateString !== "string") { + return ""; + } + return convertPersianToEnglishNumerals(dateString); +}; + +export const formatDateForSubmitDatabase = (dateString) => { + if (!dateString || typeof dateString !== "string") { + return ""; + } + + const normalizedDate = convertPersianToEnglishNumerals(dateString); + const persianPattern = /^\d{4}\/\d{2}\/\d{2}$/; + + if (persianPattern.test(normalizedDate)) { + const year = parseInt(normalizedDate.split("/")[0]); + if (year < 1500) { + const parts = normalizedDate.split("/"); + const py = parseInt(parts[0]); + const pm = parseInt(parts[1]); + const pd = parseInt(parts[2]); + + if (!isNaN(py) && !isNaN(pm) && !isNaN(pd)) { + try { + const gregorianDate = fromJalali(py, pm, pd); + const gy = gregorianDate.getFullYear(); + const gm = String(gregorianDate.getMonth() + 1).padStart(2, "0"); + const gd = String(gregorianDate.getDate()).padStart(2, "0"); + return `${gy}/${gm}/${gd}`; + } catch (error) { + console.error("Error converting Persian to Gregorian:", error); + } + } + } + } + + const gregorianPattern = /^\d{4}[-/]\d{2}[-/]\d{2}$/; + if (gregorianPattern.test(normalizedDate)) { + const year = parseInt(normalizedDate.split(/[-/]/)[0]); + if (year > 1900) { + return normalizedDate.replace(/-/g, "/"); + } + } + + try { + const date = new Date(normalizedDate); + if (!isNaN(date.getTime())) { + const year = date.getFullYear(); + const month = String(date.getMonth() + 1).padStart(2, "0"); + const day = String(date.getDate()).padStart(2, "0"); + return `${year}/${month}/${day}`; + } + } catch (error) { + console.error("Error formatting database date:", error); + } + + return normalizedDate.replace(/-/g, "/"); +}; + +export const formatDateForSubmit = (dateString, isExternalApi = false) => { + if (!dateString || typeof dateString !== "string") { + return ""; + } + + if (isExternalApi) { + return formatDateForSubmitExternal(dateString); + } else { + return formatDateForSubmitDatabase(dateString); + } +}; diff --git a/src/features/province/components/create-guilds/utils/formUtils.js b/src/features/province/components/create-guilds/utils/formUtils.js new file mode 100644 index 0000000..8287371 --- /dev/null +++ b/src/features/province/components/create-guilds/utils/formUtils.js @@ -0,0 +1,95 @@ +import * as yup from "yup"; +import { normalizeDatabaseDate } from "./dateUtils"; + +export const getValidationSchema = (isEditMode) => + yup.object({ + national_id: yup + .string() + .required("کد ملی الزامی است") + .matches(/^[0-9]{10}$/, "کد ملی باید 10 رقم باشد"), + mobile: isEditMode + ? yup + .string() + .nullable() + .test( + "mobile-format", + "شماره تلفن باید 11 رقم باشد", + (value) => !value || /^[0-9]{11}$/.test(value) + ) + : yup + .string() + .required("شماره تلفن الزامی است") + .matches(/^[0-9]{11}$/, "شماره تلفن باید 11 رقم باشد"), + first_name: yup.string(), + last_name: yup.string(), + guild_name: yup.string(), + guild_category: yup.string(), + state: yup.string(), + city: yup.string(), + address: yup.string(), + license_expire_date: yup.string(), + license_status: yup.string(), + union_name: yup.string(), + postal_code: yup.string(), + guild_national_id: yup.string(), + is_foreigner: yup.string(), + national_code: yup.string(), + has_steward: yup.string(), + has_partner: yup.string(), + license_number: yup.string(), + isAccepted: yup + .boolean() + .test("req", "باید تعهد نامه را بپذیرید!", (val) => { + return val === true; + }) + .required("این فیلد اجباری است!"), + }); + +export const getInitialValues = (guild) => ({ + first_name: guild?.user?.firstName || "", + last_name: guild?.user?.lastName || "", + corporation_name: guild?.companyName || "", + national_id: guild?.user?.nationalId || "", + national_code: guild?.user?.nationalCode || "", + birth_date: normalizeDatabaseDate(guild?.user?.birthday || ""), + father_name: guild?.user?.fatherName || "", + gender: guild?.user?.gender || "", + person_city: guild?.user?.city || "", + is_alive: guild?.user?.isAlive || "", + guild_name: guild?.guildsName || "", + area_activity: guild?.areaActivity || "", + state: guild?.address?.province?.name || "", + city: guild?.address?.city?.name || "", + address: guild?.address?.address || "", + license_expire_date: normalizeDatabaseDate(guild?.licenseExpireDate || ""), + license_status: guild?.licenseStatus || "", + license_type: guild?.licenseType || "", + union_name: guild?.unionName || "", + postal_code: guild?.address?.postalCode || "", + phone_number: guild?.phoneNumber || "", + mobile: guild?.user?.mobile || "", + is_foreigner: guild?.is_foreign_national || "", + has_steward: guild?.hasSteward || "", + has_partner: guild?.hasPartner || "", + license_number: guild?.licenseNumber || "", + isAccepted: guild?.provinceAcceptState === "accepted" || false, + steward: + typeof guild?.steward === "boolean" + ? guild.steward + : typeof guild?.isSteward === "boolean" + ? guild.isSteward + : false, + guild: + typeof guild?.guild === "boolean" + ? guild.guild + : typeof guild?.isGuild === "boolean" + ? guild.isGuild + : false, + verify_mobile: guild?.verifyMobile || false, + guild_national_id: guild?.nationalId || "", + license_issue_date: normalizeDatabaseDate(guild?.licenseIssueDate || ""), + company_name: guild?.companyName || "", + company_identifier: guild?.companyIdentifier || "", + type_activity_name: guild?.typeActivityName || "", + active: guild?.active ?? null, +}); diff --git a/src/features/province/components/create-guilds/utils/submitHandlers.js b/src/features/province/components/create-guilds/utils/submitHandlers.js new file mode 100644 index 0000000..da6ac30 --- /dev/null +++ b/src/features/province/components/create-guilds/utils/submitHandlers.js @@ -0,0 +1,45 @@ +import { + CLOSE_MODAL, + OPEN_MODAL, +} from "../../../../../lib/redux/slices/appSlice"; +import { ProvinceManageGuildsSubmitRegisterCode } from "../../province-manage-guilds-submit-register-code/ProvinceManageGuildsSubmitRegisterCode"; + +export const handleSubmitSuccess = ( + dispatch, + openNotif, + updateTable, + values, + responseData +) => { + updateTable(); + openNotif({ + vertical: "top", + horizontal: "center", + msg: "عملیات با موفقیت انجام شد.", + severity: "success", + }); + dispatch(CLOSE_MODAL()); + + if (values.verify_mobile && responseData) { + dispatch( + OPEN_MODAL({ + title: "ثبت کد احراز", + content: ( + + ), + }) + ); + } +}; + +export const handleSubmitError = (openNotif, error) => { + openNotif({ + vertical: "top", + horizontal: "center", + msg: error, + severity: "error", + }); +}; diff --git a/src/features/province/components/create-stewards/CreateStewards.js b/src/features/province/components/create-stewards/CreateStewards.js new file mode 100644 index 0000000..a966617 --- /dev/null +++ b/src/features/province/components/create-stewards/CreateStewards.js @@ -0,0 +1,81 @@ +import { Autocomplete, Button, TextField } from "@mui/material"; +import { useFormik } from "formik"; +import { useContext, useEffect } from "react"; +import { useDispatch, useSelector } from "react-redux"; +import * as yup from "yup"; +import { Grid } from "../../../../components/grid/Grid"; +import { AppContext } from "../../../../contexts/AppContext"; +import { SPACING } from "../../../../data/spacing"; +import { DRAWER } from "../../../../lib/redux/slices/appSlice"; +import { provinceCreateStewardService } from "../../services/province-create-steward"; +import { provinceGetGuildsService } from "../../services/province-get-guilds"; + +const validationSchema = yup.object({ + // guild: yup.string().required(""), +}); + +export const CreateStewards = ({ guild }) => { + const dispatch = useDispatch(); + const [openNotif] = useContext(AppContext); + const { provinceGetGuildsOptions } = useSelector( + (state) => state.provinceSlice + ); + + useEffect(() => { + dispatch(provinceGetGuildsService()); + }, []); + + const formik = useFormik({ + initialValues: { + guild: null, + }, + validationSchema, + onSubmit: (values) => { + // Handle form submission here + dispatch( + provinceCreateStewardService({ guilds_key: values.guild.value }) + ).then((r) => { + if (r.payload.error) { + openNotif({ + vertical: "top", + horizontal: "center", + msg: r.payload.error, + severity: "error", + }); + } else { + dispatch(DRAWER({ right: false, bottom: false, content: null })); + openNotif({ + vertical: "top", + horizontal: "center", + msg: "عملیات با موفقیت انجام شد.", + severity: "success", + }); + } + }); + }, + }); + + return ( +
    + + { + formik.setFieldValue("guild", v); + }} + error={formik.touched.guild && Boolean(formik.errors.guild)} + helperText={formik.touched.guild && formik.errors.guild} + getOptionLabel={(option) => option.label} + renderInput={(params) => ( + + )} + /> + + +
    + ); +}; diff --git a/src/features/province/components/edit-poultry-city/EditPoultryCity.js b/src/features/province/components/edit-poultry-city/EditPoultryCity.js new file mode 100644 index 0000000..102421e --- /dev/null +++ b/src/features/province/components/edit-poultry-city/EditPoultryCity.js @@ -0,0 +1,50 @@ +import { Autocomplete, Button, TextField } from "@mui/material"; +import { useEffect, useState } from "react"; +import { useDispatch, useSelector } from "react-redux"; +import { Grid } from "../../../../components/grid/Grid"; +import { CLOSE_MODAL } from "../../../../lib/redux/slices/appSlice"; +import { getCitiesService } from "../../services/get-cities"; +import { provinceEditPoultryCityService } from "../../services/province-edit-poultry-city"; + +export const EditPoultryCity = ({ item, updateTable }) => { + const dispatch = useDispatch(); + const [sellected, setSellected] = useState(); + const { getCitiesOptions } = useSelector((state) => state.provinceSlice); + const getOptionLabel = (option) => option.label; // Customize how the label is displayed + + useEffect(() => { + dispatch(getCitiesService()); + }, []); + + return ( + + setSellected(value)} + value={sellected} + renderInput={(params) => } + /> + + + ); +}; diff --git a/src/features/province/components/edit-stewards/EditStewards.js b/src/features/province/components/edit-stewards/EditStewards.js new file mode 100644 index 0000000..143b323 --- /dev/null +++ b/src/features/province/components/edit-stewards/EditStewards.js @@ -0,0 +1,167 @@ +import { + Autocomplete, + Button, + Checkbox, + FormControlLabel, + InputAdornment, + TextField, + Typography, +} from "@mui/material"; +import { useFormik } from "formik"; +import { useContext, useEffect, useState } from "react"; +import { useDispatch, useSelector } from "react-redux"; +import { Grid } from "../../../../components/grid/Grid"; +import { AppContext } from "../../../../contexts/AppContext"; +import { SPACING } from "../../../../data/spacing"; +import { DRAWER } from "../../../../lib/redux/slices/appSlice"; +import { Yup } from "../../../../lib/yup/yup"; +import { provinceEditStewardService } from "../../services/province-edit-steward"; +import { provinceGetBuyersService } from "../../services/province-get-buyers"; + +const validationSchema = Yup.object().shape({ + // agreed: Yup.boolean().oneOf([true], 'You must agree to the terms and conditions'), +}); + +export const EditStewards = ({ guild }) => { + const { provinceGetBuyersOptions } = useSelector( + (state) => state.provinceSlice + ); + const [warehouses, setWarehouses] = useState( + guild.centersAllocation ? guild.centersAllocation : [] + ); + const dispatch = useDispatch(); + const [openNotif] = useContext(AppContext); + const formik = useFormik({ + initialValues: { + allocation_limit: guild.allocationLimit, + centers_allocation: "", + limitation_allocation: guild.limitationAllocation, + }, + validationSchema, + onSubmit: (values) => { + dispatch( + provinceEditStewardService({ + allocation_limit: values.allocation_limit, + limitation_allocation: values.limitation_allocation, + centers_allocation: warehouses, + steward_key: guild.key, + }) + ).then((r) => { + if (r.payload.error) { + openNotif({ + vertical: "top", + horizontal: "center", + msg: r.payload.error, + severity: "error", + }); + } else { + dispatch(DRAWER({ right: false, bottom: false, content: null })); + openNotif({ + vertical: "top", + horizontal: "center", + msg: "عملیات با موفقیت انجام شد.", + severity: "success", + }); + } + }); + }, + }); + + useEffect(() => { + dispatch(provinceGetBuyersService()); + }, []); + + return ( +
    + + + } + label="محدودیت تخصیص" + /> + {formik.errors.limitation_allocation && ( +
    {formik.errors.limitation_allocation}
    + )} + {formik.values.limitation_allocation && ( + <> + کیلوگرم + ), + }} + value={formik.values.allocation_limit} + onChange={formik.handleChange} + error={ + formik.touched.allocation_limit && + Boolean(formik.errors.allocation_limit) + } + helperText={ + formik.touched.allocation_limit && + formik.errors.allocation_limit + } + /> + { + setWarehouses([...warehouses, item]); + }} + error={formik.touched.guild && Boolean(formik.errors.guild)} + helperText={formik.touched.guild && formik.errors.guild} + getOptionLabel={(option) => option.label} + renderInput={(params) => ( + + )} + /> + محدودیت انبار های انتخاب شده + {!warehouses.length && ( + محدودیتی وجود ندارد + )} + {warehouses?.map((item, i) => { + return ( + + + {item.label} + + ); + })} + + )} + + +
    +
    + ); +}; diff --git a/src/features/province/components/failed-transactions/FailedTransactions.js b/src/features/province/components/failed-transactions/FailedTransactions.js new file mode 100644 index 0000000..2c28314 --- /dev/null +++ b/src/features/province/components/failed-transactions/FailedTransactions.js @@ -0,0 +1,311 @@ +import { + Button, + Pagination, + TextField, + Tooltip, + Typography, +} from "@mui/material"; +import axios from "axios"; +import { useContext, useEffect, useState } from "react"; +import { RiFileExcel2Fill, RiSearchLine } from "react-icons/ri"; +import { useDispatch, useSelector } from "react-redux"; +import { Grid } from "../../../../components/grid/Grid"; +import { PageTable } from "../../../../components/page-table/PageTable"; +import { SPACING } from "../../../../data/spacing"; +import { AppContext } from "../../../../contexts/AppContext"; +import { DatePicker } from "@mui/x-date-pickers"; +import moment from "moment/moment"; +import { format } from "date-fns-jalali"; +import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl"; +import { SimpleTable } from "../../../../components/simple-table/SimpleTable"; +import { + LOADING_END, + LOADING_START, +} from "../../../../lib/redux/slices/appSlice"; + +export const FailedTransactions = () => { + const authToken = useSelector((state) => state.userSlice.authToken); + console.log(authToken); + const userInfo = useSelector((state) => state.userSlice); + + const [, , selectedDate1, setSelectedDate1, selectedDate2, setSelectedDate2] = + useContext(AppContext); + const [dataTableM, setDataTableM] = useState([]); + const dispatch = useDispatch(); + const [data, setData] = useState([]); + const [loading, setLoading] = useState(false); + const [totalRows, setTotalRows] = useState(0); + const [perPage, setPerPage] = useState(10); + + const [textValue, setTextValue] = useState(""); + + const handleTextChange = (event) => { + setTextValue(event.target.value); + }; + + const fetchApiData = async (page, textValue) => { + setLoading(true); + const response = await axios.get( + `transactions/?search=filter&value=${textValue}&page=${page}&page_size=${perPage}&date1=${selectedDate1}&date2=${selectedDate2}&state=failed&role=${getRoleFromUrl()}` + ); + setData(response.data.results); + setTotalRows(response.data.count); + setLoading(false); + }; + + const handlePageChange = (page) => { + fetchApiData(page, textValue); + }; + + const handlePerRowsChange = async (newPerPage, page) => { + setLoading(true); + const response = await axios.get( + `transactions/?search=filter&value=${textValue}&page=${page}&page_size=${newPerPage}&date1=${selectedDate1}&date2=${selectedDate2}&state=failed&role=${getRoleFromUrl()}` + ); + + setData(response.data.results); + setTotalRows(response.data.count); + setPerPage(newPerPage); + + setLoading(false); + dispatch(LOADING_END()); + }; + + const [page, setPage] = useState(0); + const handleChangePageM = (event, newPage) => { + dispatch(LOADING_START()); + setPage(newPage); + fetchApiData(newPage + 1, textValue); + }; + + useEffect(() => { + fetchApiData(1); + }, [selectedDate1, selectedDate2, perPage]); + + const handleSubmit = async (event) => { + event.preventDefault(); + setLoading(true); + try { + const response = await axios.get( + `transactions/?search=filter&value=${textValue}&date1=${selectedDate1}&date2=${selectedDate2}&state=failed&role=${getRoleFromUrl()}` + ); + setData(response.data.results); + setTotalRows(response.data.count); + } catch (error) { + console.error("Error fetching data:", error); + } finally { + setLoading(false); + } + }; + + const columns = [ + { + name: "تاریخ و زمان", + selector: (item) => { + return format(new Date(item.createDate), "yyyy/MM/dd hh:mm:ss"); + }, + sortable: true, + wrap: true, + allowOverflow: true, + center: true, + // width: "90px", + }, + { + name: "پرداخت کننده", + selector: (item) => { + return item.payer; + }, + sortable: true, + wrap: true, + allowOverflow: true, + center: true, + // width: "90px", + }, + { + name: "شماره درخواست", + selector: (item) => { + return item.orderId; + }, + sortable: true, + wrap: true, + allowOverflow: true, + center: true, + // width: "90px", + }, + { + name: "شماره پیگیری", + selector: (item) => { + return item.saleReferenceId; + }, + sortable: true, + wrap: true, + allowOverflow: true, + center: true, + // width: "90px", + }, + { + name: "کدسفارش", + selector: (item) => { + return item.orderId; + }, + sortable: true, + wrap: true, + allowOverflow: true, + center: true, + // width: "90px", + }, + { + name: "شماره کارت", + selector: (item) => { + return item.cardHolderPan; + }, + sortable: true, + wrap: true, + allowOverflow: true, + center: true, + // width: "90px", + }, + { + name: "قیمت", + selector: (item) => { + return item?.amount?.toLocaleString() + " ﷼"; + }, + sortable: true, + wrap: true, + allowOverflow: true, + center: true, + // width: "90px", + }, + { + name: "متن خطا", + selector: (item) => { + return item.message?.split("_")?.join(" "); + }, + sortable: true, + wrap: true, + allowOverflow: true, + center: true, + // width: "90px", + }, + ]; + + const tableTitle = ( + + + تراکنش های ناموفق + + + ( + + )} + value={selectedDate1} + onChange={(e) => { + setSelectedDate1(moment(e).format("YYYY-MM-DD")); + }} + /> + + + ( + + )} + value={selectedDate2} + onChange={(e) => { + setSelectedDate2(moment(e).format("YYYY-MM-DD")); + }} + /> + + +
    + + + + + + + + +
    +
    + ); + + const columnNames = columns.map((column) => column.name); + const isMobile = window.innerWidth <= 600; + + useEffect(() => { + const d = data?.map((item) => { + return [ + format(new Date(item.createDate), "yyyy/MM/dd hh:mm:ss"), + item.payerInfo, + item.refId, + item.message?.split("_")?.join(" "), + ]; + }); + + setDataTableM(d); + }, [data]); + + return ( + + {isMobile ? ( + <> + {tableTitle} + + { + handleChangePageM(event, newPage - 1); + }} + /> + + ) : ( + + )} + + ); +}; diff --git a/src/features/province/components/guild-limitaion/GuildLimitaion.js b/src/features/province/components/guild-limitaion/GuildLimitaion.js new file mode 100644 index 0000000..d56d658 --- /dev/null +++ b/src/features/province/components/guild-limitaion/GuildLimitaion.js @@ -0,0 +1,257 @@ +import { + Autocomplete, + Button, + Checkbox, + FormControlLabel, + InputAdornment, + TextField, + Typography, +} from "@mui/material"; +import { useFormik } from "formik"; +import { useContext, useEffect, useState } from "react"; +import { useDispatch, useSelector } from "react-redux"; +import { Grid } from "../../../../components/grid/Grid"; +import { AppContext } from "../../../../contexts/AppContext"; +import { SPACING } from "../../../../data/spacing"; +import { DRAWER } from "../../../../lib/redux/slices/appSlice"; +import { Yup } from "../../../../lib/yup/yup"; +import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl"; +import { provinceChangeActiveGuildService } from "../../services/province-change-active-guild"; +import { provinceGetBuyersService } from "../../services/province-get-buyers"; +import { provinceGetStewardsService } from "../../services/province-get-stewards"; +import { checkPathStartsWith } from "../../../../utils/checkPathStartsWith"; + +const validationSchema = Yup.object().shape({ + // agreed: Yup.boolean().oneOf([true], 'You must agree to the terms and conditions'), +}); + +export const GuildLimitaion = ({ guild, updateTable }) => { + const { provinceGetStewardsOptions, provinceGetBuyersOptions } = useSelector( + (state) => state.provinceSlice + ); + const selectedSubUser = useSelector( + (state) => state.userSlice.selectedSubUser + ); + const [warehouses, setWarehouses] = useState( + guild.centersAllocation ? guild.centersAllocation : [] + ); + const [buyers, setBuyers] = useState( + guild.killHouseCentersAllocation ? guild.killHouseCentersAllocation : [] + ); + + const dispatch = useDispatch(); + const [openNotif] = useContext(AppContext); + const formik = useFormik({ + initialValues: { + allocation_limit: guild.allocationLimit, + centers_allocation: "", + limitation_allocation: guild.limitationAllocation, + currentBuyer: "", + }, + validationSchema, + onSubmit: (values) => { + dispatch( + provinceChangeActiveGuildService({ + kill_house_centers_allocation: buyers, + allocation_limit: values.allocation_limit, + limitation_allocation: values.limitation_allocation, + centers_allocation: warehouses, + guilds_key: guild.key, + }) + ).then((r) => { + updateTable(); + if (r.payload.error) { + openNotif({ + vertical: "top", + horizontal: "center", + msg: r.payload.error, + severity: "error", + }); + } else { + dispatch(DRAWER({ right: false, bottom: false, content: null })); + openNotif({ + vertical: "top", + horizontal: "center", + msg: "عملیات با موفقیت انجام شد.", + severity: "success", + }); + } + }); + }, + }); + + useEffect(() => { + dispatch( + provinceGetStewardsService({ + role_key: checkPathStartsWith("province") + ? selectedSubUser?.key || "" + : "", + }) + ); + dispatch( + provinceGetBuyersService({ + role_key: checkPathStartsWith("province") + ? selectedSubUser?.key || "" + : "", + }) + ); + }, [selectedSubUser?.key]); + + return ( +
    + + + } + label="محدودیت تخصیص" + /> + {formik.errors.limitation_allocation && ( +
    {formik.errors.limitation_allocation}
    + )} + {formik.values.limitation_allocation && ( + <> + کیلوگرم + ), + }} + value={formik.values.allocation_limit} + onChange={formik.handleChange} + error={ + formik.touched.allocation_limit && + Boolean(formik.errors.allocation_limit) + } + helperText={ + formik.touched.allocation_limit && + formik.errors.allocation_limit + } + /> + {!guild?.steward && getRoleFromUrl() !== "Guilds" && ( + <> + { + setWarehouses([...warehouses, item]); + }} + error={formik.touched.guild && Boolean(formik.errors.guild)} + helperText={formik.touched.guild && formik.errors.guild} + getOptionLabel={(option) => option.label} + renderInput={(params) => ( + + )} + /> + محدودیت مباشرین انتخاب شده + {!warehouses.length && ( + محدودیتی وجود ندارد + )} + {warehouses?.map((item) => { + return ( + <> + {item !== null && ( + + + {item.label} + + )} + + ); + })} + + )} + + )} + + {formik.values.limitation_allocation && + getRoleFromUrl() !== "KillHouse" && + getRoleFromUrl() !== "Guilds" && ( + <> + { + setBuyers([...buyers, item]); + }} + error={formik.touched.guild && Boolean(formik.errors.guild)} + helperText={formik.touched.guild && formik.errors.guild} + getOptionLabel={(option) => option.label} + renderInput={(params) => ( + + )} + /> + محدودیت انبار های انتخاب شده + {!buyers.length && ( + محدودیتی وجود ندارد + )} + {buyers?.map((item) => { + return ( + <> + {item !== null && ( + + + {item.label} + + )} + + ); + })} + + )} + +
    +
    + ); +}; diff --git a/src/features/province/components/guilds-operations/GuildsOperations.js b/src/features/province/components/guilds-operations/GuildsOperations.js new file mode 100644 index 0000000..0545c00 --- /dev/null +++ b/src/features/province/components/guilds-operations/GuildsOperations.js @@ -0,0 +1,237 @@ +import { Grid } from "../../../../components/grid/Grid"; +import { SPACING } from "../../../../data/spacing"; +import { NavLink } from "../../../../components/nav-link/NavLink"; +import { useLocation } from "react-router-dom"; +import { + // ROUTE_ADMINX_ROUTE_GUILDS, + ROUTE_ADMINX_ROUTE_IN_PROVINCE_GUILDS_REQUESTS, + ROUTE_ADMINX_ROUTE_IN_PROVINCE_GUILDS, + ROUTE_ADMINX_ROUTE_MANAGE_GUILDS, + ROUTE_ADMINX_ROUTE_OUT_PROVINCE_GUILDS, + ROUTE_PROVINCE_ROUTE_IN_PROVINCE_GUILDS_REQUESTS, + ROUTE_PROVINCE_ROUTE_IN_PROVINCE_GUILDS, + ROUTE_PROVINCE_ROUTE_MANAGE_GUILDS, + ROUTE_PROVINCE_ROUTE_OUT_PROVINCE_GUILDS, + // ROUTE_SUPER_ADMIN_ROUTE_GUILDS, + ROUTE_SUPER_ADMIN_ROUTE_IN_PROVINCE_GUILDS_REQUESTS, + ROUTE_SUPER_ADMIN_ROUTE_IN_PROVINCE_GUILDS, + ROUTE_SUPER_ADMIN_ROUTE_MANAGE_GUILDS, + ROUTE_SUPER_ADMIN_ROUTE_OUT_PROVINCE_GUILDS, + ROUTE_SUPER_ADMIN_ROUTE_OUT_PROVINCE_TRUE_GUILDS, + ROUTE_ADMINX_ROUTE_OUT_PROVINCE_TRUE_GUILDS, + ROUTE_PROVINCE_ROUTE_OUT_PROVINCE_TRUE_GUILDS, + ROUTE_SUPER_ADMIN_ROUTE_OUT_PROVINCE_LEGAL_GUILDS, + ROUTE_ADMINX_ROUTE_OUT_PROVINCE_LEGAL_GUILDS, + ROUTE_PROVINCE_ROUTE_OUT_PROVINCE_LEGAL_GUILDS, + ROUTE_SUPER_ADMIN_ROUTE_IN_PROVINCE_TRUE_GUILDS, + ROUTE_ADMINX_ROUTE_IN_PROVINCE_TRUE_GUILDS, + ROUTE_PROVINCE_ROUTE_IN_PROVINCE_TRUE_GUILDS, + ROUTE_SUPER_ADMIN_ROUTE_IN_PROVINCE_LEGAL_GUILDS, + ROUTE_ADMINX_ROUTE_IN_PROVINCE_LEGAL_GUILDS, + ROUTE_PROVINCE_ROUTE_IN_PROVINCE_LEGAL_GUILDS, +} from "../../../../routes/routes"; +import LinkItem from "../../../../components/link-item/LinkItem"; +import { MdCorporateFare } from "react-icons/md"; +import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl"; +import { BackButton } from "../../../../components/back-button/BackButton"; + +export const GuildsOperations = () => { + const { pathname } = useLocation(); + + return ( + <> + {[ + ROUTE_SUPER_ADMIN_ROUTE_IN_PROVINCE_GUILDS, + ROUTE_ADMINX_ROUTE_IN_PROVINCE_GUILDS, + ROUTE_PROVINCE_ROUTE_IN_PROVINCE_GUILDS, + ROUTE_SUPER_ADMIN_ROUTE_OUT_PROVINCE_GUILDS, + ROUTE_ADMINX_ROUTE_OUT_PROVINCE_GUILDS, + ROUTE_PROVINCE_ROUTE_OUT_PROVINCE_GUILDS, + ].includes(pathname) && } + + + {[ + ROUTE_SUPER_ADMIN_ROUTE_MANAGE_GUILDS, + ROUTE_ADMINX_ROUTE_MANAGE_GUILDS, + ROUTE_PROVINCE_ROUTE_MANAGE_GUILDS, + ].includes(pathname) && ( + <> + + } + title="اصناف داخل استان" + /> + + + } + title="اصناف خارج استان" + /> + + + )} + {[ + ROUTE_SUPER_ADMIN_ROUTE_IN_PROVINCE_GUILDS, + ROUTE_ADMINX_ROUTE_IN_PROVINCE_GUILDS, + ROUTE_PROVINCE_ROUTE_IN_PROVINCE_GUILDS, + ].includes(pathname) && ( + <> + + } + title="درخواست های ثبت صنف" + /> + + {/* + } + title="اصناف" + /> + */} + + } + title="اصناف حقیقی" + /> + + + } + title="اصناف حقوقی" + /> + + {/* + } + title="مباشرین" + /> + + {(getRoleFromUrl() === "AdminX" || + getRoleFromUrl() === "SuperAdmin") && ( + + } + title="مدیریت مباشرین" + /> + + )} */} + + )} + + {[ + ROUTE_SUPER_ADMIN_ROUTE_OUT_PROVINCE_GUILDS, + ROUTE_ADMINX_ROUTE_OUT_PROVINCE_GUILDS, + ROUTE_PROVINCE_ROUTE_OUT_PROVINCE_GUILDS, + ].includes(pathname) && ( + <> + + } + title="اصناف حقیقی" + /> + + + } + title="اصناف حقوقی" + /> + + + )} + + + ); +}; diff --git a/src/features/province/components/guilds-settings/GuildsSettings.js b/src/features/province/components/guilds-settings/GuildsSettings.js new file mode 100644 index 0000000..203b5f6 --- /dev/null +++ b/src/features/province/components/guilds-settings/GuildsSettings.js @@ -0,0 +1,62 @@ +import React, { useEffect, useState } from "react"; +import { Grid } from "../../../../components/grid/Grid"; +import { useDispatch, useSelector } from "react-redux"; +import { getGuildsSettingsService } from "../../services/get-guilds-settings"; +import { ManageGuildsState } from "../manage-guilds-state/ManageGuildsState"; +import { ManageStewardsState } from "../manage-stewards-state/ManageStewardsState"; +import { + LOADING_END, + LOADING_START, +} from "../../../../lib/redux/slices/appSlice"; +import ResponsiveTable from "../../../../components/responsive-table/ResponsiveTable"; + +export const GuildsSettings = () => { + const dispatch = useDispatch(); + const [dataTable, setDataTable] = useState([]); + const { getGuildsSettings } = useSelector((state) => state.provinceSlice); + + useEffect(() => { + dispatch(LOADING_START()); + dispatch(getGuildsSettingsService({ kill_house_key: null })).then(() => { + dispatch(LOADING_END()); + }); + }, []); + + useEffect(() => { + if (Array.isArray(getGuildsSettings)) { + const d = getGuildsSettings?.map((item, i) => { + return [ + i + 1, + item.killHouse.name, + , + , + ]; + }); + setDataTable(d); + } + }, [getGuildsSettings]); + + return ( + + + + ); +}; diff --git a/src/features/province/components/kill-process-stats/KillProcessStats.js b/src/features/province/components/kill-process-stats/KillProcessStats.js new file mode 100644 index 0000000..9ff741f --- /dev/null +++ b/src/features/province/components/kill-process-stats/KillProcessStats.js @@ -0,0 +1,60 @@ +import { Button, TextField, Typography } from "@mui/material"; +import { DatePicker } from "@mui/x-date-pickers"; +import moment from "moment/moment"; +import { useEffect, useState } from "react"; +import { Grid } from "../../../../components/grid/Grid"; +import { SPACING } from "../../../../data/spacing"; + +export const KillProcessStats = ({ province }) => { + const [selectedDate1, setSelectedDate1] = useState( + moment(new Date()).format("YYYY-MM-DD") + ); + const [selectedDate2, setSelectedDate2] = useState( + moment(new Date()).format("YYYY-MM-DD") + ); + + useEffect(() => { + var currentDate = moment(selectedDate1); + var newDate = currentDate.add(7, "days").format("YYYY-MM-DD"); + setSelectedDate2(newDate); + }, [selectedDate1]); + + return ( + + + روند کشتار بر اساس بازه + ( + + )} + value={selectedDate1} + onChange={(e) => { + setSelectedDate1(moment(e).format("YYYY-MM-DD")); + }} + />{" "} + ( + + )} + value={selectedDate2} + onChange={(e) => { + setSelectedDate2(moment(e).format("YYYY-MM-DD")); + }} + /> + + + + + + ); +}; diff --git a/src/features/province/components/manage-car-state/ManageCarState.js b/src/features/province/components/manage-car-state/ManageCarState.js new file mode 100644 index 0000000..54cfbd1 --- /dev/null +++ b/src/features/province/components/manage-car-state/ManageCarState.js @@ -0,0 +1,73 @@ +import { Switch } from "@mui/material"; +import { useContext, useState } from "react"; +import { useDispatch } from "react-redux"; +import { AppContext } from "../../../../contexts/AppContext"; +import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl"; +import { provinceGetCars } from "../../services/province-get-cars"; +import { updateCarStateService } from "../../services/update-car-state"; + +export const ManageCarState = ({ item }) => { + const [openNotif] = useContext(AppContext); + const dispatch = useDispatch(); + const [checked, setChecked] = useState( + getRoleFromUrl() === "KillHouse" + ? item.addCarActiveState + : item.driverActiveState + ); + + const handleChange = (event) => { + let reqObj; + if (getRoleFromUrl() === "KillHouse") { + reqObj = { + add_car_key: item.addCarKey, + add_car_change_activation: event.target.checked, + }; + } else { + reqObj = { + driver_key: item.key, + change_activation: event.target.checked, + }; + } + dispatch(updateCarStateService(reqObj)).then((r) => { + if (r?.payload?.error) { + openNotif({ + vertical: "top", + horizontal: "center", + msg: r?.payload?.error, + severity: "error", + }); + } else { + dispatch(provinceGetCars()); + openNotif({ + vertical: "top", + horizontal: "center", + msg: "عملیات با موفقیت انجام شد.", + severity: "success", + }); + } + }); + setChecked(event.target.checked); + }; + + let disabled = false; + if (item.driverType === "rental") { + disabled = true; + } + + return ( + <> + + {checked ? ( + + ) : ( + + )} + + ); +}; diff --git a/src/features/province/components/manage-evacuations/ManageEvacuations.js b/src/features/province/components/manage-evacuations/ManageEvacuations.js new file mode 100644 index 0000000..c29d513 --- /dev/null +++ b/src/features/province/components/manage-evacuations/ManageEvacuations.js @@ -0,0 +1,184 @@ +import { + Grid, + Box, + Button, + Checkbox, + CircularProgress, + FormControlLabel, + FormGroup, + Stack, +} from "@mui/material"; +import axios from "axios"; +import { useCallback, useContext, useEffect, useMemo, useState } from "react"; +import { AppContext } from "../../../../contexts/AppContext"; + +const LOSS_FIELDS = [ + { + key: "includeTotalDiseaseLosses", + apiKey: "include_total_disease_losses", + label: "مجموع تلفات ناشی از بیماری", + }, + { + key: "includeTotalFlockDestruction", + apiKey: "include_total_flock_destruction", + label: "مجموع معدوم‌سازی گله", + }, + { + key: "includeTotalNormalFlockLosses", + apiKey: "include_total_normal_flock_losses", + label: "مجموع تلفات عادی گله", + }, + { + key: "includeTotalForceMajeureLosses", + apiKey: "include_total_force_majeure_losses", + label: "مجموع تلفات ناشی از عوامل قهری و طبیعی", + }, + { + key: "includeTotalFireLosses", + apiKey: "include_total_fire_losses", + label: "مجموع تلفات ناشی از آتش‌سوزی", + }, +]; + +const DEFAULT_FORM_STATE = LOSS_FIELDS.reduce( + (acc, { key }) => ({ ...acc, [key]: false }), + {} +); + +export const ManageEvacuations = () => { + const [openNotif] = useContext(AppContext); + const notify = useCallback( + ({ severity, msg, vertical = "top", horizontal = "center" }) => + openNotif({ + severity, + msg, + vertical, + horizontal, + }), + [openNotif] + ); + const [formState, setFormState] = useState(DEFAULT_FORM_STATE); + const [recordId, setRecordId] = useState(null); + const [isLoading, setIsLoading] = useState(true); + const [isSaving, setIsSaving] = useState(false); + + useEffect(() => { + const fetchLossManagement = async () => { + setIsLoading(true); + + try { + const { data } = await axios.get("hatching-loss-management/"); + + setRecordId(data?.id ?? null); + + setFormState((prev) => + LOSS_FIELDS.reduce( + (acc, { key }) => ({ + ...acc, + [key]: Boolean(data?.[key]), + }), + { ...prev } + ) + ); + } catch (error) { + const errorText = + error?.response?.data?.detail ?? + error?.response?.data?.message ?? + error?.message ?? + "خطایی در دریافت اطلاعات رخ داده است."; + notify({ severity: "error", msg: errorText }); + } finally { + setIsLoading(false); + } + }; + + fetchLossManagement(); + }, []); + + const handleChange = (fieldKey) => (event) => { + const { checked } = event.target; + setFormState((prev) => ({ + ...prev, + [fieldKey]: checked, + })); + }; + + const requestBody = useMemo( + () => + LOSS_FIELDS.reduce((acc, { key, apiKey }) => { + acc[apiKey] = Boolean(formState[key]); + return acc; + }, {}), + [formState] + ); + + const handleSubmit = async (event) => { + event.preventDefault(); + + setIsSaving(true); + + const targetId = recordId ?? 1; + + try { + await axios.patch(`hatching-loss-management/${targetId}/`, requestBody); + + notify({ + severity: "success", + msg: "اطلاعات با موفقیت به‌روزرسانی شد.", + }); + } catch (error) { + const errorText = + error?.response?.data?.detail ?? + error?.response?.data?.message ?? + error?.message ?? + "خطایی در به‌روزرسانی اطلاعات رخ داده است."; + notify({ severity: "error", msg: errorText }); + } finally { + setIsSaving(false); + } + }; + + return ( + + {isLoading ? ( + + + + ) : ( + + + {LOSS_FIELDS.map(({ key, label }) => ( + + } + label={label} + /> + ))} + + + + + + + )} + + ); +}; diff --git a/src/features/province/components/manage-guild-distributions/ManageGuildDistributions.js b/src/features/province/components/manage-guild-distributions/ManageGuildDistributions.js new file mode 100644 index 0000000..caeb679 --- /dev/null +++ b/src/features/province/components/manage-guild-distributions/ManageGuildDistributions.js @@ -0,0 +1,576 @@ +import React, { useContext, useEffect, useState } from "react"; +import { Button, Checkbox, IconButton, TextField } from "@mui/material"; +import axios from "axios"; +import { RiSearchLine } from "react-icons/ri"; +import { useDispatch } from "react-redux"; +import EditIcon from "@mui/icons-material/Edit"; +import { AppContext } from "../../../../contexts/AppContext"; +import { + LOADING_END, + LOADING_START, + OPEN_MODAL, +} from "../../../../lib/redux/slices/appSlice"; +import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl"; +import { ProvinceManageDistributionsSubmitCommitmentPercent } from "../province-manage-distributions-submit-commitment-percentet/ProvinceManageDistributionsSubmitCommitmentPercent"; +import { Grid } from "../../../../components/grid/Grid"; +import ResponsiveTable from "../../../../components/responsive-table/ResponsiveTable"; +import { ProvinceManageGuildDistributionsSubmitPercents } from "../province-manage-guild-distributions-submit-percents/ProvinceManageGuildDistributionsSubmitPercents"; +import { + provinceManageGuildTradesEditAllPercents, + provinceManageGuildTradesEditPercents, + provinceManageGuildTradesGetPercents, +} from "../../services/province-manage-guilds-trades-edit-percents"; + +export const ManageGuildDistributions = () => { + const handleTextChange = (event) => { + setTextValue(event.target.value); + }; + const [openNotif] = useContext(AppContext); + const dispatch = useDispatch(); + + const [data, setData] = useState([]); + const [totalRows, setTotalRows] = useState(0); + const [perPage, setPerPage] = useState(10); + const [textValue, setTextValue] = useState(""); + const [page, setPage] = useState(1); + const [tableData, setTableData] = useState([]); + const [dashboardData, setDashboardData] = useState([]); + + const getDashboardData = () => { + dispatch(provinceManageGuildTradesGetPercents()).then((r) => { + setDashboardData(r.payload.data); + }); + }; + + const fetchApiData = async (page) => { + let response; + dispatch(LOADING_START()); + response = await axios.get( + `guilds-for-configs/?search=filter&value=${textValue}&role=${getRoleFromUrl()}&page=${page}&page_size=${perPage}` + ); + getDashboardData(); + dispatch(LOADING_END()); + setData(response.data.results); + setTotalRows(response.data.count); + }; + + const handlePageChange = (page) => { + fetchApiData(page); + setPage(page); + }; + + const handlePerRowsChange = (perRows) => { + setPerPage(perRows); + setPage(1); + }; + + const updateTable = () => { + fetchApiData(page !== 0 ? page : 1); + }; + + const openGovModal = (item, isAll) => { + dispatch( + OPEN_MODAL({ + title: "فروش دولتی", + content: ( + + ), + }) + ); + }; + + const openFreeModal = (item, isAll) => { + dispatch( + OPEN_MODAL({ + title: "فروش آزاد", + content: ( + + ), + }) + ); + }; + + useEffect(() => { + const d = data?.map((item, i) => { + return [ + page === 1 ? i + 1 : i + perPage * (page - 1) + 1, + `${item?.user?.fullname} (${item?.user?.mobile})`, + , + { + dispatch( + provinceManageGuildTradesEditPercents({ + key: item?.key, + free_sale_from_free_quota_in_province: + !item?.freeSaleFromFreeQuotaInProvince, + }) + ).then((r) => { + if (r.payload.error) { + openNotif({ + vertical: "top", + horizontal: "center", + msg: r.payload.error, + severity: "error", + }); + } else { + updateTable(); + openNotif({ + vertical: "top", + horizontal: "center", + msg: "عملیات با موفقیت انجام شد.", + severity: "success", + }); + } + }); + }} + />, + { + dispatch( + provinceManageGuildTradesEditPercents({ + key: item?.key, + free_sale_form_governmental_quota: + !item?.freeSaleFormGovernmentalQuota, + }) + ).then((r) => { + if (r.payload.error) { + openNotif({ + vertical: "top", + horizontal: "center", + msg: r.payload.error, + severity: "error", + }); + } else { + updateTable(); + openNotif({ + vertical: "top", + horizontal: "center", + msg: "عملیات با موفقیت انجام شد.", + severity: "success", + }); + } + }); + }} + />, + + + + { + const newValue = !item?.governmentalSellingPermission; + dispatch( + provinceManageGuildTradesEditPercents({ + key: item?.key, + governmental_selling_permission: newValue, + ...(newValue === false + ? { + in_province_governmental_selling_percent: 0, + segmentation_governmental_percent: 0, + out_province_governmental_selling_percent: 0, + } + : {}), + }) + ).then(() => { + if (newValue === true) { + openGovModal(item); + } else { + openNotif({ + vertical: "top", + horizontal: "center", + msg: "عملیات با موفقیت انجام شد.", + severity: "success", + }); + } + updateTable(); + }); + }} + /> + + + {item?.governmentalSellingPermission && ( + + openGovModal(item)} + color="primary" + > + + + + )} + , + + + { + const newValue = !item?.freeSellingPermission; + dispatch( + provinceManageGuildTradesEditPercents({ + key: item?.key, + free_selling_permission: newValue, + ...(newValue === false + ? { + in_province_free_selling_percent: 0, + out_province_free_selling_percent: 0, + segmentation_free_selling_percent: 0, + } + : {}), + }) + ).then(() => { + if (newValue === true) { + openFreeModal(item); + } else { + openNotif({ + vertical: "top", + horizontal: "center", + msg: "عملیات با موفقیت انجام شد.", + severity: "success", + }); + } + updateTable(); + }); + }} + /> + + + + {item?.freeSellingPermission && ( + openFreeModal(item)} + color="primary" + > + + + )}{" "} + + , + item?.inProvinceGovernmentalSellingPercent, + item?.outProvinceGovernmentalSellingPercent, + item?.segmentationGovernmentalPercent, + item?.inProvinceFreeSellingPercent, + item?.outProvinceFreeSellingPercent, + item?.segmentationFreeSellingPercent, + ]; + }); + + setTableData(d); + }, [data]); + + useEffect(() => { + fetchApiData(1); + }, [dispatch, perPage]); + + const handleSubmit = async (event) => { + event.preventDefault(); + dispatch(LOADING_START()); + + try { + const response = await axios.get( + `guilds-for-configs/?role=${getRoleFromUrl()}&search=filter&value=${textValue}&page=${1}&page_size=${perPage}` + ); + setData(response.data.results); + setTotalRows(response.data.count); + dispatch(LOADING_END()); + } catch (error) { + console.error("Error fetching data:", error); + } + }; + + return ( + + + , + { + dispatch( + provinceManageGuildTradesEditAllPercents({ + free_sale_from_free_quota_in_province: + !dashboardData?.freeSaleFromFreeQuotaInProvince, + }) + ).then((r) => { + if (r.payload.error) { + openNotif({ + vertical: "top", + horizontal: "center", + msg: r.payload.error, + severity: "error", + }); + } else { + updateTable(); + openNotif({ + vertical: "top", + horizontal: "center", + msg: "عملیات با موفقیت انجام شد.", + severity: "success", + }); + } + }); + }} + />, + { + dispatch( + provinceManageGuildTradesEditAllPercents({ + free_sale_form_governmental_quota: + !dashboardData?.freeSaleFormGovernmentalQuota, + }) + ).then((r) => { + if (r.payload.error) { + openNotif({ + vertical: "top", + horizontal: "center", + msg: r.payload.error, + severity: "error", + }); + } else { + updateTable(); + openNotif({ + vertical: "top", + horizontal: "center", + msg: "عملیات با موفقیت انجام شد.", + severity: "success", + }); + } + }); + }} + />, + + + + { + const newValue = + !dashboardData?.governmentalSellingPermission; + dispatch( + provinceManageGuildTradesEditAllPercents({ + governmental_selling_permission: newValue, + ...(newValue === false + ? { + in_province_governmental_selling_percent: 0, + segmentation_governmental_percent: 0, + out_province_governmental_selling_percent: 0, + } + : {}), + }) + ).then(() => { + if (newValue === true) { + openGovModal(dashboardData, true); + } else { + openNotif({ + vertical: "top", + horizontal: "center", + msg: "عملیات با موفقیت انجام شد.", + severity: "success", + }); + } + updateTable(); + }); + }} + /> + + + {dashboardData?.governmentalSellingPermission && ( + + openGovModal(dashboardData, true)} + color="primary" + > + + + + )} + , + + + { + const newValue = !dashboardData?.freeSellingPermission; + dispatch( + provinceManageGuildTradesEditAllPercents({ + free_selling_permission: newValue, + ...(newValue === false + ? { + in_province_free_selling_percent: 0, + out_province_free_selling_percent: 0, + segmentation_free_selling_percent: 0, + } + : {}), + }) + ).then(() => { + if (newValue === true) { + openFreeModal(dashboardData, true); + } else { + openNotif({ + vertical: "top", + horizontal: "center", + msg: "عملیات با موفقیت انجام شد.", + severity: "success", + }); + } + updateTable(); + }); + }} + /> + + + + {dashboardData?.freeSellingPermission && ( + openFreeModal(dashboardData, true)} + color="primary" + > + + + )}{" "} + + , + dashboardData?.inProvinceGovernmentalSellingPercent, + dashboardData?.outProvinceGovernmentalSellingPercent, + dashboardData?.segmentationGovernmentalPercent, + dashboardData?.inProvinceFreeSellingPercent, + dashboardData?.outProvinceFreeSellingPercent, + dashboardData?.segmentationFreeSellingPercent, + ], + ]} + title={"تنظیمات کلی"} + /> + + + +
    + + + +
    +
    + + +
    + ); +}; diff --git a/src/features/province/components/manage-guilds-operations/ManageGuildsOperations.js b/src/features/province/components/manage-guilds-operations/ManageGuildsOperations.js new file mode 100644 index 0000000..f620f1c --- /dev/null +++ b/src/features/province/components/manage-guilds-operations/ManageGuildsOperations.js @@ -0,0 +1,285 @@ +import { + Button, + FormControlLabel, + IconButton, + Popover, + Switch, + Tooltip, +} from "@mui/material"; +import EditIcon from "@mui/icons-material/Edit"; +import { useContext, useState } from "react"; +import { useDispatch } from "react-redux"; +import axios from "axios"; +import { Grid } from "../../../../components/grid/Grid"; +import { + DRAWER, + OPEN_MODAL, + LOADING_START, + LOADING_END, +} from "../../../../lib/redux/slices/appSlice"; +import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl"; +import { CreateGuilds } from "../create-guilds/CreateGuilds"; +import { GuildLimitaion } from "../guild-limitaion/GuildLimitaion"; +import ManageHistoryIcon from "@mui/icons-material/ManageHistory"; +import VisibilityIcon from "@mui/icons-material/Visibility"; +import CheckCircleIcon from "@mui/icons-material/CheckCircle"; +import SendIcon from "@mui/icons-material/Send"; +import { AppContext } from "../../../../contexts/AppContext"; +import { SPACING } from "../../../../data/spacing"; +import { ProvinceManageGuildsSubmitRegisterCode } from "../province-manage-guilds-submit-register-code/ProvinceManageGuildsSubmitRegisterCode"; +import { provinceResendRegisterCodeStateService } from "../../services/province-get-register-code-state"; +import { ViewGuildDetails } from "../view-guild-details/ViewGuildDetails"; +import TuneIcon from "@mui/icons-material/Tune"; + +export const ManageGuildsOperations = ({ guild, updateTable }) => { + const dispatch = useDispatch(); + const [checked, setChecked] = useState(guild.active); + const [popoverOpen, setPopoverOpen] = useState(false); + const [anchorEl, setAnchorEl] = useState(null); + const [openNotif] = useContext(AppContext); + + const openPopover = (event) => { + setPopoverOpen(true); + setAnchorEl(event.currentTarget); + }; + + const closePopover = () => { + setPopoverOpen(false); + setAnchorEl(null); + }; + + const handleChange = async (event) => { + const newChecked = event.target.checked; + setChecked(newChecked); + + dispatch(LOADING_START()); + + try { + const response = await axios.put("guilds/0/", { + guilds_key: guild?.key, + active: newChecked, + role: getRoleFromUrl(), + }); + + dispatch(LOADING_END()); + + if (response.status === 200) { + updateTable(); + dispatch(DRAWER({ right: false, bottom: false, content: null })); + openNotif({ + vertical: "top", + horizontal: "center", + msg: "عملیات با موفقیت انجام شد.", + severity: "success", + }); + } + } catch (error) { + dispatch(LOADING_END()); + const errorMessage = + error.response?.data?.result || + error.response?.data?.error || + "خطا در انجام عملیات"; + openNotif({ + vertical: "top", + horizontal: "center", + msg: errorMessage, + severity: "error", + }); + // Revert the checkbox state on error + setChecked(!newChecked); + } + }; + + return ( + + + + + + + + +
    + + + + {["AdminX", "SuperAdmin", "GuildRoom"].includes( + getRoleFromUrl() + ) && ( + <> + + } + label={checked ? "فعال" : "غیرفعال"} + style={{ + justifyContent: "center", + alignItems: "center", + display: "flex", + }} + /> + + + + )} + + {!guild?.isRegistered && ( + + + + + + )} + +
    +
    +
    + ); +}; diff --git a/src/features/province/components/manage-guilds-requests-operations/ManageGuildsRequestsOperations.js b/src/features/province/components/manage-guilds-requests-operations/ManageGuildsRequestsOperations.js new file mode 100644 index 0000000..22299bf --- /dev/null +++ b/src/features/province/components/manage-guilds-requests-operations/ManageGuildsRequestsOperations.js @@ -0,0 +1,314 @@ +import { Button, IconButton, Popover, TextField } from "@mui/material"; +import { useContext, useState } from "react"; +import TuneIcon from "@mui/icons-material/Tune"; +import VisibilityIcon from "@mui/icons-material/Visibility"; +import CheckIcon from "@mui/icons-material/Check"; +import CloseIcon from "@mui/icons-material/Close"; +import CheckCircleIcon from "@mui/icons-material/CheckCircle"; +import SendIcon from "@mui/icons-material/Send"; +import { Grid } from "../../../../components/grid/Grid"; +import { SPACING } from "../../../../data/spacing"; +import { checkKillhouseRequestGuildService } from "../../services/check-killhouse-request-guild"; +import { useDispatch } from "react-redux"; +import { AppContext } from "../../../../contexts/AppContext"; +import { CLOSE_MODAL, OPEN_MODAL } from "../../../../lib/redux/slices/appSlice"; +import { ProvinceManageGuildsSubmitRegisterCode } from "../province-manage-guilds-submit-register-code/ProvinceManageGuildsSubmitRegisterCode"; +import { provinceResendRegisterCodeStateService } from "../../services/province-get-register-code-state"; +import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl"; +import { ViewGuildDetails } from "../view-guild-details/ViewGuildDetails"; + +export const ManageGuildsRequestsOperations = ({ guild, updateTable }) => { + const [popoverOpen, setPopoverOpen] = useState(false); + const [anchorEl, setAnchorEl] = useState(null); + + const dispatch = useDispatch(); + const [openNotif] = useContext(AppContext); + + const openPopover = (event) => { + setPopoverOpen(true); + setAnchorEl(event.currentTarget); + }; + + const closePopover = () => { + setPopoverOpen(false); + setAnchorEl(null); + }; + + return ( + + + + + +
    + + {/* {!readOnly && ( + + { + dispatch( + hatchingUndoArchiveService({ + key: item.key, + type: "return_archive", + }) + ).then((r) => { + if (r.payload.error) { + openNotif({ + vertical: "top", + horizontal: "center", + msg: r.payload.error, + severity: "error", + }); + } else { + updateArchive(1); + openNotif({ + vertical: "top", + horizontal: "center", + msg: "عملیات با موفقیت انجام شد.", + severity: "success", + }); + } + }); + }} + > + + + + )} */} + + {["SuperAdmin", "AdminX", "GuildRoom"].includes( + getRoleFromUrl() + ) && ( + + )} + + {(guild?.activeRegisterCode && guild?.loggedRegisterCode) || + !guild?.activeRegisterCode ? ( + + + + + ) : ( + + + + + + )} + +
    +
    +
    + ); +}; + +const RejectModal = ({ guild, updateTable }) => { + const [openNotif] = useContext(AppContext); + const [text, setText] = useState(""); + const dispatch = useDispatch(); + + return ( + + setText(e.target.value)} + /> + + + ); +}; diff --git a/src/features/province/components/manage-guilds-requests/ManageGuildsRequests.js b/src/features/province/components/manage-guilds-requests/ManageGuildsRequests.js new file mode 100644 index 0000000..1b1f49d --- /dev/null +++ b/src/features/province/components/manage-guilds-requests/ManageGuildsRequests.js @@ -0,0 +1,191 @@ +import React, { useEffect, useState } from "react"; +import { Button, TextField } from "@mui/material"; +import { useDispatch } from "react-redux"; +import axios from "axios"; +import { RiSearchLine } from "react-icons/ri"; +import { + // DRAWER, + LOADING_END, + LOADING_START, + OPEN_MODAL, +} from "../../../../lib/redux/slices/appSlice"; +import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl"; +import { Grid } from "../../../../components/grid/Grid"; +import ResponsiveTable from "../../../../components/responsive-table/ResponsiveTable"; +import { ManageGuildsRequestsOperations } from "../manage-guilds-requests-operations/ManageGuildsRequestsOperations"; +import { CreateGuilds } from "../create-guilds/CreateGuilds"; + +export const ManageGuildsRequests = () => { + const dispatch = useDispatch(); + + const handleTextChange = (event) => { + setTextValue(event.target.value); + }; + + const [data, setData] = useState([]); + const [totalRows, setTotalRows] = useState(0); + const [perPage, setPerPage] = useState(10); + const [textValue, setTextValue] = useState(""); + const [page, setPage] = useState(1); + const [tableData, setTableData] = useState([]); + + const fetchApiData = async (page) => { + dispatch(LOADING_START()); + const response = await axios.get( + `total_guilds/?search=filter&value=${textValue}&role=${getRoleFromUrl()}&page=${page}&page_size=${perPage}&check=true&state=pending` + ); + dispatch(LOADING_END()); + setData(response.data?.results || []); + setTotalRows(response.data?.count || 0); + }; + + const handlePageChange = (page) => { + fetchApiData(page); + setPage(page); + }; + + const handlePerRowsChange = (perRows) => { + setPerPage(perRows); + setPage(1); + }; + + const updateTable = () => { + fetchApiData(page !== 0 ? page : 1); + }; + + useEffect(() => { + const d = data?.map((item, i) => { + return [ + page === 1 ? i + 1 : i + perPage * (page - 1) + 1, + // item?.killHouseInfo?.length + // ? item?.killHouseInfo + // ?.map((item) => { + // const type = item?.killer ? "کشتارکن" : "کشتارگاه"; + // return `${type} ${item?.name} (${item?.mobile})`; + // }) + // .join(" - ") + // : + `${item?.registerarFullname || ""} ${ + item?.registerarMobile ? "(" + item?.registerarMobile + " )" : " " + }`, + item?.licenseNumber || "-", + item?.guildsName || "-", + `${item?.user?.fullname || "-"} (${item?.user?.mobile || "-"})`, + item?.user?.nationalId || "-", + item?.typeActivity || "-", + item?.areaActivity || "-", + item?.address?.postalCode || "-", + `${item?.address?.province?.name || "-"}/${ + item?.address?.city?.name || "-" + }/${item?.address?.address || "-"}`, + item?.steward ? "می باشد" : "نمی باشد", + item?.hasInquiry ? "استعلامی" : "دستی", + item?.activeRegisterCode ? "انجام شده" : "انجام نشده", + , + ]; + }); + + setTableData(d); + }, [data]); + + useEffect(() => { + fetchApiData(1); + }, [dispatch, perPage]); + + const handleSubmit = async (event) => { + event.preventDefault(); + dispatch(LOADING_START()); + + try { + const response = await axios.get( + `total_guilds/?role=${getRoleFromUrl()}&search=filter&value=${textValue}&page=${1}&page_size=${perPage}&check=true&state=pending` + ); + setData(response.data?.results || []); + setTotalRows(response.data?.count || 0); + dispatch(LOADING_END()); + } catch (error) { + console.error("Error fetching data:", error); + dispatch(LOADING_END()); + } + }; + + return ( + + + {["AdminX", "SuperAdmin"].includes(getRoleFromUrl()) && ( + + )} + + +
    + + + +
    +
    + + +
    + ); +}; diff --git a/src/features/province/components/manage-guilds-state/ManageGuildsState.js b/src/features/province/components/manage-guilds-state/ManageGuildsState.js new file mode 100644 index 0000000..7832979 --- /dev/null +++ b/src/features/province/components/manage-guilds-state/ManageGuildsState.js @@ -0,0 +1,41 @@ +import { FormControlLabel, Switch } from "@mui/material"; +import { useState } from "react"; +import { useDispatch } from "react-redux"; +import { Grid } from "../../../../components/grid/Grid"; +import { updateGuildsSettingsService } from "../../services/update-guilds-settings"; + +export const ManageGuildsState = ({ + guildState, + choose_steward_guilds_key, +}) => { + const dispatch = useDispatch(); + const [switchState, setSwitchState] = useState(guildState); + + const handleSwitchChange = () => { + setSwitchState((prevState) => { + dispatch( + updateGuildsSettingsService({ + choose_steward_guilds_key, + guilds: !prevState, + }) + ); + return !prevState; + }); + }; + + return ( + + + } + // label="Toggle Switch" + /> + + ); +}; diff --git a/src/features/province/components/manage-guilds/ManageGuilds.js b/src/features/province/components/manage-guilds/ManageGuilds.js new file mode 100644 index 0000000..1a7b89f --- /dev/null +++ b/src/features/province/components/manage-guilds/ManageGuilds.js @@ -0,0 +1,417 @@ +import React, { useEffect, useState } from "react"; +import { Button, TextField, Tooltip, MenuItem } from "@mui/material"; +import { useDispatch, useSelector } from "react-redux"; +import axios from "axios"; +import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl"; +import { provinceGetTotalGuildsService } from "../../services/province-get-total-guilds"; +import { Grid } from "../../../../components/grid/Grid"; +import ResponsiveTable from "../../../../components/responsive-table/ResponsiveTable"; +import { ManageGuildsOperations } from "../manage-guilds-operations/ManageGuildsOperations"; +import { OPEN_MODAL } from "../../../../lib/redux/slices/appSlice"; +import { RiFileExcel2Fill, RiSearchLine } from "react-icons/ri"; +import { SPACING } from "../../../../data/spacing"; +import { SimpleTable } from "../../../../components/simple-table/SimpleTable"; +import { CreateGuilds } from "../create-guilds/CreateGuilds"; +import { checkPathStartsWith } from "../../../../utils/checkPathStartsWith"; + +export const MaangeGuilds = () => { + const userKey = useSelector((state) => state.userSlice?.userProfile?.key); + const dispatch = useDispatch(); + const selectedSubUser = useSelector( + (state) => state.userSlice.selectedSubUser + ); + const [data, setData] = useState([]); + const [totalRows, setTotalRows] = useState(0); + const [perPage, setPerPage] = useState(10); + const [textValue, setTextValue] = useState(""); + const [page, setPage] = useState(1); + const [tableData, setTableData] = useState([]); + const [activeState, setActiveState] = useState("active"); + + const handleTextChange = (e) => setTextValue(e.target.value); + // const handleCheckboxChange = () => setIsSteward(!isSteward); + + const fetchApiData = async (page) => { + const response = await dispatch( + provinceGetTotalGuildsService({ + search: "filter", + value: textValue, + page: page, + page_size: perPage, + steward: false, + active_state: activeState, + is_real_person: true, + role_key: checkPathStartsWith("province") + ? selectedSubUser?.key || "" + : "", + }) + ); + + if (response.payload.error) { + console.error("Error fetching data:", response.payload.error); + setData([]); + setTotalRows(0); + } else { + setData(response.payload.data?.results || []); + setTotalRows(response.payload.data?.count || 0); + } + }; + + const handlePageChange = (page) => { + fetchApiData(page); + setPage(page); + }; + + const handlePerRowsChange = (perRows) => { + setPerPage(perRows); + setPage(1); + }; + + const updateTable = () => { + fetchApiData(page !== 0 ? page : 1); + }; + + useEffect(() => { + fetchApiData(1); + }, [perPage, selectedSubUser?.key, activeState]); + + useEffect(() => { + if (!data || !Array.isArray(data)) { + setTableData([]); + return; + } + const d = data.map((item, i) => { + const commonData = [ + page === 1 ? i + 1 : i + perPage * (page - 1) + 1, + item?.licenseNumber || "-", + item?.guildsName || "-", + `${item?.user?.fullname || "-"} (${item?.user?.mobile || "-"})`, + item?.user?.nationalId ? item?.user?.nationalId : "-", + item?.typeActivity || "-", + item?.areaActivity || "-", + item?.address?.postalCode || "-", + `${item?.address?.province?.name || "-"}/${ + item?.address?.city?.name || "-" + }/${item?.address?.address || "-"}`, + item?.steward ? "می باشد" : "نمی باشد", + item?.limitationAllocation ? "دارد" : "ندارد", + item?.allocationLimit ? item?.allocationLimit : "-", + item?.getPosStatus?.hasActivePons ? "دارد" : "ندارد", + item?.getPosStatus?.lenActiveSessions || "-", + ]; + + if (getRoleFromUrl() !== "KillHouse") { + commonData.push( + + ); + + commonData.push( + + ); + } + + if ( + !["CityJahad", "CityPoultry", "KillHouse"].includes(getRoleFromUrl()) + ) { + commonData.splice( + 14, + 0, + item?.productInfo?.totalCarcassesWeight + ? item.productInfo.totalCarcassesWeight.toLocaleString() + : "-" + ); + commonData.splice(10, 0, item?.hasInquiry ? "استعلامی" : "دستی"); + commonData.splice( + 11, + 0, + item?.activeRegisterCode ? "انجام شده" : "انجام نشده" + ); + } + + commonData?.push(item?.active ? "فعال" : "غیر فعال"); + + commonData.push( + !item?.isRegistered && + item?.registerCode && + !item?.loggedRegistrationCode + ? "در انتظار ورود کد احراز" + : item?.isRegistered && item?.provinceAcceptState === "pending" + ? "در انتظار تایید استان" + : item?.isRegistered + ? "احراز شده" + : "احراز نشده" + ); + if (getRoleFromUrl() !== "KillHouse") { + commonData.push( + + ); + } + + return commonData; + }); + + setTableData(d); + }, [data]); + + const handleSubmit = async (e) => { + e.preventDefault(); + const response = await dispatch( + provinceGetTotalGuildsService({ + search: "filter", + value: textValue, + page: page, + page_size: perPage, + steward: false, + active_state: activeState, + is_real_person: true, + role_key: checkPathStartsWith("province") + ? selectedSubUser?.key || "" + : "", + }) + ); + + if (response.payload.error) { + console.error("Error fetching data:", response.payload.error); + setData([]); + setTotalRows(0); + } else { + setData(response.payload.data?.results || []); + setTotalRows(response.payload.data?.count || 0); + } + }; + + return ( + + +
    + + {["KillHouse", "GuildRoom"].includes(getRoleFromUrl()) && ( + + )} + + + + {/* + } + label="نمایش مباشرین" + /> */} + {getRoleFromUrl() !== "KillHouse" && ( + setActiveState(e.target.value)} + sx={{ width: 150 }} + > + همه + فعال + غیرفعال + + )} + + + +
    + {getRoleFromUrl() !== "KillHouse" && ( + + + + + + + + )} +
    + + +
    + ); +}; diff --git a/src/features/province/components/manage-poultries/ManagePoultries.js b/src/features/province/components/manage-poultries/ManagePoultries.js new file mode 100644 index 0000000..a487ea8 --- /dev/null +++ b/src/features/province/components/manage-poultries/ManagePoultries.js @@ -0,0 +1,663 @@ +import React, { useContext, useEffect, useState } from "react"; +import { + Button, + IconButton, + List, + ListItemButton, + ListItemIcon, + ListItemText, + Popover, + TextField, + Tooltip, + Typography, +} from "@mui/material"; +import { useDispatch, useSelector } from "react-redux"; +import { useNavigate } from "react-router-dom"; +import axios from "axios"; +import { Grid } from "../../../../components/grid/Grid"; +import { + LOADING_END, + LOADING_START, + OPEN_MODAL, +} from "../../../../lib/redux/slices/appSlice"; +import { AppContext } from "../../../../contexts/AppContext"; +import { EditPoultryCity } from "../edit-poultry-city/EditPoultryCity"; +import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl"; +import { RiFileExcel2Fill } from "react-icons/ri"; +import ResponsiveTable from "../../../../components/responsive-table/ResponsiveTable"; +import { provinceGetDashboardPoultriesService } from "../../services/getDashboardOfManagePoultries"; +import { getPoultryActiveLimitedService } from "../../services/province-get-poultry-active-limited"; +import Chip from "@mui/material/Chip"; +import TuneIcon from "@mui/icons-material/Tune"; +import ManageAccountsIcon from "@mui/icons-material/ManageAccounts"; +import FileDownloadIcon from "@mui/icons-material/FileDownload"; +import ToggleOnIcon from "@mui/icons-material/ToggleOn"; +import ToggleOffIcon from "@mui/icons-material/ToggleOff"; +import VisibilityIcon from "@mui/icons-material/Visibility"; + +export const ManagePoultries = () => { + const dispatch = useDispatch(); + const [openNotif] = useContext(AppContext); + + const handleTextChange = (event) => { + setTextValue(event.target.value); + }; + const userKey = useSelector((state) => state.userSlice?.userProfile?.key); + const [dashboardData, setDashboardData] = useState([]); + const [data, setData] = useState([]); + const [totalRows, setTotalRows] = useState(0); + const [perPage, setPerPage] = useState(10); + const [textValue, setTextValue] = useState(""); + const [page, setPage] = useState(1); + const [tableData, setTableData] = useState([]); + const [has500Error, setHas500Error] = useState(false); + + const PoultryActions = ({ poultryItem, onToggleLimit }) => { + const navigate = useNavigate(); + const [anchorEl, setAnchorEl] = useState(null); + const open = Boolean(anchorEl); + + const handleOpen = (event) => { + setAnchorEl(event.currentTarget); + }; + + const handleClose = () => { + setAnchorEl(null); + }; + + const handleEdit = () => { + dispatch( + OPEN_MODAL({ + title: "ویرایش تعاونی", + content: ( + + ), + }) + ); + handleClose(); + }; + + const handleDownload = () => { + if (poultryItem?.key) { + window.open( + `${axios.defaults.baseURL}poultry_monitoring_excel/?key=${poultryItem.key}`, + "_blank" + ); + } + handleClose(); + }; + + const handleViewDetails = () => { + if (poultryItem?.breedingUniqueId) { + navigate( + window.location.pathname + + `${poultryItem.breedingUniqueId}?from=Poultry` + ); + } + handleClose(); + }; + + return ( + + + + + + + + + onToggleLimit(!poultryItem?.orderLimit)} + > + + {poultryItem?.orderLimit ? ( + + ) : ( + + )} + + + محدودیت ثبت سفارش + + } + /> + + + + + + + مشاهده جزییات + + } + /> + + + + + + + ویرایش تعاونی + + } + /> + + + + + + + خروجی اکسل + + } + /> + + + + + ); + }; + + const fetchApiData = async (page) => { + // Prevent request if there was a 500 error + if (has500Error) { + return; + } + + dispatch(LOADING_START()); + try { + const response = await axios.get( + `total_poultry/?search=filter&value=${textValue}&role=${getRoleFromUrl()}&page=${page}&page_size=${perPage}&search=filter&value=${textValue}` + ); + // Reset error state on successful response + setHas500Error(false); + setData(response.data?.results || []); + setTotalRows(response.data?.count || 0); + } catch (error) { + console.error("Error fetching data:", error); + const errorMessage = error?.message || ""; + const status = error?.response?.status; + const is500Error = errorMessage.includes("500") || status === 500; + + if (is500Error) { + setHas500Error(true); + openNotif({ + vertical: "top", + horizontal: "center", + msg: "مشکلی در دریافت اطلاعات پیش آمده است!", + severity: "error", + }); + } else { + openNotif({ + vertical: "top", + horizontal: "center", + msg: "مشکلی در دریافت اطلاعات پیش آمده است!", + severity: "error", + }); + } + setData([]); + setTotalRows(0); + } finally { + dispatch(LOADING_END()); + } + }; + + const handlePageChange = (page) => { + fetchApiData(page); + setPage(page); + }; + + const handlePerRowsChange = (perRows) => { + setPerPage(perRows); + setPage(1); + }; + + const updateTable = () => { + fetchApiData(page !== 0 ? page : 1); + }; + + useEffect(() => { + fetchApiData(1); + // eslint-disable-next-line react-hooks/exhaustive-deps + }, []); + + useEffect(() => { + // Prevent request if there was a 500 error + if (has500Error) { + return; + } + + dispatch(provinceGetDashboardPoultriesService({ textValue })) + .then((r) => { + if (r?.error) { + const errorMessage = r.error?.message || ""; + const is500Error = + errorMessage.includes("500") || + r.error?.status === 500 || + r.error?.statusCode === 500; + + if (is500Error) { + setHas500Error(true); + openNotif({ + vertical: "top", + horizontal: "center", + msg: "مشکلی در دریافت اطلاعات پیش آمده است!", + severity: "error", + }); + } else { + openNotif({ + vertical: "top", + horizontal: "center", + msg: "مشکلی در دریافت اطلاعات پیش آمده است!", + severity: "error", + }); + } + setDashboardData([]); + } else if (r?.payload?.data) { + // Reset error state on successful response + setHas500Error(false); + setDashboardData(r.payload.data); + } else { + setDashboardData([]); + } + }) + .catch((error) => { + console.error("Error fetching dashboard data:", error); + const errorMessage = error?.message || ""; + const status = error?.response?.status; + const is500Error = errorMessage.includes("500") || status === 500; + + if (is500Error) { + setHas500Error(true); + openNotif({ + vertical: "top", + horizontal: "center", + msg: "مشکلی در دریافت اطلاعات پیش آمده است!", + severity: "error", + }); + } else { + openNotif({ + vertical: "top", + horizontal: "center", + msg: "مشکلی در دریافت اطلاعات پیش آمده است!", + severity: "error", + }); + } + setDashboardData([]); + }); + // eslint-disable-next-line react-hooks/exhaustive-deps + }, []); + + // Reset error state when textValue changes + useEffect(() => { + setHas500Error(false); + }, [textValue]); + + const handleOrderLimitChange = (poultryKey, newChecked) => { + dispatch( + getPoultryActiveLimitedService({ + key: poultryKey, + order_limit: newChecked, + }) + ) + .then((r) => { + if (r?.error) { + const errorMessage = r.error?.message || ""; + const is500Error = + errorMessage.includes("500") || + r.error?.status === 500 || + r.error?.statusCode === 500; + + if (is500Error) { + setHas500Error(true); + openNotif({ + vertical: "top", + horizontal: "center", + msg: "مشکلی در دریافت اطلاعات پیش آمده است!", + severity: "error", + }); + } else { + openNotif({ + vertical: "top", + horizontal: "center", + msg: "مشکلی در تغییر وضعیت محدودیت پیش آمده است!", + severity: "error", + }); + } + } else { + // Reset error state on successful response + setHas500Error(false); + updateTable(); + } + }) + .catch((error) => { + console.error("Error updating order limit:", error); + const errorMessage = error?.message || ""; + const status = error?.response?.status; + const is500Error = errorMessage.includes("500") || status === 500; + + if (is500Error) { + setHas500Error(true); + openNotif({ + vertical: "top", + horizontal: "center", + msg: "مشکلی در دریافت اطلاعات پیش آمده است!", + severity: "error", + }); + } else { + openNotif({ + vertical: "top", + horizontal: "center", + msg: "مشکلی در تغییر وضعیت محدودیت پیش آمده است!", + severity: "error", + }); + } + }); + }; + + useEffect(() => { + if (!data || !Array.isArray(data)) { + setTableData([]); + return; + } + + const d = data.map((item, i) => { + return [ + page === 1 ? i + 1 : i + perPage * (page - 1) + 1, + item?.unitName || "", + `${item?.user?.fullname || ""} (${item?.user?.mobile || ""})`, + item?.breedingUniqueId || "", + item?.epidemiologicalCode || "", + item?.healthCertificateNumber || "", + item?.numberOfHalls || 0, + item?.totalCapacity ? item.totalCapacity.toLocaleString() : "0", + `${item?.address?.province?.name || ""}/${ + item?.address?.city?.name || "" + }`, + item?.cityOperator || "ندارد", + item?.vetFarm?.vetFarmName + ? `${item.vetFarm.vetFarmName} (${item.vetFarm?.vetFarmMobile || ""})` + : "ندارد", + `${item?.hatchingInfo?.activeHatching ? "دارد" : "ندارد"} (${ + item?.hatchingInfo?.period || "0" + })`, + , + + handleOrderLimitChange(item?.key, checked) + } + />, + ]; + }); + + setTableData(d); + }, [data, page, perPage]); + + useEffect(() => { + // Reset error state when perPage changes + setHas500Error(false); + fetchApiData(1); + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [perPage]); + + const handleSubmit = async (event) => { + event.preventDefault(); + // Reset error state on manual submit (user retry) + setHas500Error(false); + dispatch(LOADING_START()); + + try { + const response = await axios.get( + `total_poultry/?role=${getRoleFromUrl()}&search=filter&value=${textValue}&page=${1}&page_size=${perPage}&search=filter&value=${textValue}` + ); + // Reset error state on successful response + setHas500Error(false); + setData(response.data?.results || []); + setTotalRows(response.data?.count || 0); + dispatch(LOADING_END()); + + dispatch(provinceGetDashboardPoultriesService({ textValue })) + .then((r) => { + if (r?.error) { + const errorMessage = r.error?.message || ""; + const is500Error = + errorMessage.includes("500") || + r.error?.status === 500 || + r.error?.statusCode === 500; + + if (is500Error) { + setHas500Error(true); + openNotif({ + vertical: "top", + horizontal: "center", + msg: "مشکلی در دریافت اطلاعات پیش آمده است!", + severity: "error", + }); + } else { + openNotif({ + vertical: "top", + horizontal: "center", + msg: "مشکلی در دریافت اطلاعات پیش آمده است!", + severity: "error", + }); + } + setDashboardData([]); + } else if (r?.payload?.data) { + setHas500Error(false); + setDashboardData(r.payload.data); + } else { + setDashboardData([]); + } + }) + .catch((error) => { + console.error("Error fetching dashboard data:", error); + const errorMessage = error?.message || ""; + const status = error?.response?.status; + const is500Error = errorMessage.includes("500") || status === 500; + + if (is500Error) { + setHas500Error(true); + openNotif({ + vertical: "top", + horizontal: "center", + msg: "مشکلی در دریافت اطلاعات پیش آمده است!", + severity: "error", + }); + } else { + openNotif({ + vertical: "top", + horizontal: "center", + msg: "مشکلی در دریافت اطلاعات پیش آمده است!", + severity: "error", + }); + } + setDashboardData([]); + }); + } catch (error) { + console.error("Error fetching data:", error); + const errorMessage = error?.message || ""; + const status = error?.response?.status; + const is500Error = errorMessage.includes("500") || status === 500; + + if (is500Error) { + setHas500Error(true); + openNotif({ + vertical: "top", + horizontal: "center", + msg: "مشکلی در دریافت اطلاعات پیش آمده است!", + severity: "error", + }); + } else { + openNotif({ + vertical: "top", + horizontal: "center", + msg: "مشکلی در دریافت اطلاعات پیش آمده است!", + severity: "error", + }); + } + setData([]); + setTotalRows(0); + dispatch(LOADING_END()); + } + }; + + return ( + + +
    + + + + + + + + +
    + + + + + + +
    + ); +}; diff --git a/src/features/province/components/manage-stewards-operations/ManageStewardsOperations.js b/src/features/province/components/manage-stewards-operations/ManageStewardsOperations.js new file mode 100644 index 0000000..259cb9e --- /dev/null +++ b/src/features/province/components/manage-stewards-operations/ManageStewardsOperations.js @@ -0,0 +1,112 @@ +import { + Button, + FormControlLabel, + IconButton, + Popover, + Switch, + Tooltip, +} from "@mui/material"; +import { useState } from "react"; +import { useDispatch } from "react-redux"; +import { Grid } from "../../../../components/grid/Grid"; +import { DRAWER } from "../../../../lib/redux/slices/appSlice"; +import { provinceChangeActiveStewardService } from "../../services/province-change-active-steward"; +import { EditStewards } from "../edit-stewards/EditStewards"; +import EditIcon from "@mui/icons-material/Edit"; +import TuneIcon from "@mui/icons-material/Tune"; + +export const ManageStewardsOperations = ({ guild }) => { + const dispatch = useDispatch(); + const [checked, setChecked] = useState(guild.active); + const [popoverOpen, setPopoverOpen] = useState(false); + const [anchorEl, setAnchorEl] = useState(null); + + const openPopover = (event) => { + setPopoverOpen(true); + setAnchorEl(event.currentTarget); + }; + + const closePopover = () => { + setPopoverOpen(false); + setAnchorEl(null); + }; + + const handleChange = (event) => { + setChecked(event.target.checked); + dispatch( + provinceChangeActiveStewardService({ + steward_key: guild?.key, + active: event.target.checked, + }) + ); + }; + + return ( + + + + + + + + +
    + + + } + label={checked ? "فعال" : "غیرفعال"} + style={{ + justifyContent: "center", + alignItems: "center", + display: "flex", + }} + /> + + +
    +
    +
    + ); +}; diff --git a/src/features/province/components/manage-stewards-state/ManageStewardsState.js b/src/features/province/components/manage-stewards-state/ManageStewardsState.js new file mode 100644 index 0000000..c24e080 --- /dev/null +++ b/src/features/province/components/manage-stewards-state/ManageStewardsState.js @@ -0,0 +1,41 @@ +import { FormControlLabel, Switch } from "@mui/material"; +import { useState } from "react"; +import { useDispatch } from "react-redux"; +import { Grid } from "../../../../components/grid/Grid"; +import { updateGuildsSettingsService } from "../../services/update-guilds-settings"; + +export const ManageStewardsState = ({ + stewardState, + choose_steward_guilds_key, +}) => { + const dispatch = useDispatch(); + const [switchState, setSwitchState] = useState(stewardState); + + const handleSwitchChange = () => { + setSwitchState((prevState) => { + dispatch( + updateGuildsSettingsService({ + choose_steward_guilds_key, + steward: !prevState, + }) + ); + return !prevState; + }); + }; + + return ( + + + } + // label="Toggle Switch" + /> + + ); +}; diff --git a/src/features/province/components/manage-stewards/ManageStewards.js b/src/features/province/components/manage-stewards/ManageStewards.js new file mode 100644 index 0000000..4cb6010 --- /dev/null +++ b/src/features/province/components/manage-stewards/ManageStewards.js @@ -0,0 +1,122 @@ +import { Button, Tooltip, MenuItem, TextField } from "@mui/material"; +import axios from "axios"; +import { useEffect, useState } from "react"; +import { RiFileExcel2Fill } from "react-icons/ri"; +import { useDispatch, useSelector } from "react-redux"; +import { Grid } from "../../../../components/grid/Grid"; +import { SPACING } from "../../../../data/spacing"; +import { provinceGetStewardsService } from "../../services/province-get-stewards"; +import { ManageStewardsOperations } from "../manage-stewards-operations/ManageStewardsOperations"; +import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl"; +import ResponsiveTable from "../../../../components/responsive-table/ResponsiveTable"; + +export const ManageStewards = () => { + const dispatch = useDispatch(); + const [dataTable, setDataTable] = useState([]); + const [statusFilter, setStatusFilter] = useState("همه"); + const { provinceGetStewards } = useSelector((state) => state.provinceSlice); + const userKey = useSelector((state) => state.userSlice.userProfile.key); + + useEffect(() => { + dispatch(provinceGetStewardsService()); + }, []); + + useEffect(() => { + const filtered = + statusFilter === "همه" + ? provinceGetStewards + : provinceGetStewards?.filter((item) => + statusFilter === "فعال" ? item?.active : !item?.active + ); + + const d = filtered?.map((item, i) => { + const dataRow = [ + i + 1, + item?.guilds?.guildsId, + item?.guilds?.guildsName, + `${item?.guilds?.user?.fullname} (${item?.guilds?.user?.mobile})`, + item?.guilds?.user?.nationalId, + item?.guilds?.typeActivity, + item?.guilds?.areaActivity, + item?.guilds?.licenseNumber, + `${item?.guilds?.address?.province.name}/${item?.guilds?.address?.city.name}`, + item?.guilds?.address?.address, + item?.limitationAllocation ? "دارد" : "ندارد", + item?.allocationLimit?.toLocaleString(), + item?.centersAllocation?.map((item) => item.label).join(" - "), + item?.productInfo?.totalCarcassesWeight?.toLocaleString(), + item?.productInfo?.realAllocatedWeight?.toLocaleString(), + , + ]; + + if (getRoleFromUrl() === "CityJahad") { + dataRow.pop(); + } + return dataRow; + }); + + setDataTable(d); + }, [provinceGetStewards, statusFilter]); + + const columns = [ + "ردیف", + "شناسه صنف", + "نام واحد صنفی", + "نام شخص/شرکت", + "کدملی", + "نوع فعالیت", + "حوزه فعالیت", + "شماره مجوز", + "استان/شهرستان", + "آدرس واحد صنفی", + "محدودیت تخصیص", + "حداکثر تخصیص", + "مراکز تخصیص", + "وزن خرید (کیلوگرم)", + "وزن فروش (کیلوگرم)", + "عملیات", + ]; + + if (getRoleFromUrl() === "CityJahad") { + columns.pop(); + } + + return ( + + + + + + + + + setStatusFilter(e.target.value)} + size="small" + sx={{ width: 150 }} + > + همه + فعال + غیرفعال + + + + + + ); +}; diff --git a/src/features/province/components/manage-tab/ManageTab.js b/src/features/province/components/manage-tab/ManageTab.js new file mode 100644 index 0000000..01b79ba --- /dev/null +++ b/src/features/province/components/manage-tab/ManageTab.js @@ -0,0 +1,36 @@ +import { useState } from "react"; +import { Tab, Tabs } from "@mui/material"; +import { Grid } from "../../../../components/grid/Grid"; +import { MaangeGuilds } from "../manage-guilds/ManageGuilds"; +import { PspActiveSession } from "../../../psp-company/components/psp-active-session/PspActiveSession"; +import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl"; + +export const ManageTab = () => { + const [value, setValue] = useState(0); + + const handleChange = (event, newValue) => { + setValue(newValue); + }; + return ( + + + + + {getRoleFromUrl() !== "KillHouse" && ( + + )} + + + + {value === 0 && } + {value === 1 && } + + ); +}; diff --git a/src/features/province/components/monitoring-buyers/MonitoringBuyers.js b/src/features/province/components/monitoring-buyers/MonitoringBuyers.js new file mode 100644 index 0000000..f3613b6 --- /dev/null +++ b/src/features/province/components/monitoring-buyers/MonitoringBuyers.js @@ -0,0 +1,88 @@ +import { IconButton, Tooltip, Typography } from "@mui/material"; +import VisibilityIcon from "@mui/icons-material/Visibility"; +import { useEffect, useState } from "react"; +import { useDispatch, useSelector } from "react-redux"; +import { useLocation, useNavigate } from "react-router-dom"; +import { Grid } from "../../../../components/grid/Grid"; +import { SPACING } from "../../../../data/spacing"; +import { slaughterGetKillerKillhousesService } from "../../../slaughter-house/services/slaughter-get-killers-killhouses"; +import ResponsiveTable from "../../../../components/responsive-table/ResponsiveTable"; + +export function MonitoringBuyers() { + const dispatch = useDispatch(); + const navigate = useNavigate(); + const { pathname } = useLocation(); + const [dataTable, setDataTable] = useState(); + const { slaughterGetKillerKillhouses } = useSelector( + (state) => state.slaughterSlice + ); + + // Get the first segment from pathname (adminx - could be superadmin or province) + const getPathPrefix = () => { + const segments = pathname.split("/").filter(Boolean); + return segments[0] || ""; + }; + + useEffect(() => { + dispatch(slaughterGetKillerKillhousesService()); + }, [dispatch]); + + useEffect(() => { + const d = slaughterGetKillerKillhouses?.map((item, i) => { + const pathPrefix = getPathPrefix(); + + return [ + i + 1, + item?.killer ? "کشتارکن" : "کشتارگاه", + + {item?.name} + , + + + {item?.killHouseOperator?.user?.fullname} ( + {item?.killHouseOperator?.user?.mobile}) + + , + item?.uniqueIdentifier && ( + + { + navigate( + `/${pathPrefix}/poultries/${item.uniqueIdentifier}?from=KillHouse` + ); + }} + > + + + + ), + ]; + }); + + setDataTable(d); + }, [slaughterGetKillerKillhouses, navigate, pathname]); + + return ( + + + + ); +} diff --git a/src/features/province/components/parent-company-payment-by-weight-overview/ParentCompanyPaymentByWeightOverview.js b/src/features/province/components/parent-company-payment-by-weight-overview/ParentCompanyPaymentByWeightOverview.js new file mode 100644 index 0000000..42d4c0b --- /dev/null +++ b/src/features/province/components/parent-company-payment-by-weight-overview/ParentCompanyPaymentByWeightOverview.js @@ -0,0 +1,326 @@ +import { Button } from "@mui/material"; +import React, { useEffect, useState } from "react"; +import { Grid } from "../../../../components/grid/Grid"; +import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl"; +import { ProvincePaymentPayDept } from "../province-payment-pay-dept/ProvincePaymentPayDept"; +import { OPEN_MODAL } from "../../../../lib/redux/slices/appSlice"; +import { useDispatch, useSelector } from "react-redux"; +import ResponsiveTable from "../../../../components/responsive-table/ResponsiveTable"; +import { parentCompanyGetWagesOfKillhousesService } from "../../services/province-get-wages-of-killhouses"; +import { parentConpanyGetPaymentByWeightOverview } from "../../services/province-get-payment-by-weight-overview"; +import { ProvinceWagePaymentTransactions } from "../province-wage-payment-transactions/ProvinceWagePaymentTransactions"; + +export const ParentCompanyPaymentByWeightOverviewTable = ({ province }) => { + const dispatch = useDispatch(); + const [tableDataOfWages, setTableDataOfWages] = useState(); + + const { parentCompanyPaymentByWeightOverview } = useSelector( + (item) => item.provinceSlice + ); + + useEffect(() => { + dispatch(parentConpanyGetPaymentByWeightOverview(province)); + + if (getRoleFromUrl() !== "KillHouse") { + dispatch(parentCompanyGetWagesOfKillhousesService(province)).then((r) => { + const d = r.payload.data?.map((item, i) => { + return [ + i + 1, + item?.name, + Math.ceil(item?.wageInfo?.totalWage)?.toLocaleString(), + Math.ceil(item?.wageInfo?.totalPaidWage)?.toLocaleString(), + Math.ceil(item?.wageInfo?.off)?.toLocaleString(), + Math.ceil(item?.wageInfo?.totalUnpaidWage)?.toLocaleString(), + Math.ceil( + item?.wageInfo?.totalProvinceLiveWeight + )?.toLocaleString(), + Math.ceil( + item?.wageInfo?.totalProvinceCarcassesWeight + )?.toLocaleString(), + Math.ceil( + item?.wageInfo?.provinceKillRequestsTotalWeight + )?.toLocaleString(), + Math.ceil( + item?.wageInfo?.provinceKillRequestsTotalWage + )?.toLocaleString(), + Math.ceil( + item?.wageInfo?.freeBarsOutProvinceCarcasesTotalWeight + )?.toLocaleString(), + Math.ceil( + item?.wageInfo?.freeBarsOutProvinceCarcasesTotalWage + )?.toLocaleString(), + Math.ceil( + item?.wageInfo?.freeBarsCarcasesTotalWeight + )?.toLocaleString(), + Math.ceil( + item?.wageInfo?.freeBarsCarcasesTotalWage + )?.toLocaleString(), + Math.ceil( + item?.wageInfo?.freeBarsLiveTotalWeight + )?.toLocaleString(), + Math.ceil(item?.wageInfo?.freeBarsLiveTotalWage)?.toLocaleString(), + ]; + }); + + setTableDataOfWages(d); + }); + } + }, [dispatch, province]); + + return ( + + + + {(getRoleFromUrl() === "KillHouse" || + getRoleFromUrl() === "ChainCompany") && ( + + + + )} + {/* {(getRoleFromUrl() === "KillHouse" || + getRoleFromUrl() === "ChainCompany") && ( + + + + )} */} + + + + {getRoleFromUrl() !== "KillHouse" && ( + + )} + + + + + + + + + + + + ); +}; diff --git a/src/features/province/components/policy-killhouse-direct-buy/PolicyKillhouseDirectBuy.js b/src/features/province/components/policy-killhouse-direct-buy/PolicyKillhouseDirectBuy.js new file mode 100644 index 0000000..f6631ff --- /dev/null +++ b/src/features/province/components/policy-killhouse-direct-buy/PolicyKillhouseDirectBuy.js @@ -0,0 +1,72 @@ +import { Switch } from "@mui/material"; +import { useEffect, useState } from "react"; +import { useDispatch, useSelector } from "react-redux"; +import { AdvancedTable } from "../../../../components/advanced-table/AdvancedTable"; +import { Grid } from "../../../../components/grid/Grid"; +import { policyChangeKillhouseDirectBuyService } from "../../services/policy-change-killhouse-direct-buy"; +import { provinceGetKillhousesService } from "../../services/province-get-killhouses"; +import { BackButton } from "../../../../components/back-button/BackButton"; + +export const PolicyKillhouseDirectBuy = () => { + const dispatch = useDispatch(); + const { provinceGetKillhouses } = useSelector((state) => state.provinceSlice); + const [data, setData] = useState(); + + useEffect(() => { + dispatch(provinceGetKillhousesService()); + }, []); + + useEffect(() => { + const d = provinceGetKillhouses?.map((item) => { + return [ + item.killHouse.name, + { + dispatch( + policyChangeKillhouseDirectBuyService({ + direct_buying_key: item.key, + allow: event.target.checked, + }) + ).then((r) => { + dispatch(provinceGetKillhousesService()); + }); + // setChecked(event.target.checked); + }} + name="checked" + color="primary" + />, + { + dispatch( + policyChangeKillhouseDirectBuyService({ + direct_buying_key: item.key, + export_status: event.target.checked, + }) + ).then((r) => { + dispatch(provinceGetKillhousesService()); + }); + // setChecked(event.target.checked); + }} + name="checked" + color="primary" + />, + ]; + }); + setData(d); + }, [provinceGetKillhouses]); + + return ( + + + + + ); +}; diff --git a/src/features/province/components/policy-killhouse-guilds/PolicyKillhouseGuilds.js b/src/features/province/components/policy-killhouse-guilds/PolicyKillhouseGuilds.js new file mode 100644 index 0000000..33ac80f --- /dev/null +++ b/src/features/province/components/policy-killhouse-guilds/PolicyKillhouseGuilds.js @@ -0,0 +1,60 @@ +import { Switch } from "@mui/material"; +import { useEffect, useState } from "react"; +import { useDispatch, useSelector } from "react-redux"; +import { BackButton } from "../../../../components/back-button/BackButton"; +import { Grid } from "../../../../components/grid/Grid"; +import { policyChangeKillhouseGuildsService } from "../../services/policy-change-killhouse-guilds"; +import { provinceGetKillhousesGuildsService } from "../../services/province-get-killhouses-guilds"; +import ResponsiveTable from "../../../../components/responsive-table/ResponsiveTable"; + +export const PolicyKillhouseGuilds = () => { + const dispatch = useDispatch(); + const { provinceGetKillhousesGuilds } = useSelector( + (state) => state.provinceSlice + ); + const [data, setData] = useState(); + + useEffect(() => { + dispatch(provinceGetKillhousesGuildsService()); + }, []); + + useEffect(() => { + const d = provinceGetKillhousesGuilds?.map((item, i) => { + return [ + item.killHouse?.name, + item.killHouse?.killer ? "کشتارکن" : "کشتارگاه", + { + dispatch( + policyChangeKillhouseGuildsService({ + register_guilds_key: item.key, + allow: event.target.checked, + }) + ).then((r) => { + dispatch(provinceGetKillhousesGuildsService()); + }); + // setChecked(event.target.checked); + }} + name="checked" + color="primary" + />, + ]; + }); + setData(d); + }, [provinceGetKillhousesGuilds]); + + return ( + + + + + ); +}; diff --git a/src/features/province/components/policy-poultry-choose-slaughter/PolicyPoultryChooseSlaughter.js b/src/features/province/components/policy-poultry-choose-slaughter/PolicyPoultryChooseSlaughter.js new file mode 100644 index 0000000..d3c2421 --- /dev/null +++ b/src/features/province/components/policy-poultry-choose-slaughter/PolicyPoultryChooseSlaughter.js @@ -0,0 +1,53 @@ +import { Switch } from "@mui/material"; +import { useEffect, useState } from "react"; +import { useDispatch, useSelector } from "react-redux"; +import { AdvancedTable } from "../../../../components/advanced-table/AdvancedTable"; +import { Grid } from "../../../../components/grid/Grid"; +import { policyChangePoultryChooseSlaughterService } from "../../services/policy-change-poultry-choose-slaughter"; +import { provinceGetPoultriesService } from "../../services/province-get-poultries"; + +export const PolicyPoultryChooseSlaughter = () => { + const dispatch = useDispatch(); + const { provinceGetPoultries } = useSelector((state) => state.provinceSlice); + const [data, setData] = useState(); + + useEffect(() => { + dispatch(provinceGetPoultriesService()); + }, []); + + useEffect(() => { + const d = provinceGetPoultries?.map((item) => { + return [ + item.name, + { + dispatch( + policyChangePoultryChooseSlaughterService({ + poultry_key: item.key, + allow: event.target.checked, + }) + ).then(() => { + dispatch(provinceGetPoultriesService()); + }); + // setChecked(event.target.checked); + }} + name="checked" + color="primary" + />, + ]; + }); + setData(d); + }, [provinceGetPoultries]); + + return ( + + + + ); +}; diff --git a/src/features/province/components/policy-poultry-free-sale/PolicyPoultryFreeSale.js b/src/features/province/components/policy-poultry-free-sale/PolicyPoultryFreeSale.js new file mode 100644 index 0000000..b5cded6 --- /dev/null +++ b/src/features/province/components/policy-poultry-free-sale/PolicyPoultryFreeSale.js @@ -0,0 +1,55 @@ +import { Switch } from "@mui/material"; +import { useEffect, useState } from "react"; +import { useDispatch, useSelector } from "react-redux"; +import { AdvancedTable } from "../../../../components/advanced-table/AdvancedTable"; +import { Grid } from "../../../../components/grid/Grid"; +import { policyChangePoultryFreeSalesService } from "../../services/policy-change-poultry-free-sales"; +import { provinceGetPoultriesService } from "../../services/province-get-poultries"; +import { BackButton } from "../../../../components/back-button/BackButton"; + +export const PolicyPoultryFreeSale = () => { + const dispatch = useDispatch(); + const { provinceGetPoultries } = useSelector((state) => state.provinceSlice); + const [data, setData] = useState(); + + useEffect(() => { + dispatch(provinceGetPoultriesService()); + }, []); + + useEffect(() => { + const d = provinceGetPoultries?.map((item) => { + return [ + item.name, + { + dispatch( + policyChangePoultryFreeSalesService({ + poultry_key: item.key, + allow: event.target.checked, + }) + ).then((r) => { + dispatch(provinceGetPoultriesService()); + }); + // setChecked(event.target.checked); + }} + name="checked" + color="primary" + />, + ]; + }); + setData(d); + }, [provinceGetPoultries]); + + return ( + + + + + ); +}; diff --git a/src/features/province/components/poultries-details/PoultriesDetails.js b/src/features/province/components/poultries-details/PoultriesDetails.js new file mode 100644 index 0000000..494afef --- /dev/null +++ b/src/features/province/components/poultries-details/PoultriesDetails.js @@ -0,0 +1,647 @@ +import { Fragment, useContext, useEffect, useState } from "react"; +import { Grid } from "../../../../components/grid/Grid"; +import { useParams, useSearchParams } from "react-router-dom"; +import { + Autocomplete, + Checkbox, + CircularProgress, + Tab, + Tabs, + TextField, + Typography, + IconButton, +} from "@mui/material"; +import { useDispatch } from "react-redux"; +import axios from "axios"; +import { DatePicker } from "@mui/x-date-pickers"; +import moment from "moment"; +import ToggleOffOutlinedIcon from "@mui/icons-material/ToggleOffOutlined"; +import ToggleOnIcon from "@mui/icons-material/ToggleOn"; +import SearchIcon from "@mui/icons-material/Search"; +import ResponsiveTable from "../../../../components/responsive-table/ResponsiveTable"; +import { formatJustDate } from "../../../../utils/formatTime"; +import { CheckCleanceCode } from "../../../../components/check-clearance-code/ChechClearanceCode"; +import { AppContext } from "../../../../contexts/AppContext"; +import { getPoultryTransportByCodeService } from "../../services/get-poultry-transport-by-code"; +import { getPoultryTransportProductsByCodeService } from "../../services/get-poultry-transport-products-by-code"; +import { getPoultryTransportDashboardByCodeService } from "../../services/get-poultry-transport-dashboard-by-code"; + +export const PoultriesDetails = () => { + const { key } = useParams(); + const [searchParams] = useSearchParams(); + const from = searchParams.get("from"); + const dispatch = useDispatch(); + const [tabValue, setTabValue] = useState("1"); + const [tableData, setTableData] = useState([]); + const [totalRows, setTotalRows] = useState(0); + const [page, setPage] = useState(1); + const [perPage, setPerPage] = useState(10); + const [isLoading, setIsLoading] = useState(false); // eslint-disable-line no-unused-vars + const [error, setError] = useState(null); + const [withDate, setWithDate] = useState(true); + const [productOptions, setProductOptions] = useState([]); + const [selectedProduct, setSelectedProduct] = useState(""); + const [isProductLoading, setIsProductLoading] = useState(false); + const [searchValue, setSearchValue] = useState(""); + const [searchInput, setSearchInput] = useState(""); + const [dashboardData, setDashboardData] = useState(null); + const [provinceOptions, setProvinceOptions] = useState([]); + const [selectedProvince, setSelectedProvince] = useState(""); + const [isProvinceLoading, setIsProvinceLoading] = useState(false); + console.log(from); + const [, , selectedDate1, setSelectedDate1, selectedDate2, setSelectedDate2] = + useContext(AppContext); + + const columns = [ + "ردیف", + "کد رهگیری", + "محصول", + "اقلام", + "مقدار", + "واحد", + "تاریخ", + "مقصد", + "شناسه مقصد", + "استان مقصد", + "شهرستان مقصد", + "مبدا", + "شناسه مبدا", + "استان مبدا", + "شهرستان مبدا", + "نوع حمل", + "مقصد قبلی", + "تغییر مقصد", + "کد رهگیری خودرو", + "تاریخ تخلیه", + "تخلیه", + ]; + + const formatNumber = (value) => { + if (value === null || value === undefined) { + return "-"; + } + if (typeof value === "number") { + return value.toLocaleString("fa-IR"); + } + return value; + }; + + const safeValue = (value) => { + if (value === null || value === undefined || value === "") { + return "-"; + } + return value; + }; + + const formatPercent = (value) => { + if (value === null || value === undefined) { + return "-"; + } + const numericValue = Number(value); + if (Number.isNaN(numericValue)) { + return "-"; + } + return `${numericValue.toFixed(1)}%`; + }; + + const formatDateTimeFromIso = (value) => { + if (!value) return "-"; + const dateObj = new Date(value); + if (Number.isNaN(dateObj.getTime())) return "-"; + const date = dateObj.toLocaleDateString("fa-IR"); + const time = dateObj.toLocaleTimeString("fa-IR", { + hour: "2-digit", + minute: "2-digit", + hour12: false, + }); + return `${date} ${time}`; + }; + + const dashboardColumns = [ + "محصول", + "تعداد بار", + "حجم بار (کیلوگرم)", + "تعداد بار داخل استان", + "حجم بار داخل استان (کیلوگرم)", + "درصد داخل استان", + "تعداد بار خارج استان", + "حجم بار خارج استان (کیلوگرم)", + "درصد خارج استان", + "آخرین بروزرسانی", + ]; + + const handleTabChange = (event, newValue) => { + setTabValue(newValue); + setSelectedProduct(""); + setPage(1); + }; + + const handleSubmit = async (event) => { + event.preventDefault(); + const normalizedSearch = searchInput.trim(); + setSearchValue(normalizedSearch); + setSearchInput(normalizedSearch); + setPage(1); + }; + + useEffect(() => { + setPage(1); + }, [ + selectedDate1, + selectedDate2, + withDate, + selectedProduct, + searchValue, + tabValue, + selectedProvince, + ]); + + useEffect(() => { + const isMounted = { current: true }; + + const fetchProvinces = async () => { + try { + setIsProvinceLoading(true); + const { data } = await axios.get("iran_province/"); + if (!isMounted.current) { + return; + } + const names = + data?.map?.((item) => item?.name).filter((name) => !!name) ?? []; + setProvinceOptions(names); + } catch (err) { + console.error("Failed to fetch provinces:", err); + } finally { + if (isMounted.current) { + setIsProvinceLoading(false); + } + } + }; + + fetchProvinces(); + + return () => { + isMounted.current = false; + }; + }, []); + + useEffect(() => { + if (!key) return; + + const isMounted = { current: true }; + + const fetchProducts = async () => { + try { + setIsProductLoading(true); + const type = tabValue === "1" ? "in" : "out"; + const response = await dispatch( + getPoultryTransportProductsByCodeService({ + code: key, + type: type, + date1: withDate && selectedDate1 ? selectedDate1 : "", + date2: withDate && selectedDate2 ? selectedDate2 : "", + search: searchValue || "", + from: from, + }) + ); + + if (!isMounted.current) { + return; + } + + if (response.error) { + console.error("Failed to fetch products:", response.error); + return; + } + + const products = Array.isArray(response.payload?.data?.products) + ? response.payload.data.products + : []; + setProductOptions(products); + } catch (err) { + console.error("Failed to fetch product types:", err); + } finally { + if (isMounted.current) { + setIsProductLoading(false); + } + } + }; + + fetchProducts(); + + return () => { + isMounted.current = false; + }; + }, [ + key, + tabValue, + selectedDate1, + selectedDate2, + withDate, + searchValue, + dispatch, + ]); + + useEffect(() => { + if (!key) return; + + const isMounted = { current: true }; + + const fetchDashboardData = async () => { + try { + const type = tabValue === "1" ? "in" : "out"; + const response = await dispatch( + getPoultryTransportDashboardByCodeService({ + code: key, + type: type, + date1: withDate && selectedDate1 ? selectedDate1 : "", + date2: withDate && selectedDate2 ? selectedDate2 : "", + search: searchValue || "", + product: selectedProduct || "", + province: selectedProvince || "", + from: from, + }) + ); + + if (!isMounted.current) { + return; + } + + if (!response.error && response.payload?.data) { + setDashboardData(response.payload.data); + } + } catch (err) { + console.error("Failed to fetch dashboard data:", err); + } + }; + + fetchDashboardData(); + + return () => { + isMounted.current = false; + }; + }, [ + key, + tabValue, + selectedDate1, + selectedDate2, + withDate, + selectedProduct, + searchValue, + selectedProvince, + dispatch, + ]); + + useEffect(() => { + if (!key) return; + + const isMounted = { current: true }; + + const fetchTransportData = async () => { + try { + setError(null); + setIsLoading(true); + + const type = tabValue === "1" ? "in" : "out"; + + const response = await dispatch( + getPoultryTransportByCodeService({ + code: key, + type: type, + page: page, + page_size: perPage, + date1: withDate && selectedDate1 ? selectedDate1 : "", + date2: withDate && selectedDate2 ? selectedDate2 : "", + search: searchValue || "", + product: selectedProduct || "", + province: selectedProvince || "", + from: from, + }) + ); + + if (!isMounted.current) { + return; + } + + if (response.error) { + setError(response.error); + return; + } + + const responseData = response.payload?.data ?? { results: [] }; + const results = responseData?.results ?? []; + + const mappedTableData = results.map((item, index) => [ + safeValue(formatNumber(index + 1 + (page - 1) * perPage)), + , + safeValue(item?.product), + safeValue(item?.items), + safeValue(formatNumber(item?.quantity)), + safeValue(item?.unit), + safeValue(formatJustDate(item?.date)), + safeValue(item?.destination), + safeValue(item?.jihadiDestination), + safeValue(item?.destinationProvince), + safeValue(item?.destinationCity), + safeValue(item?.origin), + safeValue(item?.jihadiOrigin), + safeValue(item?.originProvince), + safeValue(item?.originCity), + safeValue( + item?.originProvince === item?.destinationProvince + ? "داخل استان" + : "خارج استان" + ), + safeValue(item?.destinationPrev), + safeValue(item?.destinationChanged), + safeValue(item?.carTrackingCode), + safeValue(formatJustDate(item?.unloadingDate)), + safeValue(item?.unloading), + ]); + + setTableData(mappedTableData); + setTotalRows(responseData?.count ?? 0); + } catch (err) { + console.error("Failed to fetch transport data:", err); + if (!isMounted.current) { + return; + } + setError(err); + } finally { + if (isMounted.current) { + setIsLoading(false); + } + } + }; + + fetchTransportData(); + + return () => { + isMounted.current = false; + }; + }, [ + key, + tabValue, + page, + perPage, + selectedDate1, + selectedDate2, + withDate, + selectedProduct, + searchValue, + selectedProvince, + dispatch, + ]); + + const handlePageChange = (newPage) => { + setPage(newPage); + }; + + const handlePerRowsChange = (newPerPage) => { + setPerPage(newPerPage); + setPage(1); + }; + + return ( + + + + + + + + + {dashboardData && ( + + + + )} + + + } + checkedIcon={} + checked={withDate} + onChange={() => setWithDate(!withDate)} + color="primary" + size="large" + /> + + ( + + )} + value={selectedDate1} + onChange={(e) => { + if (!e) return; + setSelectedDate1(moment(e).format("YYYY-MM-DD")); + }} + /> + + + ( + + )} + value={selectedDate2} + onChange={(e) => { + if (!e) return; + setSelectedDate2(moment(e).format("YYYY-MM-DD")); + }} + /> + + + + { + setSelectedProvince(value || ""); + }} + noOptionsText="استانی یافت نشد" + renderInput={(params) => ( + + {isProvinceLoading ? ( + + ) : null} + {params.InputProps.endAdornment} + + ), + }} + /> + )} + clearOnEscape + /> + { + setSelectedProduct(value || ""); + }} + noOptionsText="محصولی یافت نشد" + renderInput={(params) => ( + + {isProductLoading ? ( + + ) : null} + {params.InputProps.endAdornment} + + ), + }} + /> + )} + clearOnEscape + /> + + + setSearchInput(event.target.value)} + label="جستجو" + size="small" + variant="outlined" + sx={{ flexGrow: 1 }} + /> + + + + + + + + {error && ( + + + خطا در دریافت اطلاعات + + + )} + {!error && ( + + )} + + + + ); +}; diff --git a/src/features/province/components/province-accept-direct-buy/ProvinceAcceptDirectBuy.js b/src/features/province/components/province-accept-direct-buy/ProvinceAcceptDirectBuy.js new file mode 100644 index 0000000..9d056d6 --- /dev/null +++ b/src/features/province/components/province-accept-direct-buy/ProvinceAcceptDirectBuy.js @@ -0,0 +1,72 @@ +import { Button, TextField, Typography } from "@mui/material"; +import { useContext, useState } from "react"; +import { useDispatch } from "react-redux"; +import { Grid } from "../../../../components/grid/Grid"; +import { AppContext } from "../../../../contexts/AppContext"; +import { SPACING } from "../../../../data/spacing"; +import { CLOSE_MODAL } from "../../../../lib/redux/slices/appSlice"; +import { provinceAcceptSlaughterFreeBuyService } from "../../../slaughter-house/services/province-accept-slaughter-free-buy"; +import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl"; + +export const ProvinceAcceptDirectBuy = ({ item, updateTable }) => { + const [openNotif] = useContext(AppContext); + const dispatch = useDispatch(); + const [text, setText] = useState(item.killCapacity); + + const handleTextChange = (event) => { + setText(event.target.value); + }; + + return ( + + + مانده در سالن مرغدار:{"‌ "} + {item?.poultry?.leftOverOwnHatching?.toLocaleString()} + + + + + + ); +}; diff --git a/src/features/province/components/province-active-requests/ProvinceActiveRequests.js b/src/features/province/components/province-active-requests/ProvinceActiveRequests.js new file mode 100644 index 0000000..b1ee10c --- /dev/null +++ b/src/features/province/components/province-active-requests/ProvinceActiveRequests.js @@ -0,0 +1,75 @@ +import { Card, IconButton } from "@mui/material"; +import { useEffect, useState } from "react"; +import { AdvancedTable } from "../../../../components/advanced-table/AdvancedTable"; +import { useDispatch, useSelector } from "react-redux"; +import { provinceGetActiveRequestsService } from "../../services/province-get-active-requests"; +import { useNavigate } from "react-router-dom"; +import { ROUTE_PROVINCE_FILE } from "../../../../routes/routes"; +import PlagiarismIcon from "@mui/icons-material/Plagiarism"; +import { format } from "date-fns-jalali"; + +export const ProvinceActiveRequests = () => { + const dispatch = useDispatch(); + const navigate = useNavigate(); + const { provinceGetActiveRequests } = useSelector( + (state) => state.provinceSlice + ); + const [dataTable, setDataTable] = useState([]); + + useEffect(() => { + dispatch(provinceGetActiveRequestsService()); + }, []); + + useEffect(() => { + const d = provinceGetActiveRequests?.map((item, i) => { + return [ + i + 1, + item?.poultryRequest?.orderCode, + format(new Date(item?.poultryRequest?.createDate), "yyyy/MM/dd"), + format(new Date(item?.poultryRequest?.sendDate), "yyyy/MM/dd"), + item?.poultryRequest?.process?.poultry?.poultryName, + item?.poultryRequest?.process?.poultry?.poultryMobile, + item?.poultryRequest?.process?.poultry?.poultryCity, + item?.poultryRequest?.process?.poultry?.poultryProvince, + item?.poultryRequest?.process?.poultry?.age, + item?.poultryRequest?.process?.poultry?.poultryQuantity, + { + navigate( + ROUTE_PROVINCE_FILE + + item?.poultryRequest?.process?.poultry?.poultryRequestId + ); + }} + > + + , + ]; + }); + setDataTable(d); + }, [provinceGetActiveRequests]); + + return ( + + + + ); +}; diff --git a/src/features/province/components/province-add-buyer-auto-allocation/ProvinceAddBuyerAutoAllocation.js b/src/features/province/components/province-add-buyer-auto-allocation/ProvinceAddBuyerAutoAllocation.js new file mode 100644 index 0000000..9f38452 --- /dev/null +++ b/src/features/province/components/province-add-buyer-auto-allocation/ProvinceAddBuyerAutoAllocation.js @@ -0,0 +1,128 @@ +import { Autocomplete, Button, TextField } from "@mui/material"; +import { useFormik } from "formik"; +import { useEffect, useState } from "react"; +import { useDispatch, useSelector } from "react-redux"; +import { Grid } from "../../../../components/grid/Grid"; +import { NumberInput } from "../../../../components/number-format-custom/NumberFormatCustom"; +import { CLOSE_MODAL } from "../../../../lib/redux/slices/appSlice"; +import { provinceGetBuyersService } from "../../services/province-get-buyers"; + +export const ProvinceAddBuyerAutoAllocation = ({ + dataTable, + setDataTable, + setAddedRows, + poultryIndex, +}) => { + const dispatch = useDispatch(); + const [selectedCountry, setSelectedCountry] = useState(null); + const { provinceGetBuyers } = useSelector((state) => state.provinceSlice); + const formik = useFormik({ + initialValues: { + num: "", + }, + onSubmit: (values) => { + // console.log(values); + }, + }); + + useEffect(() => { + dispatch(provinceGetBuyersService()); + }, []); + + return ( + + { + return { + // disabled: item.debt, + name: item.debt ? `${item.name} (بدهکار)` : item.name, + obj: item, + }; + })} + getOptionLabel={(option) => option.name} + getOptionDisabled={(option) => option.disabled} + value={selectedCountry} + onChange={(event, newValue) => { + setSelectedCountry(newValue); + }} + renderInput={(params) => ( + + )} + /> +
    + +
    + + +
    + ); +}; + +function deepCopy(obj) { + let newObj = Array.isArray(obj) ? [] : {}; + for (let key in obj) { + if (typeof obj[key] === "object" && obj[key] !== null) { + newObj[key] = deepCopy(obj[key]); + } else { + newObj[key] = obj[key]; + } + } + return newObj; +} diff --git a/src/features/province/components/province-age-message/ProvinceAgeMessage.js b/src/features/province/components/province-age-message/ProvinceAgeMessage.js new file mode 100644 index 0000000..9615e16 --- /dev/null +++ b/src/features/province/components/province-age-message/ProvinceAgeMessage.js @@ -0,0 +1,299 @@ +import React, { useContext, useEffect, useState } from "react"; +import { + TextField, + Button, + Grid, + IconButton, + List, + ListItemButton, + ListItemIcon, + ListItemText, + Popover, + Tooltip, + Typography, +} from "@mui/material"; +import { useFormik } from "formik"; +import * as Yup from "yup"; +import ResponsiveTable from "../../../../components/responsive-table/ResponsiveTable"; +import { useDispatch } from "react-redux"; +import { + provinceDeleteAgeMessagesService, + provinceGetAgeMessagesService, + provinceSubmitAgeMessagesService, +} from "../../services/province-age-message"; +import { formatJustDate } from "../../../../utils/formatTime"; +import DeleteIcon from "@mui/icons-material/Delete"; +import EditIcon from "@mui/icons-material/Edit"; +import TuneIcon from "@mui/icons-material/Tune"; +import { DRAWER } from "../../../../lib/redux/slices/appSlice"; +import { ProvinceEditAgeMessage } from "../province-edit-age-message/ProvinceEditAgeMessage"; +import { AppContext } from "../../../../contexts/AppContext"; + +export const ProvinceAgeMessage = () => { + const [tableData, setTableData] = useState([]); + const [openNotif] = useContext(AppContext); + + const dispatch = useDispatch(); + const validationSchema = Yup.object({ + ageRange: Yup.number() + .required("بازه سنی ضروری است") + .max(99, "عدد دورقمی وارد کنید!"), + lossPercent: Yup.number() + .required("درصد افت ضروری است") + .max(99, "عدد دورقمی وارد کنید!"), + message: Yup.string() + .required("پیغام ضروری است") + .max(500, "حداکثر 500 کاراکتر"), + }); + + const formik = useFormik({ + initialValues: { + ageRange: "", + message: "", + lossPercent: "", + }, + validationSchema, + onSubmit: (values, { resetForm }) => { + dispatch( + provinceSubmitAgeMessagesService({ + message: values.message, + poultry_age: values.ageRange, + losses_percent: values.lossPercent, + }) + ).then((r) => { + if (r.payload.error) { + openNotif({ + vertical: "top", + horizontal: "center", + msg: r.payload.error, + severity: "error", + }); + } else { + fetchData(); + resetForm(); + openNotif({ + vertical: "top", + horizontal: "center", + msg: "عملیات با موفقیت انجام شد.", + severity: "success", + }); + } + }); + }, + }); + + const fetchData = () => { + dispatch(provinceGetAgeMessagesService()).then((r) => { + const d = r.payload.data?.map((item, i) => { + return [ + i + 1, + formatJustDate(item?.createDate), + item?.lossesPercent, + item?.poultryAge, + item?.message, + + { + dispatch(provinceDeleteAgeMessagesService(item?.key)).then( + (r) => { + if (r.payload.error) { + openNotif({ + vertical: "top", + horizontal: "center", + msg: r.payload.error, + severity: "error", + }); + } else { + fetchData(); + openNotif({ + vertical: "top", + horizontal: "center", + msg: "عملیات با موفقیت انجام شد.", + severity: "success", + }); + } + } + ); + }} + onEdit={() => { + dispatch( + DRAWER({ + right: !(window.innerWidth <= 600), + bottom: window.innerWidth <= 600, + title: "ویرایش خریدار", + content: ( + + ), + }) + ); + }} + /> + , + ]; + }); + setTableData(d); + }); + }; + + const ProvinceAgeMessageActions = ({ onDelete, onEdit }) => { + const [anchorEl, setAnchorEl] = useState(null); + const open = Boolean(anchorEl); + + const handleOpen = (event) => { + setAnchorEl(event.currentTarget); + }; + + const handleClose = () => { + setAnchorEl(null); + }; + + const handleDelete = () => { + onDelete(); + handleClose(); + }; + + const handleEdit = () => { + onEdit(); + handleClose(); + }; + + return ( + + + + + + + + + + + + + + ویرایش + + } + /> + + + + + + + حذف + + } + /> + + + + + ); + }; + + useEffect(() => { + fetchData(); + }, [dispatch]); + return ( +
    + + + + + + + + + + + + + + + + + + + +
    + ); +}; diff --git a/src/features/province/components/province-allocate-cars-form/ProvinceAllocateCarsForm.js b/src/features/province/components/province-allocate-cars-form/ProvinceAllocateCarsForm.js new file mode 100644 index 0000000..59b8926 --- /dev/null +++ b/src/features/province/components/province-allocate-cars-form/ProvinceAllocateCarsForm.js @@ -0,0 +1,210 @@ +import { Autocomplete, Button, TextField, Typography } from "@mui/material"; +import { useFormik } from "formik"; +import { useContext, useEffect, useState } from "react"; +import { useDispatch, useSelector } from "react-redux"; +import { Grid } from "../../../../components/grid/Grid"; +import { AppContext } from "../../../../contexts/AppContext"; +import { SPACING } from "../../../../data/spacing"; +import { DRAWER } from "../../../../lib/redux/slices/appSlice"; +import { Yup } from "../../../../lib/yup/yup"; +import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl"; +import { provinceAddCarToKillhouseService } from "../../services/province-add-car-to-killhouse"; +import { provinceGetCars } from "../../services/province-get-cars"; +import { provinceGetOnlyKillHousesService } from "../../services/province-get-only-kill-houses"; +import { provinceRemoveCarFromKillhouseService } from "../../services/province-remove-car-from-killhouse"; + +const validationSchema = Yup.object().shape({ + // add any other validation rules that you need + autocompleteField: Yup.string().required("This field is required"), +}); + +export const ProvinceAllocateCarsForm = ({ killHouseList, driverKey }) => { + const [openNotif] = useContext(AppContext); + + const formik = useFormik({ + initialValues: { + autocompleteField: "", + }, + validationSchema, + onSubmit: (values) => { + if (!values?.autocompleteField || !driverKey) { + openNotif({ + vertical: "top", + horizontal: "center", + msg: "لطفا تمام فیلدها را پر کنید", + severity: "error", + }); + return; + } + dispatch( + provinceAddCarToKillhouseService({ + kill_house_key: values.autocompleteField, + driver_key: driverKey, + }) + ).then((r) => { + if (r?.payload?.error) { + openNotif({ + vertical: "top", + horizontal: "center", + msg: r.payload.error, + severity: "error", + }); + } else { + dispatch(provinceGetCars()); + dispatch(DRAWER({ right: false, bottom: false, content: null })); + openNotif({ + vertical: "top", + horizontal: "center", + msg: "عملیات با موفقیت انجام شد.", + severity: "success", + }); + } + }); + }, + }); + const dispatch = useDispatch(); + const [killhouses, setKillhouses] = useState([]); + const { provinceGetOnlyKillHouses } = useSelector( + (state) => state.provinceSlice + ); + + useEffect(() => { + if (getRoleFromUrl() === "KillHouse") { + dispatch(provinceGetOnlyKillHousesService("self_kill_houses")); + } else { + dispatch(provinceGetOnlyKillHousesService("role=ProvinceOperator")); + } + }, []); + + useEffect(() => { + if ( + !provinceGetOnlyKillHouses || + !Array.isArray(provinceGetOnlyKillHouses) + ) { + setKillhouses([]); + return; + } + const d = provinceGetOnlyKillHouses + .map((item) => { + if (!item) return null; + let prefix; + if (item.killer) { + prefix = "کشتارکن"; + } else { + prefix = "کشتارگاه"; + } + const name = `${prefix} ${item?.name || ""}`; + return { title: name, value: item?.key || "" }; + }) + .filter((item) => item !== null && item.value); + setKillhouses(d || []); + }, [provinceGetOnlyKillHouses]); + + return ( + +
    + + option?.title || ""} + renderInput={(params) => ( + + )} + onChange={(e, value) => + formik.setFieldValue("autocompleteField", value?.value || "") + } + value={killhouses?.find( + (o) => o.value === formik.values.autocompleteField + )} + /> + + +
    + + کشتارگاه های خودرو + + {killHouseList && Array.isArray(killHouseList) && killHouseList.length > 0 + ? killHouseList.map((item, i) => { + if (!item) return null; + return ( + + + {i + 1}. {item?.killHouseName || ""} + + + + ); + }) + : null} +
    + ); +}; diff --git a/src/features/province/components/province-allocate-operations/ProvinceAllocateOperations.js b/src/features/province/components/province-allocate-operations/ProvinceAllocateOperations.js new file mode 100644 index 0000000..a7a6087 --- /dev/null +++ b/src/features/province/components/province-allocate-operations/ProvinceAllocateOperations.js @@ -0,0 +1,239 @@ +import { + Button, + IconButton, + Popover, + Tooltip, + Typography, +} from "@mui/material"; +import { useContext, useState } from "react"; +import { Grid } from "../../../../components/grid/Grid"; +import { + CLOSE_MODAL, + DRAWER, + OPEN_MODAL, +} from "../../../../lib/redux/slices/appSlice"; +import { provinceCloseAllocationService } from "../../services/province-close-allocation"; +import { provinceGetAllRequests } from "../../services/province-get-all-requests"; +import ArchiveIcon from "@mui/icons-material/Archive"; +import ConstructionIcon from "@mui/icons-material/Construction"; +import { ProvinceAllocation } from "../../../file/components/province-allocation/ProvinceAllocation"; +import { useDispatch } from "react-redux"; +import { AppContext } from "../../../../contexts/AppContext"; +import TuneIcon from "@mui/icons-material/Tune"; +import { ProvincePoultryRequestEnterConfirmationCode } from "../province-poultry-request-enter-confirmation-code/ProvincePoultryRequestEnterConfirmationCode"; + +export const ProvinceAllocateOperations = ({ + item, + remainQuantity, + getItemFreeSaleInProvince, + updateTable, +}) => { + const dispatch = useDispatch(); + const [openNotif, , selectedDate1] = useContext(AppContext); + + const [anchorEl, setAnchorEl] = useState(null); + + const open = Boolean(anchorEl); + const id = open ? "ProvinceAllocateRequests" : undefined; + + const handleClick = (event) => { + setAnchorEl(event.currentTarget); + }; + + const handleClose = () => { + setAnchorEl(null); + }; + + return ( + + + + + + +
    + + { + handleClose(); + if ( + item?.poultryRequest?.priceConfirmation === true && + !item?.poultryRequest?.inputPriceConfirmationCode + ) { + dispatch( + OPEN_MODAL({ + title: "ورود کد احراز", + content: ( + + ), + }) + ); + } else if (item?.provinceState === "pending") { + dispatch( + OPEN_MODAL({ + title: "اطلاعیه سیستم", + content: ( + + + درخواست ابتدا باید توسط استان تایید شود! + + + + + + + + ), + }) + ); + } else { + dispatch( + DRAWER({ + title: "انجام عملیات تخصیص", + // right: !(window.innerWidth <= 600), + top: !(window.innerWidth <= 600), + bottom: window.innerWidth <= 600, + size: 1000, + content: ( + + ), + }) + ); + } + }} + > + + + + + { + handleClose(); + dispatch( + OPEN_MODAL({ + title: "آیا مطمئن هستید؟", + content: ( + + + + + ), + }) + ); + }} + > + + + + {/* + { + handleClose(); + navigate( + ROUTE_PROVINCE_FILE + + item?.poultryRequest?.process?.poultry?.poultryRequestId + ); + }} + > + + + */} +
    +
    +
    + ); +}; diff --git a/src/features/province/components/province-allocate-requests/ProvinceAllocateRequests.js b/src/features/province/components/province-allocate-requests/ProvinceAllocateRequests.js new file mode 100644 index 0000000..8609057 --- /dev/null +++ b/src/features/province/components/province-allocate-requests/ProvinceAllocateRequests.js @@ -0,0 +1,342 @@ +import React, { useContext, useEffect, useState } from "react"; +import { + Box, + Button, + Card, + CardContent, + IconButton, + TextField, + Typography, +} from "@mui/material"; +import { DatePicker } from "@mui/x-date-pickers"; +import moment from "moment"; +import { useDispatch, useSelector } from "react-redux"; +import axios from "axios"; +import { AppContext } from "../../../../contexts/AppContext"; +import { + LOADING_END, + LOADING_START, + OPEN_MODAL, +} from "../../../../lib/redux/slices/appSlice"; +import ResponsiveTable from "../../../../components/responsive-table/ResponsiveTable"; +import { Grid } from "../../../../components/grid/Grid"; +import { ProvinceAllocateOperations } from "../province-allocate-operations/ProvinceAllocateOperations"; +import { ProvinceEditSendDate } from "../province-edit-send-date/ProvinceEditSendDate"; +import { formatJustDate, formatTime } from "../../../../utils/formatTime"; +import EditIcon from "@mui/icons-material/Edit"; +import { getPoultryRequestsTotalQuantityService } from "../../../city/services/get-poultry-requests-total-quantity"; +import { motion } from "framer-motion"; +import { RiSearchLine } from "react-icons/ri"; + +const cardVariants = { + hidden: { opacity: 0, y: 20 }, + visible: { opacity: 1, y: 0 }, +}; + +export const ProvinceAllocateRequests = () => { + const [, , selectedDate1, setSelectedDate1] = useContext(AppContext); + + const dispatch = useDispatch(); + useEffect(() => { + const currentDate = moment(new Date()).format("YYYY-MM-DD"); + setSelectedDate1(currentDate); + }, []); + + const handleTextChange = (event) => { + setTextValue(event.target.value); + }; + + const [data, setData] = useState([]); + const [totalRows, setTotalRows] = useState(0); + const [perPage, setPerPage] = useState(10); + const [textValue, setTextValue] = useState(""); + const [page, setPage] = useState(1); + const [tableData, setTableData] = useState([]); + + const fetchApiData = async (page) => { + dispatch(getPoultryRequestsTotalQuantityService(selectedDate1)).then( + async () => { + dispatch(LOADING_START()); + const response = await axios.get( + `city_operator_check_request_new/?state=waiting&date=${selectedDate1}&page=${page}&page_size=${perPage}&search=filter&value=${ + textValue ? textValue : "" + }` + ); + dispatch(LOADING_END()); + setData(response.data.results); + setTotalRows(response.data.count); + } + ); + }; + + const handlePageChange = (page) => { + fetchApiData(page); + setPage(page); + }; + + const handlePerRowsChange = (perRows) => { + setPerPage(perRows); + setPage(1); + }; + + const getItemFreeSaleInProvince = (item) => { + let sellType = ""; + if (item?.poultryRequest?.freeSaleInProvince) { + sellType = "آزاد"; + } else { + sellType = "دولتی"; + } + return sellType; + }; + + const updateTable = () => { + fetchApiData(page !== 0 ? page : 1); + }; + + useEffect(() => { + const d = data?.map((item, i) => { + return [ + page === 1 ? i + 1 : i + perPage * (page - 1) + 1, + item?.poultryRequest?.orderCode, + getItemFreeSaleInProvince(item), + formatTime(item?.poultryRequest?.createDate), + + + {formatJustDate(item?.poultryRequest?.sendDate)} + + 0} + onClick={() => { + dispatch( + OPEN_MODAL({ + title: "ویرایش تاریخ درخواست کشتار", + content: ( + + ), + }) + ); + }} + > + + + , + item?.poultryRequest?.freezing + ? "انجماد" + : item?.poultryRequest?.export + ? "صادرات" + : "عادی", + `${item?.poultryRequest?.process?.poultry?.poultryName}/${item?.poultryRequest?.process?.poultry?.poultryMobile}`, + item?.poultryRequest?.killHouseList.length + ? item?.poultryRequest?.killHouseList?.join(" - ") + : "-", + `${item?.poultryRequest?.process?.poultry?.poultryProvince}/${item?.poultryRequest?.process?.poultry?.poultryCity}`, + item?.poultryRequest?.poultry?.cityOperator, + item?.poultryRequest?.killingAge, + item?.poultryRequest?.process?.poultry?.IndexWeight, + item?.poultryRequest?.process?.poultry?.totalWeight?.toLocaleString(), + item?.poultryRequest?.process?.poultry?.poultryQuantity?.toLocaleString(), + item?.poultryRequest?.amount?.toLocaleString() + " ﷼", + + {item?.quantity?.allocatedNumber?.toLocaleString()} + , + item?.quantity?.returnedNumber?.toLocaleString(), + item?.quantity?.assignableNumber?.toLocaleString(), + , + ]; + }); + + setTableData(d); + }, [data]); + + useEffect(() => { + fetchApiData(1); + }, [dispatch, selectedDate1, perPage]); + + const handleSubmit = async (event) => { + event.preventDefault(); + dispatch(LOADING_START()); + + try { + const response = await axios.get( + `city_operator_check_request_new/?state=waiting&date=${selectedDate1}&page=${1}&page_size=${perPage}&search=filter&value=${ + textValue ? textValue : "" + }` + ); + + setData(response.data.results); + setTotalRows(response.data.count); + dispatch(LOADING_END()); + } catch (error) { + console.error("Error fetching data:", error); + } + }; + + const { poultryRequestsTotalQuantity } = useSelector( + (state) => state.citySlice + ); + + return ( + + + + ( + + )} + value={selectedDate1} + onChange={(e) => { + setSelectedDate1(moment(e).format("YYYY-MM-DD")); + }} + /> + + + +
    + + + +
    +
    + + + {[ + { + label: "تعداد درخواست کشتار", + value: poultryRequestsTotalQuantity?.acceptedQuantity || 0, + }, + { + label: "اعلام نیاز کشتارگاه ها", + value: poultryRequestsTotalQuantity?.killRequestsQuantity || 0, + }, + { + label: "تخصیص داده شده", + value: poultryRequestsTotalQuantity?.allocatedQuantity || 0, + }, + { + label: "قابل تخصیص", + value: poultryRequestsTotalQuantity?.assignableQuantity || 0, + }, + { + label: "برگشت داده شده", + value: poultryRequestsTotalQuantity?.returnedQuantity || 0, + }, + ].map((item, index) => ( + + + + + + {item.label} + + + {item.value?.toLocaleString()} قطعه + + + + + + ))} + + + + +
    + ); +}; diff --git a/src/features/province/components/province-allocate-steward-guild/ProvinceAllocateStewardGuild.js b/src/features/province/components/province-allocate-steward-guild/ProvinceAllocateStewardGuild.js new file mode 100644 index 0000000..e943ae7 --- /dev/null +++ b/src/features/province/components/province-allocate-steward-guild/ProvinceAllocateStewardGuild.js @@ -0,0 +1,218 @@ +import React, { useContext, useEffect, useState } from "react"; +import { Grid } from "../../../../components/grid/Grid"; +import { useDispatch } from "react-redux"; +import { Yup } from "../../../../lib/yup/yup"; +import { useFormik } from "formik"; +import { + provinceDispensersAddSteward, + provinceDispensersGetAllStewards, +} from "../../services/province-dispensers-services"; +import { + Autocomplete, + Button, + FormControl, + FormControlLabel, + FormLabel, + Radio, + RadioGroup, + TextField, +} from "@mui/material"; +import { AppContext } from "../../../../contexts/AppContext"; +import { CLOSE_MODAL } from "../../../../lib/redux/slices/appSlice"; + +export const ProvinceAllocateStewardGuild = ({ + killHousekey, + updateTable, + type, +}) => { + const dispatch = useDispatch(); + const [openNotif] = useContext(AppContext); + const [stewardsOptions, setStewardsOptions] = useState([]); + + const [value, setValue] = useState("forced"); + const [userType, setUserType] = useState("steward"); + + const handleChangeRadioButton = (event) => { + setValue(event.target.value); + }; + const handleChangeRadioButtonUserType = (event) => { + setUserType(event.target.value); + }; + + useEffect(() => { + dispatch( + provinceDispensersGetAllStewards({ + role_type: "KillHouse", + key: killHousekey, + type: userType, + }) + ).then((r) => { + setStewardsOptions(r.payload.data); + }); + }, [dispatch, userType]); + + const validationSchema = Yup.object({ + steward_key: Yup.string(), + allocation_limit: Yup.number() + .required("این فیلد اجباری است!") + .typeError("لطفا عدد وارد کنید!"), + }); + + const formik = useFormik({ + initialValues: { + steward_key: "", + allocation_limit: "", + }, + validationSchema, + }); + + useEffect(() => { + formik.validateForm(); + }, []); + return ( + + + + + } + label="مباشرین" + /> + } label="اصناف" /> + + + + + + ({ + id: i.key, + label: `${i.guildsName} (${i.user?.mobile}) / نوع فعالیت: ${i.typeActivity} / حوزه فعالیت: ${i.areaActivity}`, + item: i, + })) + : [] + } + value={formik.values.guild} + onChange={(e, item) => { + formik.setFieldValue("steward_key", item?.id); + formik.validateForm(); + }} + error={formik.touched.guild && Boolean(formik.errors.guild)} + helperText={formik.touched.guild && formik.errors.guild} + getOptionLabel={(option) => option.label} + renderInput={(params) => ( + + )} + /> + + + + + + + + + + + نوع تعهد: {"‌‌‌‌‌ ‌"} + + + } + label="اجباری" + /> + } + label="اختیاری" + /> + + + + + + + + + ); +}; diff --git a/src/features/province/components/province-allocated-requests-edit-allocation/ProvinceAllocatedRequestsEditAllocation.js b/src/features/province/components/province-allocated-requests-edit-allocation/ProvinceAllocatedRequestsEditAllocation.js new file mode 100644 index 0000000..a9de8fa --- /dev/null +++ b/src/features/province/components/province-allocated-requests-edit-allocation/ProvinceAllocatedRequestsEditAllocation.js @@ -0,0 +1,102 @@ +import React, { useContext } from "react"; +import { TextField, Button, Grid } from "@mui/material"; +import { useFormik } from "formik"; +import * as Yup from "yup"; +import { AppContext } from "../../../../contexts/AppContext"; +import { useDispatch } from "react-redux"; +import { + provinceGetAllocatedRequestsService, + provinceUpdateAllocatedRequestService, +} from "../../services/province-get-allocated-requests"; +import { CLOSE_MODAL } from "../../../../lib/redux/slices/appSlice"; +import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl"; + +export const ProvinceAllocatedRequestsEditAllocation = ({ + selectedDate1, + selectedDate2, + item, + fetchDashboard, +}) => { + const [openNotif] = useContext(AppContext); + const dispatch = useDispatch(); + const formik = useFormik({ + initialValues: { + amount: item.allocatedQuantity ? item.allocatedQuantity : "", + }, + validationSchema: Yup.object({ + amount: Yup.number() + .required("وارد کردن حجم الزامی است") + .min(1, "حجم باید بزرگتر از صفر باشد"), + }), + onSubmit: (values) => { + dispatch( + provinceUpdateAllocatedRequestService({ + edit_allocation_quantity: true, + province_kill_request_key: item?.provinceKillRequestKey, + quantity: parseInt(values?.amount), + role: getRoleFromUrl(), + }) + ).then((r) => { + if (r.payload.error) { + openNotif({ + vertical: "top", + horizontal: "center", + msg: r.payload.error, + severity: "error", + }); + } else { + openNotif({ + vertical: "top", + horizontal: "center", + msg: "عملیات با موفقیت انجام شد.", + severity: "success", + }); + dispatch( + provinceGetAllocatedRequestsService({ + selectedDate1, + selectedDate2, + }) + ); + fetchDashboard(); + dispatch(CLOSE_MODAL()); + } + }); + }, + }); + + return ( + + +
    + + + +
    +
    + ); +}; diff --git a/src/features/province/components/province-allocated-requests-invoice-operation/ProvinceAllocatedRequestsInvoiceOperation.js b/src/features/province/components/province-allocated-requests-invoice-operation/ProvinceAllocatedRequestsInvoiceOperation.js new file mode 100644 index 0000000..05398ab --- /dev/null +++ b/src/features/province/components/province-allocated-requests-invoice-operation/ProvinceAllocatedRequestsInvoiceOperation.js @@ -0,0 +1,64 @@ +import { IconButton, Tooltip } from "@mui/material"; +import React, { useState, useRef } from "react"; +import { BsFillFileEarmarkPdfFill } from "react-icons/bs"; +import { useReactToPrint } from "react-to-print"; +import ProvinceAllcationInvoice from "../province-allocation-invoice/ProvinceAllcationInvoice"; +import { useDispatch } from "react-redux"; +import { provinceGetAllocationLetter } from "../../services/province-get-allocation-letter"; +import { useEffect } from "react"; +import { PropTypes } from "prop-types"; + +export const ProvinceAllocatedRequestsInvoiceOperation = ({ date1, date2 }) => { + const dispatch = useDispatch(); + const [factorData, setFactorData] = useState(null); + const componentRef = useRef(); + + const handleDownloadFactor = () => { + const result = dispatch(provinceGetAllocationLetter(date1)); + setFactorData(result); + }; + + const printPDF = useReactToPrint({ + content: () => componentRef.current, + documentTitle: "گزارش روزانه", + onAfterPrint: () => { + setFactorData(null); + }, + }); + + useEffect(() => { + if (factorData) { + printPDF(); + } + }, [factorData, printPDF]); + + return ( +
    + + { + handleDownloadFactor(); + }} + size={"large"} + aria-label="delete" + color="success" + > + + + +
    + +
    +
    + ); +}; + +ProvinceAllocatedRequestsInvoiceOperation.propTypes = { + date1: PropTypes.any, + date2: PropTypes.any, +}; diff --git a/src/features/province/components/province-allocated-requests-operations/ProvinceAllocatedRequestsOperations.js b/src/features/province/components/province-allocated-requests-operations/ProvinceAllocatedRequestsOperations.js new file mode 100644 index 0000000..752c49f --- /dev/null +++ b/src/features/province/components/province-allocated-requests-operations/ProvinceAllocatedRequestsOperations.js @@ -0,0 +1,218 @@ +import { + Button, + IconButton, + Popover, + Tooltip, + Typography, +} from "@mui/material"; +import { useContext, useState } from "react"; +import TuneIcon from "@mui/icons-material/Tune"; +import { Grid } from "../../../../components/grid/Grid"; +import { SPACING } from "../../../../data/spacing"; +import { useDispatch } from "react-redux"; +import { provinceAllocatedDeleteService } from "../../services/province-allocated-delete"; +import { AppContext } from "../../../../contexts/AppContext"; +import { provinceGetAllocatedRequestsService } from "../../services/province-get-allocated-requests"; +import { provinceAllocatedReturnQuantityService } from "../../services/province-allocated-return-quantity"; +import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl"; +import { OPEN_MODAL } from "../../../../lib/redux/slices/appSlice"; +import { ProvinceAllocatedRequestsEditAllocation } from "../province-allocated-requests-edit-allocation/ProvinceAllocatedRequestsEditAllocation"; +import KeyboardReturnIcon from "@mui/icons-material/KeyboardReturn"; +import DeleteIcon from "@mui/icons-material/Delete"; +import EditIcon from "@mui/icons-material/Edit"; +export const ProvinceAllocatedRequestsOperations = ({ + item, + fetchDashboard, +}) => { + const [anchorEl, setAnchorEl] = useState(null); + const dispatch = useDispatch(); + + const [openNotif, , selectedDate1, , selectedDate2] = useContext(AppContext); + const handleClick = (event) => { + setAnchorEl(event.currentTarget); + }; + + const handleClose = () => { + setAnchorEl(null); + }; + + const open = Boolean(anchorEl); + const id = open ? "simple-popover" : undefined; + const btnDisabled = + item.allocatedState === "rejected" || + (item.allocatedCarState && item.allocatedRemainQuantity === 0); + + return ( +
    + + + + +
    + + {getRoleFromUrl() !== "KillHouse" && ( + + + + )} + + {getRoleFromUrl() !== "KillHouse" && ( + + + + )} + + + + + +
    +
    +
    + ); +}; diff --git a/src/features/province/components/province-allocated-requests/ProvinceAllocatedRequests.js b/src/features/province/components/province-allocated-requests/ProvinceAllocatedRequests.js new file mode 100644 index 0000000..60b2e74 --- /dev/null +++ b/src/features/province/components/province-allocated-requests/ProvinceAllocatedRequests.js @@ -0,0 +1,400 @@ +import { + Button, + Checkbox, + FormControlLabel, + Tab, + Tabs, + TextField, + Tooltip, + Typography, +} from "@mui/material"; +import { DatePicker } from "@mui/x-date-pickers"; +import axios from "axios"; +import moment from "moment/moment"; +import { useContext, useEffect, useState } from "react"; +import { RiFileExcel2Fill, RiSearchLine } from "react-icons/ri"; +import { useDispatch, useSelector } from "react-redux"; +import { Grid } from "../../../../components/grid/Grid"; +import { AppContext } from "../../../../contexts/AppContext"; +import { SPACING } from "../../../../data/spacing"; +import { formatJustDate, formatTime } from "../../../../utils/formatTime"; +import { provinceGetAllocatedRequestsService } from "../../services/province-get-allocated-requests"; +import { ProvinceAllocatedRequestsOperations } from "../province-allocated-requests-operations/ProvinceAllocatedRequestsOperations"; +import { ProvinceGetDeletedAllocatedRequests } from "../province-get-deleted-allocated-requests/ProvinceGetDeletedAllocatedRequests"; +import { provinceGetDashboardKillRequestService } from "../../services/get-dahsnoard-province-kill-request"; +import ResponsiveTable from "../../../../components/responsive-table/ResponsiveTable"; +import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl"; +import { checkPathStartsWith } from "../../../../utils/checkPathStartsWith"; + +export const ProvinceAllocatedRequests = () => { + const dispatch = useDispatch(); + const [dataTable, setDataTable] = useState(); + const [hasDocumentState, setHasDocumentState] = useState(false); + const [selectedTab, setSelectedTab] = useState(0); + const selectedSubUser = useSelector( + (state) => state.userSlice.selectedSubUser + ); + const userKey = useSelector((state) => state.userSlice.userProfile.key); + + const [textValue, setTextValue] = useState(""); + + const handleTextChange = (event) => { + setTextValue(event.target.value); + }; + const handleChangeDocumentState = (event) => { + const checked = event.target.checked; + setHasDocumentState(checked); + + dispatch( + provinceGetAllocatedRequestsService({ + role_key: checkPathStartsWith("province") + ? selectedSubUser?.key || "" + : "", + selectedDate1, + selectedDate2, + textValue, + hasDocumentState: checked, + }) + ); + + fetchDashboard(checked); + }; + + const handleTabChange = (event, newValue) => { + setSelectedTab(newValue); + }; + + const [, , selectedDate1, setSelectedDate1, selectedDate2, setSelectedDate2] = + useContext(AppContext); + useEffect(() => { + const currentDate = moment(new Date()).format("YYYY-MM-DD"); + setSelectedDate1(currentDate); + setSelectedDate2(currentDate); + }, []); + + const { provinceGetAllocatedRequests } = useSelector( + (state) => state.provinceSlice + ); + + const [dashboardData, setDashboardData] = useState([]); + + const fetchDashboard = (checked = hasDocumentState) => { + const params = { + selectedDate1, + selectedDate2, + textValue, + hasDocumentState: checked, + role_key: checkPathStartsWith("province") + ? selectedSubUser?.key || "" + : "", + }; + + dispatch(provinceGetDashboardKillRequestService(params)).then((r) => { + setDashboardData(r.payload.data); + }); + }; + + useEffect(() => { + if (selectedTab === 0) { + dispatch( + provinceGetAllocatedRequestsService({ + role_key: checkPathStartsWith("province") + ? selectedSubUser?.key || "" + : "", + selectedDate1, + selectedDate2, + textValue, + hasDocumentState, + }) + ); + fetchDashboard(); + } + }, [selectedDate1, selectedDate2, selectedTab, selectedSubUser?.key]); + + const handleSubmit = () => { + if (selectedTab === 0) { + dispatch( + provinceGetAllocatedRequestsService({ + role_key: checkPathStartsWith("province") + ? selectedSubUser?.key || "" + : "", + selectedDate1, + selectedDate2, + textValue, + hasDocumentState, + }) + ); + fetchDashboard(hasDocumentState); + } + }; + + useEffect(() => { + const sortedRequests = provinceGetAllocatedRequests + ?.slice() + .sort((a, b) => b.allocatedRemainQuantity - a.allocatedRemainQuantity) + .map((item, i) => { + let state = ""; + if (item.allocatedState === "pending") { + state = "در انتظار تایید"; + } else if (item.allocatedState === "accepted") { + state = "تایید شده"; + } else if (item.allocatedState === "rejected") { + state = "رد شده"; + } + let sellType = ""; + if (item?.market) { + sellType = "پنل معاملات"; + } else if (item?.directBuying) { + sellType = "خرید مستقیم"; + } else if (item?.union) { + sellType = "خرید خارج از استان"; + } else { + sellType = "اتحادیه"; + } + return [ + i + 1, + item?.orderCode, + sellType, + item?.freeSaleInProvince === false ? "دولتی" : "آزاد", + item?.freezing ? "انجماد" : item?.export ? "صادرات" : "عادی", + item?.poultryUnitName, + `${item?.poultryFullName} (${item?.poultryMobile})`, + item?.poultryCity, + formatJustDate(item?.sendDate), + item?.poultryQuantity?.toLocaleString(), + formatTime(item?.dateOfAllocate), + item?.killHouseName, + item?.killHouseCity, + item?.allocatedQuantity?.toLocaleString(), + item?.indexWeight?.toLocaleString(), + item?.totalWeight?.toLocaleString(), + item?.amount?.toLocaleString() + " ﷼", + item?.killHousePrice?.toLocaleString() + " ﷼", + state, + item?.allocatedCarState ? "دارد" : "ندارد", + item?.allocatedRemainQuantity?.toLocaleString(), + item?.returnToProvince === false ? ( + + ) : ( + + {item?.returner && ( + + + {item?.returner?.fullname || "-"} ( + {item?.returner?.mobile || "-"}) + + + {item?.returner?.date + ? formatJustDate(item?.returner?.date) + : "-"} + + + )} + + } + > + + تخصیص برگشت داده شده + + + ), + ]; + }); + setDataTable(sortedRequests); + }, [provinceGetAllocatedRequests]); + + return ( + + + + + + + + {selectedTab === 0 && ( + + + + } + value={selectedDate1} + onChange={(e) => { + setSelectedDate1(moment(e).format("YYYY-MM-DD")); + }} + /> + + + } + value={selectedDate2} + onChange={(e) => { + setSelectedDate2(moment(e).format("YYYY-MM-DD")); + }} + /> + + + + + + + + + + + + + + + } + label="نمایش تخصیصات بدون بار" + /> + + + + + + + + + )} + {selectedTab === 1 && } + + ); +}; diff --git a/src/features/province/components/province-allocation-invoice/ProvinceAllcationInvoice.js b/src/features/province/components/province-allocation-invoice/ProvinceAllcationInvoice.js new file mode 100644 index 0000000..202d65e --- /dev/null +++ b/src/features/province/components/province-allocation-invoice/ProvinceAllcationInvoice.js @@ -0,0 +1,406 @@ +import React, { forwardRef } from "react"; +import logo from "../../../../assets/images/ChickenLogo.png"; +import { PropTypes } from "prop-types"; +import { formatJustDate } from "../../../../utils/formatTime"; +import { getCeoName } from "../../../../utils/getCeoName"; +import { useSystemName } from "../../../../utils/getSystemName"; + +const styles = { + page: { + width: "210mm", + margin: "0 auto", + display: "flex", + flexDirection: "column", + position: "relative", + direction: "rtl", + fontFamily: "nazanin", + fontWeight: "bold", + }, + container: { + width: "95%", + alignSelf: "center", + pageBreakInside: "avoid", + }, + p: { + fontFamily: "nazanin", + fontWeight: "bold", + pAlign: "justify", + }, + span: { + fontFamily: "nazanin", + fontWeight: "bold", + pAlign: "justify", + }, + invoiceTable: { + width: "100%", + borderCollapse: "collapse", + alignSelf: "center", + }, + tableCell: { + border: "1px solid #000", + pAlign: "left", + textAlign: "center", + fontSize: 11, + }, + tableCellMobile: { + border: "1px solid #000", + pAlign: "left", + textAlign: "center", + fontSize: 10, + }, + tableInnerCell: { + border: "1px solid #000", + pAlign: "left", + textAlign: "center", + fontSize: 8, + whiteSpace: "nowrap", + }, + tableHeader: { + backgroundColor: "rgba(255, 229, 153, 0.5)", + pageBreakAfter: "auto", + }, + headerRow: { + backgroundColor: "rgba(255, 229, 153, 0.6)", + color: "black", + pageBreakInside: "avoid", + pageBreakAfter: "auto", + }, + logo: { + width: "60px", + height: "auto", + marginBottom: "10px", + }, + contentContainer: { + display: "flex", + justifyContent: "space-between", + marginTop: "20px", + marginLeft: "100px", + marginRight: "30px", + }, + contentInLine: { + display: "flex", + flexDirection: "column", + alignItems: "center", + }, + mainTitle: { + fontFamily: "nazanin", + fontSize: 11, + pAlign: "center", + fontWeight: "bolder", + }, + signature: { + display: "flex", + flexDirection: "column", + alignItems: "flex-end", + marginLeft: "20px", + }, + watermarkContainer: { + position: "fixed", + top: 450, + left: 0, + right: 30, + bottom: 0, + justifyContent: "center", + alignItems: "center", + opacity: 0.2, + zIndex: -1, + }, + watermarkp: { + fontSize: 100, + fontWeight: "bolder", + color: "grey", + transform: "rotate(-45deg)", + left: "50%", + }, + title: { + fontSize: 12, + fontWeight: "bolder", + pAlign: "center", + }, + titleTopic: { + marginTop: "10px", + fontSize: 12, + fontWeight: "bolder", + pAlign: "center", + }, + firsttitle: { + fontSize: 14, + fontWeight: "bolder", + marginLeft: "40px", + pAlign: "center", + }, + title2: { + fontSize: 10, + marginBottom: 10, + pAlign: "center", + }, + options: { + marginLeft: "50px", + padding: "10px", + marginTop: "15px", + display: "flex", + flexDirection: "column", + alignItems: "flex-start", + }, + divider: { + width: "100%", + height: "2px", + backgroundColor: "red", + marginBottom: 15, + }, + pTitleContainer: { + pAlign: "right", + margin: "15px", + textAlign: "justify", + textJustify: "inter-word", + }, + tableHeaderCell: { + backgroundColor: "rgba(255, 229, 153, 0.5)", + fontSize: 10, + border: "1px solid #000", + padding: "4px", + textAlign: "center", + fontWeight: "bold", + }, + footer: { + pageBreakAfter: "always", + position: "fixed", + left: 0, + bottom: 0, + width: "100%", + }, +}; + +const ProvinceAllcationInvoice = forwardRef((props, ref) => { + const { item } = props; + const { date } = props; + + const totalCapacity = item?.reduce( + (total, currentItem) => total + (currentItem?.quantity || 0), + 0 + ); + + function getItemInfoQuantity(item) { + let totalQuantity = 0; + item?.forEach((option) => { + if (option?.provinceKillRequests) { + option.provinceKillRequests.forEach((request) => { + if (request.info?.quantity !== undefined) { + totalQuantity += request.info.quantity; + } + }); + } + }); + return totalQuantity; + } + + function getItemInfoWeight(item) { + let totalQuantity = 0; + item?.forEach((option) => { + if (option?.provinceKillRequests) { + option.provinceKillRequests.forEach((request) => { + if (request.info?.weight !== undefined) { + totalQuantity += request.info.weight; + } + }); + } + }); + return totalQuantity; + } + + // function getAddressContent(systemName) { + // switch (systemName) { + // case "استان اردبیل": + // return "آدرس : اردبیل، شهرک کارشناسان ،جنب ساختمان نظام مهندسی، ساختمان فرهنگ، طبقه دوم تلفن : 33749254 تلفاکس : 33749253 "; + + // case "استان همدان": + // return "همدان، بلوار آیت اله مدنی، کوچه امامزاده یحیی یک تلفن: 081 32523689 "; + + // case "استان آذربایجان شرقی": + // return "تبریز خیابان راه آهن نبش کوی اشکان ساختمان ۱۴ طبقه دوم تلفن: 041 34502363"; + + // default: + // return "خرم آباد، مطهری، شرکت مهندسی نرم افزار آرتا مهر آرتان تلفن: 09011110919"; + // } + // } + + const systemName = useSystemName(); + + return ( +
    +
    +
    + logo + + اتحادیه سراسری تعاونی‌های کشاورزی پرورش دهندگان مرغ گوشتی ایران + + + اتحادیه شرکت های تعاونی کشاورزی مرغداران {" ‌"} {systemName} + +
    + +
    + بسمه تعالی +
    + +
    + شماره: + تاریخ: + پیوست: +
    +
    + +
    + +

    + + معاونت محترم توسعه بازرگانی و صنایع کشاورزی +
    + با سلام +
    +
    +
    + احتراماً گزارش تخصیص و کشتار مورخ {" ‌"} + {formatJustDate(date)}، مرغ گوشتی استان جهت استحضار بحضورتان ارسال می + گردد. +

    + +
    +

    + اطلاعات تخصیص:{" "} + + {" "} + تعداد درخواست کشتار ( + {totalCapacity !== undefined && totalCapacity.toLocaleString()}{" "} + قطعه)، تخصیص داده شده ({getItemInfoQuantity(item).toLocaleString()}{" "} + قطعه)، وزن کل تخصیص ({" "} + {Math.round(getItemInfoWeight(item)).toLocaleString()} کیلوگرم). + +

    + + + + + + + + + + + + + + + + + + + {item?.map((item, i) => ( + + + + + + + + + + + + + + ))} + +
    ردیفمرغدارتلفنشهرتعدادمیانگین وزنیسنخریدارتعدادوزن تقریبی بارمحل کشتار
    {i + 1} + {item?.poultry?.user?.fullname} + + {item?.poultry?.user?.mobile} + + {item?.poultry?.address?.city?.name} + + {item?.quantity.toLocaleString()} + + {item?.IndexWeight.toLocaleString()} + {item?.hatching?.age} + {item?.provinceKillRequests?.map((item, i, array) => ( + <> + {item?.killhouseUser?.killHouseOperator?.user?.fullname + ? item?.killhouseUser?.killHouseOperator?.user?.fullname + : "............"} +
    + {i < array.length - 1 && ( +
    + )} + + ))} +
    + {item?.provinceKillRequests?.map((item, i, array) => ( + <> + {item?.info?.quantity + ? item?.info?.quantity.toLocaleString() + : "............"} +
    + {i < array.length - 1 && ( +
    + )} + + ))} +
    + {item?.provinceKillRequests?.map((item, i, array) => ( + <> + {Math.round(item?.info?.weight) + ? Math.round(item?.info?.weight).toLocaleString() + : "............"} +
    + {i < array.length - 1 && ( +
    + )} + + ))} +
    + {item?.provinceKillRequests?.map((item, i, array) => ( + <> + {item?.info?.killPlace + ? item?.info?.killPlace + : "............"} +
    + {i < array.length - 1 && ( +
    + )} + + ))} +
    + +
    +
    +
    + {getCeoName()} + + مدیرعامل اتحادیه مرغداران{" ‌"} + {systemName} + +
    +
    +
    +
    +

    سامانه رصدیار

    +
    + + {/*
    +
    +

    + {getAddressContent(systemName)} +

    +
    */} +
    +
    + ); +}); + +ProvinceAllcationInvoice.displayName = "ProvinceAllcationInvoice"; + +export default ProvinceAllcationInvoice; + +ProvinceAllcationInvoice.propTypes = { + item: PropTypes.any, +}; diff --git a/src/features/province/components/province-apply-default-losses/ProvinceApplyDefaultLosses.js b/src/features/province/components/province-apply-default-losses/ProvinceApplyDefaultLosses.js new file mode 100644 index 0000000..9ef2bb8 --- /dev/null +++ b/src/features/province/components/province-apply-default-losses/ProvinceApplyDefaultLosses.js @@ -0,0 +1,86 @@ +import { Button, Checkbox, FormControlLabel, TextField } from "@mui/material"; +import { useEffect, useState } from "react"; +import { useDispatch } from "react-redux"; +import { Grid } from "../../../../components/grid/Grid"; +import { SPACING } from "../../../../data/spacing"; +import { getLossesPermissionService } from "../../services/get-losses-permission"; +import { updateLossesPermissionService } from "../../services/update-losses-permission"; + +export const ProvinceApplyDefaultLosses = () => { + const [isChecked, setIsChecked] = useState(true); + const [numberValue, setNumberValue] = useState(""); + const [data, setData] = useState(); + const dispatch = useDispatch(); + + useEffect(() => { + dispatch(getLossesPermissionService()).then((r) => { + setIsChecked(r.payload.data.allow); + setNumberValue(r.payload.data.percent); + setData(r.payload.data); + }); + }, []); + + useEffect(() => { + if (!isChecked) { + dispatch( + updateLossesPermissionService({ + permission_key: data.key, + allow: false, + percent: parseInt(numberValue), + }) + ); + } + }, [isChecked]); + + const handleChange = (event) => { + setIsChecked(event.target.checked); + }; + + // Define a handleChange function to update the state when the text field value changes + const handleChangeNumber = (event) => { + // Ensure that the entered value is a number (or an empty string) + const newValue = event.target.value; + if (/^\d*$/.test(newValue) || newValue === "") { + setNumberValue(newValue); + } + }; + + return ( + + + } + label="اعمال درصد تلفات پیش فرض:" + /> + + + + + + + + ); +}; diff --git a/src/features/province/components/province-archive-fee-details/ProvinceArchiveFeeDetails.js b/src/features/province/components/province-archive-fee-details/ProvinceArchiveFeeDetails.js new file mode 100644 index 0000000..287118c --- /dev/null +++ b/src/features/province/components/province-archive-fee-details/ProvinceArchiveFeeDetails.js @@ -0,0 +1,25 @@ +import { Typography } from "@mui/material"; +import { Grid } from "../../../../components/grid/Grid"; +import { formatTime } from "../../../../utils/formatTime"; +import { getFaUserRole } from "../../../../utils/getFaUserRole"; + +export const ProvinceArchiveFeeDetails = ({ item }) => { + return ( + + + تاریخ و زمان: + {formatTime(item?.archiver?.date)} + + + بایگانی کننده: + + {item?.archiver?.fullname} ({getFaUserRole(item.archiver.role)}) + + + + دلیل بایگانی: + {item?.archiveMessage} + + + ); +}; diff --git a/src/features/province/components/province-archive-fee-operation/ProvinceArchiveFeeOperation.js b/src/features/province/components/province-archive-fee-operation/ProvinceArchiveFeeOperation.js new file mode 100644 index 0000000..2ba0851 --- /dev/null +++ b/src/features/province/components/province-archive-fee-operation/ProvinceArchiveFeeOperation.js @@ -0,0 +1,76 @@ +import { Button, TextField } from "@mui/material"; +import { Box } from "@mui/system"; +import { useContext, useState } from "react"; +import { useDispatch } from "react-redux"; +import { Grid } from "../../../../components/grid/Grid"; +import { AppContext } from "../../../../contexts/AppContext"; +import { CLOSE_MODAL } from "../../../../lib/redux/slices/appSlice"; +import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl"; +import { provinceArchiveFeeOperationService } from "../../services/province-archive-fee-operation"; + +export const ProvinceArchiveFeeOperation = ({ selectedItems, updateTable }) => { + const dispatch = useDispatch(); + const [openNotif] = useContext(AppContext); + const [text, setText] = useState(""); + + const handleChange = (event) => { + setText(event.target.value); + }; + + const submitForm = () => { + dispatch( + provinceArchiveFeeOperationService({ + role: getRoleFromUrl(), + message: text, + province_kill_request_list: selectedItems, + type: "archive", + }) + ).then((r) => { + updateTable(); + if (r.payload.error) { + openNotif({ + vertical: "top", + horizontal: "center", + msg: r.payload.error, + severity: "error", + }); + } else { + openNotif({ + vertical: "top", + horizontal: "center", + msg: "عملیات با موفقیت انجام شد.", + severity: "success", + }); + dispatch(CLOSE_MODAL()); + } + }); + }; + + return ( + + + + + + + + + ); +}; diff --git a/src/features/province/components/province-archive-fees/ProvinceArchiveFees.js b/src/features/province/components/province-archive-fees/ProvinceArchiveFees.js new file mode 100644 index 0000000..6a606c3 --- /dev/null +++ b/src/features/province/components/province-archive-fees/ProvinceArchiveFees.js @@ -0,0 +1,365 @@ +import { + Button, + Checkbox, + FormControlLabel, + TextField, + Tooltip, + Typography, +} from "@mui/material"; +import axios from "axios"; +import { useContext, useEffect, useState } from "react"; +import { RiFileExcel2Fill, RiSearchLine } from "react-icons/ri"; +import { useSelector } from "react-redux"; +import { useNavigate } from "react-router-dom"; +import { Grid } from "../../../../components/grid/Grid"; +import { PageTable } from "../../../../components/page-table/PageTable"; +import { SPACING } from "../../../../data/spacing"; +import { ROUTE_PROVINCE_PAYING_FEES_REQUESTS } from "../../../../routes/routes"; +import moment from "moment"; +import { DatePicker } from "@mui/x-date-pickers"; +import { AppContext } from "../../../../contexts/AppContext"; +import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl"; + +export const ProvinceArchiveFees = () => { + const userInfo = useSelector((state) => state.userSlice); + const navigate = useNavigate(); + const [data, setData] = useState([]); + const [loading, setLoading] = useState(false); + const [totalRows, setTotalRows] = useState(0); + const [perPage, setPerPage] = useState(10); + const [withDate, setWithDate] = useState(false); + + const [textValue, setTextValue] = useState(""); + + const handleTextChange = (event) => { + setTextValue(event.target.value); + }; + + const [, , selectedDate1, setSelectedDate1, selectedDate2, setSelectedDate2] = + useContext(AppContext); + + useEffect(() => { + const currentDate = moment(new Date()).format("YYYY-MM-DD"); + setSelectedDate1(currentDate); + setSelectedDate2(currentDate); + }, []); + + const fetchApiData = async (page, textValue) => { + setLoading(true); + const response = await axios.get( + `kill_house_total_wage/?search=filter&value=${textValue}&role=${getRoleFromUrl()}&type=archive&page=${page}&page_size=${perPage}${ + withDate ? `&date1=${selectedDate1}&date2=${selectedDate2}` : `` + }` + ); + setData(response.data.results); + setTotalRows(response.data.count); + setLoading(false); + }; + + const handlePageChange = (page) => { + fetchApiData(page, textValue); + }; + + const handlePerRowsChange = async (newPerPage, page) => { + setLoading(true); + const response = await axios.get( + `kill_house_total_wage/?search=filter&value=${textValue}&role=${getRoleFromUrl()}&type=archive&page=${page}&page_size=${newPerPage}${ + withDate ? `&date1=${selectedDate1}&date2=${selectedDate2}` : `` + }` + ); + + setData(response.data.results); + setTotalRows(response.data.count); + setPerPage(newPerPage); + + setLoading(false); + }; + + useEffect(() => { + fetchApiData(1); + }, []); + + const handleSubmit = async (event) => { + event.preventDefault(); + setLoading(true); + try { + const response = await axios.get( + `kill_house_total_wage/?search=filter&value=${textValue}&role=${getRoleFromUrl()}&type=archive${ + withDate ? `&date1=${selectedDate1}&date2=${selectedDate2}` : `` + }` + ); + setData(response.data.results); + setTotalRows(response.data.count); + } catch (error) { + console.error("Error fetching data:", error); + } finally { + setLoading(false); + } + }; + + useEffect(() => { + fetchApiData(1); + }, [selectedDate1, selectedDate2, withDate]); + + const columns = [ + { + name: "خریدار", + selector: (item) => { + const type = item?.info?.killer ? "کشتارکن" : "کشتارگاه"; + return `${type} ${item?.info?.killHouseName} - ${item?.info?.killHouseFullname} (${item?.info?.killHouseMobile})`; + }, + sortable: true, + wrap: true, + allowOverflow: true, + center: true, + // width: "90px", + }, + { + name: "شهر", + selector: (item) => `${item?.info?.killHouseCity}`, + sortable: true, + wrap: true, + allowOverflow: true, + center: true, + // width: "80px", + }, + // { + // name: "تعداد کل سفارشات", + // selector: (item) => item?.info?.totalCount, + // sortable: true, + // wrap: true, + // allowOverflow: true, + // center: true, + // // width: "80px", + // }, + // { + // name: "تعداد کل تخصیص (قطعه)", + // selector: (item) => item?.info?.totalQuantity?.toLocaleString(), + // sortable: true, + // wrap: true, + // allowOverflow: true, + // center: true, + // }, + // { + // name: "وزن کل (کیلوگرم)", + // selector: (item) => item?.info?.totalWeight, + // sortable: true, + // wrap: true, + // allowOverflow: true, + // center: true, + // // width: "80px", + // }, + // { + // name: "پرداخت شده (سفارش)", + // selector: (item) => item.info?.paidCount, + // sortable: true, + // wrap: true, + // allowOverflow: true, + // center: true, + // // width: "90px", + // }, + { + name: "تعداد پرونده", + selector: (item) => item?.info?.archiveCount?.toLocaleString(), + sortable: true, + wrap: true, + allowOverflow: true, + center: true, + // width: "90px", + }, + { + name: "حجم", + selector: (item) => item.info?.totalArchiveQuantity?.toLocaleString(), + sortable: true, + wrap: true, + allowOverflow: true, + center: true, + // width: "90px", + }, + { + name: "وزن سفارشات (کیلوگرم)", + selector: (item) => { + return item.info?.totalWeightArchive?.toLocaleString(); + }, + sortable: true, + wrap: true, + allowOverflow: true, + center: true, + // width: "90px", + }, + // { + // name: "مبلغ کل تعرفه (ریال)", + // selector: (item) => item?.info?.totalWage?.toLocaleString(), + // sortable: true, + // wrap: true, + // allowOverflow: true, + // center: true, + // // width: "90px", + // }, + // { + // name: "مبلغ تسویه شده (تعرفه )", + // selector: (item) => item?.info?.totalPaidWage?.toLocaleString(), + // sortable: true, + // wrap: true, + // allowOverflow: true, + // center: true, + // // width: "90px", + // }, + { + name: "مبلغ تعرفه (﷼)", + selector: (item) => item?.info?.totalArchiveWage?.toLocaleString(), + sortable: true, + wrap: true, + allowOverflow: true, + center: true, + // width: "90px", + }, + { + name: "جزییات سفارش", + selector: (item) => { + return ( + + ); + }, + sortable: true, + wrap: true, + allowOverflow: true, + center: true, + // width: "90px", + }, + ]; + + return ( + + + + تعرفه های معوقه + + + setWithDate(!withDate)} + color="primary" + /> + } + /> + + + ( + + )} + value={selectedDate1} + onChange={(e) => { + setSelectedDate1(moment(e).format("YYYY-MM-DD")); + }} + /> + + + ( + + )} + value={selectedDate2} + onChange={(e) => { + setSelectedDate2(moment(e).format("YYYY-MM-DD")); + }} + /> + + +
    + + + + + + + + +
    +
    + } + columns={columns} + data={data} + progressPending={loading} + pagination + paginationServer + paginationTotalRows={totalRows} + onChangeRowsPerPage={handlePerRowsChange} + onChangePage={handlePageChange} + /> + + ); +}; diff --git a/src/features/province/components/province-auto-allocated-view/ProvinceAutoAllocatedView.js b/src/features/province/components/province-auto-allocated-view/ProvinceAutoAllocatedView.js new file mode 100644 index 0000000..99120a9 --- /dev/null +++ b/src/features/province/components/province-auto-allocated-view/ProvinceAutoAllocatedView.js @@ -0,0 +1,180 @@ +import { Button, IconButton } from "@mui/material"; +import PrintIcon from "@mui/icons-material/Print"; +import { Grid } from "../../../../components/grid/Grid"; +import { formatJustDate } from "../../../../utils/formatTime"; +import KeyboardArrowRightIcon from "@mui/icons-material/KeyboardArrowRight"; +import { SPACING } from "../../../../data/spacing"; + +export const ProvinceAutoAllocatedView = ({ + dataTable, + item, + setIsSingleView, +}) => { + const sumOfAllocationQuantity = + Array.isArray(dataTable) && + dataTable?.reduce((total, item) => { + return ( + total + + item.allocations?.reduce((allocationTotal, allocation) => { + return allocationTotal + allocation.allocationQuantity; + }, 0) + ); + }, 0); + + const sumAllocationsSum = + Array.isArray(dataTable) && + dataTable?.reduce((total, item) => { + return total + item.allocationsSum; + }, 0); + + const sumOfKillRequests = + Array.isArray(dataTable) && + dataTable?.reduce((total, item) => { + return total + item.poultryQuantity; + }, 0); + + return ( + + + + + + + +
    + + + + کد تخصیص خودکار {item.allocationOrderCode}تاریخ تخصیص {formatJustDate(item.allocationDate)}
    + + + + + + + + + + + + + + + + + + + + {dataTable?.map((poultryRequestItem, j) => { + // const sumOfAllocation = poultryRequestItem.allocations?.reduce( + // (total, item) => { + // return total + item.allocationQuantity; + // }, + // 0 + // ); + return poultryRequestItem?.allocations?.map((slaughter, i) => { + const reaminForAllocation = + poultryRequestItem?.poultryQuantity - + poultryRequestItem?.allocationsSum; + + // if (reaminForAllocation < 0) { + // reaminForAllocation = ( + // {reaminForAllocation} + // ); + // } + + return ( + + {!i && ( + + )} + + {!i && ( + + )} + + {!i && ( + + )} + + {!i && ( + + )} + + {!i && ( + + )} + + {!i && ( + + )} + + + + + + + + + {!i && ( + + )} + + {!i && ( + + )} + + + ); + }); + })} + + + + + + +
    ردیفنام واحد (مرغدار)تلفن مرغدارآدرستعداد درخواست کشتارمانده قابل تخصیصماهیت خریدارنام خریدارتلفن خریدارآدرسمحل کشتارتعداد تخصیصجمع مرغ تخصیصیسهم درصدحواله مرغدارحواله خریدار
    + {j + 1} + + {poultryRequestItem?.poultryName} + + {poultryRequestItem?.poultryMobile} + + {poultryRequestItem?.poultryAddress} + + {poultryRequestItem?.poultryQuantity?.toLocaleString()} + + {/* {poultryRequestItem?.poultryRemainQuantity} */} + {reaminForAllocation.toLocaleString()} + {slaughter?.type ? "کشتارکن" : "کشتارگاه"}{slaughter?.buyerName}{slaughter?.buyerMobile}{slaughter?.buyerAddress}{slaughter?.KillingPlace}{slaughter?.allocationQuantity} + {poultryRequestItem?.allocationsSum?.toLocaleString()} + {/* {sumOfAllocation} */} + + % + {( + (slaughter?.allocationQuantity / sumOfAllocationQuantity) * + 100 + ).toFixed(2)} + + + + + + + + +
    جمع کل{sumOfAllocationQuantity.toLocaleString()}{sumAllocationsSum.toLocaleString()} + {((sumOfAllocationQuantity / sumOfKillRequests) * 100).toFixed(2)} +
    +
    + ); +}; diff --git a/src/features/province/components/province-auto-allocation-archive/ProvinceAutoAllocationArchive.js b/src/features/province/components/province-auto-allocation-archive/ProvinceAutoAllocationArchive.js new file mode 100644 index 0000000..149d0b5 --- /dev/null +++ b/src/features/province/components/province-auto-allocation-archive/ProvinceAutoAllocationArchive.js @@ -0,0 +1,130 @@ +import { IconButton, TextField, Typography } from "@mui/material"; +import { DatePicker } from "@mui/x-date-pickers"; +import moment from "moment/moment"; +import { useContext, useEffect, useState } from "react"; +import { useDispatch, useSelector } from "react-redux"; +import ResponsiveTable from "../../../../components/responsive-table/ResponsiveTable"; +import { Grid } from "../../../../components/grid/Grid"; +import { AppContext } from "../../../../contexts/AppContext"; +import { SPACING } from "../../../../data/spacing"; +import { provinceGetArchiveAutoAllocationsService } from "../../services/province-get-archive-auto-allocations"; +import PlagiarismIcon from "@mui/icons-material/Plagiarism"; +import { ProvinceAutoAllocatedView } from "../province-auto-allocated-view/ProvinceAutoAllocatedView"; +import { formatJustDate } from "../../../../utils/formatTime"; + +export const ProvinceAutoAllocationArchive = () => { + const dispatch = useDispatch(); + const [dataTable, setDataTable] = useState([]); + const [isSingleView, setIsSingleView] = useState(); + const [, , selectedDate1, setSelectedDate1, selectedDate2, setSelectedDate2] = + useContext(AppContext); + + useEffect(() => { + const currentDate = moment(new Date()).format("YYYY-MM-DD"); + setSelectedDate1(currentDate); + setSelectedDate2(currentDate); + }, []); + + const { provinceGetArchiveAutoAllocations } = useSelector( + (state) => state.provinceSlice + ); + + useEffect(() => { + dispatch( + provinceGetArchiveAutoAllocationsService({ selectedDate1, selectedDate2 }) + ); + }, [selectedDate1, selectedDate2]); + + useEffect(() => { + const d = provinceGetArchiveAutoAllocations?.map((item, i) => { + return [ + i + 1, + item.allocationOrderCode, + formatJustDate(item.allocationDate), + item.totalQuantity.toLocaleString(), + item.allocatedQuantity.toLocaleString(), + item.numberOfPoultry.toLocaleString(), + item.numberOfKillHouse.toLocaleString(), + { + setIsSingleView(item); + }} + > + + , + ]; + }); + setDataTable(d); + }, [provinceGetArchiveAutoAllocations]); + + return ( + + {!isSingleView && ( + <> + + + بایگانی تخصیصات خودکار + + + ( + + )} + value={selectedDate1} + onChange={(e) => { + setSelectedDate1(moment(e).format("YYYY-MM-DD")); + }} + /> + + + ( + + )} + value={selectedDate2} + onChange={(e) => { + setSelectedDate2(moment(e).format("YYYY-MM-DD")); + }} + /> + + + + + )} + + {isSingleView && ( + + + + )} + + ); +}; diff --git a/src/features/province/components/province-auto-allocation-requests/ProvinceAutoAllocationRequests.js b/src/features/province/components/province-auto-allocation-requests/ProvinceAutoAllocationRequests.js new file mode 100644 index 0000000..3ff1073 --- /dev/null +++ b/src/features/province/components/province-auto-allocation-requests/ProvinceAutoAllocationRequests.js @@ -0,0 +1,791 @@ +import { + Button, + IconButton, + Popover, + TextField, + Typography, +} from "@mui/material"; +import { useContext, useEffect, useState } from "react"; +import { useDispatch, useSelector } from "react-redux"; +import { Grid } from "../../../../components/grid/Grid"; +import { SimpleTable } from "../../../../components/simple-table/SimpleTable"; +import { AppContext } from "../../../../contexts/AppContext"; +import { SPACING } from "../../../../data/spacing"; +import { getPoultryRequestsTotalQuantityService } from "../../../city/services/get-poultry-requests-total-quantity"; +import { provinceCreateAutoAllocationService } from "../../services/province-create-auto-allocation"; +import { provinceEditAutoAllocationService } from "../../services/province-edit-auto-allocation"; +import { provinceGetAutoAllocationsService } from "../../services/province-get-auto-allocations"; +import DeleteIcon from "@mui/icons-material/Delete"; +import AddIcon from "@mui/icons-material/Add"; +import { OPEN_MODAL } from "../../../../lib/redux/slices/appSlice"; +import { ProvinceAddBuyerAutoAllocation } from "../province-add-buyer-auto-allocation/ProvinceAddBuyerAutoAllocation"; +import { provinceDeleteAutoAllocationService } from "../../services/province-delete-auto-allocation"; +import { provinceAddAutoAllocationService } from "../../services/province-add-auto-allocation"; +import PrintIcon from "@mui/icons-material/Print"; +import { provinceSubmitFinalAutoAllocationsService } from "../../services/province-submit-final-auto-allocations"; +import { DatePicker } from "@mui/x-date-pickers"; +import moment from "moment/moment"; +import { ProvinceAutoSelectOptions } from "../province-auto-select-options/ProvinceAutoSelectOptions"; + +export const ProvinceAutoAllocationRequests = () => { + const dispatch = useDispatch(); + const [openNotif] = useContext(AppContext); + const [dataTable, setDataTable] = useState([]); + const [deletedRows, setDeletedRows] = useState([]); + const [addedRows, setAddedRows] = useState([]); + + const [selectedProiority, setSelectedProiority] = useState({}); + // const [allocationSumState, setAllocationSumState] = useState(0); + + const [anchorEl, setAnchorEl] = useState(null); + + const open = Boolean(anchorEl); + const id = open ? "popoverr" : undefined; + + const handleClick = (event) => { + setAnchorEl(event.currentTarget); + }; + + const handleClose = () => { + setAnchorEl(null); + }; + + useEffect(() => { + handleClose(); + }, []); + + const { poultryRequestsTotalQuantity } = useSelector( + (state) => state.citySlice + ); + + const { provinceGetAutoAllocations } = useSelector( + (state) => state.provinceSlice + ); + + useEffect(() => { + dispatch(provinceGetAutoAllocationsService()); + }, []); + + useEffect(() => { + setDataTable(deepCopy(provinceGetAutoAllocations)); + }, [provinceGetAutoAllocations]); + + const sendEditTableService = () => { + const combinedArr = dataTable?.reduce((acc, curr) => { + let d = deepCopy(curr.allocations); + d = d.filter((item) => item.allocationKey); + return [...acc, ...d]; + }, []); + dispatch( + provinceDeleteAutoAllocationService({ + allocation_delete_list: deletedRows?.filter( + (item) => item.allocationKey + ), + }) + ).then(() => { + setDeletedRows([]); + dispatch( + provinceAddAutoAllocationService({ + allocation_add_list: addedRows, + }) + ).then(() => { + dispatch( + provinceEditAutoAllocationService({ + allocation_list: combinedArr, + }) + ).then((r) => { + setAddedRows([]); + if (r.payload.error) { + openNotif({ + vertical: "top", + horizontal: "center", + msg: r.payload.error, + severity: "error", + }); + } else { + dispatch(getPoultryRequestsTotalQuantityService()); + dispatch(provinceGetAutoAllocationsService()); + openNotif({ + vertical: "top", + horizontal: "center", + msg: "عملیات با موفقیت انجام شد.", + severity: "success", + }); + } + }); + }); + }); + }; + + const checkForDebt = () => { + // check if there are debt + + const mapedDebts = dataTable.map((element) => { + const hasDebt = element.allocations.some((allocation) => allocation.debt); + return hasDebt; + }); + const res = mapedDebts.some((item) => item); + return res; + }; + + const sendFinalTableService = () => { + const combinedArr = dataTable?.reduce((acc, curr) => { + let d = deepCopy(curr.allocations); + d = d.filter((item) => item.allocationKey); + return [...acc, ...d]; + }, []); + dispatch( + provinceDeleteAutoAllocationService({ + allocation_delete_list: deletedRows?.filter( + (item) => item.allocationKey + ), + }) + ).then(() => { + setDeletedRows([]); + dispatch( + provinceAddAutoAllocationService({ + allocation_add_list: addedRows, + }) + ).then(() => { + dispatch( + provinceEditAutoAllocationService({ + allocation_list: combinedArr, + }) + ).then(() => { + setAddedRows([]); + + const allocationsForCancel = provinceGetAutoAllocations?.reduce( + (total, item) => { + return [...total, ...item.allocations]; + }, + [] + ); + const allocationsKeys = allocationsForCancel.map((item) => { + return { allocationKey: item.allocationKey }; + }); + dispatch( + provinceSubmitFinalAutoAllocationsService({ + final_registration_list: allocationsKeys, + }) + ).then((r) => { + if (r.payload.error) { + openNotif({ + vertical: "top", + horizontal: "center", + msg: r.payload.error, + severity: "error", + }); + } else { + dispatch(getPoultryRequestsTotalQuantityService()); + dispatch(provinceGetAutoAllocationsService()); + openNotif({ + vertical: "top", + horizontal: "center", + msg: "عملیات با موفقیت انجام شد.", + severity: "success", + }); + } + }); + }); + }); + }); + }; + + const sumOfAllocationQuantity = + Array.isArray(dataTable) && + dataTable?.reduce((total, item) => { + return ( + total + + item.allocations?.reduce((allocationTotal, allocation) => { + return allocationTotal + allocation.allocationQuantity; + }, 0) + ); + }, 0); + + const sumAllocationsSum = + Array.isArray(dataTable) && + dataTable?.reduce((total, item) => { + return total + item.allocationsSum; + }, 0); + + // const sumOfAllocationPercent = provinceGetAutoAllocations?.reduce( + // (total, item) => { + // return ( + // total + + // item.allocations.reduce((allocationTotal, allocation) => { + // return allocationTotal + allocation.allocationPercent; + // }, 0) + // ); + // }, + // 0 + // ); + + const sumOfKillRequests = + Array.isArray(dataTable) && + dataTable?.reduce((total, item) => { + return total + item.poultryQuantity; + }, 0); + + const [dateForAutoAlloction, setDateForAutoAllocation] = useState( + moment(new Date()).format("YYYY-MM-DD") + ); + + useEffect(() => { + dispatch(getPoultryRequestsTotalQuantityService(dateForAutoAlloction)); + }, [dateForAutoAlloction]); + + const handleList = (selected) => { + const d = selected.map((item) => { + return { + [item.key]: item.value, + }; + }); + setSelectedProiority(d); + }; + + return ( + + + ( + + )} + value={dateForAutoAlloction} + onChange={(e) => { + setDateForAutoAllocation(moment(e).format("YYYY-MM-DD")); + }} + /> + + } + columns={[ + "تعداد کل درخواست کشتار", + "تخصیص داده شده", + "قابل تخصیص", + "تعداد خریداران آماده به تخصیص", + "تعداد مرغدار", + ]} + data={[ + [ + `${poultryRequestsTotalQuantity?.acceptedQuantity?.toLocaleString()} قطعه`, + `${poultryRequestsTotalQuantity?.allocatedQuantity?.toLocaleString()} قطعه`, + `${poultryRequestsTotalQuantity?.assignableQuantity?.toLocaleString()} قطعه`, + `${poultryRequestsTotalQuantity?.numberOfKillHouse?.toLocaleString()} واحد`, + `${poultryRequestsTotalQuantity?.numberOfPoultry?.toLocaleString()} واحد`, + ], + ]} + /> + + + + اولویت بندی کشتارگاه + + + + + + + + {!!dataTable?.length && ( + <> + + + * توجه: رنگ قرمز خریدار نشان دهنده بدهی قبلی است. + + + + + + + + + + + + + + + + + + + + + + {dataTable?.map((poultryRequestItem, j) => { + // const sumOfAllocation = poultryRequestItem.allocations?.reduce( + // (total, item) => { + // return total + item.allocationQuantity; + // }, + // 0 + // ); + return poultryRequestItem?.allocations?.map((slaughter, i) => { + let reaminForAllocation = + poultryRequestItem?.poultryQuantity - + poultryRequestItem?.allocationsSum; + + // if (reaminForAllocation < 0) { + // reaminForAllocation = ( + // {reaminForAllocation} + // ); + // } + + return ( + + {!i && ( + + )} + + {!i && ( + + )} + + {!i && ( + + )} + + {!i && ( + + )} + + {!i && ( + + )} + {!i && ( + + )} + + + + + + + + {!i && ( + + )} + + {!i && ( + + )} + + + + ); + }); + })} + + + + + + + +
    ردیفواحد (مرغدار)تعداد درخواست کشتاروزن تقریبی درخواست کشتارمانده قابل تخصیصاضافهماهیت خریدارخریدارمحل کشتارتعداد تخصیصجمع مرغ تخصیصیسهم درصدحواله مرغدارحواله خریدارحذف
    + {j + 1} + + {poultryRequestItem?.poultryName} ( + {poultryRequestItem?.poultryAddress}) ( + {poultryRequestItem?.poultryMobile}) + + {poultryRequestItem?.poultryQuantity?.toLocaleString()} + + وزن تقریبی:{" "} + {poultryRequestItem?.poultryRequestWeight?.toLocaleString()} +
    + میانگین وزن:{" "} + {poultryRequestItem?.poultryRequestIndexWeight} +
    + {/* {poultryRequestItem?.poultryRemainQuantity} */} + {reaminForAllocation.toLocaleString()} + + { + dispatch( + OPEN_MODAL({ + title: "اضافه کردن خریدار", + content: ( + + ), + }) + ); + // setDataTable((prevState) => { + // // let edited = Array.from(prevState); + // let edited = deepCopy(prevState); + + // edited[j].allocationsSum = edited[ + // j + // ].allocations?.reduce((total, item) => { + // return total + item.allocationQuantity; + // }, 0); + + // return edited; + // }); + }} + > + + + + {slaughter?.type ? "کشتارکن" : "کشتارگاه"}{" "} + {slaughter.debt ? "(بدهکار)" : ""} + + {slaughter?.buyerName} ({slaughter?.buyerAddress}) ( + {slaughter?.buyerMobile}) + + {slaughter?.KillingPlace} + + { + if (Number(e.target.value) < 1) { + openNotif({ + vertical: "top", + horizontal: "center", + msg: "در صورت نیاز به کاهش کمتر از 1 از گزینه حذف استفاده نمایید.", + severity: "error", + }); + return; + } + setDataTable((prevState) => { + // let edited = Array.from(prevState); + let edited = deepCopy(prevState); + edited[j].allocations[i].allocationQuantity = + Number(e.target.value); + + edited[j].allocationsSum = edited[ + j + ].allocations?.reduce((total, item) => { + return total + item.allocationQuantity; + }, 0); + + return edited; + }); + }} + /> + + {poultryRequestItem?.allocationsSum?.toLocaleString()} + {/* {sumOfAllocation} */} + + % + {( + (slaughter?.allocationQuantity / + sumOfAllocationQuantity) * + 100 + ).toFixed(2)} + + + + + + + + + + + + + + { + setDataTable((prevState) => { + // let edited = Array.from(prevState); + let edited = deepCopy(prevState); + setDeletedRows([ + ...deletedRows, + edited[j].allocations[i], + ]); + edited[j].allocations.splice(i, 1); + + edited[j].allocationsSum = edited[ + j + ].allocations?.reduce((total, item) => { + return total + item.allocationQuantity; + }, 0); + return edited; + }); + }} + > + + +
    جمع کل{sumOfAllocationQuantity.toLocaleString()}{sumAllocationsSum.toLocaleString()} + {/* {sumOfAllocationPercent} */}% + {((sumOfAllocationQuantity / sumOfKillRequests) * 100).toFixed( + 2 + )} + + + +
    + + + + + +
    +
    +
    + + )} + + {!dataTable.length && ( + + تخصیص خودکار ایجاد نشده است! + + )} + + ); +}; + +function deepCopy(obj) { + let newObj = Array.isArray(obj) ? [] : {}; + for (let key in obj) { + if (typeof obj[key] === "object" && obj[key] !== null) { + newObj[key] = deepCopy(obj[key]); + } else { + newObj[key] = obj[key]; + } + } + return newObj; +} diff --git a/src/features/province/components/province-auto-allocation/ProvinceAutoAllocation.js b/src/features/province/components/province-auto-allocation/ProvinceAutoAllocation.js new file mode 100644 index 0000000..8e9d0b5 --- /dev/null +++ b/src/features/province/components/province-auto-allocation/ProvinceAutoAllocation.js @@ -0,0 +1,33 @@ +import { Tab, Tabs } from "@mui/material"; +import { useState } from "react"; +import { Grid } from "../../../../components/grid/Grid"; +import { ProvinceAutoAllocationArchive } from "../province-auto-allocation-archive/ProvinceAutoAllocationArchive"; +import { ProvinceAutoAllocationRequests } from "../province-auto-allocation-requests/ProvinceAutoAllocationRequests"; +import { ProvinceSlaughterhouseQuota } from "../province-slaughterhouse-quota/ProvinceSlaughterhouseQuota"; + +export const ProvinceAutoAllocation = () => { + const [activeTab, setActiveTab] = useState(0); + + const handleTabChange = (event, newValue) => { + setActiveTab(newValue); + }; + + return ( + + + + + + + + + {activeTab === 0 && } + {activeTab === 1 && } + {activeTab === 2 && } + + ); +}; diff --git a/src/features/province/components/province-auto-select-options/ProvinceAutoSelectOptions.js b/src/features/province/components/province-auto-select-options/ProvinceAutoSelectOptions.js new file mode 100644 index 0000000..2aa6791 --- /dev/null +++ b/src/features/province/components/province-auto-select-options/ProvinceAutoSelectOptions.js @@ -0,0 +1,206 @@ +import React, { useEffect } from "react"; +import { + List, + ListItem, + ListItemText, + Button, + Checkbox, + ListItemIcon, + Paper, + TextField, + Typography, +} from "@mui/material"; +import { Grid } from "../../../../components/grid/Grid"; +import { SPACING } from "../../../../data/spacing"; + +export const ProvinceAutoSelectOptions = ({ handleList }) => { + function not(a, b) { + return a.filter((value) => b.indexOf(value) === -1); + } + + function intersection(a, b) { + return a.filter((value) => b.indexOf(value) !== -1); + } + + const [checked, setChecked] = React.useState([]); + const [left, setLeft] = React.useState([ + { label: "شهر", key: "city", value: true }, + { label: "عدم بدهی", key: "no_debt", value: true }, + { label: "حداقل تعداد تخصیص", key: "minimum_allocation", value: true }, + ]); + const [right, setRight] = React.useState([ + { label: "شهر محل کشتار", key: "kill_place", value: true }, + ]); + + const leftChecked = intersection(checked, left); + const rightChecked = intersection(checked, right); + + const handleToggle = (value) => () => { + const currentIndex = checked.indexOf(value); + const newChecked = [...checked]; + + if (currentIndex === -1) { + newChecked.push(value); + } else { + newChecked.splice(currentIndex, 1); + } + + setChecked(newChecked); + }; + + const handleAllRight = () => { + setRight(right.concat(left)); + setLeft([]); + }; + + const handleCheckedRight = () => { + setRight(right.concat(leftChecked)); + setLeft(not(left, leftChecked)); + setChecked(not(checked, leftChecked)); + }; + + const handleCheckedLeft = () => { + setLeft(left.concat(rightChecked)); + setRight(not(right, rightChecked)); + setChecked(not(checked, rightChecked)); + }; + + const handleAllLeft = () => { + setLeft(left.concat(right)); + setRight([]); + }; + + const handleChange = (event) => { + const fieldToUpdateLeft = left.find( + (item) => item.key === "minimum_allocation" + ); + const fieldToUpdateRight = right.find( + (item) => item.key === "minimum_allocation" + ); + if (fieldToUpdateLeft) { + setLeft((prevState) => [ + ...prevState.filter((item) => item.key !== "minimum_allocation"), + { ...fieldToUpdateLeft, value: event.target.value }, + ]); + } else if (fieldToUpdateRight) { + setRight((prevState) => [ + ...prevState.filter((item) => item.key !== "minimum_allocation"), + { ...fieldToUpdateRight, value: event.target.value }, + ]); + } + }; + + useEffect(() => { + handleList(right); + }, [right]); + + const customList = (items) => ( + + + {items.map((value, i) => { + const labelId = `transfer-list-item-${value}-label`; + return ( + + + + + + + {value.label === "حداقل تعداد تخصیص" && ( + + + + )} + + + ); + })} + + + ); + + return ( + + + انتخاب اولویت های تخصیص خودکار + {customList(left)} + + + + + + + + + + + اولویت های انتخاب شده تخصیص خودکار + {customList(right)} + + + ); +}; diff --git a/src/features/province/components/province-bar-difference-requests/ProvinceBarDifferenceRequests.js b/src/features/province/components/province-bar-difference-requests/ProvinceBarDifferenceRequests.js new file mode 100644 index 0000000..4596277 --- /dev/null +++ b/src/features/province/components/province-bar-difference-requests/ProvinceBarDifferenceRequests.js @@ -0,0 +1,304 @@ +import React, { useContext, useEffect, useState } from "react"; +import { Button, IconButton, TextField } from "@mui/material"; +import { useDispatch, useSelector } from "react-redux"; +import axios from "axios"; +import { RiSearchLine } from "react-icons/ri"; +import { DatePicker } from "@mui/x-date-pickers"; +import moment from "moment"; +import { AppContext } from "../../../../contexts/AppContext"; +import { + DRAWER, + LOADING_END, + LOADING_START, + OPEN_MODAL, +} from "../../../../lib/redux/slices/appSlice"; +import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl"; +import { Grid } from "../../../../components/grid/Grid"; +import ResponsiveTable from "../../../../components/responsive-table/ResponsiveTable"; +import { formatJustDate } from "../../../../utils/formatTime"; +import { ProvinceSubmitBarDifference } from "../province-submit-bar-difference/ProvinceSubmitBarDifference"; +import { ProvinceBarDifferencesOperations } from "../province-bar-differences-operations/ProvinceBarDifferencesOperations"; +// import EmailIcon from "@mui/icons-material/Email"; +import { provinceGetDashboardBarDiffrenceRequest } from "../../services/province-dashboard-bar-diffrence-get-request"; +import { ProvinceBarDifferencesModal } from "../province-bar-differences-modal/ProvinceBarDifferencesModal"; +import { checkPathStartsWith } from "../../../../utils/checkPathStartsWith"; + +export const ProvinceBarDifferenceRequests = ({ state }) => { + const dispatch = useDispatch(); + const [, , selectedDate1, setSelectedDate1, selectedDate2, setSelectedDate2] = + useContext(AppContext); + const [data, setData] = useState([]); + const [totalRows, setTotalRows] = useState(0); + const [perPage, setPerPage] = useState(10); + const [textValue, setTextValue] = useState(""); + const [page, setPage] = useState(1); + const [tableData, setTableData] = useState([]); + const [dashboardData, setDashboardData] = useState([]); + const selectedSubUser = useSelector( + (state) => state.userSlice.selectedSubUser + ); + const fetchApiData = async (page) => { + dispatch(LOADING_START()); + try { + const response = await axios.get( + `bar-difference-request/?search=filter&value=${textValue}&role=${getRoleFromUrl()}${ + checkPathStartsWith("province") + ? `&role_key=${selectedSubUser?.key}` + : "" + }&page=${page}&page_size=${perPage}&state=${state}&date1=${selectedDate1}&date2=${selectedDate2}` + ); + setData(response.data.results); + setTotalRows(response.data.count); + } catch (error) { + console.error("Error fetching data:", error); + } finally { + dispatch(LOADING_END()); + } + }; + + const fetchDashboardData = () => { + dispatch( + provinceGetDashboardBarDiffrenceRequest({ + role: getRoleFromUrl(), + role_key: checkPathStartsWith("slaughter") + ? selectedSubUser?.key || "" + : "", + state: state, + filter: "search", + value: textValue, + date1: selectedDate1, + date2: selectedDate2, + }) + ).then((r) => { + if (r.payload?.data) { + setDashboardData(r.payload.data); + } + }); + }; + + const handlePageChange = (page) => { + fetchApiData(page); + setPage(page); + }; + + const handlePerRowsChange = (perRows) => { + setPerPage(perRows); + setPage(1); + }; + + const updateTable = () => { + fetchApiData(page !== 0 ? page : 1); + fetchDashboardData(); + }; + + useEffect(() => { + const d = data?.map((item, i) => { + return [ + page === 1 ? i + 1 : i + perPage * (page - 1) + 1, + item?.registerFullname, + formatJustDate(item?.createDate), + `${item?.hatching?.poultry?.unitName || ""} (${ + item?.hatching?.poultry?.user?.mobile || "" + })`, + `${item?.killHouse?.name || ""} (${ + item?.killHouse?.killHouseOperator?.user?.mobile || "" + })`, + item?.barInfo?.totalQuantity?.toLocaleString(), + item?.barInfo?.totalWeight?.toLocaleString(), + item?.barInfo?.firstTotalQuantity?.toLocaleString(), + item?.barInfo?.differenceQuantity?.toLocaleString(), + item?.quantity?.toLocaleString(), + item?.weight?.toLocaleString(), + + item?.acceptorImages?.[0] || + item?.acceptorMessage || + item?.registerMessage || + item?.violationImage?.[0] ? ( + + { + dispatch( + OPEN_MODAL({ + content: , + title: "پیوست", + }) + ); + }} + > + ✉️ + + + ) : ( + "-" + ), + + item.state === "pending" + ? "در انتظار تایید" + : item.state === "rejected" + ? "رد شده" + : "تایید شده", + state === "pending" ? ( + + ) : ( + "-" + ), + ]; + }); + + setTableData(d); + }, [data, state, page, perPage]); + + useEffect(() => { + fetchApiData(1); + fetchDashboardData(); + }, [state, perPage, selectedDate1, selectedDate2, selectedSubUser?.key]); + + const handleTextChange = (event) => { + setTextValue(event.target.value); + }; + + const handleSubmit = async (event) => { + event.preventDefault(); + fetchApiData(1); + fetchDashboardData(); + }; + + return ( + + + + + + {getRoleFromUrl() !== "KillHouse" && ( + + + + )} + + ( + + )} + value={selectedDate1} + onChange={(newValue) => { + setSelectedDate1(moment(newValue).format("YYYY-MM-DD")); + }} + /> + + + ( + + )} + value={selectedDate2} + onChange={(newValue) => { + setSelectedDate2(moment(newValue).format("YYYY-MM-DD")); + }} + /> + + +
    + + + +
    +
    + + +
    + ); +}; diff --git a/src/features/province/components/province-bar-difference/ProvinceBarDifference.js b/src/features/province/components/province-bar-difference/ProvinceBarDifference.js new file mode 100644 index 0000000..6e527ae --- /dev/null +++ b/src/features/province/components/province-bar-difference/ProvinceBarDifference.js @@ -0,0 +1,35 @@ +import React, { useState } from "react"; +import { useDispatch } from "react-redux"; +import { Grid } from "../../../../components/grid/Grid"; +import { Tab, Tabs } from "@mui/material"; +import { ProvinceBarDifferenceRequests } from "../province-bar-difference-requests/ProvinceBarDifferenceRequests"; +import { ProvinceBarDashboardService } from "../../services/province-bar-dashbored"; + +export const ProvinceBarDifference = () => { + const [value, setValue] = useState("0"); + const dispatch = useDispatch(); + + const handleChange = (event, newValue) => { + setValue(newValue); + dispatch( + ProvinceBarDashboardService({ + state: newValue === "0" ? "pending" : "archive", + }) + ); + }; + + return ( + + + + + + + + + + + ); +}; diff --git a/src/features/province/components/province-bar-differences-modal/ProvinceBarDifferencesModal.js b/src/features/province/components/province-bar-differences-modal/ProvinceBarDifferencesModal.js new file mode 100644 index 0000000..eca2dca --- /dev/null +++ b/src/features/province/components/province-bar-differences-modal/ProvinceBarDifferencesModal.js @@ -0,0 +1,127 @@ +import { useState, useEffect } from "react"; +import { Tabs, Tab, TextField, Typography } from "@mui/material"; +import ShowImage from "../../../../components/show-image/ShowImage"; +import { Grid } from "../../../../components/grid/Grid"; + +export const ProvinceBarDifferencesModal = ({ item }) => { + const [tabIndex, setTabIndex] = useState(0); + + const handleTabChange = (event, newValue) => { + setTabIndex(newValue); + }; + + const tabs = []; + if (item?.registerMessage || item?.violationImage?.[0]) { + tabs.push({ key: "register", label: "درخواست کننده" }); + } + if (item?.acceptorMessage || item?.acceptorImage?.[0]) { + tabs.push({ key: "acceptor", label: "کشتارگاه" }); + } + + useEffect(() => { + if (tabIndex >= tabs.length) { + setTabIndex(0); + } + }, [tabs.length, tabIndex]); + + return ( + + + {tabs.map((t, idx) => ( + + ))} + + + {tabs[tabIndex]?.key === "register" && ( + + {item?.registerMessage && ( + + )} + + {item?.violationImage?.[0] && ( + + + پیوست درخواست کننده: + + + + )} + + )} + + {tabs[tabIndex]?.key === "acceptor" && ( + + {item?.acceptorMessage && ( + + )} + + {item?.acceptorImage?.[0] && ( + + + پیوست کشتارگاه: + + + + )} + + )} + + ); +}; diff --git a/src/features/province/components/province-bar-differences-operations/ProvinceBarDifferencesOperations.js b/src/features/province/components/province-bar-differences-operations/ProvinceBarDifferencesOperations.js new file mode 100644 index 0000000..8e4d125 --- /dev/null +++ b/src/features/province/components/province-bar-differences-operations/ProvinceBarDifferencesOperations.js @@ -0,0 +1,313 @@ +import { + Button, + IconButton, + List, + ListItem, + ListItemButton, + ListItemIcon, + ListItemText, + Popover, + TextField, + Tooltip, + Typography, +} from "@mui/material"; +import { useState, useContext } from "react"; +import { useDispatch } from "react-redux"; +import { Grid } from "../../../../components/grid/Grid"; +import TuneIcon from "@mui/icons-material/Tune"; +import EditIcon from "@mui/icons-material/Edit"; +import DeleteIcon from "@mui/icons-material/Delete"; +import SettingsSuggestIcon from "@mui/icons-material/SettingsSuggest"; +import { ProvinceSubmitBarDifference } from "../province-submit-bar-difference/ProvinceSubmitBarDifference"; +import { + CLOSE_MODAL, + DRAWER, + OPEN_MODAL, +} from "../../../../lib/redux/slices/appSlice"; +import { + provinceDeleteBarDifferenceService, + provinceEditBarDifferenceService, +} from "../../services/province-bar-differences-services"; +import { AppContext } from "../../../../contexts/AppContext"; +import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl"; +import { ImageUpload } from "../../../../components/image-upload/ImageUpload"; +import { fixBase64 } from "../../../../utils/toBase64"; +import { resizeImage } from "../../../../utils/resizeImage"; + +export const ProvinceBarDifferencesOperations = ({ item, updateTable }) => { + const dispatch = useDispatch(); + const [anchorEl, setAnchorEl] = useState(null); + const [openNotif] = useContext(AppContext); + + const handleClick = (event) => setAnchorEl(event.currentTarget); + const handleClose = () => setAnchorEl(null); + + const open = Boolean(anchorEl); + const id = open ? "popover" : undefined; + + const handleDelete = () => { + dispatch( + OPEN_MODAL({ + title: "آیا مطمئن هستید؟", + content: ( + + + + + ), + }) + ); + handleClose(); + }; + + const openAcceptRejectModal = () => { + dispatch( + OPEN_MODAL({ + title: "تایید/ رد", + content: ( + + ), + }) + ); + handleClose(); + }; + + return ( +
    + + + + + + + {getRoleFromUrl() !== "KillHouse" ? ( + <> + + + { + handleClose(); + dispatch( + DRAWER({ + right: !(window.innerWidth <= 600), + bottom: window.innerWidth <= 600, + content: ( + + ), + title: "ویرایش اختلاف کشتار", + }) + ); + }} + > + + + + + + + + + + + { + handleClose(); + handleDelete(); + }} + > + + + + + + + + + ) : ( + + + { + handleClose(); + openAcceptRejectModal(); + }} + > + + + + + + + + )} + + +
    + ); +}; + +const AcceptRejectModal = ({ item, updateTable, openNotif }) => { + const dispatch = useDispatch(); + const [acceptorMessage, setAcceptorMessage] = useState(""); + const [profileImages, setProfileImages] = useState([]); + const [acceptorImages, setAcceptorImages] = useState([]); + + const handleEditOrAccept = (newState) => { + dispatch( + provinceEditBarDifferenceService({ + bar_key: item?.key, + kill_house_check: true, + acceptor_message: acceptorMessage, + acceptor_images: acceptorImages, + state: newState, + }) + ).then((r) => { + if (r.payload.error) { + openNotif({ + vertical: "top", + horizontal: "center", + msg: r.payload.error, + severity: "error", + }); + } else { + updateTable(); + dispatch(CLOSE_MODAL()); + openNotif({ + vertical: "top", + horizontal: "center", + msg: r.payload.data.result, + severity: "success", + }); + } + }); + }; + + const handleImageChange = (imageList) => { + if (imageList.length === 0) { + setProfileImages([]); + setAcceptorImages([]); + return; + } + + Promise.all( + imageList.map( + (image) => + new Promise((resolve) => + resizeImage(image.file, (resized) => resolve(fixBase64(resized))) + ) + ) + ).then((resizedImages) => { + setProfileImages(imageList); + setAcceptorImages(resizedImages); + }); + }; + + return ( + + + + توجه: در صورت تایید حجم قطعه اعلام شده، حجم مورد نظر از سالن مرغدار + کسر شده و با میانگین وزن کشتار مرغدار به انبار شما اضافه می‌گردد. + + + + + + + setAcceptorMessage(e.target.value)} + fullWidth + /> + + + + + + + + + + ); +}; diff --git a/src/features/province/components/province-bar-infos/ProvinceBarInfos.js b/src/features/province/components/province-bar-infos/ProvinceBarInfos.js new file mode 100644 index 0000000..adf7090 --- /dev/null +++ b/src/features/province/components/province-bar-infos/ProvinceBarInfos.js @@ -0,0 +1,10 @@ +import { AdvancedTable } from "../../../../components/advanced-table/AdvancedTable"; +import { Grid } from "../../../../components/grid/Grid"; + +export const ProvinceBarInfos = () => { + return ( + + + + ); +}; diff --git a/src/features/province/components/province-buyer-steward-allocation/ProvinceBuyerStewardAllocation.js b/src/features/province/components/province-buyer-steward-allocation/ProvinceBuyerStewardAllocation.js new file mode 100644 index 0000000..516c0dc --- /dev/null +++ b/src/features/province/components/province-buyer-steward-allocation/ProvinceBuyerStewardAllocation.js @@ -0,0 +1,616 @@ +import { useDispatch, useSelector } from "react-redux"; +import { useContext, useEffect, useState } from "react"; +import { getProvinceBuyerStewardAllocationService } from "../../services/get-province-buyer-steward-allocation"; +import { useParams } from "react-router-dom"; +import { AdvancedTable } from "../../../../components/advanced-table/AdvancedTable"; +import { Button, TextField, Tooltip, Typography } from "@mui/material"; +import { Grid } from "../../../../components/grid/Grid"; +import { NumberInput } from "../../../../components/number-format-custom/NumberFormatCustom"; +import { SPACING } from "../../../../data/spacing"; +import { provinceBuyerRealCarcassesService } from "../../services/province-buyer-real-carcasses"; +import { AppContext } from "../../../../contexts/AppContext"; +import { provinceAutomaticStewardAllocationService } from "../../services/province-automatic-steward-allocation"; +import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl"; +import { provinceUpdateAllocateStewardsService } from "../../services/province-update-allocate-stewards"; +import { CLOSE_MODAL, OPEN_MODAL } from "../../../../lib/redux/slices/appSlice"; +import { RiFileExcel2Fill } from "react-icons/ri"; +import axios from "axios"; +import { SimpleTable } from "../../../../components/simple-table/SimpleTable"; +import { slaughterGetUpdatedInventoryStock } from "../../../slaughter-house/services/salughter-get-updated-inventory-stock"; +import { DatePicker } from "@mui/x-date-pickers"; +import moment from "moment/moment"; +import { useFormik } from "formik"; +import { Yup } from "../../../../lib/yup/yup"; +import { formatJustDate } from "../../../../utils/formatTime"; +import { ProvinceManageStewardAllocations } from "../province-manage-steward-allocations/ProvinceManageStewardAllocations"; +import { provinceGetTotalReportAgentShareService } from "../../services/province-get-total-report-agent-share"; + +export const ProvinceBuyerStewardAllocation = () => { + const dispatch = useDispatch(); + let currentDate = moment(new Date()).format("YYYY-MM-DD"); + const { id, date } = useParams(); + const [datePicker, setDatePicker] = useState( + moment(new Date()).format("YYYY-MM-DD") + ); + + if (getRoleFromUrl() === "KillHouse") { + currentDate = datePicker; + } else { + currentDate = date; + } + + const [dataTable, setDataTable] = useState([]); + const { + getProvinceBuyerStewardAllocation, + provinceGetTotalReportAgentShare, + } = useSelector((state) => state.provinceSlice); + + const { slaughterUpdatedInventoryStock } = useSelector( + (state) => state.slaughterSlice + ); + + const updateInventory = () => { + dispatch( + slaughterGetUpdatedInventoryStock({ + date: currentDate, + kill_house_key: id, + }) + ); + }; + + useEffect(() => { + dispatch( + provinceGetTotalReportAgentShareService({ + date: currentDate, + kill_house_key: id, + }) + ); + if (getRoleFromUrl() === "KillHouse") { + dispatch( + provinceUpdateAllocateStewardsService({ + kill_house_key: id, + date: currentDate, + }) + ).then(() => { + dispatch( + getProvinceBuyerStewardAllocationService({ + date: currentDate, + killHouseKey: id, + }) + ).then(() => { + dispatch( + slaughterGetUpdatedInventoryStock({ + date: currentDate, + kill_house_key: id, + }) + ); + }); + }); + } + + if (getRoleFromUrl() === "ProvinceOperator") { + dispatch( + getProvinceBuyerStewardAllocationService({ + date: currentDate, + killHouseKey: id, + }) + ).then(() => { + dispatch( + slaughterGetUpdatedInventoryStock({ + date: currentDate, + kill_house_key: id, + }) + ); + }); + } + }, [currentDate]); + + const updateTable = () => { + dispatch( + getProvinceBuyerStewardAllocationService({ + date: currentDate, + killHouseKey: id, + }) + ); + }; + + useEffect(() => { + const d = getProvinceBuyerStewardAllocation?.map((item) => { + return [ + item.steward.guilds.guildsId, + // formatJustDate(item.steward.guilds.createDate), + item.steward.guilds.steward ? "مباشر" : "صنف", + item.steward.guilds.guildsName, + item.steward.guilds.user.fullname, + // item.steward?.guilds?.user?.nationalId, + item.steward?.guilds?.user?.mobile, + `${item.steward?.guilds?.typeActivity}/${item.steward?.guilds?.areaActivity}`, + item.steward?.guilds?.licenseNumber, + item.steward?.guilds?.address.city.name, + + {`${item?.numberOfCarcasses?.toLocaleString()} قطعه`} + {`${item?.weightOfCarcasses?.toLocaleString()} کیلوگرم`} + , + + {item.state === "accepted" && ( + <> + {`${item?.realNumberOfCarcasses?.toLocaleString()} قطعه`} + {`${item?.realWeightOfCarcasses?.toLocaleString()} کیلوگرم`} + + )} + + {!item.systemRegistrationCode && ( + + + + )} + , + // , + , + ]; + }); + + setDataTable(d); + }, [getProvinceBuyerStewardAllocation]); + + const [inventoryDate, setInventoryDate] = useState(new Date(currentDate)); + + useEffect(() => { + const tempDate = new Date(inventoryDate); + tempDate.setDate(new Date(currentDate).getDate() - 1); + setInventoryDate(tempDate); + }, [currentDate]); + + return ( + + + {/* سهم بندی ها */} + {getRoleFromUrl() === "KillHouse" && ( + ( + + )} + value={currentDate} + onChange={(e) => { + setDatePicker(moment(e).format("YYYY-MM-DD")); + }} + /> + )} + + + + + سهم بندی برای تاریخ کشتار مورخ {formatJustDate(inventoryDate)}{" "} + {provinceGetTotalReportAgentShare?.killer + ? "کشتارکن" + : "کشتارگاه"}{" "} + {provinceGetTotalReportAgentShare?.name} + + + + + + + + + } + columns={[ + "حجم لاشه ها", + "وزن لاشه ها (کیلوگرم)", + "حجم لاشه تخصیص داده شده", + "وزن تخصیص داده شده (کیلوگرم)", + "حجم لاشه قابل تخصیص", + "وزن قابل تخصیص (کیلوگرم)", + ]} + data={[ + [ + slaughterUpdatedInventoryStock?.totalNumberOfCarcasses?.toLocaleString(), + slaughterUpdatedInventoryStock?.totalWeightOfCarcasses?.toLocaleString(), + slaughterUpdatedInventoryStock?.allocatedTotalNumberOfCarcasses?.toLocaleString(), + slaughterUpdatedInventoryStock?.allocatedTotalWeightOfCarcasses?.toLocaleString(), + slaughterUpdatedInventoryStock?.remainTotalNumberOfCarcasses?.toLocaleString(), + slaughterUpdatedInventoryStock?.remainTotalWeightOfCarcasses?.toLocaleString(), + ], + ]} + /> + + + {(getRoleFromUrl() === "ProvinceOperator" || + getRoleFromUrl() === "SuperAdmin") && ( + + )} + + {getRoleFromUrl() === "KillHouse" && ( + + {/* سهم بندی اتوماتیک + {getRoleFromUrl() === "KillHouse" && ( + ( + + )} + value={date} + onChange={(e) => { + setDatePicker(moment(e).format("YYYY-MM-DD")); + }} + /> + )} */} + + {/* */} + + } + columns={[ + "شناسه صنف", + // "تاریخ ثبت", + "ماهیت", + "نام واحد صنفی", + "نام شخص/شرکت", + // "کدملی", + "موبایل", + "نوع/حوزه فعالیت", + "شماره مجوز", + "شهرستان", + "تعداد/وزن لاشه پیشنهادی", + "تعداد/وزن لاشه تحویلی", + "کداحراز", + ]} + data={dataTable} + /> + )} + + ); +}; + +const validationSchema = Yup.object({ + number1: Yup.number().required("این فیلد اجباری است"), + number2: Yup.number().required("این فیلد اجباری است"), +}); +const RealCarcassesInput = ({ + // realWeightOfCarcasses, + // realNumberOfCarcasses, + updateTable, + item, +}) => { + const dispatch = useDispatch(); + const [openNotif] = useContext(AppContext); + const formik = useFormik({ + initialValues: { + number1: item.realNumberOfCarcasses, + number2: item.realWeightOfCarcasses, + }, + validationSchema: validationSchema, + onSubmit: (values) => { + // Handle form submission + // console.log(values); + }, + }); + // const [numberInput, setNumberInput] = useState(realNumberOfCarcasses); + // const [textInput, setTextInput] = useState(realWeightOfCarcasses); + + // const handleNumberInputChange = (e) => { + // setNumberInput(e.target.value); + // }; + + // const handleTextInputChange = (e) => { + // setTextInput(e.target.value); + // }; + + useEffect(() => { + formik.validateForm(); + }, []); + + return ( + + + + {/* {item.state !== "accepted" && ( */} + + {/* )} */} + + ); +}; + +const RegistrationInput = ({ + loggedRegistrationCode, + item, + updateTable, + updateInventory, +}) => { + const dispatch = useDispatch(); + const [openNotif] = useContext(AppContext); + const [textInput, setTextInput] = useState(loggedRegistrationCode); + + const handleTextInputChange = (e) => { + setTextInput(e.target.value); + }; + + console.log(item.systemRegistrationCode, "zzzz"); + + return ( + + {item.systemRegistrationCode ? ( + + + {!item?.finalRegistration && ( + + )} + + ) : ( + + + + + ), + }) + ); + }} + > + ارسال کداحراز + + )} + + ); +}; diff --git a/src/features/province/components/province-buyers-allocations/ProvinceBuyersAllocations.js b/src/features/province/components/province-buyers-allocations/ProvinceBuyersAllocations.js new file mode 100644 index 0000000..62cda5c --- /dev/null +++ b/src/features/province/components/province-buyers-allocations/ProvinceBuyersAllocations.js @@ -0,0 +1,222 @@ +import { DatePicker } from "@mui/x-date-pickers"; +import { Button, TextField, Tooltip } from "@mui/material"; +import { useContext, useEffect, useState } from "react"; +import moment from "moment"; +import { Grid } from "../../../../components/grid/Grid"; +import { SPACING } from "../../../../data/spacing"; +import { useDispatch, useSelector } from "react-redux"; +import axios from "axios"; +import { RiFileExcel2Fill } from "react-icons/ri"; +import { AppContext } from "../../../../contexts/AppContext"; +import { totalReportDailyBroadCastService } from "../../../slaughter-house/services/salughter-total-report-daily-broad-cast"; +import { getProvinceBuyersAllocationsService } from "../../services/get-province-buyers-allocations"; +import ResponsiveTable from "../../../../components/responsive-table/ResponsiveTable"; + +export const ProvinceBuyersAllocations = () => { + const [, , selectedDate1, setSelectedDate1, selectedDate2, setSelectedDate2] = + useContext(AppContext); + // const navigate = useNavigate(); + const dispatch = useDispatch(); + const [dataTable, setDataTable] = useState([]); + const { getProvinceBuyersAllocations, totalReportDailyBroadCast } = + useSelector((state) => state.provinceSlice); + + useEffect(() => { + dispatch( + getProvinceBuyersAllocationsService({ selectedDate1, selectedDate2 }) + ); + dispatch( + totalReportDailyBroadCastService({ + selectedDate1, + selectedDate2, + }) + ); + }, [selectedDate1, selectedDate2]); + + useEffect(() => { + dispatch( + getProvinceBuyersAllocationsService({ selectedDate1, selectedDate2 }) + ); + dispatch( + totalReportDailyBroadCastService({ + selectedDate1, + selectedDate2, + }) + ); + }, []); + + useEffect(() => { + const d = getProvinceBuyersAllocations?.map((item, i) => { + return [ + i + 1, + item?.informations?.buyers, + item?.informations?.city, + item?.informations?.numberOfSteward.toLocaleString(), + item?.informations?.numberOfGuild.toLocaleString(), + item?.informations?.incomingWeightOfColdHouse?.toLocaleString(), + item?.informations?.incomingQuantityOfColdHouse?.toLocaleString(), + item?.informations?.totalPreColdWeight?.toLocaleString(), + item?.informations?.totalPreColdQuantity?.toLocaleString(), + item?.informations?.totalNumberOfFreeCarcasses?.toLocaleString(), + item?.informations?.totalFreeWeightOfCarcasses?.toLocaleString(), + item?.informations?.totalWeightOfCarcasses?.toLocaleString(), + item?.informations?.totalNumberOfCarcasses?.toLocaleString(), + item?.informations?.finalTotalWeightOfCarcasses?.toLocaleString(), + item?.informations?.finalTotalNumberOfCarcasses?.toLocaleString(), + item?.informations?.totalAllocatedWeight?.toLocaleString(), + item?.informations?.totalAllocatedQuantity?.toLocaleString(), + item?.informations?.totalAcceptedAllocatedWeight?.toLocaleString(), + item?.informations?.totalAcceptedAllocatedQuantity?.toLocaleString(), + item?.informations?.totalRemainQuantity?.toLocaleString(), + item?.informations?.totalRemainWeight?.toLocaleString(), + + + + + , + ]; + }); + setDataTable(d); + }, [getProvinceBuyersAllocations]); + + return ( + + + + } + value={selectedDate1} + onChange={(e) => { + setSelectedDate1(moment(e).format("YYYY-MM-DD")); + }} + /> + + + } + value={selectedDate2} + onChange={(e) => { + setSelectedDate2(moment(e).format("YYYY-MM-DD")); + }} + /> + + + + + + + + + + + + + + + ); +}; diff --git a/src/features/province/components/province-case-overview/ProvinceCaseOverview.js b/src/features/province/components/province-case-overview/ProvinceCaseOverview.js new file mode 100644 index 0000000..1b482d6 --- /dev/null +++ b/src/features/province/components/province-case-overview/ProvinceCaseOverview.js @@ -0,0 +1,139 @@ +import { Typography } from "@mui/material"; +import { Grid } from "../../../../components/grid/Grid"; +import { SPACING } from "../../../../data/spacing"; +import { formatJustDate } from "../../../../utils/formatTime"; + +export const ProvinceCaseOverview = ({ item }) => { + return ( + + + + مرغداری: + {item?.poultry?.unitName} + + + مرغدار: + + {item?.poultry?.user?.fullname} + + + + موبایل: + + {item?.poultry?.user?.mobile} + + + + تاریخ کشتار: + + {formatJustDate(item?.sendDate)} + + + + زمان و تاریخ ثبت: + + {formatJustDate(item?.createDate)} + + + + شهرستان: + + {item?.poultry?.address?.city?.name} + + + + + + تعداد: + + {item?.quantity?.toLocaleString()} + + + + متوسط وزن: + {item?.IndexWeight} + + + وزن حدودی: + {item?.hatching?.weight} + + + سن گله: + {item?.hatching?.age} + + + نژاد: + {item?.chickenBreed} + + + قیمت پیشنهادی: + + {item?.amount?.toLocaleString()} ریال + + + + + {item?.provinceKillRequests?.provinceKillRequestSerializer.length ? ( + <> + + خریداران: + + {item?.provinceKillRequests?.provinceKillRequestSerializer?.map( + (item, i) => { + return ( + + {i + 1}- + + {item?.killhouseUser?.name} + + + ({item?.killhouseUser?.killHouseOperator?.user?.mobile}) + + تعداد: + + {item?.mainQuantity?.toLocaleString()} + + محل کشتار: + {item?.killPlace} + + ); + } + )} + + ) : ( + <> + + خریداران: بدون خریدار + + + )} + + + + قیمت مرغ: + + {item?.amount?.toLocaleString()} ریال + + + {/* + مبلغ قابل پرداخت: + 55112 + + + باقی مانده قابل پرداخت: + 44 + + + مبلغ پرداخت شده: + 258522 + */} + + + ); +}; diff --git a/src/features/province/components/province-case-status/ProvinceCaseStatusComponent.js b/src/features/province/components/province-case-status/ProvinceCaseStatusComponent.js new file mode 100644 index 0000000..4b10f5e --- /dev/null +++ b/src/features/province/components/province-case-status/ProvinceCaseStatusComponent.js @@ -0,0 +1,511 @@ +import { + // Divider, + // Paper, + Table, + TableBody, + TableCell, + TableRow, + TextField, + Typography, +} from "@mui/material"; +import { DatePicker } from "@mui/x-date-pickers"; +import moment from "moment/moment"; +import { useEffect, useState } from "react"; +import { useDispatch, useSelector } from "react-redux"; +import { Grid } from "../../../../components/grid/Grid"; +import { provinceGetCaseStatusService } from "../../services/province-get-case-status"; + +export const ProvinceCaseStatusComponent = () => { + const dispatch = useDispatch(); + const { provinceGetCaseStatus } = useSelector((state) => state.provinceSlice); + + const [selectedDate, setSelectedDate] = useState( + moment(new Date()).format("YYYY-MM-DD") + ); + + const handleDateChange = (date) => { + setSelectedDate(date); + }; + + useEffect(() => { + dispatch(provinceGetCaseStatusService(selectedDate)); + }, [selectedDate]); + + return ( + + + } + value={selectedDate} + onChange={(e) => { + handleDateChange(moment(e).format("YYYY-MM-DD")); + }} + /> + + + + {provinceGetCaseStatus?.map((item, i) => { + // city state color + let cityStateColor; + if (item?.cityState?.state === "pending") { + cityStateColor = "#ff7410"; + } + if (item?.cityState?.state === "accept") { + cityStateColor = "green"; + } + if (item?.cityState?.state === "reject") { + cityStateColor = "red"; + } + + // province state color + let provinceStateColor; + if (item?.provinceState?.state === "pending") { + provinceStateColor = "#ff7410"; + } + if (item?.provinceState?.state === "accept") { + provinceStateColor = "green"; + } + if (item?.provinceState?.state === "reject") { + provinceStateColor = "red"; + } + + return ( + + + + + + + مرغدار + + + + + {item?.poultry?.poultryName} ( + {item?.poultry?.userFullname}) + + + تلفن: {item?.poultry?.userMobile} + + + {item?.poultry?.poultryRequestQuantity.toLocaleString()}{" "} + قطعه + + + دامپزشک فارم: {item?.poultry?.vetFarmName} + + + تلفن دامپزشک: {item?.poultry?.vetFarmMobile} + + + + + + + شهرستان + + + + + {item?.cityState?.operatorCity} ( + {item?.cityState?.operatorName}) + + + تلفن: {item?.cityState?.operatorMobile} + + + + + + + استان + + + + + {item?.provinceState?.provinceOperatorProvinc} ( + {item?.provinceState?.provinceOperatorName}) + + + تلفن: {item?.provinceState?.provinceOperatorMobile} + + + + + {item?.provinceKillRequests?.map((killRequest, i) => { + // killhouse state color + let killHouseStateColor; + if (killRequest?.state === "pending") { + killHouseStateColor = "#ff7410"; + } + if (killRequest?.state === "accepted") { + killHouseStateColor = "green"; + } + if (killRequest?.state === "rejected") { + killHouseStateColor = "red"; + } + return ( + + + + + خریدار + + + + + {killRequest?.buyerName} + + + {killRequest?.quantity} قطعه + + + تلفن: {killRequest?.buyerMobile} + + + + + + + راننده + + + {killRequest?.killHouseRequests?.map((car, i) => { + let carStateColor = ""; + if (car?.clearanceCode) { + carStateColor = "green"; + } else { + carStateColor = "red"; + } + return ( + + + {car?.driverName} / تعداد{" "} + {car?.quantity.toLocaleString()} / + کدبهداشتی {car?.trafficCode} / کدترخیص{" "} + {car?.clearanceCode + ? car?.clearanceCode + : "در انتظار"} + + + ); + })} + + + + + دامپزشک کشتارگاه + + + {killRequest?.killHouseRequests?.map((car, i) => { + let vetStateColor = ""; + if (car?.vetState === "pending") { + vetStateColor = "#ff7410"; + } else if (car?.vetState === "accepted") { + vetStateColor = "green"; + } else { + vetStateColor = "red"; + } + return ( + + + {car?.killHouseVetName + ? car?.killHouseVetName + : "ندارد"}{" "} + /{" "} + {car?.killHouseVetMobile + ? car.killHouseVetMobile + : "ندارد"} + + + ); + })} + + + + + اطلاعات بار + + + {killRequest?.killHouseRequests + ?.filter((car) => car.bar) + ?.map((car, i) => { + // city state color + let barStateColor; + if (car?.bar?.state === "pending") { + barStateColor = "#ff7410"; + } + if (car?.bar?.state === "accepted") { + barStateColor = "green"; + } + if (car?.bar?.state === "rejected") { + barStateColor = "red"; + } + return ( + + + + + + + وزن با بار:{" "} + {car?.bar?.carWeightWithLoad?.toLocaleString()}{" "} + / + + + + وزن بدون بار:{" "} + {car?.bar?.carWeightWithoutLoad?.toLocaleString()}{" "} + / وزن خالص: + {car?.bar?.netWeight.toLocaleString()}{" "} + / تعداد واقعی: + {car?.bar?.realQuantity.toLocaleString()} + + + + ); + })} + + + + + فاکتور استان + + + {killRequest?.killHouseRequests + ?.filter((car) => car.provinceFactor) + ?.map((car, i) => { + // city state color + let provinceFactorStateColor; + if ( + car?.killHouseFactor?.state === "pending" + ) { + provinceFactorStateColor = "#ff7410"; + } + if ( + car?.killHouseFactor?.state === "accepted" + ) { + provinceFactorStateColor = "green"; + } + if ( + car?.killHouseFactor?.state === "rejected" + ) { + provinceFactorStateColor = "red"; + } + return ( + + + فی:{" "} + {car?.provinceFactor?.factorFee.toLocaleString()} + {" / "} + وزن:{" "} + {car?.provinceFactor?.totalWeight.toLocaleString()} + {" / "} + مبلغ کل:{" "} + {car?.provinceFactor?.totalPrice.toLocaleString()} + + + + شناسه پرداخت: + {car?.killHouseFactor?.paymentCode} + + + ); + })} + + + ); + })} + + + +
    + ); + })} +
    +
    +
    + ); +}; diff --git a/src/features/province/components/province-case-step-bars-info/ProvinceCaseStepBarsInfo.js b/src/features/province/components/province-case-step-bars-info/ProvinceCaseStepBarsInfo.js new file mode 100644 index 0000000..f5f05a1 --- /dev/null +++ b/src/features/province/components/province-case-step-bars-info/ProvinceCaseStepBarsInfo.js @@ -0,0 +1,5 @@ +import { Typography } from "@mui/material"; + +export const ProvinceCaseStepBarsInfo = () => { + return اطلاعات بارها; +}; diff --git a/src/features/province/components/province-case-step-payment-information/ProvinceCaseStepPaymentInformation.js b/src/features/province/components/province-case-step-payment-information/ProvinceCaseStepPaymentInformation.js new file mode 100644 index 0000000..2af3962 --- /dev/null +++ b/src/features/province/components/province-case-step-payment-information/ProvinceCaseStepPaymentInformation.js @@ -0,0 +1,5 @@ +import { Typography } from "@mui/material"; + +export const ProvinceCaseStepPaymentInformation = () => { + return اطلاعات پرداخت; +}; diff --git a/src/features/province/components/province-case-step-shipping/ProvinceCaseStepShipping.js b/src/features/province/components/province-case-step-shipping/ProvinceCaseStepShipping.js new file mode 100644 index 0000000..a4435e1 --- /dev/null +++ b/src/features/province/components/province-case-step-shipping/ProvinceCaseStepShipping.js @@ -0,0 +1,5 @@ +import { Typography } from "@mui/material"; + +export const ProvinceCaseStepShipping = () => { + return گواهی حمل; +}; diff --git a/src/features/province/components/province-case-steps/ProvinceCaseSteps.js b/src/features/province/components/province-case-steps/ProvinceCaseSteps.js new file mode 100644 index 0000000..07bfbda --- /dev/null +++ b/src/features/province/components/province-case-steps/ProvinceCaseSteps.js @@ -0,0 +1,143 @@ +import { Step, StepLabel, Stepper, Typography } from "@mui/material"; +import { Grid } from "../../../../components/grid/Grid"; +import { SPACING } from "../../../../data/spacing"; +import { useEffect, useState } from "react"; + +export const ProvinceCaseSteps = ({ stepClickedHandler, item }) => { + const [currentStep, setCurrentStep] = useState(0); + + useEffect(() => { + let step = 0; + + if ( + item?.cityState?.state === "reject" || + item?.provinceState?.state === "reject" + ) { + step = -1; + } else { + if (item?.cityState?.date) { + step = 1; + } + if (item?.provinceState?.date) { + step = 2; + } + if ( + item?.provinceKillRequests?.provinceKillRequestSerializer.length > 0 + ) { + step = 3; + } + if (item?.killHouseRequests?.killHouseRequestsSerializer.length > 0) { + step = 4; + } + if ( + item?.killHouseRequests?.killHouseRequestVetCheckSerializer?.length > 0 + ) { + step = 5; + } + if ( + item?.killHouseRequests?.killHouseRequestAssignmentSerializer?.length > + 0 + ) { + step = 6; + } + } + + setCurrentStep(step); + }, [item]); + + const steps = item.out + ? ["درخواست کشتار", "تایید شهرستان", "تایید استان"] + : [ + "درخواست کشتار", + "تایید شهرستان", + "تایید استان", + "تخصیص به خریدار", + "ایجاد بار", + "تخلیه", + "اطلاعات بار", + "اطلاعات پرداخت", + ]; + + const isStepFailed = (step) => { + let isFailed = false; + switch (step) { + case 1: + isFailed = item?.cityState?.state === "reject"; + break; + case 2: + isFailed = item?.provinceState?.state === "reject"; + break; + default: + break; + } + return isFailed; + }; + + return ( + + + + {steps.map((label, index) => { + const labelProps = {}; + if (isStepFailed(index)) { + labelProps.optional = ( + + پرونده در این مرحله رد شد. + + ); + labelProps.error = true; + } + + return ( + { + if (currentStep >= index) { + stepClickedHandler(index); + } + }} + > + {label} + + ); + })} + + + + + {steps.map((label, index) => { + const labelProps = {}; + if (isStepFailed(index)) { + labelProps.optional = ( + + پرونده در این مرحله رد شد. + + ); + labelProps.error = true; + } + + return ( + { + if (currentStep >= index) { + stepClickedHandler(index); + } + }} + > + {label} + + ); + })} + + + + ); +}; diff --git a/src/features/province/components/province-cases-item/Pages.js b/src/features/province/components/province-cases-item/Pages.js new file mode 100644 index 0000000..433c64e --- /dev/null +++ b/src/features/province/components/province-cases-item/Pages.js @@ -0,0 +1,580 @@ +import { Typography } from "@mui/material"; +import { Grid } from "../../../../components/grid/Grid"; +import { SPACING } from "../../../../data/spacing"; + +const styles = { + tableInNewPage: { + pageBreakAfter: "always", + paddingLeft: "40px", + paddingRight: "40px", + direction: "rtl", + fontFamily: "titr", + fontWeight: "bold", + }, + container: { + width: "95%", + alignSelf: "center", + pageBreakInside: "avoid", + }, + + invoiceTable: { + width: "100%", + borderCollapse: "collapse", + alignSelf: "center", + fontFamily: "titr", + marginBottom: "5px", + marginTop: "15px", + borderRadius: "10px", + }, + tableCell: { + border: "1px solid #000", + pAlign: "left", + textAlign: "center", + fontSize: 12, + fontWeight: "bolder", + color: "#403e3e", + }, + tableCellGreen: { + border: "1px solid #000", + pAlign: "left", + textAlign: "center", + fontSize: 12, + color: "white", + fontWeight: "bolder", + backgroundColor: "rgba(26, 188, 156, 0.7)", + }, + tableCellMobile: { + border: "1px solid #000", + pAlign: "left", + textAlign: "center", + fontSize: 12, + }, + tableInnerCell: { + border: "1px solid #000", + pAlign: "left", + textAlign: "center", + fontSize: 9, + whiteSpace: "nowrap", + }, + tableHeader: { + backgroundColor: "rgba(211, 211, 211, 0.3)", + pageBreakAfter: "auto", + }, + headerRow: { + background: "linear-gradient(to right, #E684AE, #79CBCA, #77A1D3)", + backgroundColor: "rgba(232, 67, 147, 0.4)", + color: "#422020", + pageBreakInside: "avoid", + pageBreakAfter: "auto", + }, + + tableHeaderCell: { + fontSize: 14, + border: "1px solid #000", + padding: "4px", + textAlign: "center", + fontWeight: "bolder", + }, + tableHeaderCellGreen: { + backgroundColor: "rgba(26, 188, 156, 0.7)", + fontSize: 12, + border: "1px solid #000", + padding: "4px", + textAlign: "center", + fontWeight: "bolder", + color: "white", + }, + footer: { + left: 0, + bottom: 0, + width: "100%", + position: "absolute", + }, + footerContainer: { + alignItems: "center", + display: "flex", + }, + + tableRowEven: { + backgroundColor: "rgba(170, 183, 255, 0.3)", + }, + titleOfTable: { + marginRight: "20px", + fontSize: "15px", + }, + tableCellAlert: { + border: "1px solid #000", + pAlign: "left", + textAlign: "center", + fontSize: 12, + color: "red", + }, + levelDetails: { + color: "red", + fontSize: 12, + }, +}; + +export const TableCityLevel = ({ item }) => { + return ( + + مرحله شهرستان + + + + + + + + + + + + {item?.cityState?.date ? ( + + + + + + + + + + + ) : ( + + )} +
    اپراتورسمتتلفنتعاونی مرغدارآدرسوضعیت
    + {item?.cityState?.cityOperatorFullname} + اپراتور شهرستان + {item?.cityState?.cityOperatorMobile} + {item?.cityState?.poultry} + {item?.cityState?.province + " - " + item?.cityState?.city} + + {item?.cityState?.state === "accept" ? "تایید شده" : "رد شده"} +
    + هنوز شهرستان پرونده را تائید نکرده است +
    +
    + ); +}; + +export const TableProvinceLevel = ({ item }) => { + return ( + + مرحله استان + + + + + + + + + + + + {item?.provinceState?.date ? ( + + + + + + + + + + + ) : ( + + )} +
    اپراتورسمتتلفنتعاونی مرغدارآدرسوضعیت
    + {item?.provinceState?.provinceOperatorFullname} + اپراتور استان + {item?.provinceState?.provinceOperatorMobile} + {item?.provinceState?.poultry} + {item?.provinceState?.province + + " - " + + item?.provinceState?.city} + + {item?.provinceState?.state === "accept" + ? "تایید شده" + : "رد شده"} +
    + هنوز استان پرونده را تائید نکرده است +
    +
    + ); +}; + +export const TableSalughterAllocationLevel = ({ item }) => { + return ( + + + مرحله تخصیص به خریدار {" ( "} + + تعداد درخواست:{" "} + {item?.provinceKillRequests?.provinceKillRequestsTotalInfo?.poultryRequestQuantity.toLocaleString()} + ، تعداد تخصیصی به کشتارگاه:{" "} + {item?.provinceKillRequests?.provinceKillRequestsTotalInfo?.allocatedQuantity.toLocaleString()} + ، مانده قابل تخصیصی:{" "} + {item?.provinceKillRequests?.provinceKillRequestsTotalInfo?.poultryRequestRemainQuantity.toLocaleString()} + + {" ) "} + + + + + + + + + + + + + + + {item?.provinceKillRequests?.provinceKillRequestSerializer ? ( + + {item?.provinceKillRequests?.provinceKillRequestSerializer.map( + (item, i) => ( + + + + + + + + + + + ) + )} + + ) : ( + + )} +
    ردیفماهیت خریدارخریدارنوع تخصیصتعداد تخصیصیمیانگین وزنوزن تخصیصیوضعیت
    {i + 1} + {item?.killhouseUser?.killer === false + ? "کشتارگاه" + : "کشتارکن"} + + {`${item?.killhouseUser?.killHouseOperator?.user?.fullname} (${item?.killhouseUser?.killHouseOperator?.user?.mobile})`} + + {item?.automatic === false ? "دستی" : "اتوماتیک"} + + {item?.weightInfo?.provinceKillRequestQuantity} + + {item?.weightInfo?.provinceKillRequestIndexWeight} + + {item?.weightInfo?.provinceKillRequestWeight} + + {item?.state === "accepted" + ? "تایید شده" + : item?.state === "rejected" + ? "رد شده" + : "در انتظار تایید"} +
    + داده ای ثبت نشده! +
    +
    + ); +}; + +export const TableSlaughterAddCar = ({ item }) => { + return ( + + + مرحله ایجاد بار + {" ( "} + + تعداد تخصیص به خریداران:{" "} + {item?.killHouseRequests?.allocatedQuantity?.toLocaleString()}، تعداد + بارها: {item?.killHouseRequests?.numberOfBars?.toLocaleString()}، + تعداد تخصیص به ماشین:{" "} + {item?.killHouseRequests?.killHouseRequestQuantity?.toLocaleString()}، + مانده قابل تخصیص:{" "} + {item?.killHouseRequests?.remainQuantity?.toLocaleString()} + + {" ) "} + + + + + + + + + + + + + + + + + {item?.killHouseRequests?.killHouseRequestsSerializer ? ( + + {item?.killHouseRequests?.killHouseRequestsSerializer.map( + (item, i) => ( + + + + + + + + + + + + + ) + )} + + ) : ( + + )} +
    ردیفکد بارخریدارماشینرانندهتعدادوزن بارمیانگین وزنکد قرنطینهمحل کشتار
    {i + 1}{item?.barCode} + {`${item?.killhouseUser?.killHouseOperator?.user?.fullname} (${item?.killhouseUser?.killHouseOperator?.user?.mobile})`} + {`${item?.addCar?.driver?.typeCar} (${item?.addCar?.driver?.pelak})`}{`${item?.addCar?.driver?.driverName} (${item?.addCar?.driver?.driverMobile})`} + {item?.quantity.toLocaleString()} + {item?.weightInfo?.weight} + {item?.weightInfo?.indexWeight} + {item?.clearanceCode}{item?.killPlace}
    + داده ای ثبت نشده! +
    +
    + ); +}; + +export const TableSVetAcceptDischarge = ({ item }) => { + return ( + + + مرحله تخلیه بار + {" ( "} + + تعداد بارها: {item?.killHouseRequests?.numberOfBars?.toLocaleString()} + ، تایید تخلیه:{" "} + {item?.killHouseRequests?.vetAcceptedNumberOfBars?.toLocaleString()}، + تخلیه نشده:{" "} + {item?.killHouseRequests?.vetRemainNumberOfBars?.toLocaleString()} + + {" ) "} + + + + + + + + + + + + + + + + + + + + {item?.killHouseRequests?.killHouseRequestVetCheckSerializer.length ? ( + + {item?.killHouseRequests?.killHouseRequestVetCheckSerializer.map( + (item, i) => ( + + + + + + + + + + + + + + + + ) + )} + + ) : ( + + )} +
    ردیفکد بارخریدارماشینرانندهتعدادوزن بارمیانگین وزنکد قرنطینهتعداد تخلیه شده وزن تخلیه شده وضعیتاطلاعات تخلیه
    {i + 1}{item?.barCode} + {`${item?.killhouseUser?.killHouseOperator?.user?.fullname} (${item?.killhouseUser?.killHouseOperator?.user?.mobile})`} + {`${item?.addCar?.driver?.typeCar} (${item?.addCar?.driver?.pelak})`}{`${item?.addCar?.driver?.driverName} (${item?.addCar?.driver?.driverMobile})`} + {item?.quantity.toLocaleString()} + {item?.weightInfo?.weight} + {item?.weightInfo?.indexWeight} + {item?.clearanceCode} + {item?.vetAcceptedRealQuantity?.toLocaleString()} + + {item?.vetAcceptedRealWeight?.toLocaleString()} + + {item?.vetState === "accepted" + ? "تخلیه شده" + : "در انتظار تخلیه"} + + {item?.vetState === "accepted" + ? `${item?.killHouseVet?.fullname} (${item?.killHouseVet?.mobile})` + : "-"} +
    + تخلیه بار تایید نشده است. +
    +
    + ); +}; + +export const TableSlaughterInputBarData = ({ item }) => { + return ( + + اطلاعات بار + + + + + + + + + + + + + + + + + + + {item?.killHouseRequests?.killHouseRequestAssignmentSerializer ? ( + + {item?.killHouseRequests?.killHouseRequestAssignmentSerializer.map( + (item, i) => ( + + + + + + + + + + + + + {" "} + + + ) + )} + + ) : ( + + )} +
    ردیفکد بارخریدارماشینرانندهتعدادوزن بارمیانگین وزنکد قرنطینهتعداد تخلیه شده (دامپزشک)وزن تخلیه شده (دامپزشک)تعداد نهاییوزن خالص واقعی
    {i + 1}{item?.barCode} + {`${item?.killhouseUser?.killHouseOperator?.user?.fullname} (${item?.killhouseUser?.killHouseOperator?.user?.mobile})`} + {`${item?.addCar?.driver?.typeCar} (${item?.addCar?.driver?.pelak})`}{`${item?.addCar?.driver?.driverName} (${item?.addCar?.driver?.driverMobile})`} + {item?.quantity.toLocaleString()} + {item?.weightInfo?.weight} + {item?.weightInfo?.indexWeight} + {item?.clearanceCode} + {item?.vetAcceptedRealQuantity?.toLocaleString()} + + {item?.vetAcceptedRealWeight?.toLocaleString()} + + {item?.acceptedRealQuantity?.toLocaleString()} + + {item?.acceptedRealWeight?.toLocaleString()} +
    + داده ای ثبت نشده! +
    +
    + ); +}; + +export const TableSlaughterFinanceInfo = ({ item }) => { + return ( + + + + + + + + + + + + + + + + + + + {item?.provinceState?.date && ( + + + {/* */} + + + )} +
    ردیفکد بارخریدارماشینرانندهنژادکد قرنطینهتعداد نهاییوزن خالص بارمیانگین وزنمبلغ فاکتوروضعیتاطلاعات پرداخت (شناسه پرداخت)
    + {item?.provinceState?.provinceOperatorFullname} +
    + ); +}; + +export const TableInspector = ({ item }) => { + return ( + + + + + + + + + + + + + + + + + + + + {item?.provinceState?.date && ( + + + {/* */} + + + )} +
    ردیفکد بارخریدارماشینرانندهنژادکد قرنطینهتعداد نهاییوزن خالص بارمیانگین وزنمبلغ فاکتوروضعیت پرداختوضعیتنظر بازرس
    + {item?.provinceState?.provinceOperatorFullname} +
    + ); +}; diff --git a/src/features/province/components/province-cases-item/ProvinceCasesItem.js b/src/features/province/components/province-cases-item/ProvinceCasesItem.js new file mode 100644 index 0000000..6348c0c --- /dev/null +++ b/src/features/province/components/province-cases-item/ProvinceCasesItem.js @@ -0,0 +1,253 @@ +import { + Collapse, + IconButton, + Paper, + Tooltip, + Typography, +} from "@mui/material"; +import { useEffect, useState, useRef, useContext } from "react"; +import { Grid } from "../../../../components/grid/Grid"; +import { ProvinceCaseOverview } from "../province-case-overview/ProvinceCaseOverview"; +import { ProvinceCaseSteps } from "../province-case-steps/ProvinceCaseSteps"; +import { ProvinceCaseStepPaymentInformation } from "../province-case-step-payment-information/ProvinceCaseStepPaymentInformation"; +import { BsFillFileEarmarkPdfFill } from "react-icons/bs"; +import { useReactToPrint } from "react-to-print"; +import { AppContext } from "../../../../contexts/AppContext"; +import ProvinceGetCaseFile from "../province-get-case-file/ProvinceGetCaseFile"; +import { formatJustDate } from "../../../../utils/formatTime"; +import { + TableCityLevel, + TableProvinceLevel, + TableSVetAcceptDischarge, + TableSalughterAllocationLevel, + TableSlaughterAddCar, + TableSlaughterInputBarData, +} from "./Pages"; + +export const ProvinceCasesItem = ({ caseData, caseIndex, pageIndex, data }) => { + const [isCollapsed, setIsCollapsed] = useState(false); + const [clickedStep, setClickedStep] = useState(null); + + const [statusColor, setStatusColor] = useState("black"); + + const [, , selectedDate1] = useContext(AppContext); + + const [currentStep, setCurrentStep] = useState("تایید شهرستان"); + + useEffect(() => { + let step = "تایید شهرستان"; + + if ( + caseData?.cityState?.state === "reject" || + caseData?.provinceState?.state === "reject" + ) { + step = "درخواست رد شد"; + setStatusColor("red"); + } else { + if (caseData?.cityState?.date) { + step = "تایید شهرستان"; + } + if (caseData?.provinceState?.date) { + step = "تایید استان"; + } + if ( + caseData?.provinceKillRequests?.provinceKillRequestSerializer?.length > + 0 + ) { + step = "تخصیص به خریدار"; + } + if ( + caseData?.killHouseRequests?.killHouseRequestsSerializer?.length > 0 + ) { + step = "ایجاد بار"; + } + if ( + caseData?.killHouseRequests?.killHouseRequestVetCheckSerializer + ?.length > 0 + ) { + step = "تخلیه بار"; + } + if ( + caseData?.killHouseRequests?.killHouseRequestAssignmentSerializer + ?.length > 0 + ) { + step = "اطلاعات بار"; + } + } + + setCurrentStep(step); + }, [caseData]); + + const componentRef = useRef(); + const printPDF = useReactToPrint({ + content: () => componentRef.current, + documentTitle: `گزارش پرونده `, + }); + + const setPdfOptions = () => { + if (caseData) { + printPDF(); + } + }; + + const handleToggleCollapse = () => { + setIsCollapsed(!isCollapsed); + }; + + const stepClickedHandler = (step) => { + setClickedStep(step); + }; + + let clickedStepComponent; + + switch (clickedStep) { + case 1: + clickedStepComponent = ; + break; + case 2: + clickedStepComponent = ; + break; + case 3: + clickedStepComponent = ; + break; + case 4: + clickedStepComponent = ; + break; + case 5: + clickedStepComponent = ; + break; + case 6: + clickedStepComponent = ; + break; + case 7: + clickedStepComponent = ; + break; + default: + break; + } + + return ( + + +
    + + {pageIndex + caseIndex}. + +
    + + {caseData.out ? "خارج استان" : "داخل استان"} + +
    +
    +
    +
    + +
    + +
    + + + + شماره سفارش: {caseData?.orderCode} + + + + + + نوع کشتار: {caseData?.freezing ? "انجماد" : "عادی"} + + + + + + تاریخ کشتار: {formatJustDate(caseData?.sendDate)} + + + + + + مرغدار: {caseData?.poultry?.unitName} + + + + + + وضعیت: {currentStep} + + + + + + + + + + + +
    + + + + + {clickedStepComponent} + + +
    +
    +
    + ); +}; diff --git a/src/features/province/components/province-cases/ProvinceCases.js b/src/features/province/components/province-cases/ProvinceCases.js new file mode 100644 index 0000000..e88ea1f --- /dev/null +++ b/src/features/province/components/province-cases/ProvinceCases.js @@ -0,0 +1,290 @@ +import { + Button, + Pagination, + TextField, + Tooltip, + Typography, +} from "@mui/material"; +import { Grid } from "../../../../components/grid/Grid"; +import { DatePicker } from "@mui/x-date-pickers"; +import moment from "moment/moment"; +import { RiFileExcel2Fill, RiSearchLine } from "react-icons/ri"; +import axios from "axios"; +import { AppContext } from "../../../../contexts/AppContext"; +import { useContext, useEffect, useState } from "react"; +import { SPACING } from "../../../../data/spacing"; +import { ProvinceCasesItem } from "../province-cases-item/ProvinceCasesItem"; +import { useDispatch, useSelector } from "react-redux"; +import { + LOADING_END, + LOADING_START, +} from "../../../../lib/redux/slices/appSlice"; +import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl"; +import { provinceGetCasesOverview } from "../../services/get-cases-overview"; +import ResponsiveTable from "../../../../components/responsive-table/ResponsiveTable"; + +export const ProvinceCases = () => { + const [, , selectedDate1, setSelectedDate1, selectedDate2, setSelectedDate2] = + useContext(AppContext); + const [textValue, setTextValue] = useState(""); + const [data, setData] = useState([]); + const [totalRows, setTotalRows] = useState(0); + const [perPage, setPerPage] = useState(10); + const dispatch = useDispatch(); + + const { casesOverview } = useSelector((item) => item.provinceSlice); + + const fetchApiData = async (page) => { + setPage(1); + dispatch(LOADING_START()); + const response = await axios.get( + `poultry_requests_for_total_information/?date1=${selectedDate1}&date2=${selectedDate2}&search=filter&value=${ + textValue ? textValue : "" + }&page=${page}&page_size=${perPage}&role=${getRoleFromUrl()}` + ); + setData(response.data.results); + setTotalRows(response.data.count); + dispatch(LOADING_END()); + }; + + const [page, setPage] = useState(1); + + const handleChangePage = (event, newPage) => { + setPage(newPage + 1, fetchApiData(newPage + 1)); + }; + + // const handlePageChange = (page) => { + // fetchApiData(page, textValue); + // }; + + // const handlePerRowsChange = async (newPerPage, page) => { + // setLoading(true); + // let response = await axios.get( + // `Poultry_Request/?state=accepted&date1=${selectedDate1}&date2=${selectedDate2}&search=filter&value=${ + // textValue ? textValue : "" + // }&page=${page}&page_size=${newPerPage}` + // ); + + // setData(response.data.results); + // setTotalRows(response.data.count); + // setPerPage(newPerPage); + + // setLoading(false); + // }; + const userKey = useSelector((state) => state.userSlice.userProfile.key); + + const [openNotif] = useContext(AppContext); + + useEffect(() => { + setPerPage(10); + fetchApiData(1); + dispatch( + provinceGetCasesOverview({ date1: selectedDate1, date2: selectedDate2 }) + ); + }, [selectedDate1, selectedDate2]); + + useEffect(() => { + const currentDate = moment(new Date()).format("YYYY-MM-DD"); + setSelectedDate1(currentDate); + setSelectedDate2(currentDate); + }, []); + + const handleTextChange = (event) => { + setTextValue(event.target.value); + }; + + const handleSubmit = async (event) => { + event.preventDefault(); + fetchApiData(1); + }; + + return ( + + + روند پرونده ها + + } + value={selectedDate1} + onChange={(e) => { + setSelectedDate1(moment(e).format("YYYY-MM-DD")); + }} + /> + + + } + value={selectedDate2} + onChange={(e) => { + setSelectedDate2(moment(e).format("YYYY-MM-DD")); + }} + /> + + {/*
    */} + + + {/* */} + + {/* */} + + {/* */} + + + {/* */} + + {/* */} + +
    + + + { + openNotif({ + vertical: "top", + horizontal: "center", + msg: "فایل اکسل در حال دانلود می باشد، این علمیات ممکن است زمان بر باشد لطفا صبر کنید.", + severity: "success", + }); + const link = `${ + axios.defaults.baseURL + }detail_of_killing_excel/?date1=${selectedDate1}&date2=${selectedDate2}&role=${getRoleFromUrl()}&key=${userKey}`; + window.location.href = link; + }} + > + + , + ], + ]} + /> + + + {data.map((item, i) => ( + + ))} + {!!data?.length && ( + + { + handleChangePage(event, newPage - 1); + }} + /> + + )} + + +
    + ); +}; diff --git a/src/features/province/components/province-check-chain-allocation/ProvinceCheckChainAllocation.js b/src/features/province/components/province-check-chain-allocation/ProvinceCheckChainAllocation.js new file mode 100644 index 0000000..92d1bab --- /dev/null +++ b/src/features/province/components/province-check-chain-allocation/ProvinceCheckChainAllocation.js @@ -0,0 +1,129 @@ +import { Button, TextField, Typography } from "@mui/material"; +import { useContext, useState } from "react"; +import { useDispatch } from "react-redux"; +import { AppContext } from "../../../../contexts/AppContext"; +import { Grid } from "../../../../components/grid/Grid"; +import { SPACING } from "../../../../data/spacing"; +import { DRAWER } from "../../../../lib/redux/slices/appSlice"; +import { provinceCheckChainAllocationService } from "../../services/province-check-chain-allocation"; + +export const ProvinceCheckChainAllocation = ({ item, fetchApiData }) => { + const dispatch = useDispatch(); + const [openNotif] = useContext(AppContext); + const [value, setValue] = useState(""); + + const handleChange = (event) => { + setValue(event.target.value); + }; + + return ( + + + + اطلاعات مرغدار + + + نام: {item?.poultryHatching?.poultry?.unitName} ( + {item?.poultryHatching?.poultry?.user?.mobile}) + + + شرکت زنجیره:{" "} + {`${item?.chainCompany?.name} (${item?.chainCompany?.user.mobile})`} + + + نوع تخصیص: {item?.outProvince ? "خارج استان" : "داخل استان"} + + + خریدار:{" "} + {item?.killHouse?.killHouseOperator?.user.fullname + ? `${item?.killHouse?.killHouseOperator?.user.fullname} (${item?.killHouse?.killHouseOperator?.user.mobile})` + : `${item?.buyerName} (${item?.buyerMobile})`} + + + + + + + + + + ); +}; diff --git a/src/features/province/components/province-check-free-sale/ProvinceCheckFreeSale.js b/src/features/province/components/province-check-free-sale/ProvinceCheckFreeSale.js new file mode 100644 index 0000000..72ed3cd --- /dev/null +++ b/src/features/province/components/province-check-free-sale/ProvinceCheckFreeSale.js @@ -0,0 +1,407 @@ +import { + Button, + FormControl, + FormControlLabel, + FormLabel, + Radio, + RadioGroup, + TextField, + Typography, +} from "@mui/material"; +import { useContext, useEffect, useState } from "react"; +import { useDispatch } from "react-redux"; +import { Grid } from "../../../../components/grid/Grid"; +import { AppContext } from "../../../../contexts/AppContext"; +import { SPACING } from "../../../../data/spacing"; +import { DRAWER } from "../../../../lib/redux/slices/appSlice"; +import { provinceCheckFreeSaleService } from "../../services/province-check-free-sale"; +import { provinceGetFreeSalesRequestsService } from "../../services/province-get-free-sales-requests"; +import { useFormik } from "formik"; +import { Yup } from "../../../../lib/yup/yup"; +import { provinceEditFreeSaleService } from "../../services/province-edit-free-sale"; +import { useProvinceName } from "../../../../utils/getProvinceName"; + +export const ProvinceCheckFreeSale = ({ + buyer, + poultryRequestKey, + item, + isEdit, +}) => { + const [, , selectedDate1, , selectedDate2] = useContext(AppContext); + + const dispatch = useDispatch(); + const [openNotif] = useContext(AppContext); + const [value, setValue] = useState(""); + const [payerValue, setPayerValue] = useState( + isEdit ? item.payerType : "poultry" + ); + const handleChange = (event) => { + setValue(event.target.value); + }; + + const provinceName = useProvinceName(); + + const handleChangePayer = (event) => { + setPayerValue(event.target.value); + if (event.target.value === "buyer") { + formik.setFieldValue("mobile", buyer.mobile); + } else { + formik.setFieldValue("mobile", item.poultry.user.mobile); + } + }; + + const formik = useFormik({ + initialValues: { + mobile: item.poultry.user.mobile, + weight: isEdit ? item?.IndexWeight : "", + quantity: isEdit ? item?.quantity : "", + }, + validationSchema: Yup.object({ + mobile: Yup.string() + .required("شماره موبایل الزامی است") + .min(11, "شماره موبایل باید 11 رقم باشد") + .max(11, "شماره موبایل باید 11 رقم باشد") + .matches(/^09\d{9}$/, "شماره موبایل باید با 09 شروع شود و 11 رقم باشد"), + weight: Yup.number(), + quantity: Yup.number(), + }), + }); + + useEffect(() => { + formik.validateForm(); + }, []); + + useEffect(() => { + let newVal = formik.values.weight; + const mystring = formik.values.weight.toString().split(".").join(""); + if (formik.values.weight) { + if (mystring.length <= 3) { + if (mystring.length === 2) { + newVal = mystring[0] + "." + mystring[1]; + } + if (mystring.length === 3) { + newVal = mystring[0] + "." + mystring[1] + mystring[2]; + } + } + } + if (isNaN(Number.parseFloat(newVal))) { + formik.setFieldValue("weight", ""); + } else { + formik.setFieldValue("weight", Number.parseFloat(newVal)); + } + }, [formik.values.weight]); + + let buyerType = "-"; + if (buyer.buyerType === "freezing") { + buyerType = "انجماد"; + } else if (buyer.buyerType === "killer") { + buyerType = "کشتارکن"; + } else if (buyer.buyerType === "killhouse") { + buyerType = "کشتارگاه"; + } + + const reg = new RegExp(/^09\d{9}$/); + + return ( + + + + اطلاعات خریدار + + + نام: {buyer.firstName} {buyer.lastName} + + + موبایل: {buyer.mobile} + + + شهر: {buyer.city} + + + استان: {buyer.province} + + + ماهیت خریدار: {buyerType} + + + + {provinceName !== "hamedan" && ( + <> + + + پرداخت کننده + + + } + label="مرغدار" + /> + } + label="خریدار" + /> + + + + + {payerValue === "poultry" ? ( + + {!reg.test(item.poultry.user.mobile) + ? "فرمت تلفن مرغدار نادرست است! لطفا یک شماره موبایل معتبر وارد کنید." + : "از این قسمت میتوانید تلفن مرغدار را ویرایش کنید."} + + ) : ( + + {!reg.test(buyer.mobile) + ? "فرمت تلفن خریدار نادرست است! لطفا یک شماره موبایل معتبر وارد کنید." + : "از این قسمت میتوانید تلفن خریدار را ویرایش کنید."} + + )} + + + + + {isEdit && ( + + + + + + + + + )} + + )} + + + {!isEdit && ( + + )} + {isEdit ? ( + + ) : ( + <> + + + + )} + + + ); +}; diff --git a/src/features/province/components/province-chicken-distribution-and-sales-details/ProvinceChickenDistributionsAndSalesDetails.js b/src/features/province/components/province-chicken-distribution-and-sales-details/ProvinceChickenDistributionsAndSalesDetails.js new file mode 100644 index 0000000..b9a2f45 --- /dev/null +++ b/src/features/province/components/province-chicken-distribution-and-sales-details/ProvinceChickenDistributionsAndSalesDetails.js @@ -0,0 +1,269 @@ +import React, { useContext, useEffect, useState } from "react"; +import { Button, Checkbox, TextField, Tooltip } from "@mui/material"; +import { DatePicker } from "@mui/x-date-pickers"; +import moment from "moment"; +import { useDispatch } from "react-redux"; +import axios from "axios"; +import { RiFileExcel2Fill, RiSearchLine } from "react-icons/ri"; +import { AppContext } from "../../../../contexts/AppContext"; +import { + LOADING_END, + LOADING_START, +} from "../../../../lib/redux/slices/appSlice"; +import { Grid } from "../../../../components/grid/Grid"; +import ResponsiveTable from "../../../../components/responsive-table/ResponsiveTable"; +import { useParams } from "react-router-dom"; +import { formatJustDate } from "../../../../utils/formatTime"; +import ToggleOffOutlinedIcon from "@mui/icons-material/ToggleOffOutlined"; +import ToggleOnIcon from "@mui/icons-material/ToggleOn"; +import { CheckCleanceCode } from "../../../../components/check-clearance-code/ChechClearanceCode"; + +export const ProvinceChickenDistributionsAndSalesDetails = () => { + const [, , selectedDate1, setSelectedDate1, selectedDate2, setSelectedDate2] = + useContext(AppContext); + const { unitkey, name, type } = useParams(); + const [withDate, setWithDate] = useState(false); + + const [openNotif] = useContext(AppContext); + + const dispatch = useDispatch(); + useEffect(() => { + const currentDate = moment(new Date()).format("YYYY-MM-DD"); + setSelectedDate1(currentDate); + setSelectedDate2(currentDate); + }, []); + + const handleTextChange = (event) => { + setTextValue(event.target.value); + }; + + const [data, setData] = useState([]); + const [totalRows, setTotalRows] = useState(0); + const [perPage, setPerPage] = useState(10); + const [textValue, setTextValue] = useState(""); + const [page, setPage] = useState(1); + const [tableData, setTableData] = useState([]); + + const fetchApiData = async (page) => { + let response; + dispatch(LOADING_START()); + response = await axios.get( + `https://rsibackend.rasadyar.com/app/${ + type === "Steward" ? "guilds-" : "" + }transport-carcass-detail/?search=${textValue}${ + withDate ? `&date1=${selectedDate1}&date2=${selectedDate2}` : `` + }&page=${page}&page_size=${perPage}&code=${unitkey}` + ); + dispatch(LOADING_END()); + setData(response.data.results); + setTotalRows(response.data.count); + }; + + const handlePageChange = (page) => { + fetchApiData(page); + setPage(page); + }; + + const handlePerRowsChange = (perRows) => { + setPerPage(perRows); + setPage(1); + }; + + // const updateTable = () => { + // fetchApiData(page !== 0 ? page : 1); + // }; + + useEffect(() => { + const d = data?.map((item, i) => { + return [ + page === 1 ? i + 1 : i + perPage * (page - 1) + 1, + item?.productDate ? formatJustDate(item?.productDate) : "-", + `${formatJustDate(item?.date)} (${item?.time?.slice(0, 5)})`, + item?.out ? "خارج استان" : "داخل استان", + item?.product, + item?.quantity?.toLocaleString(), + , + item?.origin, + item?.originProvince, + item?.originCity, + item?.destination, + item?.destinationProvince, + item?.destinationCity, + item?.driverName, + item?.owner, + item?.carTrackingCode, + item?.plate, + item?.unloading ? "تخلیه شده" : "در انتظار تخلیه", + ]; + }); + + setTableData(d); + }, [data]); + + useEffect(() => { + fetchApiData(1); + }, [dispatch, selectedDate1, selectedDate2, perPage, withDate]); + + const handleSubmit = async (event) => { + event.preventDefault(); + dispatch(LOADING_START()); + + try { + const response = await axios.get( + `https://rsibackend.rasadyar.com/app/${ + type === "Steward" ? "guilds-" : "" + }transport-carcass-detail/?search=${textValue}${ + withDate ? `&date1=${selectedDate1}&date2=${selectedDate2}` : `` + }&page=${1}&page_size=${perPage}&code=${unitkey}` + ); + setData(response.data.results); + setTotalRows(response.data.count); + dispatch(LOADING_END()); + } catch (error) { + console.error("Error fetching data:", error); + } + }; + + return ( + + + + } + checkedIcon={} + checked={withDate} + onChange={() => setWithDate(!withDate)} + color="primary" + size="large" + /> + + ( + + )} + value={selectedDate1} + onChange={(e) => { + setSelectedDate1(moment(e).format("YYYY-MM-DD")); + }} + /> + + + ( + + )} + value={selectedDate2} + onChange={(e) => { + setSelectedDate2(moment(e).format("YYYY-MM-DD")); + }} + /> + + + +
    + + + +
    + + + {/* */} + +
    + + +
    + ); +}; diff --git a/src/features/province/components/province-chicken-distribution-and-sales/ProvinceChickenDistributionsAndSales.js b/src/features/province/components/province-chicken-distribution-and-sales/ProvinceChickenDistributionsAndSales.js new file mode 100644 index 0000000..c5a4a6f --- /dev/null +++ b/src/features/province/components/province-chicken-distribution-and-sales/ProvinceChickenDistributionsAndSales.js @@ -0,0 +1,437 @@ +import React, { useContext, useEffect, useState } from "react"; +import { + Autocomplete, + Button, + Checkbox, + IconButton, + MenuItem, + Select, + TextField, + Tooltip, +} from "@mui/material"; +import { DatePicker } from "@mui/x-date-pickers"; +import moment from "moment"; +import { useDispatch } from "react-redux"; +import axios from "axios"; +import { RiFileExcel2Fill, RiSearchLine } from "react-icons/ri"; +import { AppContext } from "../../../../contexts/AppContext"; +import { + LOADING_END, + LOADING_START, +} from "../../../../lib/redux/slices/appSlice"; +import { Grid } from "../../../../components/grid/Grid"; +import ResponsiveTable from "../../../../components/responsive-table/ResponsiveTable"; +import { getSamasatProvinces } from "../../../../utils/getSamasatProvinces"; +import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl"; +import { + ROUTE_ADMINX_ROUTE_NATIONAL_INFO_SLAUGHTER, + ROUTE_SUPER_ADMIN_ROUTE_NATIONAL_INFO_SLAUGHTER, +} from "../../../../routes/routes"; +import { ProvinceChickenDistributionsAndSalesDashboardService } from "../../services/province-chicken-distribution-and-sales-dashboard"; +import { formatTime } from "../../../../utils/formatTime"; +import ToggleOffOutlinedIcon from "@mui/icons-material/ToggleOffOutlined"; +import ToggleOnIcon from "@mui/icons-material/ToggleOn"; +import VisibilityIcon from "@mui/icons-material/Visibility"; + +export const ProvinceChickenDistributionsAndSales = () => { + const [, , selectedDate1, setSelectedDate1, selectedDate2, setSelectedDate2] = + useContext(AppContext); + const dispatch = useDispatch(); + const [selectedRole, setSelectedRole] = useState("KillHouse"); + useEffect(() => { + const currentDate = moment(new Date()).format("YYYY-MM-DD"); + setSelectedDate1(currentDate); + setSelectedDate2(currentDate); + }, []); + const [dashboardData, setDashboardData] = useState([]); + const [withDate, setWithDate] = useState(false); + const [openNotif] = useContext(AppContext); + + const [selectedProvince, setSelectedProvince] = useState(""); + + const handleTextChange = (event) => { + setTextValue(event.target.value); + }; + + const [data, setData] = useState([]); + const [totalRows, setTotalRows] = useState(0); + const [perPage, setPerPage] = useState(10); + const [textValue, setTextValue] = useState(""); + const [page, setPage] = useState(1); + const [tableData, setTableData] = useState([]); + + const fetchApiData = async (page) => { + let response; + getDashboardData(); + dispatch(LOADING_START()); + response = await axios.get( + `https://rsibackend.rasadyar.com/app/transport-carcass-detail/?search=${textValue}${ + withDate ? `&date1=${selectedDate1}&date2=${selectedDate2}` : `` + }&role=${selectedRole}&province=${selectedProvince}&page=${page}&page_size=${perPage}` + ); + dispatch(LOADING_END()); + setData(response.data.results); + setTotalRows(response.data.count); + }; + + const handlePageChange = (page) => { + fetchApiData(page); + setPage(page); + }; + + const handlePerRowsChange = (perRows) => { + setPerPage(perRows); + setPage(1); + }; + + // const updateTable = () => { + // fetchApiData(page !== 0 ? page : 1); + // }; + + const getDashboardData = () => { + dispatch( + ProvinceChickenDistributionsAndSalesDashboardService({ + role: selectedRole, + province: selectedProvince, + date1: withDate ? selectedDate1 : null, + date2: withDate ? selectedDate2 : null, + }) + ).then((r) => { + setDashboardData(r.payload.data); + }); + }; + + useEffect(() => { + const d = data?.map((item, i) => { + const distributonWeight = + item?.info?.totalInputBarsWight + item?.info?.totalOutputBarsWight; + return [ + page === 1 ? i + 1 : i + perPage * (page - 1) + 1, + item?.info?.role, + item?.UnitName || item?.name, + item?.PartIdCode || item?.jihadiCode, + item?.Province || item?.province, + item?.City || item?.city, + "گوشت مرغ تازه", + item?.info?.totalInputBuyBarsCount?.toLocaleString(), + item?.info?.totalInputBuyBarsWight?.toLocaleString(), + item?.info?.totalOutputBuyBarsCount?.toLocaleString(), + item?.info?.totalOutputBuyBarsWight?.toLocaleString(), + item?.info?.totalWareHouse?.toLocaleString(), + distributonWeight?.toLocaleString(), + "%" + + (item?.info?.totalWareHouse + ? ((distributonWeight / item?.info?.totalWareHouse) * 100).toFixed( + 1 + ) + : 0), + item?.info?.inputBars?.toLocaleString(), + item?.info?.totalInputBarsWight?.toLocaleString(), + "%" + item?.info?.totalInputBarsPercent?.toLocaleString(), + item?.info?.totalOutputBarsWight?.toLocaleString(), + "%" + item?.info?.totalOutputBarsPercent?.toLocaleString(), + { + window.open( + getRoleFromUrl() === "AdminX" + ? `${ROUTE_ADMINX_ROUTE_NATIONAL_INFO_SLAUGHTER}/${ + selectedRole === "KillHouse" + ? item.PartIdCode + : item?.jihadiCode + }/${item?.UnitName || item?.name}/distribution` + : `${ROUTE_SUPER_ADMIN_ROUTE_NATIONAL_INFO_SLAUGHTER}/${ + selectedRole === "KillHouse" + ? item.PartIdCode + : item?.jihadiCode + }/${item?.UnitName || item?.name}/distribution`, + "_blank" + ); + }} + > + + , + ]; + }); + + setTableData(d); + }, [data]); + + useEffect(() => { + fetchApiData(1); + }, [ + dispatch, + selectedDate1, + selectedDate2, + perPage, + selectedRole, + selectedProvince, + withDate, + ]); + + const handleSubmit = async (event) => { + event.preventDefault(); + getDashboardData(); + dispatch(LOADING_START()); + + try { + const response = await axios.get( + `https://rsibackend.rasadyar.com/app/transport-carcass-detail/?role=${selectedRole}&province=${selectedProvince}&search=${textValue}${ + withDate ? `&date1=${selectedDate1}&date2=${selectedDate2}` : `` + }&page=${1}&page_size=${perPage}` + ); + setData(response.data.results); + setTotalRows(response.data.count); + dispatch(LOADING_END()); + } catch (error) { + console.error("Error fetching data:", error); + } + }; + + const getProvinceList = () => { + return [{ name: "همه" }, ...getSamasatProvinces()]; + }; + + return ( + + + + + + { + return { + label: i.name, + }; + })} + onChange={(event, value) => { + if (value.label !== "همه") { + setSelectedProvince(value.label); + } else { + setSelectedProvince(""); + } + }} + renderInput={(params) => ( + + )} + /> + + + + } + checkedIcon={} + checked={withDate} + onChange={() => setWithDate(!withDate)} + color="primary" + size="large" + /> + + ( + + )} + value={selectedDate1} + onChange={(e) => { + setSelectedDate1(moment(e).format("YYYY-MM-DD")); + }} + /> + + + ( + + )} + value={selectedDate2} + onChange={(e) => { + setSelectedDate2(moment(e).format("YYYY-MM-DD")); + }} + /> + + + +
    + + + +
    + + + {/* */} + +
    + + +
    + ); +}; diff --git a/src/features/province/components/province-chicken-steward-sales/ProvinceChickenStewardSales.js b/src/features/province/components/province-chicken-steward-sales/ProvinceChickenStewardSales.js new file mode 100644 index 0000000..23d1fac --- /dev/null +++ b/src/features/province/components/province-chicken-steward-sales/ProvinceChickenStewardSales.js @@ -0,0 +1,365 @@ +import React, { useContext, useEffect, useState } from "react"; +import { + Autocomplete, + Button, + Checkbox, + IconButton, + TextField, + Tooltip, +} from "@mui/material"; +import { DatePicker } from "@mui/x-date-pickers"; +import moment from "moment"; +import { useDispatch } from "react-redux"; +import axios from "axios"; +import { RiFileExcel2Fill, RiSearchLine } from "react-icons/ri"; +import { AppContext } from "../../../../contexts/AppContext"; +import { + LOADING_END, + LOADING_START, +} from "../../../../lib/redux/slices/appSlice"; +import { Grid } from "../../../../components/grid/Grid"; +import ResponsiveTable from "../../../../components/responsive-table/ResponsiveTable"; +import { getSamasatProvinces } from "../../../../utils/getSamasatProvinces"; +import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl"; +import { + ROUTE_ADMINX_ROUTE_NATIONAL_INFO_SLAUGHTER, + ROUTE_SUPER_ADMIN_ROUTE_NATIONAL_INFO_SLAUGHTER, +} from "../../../../routes/routes"; +import { ProvinceStewardChickenDistributionsAndSalesDashboardService } from "../../services/province-chicken-distribution-and-sales-dashboard"; +import { formatTime } from "../../../../utils/formatTime"; +import ToggleOffOutlinedIcon from "@mui/icons-material/ToggleOffOutlined"; +import ToggleOnIcon from "@mui/icons-material/ToggleOn"; +import VisibilityIcon from "@mui/icons-material/Visibility"; + +export const ProvinceChickenStewardSales = () => { + const [, , selectedDate1, setSelectedDate1, selectedDate2, setSelectedDate2] = + useContext(AppContext); + const dispatch = useDispatch(); + const [openNotif] = useContext(AppContext); + useEffect(() => { + const currentDate = moment(new Date()).format("YYYY-MM-DD"); + setSelectedDate1(currentDate); + setSelectedDate2(currentDate); + }, []); + const [dashboardData, setDashboardData] = useState([]); + const [withDate, setWithDate] = useState(false); + + const [selectedProvince, setSelectedProvince] = useState(""); + + const handleTextChange = (event) => { + setTextValue(event.target.value); + }; + + const [data, setData] = useState([]); + const [totalRows, setTotalRows] = useState(0); + const [perPage, setPerPage] = useState(10); + const [textValue, setTextValue] = useState(""); + const [page, setPage] = useState(1); + const [tableData, setTableData] = useState([]); + + const fetchApiData = async (page) => { + let response; + getDashboardData(); + dispatch(LOADING_START()); + response = await axios.get( + `https://rsibackend.rasadyar.com/app/guilds-transport-carcass-detail/?search=${textValue}${ + withDate ? `&date1=${selectedDate1}&date2=${selectedDate2}` : `` + }&province=${selectedProvince}&page=${page}&page_size=${perPage}` + ); + dispatch(LOADING_END()); + setData(response.data.results); + setTotalRows(response.data.count); + }; + + const handlePageChange = (page) => { + fetchApiData(page); + setPage(page); + }; + + const handlePerRowsChange = (perRows) => { + setPerPage(perRows); + setPage(1); + }; + + // const updateTable = () => { + // fetchApiData(page !== 0 ? page : 1); + // }; + + const getDashboardData = () => { + dispatch( + ProvinceStewardChickenDistributionsAndSalesDashboardService({ + province: selectedProvince, + date1: withDate ? selectedDate1 : null, + date2: withDate ? selectedDate2 : null, + }) + ).then((r) => { + setDashboardData(r.payload.data); + }); + }; + + useEffect(() => { + const d = data?.map((item, i) => { + return [ + page === 1 ? i + 1 : i + perPage * (page - 1) + 1, + item?.info?.role, + item?.name, + item?.PartIdCode || item?.jihadiCode, + item?.Province || item?.province, + item?.City || item?.city, + "گوشت مرغ تازه", + item?.info?.totalInputBuyBarsCount?.toLocaleString(), + item?.info?.totalInputBuyBarsWight?.toLocaleString(), + item?.info?.totalOutputBuyBarsCount?.toLocaleString(), + item?.info?.totalOutputBuyBarsWight?.toLocaleString(), + item?.info?.totalWareHouse?.toLocaleString(), + item?.info?.totalInputBuyBarsPercent?.toLocaleString(), + item?.info?.totalOutputBuyBarsPercent?.toLocaleString(), + + { + window.open( + getRoleFromUrl() === "AdminX" + ? `${ROUTE_ADMINX_ROUTE_NATIONAL_INFO_SLAUGHTER}/${item?.jihadiCode}/${item?.name}/Steward` + : `${ROUTE_SUPER_ADMIN_ROUTE_NATIONAL_INFO_SLAUGHTER}/${item?.jihadiCode}/${item?.name}/Steward`, + "_blank" + ); + }} + > + + , + ]; + }); + + setTableData(d); + }, [data]); + + useEffect(() => { + fetchApiData(1); + }, [ + dispatch, + selectedDate1, + selectedDate2, + perPage, + selectedProvince, + withDate, + ]); + + const handleSubmit = async (event) => { + event.preventDefault(); + getDashboardData(); + dispatch(LOADING_START()); + + try { + const response = await axios.get( + `https://rsibackend.rasadyar.com/app/guilds-transport-carcass-detail/?&province=${selectedProvince}&search=${textValue}${ + withDate ? `&date1=${selectedDate1}&date2=${selectedDate2}` : `` + }&page=${1}&page_size=${perPage}` + ); + setData(response.data.results); + setTotalRows(response.data.count); + dispatch(LOADING_END()); + } catch (error) { + console.error("Error fetching data:", error); + } + }; + + const getProvinceList = () => { + return [{ name: "همه" }, ...getSamasatProvinces()]; + }; + + return ( + + + + + + { + return { + label: i.name, + }; + })} + onChange={(event, value) => { + if (value.label !== "همه") { + setSelectedProvince(value.label); + } else { + setSelectedProvince(""); + } + }} + renderInput={(params) => ( + + )} + /> + + + } + checkedIcon={} + checked={withDate} + onChange={() => setWithDate(!withDate)} + color="primary" + size="large" + /> + + ( + + )} + value={selectedDate1} + onChange={(e) => { + setSelectedDate1(moment(e).format("YYYY-MM-DD")); + }} + /> + + + ( + + )} + value={selectedDate2} + onChange={(e) => { + setSelectedDate2(moment(e).format("YYYY-MM-DD")); + }} + /> + + + + +
    + + + +
    + + + {/* */} + +
    + + +
    + ); +}; diff --git a/src/features/province/components/province-city-new-requests/ProvinceCityNewRequests.js b/src/features/province/components/province-city-new-requests/ProvinceCityNewRequests.js new file mode 100644 index 0000000..b210b63 --- /dev/null +++ b/src/features/province/components/province-city-new-requests/ProvinceCityNewRequests.js @@ -0,0 +1,252 @@ +import React, { useContext, useEffect, useState } from "react"; +import { Button, TextField } from "@mui/material"; +import { DatePicker } from "@mui/x-date-pickers"; +import moment from "moment"; +import { useDispatch } from "react-redux"; +import axios from "axios"; +import ResponsiveTable from "../../../../components/responsive-table/ResponsiveTable"; +import { Grid } from "../../../../components/grid/Grid"; +import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl"; +import { + DRAWER, + LOADING_END, + LOADING_START, +} from "../../../../lib/redux/slices/appSlice"; +import { AppContext } from "../../../../contexts/AppContext"; +import IconButton from "@mui/material/IconButton"; +import CreateIcon from "@mui/icons-material/Create"; +import { formatJustDate } from "../../../../utils/formatTime"; +import { getFaUserRole } from "../../../../utils/getFaUserRole"; +import CityFileOperations from "../../../file/components/city-file-operations/CityFileOperations"; +// import { useNavigate } from "react-router-dom"; +// import PlagiarismIcon from "@mui/icons-material/Plagiarism"; +// import { ROUTE_PROVINCE_FILE } from "../../../../routes/routes"; +import ProvinceCheckRequest from "../../../file/components/province-check-request/ProvinceCheckRequest"; +import { RiSearchLine } from "react-icons/ri"; + +export const ProvinceCityNewRequests = () => { + const [, , selectedDate1, setSelectedDate1, selectedDate2, setSelectedDate2] = + useContext(AppContext); + const dispatch = useDispatch(); + useEffect(() => { + const currentDate = moment(new Date()).format("YYYY-MM-DD"); + setSelectedDate1(currentDate); + setSelectedDate2(currentDate); + }, []); + + const handleTextChange = (event) => { + setTextValue(event.target.value); + }; + // const navigate = useNavigate(); + + const [data, setData] = useState([]); + const [totalRows, setTotalRows] = useState(0); + const [perPage, setPerPage] = useState(10); + const [textValue, setTextValue] = useState(""); + const [page, setPage] = useState(1); + const [tableData, setTableData] = useState([]); + + const fetchApiData = async (page) => { + let response; + dispatch(LOADING_START()); + response = await axios.get( + `management_request/?search=filter&value=${textValue}&role=${getRoleFromUrl()}&date1=${selectedDate1}&date2=${selectedDate2}&page=${page}&page_size=${perPage}` + ); + dispatch(LOADING_END()); + setData(response.data.results); + setTotalRows(response.data.count); + }; + + const handlePageChange = (page) => { + fetchApiData(page); + setPage(page); + }; + + const handlePerRowsChange = (perRows) => { + setPerPage(perRows); + setPage(1); + }; + + const updateTable = () => { + fetchApiData(page !== 0 ? page : 1); + }; + + useEffect(() => { + const d = data?.map((item, i) => { + return [ + page === 1 ? i + 1 : i + perPage * (page - 1) + 1, + item.stateProcess === "pending" + ? "در انتظار تایید شهرستان" + : "در انتظار تایید استان", + item.orderCode, + item?.poultry?.user?.baseOrder, + formatJustDate(item?.createDate) + + " " + + `(${item?.registrar?.fullname} - ${getFaUserRole( + item?.registrar?.role + )})`, + formatJustDate(item?.sendDate), + item?.freezing ? "انجماد" : item?.export ? "صادرات" : "عادی", + `${item?.poultry?.user?.fullname} (${item?.poultry?.user?.mobile})`, + `${item?.poultry?.unitName}`, + item?.poultry?.cityOperator, + item?.poultry?.address?.city?.name, + formatJustDate(item?.hatching?.hatchingDate), + item?.hatching?.age, + item?.IndexWeight, + item?.quantity.toLocaleString(), + (item?.quantity * item?.IndexWeight).toLocaleString(), + + dispatch( + DRAWER({ + right: !(window.innerWidth <= 600), + bottom: window.innerWidth <= 600, + content: + item.stateProcess === "pending" ? ( + + ) : ( + + ), + title: "انجام عملیات تایید/رد", + }) + ) + } + > + + , + // + // navigate(ROUTE_PROVINCE_FILE + item?.poultry?.poultryRequestId) + // } + // > + // + // , + ]; + }); + + setTableData(d); + }, [data]); + + useEffect(() => { + fetchApiData(1); + }, [dispatch, selectedDate1, selectedDate2, perPage]); + + const handleSubmit = async (event) => { + event.preventDefault(); + dispatch(LOADING_START()); + + try { + const response = await axios.get( + `management_request/?role=${getRoleFromUrl()}&search=filter&value=${textValue}&date1=${selectedDate1}&date2=${selectedDate2}&page=${1}&page_size=${perPage}` + ); + setData(response.data.results); + setTotalRows(response.data.count); + dispatch(LOADING_END()); + } catch (error) { + console.error("Error fetching data:", error); + } + }; + + return ( + + + + ( + + )} + value={selectedDate1} + onChange={(e) => { + setSelectedDate1(moment(e).format("YYYY-MM-DD")); + }} + /> + + + ( + + )} + value={selectedDate2} + onChange={(e) => { + setSelectedDate2(moment(e).format("YYYY-MM-DD")); + }} + /> + + +
    + + + +
    +
    + + +
    + ); +}; diff --git a/src/features/province/components/province-cold-houses-killhouses/ProvinceColdHousesKillHouses.js b/src/features/province/components/province-cold-houses-killhouses/ProvinceColdHousesKillHouses.js new file mode 100644 index 0000000..4a05f9c --- /dev/null +++ b/src/features/province/components/province-cold-houses-killhouses/ProvinceColdHousesKillHouses.js @@ -0,0 +1,201 @@ +import React, { useContext, useEffect, useState } from "react"; +import { Button, IconButton, TextField, Tooltip } from "@mui/material"; +import { useDispatch } from "react-redux"; +import axios from "axios"; +import ResponsiveTable from "../../../../components/responsive-table/ResponsiveTable"; +import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl"; +import { + LOADING_END, + LOADING_START, +} from "../../../../lib/redux/slices/appSlice"; +import { Grid } from "../../../../components/grid/Grid"; +import { + ROUTE_ADMINX_COLD_HOUSES_MANAGEMENT, + ROUTE_PROVINCE_COLD_HOUSES_MANAGEMENT, + ROUTE_SUPER_ADMIN_COLD_HOUSES_MANAGEMENT, +} from "../../../../routes/routes"; +import { useNavigate } from "react-router-dom"; +import { RiFileExcel2Fill } from "react-icons/ri"; +import { AppContext } from "../../../../contexts/AppContext"; +import { RiSearchLine } from "react-icons/ri"; +import VisibilityIcon from "@mui/icons-material/Visibility"; + +export const ProvinceColdHousesKillHouses = () => { + const dispatch = useDispatch(); + const navigate = useNavigate(); + const handleTextChange = (event) => { + setTextValue(event.target.value); + }; + const [openNotif] = useContext(AppContext); + + const [data, setData] = useState([]); + const [totalRows, setTotalRows] = useState(0); + const [perPage, setPerPage] = useState(10); + const [textValue, setTextValue] = useState(""); + const [page, setPage] = useState(1); + const [tableData, setTableData] = useState([]); + + const fetchApiData = async (page) => { + let response; + dispatch(LOADING_START()); + response = await axios.get( + `kill-house-cold-house/?search=filter&value=${textValue}&role=${getRoleFromUrl()}&page=${page}&page_size=${perPage}` + ); + dispatch(LOADING_END()); + setData(response.data.results); + setTotalRows(response.data.count); + }; + + const handlePageChange = (page) => { + fetchApiData(page); + setPage(page); + }; + + const handlePerRowsChange = (perRows) => { + setPerPage(perRows); + setPage(1); + }; + + // const updateTable = () => { + // fetchApiData(page !== 0 ? page : 1); + // }; + + useEffect(() => { + const d = data?.map((item, i) => { + return [ + page === 1 ? i + 1 : i + perPage * (page - 1) + 1, + item?.name, + item?.fullname, + item?.mobile, + item?.city, + item?.coldHousesInfo?.totalColdHouses?.toLocaleString(), + item?.coldHousesInfo?.totalInputWeight?.toLocaleString(), + item?.coldHousesInfo?.totalAllocatedWeight?.toLocaleString(), + item?.coldHousesInfo?.totalRemainWeight?.toLocaleString(), + + { + navigate( + (getRoleFromUrl() === "ProvinceOperator" + ? ROUTE_PROVINCE_COLD_HOUSES_MANAGEMENT + : getRoleFromUrl() === "AdminX" + ? ROUTE_ADMINX_COLD_HOUSES_MANAGEMENT + : ROUTE_SUPER_ADMIN_COLD_HOUSES_MANAGEMENT) + + "/" + + item?.key + + "/" + + item?.fullname + + "/" + + "killhouse" + ); + }} + > + + + , + ]; + }); + + setTableData(d); + }, [data]); + + useEffect(() => { + fetchApiData(1); + }, [dispatch, perPage]); + + const handleSubmit = async (event) => { + event.preventDefault(); + dispatch(LOADING_START()); + + try { + const response = await axios.get( + `kill-house-cold-house/?role=${getRoleFromUrl()}&search=filter&value=${textValue}&page=${1}&page_size=${perPage}` + ); + setData(response.data.results); + setTotalRows(response.data.count); + dispatch(LOADING_END()); + } catch (error) { + console.error("Error fetching data:", error); + } + }; + + return ( + + + +
    + + + +
    + + + {/* */} + + {/* */} + +
    + + +
    + ); +}; diff --git a/src/features/province/components/province-cold-houses-list-add-cold-house/ProvinceColdHousesListAddColdHouse.js b/src/features/province/components/province-cold-houses-list-add-cold-house/ProvinceColdHousesListAddColdHouse.js new file mode 100644 index 0000000..8162515 --- /dev/null +++ b/src/features/province/components/province-cold-houses-list-add-cold-house/ProvinceColdHousesListAddColdHouse.js @@ -0,0 +1,326 @@ +import React, { useContext, useEffect, useState } from "react"; +import { + Grid, + TextField, + Button, + Autocomplete, + Typography, + FormControlLabel, + Checkbox, +} from "@mui/material"; +import { useFormik } from "formik"; +import * as Yup from "yup"; +import { DRAWER } from "../../../../lib/redux/slices/appSlice"; +import { useDispatch } from "react-redux"; +import { + provinceCreateColdHouseService, + provinceEditColdHouseService, + provinceGetAllStewardsService, +} from "../../services/province-cold-houses"; +import { + slaughterGetCitiesService, + slaughterGetProvinceService, +} from "../../../slaughter-house/services/slaughter-get-provinces"; +import { AppContext } from "../../../../contexts/AppContext"; + +export const ProvinceColdHousesListAddColdHouse = ({ + isEdit, + updateTable, + item, + stewardKey, + killhouseKey, +}) => { + const dispatch = useDispatch(); + const [stewardsOptions, setStewardsOptions] = useState([]); + const validationSchema = Yup.object({ + name: Yup.string().required("این فیلد اجباریست!"), + address: Yup.string().required("این فیلد اجباریست!"), + steward_key: Yup.string(), + province: Yup.string() + .required("این فیلد اجباری است!") + .typeError("لطفا فیلد را به درستی وارد کنید!"), + city: Yup.string() + .required("این فیلد اجباری است!") + .typeError("لطفا فیلد را به درستی وارد کنید!"), + active: Yup.boolean(), + broadcast: Yup.boolean(), + relocate: Yup.boolean(), + }); + + const [provinceData, setProvinceData] = useState([]); + const [cityData, setCityData] = useState([]); + const [openNotif] = useContext(AppContext); + + useEffect(() => { + if (!isEdit && !stewardKey) { + dispatch(provinceGetAllStewardsService()).then((r) => { + setStewardsOptions(r.payload.data); + }); + } + }, []); + const formik = useFormik({ + initialValues: { + name: isEdit ? item?.name : "", + address: isEdit ? item?.address : "", + steward_key: "", + province: isEdit ? item?.province : "", + city: isEdit ? item?.city : "", + active: isEdit ? item?.active : false, + broadcast: isEdit ? item?.broadcast : false, + relocate: isEdit ? item?.relocate : false, + }, + validationSchema, + onSubmit: (values) => { + if (isEdit) { + dispatch( + provinceEditColdHouseService({ + cold_house_key: item?.key, + name: values.name, + province: values.province, + city: values.city, + address: values.address, + active: values.active, + broadcast: values.broadcast, + relocate: values.relocate, + }) + ).then((r) => { + if (r.payload.error) { + openNotif({ + vertical: "top", + horizontal: "center", + msg: r.payload.error, + severity: "error", + }); + } else { + dispatch(DRAWER({ right: false, bottom: false, content: null })); + updateTable(); + openNotif({ + vertical: "top", + horizontal: "center", + msg: "عملیات با موفقیت انجام شد.", + severity: "success", + }); + } + }); + } else { + let req = { + steward_key: killhouseKey + ? null + : stewardKey + ? stewardKey + : values.steward_key, + kill_house_key: killhouseKey, + name: values.name, + province: values.province, + city: values.city, + address: values.address, + active: values.active, + broadcast: values.broadcast, + relocate: values.relocate, + }; + req = Object.fromEntries( + Object.entries(req).filter(([_, value]) => value !== null) + ); + dispatch(provinceCreateColdHouseService(req)).then((r) => { + if (r.payload.error) { + openNotif({ + vertical: "top", + horizontal: "center", + msg: r.payload.error, + severity: "error", + }); + } else { + dispatch(DRAWER({ right: false, bottom: false, content: null })); + updateTable(); + openNotif({ + vertical: "top", + horizontal: "center", + msg: "عملیات با موفقیت انجام شد.", + severity: "success", + }); + } + }); + } + }, + }); + + useEffect(() => { + formik.validateForm(); + }, []); + + useEffect(() => { + dispatch(slaughterGetProvinceService()).then((r) => { + setProvinceData(r.payload.data); + }); + }, []); + + useEffect(() => { + if (formik.values.province) { + setCityData( + [], + dispatch(slaughterGetCitiesService(formik.values.province)).then( + (r) => { + setCityData(r.payload.data); + } + ) + ); + } + }, [formik.values.province]); + + return ( + + {!isEdit && !stewardKey && ( + + ({ + id: i.key, + label: `${i.fullname} / ${i.mobile} `, + item: i, + })) + : [] + } + value={formik.values.guild} + onChange={(e, item) => { + formik.setFieldValue("steward_key", item?.id); + formik.validateForm(); + }} + error={formik.touched.guild && Boolean(formik.errors.guild)} + helperText={formik.touched.guild && formik.errors.guild} + getOptionLabel={(option) => option.label} + renderInput={(params) => ( + + )} + /> + + )} + + + + + ({ id: i.name, label: i.name })) + : [] + } + onChange={(e, value) => { + formik.setFieldValue("province", value ? value.id : ""); + formik.setFieldValue("city", ""); + }} + renderInput={(params) => ( + + )} + /> + {isEdit && ( + + استان: {formik.values.province} + + )} + + ({ id: i.name, label: i.name })) : [] + } + onChange={(e, value) => { + formik.setFieldValue("city", value ? value.id : ""); + }} + renderInput={(params) => ( + + )} + /> + + {isEdit && ( + + شهر: {formik.values.city} + + )} + + + + + + + + } + label="فعال" + /> + + } + label="اجازه پخش" + /> + + } + label="اجازه جابجایی" + /> + + + + + + + ); +}; diff --git a/src/features/province/components/province-cold-houses-list/ProvinceColdHousesList.js b/src/features/province/components/province-cold-houses-list/ProvinceColdHousesList.js new file mode 100644 index 0000000..480bf8c --- /dev/null +++ b/src/features/province/components/province-cold-houses-list/ProvinceColdHousesList.js @@ -0,0 +1,74 @@ +import React, { useEffect, useState } from "react"; +import { Grid } from "../../../../components/grid/Grid"; +import ResponsiveTable from "../../../../components/responsive-table/ResponsiveTable"; +import { Tab, Tabs } from "@mui/material"; +import { ProvinceColdHousesKillHouses } from "../province-cold-houses-killhouses/ProvinceColdHousesKillHouses"; +import { ProvinceColdHousesStewards } from "../province-cold-houses-stewards/ProvinceColdHousesStewards"; +import { useDispatch } from "react-redux"; +import { provinceGetColdHousesDashboard } from "../../services/province-cold-houses"; + +export const ProvinceColdHousesList = () => { + const [value, setValue] = useState(0); + + const handleChange = (event, newValue) => { + setValue(newValue); + }; + const [dashboardData, setDashboardData] = useState([]); + const dispatch = useDispatch(); + + useEffect(() => { + dispatch(provinceGetColdHousesDashboard()).then((r) => { + setDashboardData(r.payload.data); + }); + }, [dispatch]); + + return ( + + + + + + + + + + + {value === 0 && } + {value === 1 && } + + ); +}; diff --git a/src/features/province/components/province-cold-houses-operations/ProvinceColdHousesOperations.js b/src/features/province/components/province-cold-houses-operations/ProvinceColdHousesOperations.js new file mode 100644 index 0000000..434aa06 --- /dev/null +++ b/src/features/province/components/province-cold-houses-operations/ProvinceColdHousesOperations.js @@ -0,0 +1,51 @@ +import React from "react"; +import { useLocation } from "react-router-dom"; +import { Grid } from "../../../../components/grid/Grid"; +import { SPACING } from "../../../../data/spacing"; +import { NavLink } from "../../../../components/nav-link/NavLink"; +import LinkItem from "../../../../components/link-item/LinkItem"; +import AcUnitIcon from "@mui/icons-material/AcUnit"; +import { + ROUTE_ADMINX_COLD_HOUSES_MANAGEMENT, + ROUTE_PROVINCE_COLD_HOUSES_MANAGEMENT, + ROUTE_SUPER_ADMIN_COLD_HOUSES_MANAGEMENT, +} from "../../../../routes/routes"; +import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl"; + +export const ProvinceColdHousesOperations = () => { + const { pathname } = useLocation(); + + return ( + + + + + } + title="سردخانه ها" + description="سردخانه ها" + /> + + + + + ); +}; diff --git a/src/features/province/components/province-cold-houses-stewards/ProvinceColdHousesStewards.js b/src/features/province/components/province-cold-houses-stewards/ProvinceColdHousesStewards.js new file mode 100644 index 0000000..53985cb --- /dev/null +++ b/src/features/province/components/province-cold-houses-stewards/ProvinceColdHousesStewards.js @@ -0,0 +1,205 @@ +import React, { useEffect, useState } from "react"; +import { Button, IconButton, TextField, Tooltip } from "@mui/material"; +import { useDispatch } from "react-redux"; +import axios from "axios"; +import ResponsiveTable from "../../../../components/responsive-table/ResponsiveTable"; +import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl"; +import { + DRAWER, + LOADING_END, + LOADING_START, +} from "../../../../lib/redux/slices/appSlice"; +import { Grid } from "../../../../components/grid/Grid"; +import { ProvinceColdHousesListAddColdHouse } from "../province-cold-houses-list-add-cold-house/ProvinceColdHousesListAddColdHouse"; +import { useNavigate } from "react-router-dom"; +import { + ROUTE_ADMINX_COLD_HOUSES_MANAGEMENT, + ROUTE_PROVINCE_COLD_HOUSES_MANAGEMENT, + ROUTE_SUPER_ADMIN_COLD_HOUSES_MANAGEMENT, +} from "../../../../routes/routes"; +import { RiSearchLine } from "react-icons/ri"; +import RemoveRedEyeIcon from "@mui/icons-material/RemoveRedEye"; + +export const ProvinceColdHousesStewards = () => { + const dispatch = useDispatch(); + const navigate = useNavigate(); + const handleTextChange = (event) => { + setTextValue(event.target.value); + }; + + const [data, setData] = useState([]); + const [totalRows, setTotalRows] = useState(0); + const [perPage, setPerPage] = useState(10); + const [textValue, setTextValue] = useState(""); + const [page, setPage] = useState(1); + const [tableData, setTableData] = useState([]); + + const fetchApiData = async (page) => { + let response; + dispatch(LOADING_START()); + response = await axios.get( + `stewards-for-cold-house/?search=filter&value=${textValue}&role=${getRoleFromUrl()}&page=${page}&page_size=${perPage}&total=true` + ); + dispatch(LOADING_END()); + setData(response.data.results); + setTotalRows(response.data.count); + }; + + const handlePageChange = (page) => { + fetchApiData(page); + setPage(page); + }; + + const handlePerRowsChange = (perRows) => { + setPerPage(perRows); + setPage(1); + }; + + const updateTable = () => { + fetchApiData(page !== 0 ? page : 1); + }; + + useEffect(() => { + const d = data?.map((item, i) => { + // const coldHouses = item?.coldHouses?.map((option, index) => { + // return [ + // index + 1, + // option?.name, + // option?.city, + // option?.address, + // option?.totalInputWeight?.toLocaleString(), + // option?.totalAllocatedWeight?.toLocaleString(), + // option?.totalRemainWeight?.toLocaleString(), + // ]; + // }); + + return [ + page === 1 ? i + 1 : i + perPage * (page - 1) + 1, + item?.fullname, + item?.mobile, + item?.city, + item?.coldHousesInfo?.totalColdHouses?.toLocaleString(), + item?.coldHousesInfo?.totalInputWeight?.toLocaleString(), + item?.coldHousesInfo?.totalAllocatedWeight?.toLocaleString(), + item?.coldHousesInfo?.totalRemainWeight?.toLocaleString(), + + { + navigate( + (getRoleFromUrl() === "ProvinceOperator" + ? ROUTE_PROVINCE_COLD_HOUSES_MANAGEMENT + : getRoleFromUrl() === "AdminX" + ? ROUTE_ADMINX_COLD_HOUSES_MANAGEMENT + : ROUTE_SUPER_ADMIN_COLD_HOUSES_MANAGEMENT) + + "/" + + item?.key + + "/" + + item?.fullname + + "/" + + "steward" + ); + }} + > + + + , + ]; + }); + + setTableData(d); + }, [data]); + + useEffect(() => { + fetchApiData(1); + }, [dispatch, perPage]); + + const handleSubmit = async (event) => { + event.preventDefault(); + dispatch(LOADING_START()); + + try { + const response = await axios.get( + `stewards-for-cold-house/?role=${getRoleFromUrl()}&search=filter&value=${textValue}&page=${1}&page_size=${perPage}&total=true` + ); + setData(response.data.results); + setTotalRows(response.data.count); + dispatch(LOADING_END()); + } catch (error) { + console.error("Error fetching data:", error); + } + }; + + return ( + + + + +
    + + + +
    +
    + + +
    + ); +}; diff --git a/src/features/province/components/province-cold-houses/ProvinceColdHouses.js b/src/features/province/components/province-cold-houses/ProvinceColdHouses.js new file mode 100644 index 0000000..2278a22 --- /dev/null +++ b/src/features/province/components/province-cold-houses/ProvinceColdHouses.js @@ -0,0 +1,178 @@ +import React, { useContext, useEffect, useState } from "react"; +import { Button, TextField } from "@mui/material"; +import { DatePicker } from "@mui/x-date-pickers"; +import moment from "moment"; +import { useDispatch } from "react-redux"; +import axios from "axios"; +import { RiSearchLine } from "react-icons/ri"; +import { AppContext } from "../../../../contexts/AppContext"; +import { + LOADING_END, + LOADING_START, +} from "../../../../lib/redux/slices/appSlice"; +import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl"; +import { Grid } from "../../../../components/grid/Grid"; +import ResponsiveTable from "../../../../components/responsive-table/ResponsiveTable"; + +export const ProvinceColdHouses = () => { + const [, , selectedDate1, setSelectedDate1, selectedDate2, setSelectedDate2] = + useContext(AppContext); + const dispatch = useDispatch(); + useEffect(() => { + const currentDate = moment(new Date()).format("YYYY-MM-DD"); + setSelectedDate1(currentDate); + setSelectedDate2(currentDate); + }, []); + + const handleTextChange = (event) => { + setTextValue(event.target.value); + }; + + const [data, setData] = useState([]); + const [totalRows, setTotalRows] = useState(0); + const [perPage, setPerPage] = useState(10); + const [textValue, setTextValue] = useState(""); + const [page, setPage] = useState(1); + const [tableData, setTableData] = useState([]); + + const fetchApiData = async (page) => { + let response; + dispatch(LOADING_START()); + response = await axios.get( + `kill-house-cold-house-allocations-info/?search=filter&value=${textValue}&role=${getRoleFromUrl()}&date1=${selectedDate1}&date2=${selectedDate2}&page=${page}&page_size=${perPage}` + ); + dispatch(LOADING_END()); + setData(response.data.results); + setTotalRows(response.data.count); + }; + + const handlePageChange = (page) => { + fetchApiData(page); + setPage(page); + }; + + const handlePerRowsChange = (perRows) => { + setPerPage(perRows); + setPage(1); + }; + + // const updateTable = () => { + // fetchApiData(page !== 0 ? page : 1); + // }; + + useEffect(() => { + const d = data?.map((item, i) => { + return [ + page === 1 ? i + 1 : i + perPage * (page - 1) + 1, + item?.name, + item?.info?.totalAllocationsCount?.toLocaleString(), + item?.info?.totalAllocationsWeight?.toLocaleString(), + item?.info?.totalSelfAllocationsCount?.toLocaleString(), + item?.info?.totalSelfAllocationsWeight?.toLocaleString(), + item?.info?.totalOtherAllocationsCount?.toLocaleString(), + item?.info?.totalOtherAllocationsWeight?.toLocaleString(), + ]; + }); + + setTableData(d); + }, [data]); + + useEffect(() => { + fetchApiData(1); + }, [dispatch, selectedDate1, selectedDate2, perPage]); + + const handleSubmit = async (event) => { + event.preventDefault(); + dispatch(LOADING_START()); + + try { + const response = await axios.get( + `kill-house-cold-house-allocations-info/?role=${getRoleFromUrl()}&search=filter&value=${textValue}&date1=${selectedDate1}&date2=${selectedDate2}&page=${1}&page_size=${perPage}` + ); + setData(response.data.results); + setTotalRows(response.data.count); + dispatch(LOADING_END()); + } catch (error) { + console.error("Error fetching data:", error); + } + }; + + return ( + + + + ( + + )} + value={selectedDate1} + onChange={(e) => { + setSelectedDate1(moment(e).format("YYYY-MM-DD")); + }} + /> + + + ( + + )} + value={selectedDate2} + onChange={(e) => { + setSelectedDate2(moment(e).format("YYYY-MM-DD")); + }} + /> + + +
    + + + +
    +
    + + +
    + ); +}; diff --git a/src/features/province/components/province-create-allocate-steward-guild/ProvinceCreateAllocateStewardGuild.js b/src/features/province/components/province-create-allocate-steward-guild/ProvinceCreateAllocateStewardGuild.js new file mode 100644 index 0000000..c4d62e6 --- /dev/null +++ b/src/features/province/components/province-create-allocate-steward-guild/ProvinceCreateAllocateStewardGuild.js @@ -0,0 +1,370 @@ +import React, { useContext, useEffect, useState } from "react"; +import { useFormik } from "formik"; +import * as yup from "yup"; +import { + Button, + Checkbox, + FormControl, + FormControlLabel, + FormLabel, + MenuItem, + Radio, + RadioGroup, + TextField, +} from "@mui/material"; +import { useDispatch, useSelector } from "react-redux"; +import { provinceGetCitiesService } from "../../services/province-get-cities"; +import { provinceGetFieldOfWorks } from "../../services/ProvinceGetFieldOfWorks"; +import { provinceGetTypeActivity } from "../../services/provinceGetTypeActivity"; +import { SPACING } from "../../../../data/spacing"; +import { Grid } from "../../../../components/grid/Grid"; +import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl"; +import { provinceDispensersCreateSteward } from "../../services/province-dispensers-services"; +import { AppContext } from "../../../../contexts/AppContext"; +import { DRAWER } from "../../../../lib/redux/slices/appSlice"; + +const validationSchema = yup.object({ + mobile: yup + .string() + .required("شماره موبایل الزامی است") + .min(11, "شماره موبایل باید 11 رقم باشد") + .max(11, "شماره موبایل باید 11 رقم باشد") + .matches(/^09\d{9}$/, "شماره موبایل باید با 09 شروع شود و 11 رقم باشد"), + first_name: yup.string().required("نام الزامی است"), + last_name: yup.string().required("نام خانوادگی الزامی است"), + national_id: yup.string().required("کدملی الزامی است"), + postal_code: yup.string().required("کدپستی الزامی است"), + city: yup.string().required("شهر الزامی است"), + address: yup.string().required("آدرس الزامی است"), + guilds_id: yup.string().required("شناسه انجمن الزامی است"), + license_number: yup.string().required("شماره مجوز الزامی است"), + guilds_name: yup.string().required("نام انجمن الزامی است"), + type_activity: yup.string().required("نوع فعالیت الزامی است"), + area_activity: yup.string().required("حوزه فعالیت الزامی است"), + allocation_limit: yup.string().required("این فیلد الزامی است"), +}); + +export const ProvinceCreateAllocateStewardGuild = ({ + killHousekey, + type, + updateTable, + item, +}) => { + const dispatch = useDispatch(); + const [openNotif] = useContext(AppContext); + const { provinceGetCities, provinceGetAreActivity, provinceTypeActivity } = + useSelector((state) => state.provinceSlice); + + const formik = useFormik({ + initialValues: { + mobile: item ? item.user.mobile : "", + first_name: item ? item.user.firstName : "", + last_name: item ? item.user.lastName : "", + city: item ? item.address.city.name : "", + address: item ? item.address.address : "", + guilds_id: item ? item.guildsId : "", + license_number: item ? item.licenseNumber : "", + postal_code: item ? item.address.postalCode : "", + guilds_name: item ? item.guildsName : "", + type_activity: item ? item.typeActivity : "", + area_activity: item ? item.areaActivity : "", + steward: item ? item.steward : false, + national_id: item ? item.user.nationalId : "", + allocation_limit: item ? item.allocation_limit : "", + }, + validationSchema, + onSubmit: (values) => { + dispatch( + provinceDispensersCreateSteward({ + ...values, + role: getRoleFromUrl(), + allocation_type: value, + owner_key: killHousekey, + role_type: type, + }) + ).then((r) => { + if (r.payload.error) { + openNotif({ + vertical: "top", + horizontal: "center", + msg: r.payload.error, + severity: "error", + }); + } else { + updateTable(); + dispatch(DRAWER({ right: false, bottom: false, content: null })); + openNotif({ + vertical: "top", + horizontal: "center", + msg: "عملیات با موفقیت انجام شد.", + severity: "success", + }); + } + }); + }, + }); + + useEffect(() => { + dispatch(provinceGetCitiesService()); + dispatch(provinceGetFieldOfWorks()); + dispatch(provinceGetTypeActivity()); + }, []); + + const [value, setValue] = useState("forced"); + + const handleChangeRadioButton = (event) => { + setValue(event.target.value); + }; + + return ( +
    + + + + + + + + {provinceGetCities?.map((city) => ( + + {city.name} + + ))} + + + + + + + + + {provinceTypeActivity?.map((option) => ( + + {option.title} + + ))} + + + + {provinceGetAreActivity?.map((option) => ( + + {option.title} + + ))} + + + + + + + + + + + نوع تعهد + + + } + label="اجباری" + /> + } + label="اختیاری" + /> + + + + + {getRoleFromUrl() !== "Guilds" && ( + + } + label="مباشر" + /> + )} + + {formik.errors.steward &&
    {formik.errors.steward}
    } + + +
    +
    + ); +}; diff --git a/src/features/province/components/province-create-killhouse/ProvinceCreateKillhouse.js b/src/features/province/components/province-create-killhouse/ProvinceCreateKillhouse.js new file mode 100644 index 0000000..8de5efd --- /dev/null +++ b/src/features/province/components/province-create-killhouse/ProvinceCreateKillhouse.js @@ -0,0 +1,234 @@ +import { + Button, + Checkbox, + FormControlLabel, + MenuItem, + TextField, +} from "@mui/material"; +import { useFormik } from "formik"; +import { useContext, useEffect } from "react"; +import { useDispatch, useSelector } from "react-redux"; +import { Grid } from "../../../../components/grid/Grid"; +import { AppContext } from "../../../../contexts/AppContext"; +import { SPACING } from "../../../../data/spacing"; +import { DRAWER } from "../../../../lib/redux/slices/appSlice"; +import { Yup } from "../../../../lib/yup/yup"; +import { slaughterGetKillerKillhousesService } from "../../../slaughter-house/services/slaughter-get-killers-killhouses"; +import { provinceCreateKillhouseService } from "../../services/province-create-killhouse"; +import { provinceGetCitiesService } from "../../services/province-get-cities"; +import { provinceGetSlaughterhousesQuotaService } from "../../services/province-get-slaughterhouses-quota"; + +const initialValues = { + city: "", + mobile: "", + password: "", + first_name: "", + last_name: "", + national_id: "", + address: "", + name: "", + killer: false, +}; + +const validationSchema = Yup.object().shape({ + city: Yup.string().required("City is required"), + mobile: Yup.string().required("Mobile is required"), + password: Yup.string().required("Password is required"), + first_name: Yup.string().required("First Name is required"), + last_name: Yup.string().required("Last Name is required"), + national_id: Yup.string().required("National ID is required"), + address: Yup.string().required("Address is required"), + name: Yup.string().required("Name is required"), +}); + +export const ProvinceCreateKillhouse = () => { + const dispatch = useDispatch(); + const [openNotif] = useContext(AppContext); + const { provinceGetCities } = useSelector((state) => state.provinceSlice); + const formik = useFormik({ + initialValues, + validationSchema, + onSubmit: (values) => { + // Handle form submission here + // console.log(values); + const { + first_name, + last_name, + mobile, + city, + password, + national_id, + address, + name, + killer, + } = values; + dispatch( + provinceCreateKillhouseService({ + city, + mobile, + password, + first_name, + last_name, + national_id, + address, + name, + killer, + }) + ).then((r) => { + if (r.payload.error) { + openNotif({ + vertical: "top", + horizontal: "center", + msg: r.payload.error, + severity: "error", + }); + } else { + dispatch(provinceGetSlaughterhousesQuotaService()); + dispatch(slaughterGetKillerKillhousesService()); + dispatch(DRAWER({ right: false, bottom: false, content: null })); + openNotif({ + vertical: "top", + horizontal: "center", + msg: "عملیات با موفقیت انجام شد.", + severity: "success", + }); + } + }); + }, + }); + + useEffect(() => { + dispatch(provinceGetCitiesService()); + }, []); + + return ( +
    +
    + + + + + + + + {provinceGetCities?.map((city) => ( + + {city.name} + + ))} + + + + + + + + + + + + } + label="کشتارکن می باشد" + /> + + + +
    +
    + ); +}; diff --git a/src/features/province/components/province-daily-bars-details/ProvinceDailyBarsDetails.js b/src/features/province/components/province-daily-bars-details/ProvinceDailyBarsDetails.js new file mode 100644 index 0000000..f683f67 --- /dev/null +++ b/src/features/province/components/province-daily-bars-details/ProvinceDailyBarsDetails.js @@ -0,0 +1,405 @@ +import { + Button, + Checkbox, + TextField, + Tooltip, + Typography, +} from "@mui/material"; +import ToggleOffOutlinedIcon from "@mui/icons-material/ToggleOffOutlined"; +import ToggleOnIcon from "@mui/icons-material/ToggleOn"; +import axios from "axios"; +import { useContext, useEffect, useState } from "react"; +import { Grid } from "../../../../components/grid/Grid"; +import { PageTable } from "../../../../components/page-table/PageTable"; +import { SPACING } from "../../../../data/spacing"; +import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl"; +import { RiSearchLine } from "react-icons/ri"; +import { AppContext } from "../../../../contexts/AppContext"; +import { DatePicker } from "@mui/x-date-pickers"; +import moment from "moment"; +import { format } from "date-fns-jalali"; +import { RiFileExcel2Fill } from "react-icons/ri"; +import { useSelector } from "react-redux"; + +export const ProvinceDailyBarsDetails = ({ killhouseKey, type }) => { + const [, , selectedDate1, setSelectedDate1, selectedDate2, setSelectedDate2] = + useContext(AppContext); + const [openNotif] = useContext(AppContext); + const userKey = useSelector((state) => state.userSlice.userProfile.key); + + useEffect(() => { + const currentDate = moment(new Date()).format("YYYY-MM-DD"); + setSelectedDate1(currentDate); + setSelectedDate2(currentDate); + }, []); + + const [data, setData] = useState([]); + const [loading, setLoading] = useState(false); + const [totalRows, setTotalRows] = useState(0); + const [perPage, setPerPage] = useState(10); + const [withDate, setWithDate] = useState(false); + const [textValue, setTextValue] = useState(""); + + const handleTextChange = (event) => { + setTextValue(event.target.value); + }; + + const fetchApiData = async (page, textValue) => { + setLoading(true); + const response = await axios.get( + `kill_house_request_bar_management_wage/?search=filter&value=${textValue}&page=${page}&page_size=${perPage}&type=paid&kill_house_key=${killhouseKey}&role=${getRoleFromUrl()}&date1=${selectedDate1}&date2=${selectedDate2}` + ); + setData(response.data.results); + setTotalRows(response.data.count); + setLoading(false); + }; + + const handlePageChange = (page) => { + fetchApiData(page, textValue); + }; + + const handlePerRowsChange = async (newPerPage, page) => { + setLoading(true); + const response = await axios.get( + `kill_house_request_bar_management_wage/?search=filter&value=${textValue}&page=${page}&page_size=${newPerPage}&type=paid&kill_house_key=${killhouseKey}&role=${getRoleFromUrl()}&date1=${selectedDate1}&date2=${selectedDate2}` + ); + + setData(response.data.results); + setTotalRows(response.data.count); + setPerPage(newPerPage); + + setLoading(false); + }; + + useEffect(() => { + fetchApiData(1); + }, []); + + useEffect(() => { + fetchApiData(1); + }, [selectedDate1, selectedDate2, perPage, withDate]); + + const handleSubmit = async (event) => { + event.preventDefault(); + setLoading(true); + + try { + const response = await axios.get( + `kill_house_request_bar_management_wage/?search=filter&value=${textValue}&type=paid&kill_house_key=${killhouseKey}&role=${getRoleFromUrl()}&date1=${selectedDate1}&date2=${selectedDate2}` + ); + setData(response.data.results); + setTotalRows(response.data.count); + } catch (error) { + console.error("Error fetching data:", error); + } finally { + setLoading(false); + } + }; + + const columns = [ + { + name: "کد بار", + selector: (item) => { + return item.barCode; + }, + sortable: true, + wrap: true, + allowOverflow: true, + center: true, + // width: "90px", + }, + { + name: "خریدار", + selector: (item) => { + return `${item.killhouseUser?.name} (${item.killhouseUser?.killHouseOperator?.user?.mobile})`; + }, + sortable: true, + wrap: true, + allowOverflow: true, + center: true, + // width: "90px", + }, + { + name: "ماشین", + selector: (item) => { + return `${item.addCar.driver.typeCar} ${item.addCar.driver.pelak}`; + }, + sortable: true, + wrap: true, + allowOverflow: true, + center: true, + // width: "90px", + }, + { + name: "راننده", + selector: (item) => { + return `${item.addCar.driver.driverName} (${item.addCar.driver.driverMobile})`; + }, + sortable: true, + wrap: true, + allowOverflow: true, + center: true, + // width: "90px", + }, + { + name: "کد بهداشتی حمل و نقل", + selector: (item) => { + return item?.trafficCode; + }, + sortable: true, + wrap: true, + allowOverflow: true, + center: true, + // width: "90px", + }, + { + name: "نژاد", + selector: (item) => { + return item.poultryRequest.chickenBreed; + }, + sortable: true, + wrap: true, + allowOverflow: true, + center: true, + // width: "90px", + }, + { + name: "تعداد", + selector: (item) => item.quantity?.toLocaleString(), + sortable: true, + wrap: true, + allowOverflow: true, + center: true, + // width: "90px", + }, + { + name: "وزن بار", + selector: (item) => item?.weightInfo?.weight?.toLocaleString(), + sortable: true, + wrap: true, + allowOverflow: true, + center: true, + // width: "90px", + }, + { + name: "میانگین وزن", + selector: (item) => item?.weightInfo?.indexWeight?.toLocaleString(), + sortable: true, + wrap: true, + allowOverflow: true, + center: true, + // width: "90px", + }, + { + name: "مرغدار", + selector: (item) => + `${item.poultryRequest?.poultry?.unitName} (${item.poultryRequest.poultry?.user?.mobile})`, + sortable: true, + wrap: true, + allowOverflow: true, + center: true, + // width: "90px", + }, + { + name: "دامپزشک فارم", + selector: (item) => + item?.vetFarm?.vet?.user?.fullname + ? item?.vetFarm?.vet?.user?.fullname + + `(${item?.vetFarm?.vet?.user?.mobile})` + : "فاقد دامپزشک", + sortable: true, + wrap: true, + allowOverflow: true, + center: true, + // width: "90px", + }, + { + name: "کد رهگیری قرنطینه", + selector: (item) => (item?.clearanceCode ? item?.clearanceCode : "-"), + sortable: true, + wrap: true, + allowOverflow: true, + center: true, + // width: "90px", + }, + { + name: "محل کشتار", + selector: (item) => item.killPlace, + sortable: true, + wrap: true, + allowOverflow: true, + center: true, + // width: "90px", + }, + { + name: "شهر", + selector: (item) => item.poultryRequest.poultry.address.city.name, + sortable: true, + wrap: true, + allowOverflow: true, + center: true, + // width: "90px", + }, + { + name: "تاریخ کشتار", + selector: (item) => + item?.poultryRequest.sendDate + ? format(new Date(item?.poultryRequest.sendDate), "yyyy/MM/dd") + : "-", + sortable: true, + wrap: true, + allowOverflow: true, + center: true, + // width: "90px", + }, + { + name: "کد سفارش کشتار", + selector: (item) => item?.poultryRequest.orderCode, + sortable: true, + wrap: true, + allowOverflow: true, + center: true, + // width: "90px", + }, + { + name: "وضعیت", + selector: (item) => + item.vetState === "accepted" ? "تایید تخلیه" : "در انتظار تخلیه", + sortable: true, + wrap: true, + allowOverflow: true, + center: true, + // width: "90px", + }, + ]; + + return ( + + + بارها + + + } + checkedIcon={} + checked={withDate} + onChange={() => setWithDate(!withDate)} + color="primary" + size="large" + /> + + ( + + )} + value={selectedDate1} + onChange={(e) => { + setSelectedDate1(moment(e).format("YYYY-MM-DD")); + }} + /> + + + ( + + )} + value={selectedDate2} + onChange={(e) => { + setSelectedDate2(moment(e).format("YYYY-MM-DD")); + }} + /> + + + +
    + + + +
    + + {/* */} + + {/* */} + +
    + {true === false && ( + + )} +
    + ); +}; diff --git a/src/features/province/components/province-daily-bars/ProvinceDailyBars.js b/src/features/province/components/province-daily-bars/ProvinceDailyBars.js new file mode 100644 index 0000000..c977818 --- /dev/null +++ b/src/features/province/components/province-daily-bars/ProvinceDailyBars.js @@ -0,0 +1,268 @@ +import React, { useContext, useEffect, useState } from "react"; +import { + Button, + Checkbox, + FormControlLabel, + IconButton, + TextField, + Tooltip, +} from "@mui/material"; +import { DatePicker } from "@mui/x-date-pickers"; +import moment from "moment"; +import { useDispatch, useSelector } from "react-redux"; +import axios from "axios"; +import { RiFileExcel2Fill, RiSearchLine } from "react-icons/ri"; +import ResponsiveTable from "../../../../components/responsive-table/ResponsiveTable"; +import { Grid } from "../../../../components/grid/Grid"; +import { + LOADING_END, + LOADING_START, +} from "../../../../lib/redux/slices/appSlice"; +import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl"; +import { AppContext } from "../../../../contexts/AppContext"; +import { + ROUTE_ADMINX_PAYING_FEES_REQUESTS, + ROUTE_PROVINCE_PAYING_FEES_REQUESTS, + ROUTE_SUPER_ADMIN_PAYING_FEES_REQUESTS, +} from "../../../../routes/routes"; +import { useNavigate } from "react-router-dom"; +import VisibilityIcon from "@mui/icons-material/Visibility"; + +export const ProvinceDailyBars = () => { + const authToken = useSelector((state) => state.userSlice.authToken); + + const [, , selectedDate1, setSelectedDate1, selectedDate2, setSelectedDate2] = + useContext(AppContext); + const dispatch = useDispatch(); + useEffect(() => { + const currentDate = moment(new Date()).format("YYYY-MM-DD"); + setSelectedDate1(currentDate); + setSelectedDate2(currentDate); + }, []); + + const navigate = useNavigate(); + + const handleTextChange = (event) => { + setTextValue(event.target.value); + }; + const [withDate, setWithDate] = useState(false); + + const [data, setData] = useState([]); + const [totalRows, setTotalRows] = useState(0); + const [perPage, setPerPage] = useState(10); + const [textValue, setTextValue] = useState(""); + const [page, setPage] = useState(1); + const [tableData, setTableData] = useState([]); + + const fetchApiData = async (page) => { + let response; + dispatch(LOADING_START()); + response = await axios.get( + `kill-house-request-total-wage/?search=filter&value=${textValue}&page=${page}&role=${getRoleFromUrl()}&page_size=${perPage}${ + withDate ? `&date1=${selectedDate1}&date2=${selectedDate2}` : `` + }` + ); + + dispatch(LOADING_END()); + setData(response.data.results); + setTotalRows(response.data.count); + }; + + const handlePageChange = (page) => { + fetchApiData(page); + setPage(page); + }; + + const handlePerRowsChange = (perRows) => { + setPerPage(perRows); + setPage(1); + }; + + // const updateTable = () => { + // fetchApiData(page !== 0 ? page : 1); + // }; + + useEffect(() => { + const d = data?.map((item, i) => { + const type = item?.info?.killer ? "کشتارکن" : "کشتارگاه"; + + return [ + page === 1 ? i + 1 : i + perPage * (page - 1) + 1, + `${type} ${item?.info?.killHouseName} - ${item?.info?.killHouseFullname} (${item?.info?.killHouseMobile})`, + item?.info?.killHouseCity, + item?.info?.totalCount?.toLocaleString(), + item.info?.totalQuantity?.toLocaleString(), + item.info?.totalWeight?.toLocaleString(), + { + navigate( + `${ + getRoleFromUrl() === "SuperAdmin" + ? ROUTE_SUPER_ADMIN_PAYING_FEES_REQUESTS + : getRoleFromUrl() === "AdminX" + ? ROUTE_ADMINX_PAYING_FEES_REQUESTS + : ROUTE_PROVINCE_PAYING_FEES_REQUESTS + }/daily_bar/${item.key}` + ); + }} + > + + , + ]; + }); + + setTableData(d); + }, [data]); + + useEffect(() => { + fetchApiData(1); + }, [dispatch, selectedDate1, selectedDate2, perPage]); + + const handleSubmit = async (event) => { + event.preventDefault(); + dispatch(LOADING_START()); + + try { + const response = await axios.get( + `kill-house-request-total-wage/?search=filter&value=${textValue}${ + withDate ? `&date1=${selectedDate1}&date2=${selectedDate2}` : `` + }` + ); + + setData(response.data.results); + setTotalRows(response.data.count); + dispatch(LOADING_END()); + } catch (error) { + console.error("Error fetching data:", error); + } + }; + + return ( + + + + + setWithDate(!withDate)} + color="primary" + /> + } + /> + + + ( + + )} + value={selectedDate1} + onChange={(e) => { + setSelectedDate1(moment(e).format("YYYY-MM-DD")); + }} + /> + + + ( + + )} + value={selectedDate2} + onChange={(e) => { + setSelectedDate2(moment(e).format("YYYY-MM-DD")); + }} + /> + + + + +
    + + + +
    + + + + + +
    + + +
    + ); +}; diff --git a/src/features/province/components/province-dashboard-news/ProvinceDashboardNews.js b/src/features/province/components/province-dashboard-news/ProvinceDashboardNews.js new file mode 100644 index 0000000..0893497 --- /dev/null +++ b/src/features/province/components/province-dashboard-news/ProvinceDashboardNews.js @@ -0,0 +1,190 @@ +import React, { useContext, useState } from "react"; +import { Grid } from "../../../../components/grid/Grid"; +import { + Button, + TextField, + MenuItem, + Select, + FormControl, + InputLabel, + Chip, + Box, + Typography, + Paper, +} from "@mui/material"; +import { useDispatch } from "react-redux"; +import { provinceSubmitDashboardNewsService } from "../../services/province-dashboard-submit-news"; +import { AppContext } from "../../../../contexts/AppContext"; +import { styled } from "@mui/material/styles"; + +const roles = [ + { id: 1, role: "AdminX", name: "ادمین ایکس" }, + { id: 2, role: "SuperAdmin", name: "ادمین کل" }, + { id: 3, role: "ProvinceOperator", name: "مدیر اجرایی" }, +]; + +const StyledPaper = styled(Paper)(({ theme }) => ({ + padding: theme.spacing(4), + borderRadius: theme.shape.borderRadius * 2, + boxShadow: theme.shadows[4], + maxWidth: 800, + margin: "0 auto", +})); + +const StyledButton = styled(Button)(({ theme }) => ({ + marginTop: theme.spacing(3), + padding: theme.spacing(1.5), + fontSize: "1rem", +})); + +export const ProvinceDashboardNews = () => { + const [formData, setFormData] = useState({ + title: "", + text: "", + status: "", + selectedRoles: [], + }); + const dispatch = useDispatch(); + const [openNotif] = useContext(AppContext); + + const handleChange = (e) => { + const { name, value } = e.target; + setFormData((prev) => ({ ...prev, [name]: value })); + }; + + const handleRoleChange = (event) => { + const selectedValues = event.target.value; + setFormData((prev) => ({ + ...prev, + selectedRoles: Array.isArray(selectedValues) + ? selectedValues + : [selectedValues], + })); + }; + + const handleSubmit = () => { + const payload = { + role: formData.selectedRoles.map((role) => role.role), + title: formData.title, + text: formData.text, + status: formData.status, + }; + + dispatch(provinceSubmitDashboardNewsService(payload)).then((response) => { + if (response.error) { + openNotif({ + vertical: "top", + horizontal: "center", + msg: response.error, + severity: "error", + }); + } else { + openNotif({ + vertical: "top", + horizontal: "center", + msg: "عملیات با موفقیت انجام شد.", + severity: "success", + }); + setFormData({ + title: "", + text: "", + status: "", + selectedRoles: [], + }); + } + }); + }; + + return ( + + + + ایجاد اطلاعیه جدید + + + + + + + + + + + + + + + + + + نقش ها + + + + + + + ثبت اطلاعیه + + + + + + ); +}; diff --git a/src/features/province/components/province-direct-buy-operation/ProvinceDirectBuyOperation.js b/src/features/province/components/province-direct-buy-operation/ProvinceDirectBuyOperation.js new file mode 100644 index 0000000..717f05c --- /dev/null +++ b/src/features/province/components/province-direct-buy-operation/ProvinceDirectBuyOperation.js @@ -0,0 +1,397 @@ +import { Button, IconButton, Popover, Tooltip } from "@mui/material"; +import { Grid } from "../../../../components/grid/Grid"; + +import { useDispatch } from "react-redux"; +import { CLOSE_MODAL, OPEN_MODAL } from "../../../../lib/redux/slices/appSlice"; +import VpnKeyIcon from "@mui/icons-material/VpnKey"; +import { useContext, useState } from "react"; +import { AppContext } from "../../../../contexts/AppContext"; +import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl"; +import TuneIcon from "@mui/icons-material/Tune"; +import EditIcon from "@mui/icons-material/Edit"; +import DeleteIcon from "@mui/icons-material/Delete"; +import ThumbUpAltIcon from "@mui/icons-material/ThumbUpAlt"; +import DoNotDisturbIcon from "@mui/icons-material/DoNotDisturb"; +import DoneOutlineIcon from "@mui/icons-material/DoneOutline"; +import { provinceDeleteTradePanelService } from "../../services/province-delete-trade-panel"; +import TradePanelPurchaseModal from "../trade-panel-purchase-modal/TradePanelPurchaseModal"; +import { ProvinceMarketRequestFinalAcceptService } from "../../services/province-market-request-final-accept"; +import { ProvinceTradePanelEnterMarketCode } from "../province-trade-panel-enter-market-code/ProvinceTradePanelEnterMarketCode"; +export const ProvinceDirectBuyOperation = ({ + item, + updateTable, + updateTable2, +}) => { + const dispatch = useDispatch(); + const [openNotif] = useContext(AppContext); + + const [anchorEl, setAnchorEl] = useState(null); + + const handleClick = (event) => { + setAnchorEl(event.currentTarget); + }; + + const handleClose = () => { + setAnchorEl(null); + }; + + const open = Boolean(anchorEl); + const id = open ? "popover" : undefined; + + const updateAll = () => { + updateTable(); + updateTable2(); + }; + + return ( + + + + + +
    + + {getRoleFromUrl() === "KillHouse" && + item?.marketCodeStatus === true && + !item?.inputMarketCode && + item?.marketFinalAccept === true && ( + + { + handleClose(); + dispatch( + OPEN_MODAL({ + title: "ورود کد احراز", + content: ( + + ), + }) + ); + }} + > + + + + )} + + {getRoleFromUrl() === "KillHouse" && !item?.marketFinalAccept && ( + + { + handleClose(); + dispatch( + OPEN_MODAL({ + title: "آیا مطمئن هستید؟", + content: ( + + + + + ), + }) + ); + }} + > + + + + )} + + {getRoleFromUrl() === "KillHouse" && + item?.marketFinalAccept === false && ( + + { + handleClose(); + dispatch( + OPEN_MODAL({ + title: "ویرایش خرید", + content: ( + + ), + }) + ); + }} + > + + + + )} + {getRoleFromUrl() === "KillHouse" && ( + + { + handleClose(); + dispatch( + OPEN_MODAL({ + title: "آیا مطمئن هستید؟", + content: ( + + + + + ), + }) + ); + }} + > + + + + )} + + {(getRoleFromUrl() === "ProvinceOperator" || + getRoleFromUrl() === "SuperAdmin" || + getRoleFromUrl() === "AdminX") && ( + + { + handleClose(); + dispatch( + OPEN_MODAL({ + title: "آیا مطمئن هستید؟", + content: ( + + + + + ), + }) + ); + }} + > + + + + )} + + {(getRoleFromUrl() === "ProvinceOperator" || + getRoleFromUrl() === "SuperAdmin" || + getRoleFromUrl() === "AdminX") && ( + + { + handleClose(); + dispatch( + OPEN_MODAL({ + title: "آیا مطمئن هستید؟", + content: ( + + + + + ), + }) + ); + }} + > + + + + )} + +
    +
    +
    + ); +}; diff --git a/src/features/province/components/province-dispencer-sale-distribution/ProvinceDispencerSaleDistribution.js b/src/features/province/components/province-dispencer-sale-distribution/ProvinceDispencerSaleDistribution.js new file mode 100644 index 0000000..533f999 --- /dev/null +++ b/src/features/province/components/province-dispencer-sale-distribution/ProvinceDispencerSaleDistribution.js @@ -0,0 +1,336 @@ +import { useContext, useEffect, useState } from "react"; +import { AppContext } from "../../../../contexts/AppContext"; +import { useDispatch, useSelector } from "react-redux"; +import moment from "moment"; +import { Button, Checkbox, Tab, Tabs, TextField, Tooltip } from "@mui/material"; +import axios from "axios"; +import { RiFileExcel2Fill } from "react-icons/ri"; +import { Grid } from "../../../../components/grid/Grid"; +import ResponsiveTable from "../../../../components/responsive-table/ResponsiveTable"; +import { DatePicker } from "@mui/x-date-pickers"; +import { ProvinceDispenserSaleOut } from "../province-dispenser-sale-out/ProvinceDispenserSaleOut"; +import ToggleOffOutlinedIcon from "@mui/icons-material/ToggleOffOutlined"; +import ToggleOnIcon from "@mui/icons-material/ToggleOn"; +import { SPACING } from "../../../../data/spacing"; +import { ProvinceSaleInDispenser } from "../province-sale-dispenser/ProvinceSaleInDispenser"; +import { provinceGetDispenserSlaughterToStewardDashboardService } from "../../services/province-dispenser-slaughter-get-steward-service"; +import { + LOADING_END, + LOADING_START, +} from "../../../../lib/redux/slices/appSlice"; +import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl"; +import { ProvinceDispenserSegmentation } from "../province-dispenser-segmentation/ProvinceDispenserSegmentation"; + +export const ProvinceDispencerSaleDistribution = () => { + const [data, setData] = useState([]); + const [withDate, setWithDate] = useState(false); + const [dashboardData, setDashboardData] = useState([]); + const [openNotif] = useContext(AppContext); + const [value, setValue] = useState(0); + const [page, setPage] = useState(1); + const [totalRows, setTotalRows] = useState(0); + const [perPage, setPerPage] = useState(10); + const [tableData, setTableData] = useState([]); + + const userKey = useSelector((state) => state.userSlice.userProfile.key); + const [, , selectedDate1, setSelectedDate1, selectedDate2, setSelectedDate2] = + useContext(AppContext); + + const handleChange = (event, newValue) => { + setValue(newValue); + }; + + const dispatch = useDispatch(); + + const fetchApiData = async (page) => { + dispatch(LOADING_START()); + try { + const response = await axios.get( + `/total-steward-dashboard-detail/?&role=${getRoleFromUrl()}&page=${page}&page_size=${perPage}${ + withDate ? `&date1=${selectedDate1}&date2=${selectedDate2}` : `` + }` + ); + setData(response.data.results); + setTotalRows(response.data.count); + } catch (error) { + console.error("Error fetching data:", error); + } finally { + dispatch(LOADING_END()); + } + }; + + const fetchDashboardData = () => { + dispatch( + provinceGetDispenserSlaughterToStewardDashboardService({ + selectedDate1: withDate ? selectedDate1 : null, + selectedDate2: withDate ? selectedDate2 : null, + }) + ).then((r) => { + setDashboardData(r.payload.data); + }); + }; + + const fetchTableData = () => { + const d = data?.map((item, i) => { + return [ + page === 1 ? i + 1 : i + perPage * (page - 1) + 1, + `${item?.user?.fullname?.toLocaleString()} ${item?.user?.mobile?.toLocaleString()}`, + `${item?.steward ? "مباشر" : "صنف"} `, + item?.address?.city?.name || item?.user?.cityName, + item?.wareHouseInfo?.totalBarsWeight?.toLocaleString(), + item?.wareHouseInfo?.totalEnteredBarsWeight?.toLocaleString(), + item?.wareHouseInfo?.totalOutputWeight?.toLocaleString(), + item?.wareHouseInfo?.totalRemainWeight?.toLocaleString(), + item?.wareHouseInfo?.totalRemainGovernmentalWeight?.toLocaleString(), + item?.wareHouseInfo?.totalRemainFreeWeight?.toLocaleString(), + item?.wareHouseInfo?.inputBarsWeight?.toLocaleString(), + item?.wareHouseInfo?.freeBarsWeight?.toLocaleString(), + item?.wareHouseInfo?.inProvinceBarsWeight?.toLocaleString(), + item?.wareHouseInfo?.outProvinceBarsWeight?.toLocaleString(), + item?.wareHouseInfo?.totalOutputGovernmentalWeight?.toLocaleString(), + item?.wareHouseInfo?.totalOutputFreeWeight?.toLocaleString(), + item?.wareHouseInfo?.lastTotalRemainWeight?.toLocaleString(), + item?.wareHouseInfo?.lastTotalRemainGovernmentalWeight?.toLocaleString(), + item?.wareHouseInfo?.lastTotalRemainFreeWeight?.toLocaleString(), + item?.wareHouseInfo?.segmentationsWeight?.toLocaleString(), + ]; + }); + setTableData(d); + }; + + useEffect(() => { + if (value === 0) { + fetchApiData(page); + fetchDashboardData(); + } + }, [value]); + + useEffect(() => { + if (value === 0) { + fetchApiData(page); + fetchDashboardData(); + } + }, [dispatch, selectedDate1, selectedDate2, perPage, withDate]); + + useEffect(() => { + if (value === 0) { + fetchTableData(); + } + }, [data, perPage]); + + const handlePageChange = (page) => { + if (value === 0) { + fetchApiData(page); + setPage(page); + } + }; + + const handlePerRowsChange = (perRows) => { + if (value === 0) { + setPerPage(perRows); + setPage(1); + } + }; + + return ( + + + + + + + + + + + + + {value === 0 && ( + <> + + + } + checkedIcon={} + checked={withDate} + onChange={() => setWithDate(!withDate)} + color="primary" + size="large" + /> + + ( + + )} + value={selectedDate1} + onChange={(e) => { + setSelectedDate1(moment(e).format("YYYY-MM-DD")); + }} + /> + + + ( + + )} + value={selectedDate2} + onChange={(e) => { + setSelectedDate2(moment(e).format("YYYY-MM-DD")); + }} + /> + + + + + + + + + + + + )} + + {value === 1 && } + + {value === 2 && } + + {value === 3 && } + + ); +}; diff --git a/src/features/province/components/province-dispenser-accepted-sale-with-in-province/ProvinceDispenserAcceptedSaleWithInProvince.js b/src/features/province/components/province-dispenser-accepted-sale-with-in-province/ProvinceDispenserAcceptedSaleWithInProvince.js new file mode 100644 index 0000000..8343bf1 --- /dev/null +++ b/src/features/province/components/province-dispenser-accepted-sale-with-in-province/ProvinceDispenserAcceptedSaleWithInProvince.js @@ -0,0 +1,343 @@ +import { useContext, useEffect, useState } from "react"; +import { Grid } from "../../../../components/grid/Grid"; +import ResponsiveTable from "../../../../components/responsive-table/ResponsiveTable"; +import { useDispatch, useSelector } from "react-redux"; +import { + Button, + FormControl, + InputLabel, + MenuItem, + Select, + TextField, + Tooltip, +} from "@mui/material"; +import { + LOADING_END, + LOADING_START, +} from "../../../../lib/redux/slices/appSlice"; +import moment from "moment"; +import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl"; +import axios from "axios"; +import { DatePicker } from "@mui/x-date-pickers"; +import { formatJustDate, formatTime } from "../../../../utils/formatTime"; +import { RiSearchLine } from "react-icons/ri"; +import { ProvinceDispenserSaleWithInInventory } from "../province-dispenser-sale-with-in-province-inventory/ProvinceDispenserSaleWithInInventory"; +import { AppContext } from "../../../../contexts/AppContext"; +import { provinceDispenserWithInGetDashboard } from "../../services/province-dispenser-with-in-sale-inventory-dashboard"; +import { ProvinceDispenserSaleWithInProvinceOperation } from "../province-dispenser-sale-with-in-province-operation/ProvinceDispenserSaleWithInProvinceOperation"; +import { RiFileExcel2Fill } from "react-icons/ri"; +import { provinceDispenserGetKillHouseService } from "../../services/province-dispenser-get-kill-house"; +import ShowImage from "../../../../components/show-image/ShowImage"; +import { getAllocationType } from "../../../../utils/getAllocationType"; + +export const ProvinceDispenserAcceptedSaleWithInProvince = ({ priceInfo }) => { + const dispatch = useDispatch(); + const [, , selectedDate1, setSelectedDate1, selectedDate2, setSelectedDate2] = + useContext(AppContext); + const [dashboardData, setDashboardData] = useState([]); + const [openNotif] = useContext(AppContext); + const userKey = useSelector((state) => state.userSlice.userProfile.key); + const [data, setData] = useState([]); + const [totalRows, setTotalRows] = useState(0); + const [perPage, setPerPage] = useState(10); + const [textValue, setTextValue] = useState(""); + const [page, setPage] = useState(1); + const [tableData, setTableData] = useState([]); + const [killHouses, setKillHouses] = useState([]); + const [selectedKillHouse, setSelectedKillHouse] = useState(null); + + const fetchApiData = async (page) => { + dispatch(LOADING_START()); + try { + const response = await axios.get( + `/in-province-allocation/?search=filter&value=${textValue}&role=${getRoleFromUrl()}&date1=${selectedDate1}&date2=${selectedDate2}&trash=false&page=${ + page || 1 + }&page_size=${perPage}&type=KillHouse${ + selectedKillHouse + ? `&kill_house_key=${selectedKillHouse}` + : "&kill_house_key=all" + }` + ); + setData(response.data.results); + setTotalRows(response.data.count); + } catch (error) { + console.error("Error fetching data:", error); + } finally { + dispatch(LOADING_END()); + } + }; + const fetchKillHouses = () => { + dispatch(provinceDispenserGetKillHouseService()).then((r) => { + setKillHouses(r.payload.data); + }); + }; + const handlePageChange = (page) => { + fetchApiData(page); + setPage(page); + }; + + const handleTextChange = (event) => { + setTextValue(event.target.value); + }; + + const getAllocationData = (item) => { + if (!item) return "-"; + + switch (item?.allocationType) { + case "killhouse_killhouse": + return `${item?.toKillHouse?.name || "-"} - ${ + item?.toKillHouse?.killHouseOperator?.user?.fullname || "-" + } (${item?.toKillHouse?.killHouseOperator?.user?.mobile || "-"})`; + case "killhouse_steward": + return `${item?.toStewards?.name || "-"} - ${ + item?.toStewards?.user?.fullname || "-" + } (${item?.toStewards?.user?.mobile || "-"})`; + case "killhouse_guild": + return `${item?.toGuilds?.guildsName || "-"} - ${ + item?.toGuilds?.user?.fullname || "-" + } (${item?.toGuilds?.user?.mobile || "-"})`; + case "ColdHouse": + return `${item?.toColdHouse?.name || "-"}`; + default: + return `${item?.toKillHouse?.name || "-"} - ${ + item?.toKillHouse?.killHouseOperator?.user?.fullname || "-" + } (${item?.toKillHouse?.killHouseOperator?.user?.mobile || "-"})`; + } + }; + + const handlePerRowsChange = (perRows) => { + setPerPage(perRows); + setPage(1); + }; + + const fetchDashboardData = () => { + dispatch( + provinceDispenserWithInGetDashboard({ + search: "filter", + role: getRoleFromUrl(), + selectedDate1, + selectedDate2, + kill_house_key: selectedKillHouse || "all", + trash: false, + }) + ).then((r) => { + setDashboardData(r.payload.data); + }); + }; + + useEffect(() => { + const d = data?.map((item, i) => { + return [ + page === 1 ? i + 1 : i + perPage * (page - 1) + 1, + item?.date ? formatTime(item?.date) : "-", + item?.productionDate ? formatJustDate(item?.productionDate) : "-", + item?.distributionType === "web" + ? "سایت" + : item?.distributionType === "app" + ? "موبایل" + : item?.distributionType === "pos" + ? "پوز" + : item?.distributionType, + getAllocationType(item), + `${item?.killHouse?.killHouseOperator?.user?.fullname?.toLocaleString()} ${item?.killHouse?.name?.toLocaleString()} ${ + item?.killHouse?.killHouseOperator?.user?.mobile?.toLocaleString() || + "-" + }`, + getAllocationData(item), + item?.sellType === "exclusive" ? "اختصاصی" : "آزاد", + item?.quota === "governmental" + ? "دولتی" + : item?.quota === "free" + ? "آزاد" + : "-", + item?.approvedPriceStatus ? "دولتی" : "آزاد", + (item?.amount?.toLocaleString() || "0") + " ریال", + (item?.totalAmount?.toLocaleString() || "0") + " ریال", + item?.weightOfCarcasses?.toLocaleString() || "0", + item?.reciverWeightOfCarcasses?.toLocaleString() || "0", + item?.loggedRegistrationCode || "-", + item?.registrationCode ? "ارسال شده" : "ارسال نشده", + , + item?.receiverState === "accepted" || item?.loggedRegistrationCode + ? "تایید شده" + : item?.receiverState === "rejected" + ? "رد شده" + : item?.activeExpireDateTime && !item?.loggedRegistrationCode + ? "در انتظار ورود کد احراز" + : "در انتظار تایید", + , + ]; + }); + setTableData(d); + }, [data, page, perPage, priceInfo]); + + useEffect(() => { + fetchApiData(1); + fetchDashboardData(); + }, [dispatch, selectedDate1, selectedDate2, perPage, selectedKillHouse]); + + useEffect(() => { + fetchKillHouses(); + }, [dispatch]); + + const handleSubmit = async (event) => { + event.preventDefault(); + fetchApiData(1); + fetchDashboardData(); + }; + + return ( + + + + + + + + ( + + )} + value={selectedDate1} + onChange={(newValue) => { + setSelectedDate1(moment(newValue).format("YYYY-MM-DD")); + }} + /> + + + ( + + )} + value={selectedDate2} + onChange={(newValue) => { + setSelectedDate2(moment(newValue).format("YYYY-MM-DD")); + }} + /> + + +
    + + کشتارگاه + + + + + + +
    + + + +
    + + +
    +
    + ); +}; diff --git a/src/features/province/components/province-dispenser-edit-sale-out/ProvinceDispenserEditSaleOut.js b/src/features/province/components/province-dispenser-edit-sale-out/ProvinceDispenserEditSaleOut.js new file mode 100644 index 0000000..1fc5b25 --- /dev/null +++ b/src/features/province/components/province-dispenser-edit-sale-out/ProvinceDispenserEditSaleOut.js @@ -0,0 +1,152 @@ +import { useContext } from "react"; +import { useDispatch } from "react-redux"; +import { AppContext } from "../../../../contexts/AppContext"; +import { Yup } from "../../../../lib/yup/yup"; +import { useFormik } from "formik"; +import { CLOSE_MODAL } from "../../../../lib/redux/slices/appSlice"; +import { Grid } from "../../../../components/grid/Grid"; +import { Button, TextField } from "@mui/material"; +import { NumberInput } from "../../../../components/number-format-custom/NumberFormatCustom"; +import moment from "moment"; +import { DatePicker } from "@mui/x-date-pickers"; +import { slaughterEditOutOfProvinceService } from "../../../slaughter-house/services/slaughterEditOutOfProvinceService"; +import { slaughterGetOutOfProvinceSells } from "../../../slaughter-house/services/slaughter-get-out-of-province-sells"; + +export const ProvinceDispenserEditSaleOut = ({ + editData, + fetchData, + fetchApiData, + fetchDashboardData, +}) => { + const dispatch = useDispatch(); + const [openNotif] = useContext(AppContext); + + const validationSchema = Yup.object({ + weight: Yup.number() + .required("این فیلد اجباری است!") + .min(1, "یک مقدار مثبت وارد کنید!"), + // .max( + // editData?.realWeightOfCarcasses || 0, + // "وزن وارد شده بیش از موجودی انبار است!" + // ), + quarantineCode: Yup.string().required("کد قرنطینه الزامی است"), + date: Yup.date().required("تاریخ الزامی است"), + }); + + const formik = useFormik({ + initialValues: { + weight: editData?.realWeightOfCarcasses || "", + quarantineCode: editData?.clearanceCode || "", + date: editData?.date ? moment(editData.date) : moment(), + }, + validationSchema, + enableReinitialize: true, + }); + + const successSubmit = () => { + dispatch(CLOSE_MODAL()); + openNotif({ + vertical: "top", + horizontal: "center", + msg: "وزن با موفقیت ویرایش شد.", + severity: "success", + }); + dispatch(slaughterGetOutOfProvinceSells()); + fetchApiData(1); + fetchDashboardData(); + }; + + return ( + + + + + { + formik.setFieldValue("date", value); + }} + onBlur={() => formik.setFieldTouched("date", true)} + renderInput={(params) => ( + + )} + /> + + + + ); +}; diff --git a/src/features/province/components/province-dispenser-edit-to-guild/ProvinceDispenserEditToGuild.js b/src/features/province/components/province-dispenser-edit-to-guild/ProvinceDispenserEditToGuild.js new file mode 100644 index 0000000..84b1228 --- /dev/null +++ b/src/features/province/components/province-dispenser-edit-to-guild/ProvinceDispenserEditToGuild.js @@ -0,0 +1,453 @@ +import { useContext, useEffect, useState } from "react"; +import { useDispatch } from "react-redux"; +import { AppContext } from "../../../../contexts/AppContext"; +import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl"; +import { slaughterGetProductsService } from "../../../slaughter-house/services/slaughter-inventory-gets"; +import { slaughterGetGuildsForAllocateService } from "../../../slaughter-house/services/slaughter-get-guilds-for-allocate"; +import { Yup } from "../../../../lib/yup/yup"; +import { useFormik } from "formik"; +import { CLOSE_MODAL } from "../../../../lib/redux/slices/appSlice"; +import moment from "moment"; +import { Grid } from "../../../../components/grid/Grid"; +import { DatePicker } from "@mui/x-date-pickers"; +import { + Autocomplete, + Button, + FormControl, + FormControlLabel, + InputAdornment, + Radio, + RadioGroup, + TextField, +} from "@mui/material"; +import { NumberInput } from "../../../../components/number-format-custom/NumberFormatCustom"; +import { + slaughterAllocateStewardService, + slaughterEditAllocateStewardService, +} from "../../../slaughter-house/services/slaughter-allocate-steward"; +import { fetchSlaughterBroadcastAndProducts } from "../../../slaughter-house/services/handle-fetch-slaughter-products"; + +export const ProvinceDispenserEditToGuild = ({ + item, + key, + sellerType, + buyerType, + allocationType, + sellType, + fetchApiData, + editData, + priceInfo, + coldHouseKey, + coldHouseItemKey, + remainWeight, + fetchDashboardData, +}) => { + const dispatch = useDispatch(); + const [productData, setProductData] = useState([]); + const [guildsData, setGuildsData] = useState([]); + const [productKey, setProductKey] = useState(null); + const [openNotif] = useContext(AppContext); + + const [value, setValue] = useState("own"); + + const handleChange = (event) => { + setValue(event.target.value); + setBuyerData({ + key: "", + item: "", + buyerType: "", + allocationType: "", + }); + }; + + const [sellGovernmental, setSellGovernmental] = useState( + priceInfo?.active ? "true" : "false" + ); + + const handleChangeSellGovernmental = (event) => { + setSellGovernmental(event.target.value); + if (event.target.value === "false") { + formik.setFieldValue("price", ""); + } + }; + + const [buyerData, setBuyerData] = useState({ + key, + item, + buyerType, + allocationType, + }); + + useEffect(() => { + if (getRoleFromUrl() === "Steward") { + setValue("free"); + } + }, []); + + useEffect(() => { + if (!editData) { + dispatch(slaughterGetProductsService()).then((r) => { + setProductData(r.payload.data); + }); + if (!item) { + dispatch( + slaughterGetGuildsForAllocateService({ + free: value === "free" ? true : false, + }) + ).then((r) => { + setGuildsData(r.payload.data); + }); + } + } + }, [dispatch, value]); + + const validationSchema = Yup.object({ + weight: Yup.number() + .required("این فیلد اجباری است!") + .min(1, "یک مقدار مثبت وارد کنید!"), + price: Yup.number() + .required("این فیلد اجباری است!") + .min(1, "یک مقدار مثبت وارد کنید!"), + wholePrice: Yup.number() + .required("این فیلد اجباری است!") + .min(1, "یک مقدار مثبت وارد کنید!"), + }); + + const formik = useFormik({ + initialValues: { + weight: editData?.realWeightOfCarcasses || "", + wholePrice: editData?.totalAmount || "", + price: editData?.amount || "", + }, + validationSchema, + }); + + useEffect(() => { + formik.validateForm(); + }, []); + + useEffect(() => { + if (sellGovernmental === "false") { + if (formik.values.weight && formik.values.price) { + formik.setFieldValue( + "wholePrice", + formik.values.price * formik.values.weight + ); + } + } else { + if (priceInfo?.active && formik.values.weight) { + formik.setFieldValue( + "wholePrice", + priceInfo?.killHousePrice * formik.values.weight + ); + } + } + }, [formik.values.price, formik.values.weight, sellGovernmental]); + + useEffect(() => { + if (priceInfo?.active && sellGovernmental === "true") { + formik.setFieldValue("price", priceInfo?.killHousePrice); + } + }, [sellGovernmental]); + + const successSubmit = () => { + dispatch(CLOSE_MODAL()); + openNotif({ + vertical: "top", + horizontal: "center", + msg: "عملیات با موفقیت انجام شد.", + severity: "success", + }); + dispatch(fetchSlaughterBroadcastAndProducts()); + fetchDashboardData(); + fetchApiData(1); + }; + + const [selectedDate1, setSelectedDate1] = useState( + moment(new Date()).format("YYYY-MM-DD") + ); + + return ( + + {!editData && ( + } + value={selectedDate1} + onChange={(e) => { + setSelectedDate1(moment(e).format("YYYY-MM-DD")); + }} + /> + )} + + {!editData && !coldHouseKey && ( + + { + return { + data: i, + label: `${i.name}`, + }; + }) + : [] + } + onChange={(event, value) => { + setProductKey(value.data); + }} + renderInput={(params) => ( + + )} + /> + + )} + + {!editData && ( + + + } + label="صنوف اختصاصی" + /> + } + label="صنوف آزاد" + /> + + + )} + + {!item && !editData && ( + + { + return { + data: i, + label: `${i?.steward ? "مباشر" : "صنف"} ${ + i?.guildsName + } ${i?.user?.fullname} (${i?.user?.mobile})`, + }; + }) + : [] + } + onChange={(event, value) => { + setBuyerData({ + item: value?.data, + key: value?.data?.key, + allocationType: value?.data?.steward + ? "killhouse_steward" + : "killhouse_guild", + buyerType: value?.data?.steward ? "Steward" : "Guild", + }); + }} + renderInput={(params) => ( + + )} + /> + + )} + + + {priceInfo?.active && ( + + + } + label="قیمت مصوب" + /> + } + label="قیمت آزاد" + /> + + + )} + + ریال, + }} + value={formik.values.price} + error={formik.touched.price ? Boolean(formik.errors.price) : null} + onChange={formik.handleChange} + onBlur={formik.handleBlur} + helperText={ + formik.touched.price && Boolean(formik.errors.price) + ? formik.errors.price + : null + } + /> + + ریال, + }} + value={formik.values.wholePrice} + error={ + formik.touched.wholePrice ? Boolean(formik.errors.wholePrice) : null + } + onChange={formik.handleChange} + onBlur={formik.handleBlur} + helperText={ + formik.touched.wholePrice && Boolean(formik.errors.wholePrice) + ? formik.errors.wholePrice + : null + } + /> + + + + ); +}; diff --git a/src/features/province/components/province-dispenser-killhouses/ProvinceDispenserKillhouses.js b/src/features/province/components/province-dispenser-killhouses/ProvinceDispenserKillhouses.js new file mode 100644 index 0000000..dcbc011 --- /dev/null +++ b/src/features/province/components/province-dispenser-killhouses/ProvinceDispenserKillhouses.js @@ -0,0 +1,188 @@ +import React, { useEffect, useState } from "react"; +import { Button, IconButton, TextField, Tooltip } from "@mui/material"; +import { useDispatch } from "react-redux"; +import axios from "axios"; +import { Grid } from "../../../../components/grid/Grid"; +import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl"; +import ResponsiveTable from "../../../../components/responsive-table/ResponsiveTable"; +import { + LOADING_END, + LOADING_START, +} from "../../../../lib/redux/slices/appSlice"; +import { RiSearchLine } from "react-icons/ri"; +import { useNavigate } from "react-router-dom"; +import { + ROUTE_ADMINX_DISPENSERS_KILLHOUSES, + ROUTE_PROVINCE_DISPENSERS_KILLHOUSES, + ROUTE_SUPER_ADMIN_DISPENSERS_KILLHOUSES, +} from "../../../../routes/routes"; +import VisibilityIcon from "@mui/icons-material/Visibility"; + +export const ProvinceDispenserKillhouses = () => { + const dispatch = useDispatch(); + const handleTextChange = (event) => { + setTextValue(event.target.value); + }; + const navigate = useNavigate(); + + const [data, setData] = useState([]); + const [totalRows, setTotalRows] = useState(0); + const [perPage, setPerPage] = useState(10); + const [textValue, setTextValue] = useState(""); + const [page, setPage] = useState(1); + const [tableData, setTableData] = useState([]); + + const fetchApiData = async (page) => { + let response; + dispatch(LOADING_START()); + response = await axios.get( + `kill-house-distribution-management/?search=filter&value=${textValue}&role=${getRoleFromUrl()}&page=${page}&page_size=${perPage}` + ); + dispatch(LOADING_END()); + setData(response.data.results); + setTotalRows(response.data.count); + }; + + const handlePageChange = (page) => { + fetchApiData(page); + setPage(page); + }; + + const handlePerRowsChange = (perRows) => { + setPerPage(perRows); + setPage(1); + }; + + // const updateTable = () => { + // fetchApiData(page !== 0 ? page : 1); + // }; + + useEffect(() => { + const d = data?.map((item, i) => { + return [ + page === 1 ? i + 1 : i + (perPage * page) / 2 + 1, + `${item?.killHouseOperator?.user?.fullname} (${item?.killHouseOperator?.user?.mobile})`, + item?.name, + item?.killHouseOperator?.user?.city?.name, + item?.distributionInfo?.stewards.toLocaleString(), + item?.distributionInfo?.guilds.toLocaleString(), + item?.distributionInfo?.totalDailyWeight.toLocaleString(), + item?.distributionInfo?.forceDailyWeight.toLocaleString(), + item?.distributionInfo?.optionalDailyWeight.toLocaleString(), + item?.distributionInfo?.aveTotalDailyWeight.toLocaleString(), + + { + navigate( + getRoleFromUrl() === "AdminX" + ? ROUTE_ADMINX_DISPENSERS_KILLHOUSES + + "/" + + item?.key + + "/" + + item?.name + : getRoleFromUrl() === "SuperAdmin" + ? ROUTE_SUPER_ADMIN_DISPENSERS_KILLHOUSES + + "/" + + item?.key + + "/" + + item?.name + : getRoleFromUrl() === "ProvinceOperator" + ? ROUTE_PROVINCE_DISPENSERS_KILLHOUSES + + "/" + + item?.key + + "/" + + item?.name + : ROUTE_PROVINCE_DISPENSERS_KILLHOUSES + + "/" + + item?.key + + "/" + + item?.name + ); + }} + > + + + , + ]; + }); + + setTableData(d); + }, [data]); + + useEffect(() => { + fetchApiData(1); + }, [dispatch, perPage]); + + const handleSubmit = async (event) => { + event.preventDefault(); + dispatch(LOADING_START()); + + try { + const response = await axios.get( + `kill-house-distribution-management/?role=${getRoleFromUrl()}&search=filter&value=${textValue}&page=${1}&page_size=${perPage}` + ); + setData(response.data.results); + setTotalRows(response.data.count); + dispatch(LOADING_END()); + } catch (error) { + console.error("Error fetching data:", error); + } + }; + + return ( + + + +
    + + + +
    +
    + + +
    + ); +}; diff --git a/src/features/province/components/province-dispenser-rejected-sale-with-in-province/ProvinceDispenserRejectedSaleWithInProvince.js b/src/features/province/components/province-dispenser-rejected-sale-with-in-province/ProvinceDispenserRejectedSaleWithInProvince.js new file mode 100644 index 0000000..fafaa91 --- /dev/null +++ b/src/features/province/components/province-dispenser-rejected-sale-with-in-province/ProvinceDispenserRejectedSaleWithInProvince.js @@ -0,0 +1,336 @@ +import { useContext, useEffect, useState } from "react"; +import { Grid } from "../../../../components/grid/Grid"; +import ResponsiveTable from "../../../../components/responsive-table/ResponsiveTable"; +import { useDispatch, useSelector } from "react-redux"; +import { + Button, + FormControl, + InputLabel, + MenuItem, + Select, + TextField, + Tooltip, +} from "@mui/material"; +import { + LOADING_END, + LOADING_START, +} from "../../../../lib/redux/slices/appSlice"; +import moment from "moment"; +import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl"; +import axios from "axios"; +import { DatePicker } from "@mui/x-date-pickers"; +import { formatJustDate, formatTime } from "../../../../utils/formatTime"; +import { RiSearchLine } from "react-icons/ri"; +import { ProvinceDispenserSaleWithInInventory } from "../province-dispenser-sale-with-in-province-inventory/ProvinceDispenserSaleWithInInventory"; +import { AppContext } from "../../../../contexts/AppContext"; +import { provinceDispenserWithInGetDashboard } from "../../services/province-dispenser-with-in-sale-inventory-dashboard"; +import { ProvinceDispenserSaleWithInProvinceOperation } from "../province-dispenser-sale-with-in-province-operation/ProvinceDispenserSaleWithInProvinceOperation"; +import { RiFileExcel2Fill } from "react-icons/ri"; +import { provinceDispenserGetKillHouseService } from "../../services/province-dispenser-get-kill-house"; +import ShowImage from "../../../../components/show-image/ShowImage"; +import { getAllocationType } from "../../../../utils/getAllocationType"; + +export const ProvinceDispenserRejectedSaleWithInProvince = ({ priceInfo }) => { + const dispatch = useDispatch(); + const [, , selectedDate1, setSelectedDate1, selectedDate2, setSelectedDate2] = + useContext(AppContext); + const [dashboardData, setDashboardData] = useState([]); + const [openNotif] = useContext(AppContext); + const userKey = useSelector((state) => state.userSlice.userProfile.key); + const [data, setData] = useState([]); + const [totalRows, setTotalRows] = useState(0); + const [perPage, setPerPage] = useState(10); + const [textValue, setTextValue] = useState(""); + const [page, setPage] = useState(1); + const [tableData, setTableData] = useState([]); + const [killHouses, setKillHouses] = useState([]); + const [selectedKillHouse, setSelectedKillHouse] = useState(null); + + const fetchApiData = async (page) => { + dispatch(LOADING_START()); + try { + const response = await axios.get( + `/in-province-allocation/?search=filter&value=${textValue}&role=${getRoleFromUrl()}&date1=${selectedDate1}&date2=${selectedDate2}&trash=true&page=${ + page || 1 + }&page_size=${perPage}&type=KillHouse${ + selectedKillHouse + ? `&kill_house_key=${selectedKillHouse}` + : "&kill_house_key=all" + }` + ); + setData(response.data.results); + setTotalRows(response.data.count); + } catch (error) { + console.error("Error fetching data:", error); + } finally { + dispatch(LOADING_END()); + } + }; + const fetchKillHouses = () => { + dispatch(provinceDispenserGetKillHouseService()).then((r) => { + setKillHouses(r.payload.data); + }); + }; + const handlePageChange = (page) => { + fetchApiData(page); + setPage(page); + }; + + const handleTextChange = (event) => { + setTextValue(event.target.value); + }; + + const getAllocationData = (item) => { + if (!item) return "-"; + + switch (item?.allocationType) { + case "killhouse_killhouse": + return `${item?.toKillHouse?.name || "-"} - ${ + item?.toKillHouse?.killHouseOperator?.user?.fullname || "-" + } (${item?.toKillHouse?.killHouseOperator?.user?.mobile || "-"})`; + case "killhouse_steward": + return `${item?.toStewards?.name || "-"} - ${ + item?.toStewards?.user?.fullname || "-" + } (${item?.toStewards?.user?.mobile || "-"})`; + case "killhouse_guild": + return `${item?.toGuilds?.guildsName || "-"} - ${ + item?.toGuilds?.user?.fullname || "-" + } (${item?.toGuilds?.user?.mobile || "-"})`; + case "ColdHouse": + return `${item?.toColdHouse?.name || "-"}`; + default: + return `${item?.toKillHouse?.name || "-"} - ${ + item?.toKillHouse?.killHouseOperator?.user?.fullname || "-" + } (${item?.toKillHouse?.killHouseOperator?.user?.mobile || "-"})`; + } + }; + + const handlePerRowsChange = (perRows) => { + setPerPage(perRows); + setPage(1); + }; + + const fetchDashboardData = () => { + dispatch( + provinceDispenserWithInGetDashboard({ + search: "filter", + role: getRoleFromUrl(), + selectedDate1, + selectedDate2, + kill_house_key: selectedKillHouse || "all", + trash: true, + }) + ).then((r) => { + setDashboardData(r.payload.data); + }); + }; + + useEffect(() => { + const d = data?.map((item, i) => { + return [ + page === 1 ? i + 1 : i + perPage * (page - 1) + 1, + item?.date ? formatTime(item?.date) : "-", + item?.productionDate ? formatJustDate(item?.productionDate) : "-", + item?.distributionType === "web" + ? "سایت" + : item?.distributionType === "app" + ? "موبایل" + : item?.distributionType === "pos" + ? "پوز" + : item?.distributionType, + getAllocationType(item), + `${item?.killHouse?.killHouseOperator?.user?.fullname?.toLocaleString()} ${item?.killHouse?.name?.toLocaleString()} ${ + item?.killHouse?.killHouseOperator?.user?.mobile?.toLocaleString() || + "-" + }`, + getAllocationData(item), + item?.sellType === "exclusive" ? "اختصاصی" : "آزاد", + item?.quota === "governmental" + ? "دولتی" + : item?.quota === "free" + ? "آزاد" + : "-", + item?.approvedPriceStatus ? "دولتی" : "آزاد", + (item?.amount?.toLocaleString() || "0") + " ریال", + (item?.totalAmount?.toLocaleString() || "0") + " ریال", + item?.weightOfCarcasses?.toLocaleString() || "0", + item?.reciverWeightOfCarcasses?.toLocaleString() || "0", + item?.loggedRegistrationCode || "-", + item?.registrationCode ? "ارسال شده" : "ارسال نشده", + , + "حذف (احراز نشده)", + , + ]; + }); + setTableData(d); + }, [data, page, perPage, priceInfo]); + + useEffect(() => { + fetchApiData(1); + fetchDashboardData(); + }, [dispatch, selectedDate1, selectedDate2, perPage, selectedKillHouse]); + + useEffect(() => { + fetchKillHouses(); + }, [dispatch]); + + const handleSubmit = async (event) => { + event.preventDefault(); + fetchApiData(1); + fetchDashboardData(); + }; + + return ( + + + + + + + + ( + + )} + value={selectedDate1} + onChange={(newValue) => { + setSelectedDate1(moment(newValue).format("YYYY-MM-DD")); + }} + /> + + + ( + + )} + value={selectedDate2} + onChange={(newValue) => { + setSelectedDate2(moment(newValue).format("YYYY-MM-DD")); + }} + /> + + +
    + + کشتارگاه + + + + + + +
    + + + +
    + + +
    +
    + ); +}; diff --git a/src/features/province/components/province-dispenser-returned-sale-with-in-province/ProvinceDispenserReturnedSaleWithInProvince.js b/src/features/province/components/province-dispenser-returned-sale-with-in-province/ProvinceDispenserReturnedSaleWithInProvince.js new file mode 100644 index 0000000..db0d072 --- /dev/null +++ b/src/features/province/components/province-dispenser-returned-sale-with-in-province/ProvinceDispenserReturnedSaleWithInProvince.js @@ -0,0 +1,328 @@ +import { useContext, useEffect, useState } from "react"; +import { Grid } from "../../../../components/grid/Grid"; +import ResponsiveTable from "../../../../components/responsive-table/ResponsiveTable"; +import { useDispatch, useSelector } from "react-redux"; +import { + Button, + FormControl, + InputLabel, + MenuItem, + Select, + TextField, + Tooltip, +} from "@mui/material"; +import { + LOADING_END, + LOADING_START, +} from "../../../../lib/redux/slices/appSlice"; +import moment from "moment"; +import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl"; +import axios from "axios"; +import { DatePicker } from "@mui/x-date-pickers"; +import { formatJustDate, formatTime } from "../../../../utils/formatTime"; +import { RiSearchLine } from "react-icons/ri"; +import { ProvinceDispenserSaleWithInInventory } from "../province-dispenser-sale-with-in-province-inventory/ProvinceDispenserSaleWithInInventory"; +import { AppContext } from "../../../../contexts/AppContext"; +import { provinceDispenserWithInGetDashboard } from "../../services/province-dispenser-with-in-sale-inventory-dashboard"; +import { RiFileExcel2Fill } from "react-icons/ri"; +import { provinceDispenserGetKillHouseService } from "../../services/province-dispenser-get-kill-house"; +import ShowImage from "../../../../components/show-image/ShowImage"; +import { getAllocationType } from "../../../../utils/getAllocationType"; + +export const ProvinceDispenserReturnedSaleWithInProvince = ({ priceInfo }) => { + const dispatch = useDispatch(); + const [, , selectedDate1, setSelectedDate1, selectedDate2, setSelectedDate2] = + useContext(AppContext); + const [dashboardData, setDashboardData] = useState([]); + const [openNotif] = useContext(AppContext); + const userKey = useSelector((state) => state.userSlice.userProfile.key); + const [data, setData] = useState([]); + const [totalRows, setTotalRows] = useState(0); + const [perPage, setPerPage] = useState(10); + const [textValue, setTextValue] = useState(""); + const [page, setPage] = useState(1); + const [tableData, setTableData] = useState([]); + const [killHouses, setKillHouses] = useState([]); + const [selectedKillHouse, setSelectedKillHouse] = useState(null); + + const fetchApiData = async (page) => { + dispatch(LOADING_START()); + try { + const response = await axios.get( + `/in-province-allocation/?search=filter&value=${textValue}&role=${getRoleFromUrl()}&date1=${selectedDate1}&date2=${selectedDate2}&trash=false&return_trash=true&page=${ + page || 1 + }&page_size=${perPage}&type=KillHouse${ + selectedKillHouse + ? `&kill_house_key=${selectedKillHouse}` + : "&kill_house_key=all" + }` + ); + setData(response.data.results); + setTotalRows(response.data.count); + } catch (error) { + console.error("Error fetching data:", error); + } finally { + dispatch(LOADING_END()); + } + }; + const fetchKillHouses = () => { + dispatch(provinceDispenserGetKillHouseService()).then((r) => { + setKillHouses(r.payload.data); + }); + }; + const handlePageChange = (page) => { + fetchApiData(page); + setPage(page); + }; + + const handleTextChange = (event) => { + setTextValue(event.target.value); + }; + + const getAllocationData = (item) => { + if (!item) return "-"; + + switch (item?.allocationType) { + case "killhouse_killhouse": + return `${item?.toKillHouse?.name || "-"} - ${ + item?.toKillHouse?.killHouseOperator?.user?.fullname || "-" + } (${item?.toKillHouse?.killHouseOperator?.user?.mobile || "-"})`; + case "killhouse_steward": + return `${item?.toStewards?.name || "-"} - ${ + item?.toStewards?.user?.fullname || "-" + } (${item?.toStewards?.user?.mobile || "-"})`; + case "killhouse_guild": + return `${item?.toGuilds?.guildsName || "-"} - ${ + item?.toGuilds?.user?.fullname || "-" + } (${item?.toGuilds?.user?.mobile || "-"})`; + case "ColdHouse": + return `${item?.toColdHouse?.name || "-"}`; + default: + return `${item?.toKillHouse?.name || "-"} - ${ + item?.toKillHouse?.killHouseOperator?.user?.fullname || "-" + } (${item?.toKillHouse?.killHouseOperator?.user?.mobile || "-"})`; + } + }; + + const handlePerRowsChange = (perRows) => { + setPerPage(perRows); + setPage(1); + }; + + const fetchDashboardData = () => { + dispatch( + provinceDispenserWithInGetDashboard({ + search: "filter", + role: getRoleFromUrl(), + selectedDate1, + selectedDate2, + kill_house_key: selectedKillHouse || "all", + trash: false, + return_trash: true, + }) + ).then((r) => { + setDashboardData(r.payload.data); + }); + }; + + useEffect(() => { + const d = data?.map((item, i) => { + return [ + page === 1 ? i + 1 : i + perPage * (page - 1) + 1, + item?.date ? formatTime(item?.date) : "-", + item?.productionDate ? formatJustDate(item?.productionDate) : "-", + item?.distributionType === "web" + ? "سایت" + : item?.distributionType === "app" + ? "موبایل" + : item?.distributionType === "pos" + ? "پوز" + : item?.distributionType, + getAllocationType(item), + `${item?.killHouse?.killHouseOperator?.user?.fullname?.toLocaleString()} ${item?.killHouse?.name?.toLocaleString()} ${ + item?.killHouse?.killHouseOperator?.user?.mobile?.toLocaleString() || + "-" + }`, + getAllocationData(item), + item?.sellType === "exclusive" ? "اختصاصی" : "آزاد", + item?.quota === "governmental" + ? "دولتی" + : item?.quota === "free" + ? "آزاد" + : "-", + item?.approvedPriceStatus ? "دولتی" : "آزاد", + (item?.amount?.toLocaleString() || "0") + " ریال", + (item?.totalAmount?.toLocaleString() || "0") + " ریال", + item?.weightOfCarcasses?.toLocaleString() || "0", + item?.reciverWeightOfCarcasses?.toLocaleString() || "0", + item?.loggedRegistrationCode || "-", + item?.registrationCode ? "ارسال شده" : "ارسال نشده", + , + "برگشت خورده", + ]; + }); + setTableData(d); + }, [data, page, perPage, priceInfo]); + + useEffect(() => { + fetchApiData(1); + fetchDashboardData(); + }, [dispatch, selectedDate1, selectedDate2, perPage, selectedKillHouse]); + + useEffect(() => { + fetchKillHouses(); + }, [dispatch]); + + const handleSubmit = async (event) => { + event.preventDefault(); + fetchApiData(1); + fetchDashboardData(); + }; + + return ( + + + + + + + + ( + + )} + value={selectedDate1} + onChange={(newValue) => { + setSelectedDate1(moment(newValue).format("YYYY-MM-DD")); + }} + /> + + + ( + + )} + value={selectedDate2} + onChange={(newValue) => { + setSelectedDate2(moment(newValue).format("YYYY-MM-DD")); + }} + /> + + +
    + + کشتارگاه + + + + + + +
    + + + +
    + + +
    +
    + ); +}; diff --git a/src/features/province/components/province-dispenser-sale-out-dashboard/ProvinceDispenserSaleOutDashboard.js b/src/features/province/components/province-dispenser-sale-out-dashboard/ProvinceDispenserSaleOutDashboard.js new file mode 100644 index 0000000..b490e43 --- /dev/null +++ b/src/features/province/components/province-dispenser-sale-out-dashboard/ProvinceDispenserSaleOutDashboard.js @@ -0,0 +1,21 @@ +import { Grid } from "../../../../components/grid/Grid"; +import ResponsiveTable from "../../../../components/responsive-table/ResponsiveTable"; + +export const ProvinceDispenserSaleOutDashboard = ({ dashboardData }) => { + return ( + + + + ); +}; diff --git a/src/features/province/components/province-dispenser-sale-out-operation/ProvinceDispenserSaleOutOperation.js b/src/features/province/components/province-dispenser-sale-out-operation/ProvinceDispenserSaleOutOperation.js new file mode 100644 index 0000000..41945ee --- /dev/null +++ b/src/features/province/components/province-dispenser-sale-out-operation/ProvinceDispenserSaleOutOperation.js @@ -0,0 +1,130 @@ +import React, { useState } from "react"; +import { + IconButton, + List, + ListItemButton, + ListItemIcon, + ListItemText, + Popover, +} from "@mui/material"; +import TuneIcon from "@mui/icons-material/Tune"; +import EditOutlinedIcon from "@mui/icons-material/EditOutlined"; +import DeleteOutlineIcon from "@mui/icons-material/DeleteOutline"; +import { useDispatch } from "react-redux"; +import { Grid } from "../../../../components/grid/Grid"; +import { OPEN_MODAL } from "../../../../lib/redux/slices/appSlice"; +import { ProvinceDispenserEditSaleOut } from "../province-dispenser-edit-sale-out/ProvinceDispenserEditSaleOut"; +import { provinceDispenserDeleteService } from "../../../slaughter-house/services/province-dispenser-delete-sale-out"; + +export const ProvinceDispenserSaleOutOperation = ({ + fetchApiData, + item, + fetchData, + updateTable, + priceInfo, + fetchDashboardData, +}) => { + const [anchorEl, setAnchorEl] = useState(null); + const dispatch = useDispatch(); + + const handleClick = (event) => { + setAnchorEl(event.currentTarget); + }; + + const handleClose = () => { + setAnchorEl(null); + }; + + const handleEditClick = () => { + handleClose(); + dispatch( + OPEN_MODAL({ + title: "ویرایش تخصیص", + content: ( + + ), + // ), + }) + ); + }; + + const handleDeleteClick = () => { + dispatch( + provinceDispenserDeleteService({ + key: item.key, + }) + ).then(() => { + fetchDashboardData(); + fetchApiData(1); + setAnchorEl(null); + }); + }; + + const open = Boolean(anchorEl); + const id = open ? "popover" : undefined; + + return ( + + + + + + + + + + + + + + + + + + + + + + ); +}; diff --git a/src/features/province/components/province-dispenser-sale-out-province/ProvinceDispenserSaleInProvince.js b/src/features/province/components/province-dispenser-sale-out-province/ProvinceDispenserSaleInProvince.js new file mode 100644 index 0000000..af12fb4 --- /dev/null +++ b/src/features/province/components/province-dispenser-sale-out-province/ProvinceDispenserSaleInProvince.js @@ -0,0 +1,285 @@ +import { useContext, useEffect, useState } from "react"; +import { Grid } from "../../../../components/grid/Grid"; +import ResponsiveTable from "../../../../components/responsive-table/ResponsiveTable"; +import { useDispatch, useSelector } from "react-redux"; +import { + Button, + FormControl, + InputLabel, + MenuItem, + Select, + TextField, + Tooltip, +} from "@mui/material"; +import { + LOADING_END, + LOADING_START, +} from "../../../../lib/redux/slices/appSlice"; +import moment from "moment"; +import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl"; +import axios from "axios"; +import { DatePicker } from "@mui/x-date-pickers"; +import { formatJustDate } from "../../../../utils/formatTime"; +import { RiSearchLine } from "react-icons/ri"; +import { ProvinceDispenserSaleOutDashboard } from "../province-dispenser-sale-out-dashboard/ProvinceDispenserSaleOutDashboard"; +import { CheckCleanceCode } from "../../../../components/check-clearance-code/ChechClearanceCode"; +import { provinceDispenserWithOutGetDashboard } from "../../services/province-dispenser-sale-out-dashboard"; +import { AppContext } from "../../../../contexts/AppContext"; +import { ProvinceDispenserSaleOutOperation } from "../province-dispenser-sale-out-operation/ProvinceDispenserSaleOutOperation"; +import { RiFileExcel2Fill } from "react-icons/ri"; +import { provinceDispenserGetKillHouseService } from "../../services/province-dispenser-get-kill-house"; + +export const ProvinceDispenserSaleOutProvince = ({ + updateTable, + priceInfo, + remainWeight, +}) => { + const dispatch = useDispatch(); + const [, , selectedDate1, setSelectedDate1, selectedDate2, setSelectedDate2] = + useContext(AppContext); + // const [openNotif] = useContext(AppContext); + + const handleTextChange = (event) => { + setTextValue(event.target.value); + }; + + const [data, setData] = useState([]); + const [totalRows, setTotalRows] = useState(0); + const [perPage, setPerPage] = useState(10); + const [textValue, setTextValue] = useState(""); + const [page, setPage] = useState(1); + const [tableData, setTableData] = useState([]); + const [dashboardData, setDashboardData] = useState([]); + const userKey = useSelector((state) => state.userSlice.userProfile.key); + const [openNotif] = useContext(AppContext); + const [killHouses, setKillHouses] = useState([]); + const [selectedKillHouse, setSelectedKillHouse] = useState(null); + + const fetchApiData = async (page) => { + dispatch(LOADING_START()); + try { + const response = await axios.get( + `kill_house_free_sale_bar/?search=filter&value=${textValue}&role=${getRoleFromUrl()}&date1=${selectedDate1}&date2=${selectedDate2}&page=${ + page || 1 + }&page_size=${perPage}&type=dashboard${ + selectedKillHouse + ? `&kill_house_key=${selectedKillHouse}` + : "&kill_house_key=all" + }` + ); + setData(response.data.results); + setTotalRows(response.data.count); + } catch (error) { + console.error("Error fetching data:", error); + } finally { + dispatch(LOADING_END()); + } + }; + + const fetchDashboardData = () => { + dispatch( + provinceDispenserWithOutGetDashboard({ + search: "filter", + role: getRoleFromUrl(), + selectedDate1, + selectedDate2, + }) + ).then((r) => { + setDashboardData(r.payload?.data); + }); + }; + + const handlePerRowsChange = (perRows) => { + setPerPage(perRows); + setPage(1); + }; + + useEffect(() => { + const d = data?.map((item, i) => { + return [ + page === 1 ? i + 1 : i + perPage * (page - 1) + 1, + formatJustDate(item?.date) || "-", + `${item?.killHouse?.killHouseOperator?.user?.fullname} ${ + item?.killHouse?.name + } ${item?.killHouse?.killHouseOperator?.user?.mobile || "-"}`, + `${item?.buyerName} (${item?.buyerMobile})`, + item?.buyer ? `${item?.buyer?.unitName}` : `${item?.buyerName}`, + item?.province, + item?.city, + item?.clearanceCode && ( + + ), + item?.quarantineWeightOfCarcasses?.toLocaleString(), + item?.weightOfCarcasses?.toLocaleString(), + , + ]; + }); + setTableData(d); + }, [data, page, perPage, priceInfo]); + + const fetchKillHouses = () => { + dispatch(provinceDispenserGetKillHouseService()).then((r) => { + setKillHouses(r.payload.data); + }); + }; + const handlePageChange = (page) => { + fetchApiData(page); + setPage(page); + }; + useEffect(() => { + fetchApiData(1); + fetchDashboardData(); + fetchKillHouses(); + }, [dispatch, selectedDate1, selectedDate2, perPage, selectedKillHouse]); + + const handleSubmit = async (event) => { + event.preventDefault(); + fetchApiData(1); + fetchDashboardData(); + }; + + return ( + + + + + + + + ( + + )} + value={selectedDate1} + onChange={(newValue) => { + setSelectedDate1(moment(newValue).format("YYYY-MM-DD")); + }} + /> + + + ( + + )} + value={selectedDate2} + onChange={(newValue) => { + setSelectedDate2(moment(newValue).format("YYYY-MM-DD")); + }} + /> + + +
    + + کشتارگاه + + + + + + +
    + + + +
    + + +
    +
    + ); +}; diff --git a/src/features/province/components/province-dispenser-sale-out/ProvinceDispenserSaleOut.js b/src/features/province/components/province-dispenser-sale-out/ProvinceDispenserSaleOut.js new file mode 100644 index 0000000..a46dca6 --- /dev/null +++ b/src/features/province/components/province-dispenser-sale-out/ProvinceDispenserSaleOut.js @@ -0,0 +1,301 @@ +import { useDispatch, useSelector } from "react-redux"; +import { AppContext } from "../../../../contexts/AppContext"; +import { useContext, useEffect, useState } from "react"; +import { + LOADING_END, + LOADING_START, +} from "../../../../lib/redux/slices/appSlice"; +import axios from "axios"; +import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl"; +import { formatJustDate, formatTime } from "../../../../utils/formatTime"; +import { CheckCleanceCode } from "../../../../components/check-clearance-code/ChechClearanceCode"; +import { Grid } from "../../../../components/grid/Grid"; +import { StewardDispenserSaleOutDashboard } from "../../../guild/components/StewardDispenserSaleOutDashboard"; +import { DatePicker } from "@mui/x-date-pickers"; +import { + Autocomplete, + Button, + FormControl, + TextField, + Tooltip, +} from "@mui/material"; +import moment from "moment"; +import { RiFileExcel2Fill, RiSearchLine } from "react-icons/ri"; +import ResponsiveTable from "../../../../components/responsive-table/ResponsiveTable"; +import { provinceDispenserWithOutGetDashboard } from "../../services/province-deispenser-sale-out-get-dashboard"; +import { provinceDispenserGetStewardService } from "../../services/province-dispenser-get-steward"; +import { ProvinceDispenserStewardSaleOutOperation } from "../province-dispenser-steward-sale-out-operation/ProvinceDispenserStewardSaleOutOperation"; + +export const ProvinceDispenserSaleOut = ({ priceInfo }) => { + const { slaughterProducts } = useSelector( + (state) => state.slaughterSlice || {} + ); + const dispatch = useDispatch(); + const [, , selectedDate1, setSelectedDate1, selectedDate2, setSelectedDate2] = + useContext(AppContext); + + const handleTextChange = (event) => { + setTextValue(event.target.value); + }; + + const [data, setData] = useState([]); + const [totalRows, setTotalRows] = useState(0); + const [perPage, setPerPage] = useState(10); + const [textValue, setTextValue] = useState(""); + const [page, setPage] = useState(1); + const [tableData, setTableData] = useState([]); + const [dashboardData, setDashboardData] = useState([]); + const [steward, setSteward] = useState([]); + const [selectedSteward, setselectedSteward] = useState(null); + + const userKey = useSelector((state) => state.userSlice?.userProfile?.key); + const [openNotif] = useContext(AppContext); + const fetchApiData = async (page) => { + dispatch(LOADING_START()); + try { + const response = await axios.get( + `steward_free_sale_bar/?search=filter&value=${textValue}&role=${getRoleFromUrl()}&date1=${selectedDate1}&date2=${selectedDate2}&page=${ + page || 1 + }&page_size=${perPage}&type=dashboard${ + selectedSteward + ? `&steward_key=${selectedSteward}` + : "&steward_key=all" + }` + ); + setData(response.data?.results || []); + setTotalRows(response.data?.count || 0); + } catch (error) { + console.error("Error fetching data:", error); + } finally { + dispatch(LOADING_END()); + } + }; + const fetchsteward = () => { + dispatch(provinceDispenserGetStewardService()).then((r) => { + setSteward(r?.payload?.data || []); + }); + }; + const fetchDashboardData = () => { + dispatch( + provinceDispenserWithOutGetDashboard({ + search: "filter", + role: getRoleFromUrl(), + selectedDate1, + selectedDate2, + steward_key: selectedSteward || "all", + }) + ).then((r) => { + setDashboardData(r?.payload?.data || []); + }); + }; + const handlePageChange = (page) => { + fetchApiData(page); + setPage(page); + }; + + const handlePerRowsChange = (perRows) => { + setPerPage(perRows); + setPage(1); + }; + + useEffect(() => { + const d = Array.isArray(data) + ? data.map((item, i) => { + return [ + page === 1 ? i + 1 : i + perPage * (page - 1) + 1, + item?.date ? formatTime(item?.date) : "-", + item?.productionDate ? formatJustDate(item?.productionDate) : "-", + item?.distributionType === "web" + ? "سایت" + : item?.distributionType === "app" + ? "موبایل" + : item?.distributionType === "pos" + ? "پوز" + : item?.distributionType, + `${item?.steward?.guildsName?.toLocaleString()} ${item?.steward?.user?.fullname?.toLocaleString()} ${ + item?.steward?.user?.mobile?.toLocaleString() || "-" + }`, + `${item?.buyerName} (${item?.buyerMobile})`, + item?.buyer ? `${item?.buyer?.unitName}` : `${item?.buyerName}`, + item?.province, + item?.city, + item?.clearanceCode && ( + + ), + item?.quarantineWeightOfCarcasses?.toLocaleString(), + item?.weightOfCarcasses?.toLocaleString(), + , + ]; + }) + : []; + setTableData(d); + }, [data, page, perPage, priceInfo, slaughterProducts]); + useEffect(() => { + fetchApiData(1); + fetchDashboardData(); + fetchsteward(); + }, [dispatch, selectedDate1, selectedDate2, perPage, selectedSteward]); + + const handleSubmit = async (event) => { + event.preventDefault(); + fetchApiData(1); + fetchDashboardData(); + }; + + return ( + + + + + + + + ( + + )} + value={selectedDate1} + onChange={(newValue) => { + setSelectedDate1(moment(newValue).format("YYYY-MM-DD")); + }} + /> + + + ( + + )} + value={selectedDate2} + onChange={(newValue) => { + setSelectedDate2(moment(newValue).format("YYYY-MM-DD")); + }} + /> + + +
    + + + `(${option?.guildsName}) ${option?.user?.fullname}` + } + value={ + selectedSteward && Array.isArray(steward) + ? steward.find((item) => item?.key === selectedSteward) || + null + : null + } + onChange={(event, newValue) => { + setselectedSteward(newValue ? newValue.key : null); + }} + renderInput={(params) => ( + + )} + noOptionsText="مباشری یافت نشد" + isOptionEqualToValue={(option, value) => + option?.key === value?.key + } + /> + + + + + +
    + + + +
    + + +
    +
    + ); +}; diff --git a/src/features/province/components/province-dispenser-sale-with-in-province-inventory/ProvinceDispenserSaleWithInInventory.js b/src/features/province/components/province-dispenser-sale-with-in-province-inventory/ProvinceDispenserSaleWithInInventory.js new file mode 100644 index 0000000..c860197 --- /dev/null +++ b/src/features/province/components/province-dispenser-sale-with-in-province-inventory/ProvinceDispenserSaleWithInInventory.js @@ -0,0 +1,27 @@ +import { Grid } from "../../../../components/grid/Grid"; +import ResponsiveTable from "../../../../components/responsive-table/ResponsiveTable"; + +export const ProvinceDispenserSaleWithInInventory = ({ dashboardData }) => { + return ( + + + + ); +}; diff --git a/src/features/province/components/province-dispenser-sale-with-in-province-operation/ProvinceDispenserSaleWithInProvinceOperation.js b/src/features/province/components/province-dispenser-sale-with-in-province-operation/ProvinceDispenserSaleWithInProvinceOperation.js new file mode 100644 index 0000000..ba77a9f --- /dev/null +++ b/src/features/province/components/province-dispenser-sale-with-in-province-operation/ProvinceDispenserSaleWithInProvinceOperation.js @@ -0,0 +1,242 @@ +import React, { useContext, useState } from "react"; +import { + Button, + IconButton, + List, + ListItemButton, + ListItemIcon, + ListItemText, + Popover, +} from "@mui/material"; +import TuneIcon from "@mui/icons-material/Tune"; +import EditOutlinedIcon from "@mui/icons-material/EditOutlined"; +import DeleteOutlineIcon from "@mui/icons-material/DeleteOutline"; +import ReplayIcon from "@mui/icons-material/Replay"; +import { useDispatch } from "react-redux"; +import { Grid } from "../../../../components/grid/Grid"; +import { + slaughterDeleteAllocatedService, + slaughterReturnAllocatedService, +} from "../../../slaughter-house/services/salughter-delete-allocated"; +import { CLOSE_MODAL, OPEN_MODAL } from "../../../../lib/redux/slices/appSlice"; +import { ProvinceDispenserEditToGuild } from "../province-dispenser-edit-to-guild/ProvinceDispenserEditToGuild"; +import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl"; +import { AppContext } from "../../../../contexts/AppContext"; + +export const ProvinceDispenserSaleWithInProvinceOperation = ({ + fetchApiData, + item, + fetchData, + updateTable, + priceInfo, + fetchDashboardData, + isAccepted, +}) => { + const [anchorEl, setAnchorEl] = useState(null); + const dispatch = useDispatch(); + + const [openNotif] = useContext(AppContext); + + const handleClick = (event) => { + setAnchorEl(event.currentTarget); + }; + + const handleClose = () => { + setAnchorEl(null); + }; + + const handleEditClick = () => { + handleClose(true); + dispatch( + OPEN_MODAL({ + title: "ویرایش تخصیص", + content: ( + + ), + }) + ); + }; + + const handleDeleteClick = () => { + dispatch( + OPEN_MODAL({ + title: "آیا مطمئن هستید؟", + content: ( + + + + + ), + }) + ); + }; + + const handleReturnClick = () => { + dispatch( + OPEN_MODAL({ + title: "آیا مطمئن هستید؟", + content: ( + + + + + ), + }) + ); + }; + + const open = Boolean(anchorEl); + const id = open ? "popover" : undefined; + + return ( + + + + + + + {isAccepted ? ( + <> + + + + + + + + + + + + + + ) : ( + + + + + + + )} + + + + ); +}; diff --git a/src/features/province/components/province-dispenser-sale-with-in-province/ProvinceDispenserSaleWithInProvince.js b/src/features/province/components/province-dispenser-sale-with-in-province/ProvinceDispenserSaleWithInProvince.js new file mode 100644 index 0000000..134f16f --- /dev/null +++ b/src/features/province/components/province-dispenser-sale-with-in-province/ProvinceDispenserSaleWithInProvince.js @@ -0,0 +1,38 @@ +import React, { useState } from "react"; +import { Grid } from "../../../../components/grid/Grid"; +import { Tab, Tabs } from "@mui/material"; +import { ProvinceDispenserAcceptedSaleWithInProvince } from "../province-dispenser-accepted-sale-with-in-province/ProvinceDispenserAcceptedSaleWithInProvince"; +import { ProvinceDispenserRejectedSaleWithInProvince } from "../province-dispenser-rejected-sale-with-in-province/ProvinceDispenserRejectedSaleWithInProvince"; +import { ProvinceDispenserReturnedSaleWithInProvince } from "../province-dispenser-returned-sale-with-in-province/ProvinceDispenserReturnedSaleWithInProvince"; + +export const ProvinceDispenserSaleWithInProvince = () => { + const [value, setValue] = useState(0); + + const handleChange = (event, newValue) => { + setValue(newValue); + }; + return ( + + + + + + + + + + + {value === 0 && } + {value === 1 && } + {value === 2 && } + + + ); +}; diff --git a/src/features/province/components/province-dispenser-segmentation/ProvinceDispenserSegmentation.js b/src/features/province/components/province-dispenser-segmentation/ProvinceDispenserSegmentation.js new file mode 100644 index 0000000..97feb6f --- /dev/null +++ b/src/features/province/components/province-dispenser-segmentation/ProvinceDispenserSegmentation.js @@ -0,0 +1,298 @@ +import { useDispatch, useSelector } from "react-redux"; +import { AppContext } from "../../../../contexts/AppContext"; +import { useContext, useEffect, useState } from "react"; +import { + LOADING_END, + LOADING_START, +} from "../../../../lib/redux/slices/appSlice"; +import axios from "axios"; +import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl"; +import { formatJustDate } from "../../../../utils/formatTime"; +import { Grid } from "../../../../components/grid/Grid"; +import { DatePicker } from "@mui/x-date-pickers"; +import { + Autocomplete, + Button, + FormControl, + TextField, + Tooltip, +} from "@mui/material"; +import moment from "moment"; +import { RiFileExcel2Fill, RiSearchLine } from "react-icons/ri"; +import ResponsiveTable from "../../../../components/responsive-table/ResponsiveTable"; +import { provinceDispenserGetStewardService } from "../../services/province-dispenser-get-steward"; +import { provinceDispenserSegmentationDashboard } from "../../services/province-dispenser-segmentation-dashboard"; + +export const ProvinceDispenserSegmentation = ({ + updateTable, + priceInfo, + remainWeight, +}) => { + const { slaughterProducts } = useSelector((state) => state.slaughterSlice); + const dispatch = useDispatch(); + const [, , selectedDate1, setSelectedDate1, selectedDate2, setSelectedDate2] = + useContext(AppContext); + + const handleTextChange = (event) => { + setTextValue(event.target.value); + }; + + const [data, setData] = useState([]); + const [totalRows, setTotalRows] = useState(0); + const [perPage, setPerPage] = useState(10); + const [textValue, setTextValue] = useState(""); + const [page, setPage] = useState(1); + const [tableData, setTableData] = useState([]); + const [dashboardData, setDashboardData] = useState([]); + const [steward, setSteward] = useState([]); + const [selectedSteward, setselectedSteward] = useState(null); + + const userKey = useSelector((state) => state.userSlice.userProfile.key); + const [openNotif] = useContext(AppContext); + const fetchApiData = async (page) => { + dispatch(LOADING_START()); + try { + const response = await axios.get( + `app-segmentation/?search=filter&value=${textValue}&role=${getRoleFromUrl()}&date1=${selectedDate1}&date2=${selectedDate2}&page=${ + page || 1 + }&page_size=${perPage}&type=dashboard${ + selectedSteward + ? `&steward_key=${selectedSteward}` + : "&steward_key=all" + }` + ); + setData(response.data.results); + setTotalRows(response.data.count); + } catch (error) { + console.error("Error fetching data:", error); + } finally { + dispatch(LOADING_END()); + } + }; + const fetchsteward = () => { + dispatch(provinceDispenserGetStewardService()).then((r) => { + setSteward(r.payload.data); + }); + }; + const fetchDashboardData = () => { + dispatch( + provinceDispenserSegmentationDashboard({ + search: "filter", + role: getRoleFromUrl(), + selectedDate1, + selectedDate2, + steward_key: selectedSteward || "all", + }) + ).then((r) => { + setDashboardData(r.payload.data); + }); + }; + const handlePageChange = (page) => { + fetchApiData(page); + setPage(page); + }; + + const handlePerRowsChange = (perRows) => { + setPerPage(perRows); + setPage(1); + }; + + useEffect(() => { + const d = data?.map((item, i) => { + return [ + page === 1 ? i + 1 : i + perPage * (page - 1) + 1, + item?.toGuild ? "قطعه بند" : "مباشر", + `${item?.buyer?.fullname}(${item?.buyer?.mobile})`, + item?.toGuild + ? `${item?.toGuild?.user?.fullname}(${item?.toGuild?.user?.mobile})` + : "-", + formatJustDate(item?.date), + item?.weight, + item?.quota === "governmental" + ? "دولتی" + : item?.quota === "free" + ? "آزاد" + : "-", + item?.saleType === "governmental" + ? "دولتی" + : item?.saleType === "free" + ? "آزاد" + : "-", + ]; + }); + setTableData(d); + }, [data, page, perPage, priceInfo, slaughterProducts]); + useEffect(() => { + fetchApiData(1); + fetchDashboardData(); + fetchsteward(); + }, [dispatch, selectedDate1, selectedDate2, perPage, selectedSteward]); + + const handleSubmit = async (event) => { + event.preventDefault(); + fetchApiData(1); + fetchDashboardData(); + }; + + return ( + + + + + + + + ( + + )} + value={selectedDate1} + onChange={(newValue) => { + setSelectedDate1(moment(newValue).format("YYYY-MM-DD")); + }} + /> + + + ( + + )} + value={selectedDate2} + onChange={(newValue) => { + setSelectedDate2(moment(newValue).format("YYYY-MM-DD")); + }} + /> + + +
    + + + `(${option?.guildsName}) ${option?.user?.fullname}` + } + value={ + selectedSteward + ? steward.find((item) => item.key === selectedSteward) || + null + : null + } + onChange={(event, newValue) => { + setselectedSteward(newValue ? newValue.key : null); + }} + renderInput={(params) => ( + + )} + noOptionsText="مباشری یافت نشد" + isOptionEqualToValue={(option, value) => + option.key === value.key + } + /> + + + + + +
    + + + +
    + + +
    +
    + ); +}; diff --git a/src/features/province/components/province-dispenser-steward-edit-operation/ProvinceDispenserStewardEditOperation.js b/src/features/province/components/province-dispenser-steward-edit-operation/ProvinceDispenserStewardEditOperation.js new file mode 100644 index 0000000..a3ce157 --- /dev/null +++ b/src/features/province/components/province-dispenser-steward-edit-operation/ProvinceDispenserStewardEditOperation.js @@ -0,0 +1,455 @@ +import { useContext, useEffect, useState } from "react"; +import { useDispatch } from "react-redux"; +import { AppContext } from "../../../../contexts/AppContext"; +import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl"; + +import { Yup } from "../../../../lib/yup/yup"; +import { useFormik } from "formik"; +import { CLOSE_MODAL } from "../../../../lib/redux/slices/appSlice"; +import moment from "moment"; +import { Grid } from "../../../../components/grid/Grid"; +import { DatePicker } from "@mui/x-date-pickers"; +import { + Autocomplete, + Button, + FormControl, + FormControlLabel, + InputAdornment, + Radio, + RadioGroup, + TextField, +} from "@mui/material"; +import { NumberInput } from "../../../../components/number-format-custom/NumberFormatCustom"; +import { + slaughterAllocateStewardService, + slaughterEditAllocateStewardService, +} from "../../../slaughter-house/services/slaughter-allocate-steward"; +import { fetchSlaughterBroadcastAndProducts } from "../../../slaughter-house/services/handle-fetch-slaughter-products"; + +export const ProvinceDispenserStewardEditOperation = ({ + item, + key, + sellerType, + buyerType, + allocationType, + sellType, + fetchApiData, + editData, + priceInfo, + coldHouseKey, + coldHouseItemKey, + fetchDashboardData, +}) => { + const dispatch = useDispatch(); + const [productData, setProductData] = useState([]); + const [guildsData, setGuildsData] = useState([]); + const [productKey, setProductKey] = useState(null); + const [openNotif] = useContext(AppContext); + + const [value, setValue] = useState("own"); + + const handleChange = (event) => { + setValue(event.target.value); + setBuyerData({ + key: "", + item: "", + buyerType: "", + allocationType: "", + }); + }; + + const [sellGovernmental, setSellGovernmental] = useState( + priceInfo?.active ? "true" : "false" + ); + + const handleChangeSellGovernmental = (event) => { + setSellGovernmental(event.target.value); + if (event.target.value === "false") { + formik.setFieldValue("price", ""); + } + }; + + const [buyerData, setBuyerData] = useState({ + key, + item, + buyerType, + allocationType, + }); + + useEffect(() => { + if (getRoleFromUrl() === "Steward") { + setValue("free"); + } + }, []); + + useEffect(() => { + if (!editData) { + dispatch(slaughterAllocateStewardService()).then((r) => { + setProductData(r.payload.data); + }); + if (!item) { + dispatch( + slaughterEditAllocateStewardService({ + free: value === "free" ? true : false, + }) + ).then((r) => { + setGuildsData(r.payload.data); + }); + } + } + }, [dispatch, value]); + + const validationSchema = Yup.object({ + weight: Yup.number() + .required("این فیلد اجباری است!") + .min(1, "یک مقدار مثبت وارد کنید!"), + price: Yup.number() + .required("این فیلد اجباری است!") + .min(1, "یک مقدار مثبت وارد کنید!"), + wholePrice: Yup.number() + .required("این فیلد اجباری است!") + .min(1, "یک مقدار مثبت وارد کنید!"), + }); + + const formik = useFormik({ + initialValues: { + weight: editData?.realWeightOfCarcasses || "", + wholePrice: editData?.totalAmount || "", + price: editData?.amount || "", + }, + validationSchema, + }); + + useEffect(() => { + formik.validateForm(); + }, []); + + useEffect(() => { + if (sellGovernmental === "false") { + if (formik.values.weight && formik.values.price) { + formik.setFieldValue( + "wholePrice", + formik.values.price * formik.values.weight + ); + } + } else { + if (priceInfo?.active && formik.values.weight) { + formik.setFieldValue( + "wholePrice", + priceInfo?.killHousePrice * formik.values.weight + ); + } + } + }, [formik.values.price, formik.values.weight, sellGovernmental]); + + useEffect(() => { + if (priceInfo?.active && sellGovernmental === "true") { + formik.setFieldValue("price", priceInfo?.killHousePrice); + } + }, [sellGovernmental]); + + const successSubmit = () => { + dispatch(CLOSE_MODAL()); + openNotif({ + vertical: "top", + horizontal: "center", + msg: "عملیات با موفقیت انجام شد.", + severity: "success", + }); + dispatch(fetchSlaughterBroadcastAndProducts()); + fetchDashboardData(); + fetchApiData(1); + }; + + const [selectedDate1, setSelectedDate1] = useState( + moment(new Date()).format("YYYY-MM-DD") + ); + + return ( + + {!editData && ( + } + value={selectedDate1} + onChange={(e) => { + setSelectedDate1(moment(e).format("YYYY-MM-DD")); + }} + /> + )} + + {!editData && !coldHouseKey && ( + + { + return { + data: i, + label: `${i.name}`, + }; + }) + : [] + } + onChange={(event, value) => { + setProductKey(value.data); + }} + renderInput={(params) => ( + + )} + /> + + )} + + {!editData && ( + + + } + label="صنوف اختصاصی" + /> + } + label="صنوف آزاد" + /> + + + )} + + {!item && !editData && ( + + { + return { + data: i, + label: `${i?.steward ? "مباشر" : "صنف"} ${ + i?.guildsName + } ${i?.user?.fullname} (${i?.user?.mobile})`, + }; + }) + : [] + } + onChange={(event, value) => { + setBuyerData({ + item: value?.data, + key: value?.data?.key, + allocationType: value?.data?.steward + ? "killhouse_steward" + : "killhouse_guild", + buyerType: value?.data?.steward ? "Steward" : "Guild", + }); + }} + renderInput={(params) => ( + + )} + /> + + )} + + + {priceInfo?.active && ( + + + } + label="قیمت مصوب" + /> + } + label="قیمت آزاد" + /> + + + )} + + ریال, + }} + value={formik.values.price} + error={formik.touched.price ? Boolean(formik.errors.price) : null} + onChange={formik.handleChange} + onBlur={formik.handleBlur} + helperText={ + formik.touched.price && Boolean(formik.errors.price) + ? formik.errors.price + : null + } + /> + + ریال, + }} + value={formik.values.wholePrice} + error={ + formik.touched.wholePrice ? Boolean(formik.errors.wholePrice) : null + } + onChange={formik.handleChange} + onBlur={formik.handleBlur} + helperText={ + formik.touched.wholePrice && Boolean(formik.errors.wholePrice) + ? formik.errors.wholePrice + : null + } + /> + + + + ); +}; diff --git a/src/features/province/components/province-dispenser-steward-sale-in-operation/ProvinceDispenserStewardSaleInOperation.js b/src/features/province/components/province-dispenser-steward-sale-in-operation/ProvinceDispenserStewardSaleInOperation.js new file mode 100644 index 0000000..bbbb938 --- /dev/null +++ b/src/features/province/components/province-dispenser-steward-sale-in-operation/ProvinceDispenserStewardSaleInOperation.js @@ -0,0 +1,138 @@ +import React, { useState } from "react"; +import { + IconButton, + List, + ListItemButton, + ListItemIcon, + ListItemText, + Popover, +} from "@mui/material"; +import TuneIcon from "@mui/icons-material/Tune"; +import { useDispatch } from "react-redux"; +import { Grid } from "../../../../components/grid/Grid"; +import { slaughterDeleteAllocatedService } from "../../../slaughter-house/services/salughter-delete-allocated"; +import { OPEN_MODAL } from "../../../../lib/redux/slices/appSlice"; +import { ProvinceDispenserStewardEditOperation } from "../province-dispenser-steward-edit-operation/ProvinceDispenserStewardEditOperation"; +import { fetchSlaughterBroadcastAndProducts } from "../../../slaughter-house/services/handle-fetch-slaughter-products"; +import EditIcon from "@mui/icons-material/Edit"; +import DeleteIcon from "@mui/icons-material/Delete"; +export const ProvinceDispenserStewardSaleInOperation = ({ + fetchApiData, + item, + fetchData, + updateTable, + priceInfo, + // remainWeight, + fetchDashboardData, +}) => { + const [anchorEl, setAnchorEl] = useState(null); + const dispatch = useDispatch(); + + const handleClick = (event) => { + setAnchorEl(event.currentTarget); + }; + + const handleClose = () => { + setAnchorEl(null); + }; + + const handleEditClick = () => { + handleClose(true); + dispatch( + OPEN_MODAL({ + title: "ویرایش تخصیص", + content: ( + + ), + }) + ); + }; + + const handleDeleteClick = () => { + dispatch( + slaughterDeleteAllocatedService({ + steward_allocation_key: item.key, + }) + ).then(() => { + dispatch(fetchSlaughterBroadcastAndProducts()); + fetchApiData(1); + setAnchorEl(null); + }); + }; + + const open = Boolean(anchorEl); + const id = open ? "popover" : undefined; + + return ( + + + + + + + { + handleClose(); + handleEditClick(); + }} + sx={{ borderRadius: 1, mb: 0.25, py: 0.5 }} + > + + + + + + { + handleClose(); + handleDeleteClick(); + }} + sx={{ borderRadius: 1, py: 0.5 }} + > + + + + + + + + + ); +}; diff --git a/src/features/province/components/province-dispenser-steward-sale-out-operation/ProvinceDispenserStewardSaleOutOperation.js b/src/features/province/components/province-dispenser-steward-sale-out-operation/ProvinceDispenserStewardSaleOutOperation.js new file mode 100644 index 0000000..433d37f --- /dev/null +++ b/src/features/province/components/province-dispenser-steward-sale-out-operation/ProvinceDispenserStewardSaleOutOperation.js @@ -0,0 +1,129 @@ +import React, { useState } from "react"; +import { + IconButton, + List, + ListItemButton, + ListItemIcon, + ListItemText, + Popover, +} from "@mui/material"; +import TuneIcon from "@mui/icons-material/Tune"; +import EditOutlinedIcon from "@mui/icons-material/EditOutlined"; +import DeleteOutlineIcon from "@mui/icons-material/DeleteOutline"; +import { useDispatch } from "react-redux"; +import { Grid } from "../../../../components/grid/Grid"; +import { OPEN_MODAL } from "../../../../lib/redux/slices/appSlice"; +import { ProvinceStewardEditSaleOutOperation } from "../province-steward-edit-sale-out-operation/ProvinceStewardEditSaleOutOperation"; +import { stewardDeleteOutSellService } from "../../../guild/services/steward-sell-out-delete-service"; +import { fetchSlaughterBroadcastAndProducts } from "../../../slaughter-house/services/handle-fetch-slaughter-products"; + +export const ProvinceDispenserStewardSaleOutOperation = ({ + fetchApiData, + item, + fetchData, + updateTable, + priceInfo, + fetchDashboardData, + remainWeight, +}) => { + const [anchorEl, setAnchorEl] = useState(null); + const dispatch = useDispatch(); + + const handleClick = (event) => { + setAnchorEl(event.currentTarget); + }; + + const handleClose = () => { + setAnchorEl(null); + }; + + const handleEditClick = () => { + handleClose(); + dispatch( + OPEN_MODAL({ + title: "ویرایش تخصیص", + content: ( + + ), + }) + ); + }; + + const handleDeleteClick = () => { + handleClose(); + dispatch(stewardDeleteOutSellService(item?.key)).then(() => { + dispatch(fetchSlaughterBroadcastAndProducts()); + fetchApiData(1); + setAnchorEl(null); + }); + }; + + const open = Boolean(anchorEl); + const id = open ? "popover" : undefined; + + return ( + + + + + + + + + + + + + + + + + + + + + + ); +}; diff --git a/src/features/province/components/province-dispenser-stewards/ProvinceDispenserStewards.js b/src/features/province/components/province-dispenser-stewards/ProvinceDispenserStewards.js new file mode 100644 index 0000000..97cee69 --- /dev/null +++ b/src/features/province/components/province-dispenser-stewards/ProvinceDispenserStewards.js @@ -0,0 +1,10 @@ +import React from "react"; +import { Grid } from "../../../../components/grid/Grid"; + +export const ProvinceDispenserStewards = () => { + return ( + + در حال توسعه ... + + ); +}; diff --git a/src/features/province/components/province-dispensers-killhouses/ProvinceDispensersKillhouses.js b/src/features/province/components/province-dispensers-killhouses/ProvinceDispensersKillhouses.js new file mode 100644 index 0000000..2801150 --- /dev/null +++ b/src/features/province/components/province-dispensers-killhouses/ProvinceDispensersKillhouses.js @@ -0,0 +1,393 @@ +import React, { useContext, useEffect, useState } from "react"; +import { Grid } from "../../../../components/grid/Grid"; +import moment from "moment"; +import { DatePicker } from "@mui/x-date-pickers"; +import { Button, Checkbox, Tab, Tabs, TextField, Tooltip } from "@mui/material"; +import ResponsiveTable from "../../../../components/responsive-table/ResponsiveTable"; +import { useDispatch } from "react-redux"; +import { + provinceGetDispenserKillhousesDashboardService, + provinceGetDispenserKillhousesService, +} from "../../services/province-get-dispenser-killhouses"; +import { AppContext } from "../../../../contexts/AppContext"; +import { RiFileExcel2Fill } from "react-icons/ri"; +import axios from "axios"; +import ToggleOffOutlinedIcon from "@mui/icons-material/ToggleOffOutlined"; +import ToggleOnIcon from "@mui/icons-material/ToggleOn"; +import { SPACING } from "../../../../data/spacing"; +import { ProvinceDispenserSaleWithInProvince } from "../province-dispenser-sale-with-in-province/ProvinceDispenserSaleWithInProvince"; +import { ProvinceDispenserSaleOutProvince } from "../province-dispenser-sale-out-province/ProvinceDispenserSaleInProvince"; +import { ProvinceSegmentation } from "../province-segmentation/ProvinceSegmentation"; +import { ProvinceColdHouses } from "../province-cold-houses/ProvinceColdHouses"; + +export const ProvinceDispensersKillhouses = () => { + const [tableData, setTableData] = useState([]); + const [withDate, setWithDate] = useState(false); + const [dashboardData, setDashboardData] = useState([]); + const [openNotif] = useContext(AppContext); + const [value, setValue] = useState(0); + + const handleChange = (event, newValue) => { + setValue(newValue); + }; + + const dispatch = useDispatch(); + + const fetchDashboardData = () => { + if (value === 0) { + dispatch( + provinceGetDispenserKillhousesDashboardService({ + selectedDate1: withDate ? selectedDate1 : null, + selectedDate2: withDate ? selectedDate2 : null, + }) + ).then((r) => { + setDashboardData(r.payload.data); + }); + } + }; + + const fetchTableData = () => { + if (value === 0) { + dispatch( + provinceGetDispenserKillhousesService( + withDate ? { selectedDate1, selectedDate2 } : {} + ) + ).then((r) => { + const d = r.payload?.data?.map((item, i) => { + return [ + i + 1, + `${item?.killHouseOperator?.user?.fullname} (${item?.killHouseOperator?.user?.mobile})`, + `${item?.killer ? "کشتارکن" : "کشتارگاه"} (${item?.name})`, + item?.killHouseOperator?.user?.city?.name, + item?.wareHouseInfo?.productRemainWeight?.toLocaleString(), + item?.wareHouseInfo?.totalGovernmentalRemainWeight?.toLocaleString(), + item?.wareHouseInfo?.totalFreeRemainWeight?.toLocaleString(), + item?.wareHouseInfo?.warehouseTotalEnteredCarcassesWeight?.toLocaleString(), + item?.wareHouseInfo?.totalSell?.toLocaleString(), + // item?.wareHouseInfo?.provinceKillRequestsQuantity?.toLocaleString(), + // item?.wareHouseInfo?.totalProvinceBars?.toLocaleString(), + // item?.wareHouseInfo?.totalProvinceBarsQuantity?.toLocaleString(), + // item?.wareHouseInfo?.totalProvinceBarsWeight?.toLocaleString(), + // item?.wareHouseInfo?.totalKillHouseFreeBar?.toLocaleString(), + // item?.wareHouseInfo?.totalKillHouseFreeLiveBarQuantity?.toLocaleString(), + // item?.wareHouseInfo?.totalKillHouseFreeLiveBarWeight?.toLocaleString(), + // item?.wareHouseInfo?.totalKillHouseFreeCarcassesBar?.toLocaleString(), + // item?.wareHouseInfo?.totalKillHouseFreeBarCarcasses?.toLocaleString(), + // item?.wareHouseInfo?.totalKillHouseFreeBarCarcassesWeight?.toLocaleString(), + item?.wareHouseInfo?.totalBars?.toLocaleString(), + item?.wareHouseInfo?.warehouseTotalQuantity?.toLocaleString(), + Math.floor( + item?.wareHouseInfo?.warehouseTotalWeight + )?.toLocaleString(), + item?.wareHouseInfo?.warehouseTotalEnteredBars?.toLocaleString(), + item?.wareHouseInfo?.totalGovernmentalInputWeight?.toLocaleString(), + item?.wareHouseInfo?.totalFreeInputWeight?.toLocaleString(), + item?.wareHouseInfo?.totalKillHouseAllocationsWeight?.toLocaleString(), + item?.wareHouseInfo?.totalKillHouseFreeSale_barCarcassesWeight?.toLocaleString(), + item?.wareHouseInfo?.totalKillHouseSegmentationsWeight?.toLocaleString(), + item?.wareHouseInfo?.totalKillHouseColdHouseAllocationsWeight?.toLocaleString(), + item?.wareHouseInfo?.totalGovernmentalOutputWeight?.toLocaleString(), + item?.wareHouseInfo?.totalFreeOutputWeight?.toLocaleString(), + item?.wareHouseInfo?.lastTotalRemainWeight?.toLocaleString(), + item?.wareHouseInfo?.lastTotalGovernmentalRemainWeight?.toLocaleString(), + item?.wareHouseInfo?.lastTotalFreeRemainWeight?.toLocaleString(), + item?.wareHouseInfo?.warehouseTotalNotEnteredBars?.toLocaleString(), + item?.wareHouseInfo?.warehouseTotalNotEnteredBarsQuantity?.toLocaleString(), + item?.wareHouseInfo?.warehouseTotalNotEnteredBarsWeight?.toLocaleString(), + + + , + ]; + }); + setTableData(d); + }); + } + }; + + const [selectedDate1, setSelectedDate1] = useState( + moment(new Date()).format("YYYY-MM-DD") + ); + const [selectedDate2, setSelectedDate2] = useState( + moment(new Date()).format("YYYY-MM-DD") + ); + + useEffect(() => { + fetchDashboardData(); + fetchTableData(); + }, [selectedDate1, selectedDate2, withDate, value]); + + return ( + + + + + + + + + + + + + + {value === 0 && ( + <> + + + + } + checkedIcon={} + checked={withDate} + onChange={() => setWithDate(!withDate)} + color="primary" + size="large" + /> + + + ( + + )} + value={selectedDate1} + onChange={(e) => { + setSelectedDate1(moment(e).format("YYYY-MM-DD")); + }} + /> + + + ( + + )} + value={selectedDate2} + onChange={(e) => { + setSelectedDate2(moment(e).format("YYYY-MM-DD")); + }} + /> + + + + + + + + + + + + + + + + )} + + {value === 1 && } + + {value === 2 && } + + {value === 3 && } + + {value === 4 && } + + ); +}; diff --git a/src/features/province/components/province-dispensers-sell-carcass-buyers-out/ProvinceDispensersSellCarcassBuyersOut.js b/src/features/province/components/province-dispensers-sell-carcass-buyers-out/ProvinceDispensersSellCarcassBuyersOut.js new file mode 100644 index 0000000..678560b --- /dev/null +++ b/src/features/province/components/province-dispensers-sell-carcass-buyers-out/ProvinceDispensersSellCarcassBuyersOut.js @@ -0,0 +1,180 @@ +import React, { useContext, useEffect, useState } from "react"; +import { Button, TextField } from "@mui/material"; +import { DatePicker } from "@mui/x-date-pickers"; +import moment from "moment"; +import { useDispatch } from "react-redux"; +import axios from "axios"; +import { AppContext } from "../../../../contexts/AppContext"; +import { + LOADING_END, + LOADING_START, +} from "../../../../lib/redux/slices/appSlice"; +import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl"; +import { Grid } from "../../../../components/grid/Grid"; +import ResponsiveTable from "../../../../components/responsive-table/ResponsiveTable"; +import { RiSearchLine } from "react-icons/ri"; + +export const ProvinceDispensersSellCarcassBuyersOut = () => { + const [, , selectedDate1, setSelectedDate1, selectedDate2, setSelectedDate2] = + useContext(AppContext); + const dispatch = useDispatch(); + useEffect(() => { + const currentDate = moment(new Date()).format("YYYY-MM-DD"); + setSelectedDate1(currentDate); + setSelectedDate2(currentDate); + }, []); + + const handleTextChange = (event) => { + setTextValue(event.target.value); + }; + + const [data, setData] = useState([]); + const [totalRows, setTotalRows] = useState(0); + const [perPage, setPerPage] = useState(10); + const [textValue, setTextValue] = useState(""); + const [page, setPage] = useState(1); + const [tableData, setTableData] = useState([]); + + const fetchApiData = async (page) => { + let response; + dispatch(LOADING_START()); + response = await axios.get( + `base-out-province-carcasses-buyer/?search=filter&value=${textValue}&role=${getRoleFromUrl()}&date1=${selectedDate1}&date2=${selectedDate2}&page=${page}&page_size=${perPage}&state=true` + ); + dispatch(LOADING_END()); + setData(response.data.results); + setTotalRows(response.data.count); + }; + + const handlePageChange = (page) => { + fetchApiData(page); + setPage(page); + }; + + const handlePerRowsChange = (perRows) => { + setPerPage(perRows); + setPage(1); + }; + + // const updateTable = () => { + // fetchApiData(page !== 0 ? page : 1); + // }; + + useEffect(() => { + const d = data?.map((item, i) => { + return [ + page === 1 ? i + 1 : i + perPage * (page - 1) + 1, + `${item?.fullname} (${item?.mobile})`, + item?.unitName, + item?.province, + item?.city, + item?.killHouses?.map((option) => option).join(" - "), + item?.requestsInfo?.numberOfRequests?.toLocaleString(), + item?.requestsInfo?.totalQuantity?.toLocaleString(), + item?.requestsInfo?.totalWeight?.toLocaleString(), + ]; + }); + + setTableData(d); + }, [data]); + + useEffect(() => { + fetchApiData(1); + }, [dispatch, selectedDate1, selectedDate2, perPage]); + + const handleSubmit = async (event) => { + event.preventDefault(); + dispatch(LOADING_START()); + + try { + const response = await axios.get( + `base-out-province-carcasses-buyer/?role=${getRoleFromUrl()}&search=filter&value=${textValue}&date1=${selectedDate1}&date2=${selectedDate2}&page=${1}&page_size=${perPage}&state=true` + ); + setData(response.data.results); + setTotalRows(response.data.count); + dispatch(LOADING_END()); + } catch (error) { + console.error("Error fetching data:", error); + } + }; + + return ( + + + + ( + + )} + value={selectedDate1} + onChange={(e) => { + setSelectedDate1(moment(e).format("YYYY-MM-DD")); + }} + /> + + + ( + + )} + value={selectedDate2} + onChange={(e) => { + setSelectedDate2(moment(e).format("YYYY-MM-DD")); + }} + /> + + +
    + + + +
    +
    + + +
    + ); +}; diff --git a/src/features/province/components/province-dispensers-sell-carcass-sell-out/ProvinceDispensersSellCarcassSellOut.js b/src/features/province/components/province-dispensers-sell-carcass-sell-out/ProvinceDispensersSellCarcassSellOut.js new file mode 100644 index 0000000..7331849 --- /dev/null +++ b/src/features/province/components/province-dispensers-sell-carcass-sell-out/ProvinceDispensersSellCarcassSellOut.js @@ -0,0 +1,128 @@ +import React, { useContext, useEffect, useState } from "react"; +import { Grid } from "../../../../components/grid/Grid"; +import { TextField } from "@mui/material"; +import { DatePicker } from "@mui/x-date-pickers"; +import { AppContext } from "../../../../contexts/AppContext"; +import { useDispatch } from "react-redux"; +import moment from "moment"; +import ResponsiveTable from "../../../../components/responsive-table/ResponsiveTable"; +import { slaughterSellCarcassOutProvinceGetDashboard } from "../../../slaughter-house/services/slaughter-sell-carcass-out-province"; + +export const ProvinceDispensersSellCarcassSellOut = () => { + const [, , selectedDate1, setSelectedDate1, selectedDate2, setSelectedDate2] = + useContext(AppContext); + const dispatch = useDispatch(); + useEffect(() => { + const currentDate = moment(new Date()).format("YYYY-MM-DD"); + setSelectedDate1(currentDate); + setSelectedDate2(currentDate); + }, []); + + const [dashboardData, setDashboardData] = useState([]); + + useEffect(() => { + dispatch( + slaughterSellCarcassOutProvinceGetDashboard({ + selectedDate1, + selectedDate2, + }) + ).then((r) => { + setDashboardData(r.payload.data); + }); + }, [selectedDate1, selectedDate2]); + + return ( + + + + ( + + )} + value={selectedDate1} + onChange={(e) => { + setSelectedDate1(moment(e).format("YYYY-MM-DD")); + }} + /> + + + ( + + )} + value={selectedDate2} + onChange={(e) => { + setSelectedDate2(moment(e).format("YYYY-MM-DD")); + }} + /> + + {/* +
    + + + +
    + + + + + */} +
    + + + + +
    + ); +}; diff --git a/src/features/province/components/province-dispensers-sell-carcass/ProvinceDispensersSellCarcass.js b/src/features/province/components/province-dispensers-sell-carcass/ProvinceDispensersSellCarcass.js new file mode 100644 index 0000000..b98c73a --- /dev/null +++ b/src/features/province/components/province-dispensers-sell-carcass/ProvinceDispensersSellCarcass.js @@ -0,0 +1,73 @@ +import React, { useState } from "react"; +import { Box, Divider, Tab, Tabs } from "@mui/material"; +import { Grid } from "../../../../components/grid/Grid"; +import { SPACING } from "../../../../data/spacing"; +import { ProvinceDispensersSellCarcassSellOut } from "../province-dispensers-sell-carcass-sell-out/ProvinceDispensersSellCarcassSellOut"; +import { ProvinceDispensersSellCarcassBuyersOut } from "../province-dispensers-sell-carcass-buyers-out/ProvinceDispensersSellCarcassBuyersOut"; + +export const ProvinceDispensersSellCarcass = () => { + const [value, setValue] = useState(0); + + const handleChangeTab = (event, newValue) => { + setValue(newValue); + }; + + const [valueOutProvince, setValueOutProvince] = useState(0); + + const handleChangeTabsetOutProvince = (event, newValue) => { + setValueOutProvince(newValue); + }; + + return ( + + + + + + + + + + + {value === 0 && ( + + + + + + + + + {valueOutProvince === 0 && } + + {valueOutProvince === 1 && } + + )} + + ); +}; diff --git a/src/features/province/components/province-dispensers-stock-slug/ProvinceDispensersStockSlug.js b/src/features/province/components/province-dispensers-stock-slug/ProvinceDispensersStockSlug.js new file mode 100644 index 0000000..f60e859 --- /dev/null +++ b/src/features/province/components/province-dispensers-stock-slug/ProvinceDispensersStockSlug.js @@ -0,0 +1,58 @@ +import { Box, Tab, Tabs } from "@mui/material"; +import { Grid } from "../../../../components/grid/Grid"; +import { SPACING } from "../../../../data/spacing"; +import { BackButton } from "../../../../components/back-button/BackButton"; +import { useState } from "react"; +import { ProvinceDispensersStockSlugActive } from "./ProvinceDispensersStockSlugActive"; +import { ProvinceDispensersStockSlugArchive } from "./ProvinceDispensersStockSlugArchive"; + +const ProvinceDispensersStockSlug = () => { + const [value, setValue] = useState("active"); + + const handleChange = (event, newValue) => { + setValue(newValue); + }; + return ( + + + + + + + + + + + + {value === "active" && } + {value === "archive" && } + + + + + ); +}; + +export default ProvinceDispensersStockSlug; diff --git a/src/features/province/components/province-dispensers-stock-slug/ProvinceDispensersStockSlugActive.js b/src/features/province/components/province-dispensers-stock-slug/ProvinceDispensersStockSlugActive.js new file mode 100644 index 0000000..9e69e8d --- /dev/null +++ b/src/features/province/components/province-dispensers-stock-slug/ProvinceDispensersStockSlugActive.js @@ -0,0 +1,492 @@ +import { useCallback, useContext, useEffect, useState } from "react"; +import { useDispatch } from "react-redux"; +import { Grid } from "../../../../components/grid/Grid"; +import ResponsiveTable from "../../../../components/responsive-table/ResponsiveTable"; +import { + Button, + Box, + Typography, + TextField, + FormControlLabel, + Switch, +} from "@mui/material"; +import { DRAWER } from "../../../../lib/redux/slices/appSlice"; +import { SPACING } from "../../../../data/spacing"; +import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl"; +import { ImageUpload } from "../../../../components/image-upload/ImageUpload"; +import { resizeImage } from "../../../../utils/resizeImage"; +import { fixBase64 } from "../../../../utils/toBase64"; +import { AppContext } from "../../../../contexts/AppContext"; +import { provinceWarehouseArchive } from "../../services/province-warehouse-archive"; +import { provinceGetTotalKillhouseRemainWeight } from "../../services/province-get-total-killhouse-remain-weight"; +import { useLocation } from "react-router-dom"; +import { formatJustDate } from "../../../../utils/formatTime"; + +const DayDetailContent = ({ + killhouseName, + killhouseKey, + dayData, + governmentalData, + freeData, + selectedType, + onSuccess, +}) => { + const dispatch = useDispatch(); + const location = useLocation(); + const [openNotif] = useContext(AppContext); + + const [description, setDescription] = useState(""); + const [profileImages, setProfileImages] = useState([]); + const [profileImg, setProfileImg] = useState(""); + + const currentData = selectedType === "free" ? freeData : governmentalData; + + const getArchiveType = () => { + const pathSegments = location.pathname.split("/").filter(Boolean); + if (pathSegments.includes("steward")) { + return "steward"; + } + if (pathSegments.includes("killhouse")) { + return "kill_house"; + } + return pathSegments[pathSegments.length - 1] || "kill_house"; + }; + + const imageHandler = (imageList) => { + setProfileImages(imageList); + if (imageList[0]) { + const file = imageList[0]?.file; + resizeImage(file, (resizedDataUrl) => { + const optimizedBase64 = fixBase64(resizedDataUrl); + setProfileImg(optimizedBase64); + }); + } else { + setProfileImg(""); + } + }; + + const handleSubmit = () => { + const archiveType = getArchiveType(); + const role = getRoleFromUrl(); + + const payload = { + role, + owner_key: killhouseKey, + archive_type: archiveType, + date: dayData, + weight: currentData.amount, + quota: selectedType, + image: profileImg || "", + description: description || "", + }; + + dispatch(provinceWarehouseArchive(payload)).then((r) => { + if (r.payload?.error) { + openNotif({ + vertical: "top", + horizontal: "center", + msg: r.payload.error, + severity: "error", + }); + } else { + openNotif({ + vertical: "top", + horizontal: "center", + msg: "بایگانی با موفقیت ثبت شد", + severity: "success", + }); + + dispatch( + DRAWER({ + top: false, + left: false, + bottom: false, + right: false, + title: null, + content: null, + size: null, + }) + ); + setDescription(""); + setProfileImg(""); + setProfileImages([]); + + if (onSuccess) { + onSuccess(); + } + } + }); + }; + + return ( + + + + {killhouseName} + + + تاریخ: {formatJustDate(dayData)} + + + + + + + موجودی {selectedType === "free" ? "آزاد" : "دولتی"}: + + + {currentData.amount.toLocaleString()} کیلوگرم + + + + + + + + + + { + setDescription(e.target.value); + }} + placeholder="توضیحات خود را وارد کنید..." + /> + + + + + + ); +}; + +export const ProvinceDispensersStockSlugActive = () => { + const dispatch = useDispatch(); + const [openNotif] = useContext(AppContext); + const location = useLocation(); + const pathSegments = location.pathname.split("/").filter(Boolean); + const lastSegment = pathSegments[pathSegments.length - 1] || ""; + const isStewardPage = lastSegment === "steward"; + const nameColumnLabel = isStewardPage ? "مباشر" : "کشتارگاه"; + const [tableData, setTableData] = useState([]); + const [killhousesData, setKillhousesData] = useState([]); + const [showType, setShowType] = useState("governmental"); + const initialPageSize = isStewardPage ? 40 : 10; + const [tablePage, setTablePage] = useState(1); + const [tablePageSize, setTablePageSize] = useState(initialPageSize); + const [tableTotalRows, setTableTotalRows] = useState(0); + + const handleTypeToggle = () => { + setShowType((prev) => (prev === "free" ? "governmental" : "free")); + }; + + const fetchKillhouseData = useCallback(() => { + const params = { + search: "filter", + value: "", + page: tablePage, + page_size: tablePageSize, + quota: showType === "free" ? "free" : "governmental", + + ...(isStewardPage ? { owner_type: "steward" } : {}), + }; + + dispatch(provinceGetTotalKillhouseRemainWeight(params)).then((r) => { + if (r.payload?.error) { + openNotif({ + vertical: "top", + horizontal: "center", + msg: r.payload.error, + severity: "error", + }); + } else if (r.payload?.data) { + const apiData = r.payload.data.results || []; + const totalCount = r.payload.data.count || 0; + setTableTotalRows(totalCount); + + if (apiData.length === 0 && totalCount > 0 && tablePage > 1) { + setTablePage((prev) => Math.max(prev - 1, 1)); + return; + } + + const transformedData = apiData + .filter((item) => item.info !== null) + .map((item) => ({ + id: item.key, + key: item.key, + name: isStewardPage ? item.guildsName || item.name : item.name, + governmental: item.info?.governmental || [], + free: item.info?.free || [], + })); + + setKillhousesData(transformedData); + } + }); + }, [dispatch, openNotif, isStewardPage, tablePage, tablePageSize, showType]); + + useEffect(() => { + setTablePage(1); + setTablePageSize(isStewardPage ? 40 : 10); + }, [isStewardPage]); + + useEffect(() => { + fetchKillhouseData(); + }, [fetchKillhouseData]); + + useEffect(() => { + const filteredKillhouses = killhousesData + .map((killhouse) => { + const relevantList = + showType === "free" ? killhouse.free : killhouse.governmental; + const nonZeroDays = Array.isArray(relevantList) + ? relevantList.filter((item) => item?.amount) + : []; + + if (!nonZeroDays.length) { + return null; + } + + const totalWeight = nonZeroDays.reduce( + (acc, curr) => acc + (curr?.amount || 0), + 0 + ); + + return { killhouse, nonZeroDays, totalWeight }; + }) + .filter(Boolean); + + if (!filteredKillhouses.length && tableTotalRows > 0 && tablePage > 1) { + setTablePage((prev) => Math.max(prev - 1, 1)); + return; + } + + const data = filteredKillhouses.map((item, index) => { + const { killhouse, nonZeroDays, totalWeight } = item; + const uniqueDays = [...new Set(nonZeroDays.map((d) => d.day))].sort(); + + const daysContent = ( + + {uniqueDays + .map((day, dayIndex) => { + const govDay = killhouse.governmental.find((d) => d.day === day); + const freeDay = killhouse.free.find((d) => d.day === day); + + const currentAmount = + showType === "free" + ? freeDay?.amount || 0 + : govDay?.amount || 0; + + if (!currentAmount) { + return null; + } + + return ( + + ); + }) + .filter(Boolean)} + + ); + + return [ + (tablePage - 1) * tablePageSize + index + 1, + killhouse.name || "نامشخص", + totalWeight.toLocaleString(), + daysContent, + ]; + }); + + setTableData(data); + }, [ + showType, + killhousesData, + fetchKillhouseData, + dispatch, + tablePage, + tablePageSize, + tableTotalRows, + ]); + + return ( + + + + + + } + label={ + + + دولتی + + + / + + + آزاد + + + } + labelPlacement="start" + /> + + + + + setTablePage(newPage)} + handlePerRowsChange={(newPageSize) => { + setTablePageSize(newPageSize); + setTablePage(1); + }} + /> + + + ); +}; diff --git a/src/features/province/components/province-dispensers-stock-slug/ProvinceDispensersStockSlugArchive.js b/src/features/province/components/province-dispensers-stock-slug/ProvinceDispensersStockSlugArchive.js new file mode 100644 index 0000000..0b02c9d --- /dev/null +++ b/src/features/province/components/province-dispensers-stock-slug/ProvinceDispensersStockSlugArchive.js @@ -0,0 +1,444 @@ +import { useContext, useEffect, useState } from "react"; +import { useDispatch } from "react-redux"; +import { Grid } from "../../../../components/grid/Grid"; +import ResponsiveTable from "../../../../components/responsive-table/ResponsiveTable"; +import { + TextField, + Switch, + FormControlLabel, + IconButton, + Button, + Typography, +} from "@mui/material"; +import DeleteIcon from "@mui/icons-material/Delete"; +import SearchIcon from "@mui/icons-material/Search"; +import { SPACING } from "../../../../data/spacing"; +import { AppContext } from "../../../../contexts/AppContext"; +import { + provinceGetWarehouseArchive, + provinceDeleteWarehouseArchive, +} from "../../services/province-warehouse-archive"; +import { provinceGetTotalKillhouseArchiveDashboard } from "../../services/province-get-total-killhouse-remain-weight"; +import { DatePicker } from "@mui/x-date-pickers"; +import moment from "moment"; +import { formatJustDate, formatTime } from "../../../../utils/formatTime"; +import { numberDigitSeperator } from "../../../../utils/numberDigitSeperator"; +import { useLocation } from "react-router-dom"; +import { OPEN_MODAL, CLOSE_MODAL } from "../../../../lib/redux/slices/appSlice"; + +export const ProvinceDispensersStockSlugArchive = () => { + const dispatch = useDispatch(); + const [openNotif] = useContext(AppContext); + const location = useLocation(); + const pathSegments = location.pathname.split("/").filter(Boolean); + const isStewardPage = pathSegments.includes("steward"); + const nameColumnLabel = isStewardPage ? "نام مباشر" : "نام کشتارگاه"; + const [tableData, setTableData] = useState([]); + const [tablePage, setTablePage] = useState(1); + const [tablePageSize, setTablePageSize] = useState(10); + const [tableTotalRows, setTableTotalRows] = useState(0); + const [dashboardTableData, setDashboardTableData] = useState([]); + const [dashboardPage, setDashboardPage] = useState(1); + const [dashboardPageSize, setDashboardPageSize] = useState(10); + const [dashboardTotalRows, setDashboardTotalRows] = useState(0); + const [dashboardSearchValue, setDashboardSearchValue] = useState(""); + const [dateRangeEnabled, setDateRangeEnabled] = useState(false); + const [selectedDate1, setSelectedDate1] = useState( + moment(new Date()).format("YYYY-MM-DD") + ); + const [selectedDate2, setSelectedDate2] = useState( + moment(new Date()).format("YYYY-MM-DD") + ); + + const handleDeleteWarehouseItem = (key) => { + dispatch( + OPEN_MODAL({ + title: "تأیید حذف", + size: "auto", + content: ( + + + + آیا از حذف این بایگانی اطمینان دارید؟ + + + + + + + + + + ), + }) + ); + }; + + const fetchDashboardData = () => { + const params = { + search: "filter", + value: dashboardSearchValue, + page: dashboardPage, + page_size: dashboardPageSize, + ...(isStewardPage ? { owner_type: "steward" } : { role: "SuperAdmin" }), + }; + + if (dateRangeEnabled) { + params.date1 = selectedDate1; + params.date2 = selectedDate2; + } + + dispatch(provinceGetTotalKillhouseArchiveDashboard(params)).then((r) => { + if (r.payload?.error) { + openNotif({ + vertical: "top", + horizontal: "center", + msg: r.payload.error, + severity: "error", + }); + } else if (r.payload?.data) { + const apiData = r.payload.data.results || []; + setDashboardTotalRows(r.payload.data.count || 0); + + const data = apiData.map((item, index) => { + const info = item?.info || {}; + const normalizeInfoValue = (...keys) => { + for (const key of keys) { + if (info?.[key] !== undefined && info?.[key] !== null) { + return info[key]; + } + } + return 0; + }; + + const nameValue = isStewardPage + ? item?.guilds_name || item?.guildsName || item?.name || "نامشخص" + : item?.name || "نامشخص"; + + return [ + (dashboardPage - 1) * dashboardPageSize + index + 1, + nameValue, + numberDigitSeperator( + normalizeInfoValue("total_count", "totalCount") + ) || 0, + numberDigitSeperator( + normalizeInfoValue( + "total_governmental_count", + "totalGovernmentalCount" + ) + ) || 0, + numberDigitSeperator( + normalizeInfoValue("total_free_count", "totalFreeCount") + ) || 0, + numberDigitSeperator( + normalizeInfoValue("total_weight", "totalWeight") + ) || 0, + numberDigitSeperator( + normalizeInfoValue( + "total_governmental_weight", + "totalGovernmentalWeight" + ) + ) || 0, + numberDigitSeperator( + normalizeInfoValue("total_free_weight", "totalFreeWeight") + ) || 0, + ]; + }); + + setDashboardTableData(data); + } + }); + }; + + const fetchWarehouseData = () => { + const params = { + search: "filter", + value: "", + page: tablePage, + page_size: tablePageSize, + ...(isStewardPage + ? { archive_type: "steward", owner_type: "steward" } + : {}), + }; + + if (dateRangeEnabled) { + params.date1 = selectedDate1; + params.date2 = selectedDate2; + } + + dispatch(provinceGetWarehouseArchive(params)).then((r) => { + if (r.payload?.error) { + openNotif({ + vertical: "top", + horizontal: "center", + msg: r.payload.error, + severity: "error", + }); + } else if (r.payload?.data) { + const apiData = r.payload.data.results || []; + const totalCount = r.payload.data.count || 0; + setTableTotalRows(totalCount); + + if (apiData.length === 0 && totalCount > 0 && tablePage > 1) { + setTablePage((prev) => Math.max(prev - 1, 1)); + return; + } + + const data = apiData.map((item, index) => { + const killHouse = item?.killHouse || {}; + const steward = item?.steward || {}; + const guild = item?.guild || {}; + + const createDateValue = item?.createDate; + const registererMobile = item?.registererMobile || "-"; + const registererName = item?.registerer || "-"; + const quotaLabel = item?.quota === "free" ? "آزاد" : "دولتی"; + const description = item?.description || "-"; + const archiveKey = item?.key; + + const nameValue = isStewardPage + ? item?.guildsName || + steward?.guildsName || + steward?.fullname || + guild?.name || + item?.ownerName || + killHouse?.name || + "نامشخص" + : killHouse?.name || item?.ownerName || "نامشخص"; + + const cityValue = isStewardPage + ? item?.guildsCity || + steward?.city || + guild?.city || + item?.ownerCity || + killHouse?.city || + "-" + : killHouse?.city || item?.ownerCity || "-"; + + return [ + (tablePage - 1) * tablePageSize + index + 1, + createDateValue ? formatTime(createDateValue) : "-", + item?.date ? formatJustDate(item.date) : "-", + nameValue, + cityValue, + numberDigitSeperator(item?.weight || 0) || 0, + quotaLabel, + registererName, + registererMobile, + description, + handleDeleteWarehouseItem(archiveKey)} + size="small" + > + + , + ]; + }); + + setTableData(data); + } + }); + }; + + useEffect(() => { + setTablePage(1); + }, [selectedDate1, selectedDate2, dateRangeEnabled]); + + useEffect(() => { + fetchWarehouseData(); + }, [ + selectedDate1, + selectedDate2, + dateRangeEnabled, + tablePage, + tablePageSize, + ]); + + useEffect(() => { + fetchDashboardData(); + }, [ + selectedDate1, + selectedDate2, + dateRangeEnabled, + dashboardPage, + dashboardPageSize, + ]); + + return ( + + + + setDateRangeEnabled(e.target.checked)} + color="primary" + /> + } + /> + + + ( + + )} + value={selectedDate1} + onChange={(e) => { + setSelectedDate1(moment(e).format("YYYY-MM-DD")); + }} + /> + + + ( + + )} + value={selectedDate2} + onChange={(e) => { + setSelectedDate2(moment(e).format("YYYY-MM-DD")); + }} + /> + + + setDashboardSearchValue(e.target.value)} + onKeyPress={(e) => { + if (e.key === "Enter") { + fetchDashboardData(); + } + }} + /> + + + + + + + setDashboardPage(newPage)} + handlePerRowsChange={(newPageSize) => { + setDashboardPageSize(newPageSize); + setDashboardPage(1); + }} + /> + + + + setTablePage(newPage)} + handlePerRowsChange={(newPageSize) => { + setTablePageSize(newPageSize); + setTablePage(1); + }} + /> + + + ); +}; diff --git a/src/features/province/components/province-dispensers-stock-slug/service.js b/src/features/province/components/province-dispensers-stock-slug/service.js new file mode 100644 index 0000000..4d178f9 --- /dev/null +++ b/src/features/province/components/province-dispensers-stock-slug/service.js @@ -0,0 +1,22 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { + LOADING_END, + LOADING_START, +} from "../../../../lib/redux/slices/appSlice"; +// import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl"; + +export const getKillhouseRemainWeight = createAsyncThunk( + "GET_KILLHOUSE_REMAIN_WEIGHT", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + const { data, status } = await axios.get( + "/api/killhouse-remain-weight" + // , { + // params: { role: getRoleFromUrl() }, + // } + ); + dispatch(LOADING_END()); + return { data, status }; + } +); diff --git a/src/features/province/components/province-dispensers-stock/ProvinceDispensersStock.js b/src/features/province/components/province-dispensers-stock/ProvinceDispensersStock.js new file mode 100644 index 0000000..32624a1 --- /dev/null +++ b/src/features/province/components/province-dispensers-stock/ProvinceDispensersStock.js @@ -0,0 +1,139 @@ +import React from "react"; +import { SPACING } from "../../../../data/spacing"; +import { Grid } from "../../../../components/grid/Grid"; +import { NavLink } from "../../../../components/nav-link/NavLink"; +import LinkItem from "../../../../components/link-item/LinkItem"; +import { BackButton } from "../../../../components/back-button/BackButton"; +import { VscBroadcast } from "react-icons/vsc"; +import { FaStore } from "react-icons/fa"; +import { GiMeat } from "react-icons/gi"; +import { + ROUTE_ADMINX_DISPENSERS_STOCK_KILLHOUSE, + ROUTE_SUPER_ADMIN_DISPENSERS_STOCK_KILLHOUSE, + ROUTE_ADMINX_DISPENSERS_STOCK_STEWARD, + ROUTE_SUPER_ADMIN_DISPENSERS_STOCK_STEWARD, + ROUTE_ADMINX_DISPENSERS_STOCK_GUILD, + ROUTE_SUPER_ADMIN_DISPENSERS_STOCK_GUILD, + ROUTE_PROVINCE_SUPERVISOR_DISPENSERS_STOCK_STEWARD, + ROUTE_PROVINCE_SUPERVISOR_DISPENSERS_STOCK_GUILD, + ROUTE_PROVINCE_SUPERVISOR_DISPENSERS_STOCK_KILLHOUSE, +} from "../../../../routes/routes"; +import { useLocation } from "react-router-dom"; +import { Box } from "@mui/material"; +import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl"; + +const ProvinceDispensersStock = () => { + const { pathname } = useLocation(); + + return ( + + + + + + + + + + } + title="کشتارگاه" + description="کشتارگاه" + /> + + + + } + title="مباشر" + description="مباشر" + /> + + + + } + title="صنف" + description="صنف" + /> + + + + + + ); +}; + +export default ProvinceDispensersStock; diff --git a/src/features/province/components/province-dispensers-view-killhouse/ProvinceDispensersViewKillHouse.js b/src/features/province/components/province-dispensers-view-killhouse/ProvinceDispensersViewKillHouse.js new file mode 100644 index 0000000..3e88012 --- /dev/null +++ b/src/features/province/components/province-dispensers-view-killhouse/ProvinceDispensersViewKillHouse.js @@ -0,0 +1,32 @@ +import React from "react"; +import { Grid } from "../../../../components/grid/Grid"; +import { Tab, Tabs } from "@mui/material"; +import { ProvinceDispensersView } from "../province-dispensers-view/ProvinceDispensersView"; + +export const ProvinceDispensersViewKillHouse = ({ key, name }) => { + const [value, setValue] = React.useState("0"); + + const handleChange = (event, newValue) => { + setValue(newValue); + }; + + return ( + + + + + + + {value === "0" && ( + + )} + {value === "1" && ( + + )} + + ); +}; diff --git a/src/features/province/components/province-dispensers-view/ProvinceDispensersView.js b/src/features/province/components/province-dispensers-view/ProvinceDispensersView.js new file mode 100644 index 0000000..67eea83 --- /dev/null +++ b/src/features/province/components/province-dispensers-view/ProvinceDispensersView.js @@ -0,0 +1,300 @@ +import React, { useEffect, useState } from "react"; +import { Button, Popover, TextField, Typography } from "@mui/material"; +import axios from "axios"; +import { RiSearchLine } from "react-icons/ri"; +import ResponsiveTable from "../../../../components/responsive-table/ResponsiveTable"; +import { Grid } from "../../../../components/grid/Grid"; +import { + DRAWER, + LOADING_END, + LOADING_START, + OPEN_MODAL, +} from "../../../../lib/redux/slices/appSlice"; +import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl"; +import { useDispatch } from "react-redux"; +import { useParams } from "react-router-dom"; +import { ProvinceAllocateStewardGuild } from "../province-allocate-steward-guild/ProvinceAllocateStewardGuild"; +import { ProvinceCreateAllocateStewardGuild } from "../province-create-allocate-steward-guild/ProvinceCreateAllocateStewardGuild"; + +export const ProvinceDispensersView = ({ type, roleType }) => { + const dispatch = useDispatch(); + const handleTextChange = (event) => { + setTextValue(event.target.value); + }; + const { key, name } = useParams(); + + const [data, setData] = useState([]); + const [totalRows, setTotalRows] = useState(0); + const [perPage, setPerPage] = useState(10); + const [textValue, setTextValue] = useState(""); + const [page, setPage] = useState(1); + const [tableData, setTableData] = useState([]); + + const fetchApiData = async (page) => { + let response; + dispatch(LOADING_START()); + response = await axios.get( + `total-guilds-distribution-management/?search=filter&value=${textValue}&role=${getRoleFromUrl()}&page=${page}&page_size=${perPage}${ + roleType && "&role_type=" + roleType + }${type && "&type=" + type}&key=${key}` + ); + dispatch(LOADING_END()); + setData(response.data.results); + setTotalRows(response.data.count); + }; + + const handlePageChange = (page) => { + fetchApiData(page); + setPage(page); + }; + + const handlePerRowsChange = (perRows) => { + setPerPage(perRows); + setPage(1); + }; + + const updateTable = () => { + fetchApiData(page !== 0 ? page : 1); + }; + + useEffect(() => { + const d = data?.map((item, i) => { + return [ + page === 1 ? i + 1 : i + perPage * (page - 1) + 1, + item?.guildsName, + `${item?.user?.fullname} (${item?.user?.mobile})`, + item?.city, + item?.userLevel?.length + ? item?.userLevel?.map((option, i) => ( + + {option?.faTitle} + + )) + : "-", + item?.typeActivity, + item?.areaActivity, + item?.generalInfos?.selfTotalAllocationType === "forced" + ? "اجباری" + : "اختیاری", + item?.generalInfos?.inputTotalAllocationLimit?.toLocaleString(), + item?.generalInfos?.outputTotalAllocationLimit?.toLocaleString(), + ]; + }); + + setTableData(d); + }, [data]); + + useEffect(() => { + fetchApiData(1); + }, [dispatch, perPage]); + + const handleSubmit = async (event) => { + event.preventDefault(); + dispatch(LOADING_START()); + + try { + const response = await axios.get( + `total-guilds-distribution-management/?role=${getRoleFromUrl()}&search=filter&value=${textValue}&page=${1}&page_size=${perPage}` + ); + setData(response.data.results); + setTotalRows(response.data.count); + dispatch(LOADING_END()); + } catch (error) { + console.error("Error fetching data:", error); + } + }; + + const [anchorEl, setAnchorEl] = React.useState(null); + + const handleClick = (event) => { + setAnchorEl(event.currentTarget); + }; + + const handleClose = () => { + setAnchorEl(null); + }; + + const open = Boolean(anchorEl); + const id = open ? "simple-popover" : undefined; + + return ( + + + + + + + + + + + + + + + + +
    + + + +
    +
    + + +
    + ); +}; diff --git a/src/features/province/components/province-edit-age-message/ProvinceEditAgeMessage.js b/src/features/province/components/province-edit-age-message/ProvinceEditAgeMessage.js new file mode 100644 index 0000000..1a7f37b --- /dev/null +++ b/src/features/province/components/province-edit-age-message/ProvinceEditAgeMessage.js @@ -0,0 +1,125 @@ +import React, { useContext } from "react"; +import { TextField, Button, Grid } from "@mui/material"; +import { useFormik } from "formik"; +import * as Yup from "yup"; +import { provinceEditAgeMessagesService } from "../../services/province-age-message"; +import { AppContext } from "../../../../contexts/AppContext"; +import { useDispatch } from "react-redux"; +import { DRAWER } from "../../../../lib/redux/slices/appSlice"; + +export const ProvinceEditAgeMessage = ({ item, fetchData }) => { + const [openNotif] = useContext(AppContext); + const dispatch = useDispatch(); + const validationSchema = Yup.object({ + ageRange: Yup.number() + .required("بازه سنی ضروری است") + .max(99, "عدد دورقمی وارد کنید!"), + lossPercent: Yup.number() + .required("درصد افت ضروری است") + .max(99, "عدد دورقمی وارد کنید!"), + message: Yup.string() + .required("پیغام ضروری است") + .max(500, "حداکثر 500 کاراکتر"), + }); + + const formik = useFormik({ + initialValues: { + ageRange: item?.poultryAge, + message: item?.message, + lossPercent: item?.lossesPercent, + }, + validationSchema, + onSubmit: (values) => { + dispatch( + provinceEditAgeMessagesService({ + message: values.message, + poultry_age: values.ageRange, + losses_percent: values.lossPercent, + notif_key: item?.key, + }) + ).then((r) => { + if (r.payload.error) { + openNotif({ + vertical: "top", + horizontal: "center", + msg: r.payload.error, + severity: "error", + }); + } else { + fetchData(); + dispatch(DRAWER({ right: false, bottom: false, content: null })); + openNotif({ + vertical: "top", + horizontal: "center", + msg: "عملیات با موفقیت انجام شد.", + severity: "success", + }); + } + }); + }, + }); + + return ( +
    + + + + + + + + + + + + + + +
    + ); +}; diff --git a/src/features/province/components/province-edit-kill-capacity-form/ProvinceEditKillCapacityForm.js b/src/features/province/components/province-edit-kill-capacity-form/ProvinceEditKillCapacityForm.js new file mode 100644 index 0000000..df35f05 --- /dev/null +++ b/src/features/province/components/province-edit-kill-capacity-form/ProvinceEditKillCapacityForm.js @@ -0,0 +1,83 @@ +import { Button, TextField } from "@mui/material"; +import { useFormik } from "formik"; +import { useContext } from "react"; +import { useDispatch } from "react-redux"; +import { Grid } from "../../../../components/grid/Grid"; +import { AppContext } from "../../../../contexts/AppContext"; +import { SPACING } from "../../../../data/spacing"; +import { CLOSE_MODAL } from "../../../../lib/redux/slices/appSlice"; +import { getSlaughterHousesRequest } from "../../../file/services/getSlaughterHousesRequest"; +import { provinceEditKillCapacityService } from "../../services/province-edit-kill-capacity"; + +export const ProvinceEditKillCapacityForm = ({ + killRequestKey, + poultryRequestKey, + killCapacity, + updateTable, +}) => { + const dispatch = useDispatch(); + const [openNotif] = useContext(AppContext); + + const formik = useFormik({ + initialValues: { + number: killCapacity, + }, + onSubmit: (values) => { + dispatch( + provinceEditKillCapacityService({ + kill_request_key: killRequestKey, + quantity: values.number, + }) + ).then((r) => { + if (r.payload.error) { + openNotif({ + vertical: "top", + horizontal: "center", + msg: r.payload.error, + severity: "error", + }); + } else { + dispatch(getSlaughterHousesRequest(poultryRequestKey)); + dispatch(CLOSE_MODAL()); + openNotif({ + vertical: "top", + horizontal: "center", + msg: "عملیات با موفقیت انجام شد.", + severity: "success", + }); + updateTable(); + } + }); + }, + validate: (values) => { + const errors = {}; + if (!values.number) { + errors.number = "این فیلد اجباری است"; + } else if (isNaN(parseInt(values.number))) { + errors.number = "باید عدد وارد شود."; + } + return errors; + }, + }); + + return ( +
    + + + + +
    + ); +}; diff --git a/src/features/province/components/province-edit-poultry-request-form/ProvinceEditPoultryRequestForm.js b/src/features/province/components/province-edit-poultry-request-form/ProvinceEditPoultryRequestForm.js new file mode 100644 index 0000000..f57c1df --- /dev/null +++ b/src/features/province/components/province-edit-poultry-request-form/ProvinceEditPoultryRequestForm.js @@ -0,0 +1,85 @@ +import { Button, TextField } from "@mui/material"; +import { useFormik } from "formik"; +import { useContext } from "react"; +import { useDispatch } from "react-redux"; +import { Grid } from "../../../../components/grid/Grid"; +import { AppContext } from "../../../../contexts/AppContext"; +import { SPACING } from "../../../../data/spacing"; +import { CLOSE_MODAL } from "../../../../lib/redux/slices/appSlice"; +import useUserProfile from "../../../authentication/hooks/useUserProfile"; +import { getFileFromApi } from "../../../file/hooks/useRequestFile"; +import { provinceEditPoultryRequestService } from "../../services/province-edit-poultry-request-service"; +import { provinceGetAllRequests } from "../../services/province-get-all-requests"; + +export const ProvinceEditPoultryRequestForm = ({ + quantity, + poultryRequestKey, +}) => { + const [openNotif] = useContext(AppContext); + const [roles] = useUserProfile(); + + const dispatch = useDispatch(); + const formik = useFormik({ + initialValues: { + numberField: quantity, + }, + onSubmit: (values) => { + dispatch( + provinceEditPoultryRequestService({ + quantity: values.numberField, + key: poultryRequestKey, + }) + ).then((r) => { + if (r.payload.error) { + openNotif({ + vertical: "top", + horizontal: "center", + msg: r.payload.error, + severity: "error", + }); + } else { + getFileFromApi(roles, poultryRequestKey, dispatch); + dispatch(provinceGetAllRequests()); + dispatch(CLOSE_MODAL()); + openNotif({ + vertical: "top", + horizontal: "center", + msg: "عملیات با موفقیت انجام شد.", + severity: "success", + }); + } + }); + }, + validate: (values) => { + const errors = {}; + if (!values.numberField) { + errors.numberField = "Field cannot be empty"; + } else if (!/^\d+$/.test(values.numberField)) { + errors.numberField = "Only numbers are allowed"; + } + return errors; + }, + }); + return ( +
    + + + + +
    + ); +}; diff --git a/src/features/province/components/province-edit-price/ProvincePriceEdit.js b/src/features/province/components/province-edit-price/ProvincePriceEdit.js new file mode 100644 index 0000000..840d68c --- /dev/null +++ b/src/features/province/components/province-edit-price/ProvincePriceEdit.js @@ -0,0 +1,246 @@ +import { + Button, + IconButton, + Popover, + Tooltip, + Typography, +} from "@mui/material"; +import { useDispatch } from "react-redux"; +import { AppContext } from "../../../../contexts/AppContext"; +import { useContext, useState } from "react"; +import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl"; +import { + CLOSE_MODAL, + DRAWER, + OPEN_MODAL, +} from "../../../../lib/redux/slices/appSlice"; +import { Grid } from "../../../../components/grid/Grid"; +import EditIcon from "@mui/icons-material/Edit"; +import SettingsSuggestIcon from "@mui/icons-material/SettingsSuggest"; +import TuneIcon from "@mui/icons-material/Tune"; +import { provincePriceEditService } from "../../services/province-price-edit"; +import { ProvineSubmitPrice } from "../province-submit-price/ProvineSubmitPrice"; + +export const ProvincePriceEdit = ({ item, updateTable }) => { + const dispatch = useDispatch(); + const [anchorEl, setAnchorEl] = useState(null); + const [openNotif] = useContext(AppContext); + + const handleClick = (event) => setAnchorEl(event.currentTarget); + const handleClose = () => setAnchorEl(null); + const open = Boolean(anchorEl); + const id = open ? "popover" : undefined; + const role = getRoleFromUrl(); + + const isToday = () => { + if (!item?.date) return false; + const today = new Date(); + const itemDate = new Date(item.date); + return ( + itemDate.getFullYear() === today.getFullYear() && + itemDate.getMonth() === today.getMonth() && + itemDate.getDate() === today.getDate() + ); + }; + + const handleEdit = () => { + handleClose(); + + if (!isToday()) { + openNotif({ + msg: "فقط قیمت‌های مربوط به تاریخ امروز قابل ویرایش هستند.", + severity: "error", + vertical: "top", + horizontal: "center", + }); + return; + } + + dispatch( + DRAWER({ + right: !(window.innerWidth <= 600), + bottom: window.innerWidth <= 600, + content: ( + { + dispatch( + provincePriceEditService({ + id: item.id, + prices: { + kill_house_price: prices.killHousePrice, + wholesaler_price: prices.wholesalerPrice, + retailer_price: prices.retailerPrice, + }, + }) + ).then((r) => { + if (r.payload.error) { + openNotif({ + msg: r.payload.error, + severity: "error", + vertical: "top", + horizontal: "center", + }); + } else { + updateTable(); + openNotif({ + msg: "قیمت‌ها با موفقیت ویرایش شدند", + severity: "success", + vertical: "top", + horizontal: "center", + }); + } + }); + }} + /> + ), + title: "ویرایش قیمت‌های کارمزد", + }) + ); + }; + + const handleApproval = (state) => { + dispatch( + provincePriceEditService({ + id: item.id, + prices: { + kill_house_check: true, + state, + }, + }) + ).then((r) => { + if (r.payload.error) { + openNotif({ + msg: r.payload.error, + severity: "error", + vertical: "top", + horizontal: "center", + }); + } else { + updateTable(); + dispatch(CLOSE_MODAL()); + openNotif({ + msg: "وضعیت با موفقیت به روز رسانی شد", + severity: "success", + vertical: "top", + horizontal: "center", + }); + } + }); + }; + + const renderActions = () => { + if (role !== "KillHouse") { + return ( + + + + ); + } else { + return ( + + + + + + + + ), + }) + ); + }} + sx={{ + "&.Mui-disabled": { + backgroundColor: "transparent", + color: "text.disabled", + }, + }} + > + + تایید / رد + + + + ); + } + }; + + return ( +
    + + + + +
    + + {renderActions()} + +
    +
    +
    + ); +}; diff --git a/src/features/province/components/province-edit-send-date/ProvinceEditSendDate.js b/src/features/province/components/province-edit-send-date/ProvinceEditSendDate.js new file mode 100644 index 0000000..401b790 --- /dev/null +++ b/src/features/province/components/province-edit-send-date/ProvinceEditSendDate.js @@ -0,0 +1,76 @@ +import { DatePicker } from "@mui/x-date-pickers"; +import { Button, TextField } from "@mui/material"; +import { useFormik } from "formik"; +import moment from "moment"; +import { Grid } from "../../../../components/grid/Grid"; +import { SPACING } from "../../../../data/spacing"; +import { useDispatch } from "react-redux"; +import { provinceEditSendDate } from "../../services/province-edit-send-date"; +import { CLOSE_MODAL } from "../../../../lib/redux/slices/appSlice"; +import { AppContext } from "../../../../contexts/AppContext"; +import { useContext } from "react"; +import { provinceGetAllRequests } from "../../services/province-get-all-requests"; + +export const ProvinceEditSendDate = ({ poultryRequestKey }) => { + const [openNotif] = useContext(AppContext); + const dispatch = useDispatch(); + const formik = useFormik({ + initialValues: { + date: moment(Date()).format("YYYY-MM-DD hh:mm:ss"), + }, + }); + + return ( + + } + value={formik.values.date} + error={formik.touched.date ? Boolean(formik.errors.date) : null} + onChange={(e) => { + formik.setFieldValue("date", moment(e).format("YYYY-MM-DD hh:mm:ss")); + }} + onBlur={formik.handleBlur} + helperText={ + formik.touched.date && Boolean(formik.errors.date) + ? formik.errors.date + : null + } + /> + + + ); +}; diff --git a/src/features/province/components/province-edit-unpaid-fee/ProvinceEditUnpaidFee.js b/src/features/province/components/province-edit-unpaid-fee/ProvinceEditUnpaidFee.js new file mode 100644 index 0000000..190aa55 --- /dev/null +++ b/src/features/province/components/province-edit-unpaid-fee/ProvinceEditUnpaidFee.js @@ -0,0 +1,70 @@ +import { Button, InputAdornment } from "@mui/material"; +import { useContext, useState } from "react"; +import { useDispatch } from "react-redux"; +import { Grid } from "../../../../components/grid/Grid"; +import { NumberInput } from "../../../../components/number-format-custom/NumberFormatCustom"; +import { AppContext } from "../../../../contexts/AppContext"; +import { SPACING } from "../../../../data/spacing"; +import { CLOSE_MODAL } from "../../../../lib/redux/slices/appSlice"; +import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl"; +import { provinceEditUnpaidFeeService } from "../../services/province-edit-unpaid-fee"; + +export const ProvinceEditUnpaidFee = ({ item, updateTable }) => { + const [openNotif] = useContext(AppContext); + const dispatch = useDispatch(); + const [value, setValue] = useState(item?.provinceRequest?.totalAmount); + + const handleChange = (event) => { + setValue(event.target.value); + }; + + return ( + + ریال, + }} + /> + + + ); +}; diff --git a/src/features/province/components/province-export/ProvinceExport.js b/src/features/province/components/province-export/ProvinceExport.js new file mode 100644 index 0000000..cbf57db --- /dev/null +++ b/src/features/province/components/province-export/ProvinceExport.js @@ -0,0 +1,364 @@ +import React, { useContext, useEffect, useState } from "react"; +import moment from "moment"; +import axios from "axios"; +import { useDispatch, useSelector } from "react-redux"; +import { + Button, + Chip, + IconButton, + Tab, + Tabs, + TextField, + Tooltip, +} from "@mui/material"; +import { DatePicker } from "@mui/x-date-pickers"; +import { Grid } from "../../../../components/grid/Grid"; +import { SPACING } from "../../../../data/spacing"; +import ResponsiveTable from "../../../../components/responsive-table/ResponsiveTable"; +import { formatJustDate, formatTime } from "../../../../utils/formatTime"; +import { AppContext } from "../../../../contexts/AppContext"; +import { + LOADING_END, + LOADING_START, + OPEN_MODAL, +} from "../../../../lib/redux/slices/appSlice"; +import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl"; +import { SlaughterFreeBuyOperations } from "../../../slaughter-house/components/slaughter-free-buy-operations/SlaughterFreeBuyOperations"; +import { EnterAuthCodeDirectBuy } from "../../../slaughter-house/components/enter-auth-code-direct-buy/EnterAuthCodeDirectBuy"; +import { RiFileExcel2Fill } from "react-icons/ri"; +import { RiSearchLine } from "react-icons/ri"; +import AddCircleOutlineIcon from "@mui/icons-material/AddCircleOutline"; + +export const ProvinceExport = () => { + const dispatch = useDispatch(); + + const [activeTab, setActiveTab] = useState(0); + + const handleTabChange = (event, newValue) => { + setActiveTab(newValue); + }; + + const [, , selectedDate1, setSelectedDate1, selectedDate2, setSelectedDate2] = + useContext(AppContext); + + useEffect(() => { + const currentDate = moment(new Date()).format("YYYY-MM-DD"); + setSelectedDate1(currentDate); + setSelectedDate2(currentDate); + }, []); + + const handleTextChange = (event) => { + setTextValue(event.target.value); + }; + + const [data, setData] = useState([]); + const [totalRows, setTotalRows] = useState(0); + const [perPage, setPerPage] = useState(10); + const [textValue, setTextValue] = useState(""); + const [page, setPage] = useState(1); + const [tableData, setTableData] = useState([]); + const [tableDataArchive, setTableDataArchive] = useState([]); + + const fetchApiData = async (page) => { + dispatch(LOADING_START()); + const response = await axios.get( + `kill_request/?export=true&type=${ + activeTab === 0 ? "pending" : "archive" + }&search=filter&value=${textValue}&role=${getRoleFromUrl()}&date1=${selectedDate1}&date2=${selectedDate2}&page=${page}&page_size=${perPage}` + ); + dispatch(LOADING_END()); + setData(response.data.results); + setTotalRows(response.data.count); + }; + + const handlePageChange = (page) => { + fetchApiData(page); + setPage(page); + }; + + const handlePerRowsChange = (perRows) => { + setPerPage(perRows); + setPage(1); + }; + + const updateTable = () => { + fetchApiData(page !== 0 ? page : 1); + }; + + useEffect(() => { + fetchApiData(1); + }, []); + + const getItemState = (item) => { + let state = ""; + if (item.exportState === "pending") { + state = "در انتظار تایید"; + } else if (item.exportState === "rejected") { + state = "رد شده"; + } else if (item.exportState === "accepted") { + state = "تایید شده"; + } else if (item.exportState === "deleted") { + state = "حذف شده"; + } + return state; + }; + + useEffect(() => { + const d = data?.map((item, i) => { + return [ + page === 1 ? i + 1 : i + perPage * (page - 1) + 1, + formatJustDate(item?.createDate), + formatJustDate(item.reciveDate), + `${item.killHouse.name} (${item.killHouse.killHouseOperator.user.mobile})`, + item?.slaughterHouse + ? item?.slaughterHouse?.name + : item?.killHouse?.name, + item?.exportCountry, + `${item?.poultry?.userprofile?.fullName} (${item?.poultry?.userprofile?.mobile})`, + item.killCapacity, + item.IndexWeight, + (item.IndexWeight * item.killCapacity)?.toLocaleString(), + <> + {item?.inputDirectBuyingCode ? ( + item?.inputDirectBuyingCode + ) : ( + + { + dispatch( + OPEN_MODAL({ + title: "ثبت کد احراز", + size: "auto", + content: ( + + ), + }) + ); + }} + > + + + + )} + , + , + , + ]; + }); + + setTableData(d); + + const a = data?.map((item, i) => { + return [ + page === 1 ? i + 1 : i + perPage * (page - 1) + 1, + formatJustDate(item?.createDate), + formatJustDate(item.reciveDate), + `${item.killHouse.name} (${item.killHouse.killHouseOperator.user.mobile})`, + item?.slaughterHouse + ? item?.slaughterHouse?.name + : item?.killHouse?.name, + item?.exportCountry, + `${item?.poultry?.userprofile?.fullName} (${item?.poultry?.userprofile?.mobile})`, + item.killCapacity, + item.IndexWeight, + (item.IndexWeight * item.killCapacity)?.toLocaleString(), + getItemState(item), + item?.acceptRejectDate ? formatTime(item?.acceptRejectDate) : "-", + item?.directBuyingMessage, + ]; + }); + + setTableDataArchive(a); + }, [data]); + + useEffect(() => { + fetchApiData(1); + }, [selectedDate1, selectedDate2, perPage, activeTab]); + + const handleSubmit = async (event) => { + event.preventDefault(); + dispatch(LOADING_START()); + + try { + const response = await axios.get( + `kill_request/?export=true&type=${ + activeTab === 0 ? "pending" : "archive" + }&role=${getRoleFromUrl()}&search=filter&value=${textValue}&date1=${selectedDate1}&date2=${selectedDate2}&page=${1}&page_size=${perPage}` + ); + setData(response.data.results); + setTotalRows(response.data.count); + dispatch(LOADING_END()); + } catch (error) { + console.error("Error fetching data:", error); + } + }; + + const userKey = useSelector((state) => state.userSlice.userProfile.key); + + return ( + + + + + + + + +
    + + + + + ( + + )} + value={selectedDate1} + onChange={(e) => { + setSelectedDate1(moment(e).format("YYYY-MM-DD")); + }} + /> + + + ( + + )} + value={selectedDate2} + onChange={(e) => { + setSelectedDate2(moment(e).format("YYYY-MM-DD")); + }} + /> + + {activeTab === 1 && ( + + + + + + + + )} + +
    + + {activeTab === 0 ? ( + + ) : ( + + )} +
    +
    + ); +}; diff --git a/src/features/province/components/province-fees-overview/ProvinceFeesOverview.js b/src/features/province/components/province-fees-overview/ProvinceFeesOverview.js new file mode 100644 index 0000000..c826c52 --- /dev/null +++ b/src/features/province/components/province-fees-overview/ProvinceFeesOverview.js @@ -0,0 +1,358 @@ +import axios from "axios"; +import { + Button, + Checkbox, + FormControlLabel, + TextField, + Tooltip, + Typography, +} from "@mui/material"; +import { useContext, useEffect, useState } from "react"; +import { Grid } from "../../../../components/grid/Grid"; +import { PageTable } from "../../../../components/page-table/PageTable"; +import { SPACING } from "../../../../data/spacing"; +import { ProvinceFeesTotalOverview } from "../province-fees-total-overview/ProvinceFeesTotalOverview"; +import { RiFileExcel2Fill, RiSearchLine } from "react-icons/ri"; +import { useSelector } from "react-redux"; +import { DatePicker } from "@mui/x-date-pickers"; +import moment from "moment"; +import { AppContext } from "../../../../contexts/AppContext"; +import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl"; + +export const ProvinceFeesOverview = () => { + const authToken = useSelector((state) => state.userSlice.authToken); + const [data, setData] = useState([]); + const [loading, setLoading] = useState(false); + const [totalRows, setTotalRows] = useState(0); + const [perPage, setPerPage] = useState(10); + const [textValue, setTextValue] = useState(""); + const [withDate, setWithDate] = useState(false); + + const handleTextChange = (event) => { + setTextValue(event.target.value); + }; + + const [, , selectedDate1, setSelectedDate1, selectedDate2, setSelectedDate2] = + useContext(AppContext); + + useEffect(() => { + const currentDate = moment(new Date()).format("YYYY-MM-DD"); + setSelectedDate1(currentDate); + setSelectedDate2(currentDate); + }, []); + + const fetchApiData = async (page, textValue) => { + setLoading(true); + const response = await axios.get( + `kill_house_total_wage/?search=filter&value=${textValue}&type=total&page=${page}&role=${getRoleFromUrl()}&page_size=${perPage}${ + withDate ? `&date1=${selectedDate1}&date2=${selectedDate2}` : `` + }` + ); + setData(response.data.results); + setTotalRows(response.data.count); + setLoading(false); + }; + + const handlePageChange = (page) => { + fetchApiData(page, textValue); + }; + + const handlePerRowsChange = async (newPerPage, page) => { + setLoading(true); + const response = await axios.get( + `kill_house_total_wage/?search=filter&value=${textValue}&type=total&page=${page}&role=${getRoleFromUrl()}&page_size=${newPerPage}${ + withDate ? `&date1=${selectedDate1}&date2=${selectedDate2}` : `` + }` + ); + + setData(response.data.results); + setTotalRows(response.data.count); + setPerPage(newPerPage); + setLoading(false); + }; + + useEffect(() => { + fetchApiData(1); + }, []); + + const handleSubmit = async (event) => { + event.preventDefault(); + setLoading(true); + + try { + const response = await axios.get( + `kill_house_total_wage/?search=filter&value=${textValue}&role=${getRoleFromUrl()}&type=total${ + withDate ? `&date1=${selectedDate1}&date2=${selectedDate2}` : `` + }` + ); + setData(response.data.results); + setTotalRows(response.data.count); + } catch (error) { + console.error("Error fetching data:", error); + } finally { + setLoading(false); + } + }; + + useEffect(() => { + fetchApiData(1); + }, [selectedDate1, selectedDate2, withDate]); + + const columns = [ + { + name: "خریدار", + selector: (item) => { + const type = item?.info?.killer ? "کشتارکن" : "کشتارگاه"; + return `${type} ${item?.info?.killHouseName} - ${item?.info?.killHouseFullname} (${item?.info?.killHouseMobile})`; + }, + sortable: true, + wrap: true, + allowOverflow: true, + center: true, + // width: "90px", + }, + { + name: "شهر", + selector: (item) => `${item?.info?.killHouseCity?.toLocaleString()}`, + sortable: true, + wrap: true, + allowOverflow: true, + center: true, + width: "80px", + }, + { + name: "تعداد کل سفارشات", + selector: (item) => `${item?.info?.totalCount?.toLocaleString()}`, + sortable: true, + wrap: true, + allowOverflow: true, + center: true, + width: "90px", + }, + { + name: "تعداد کل قطعه ها", + selector: (item) => `${item?.info?.totalQuantity?.toLocaleString()}`, + sortable: true, + wrap: true, + allowOverflow: true, + center: true, + width: "90px", + }, + { + name: "وزن کل (کیلوگرم)", + selector: (item) => `${item?.info?.totalWeight?.toLocaleString()}`, + sortable: true, + wrap: true, + allowOverflow: true, + center: true, + width: "90px", + }, + { + name: "مبلغ کل (﷼)", + selector: (item) => `${item?.info?.totalWage?.toLocaleString()}`, + sortable: true, + wrap: true, + allowOverflow: true, + center: true, + width: "90px", + }, + { + name: "تعداد سفارشات پرداخت شده", + selector: (item) => `${item?.info?.paidCount?.toLocaleString()}`, + sortable: true, + wrap: true, + allowOverflow: true, + center: true, + width: "90px", + }, + { + name: "تعداد قطعات پرداخت شده", + selector: (item) => `${item?.info?.totalPaidQuantity?.toLocaleString()}`, + sortable: true, + wrap: true, + allowOverflow: true, + center: true, + width: "90px", + }, + { + name: "وزن قطعات پرداخت شده (کیلوگرم)", + selector: (item) => `${item?.info?.totalWeightPaid?.toLocaleString()}`, + sortable: true, + wrap: true, + allowOverflow: true, + center: true, + width: "90px", + }, + { + name: "مبلغ قطعات پرداخت شده (﷼)", + selector: (item) => `${item?.info?.totalPaidWage?.toLocaleString()}`, + sortable: true, + wrap: true, + allowOverflow: true, + center: true, + width: "90px", + }, + { + name: "تعداد سفارشات پرداخت نشده", + selector: (item) => `${item?.info?.unpaidCount?.toLocaleString()}`, + sortable: true, + wrap: true, + allowOverflow: true, + center: true, + width: "90px", + }, + { + name: "تعداد قطعات پرداخت نشده", + selector: (item) => + `${item?.info?.totalUnpaidQuantity?.toLocaleString()}`, + sortable: true, + wrap: true, + allowOverflow: true, + center: true, + width: "90px", + }, + { + name: "وزن قطعات پرداخت نشده (کیلوگرم)", + selector: (item) => `${item?.info?.totalWeightUnpaid?.toLocaleString()}`, + sortable: true, + wrap: true, + allowOverflow: true, + center: true, + width: "90px", + }, + { + name: "مبلغ قطعات پرداخت نشده (﷼)", + selector: (item) => `${item?.info?.totalUnpaidWage?.toLocaleString()}`, + sortable: true, + wrap: true, + allowOverflow: true, + center: true, + width: "90px", + }, + ]; + + return ( + + + + + اطلاعات کلی + + + setWithDate(!withDate)} + color="primary" + /> + } + /> + + + ( + + )} + value={selectedDate1} + onChange={(e) => { + setSelectedDate1(moment(e).format("YYYY-MM-DD")); + }} + /> + + + ( + + )} + value={selectedDate2} + onChange={(e) => { + setSelectedDate2(moment(e).format("YYYY-MM-DD")); + }} + /> + + +
    + + + + + + + + +
    +
    + } + columns={columns} + data={data} + progressPending={loading} + pagination + paginationServer + paginationTotalRows={totalRows} + onChangeRowsPerPage={handlePerRowsChange} + onChangePage={handlePageChange} + /> + + ); +}; diff --git a/src/features/province/components/province-fees-total-overview/ProvinceFeesTotalOverview.js b/src/features/province/components/province-fees-total-overview/ProvinceFeesTotalOverview.js new file mode 100644 index 0000000..b35e87d --- /dev/null +++ b/src/features/province/components/province-fees-total-overview/ProvinceFeesTotalOverview.js @@ -0,0 +1,61 @@ +import { useEffect } from "react"; +import { useDispatch, useSelector } from "react-redux"; +import { SimpleTable } from "../../../../components/simple-table/SimpleTable"; +import { getProvinceFeeTotalOverviewService } from "../../services/get-province-fee-total-overview"; + +export const ProvinceFeesTotalOverview = () => { + const dispatch = useDispatch(); + const { getProvinceFeeTotalOverview } = useSelector( + (state) => state.provinceSlice + ); + + useEffect(() => { + dispatch(getProvinceFeeTotalOverviewService()); + }, []); + + return ( + + ); +}; diff --git a/src/features/province/components/province-files-state/ProvinceFilesState.js b/src/features/province/components/province-files-state/ProvinceFilesState.js new file mode 100644 index 0000000..7172121 --- /dev/null +++ b/src/features/province/components/province-files-state/ProvinceFilesState.js @@ -0,0 +1,70 @@ +import { + // IconButton, + ToggleButton, + ToggleButtonGroup, + Typography, +} from "@mui/material"; +import { useState } from "react"; +// import { useSelector } from "react-redux"; +import { Grid } from "../../../../components/grid/Grid"; +import { SPACING } from "../../../../data/spacing"; + +// import { formatJustDate } from "../../../../utils/formatTime"; + +import { ProvinceCaseStatusComponent } from "../province-case-status/ProvinceCaseStatusComponent"; + +import { ProvinceCases } from "../province-cases/ProvinceCases"; +import { ProvinceManageContradictions } from "../province-manage-contradictions/ProvinceManageContradictions"; +import { ProvinceKillbroadcastInDetail } from "../province-kill-broadcast-in-detail/ProvinceKillbroadcastInDetail"; +import { ProvinceSlaughterSurveillance } from "../province-slaughter-surveillance/ProvinceSlaughterSurveillance"; + +export const ProvinceFilesState = () => { + const [view, setView] = useState("new"); + + const handleChange = (event, newAlignment) => { + if (newAlignment) { + setView(newAlignment); + } + }; + + // const updateTable = () => { + // fetchApiData(1); + // }; + + return ( + + + + نمایش بصورت: + + پرونده ای + گزارش مغایرت + با جزئیات + جزئیات کشتار و پخش + + جزئیات پایش کشتارگاه + + + + + + {view === "atlas" && } + {view === "new" && } + {view === "contradictions" && } + {view === "killdetail" && } + {view === "killhouseSurveillance" && } + + + ); +}; diff --git a/src/features/province/components/province-free-sale-add-buyer/ProvinceFreeSaleAddBuyer.js b/src/features/province/components/province-free-sale-add-buyer/ProvinceFreeSaleAddBuyer.js new file mode 100644 index 0000000..ba169bb --- /dev/null +++ b/src/features/province/components/province-free-sale-add-buyer/ProvinceFreeSaleAddBuyer.js @@ -0,0 +1,306 @@ +import React, { useContext, useEffect, useState } from "react"; +import { Grid } from "../../../../components/grid/Grid"; +import { + Button, + FormControl, + FormControlLabel, + FormLabel, + Radio, + RadioGroup, + TextField, +} from "@mui/material"; +import { Yup } from "../../../../lib/yup/yup"; +import { useFormik } from "formik"; +import { SPACING } from "../../../../data/spacing"; +import { provinceFreeSalesSubmitBuyer } from "../../services/province-free-sales-submit-buyer"; +import { AppContext } from "../../../../contexts/AppContext"; +import { useDispatch } from "react-redux"; +import { DRAWER } from "../../../../lib/redux/slices/appSlice"; +import { provinceFreeSalesEditBuyer } from "../../services/province-free-sales-edit-buyer"; + +export const ProvinceFreeSaleAddBuyer = ({ fetchApiData, isEdit, item }) => { + const [openNotif] = useContext(AppContext); + const dispatch = useDispatch(); + const formik = useFormik({ + initialValues: { + fullname: item?.fullname ? item?.fullname : "", + mobile: item?.mobile ? item?.mobile : "", + province: item?.province ? item?.province : "", + city: item?.city ? item?.city : "", + unitname: item?.unitName ? item?.unitName : "", + uniqueCode: item?.killHouseUniqueId ? item?.killHouseUniqueId : "", + }, + validationSchema: Yup.object({ + fullname: Yup.string() + .required("این فیلد اجباری است!") + .matches( + /^[^*&^%$#@!()|.]*$/, + "این فیلد نباید شامل کاراکترهای ویژه باشد!" + ), + mobile: Yup.string() + .required("شماره موبایل الزامی است") + .min(11, "شماره موبایل باید 11 رقم باشد") + .max(11, "شماره موبایل باید 11 رقم باشد") + .matches(/^09\d{9}$/, "شماره موبایل باید با 09 شروع شود و 11 رقم باشد"), + province: Yup.string() + .required("این فیلد اجباری است!") + .matches( + /^[^*&^%$#@!()|.]*$/, + "این فیلد نباید شامل کاراکترهای ویژه باشد!" + ), + city: Yup.string() + .required("این فیلد اجباری است!") + .matches( + /^[^*&^%$#@!()|.]*$/, + "این فیلد نباید شامل کاراکترهای ویژه باشد!" + ), + unitname: Yup.string().matches( + /^[^*&^%$#@!()|.]*$/, + "این فیلد نباید شامل کاراکترهای ویژه باشد!" + ), + uniqueCode: Yup.string().matches( + /^[^*&^%$#@!()|.]*$/, + "این فیلد نباید شامل کاراکترهای ویژه باشد!" + ), + }), + }); + + useEffect(() => { + formik.validateForm(); + }, []); + + const [type, setType] = useState(item?.type ? item?.type : "killhouse"); + + const handleChange = (event) => { + setType(event.target.value); + }; + + const isFormValid = () => { + if (type === "killhouse") { + return formik.isValid && formik.values.unitname; + } else { + return formik.isValid; + } + }; + + return ( + + + + + + + + + نوع خریدار + + + } + label="کشتارگاه" + /> + } + label="کشتارکن" + /> + + + + {type === "killhouse" && ( + + + + + + )} + + + + + ); +}; diff --git a/src/features/province/components/province-free-sale-edit-request/ProvinceFreeSaleEditRequest.js b/src/features/province/components/province-free-sale-edit-request/ProvinceFreeSaleEditRequest.js new file mode 100644 index 0000000..971c348 --- /dev/null +++ b/src/features/province/components/province-free-sale-edit-request/ProvinceFreeSaleEditRequest.js @@ -0,0 +1,552 @@ +import React, { useContext, useEffect, useState } from "react"; +import { SPACING } from "../../../../data/spacing"; +import { Grid } from "../../../../components/grid/Grid"; +import { Yup } from "../../../../lib/yup/yup"; +import { useFormik } from "formik"; +import { NumberInput } from "../../../../components/number-format-custom/NumberFormatCustom"; +import { + Autocomplete, + Button, + Divider, + FormControl, + FormControlLabel, + FormLabel, + IconButton, + InputAdornment, + Radio, + RadioGroup, + TextField, + Typography, +} from "@mui/material"; +import { CarPelak } from "../../../../components/car-pelak/CarPelak"; +import { useDispatch } from "react-redux"; +import { provinceFreeSaleEditRequestService } from "../../services/province-free-sale-edit-request"; +import { DRAWER } from "../../../../lib/redux/slices/appSlice"; +import { AppContext } from "../../../../contexts/AppContext"; +import { provinceFreeSaleBuyers } from "../../services/province-free-sales-get-buyers"; +import { avicultureGetWageType } from "../../../aviculture/services/aviculture-get-wage-type"; +import AddIcon from "@mui/icons-material/Add"; +import RemoveIcon from "@mui/icons-material/Remove"; + +export const ProvinceFreeSaleEditRequest = ({ item, fetchApiData }) => { + const [openNotif] = useContext(AppContext); + const [submitDriver, setSubmitDriver] = useState( + item?.outProvinceDriverInfo?.driverName ? true : false + ); + const dispatch = useDispatch(); + const formik = useFormik({ + initialValues: { + noChicken: item?.quantity ? item?.quantity : "", + weight: item?.IndexWeight ? item?.IndexWeight : "", + }, + validationSchema: Yup.object({ + noChicken: Yup.string() + .required("این فیلد اجباری است!") + .typeError("لطفا عدد وارد کنید!"), + weight: Yup.number() + .test("weight", "وزن را تا دو رقم اعشار وارد کنید", (val, context) => { + return ( + context.originalValue && + context.originalValue.toString().length <= 4 + ); + }) + .required("این فیلد اجباری است!") + .typeError("لطفا وزن را وارد کنید!"), + }), + }); + + const formikDriver = useFormik({ + initialValues: { + driverName: item?.outProvinceDriverInfo?.driverName + ? item?.outProvinceDriverInfo?.driverName + : "", + driverMobile: item?.outProvinceDriverInfo?.driverMobile + ? item?.outProvinceDriverInfo?.driverMobile + : "", + driverCar: item?.outProvinceDriverInfo?.driverCar + ? item?.outProvinceDriverInfo?.driverCar + : "", + driverhealthCode: item?.outProvinceDriverInfo?.driverhealthCode + ? item?.outProvinceDriverInfo?.driverhealthCode + : "", + }, + validationSchema: Yup.object({ + driverName: Yup.string().required("این فیلد اجباری است!"), + driverMobile: Yup.string().required("این فیلد اجباری است!"), + driverCar: Yup.string().required("این فیلد اجباری است!"), + driverhealthCode: Yup.string().required("این فیلد اجباری است!"), + }), + }); + + const formikPayer = useFormik({ + initialValues: { + mobile: "", + weight: "", + quantity: "", + }, + validationSchema: Yup.object({ + mobile: Yup.string() + .required("شماره موبایل الزامی است") + .min(11, "شماره موبایل باید 11 رقم باشد") + .max(11, "شماره موبایل باید 11 رقم باشد") + .matches(/^09\d{9}$/, "شماره موبایل باید با 09 شروع شود و 11 رقم باشد"), + weight: Yup.number(), + quantity: Yup.number(), + }), + }); + + const [driverPelak, setDriverPelak] = useState([]); + + const carPelakHandleChange = (pelak1, pelak2, pelak3, pelak4) => { + setDriverPelak([pelak1, pelak2, pelak3, pelak4]); + }; + + const [buyersData, setBuyersData] = useState([]); + const [buyerSelected, setBuyerSelected] = useState(); + const [buyerItem, setBuyerItem] = useState(); + const [wageType, setWageType] = useState(); + + useEffect(() => { + setBuyerSelected(item?.outProvincePoultryRequestBuyer?.key); + dispatch(avicultureGetWageType()).then((r) => { + setWageType(r.payload.data.status); + }); + + dispatch(provinceFreeSaleBuyers()).then((r) => { + setBuyersData(r.payload.data); + }); + }, []); + + const [payerValue, setPayerValue] = useState("poultry"); + + const handleChangePayer = (event) => { + setPayerValue(event.target.value); + if (event.target.value === "poultry") { + formikPayer.setFieldValue("mobile", item.poultry.user.mobile); + } else if (buyerItem) { + formikPayer.setFieldValue("mobile", buyerItem.mobile); + } else { + formikPayer.setFieldValue( + "mobile", + item?.outProvincePoultryRequestBuyer.mobile + ); + } + }; + + const wageValidation = () => { + if (wageType) { + return formikPayer.isValid; + } else { + return true; + } + }; + + const isFormValid = () => { + if (payerValue === "poultry") { + if (submitDriver) { + return ( + formik.isValid && + wageValidation() && + buyerSelected && + formikDriver && + driverPelak[0] + ); + } else { + return ( + formik.isValid && + formikPayer.isValid && + buyerSelected && + wageValidation() + ); + } + } else { + if (submitDriver) { + return ( + formik.isValid && + buyerSelected && + formikDriver && + driverPelak[0] && + wageValidation() + ); + } else { + return formik.isValid && buyerSelected && wageValidation(); + } + } + }; + + useEffect(() => { + formikPayer.setFieldValue("mobile", item.poultry.user.mobile); + }, []); + + return ( + + + + + وزن کل:{" "} + + + {Math.floor(item.IndexWeight * item.quantity)?.toLocaleString()} + + {" "} + + کیلوگرم + ), + }} + value={formik.values.weight} + error={formik.touched.weight ? Boolean(formik.errors.weight) : null} + onChange={formik.handleChange} + onBlur={formik.handleBlur} + helperText={ + formik.touched.weight && Boolean(formik.errors.weight) + ? formik.errors.weight + : null + } + /> + + + وزن کل:{" "} + + + {Math.floor( + parseInt(formik.values.noChicken) * + parseFloat(formik.values.weight) + )?.toLocaleString()} + {"‌ ‌"} + کیلوگرم + + + + اطلاعات خریدار + option.disabled} + options={ + buyersData + ? buyersData?.map((i) => ({ + id: i.key, + label: `${i?.fullname} / ${i.mobile} / استان ${i?.province}/ ${i?.city}`, + item: i, + mobile: i.mobile, + })) + : [] + } + onChange={(event, value) => { + setBuyerSelected(value.id); + setBuyerItem(value.item); + if (payerValue === "buyer") { + formikPayer.setFieldValue("mobile", value.mobile); + } + }} + renderInput={(params) => ( + + )} + /> + + + خریدار:{"‌ ‌"} + + {buyerItem ? ( + + {" "} + {buyerItem?.fullname} ({buyerItem?.mobile}) + + ) : ( + + {" "} + {item?.outProvincePoultryRequestBuyer?.fullname} ( + {item?.outProvincePoultryRequestBuyer?.mobile}) + + )} + + + { + setSubmitDriver(!submitDriver); + }} + > + + {" "} + افزودن اطلاعات خودرو + + + {submitDriver ? : } + + {submitDriver && ( + + اطلاعات خودرو حمل + + + + + + + )} + + {wageType && ( + <> + + + پرداخت کننده + + + } + label="مرغدار" + /> + } + label="خریدار" + /> + + + + + از این قسمت میتوانید تلفن{" "} + {payerValue === "poultry" ? "مرغدار" : "خریدار"} را ویرایش کنید. + + + + + )} + + + + + + ); +}; diff --git a/src/features/province/components/province-free-sales-accepted-requests-operations/ProvinceFreeSalesAcceptedRequestsOperations.js b/src/features/province/components/province-free-sales-accepted-requests-operations/ProvinceFreeSalesAcceptedRequestsOperations.js new file mode 100644 index 0000000..d3c485c --- /dev/null +++ b/src/features/province/components/province-free-sales-accepted-requests-operations/ProvinceFreeSalesAcceptedRequestsOperations.js @@ -0,0 +1,210 @@ +import React, { useContext, useState } from "react"; +import { useDispatch } from "react-redux"; +import { AppContext } from "../../../../contexts/AppContext"; +import { Grid } from "../../../../components/grid/Grid"; +import { + Button, + IconButton, + Popover, + List, + ListItemButton, + ListItemIcon, + ListItemText, + Typography, +} from "@mui/material"; +import TuneIcon from "@mui/icons-material/Tune"; +import { + CLOSE_MODAL, + DRAWER, + OPEN_MODAL, +} from "../../../../lib/redux/slices/appSlice"; +import { provinceOutRequestCancelRequest } from "../../services/provinceOutRequestCancelRequest"; +import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl"; +import { ProvinceFreeSaleEditRequest } from "../province-free-sale-edit-request/ProvinceFreeSaleEditRequest"; +import EditIcon from "@mui/icons-material/Edit"; +import CloseIcon from "@mui/icons-material/Close"; + +export const ProvinceFreeSalesAcceptedRequestsOperations = ({ + fetchApiData, + item, +}) => { + const dispatch = useDispatch(); + + const [anchorEl, setAnchorEl] = useState(null); + + const handleClick = (event) => { + setAnchorEl(event.currentTarget); + }; + + const handleClose = () => { + setAnchorEl(null); + }; + + const open = Boolean(anchorEl); + const id = open ? "popover" : undefined; + + const [openNotif] = useContext(AppContext); + const role = getRoleFromUrl(); + + const handleEdit = () => { + handleClose(); + dispatch( + DRAWER({ + title: "ویرایش درخواست", + right: !(window.innerWidth <= 600), + bottom: window.innerWidth <= 600, + content: ( + + ), + }) + ); + }; + + const handleCancelRequest = () => { + handleClose(); + dispatch( + OPEN_MODAL({ + title: "آیا از لغو درخواست مطمئن هستید؟", + content: ( + + + + + ), + }) + ); + }; + + const options = [ + { + key: "edit", + label: "ویرایش", + color: "primary.main", + icon: , + action: handleEdit, + disabled: Boolean(item.quarantineCode || item?.outState === "پرداخت شده"), + }, + { + key: "cancel", + label: "لغو", + color: "error.main", + icon: , + action: handleCancelRequest, + disabled: + !item.provinceState === "pending" || + !item.provinceState === "accepted" || + item?.outState === "پرداخت شده" || + item.quarantineCode, + }, + ]; + + return ( + + + + + + + {options.map((option) => ( + { + if (option.disabled) { + return; + } + option.action(); + }} + disabled={Boolean(option.disabled)} + sx={{ + borderRadius: 1, + mb: 0.5, + color: option.disabled ? "text.disabled" : option.color, + "&:last-of-type": { + mb: 0, + }, + }} + > + + {option.icon} + + + {option.label} + + } + /> + + ))} + + + + ); +}; diff --git a/src/features/province/components/province-free-sales-accepted-requests/ProvinceFreeSalesAcceptedRequests.js b/src/features/province/components/province-free-sales-accepted-requests/ProvinceFreeSalesAcceptedRequests.js new file mode 100644 index 0000000..aea308f --- /dev/null +++ b/src/features/province/components/province-free-sales-accepted-requests/ProvinceFreeSalesAcceptedRequests.js @@ -0,0 +1,499 @@ +import React, { useContext, useEffect, useState } from "react"; +import { Button, Chip, TextField, Tooltip } from "@mui/material"; +import { DatePicker } from "@mui/x-date-pickers"; +import moment from "moment"; +import { useDispatch } from "react-redux"; +import axios from "axios"; +import { RiSearchLine } from "react-icons/ri"; +import { AppContext } from "../../../../contexts/AppContext"; +import { RiFileExcel2Fill } from "react-icons/ri"; +import { useSelector } from "react-redux"; + +import { + LOADING_END, + LOADING_START, + OPEN_MODAL, +} from "../../../../lib/redux/slices/appSlice"; +import ResponsiveTable from "../../../../components/responsive-table/ResponsiveTable"; +import { Grid } from "../../../../components/grid/Grid"; +import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl"; +import { ProvinceFreeSalesAcceptedRequestsOperations } from "../province-free-sales-accepted-requests-operations/ProvinceFreeSalesAcceptedRequestsOperations"; +import { formatJustDate } from "../../../../utils/formatTime"; +import { VetFarmSubmitClearanceCode } from "../../../vet-farm/components/vet-farm-submit-clearance-code/VetFarmSubmitClearanceCode"; + +export const ProvinceFreeSalesAcceptedRequests = ({ state }) => { + const [data, setData] = useState([]); + const [totalRows, setTotalRows] = useState(0); + const [perPage, setPerPage] = useState(10); + const [textValue, setTextValue] = useState(""); + const [page, setPage] = useState(1); + const [accepttableData, setaccepteTableData] = useState([]); + const [columnsRejected, setcolumnsRejected] = useState([]); + + const [, , selectedDate1, setSelectedDate1, selectedDate2, setSelectedDate2] = + useContext(AppContext); + const userKey = useSelector((state) => state.userSlice.userProfile.key); + + const fetchApiData = async (page) => { + dispatch(LOADING_START()); + const response = await axios.get( + `out-province-poultry-requests/?search=filter&value=${textValue}&page=${page}&role=${getRoleFromUrl()}&page_size=${perPage}&date1=${selectedDate1}&date2=${selectedDate2}&state=${state}` + ); + + dispatch(LOADING_END()); + setData(response.data.results); + setTotalRows(response.data.count); + }; + + const handlePageChange = (page) => { + fetchApiData(page); + setPage(page); + }; + const dispatch = useDispatch(); + useEffect(() => { + const currentDate = moment(new Date()).format("YYYY-MM-DD"); + setSelectedDate1(currentDate); + setSelectedDate2(currentDate); + }, []); + + const handleTextChange = (event) => { + setTextValue(event.target.value); + }; + + const handlePerRowsChange = (perRows) => { + setPerPage(perRows); + setPage(1); + }; + const updateTable = () => { + fetchApiData(page !== 0 ? page : 1); + }; + // const updateTable = () => { + // fetchApiData(page !== 0 ? page : 1); + // }; + + useEffect(() => { + const d = data?.map((item, i) => { + return [ + page === 1 ? i + 1 : i + perPage * (page - 1) + 1, + getRoleFromUrl() === "CityOperator" ? ( + "-" + ) : ( + + ), + , + `${item?.totalWageAmount?.toLocaleString()} ریال`, + `${item?.registrar?.fullname}`, + item.orderCode, + item.buyer?.firstName + ? `${item.buyer?.firstName} ${item.buyer?.lastName} (${item.buyer?.mobile}) / ${item.buyer.province} - ${item.buyer.city}` + : item?.outProvincePoultryRequestBuyer.type === "killhouse" + ? `کشتارگاه ${item.buyerFullname} (${item.buyerMobile}) / شناسه یکتا ${item.outProvincePoultryRequestBuyer?.killHouseUniqueId} / ${item.buyerProvince} - ${item.buyerCity}` + : `کشتارکن ${item.buyerFullname} (${ + item.buyerMobile + }) / نام کشتارگاه ${ + item.killerKillHouseUnitName ? item.killerKillHouseUnitName : "-" + } / شناسه یکتا ${ + item.killerKillHouseUniqueId ? item.killerKillHouseUniqueId : "-" + } / استان ${ + item.killerKillHouseProvince ? item.killerKillHouseProvince : "-" + } / شهر ${ + item.killerKillHouseCity ? item.killerKillHouseCity : "-" + }`, + item?.outProvincePoultryRequestBuyer?.type === "killhouse" + ? "محل کشتارگاه" + : item?.killerKillHouseUnitName + ? `کشتارگاه ${item?.killerKillHouseUnitName} / ${item?.killerKillHouseProvince} / ${item?.killerKillHouseCity}` + : "-", + item?.hasWage ? item?.payerFullname : "-", + `${item.poultry?.unitName} (${item.poultry.user.mobile})`, + + + , + formatJustDate(item?.createDate), + formatJustDate(item.sendDate), + item.hatching.age, + item.IndexWeight?.toLocaleString(), + item.quantity.toLocaleString(), + Math.floor(item.IndexWeight * item.quantity)?.toLocaleString(), + item?.freezing ? "انجماد" : "عادی", + item?.hasWage ? "دارد" : "ندارد", + item.hatching?.city, + item.hatching?.province, + item.hatching.leftOver?.toLocaleString(), + item.hatching.hatchingQuantity?.toLocaleString(), + item?.outProvinceDriverInfo?.driverCar + ? item?.outProvinceDriverInfo?.driverCar + : "-", + item?.outProvinceDriverInfo?.driverPelak + ? item?.outProvinceDriverInfo?.driverPelak + : "-", + item?.outProvinceDriverInfo?.driverName + ? item?.outProvinceDriverInfo?.driverName + : "-", + item?.outProvinceDriverInfo?.driverMobile + ? item?.outProvinceDriverInfo?.driverMobile + : "-", + item?.outProvinceDriverInfo?.driverhealthCode + ? item?.outProvinceDriverInfo?.driverhealthCode + : "-", + // getBuyerType(item), + item?.outProvinceDriverInfo?.driverhealthCode, + ]; + }); + setaccepteTableData(d); + + const r = data?.map((item, i) => { + return [ + page === 1 ? i + 1 : i + perPage * (page - 1) + 1, + + , + `${item?.totalWageAmount?.toLocaleString()} ریال`, + item.outProvinceRequestCanceller?.fullname + ? `${item.outProvinceRequestCanceller?.fullname} (${item.outProvinceRequestCanceller?.mobile})` + : item.agent?.fullname + ? `${item.agent?.fullname} (${item.agent?.mobile})` + : "-", + `${item?.registrar?.fullname}`, + item.orderCode, + item.buyer?.firstName + ? `${item.buyer?.firstName} ${item.buyer?.lastName} (${item.buyer?.mobile}) / ${item.buyer.province} - ${item.buyer.city}` + : item?.outProvincePoultryRequestBuyer.type === "killhouse" + ? `کشتارگاه ${item.buyerFullname} (${item.buyerMobile}) / شناسه یکتا ${item.outProvincePoultryRequestBuyer?.killHouseUniqueId} / ${item.buyerProvince} - ${item.buyerCity}` + : `کشتارکن ${item.buyerFullname} (${ + item.buyerMobile + }) / نام کشتارگاه ${ + item.killerKillHouseUnitName ? item.killerKillHouseUnitName : "-" + } / شناسه یکتا ${ + item.killerKillHouseUniqueId ? item.killerKillHouseUniqueId : "-" + } / استان ${ + item.killerKillHouseProvince ? item.killerKillHouseProvince : "-" + } / شهر ${ + item.killerKillHouseCity ? item.killerKillHouseCity : "-" + }`, + item?.outProvincePoultryRequestBuyer?.type === "killhouse" + ? "محل کشتارگاه" + : item?.killerKillHouseUnitName + ? `کشتارگاه ${item?.killerKillHouseUnitName} / ${item?.killerKillHouseProvince} / ${item?.killerKillHouseCity}` + : "-", + item?.hasWage ? item?.payerFullname : "-", + `${item.poultry?.unitName} (${item.poultry.user.mobile})`, + item.quarantineCode ? item?.quarantineCode : "-", + formatJustDate(item?.createDate), + formatJustDate(item.sendDate), + item.IndexWeight?.toLocaleString(), + item.hatching.age, + item.quantity.toLocaleString(), + Math.floor(item.IndexWeight * item.quantity)?.toLocaleString(), + item?.freezing ? "انجماد" : "عادی", + item?.hasWage ? "دارد" : "ندارد", + item.hatching?.city, + item.hatching?.province, + item.hatching.leftOver?.toLocaleString(), + item.hatching.hatchingQuantity?.toLocaleString(), + item?.outProvinceDriverInfo?.driverCar + ? item?.outProvinceDriverInfo?.driverCar + : "-", + item?.outProvinceDriverInfo?.driverPelak + ? item?.outProvinceDriverInfo?.driverPelak + : "-", + item?.outProvinceDriverInfo?.driverName + ? item?.outProvinceDriverInfo?.driverName + : "-", + item?.outProvinceDriverInfo?.driverMobile + ? item?.outProvinceDriverInfo?.driverMobile + : "-", + item?.outProvinceDriverInfo?.driverhealthCode + ? item?.outProvinceDriverInfo?.driverhealthCode + : "-", + ]; + }); + + setcolumnsRejected(r); + }, [data]); + + // useEffect(() => { + // const d = data?.map((item, i) => { + // return [ + // page === 1 ? i + 1 : i + perPage * (page - 1) + 1, + // item?.poultryRequest?.freezing ? "انجماد" : "عادی", + // ]; + // }); + + // setaccepteTableData(d); + // }, [data]); + + useEffect(() => { + fetchApiData(1); + }, [dispatch, selectedDate1, selectedDate2, perPage]); + + const handleSubmit = async (event) => { + event.preventDefault(); + dispatch(LOADING_START()); + + try { + const response = await await axios.get( + `out-province-poultry-requests/?search=filter&value=${textValue}&date1=${selectedDate1}&date2=${selectedDate2}&state=${state}&role=${getRoleFromUrl()}` + ); + + setData(response.data.results); + setTotalRows(response.data.count); + dispatch(LOADING_END()); + } catch (error) { + console.error("Error fetching data:", error); + } + }; + + return ( + + + + ( + + )} + value={selectedDate1} + onChange={(e) => { + setSelectedDate1(moment(e).format("YYYY-MM-DD")); + }} + /> + + + ( + + )} + value={selectedDate2} + onChange={(e) => { + setSelectedDate2(moment(e).format("YYYY-MM-DD")); + }} + /> + +
    + + + + + + + + + + +
    + {/* + + */} + + + + +
    + ); +}; diff --git a/src/features/province/components/province-free-sales-manage-buyers/ProvinceFreeSalsesManageBuyers.js b/src/features/province/components/province-free-sales-manage-buyers/ProvinceFreeSalsesManageBuyers.js new file mode 100644 index 0000000..a7b9547 --- /dev/null +++ b/src/features/province/components/province-free-sales-manage-buyers/ProvinceFreeSalsesManageBuyers.js @@ -0,0 +1,362 @@ +import React, { useContext, useEffect, useState } from "react"; +import { + Button, + IconButton, + Popover, + TextField, + Tooltip, + List, + ListItemButton, + ListItemIcon, + ListItemText, + Typography, +} from "@mui/material"; +import TuneIcon from "@mui/icons-material/Tune"; +import ToggleOnIcon from "@mui/icons-material/ToggleOn"; +import ToggleOffIcon from "@mui/icons-material/ToggleOff"; +import { DRAWER } from "../../../../lib/redux/slices/appSlice"; +import { ProvinceFreeSaleAddBuyer } from "../province-free-sale-add-buyer/ProvinceFreeSaleAddBuyer"; +import { useDispatch, useSelector } from "react-redux"; +import axios from "axios"; +import { RiFileExcel2Fill, RiSearchLine } from "react-icons/ri"; +import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl"; +import { + LOADING_END, + LOADING_START, +} from "../../../../lib/redux/slices/appSlice"; +import { Grid } from "../../../../components/grid/Grid"; +import ResponsiveTable from "../../../../components/responsive-table/ResponsiveTable"; +import { SPACING } from "../../../../data/spacing"; +import EditIcon from "@mui/icons-material/Edit"; +import { provinceFreeSalesEditBuyer } from "../../services/province-free-sales-edit-buyer"; +import { AppContext } from "../../../../contexts/AppContext"; + +const BuyerOperations = ({ item, fetchApiData, openNotif }) => { + const dispatch = useDispatch(); + const [anchorEl, setAnchorEl] = useState(null); + + const handleOpen = (event) => { + setAnchorEl(event.currentTarget); + }; + + const handleClose = () => { + setAnchorEl(null); + }; + + const handleToggleActive = () => { + handleClose(); + dispatch( + provinceFreeSalesEditBuyer({ + buyer_key: item?.key, + active: !item?.active, + }) + ).then((r) => { + if (r.payload.error) { + openNotif({ + vertical: "top", + horizontal: "center", + msg: r.payload.error, + severity: "error", + }); + } else { + fetchApiData(1); + openNotif({ + vertical: "top", + horizontal: "center", + msg: "عملیات با موفقیت انجام شد.", + severity: "success", + }); + } + }); + }; + + const handleEdit = () => { + handleClose(); + dispatch( + DRAWER({ + right: !(window.innerWidth <= 600), + bottom: window.innerWidth <= 600, + title: "ویرایش خریدار", + content: ( + + ), + }) + ); + }; + + const options = [ + { + key: "toggle", + label: item?.active ? "غیرفعال سازی" : "فعالسازی", + color: item?.active ? "error.main" : "success.main", + icon: item?.active ? : , + action: handleToggleActive, + }, + { + key: "edit", + label: "ویرایش", + color: "primary.main", + icon: , + action: handleEdit, + disabled: !item?.active, + }, + ]; + + const open = Boolean(anchorEl); + const id = open ? `buyer-operations-${item?.key}` : undefined; + + return ( + + + + + + + + + {options.map((option) => ( + { + if (option.disabled) { + return; + } + option.action(); + }} + disabled={Boolean(option.disabled)} + sx={{ + borderRadius: 1, + mb: 0.5, + color: option.disabled ? "text.disabled" : option.color, + "&:last-of-type": { + mb: 0, + }, + }} + > + + {React.cloneElement(option.icon, { fontSize: "small" })} + + + {option.label} + + } + /> + + ))} + + + + ); +}; + +export const ProvinceFreeSalsesManageBuyers = () => { + const [data, setData] = useState([]); + const [totalRows, setTotalRows] = useState(0); + const [perPage, setPerPage] = useState(10); + const [textValue, setTextValue] = useState(""); + const [page, setPage] = useState(1); + const [tableData, setTableData] = useState([]); + const dispatch = useDispatch(); + + const [openNotif] = useContext(AppContext); + + const userKey = useSelector((state) => state.userSlice.userProfile.key); + + const fetchApiData = async (page) => { + dispatch(LOADING_START()); + const response = await axios.get( + `out-province-poultry-request-buyers/?search=filter&value=${textValue}&page=${page}&page_size=${perPage}&role=${getRoleFromUrl()}&state=buyer-list` + ); + + dispatch(LOADING_END()); + setData(response.data.results); + setTotalRows(response.data.count); + }; + + const handlePageChange = (page) => { + fetchApiData(page); + setPage(page); + }; + + const handlePerRowsChange = (perRows) => { + setPerPage(perRows); + setPage(1); + }; + + const updateTable = () => { + fetchApiData(page !== 0 ? page : 1); + }; + + const handleTextChange = (event) => { + setTextValue(event.target.value); + }; + useEffect(() => { + const d = data?.map((item, i) => { + return [ + page === 1 ? i + 1 : i + perPage * (page - 1) + 1, + item?.fullname, + item?.mobile, + item?.province, + item?.city, + item?.type === "killhouse" ? "کشتارگاه" : "کشتارکن", + item?.unitName ? item?.unitName : "-", + item?.killHouseUniqueId ? item?.killHouseUniqueId : "-", + item?.requestsInfo?.numberOfRequests?.toLocaleString(), + item?.requestsInfo?.totalQuantity?.toLocaleString(), + item?.requestsInfo?.totalWeight?.toLocaleString(), + item?.active ? "فعال" : "غیر فعال", + , + ]; + }); + + setTableData(d); + }, [data]); + + useEffect(() => { + fetchApiData(1); + }, [dispatch, perPage]); + + const handleSubmit = async (event) => { + event.preventDefault(); + dispatch(LOADING_START()); + + try { + const response = await axios.get( + `out-province-poultry-request-buyers/?search=filter&value=${textValue}&role=${getRoleFromUrl()}&state=buyer-list` + ); + + setData(response.data.results); + setTotalRows(response.data.count); + dispatch(LOADING_END()); + } catch (error) { + console.error("Error fetching data:", error); + } + }; + + return ( + + + + + + +
    + + + +
    + + + + + +
    + + +
    + ); +}; diff --git a/src/features/province/components/province-free-sales-operations/ProvinceFreeSalesOperations.js b/src/features/province/components/province-free-sales-operations/ProvinceFreeSalesOperations.js new file mode 100644 index 0000000..ced238c --- /dev/null +++ b/src/features/province/components/province-free-sales-operations/ProvinceFreeSalesOperations.js @@ -0,0 +1,360 @@ +import React, { useContext, useState } from "react"; +import { Grid } from "../../../../components/grid/Grid"; +import { + Button, + IconButton, + Popover, + Typography, + List, + ListItemButton, + ListItemIcon, + ListItemText, +} from "@mui/material"; +import EditIcon from "@mui/icons-material/Edit"; +import CloseIcon from "@mui/icons-material/Close"; +import { ProvinceFreeSaleEditRequest } from "../province-free-sale-edit-request/ProvinceFreeSaleEditRequest"; +import { provinceOutRequestCancelRequest } from "../../services/provinceOutRequestCancelRequest"; +import TuneIcon from "@mui/icons-material/Tune"; +import ThumbDownOffAltIcon from "@mui/icons-material/ThumbDownOffAlt"; +import { ProvinceFreeSalesRejectRequest } from "../province-free-sales-reject-request/ProvinceFreeSalesRejectRequest"; +import { provinceCheckFreeSaleService } from "../../services/province-check-free-sale"; +import CheckIcon from "@mui/icons-material/Check"; +import { useDispatch } from "react-redux"; +import { + CLOSE_MODAL, + DRAWER, + OPEN_MODAL, +} from "../../../../lib/redux/slices/appSlice"; +import { AppContext } from "../../../../contexts/AppContext"; +import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl"; +import { provinceFreeSalsesSendSmsService } from "../../services/province-free-sales-send-sms-again"; +import SmsIcon from "@mui/icons-material/Sms"; + +export const ProvinceFreeSalesOperations = ({ item, fetchApiData }) => { + const dispatch = useDispatch(); + + const [anchorEl, setAnchorEl] = useState(null); + + const handleClick = (event) => { + setAnchorEl(event.currentTarget); + }; + + const handleClose = () => { + setAnchorEl(null); + }; + + const open = Boolean(anchorEl); + const id = open ? "popover" : undefined; + + const [openNotif] = useContext(AppContext); + const role = getRoleFromUrl(); + + const handleEdit = () => { + dispatch( + DRAWER({ + title: "ویرایش درخواست", + right: !(window.innerWidth <= 600), + bottom: window.innerWidth <= 600, + content: ( + + ), + }) + ); + }; + + const handleApprove = () => { + dispatch( + OPEN_MODAL({ + title: "آیا از تایید درخواست مطمئن هستید؟", + content: ( + + + + + ), + }) + ); + }; + + const handleResendSms = () => { + dispatch( + OPEN_MODAL({ + title: "پیامک مجددا ارسال شود؟", + content: ( + + {item?.hasWage && ( + + پیامک پرداخت مجددا برای {item?.payerFullname} {"‌‌"} به شماره + موبایل{" "} + {item?.payerType === "buyer" + ? item?.outProvincePoultryRequestBuyer?.mobile + : item?.poultry?.user?.mobile}{" "} + ارسال میشود. + + )} + + + + + + ), + }) + ); + }; + + const handleCancel = () => { + dispatch( + OPEN_MODAL({ + title: "آیا از لغو درخواست مطمئن هستید؟", + content: ( + + + + + ), + }) + ); + }; + + const handleReject = () => { + dispatch( + OPEN_MODAL({ + title: "رد درخواست فروش خارج از استان", + content: ( + + ), + }) + ); + }; + + const options = [ + { + key: "edit", + label: "ویرایش", + color: "primary.main", + icon: , + action: handleEdit, + }, + role !== "CityOperator" && { + key: "approve", + label: "تایید درخواست", + color: "success.main", + icon: , + action: handleApprove, + disabled: item.provinceState !== "pending", + }, + (role === "CityOperator" || + role === "ProvinceOperator" || + role === "SuperAdmin" || + role === "AdminX") && { + key: "resendSms", + label: "ارسال مجدد پیامک", + color: "info.main", + icon: , + action: handleResendSms, + disabled: item.outState !== "در انتظار پرداخت", + }, + { + key: "cancel", + label: "لغو", + color: "error.main", + icon: , + action: handleCancel, + disabled: + !item.provinceState === "pending" || !item.provinceState === "accepted", + }, + role !== "CityOperator" && { + key: "reject", + label: "رد درخواست", + color: "error.main", + icon: , + action: handleReject, + disabled: + !item.provinceState === "pending" || + !item.provinceState === "accepted" || + item.outState === "در انتظار پرداخت", + }, + ].filter(Boolean); + + return ( + + + + + + + {options.map((option) => ( + { + handleClose(); + option.action(); + }} + disabled={Boolean(option.disabled)} + sx={{ + borderRadius: 1, + mb: 0.5, + color: option.disabled ? "text.disabled" : option.color, + "&:last-of-type": { + mb: 0, + }, + }} + > + + {React.cloneElement(option.icon, { fontSize: "small" })} + + + {option.label} + + } + /> + + ))} + + + + ); +}; diff --git a/src/features/province/components/province-free-sales-reject-request/ProvinceFreeSalesRejectRequest.js b/src/features/province/components/province-free-sales-reject-request/ProvinceFreeSalesRejectRequest.js new file mode 100644 index 0000000..8084706 --- /dev/null +++ b/src/features/province/components/province-free-sales-reject-request/ProvinceFreeSalesRejectRequest.js @@ -0,0 +1,86 @@ +import React, { useContext, useEffect } from "react"; +import { TextField, Button } from "@mui/material"; +import { useFormik } from "formik"; +import * as Yup from "yup"; +import { Grid } from "../../../../components/grid/Grid"; +import { useDispatch } from "react-redux"; +import { provinceCheckFreeSaleService } from "../../services/province-check-free-sale"; +import { AppContext } from "../../../../contexts/AppContext"; +import { CLOSE_MODAL } from "../../../../lib/redux/slices/appSlice"; + +export const ProvinceFreeSalesRejectRequest = ({ item, fetchApiData }) => { + const [openNotif] = useContext(AppContext); + + const dispatch = useDispatch(); + const formik = useFormik({ + initialValues: { + textFieldInput: "", + }, + validationSchema: Yup.object({ + textFieldInput: Yup.string().required("این فیلد اجباری است!"), + }), + }); + + useEffect(() => { + formik.validateForm(); + }, []); + + return ( + + + + + ); +}; diff --git a/src/features/province/components/province-free-sales-transactions/ProvinceFreeSalesTransactions.js b/src/features/province/components/province-free-sales-transactions/ProvinceFreeSalesTransactions.js new file mode 100644 index 0000000..cfb9a4d --- /dev/null +++ b/src/features/province/components/province-free-sales-transactions/ProvinceFreeSalesTransactions.js @@ -0,0 +1,307 @@ +import React, { useContext, useEffect, useState } from "react"; +import { + Button, + Tab, + Tabs, + TextField, + Tooltip, + Typography, +} from "@mui/material"; +import { DatePicker } from "@mui/x-date-pickers"; +import moment from "moment"; +import { useDispatch } from "react-redux"; +import axios from "axios"; +import { AppContext } from "../../../../contexts/AppContext"; +import { + LOADING_END, + LOADING_START, +} from "../../../../lib/redux/slices/appSlice"; +import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl"; +import { Grid } from "../../../../components/grid/Grid"; +import ResponsiveTable from "../../../../components/responsive-table/ResponsiveTable"; +import { RiFileExcel2Fill } from "react-icons/ri"; +import { provinceFreeSalesGetDashboardTransactionsService } from "../../services/province-free-sales-get-transaction-dashboard"; +import { RiSearchLine } from "react-icons/ri"; + +export const ProvinceFreeSalesTransactions = () => { + const [, , selectedDate1, setSelectedDate1, selectedDate2, setSelectedDate2] = + useContext(AppContext); + const dispatch = useDispatch(); + useEffect(() => { + const currentDate = moment(new Date()).format("YYYY-MM-DD"); + setSelectedDate1(currentDate); + setSelectedDate2(currentDate); + }, []); + + const handleTextChange = (event) => { + setTextValue(event.target.value); + }; + const handleChange = (event, newValue) => { + setValue(newValue); + }; + const [dashboardData, setDashboardData] = useState([]); + + const [data, setData] = useState([]); + const [totalRows, setTotalRows] = useState(0); + const [perPage, setPerPage] = useState(10); + const [textValue, setTextValue] = useState(""); + const [page, setPage] = useState(1); + const [tableData, setTableData] = useState([]); + const [value, setValue] = useState(0); + + const fetchApiData = async (page) => { + let response; + dispatch(LOADING_START()); + response = await axios.get( + `poultry-requests-transactions/?search=filter&value=${textValue}&role=${getRoleFromUrl()}&date1=${selectedDate1}&date2=${selectedDate2}&page=${page}&page_size=${perPage}&type=${ + value === 0 ? "poultry" : "buyer" + }` + ); + dispatch(LOADING_END()); + setData(response.data.results); + setTotalRows(response.data.count); + }; + + const handlePageChange = (page) => { + fetchApiData(page); + setPage(page); + }; + + const handlePerRowsChange = (perRows) => { + setPerPage(perRows); + setPage(1); + }; + + // const updateTable = () => { + // fetchApiData(page !== 0 ? page : 1); + // }; + + useEffect(() => { + const d = data?.map((item, i) => { + return [ + page === 1 ? i + 1 : i + perPage * (page - 1) + 1, + item?.orderId, + item?.poultryRequest?.map((option, index) => ( + + {option.orderCode} + + )), + item?.amount?.toLocaleString(), + `${item?.payerInfo?.fullname} (${item?.payerInfo?.mobile})`, + item?.refId, + item?.unionShare?.toLocaleString(), + item?.companyShare?.toLocaleString(), + item?.guildsShare?.toLocaleString(), + item?.otherShare?.toLocaleString(), + ]; + }); + + setTableData(d); + }, [data]); + + useEffect(() => { + fetchApiData(1); + dispatch( + provinceFreeSalesGetDashboardTransactionsService({ + selectedDate1, + selectedDate2, + textValue, + }) + ).then((r) => { + setDashboardData(r.payload.data); + }); + }, [dispatch, selectedDate1, selectedDate2, perPage, value]); + + const handleSubmit = async (event) => { + event.preventDefault(); + dispatch(LOADING_START()); + + try { + const response = await axios.get( + `poultry-requests-transactions/?role=${getRoleFromUrl()}&search=filter&value=${textValue}&date1=${selectedDate1}&date2=${selectedDate2}&page=${1}&page_size=${perPage}&type=${ + value === 0 ? "poultry" : "buyer" + }` + ); + setData(response.data.results); + setTotalRows(response.data.count); + + dispatch(LOADING_END()); + dispatch( + provinceFreeSalesGetDashboardTransactionsService({ + selectedDate1, + selectedDate2, + textValue, + type: value === 0 ? "poultry" : "buyer", + }) + ).then((r) => { + setDashboardData(r.payload.data); + }); + } catch (error) { + console.error("Error fetching data:", error); + } + }; + + return ( + + + + ( + + )} + value={selectedDate1} + onChange={(e) => { + setSelectedDate1(moment(e).format("YYYY-MM-DD")); + }} + /> + + + ( + + )} + value={selectedDate2} + onChange={(e) => { + setSelectedDate2(moment(e).format("YYYY-MM-DD")); + }} + /> + + +
    + + + +
    + + + + + + + +
    + + + + + + + + + + {value === 0 ? ( + + ) : ( + + )} +
    + ); +}; diff --git a/src/features/province/components/province-free-sales/ProvinceFreeSales.js b/src/features/province/components/province-free-sales/ProvinceFreeSales.js new file mode 100644 index 0000000..17dc873 --- /dev/null +++ b/src/features/province/components/province-free-sales/ProvinceFreeSales.js @@ -0,0 +1,477 @@ +import React, { useContext, useEffect, useState } from "react"; +import { Grid } from "../../../../components/grid/Grid"; +import { Button, Chip, Tab, Tabs, TextField, Tooltip } from "@mui/material"; +import { DatePicker } from "@mui/x-date-pickers"; +import moment from "moment"; +import axios from "axios"; +import { RiFileExcel2Fill, RiSearchLine } from "react-icons/ri"; +import { AppContext } from "../../../../contexts/AppContext"; +import { + DRAWER, + LOADING_END, + LOADING_START, +} from "../../../../lib/redux/slices/appSlice"; +import { ProvinceFreeSaleNewRequest } from "../../../aviculture/components/province-free-sale-new-request/ProvinceFreeSaleNewRequest"; +import { SPACING } from "../../../../data/spacing"; +import { useDispatch, useSelector } from "react-redux"; +import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl"; +import { formatJustDate } from "../../../../utils/formatTime"; +import { ProvinceFreeSalesAcceptedRequests } from "../province-free-sales-accepted-requests/ProvinceFreeSalesAcceptedRequests"; +import { ProvinceFreeSalsesManageBuyers } from "../province-free-sales-manage-buyers/ProvinceFreeSalsesManageBuyers"; +import { provinceApproveFreeSaleService } from "../../services/province-approve-free-sale"; +import { ProvinceFreeSalesOperations } from "../province-free-sales-operations/ProvinceFreeSalesOperations"; +import { avicultureGetWageType } from "../../../aviculture/services/aviculture-get-wage-type"; +import { ProvinceFreeSalesTransactions } from "../province-free-sales-transactions/ProvinceFreeSalesTransactions"; +import ResponsiveTable from "../../../../components/responsive-table/ResponsiveTable"; +import { provinceGetFreeSalesDashboardService } from "../../services/province-get-free-sales-dashboard"; + +export const ProvinceFreeSales = () => { + const [data, setData] = useState([]); + const [totalRows, setTotalRows] = useState(0); + const [perPage, setPerPage] = useState(10); + const [textValue, setTextValue] = useState(""); + const [page, setPage] = useState(1); + const [tableData, setTableData] = useState([]); + const [value, setValue] = useState(0); + const [dashboardData, setDashboardData] = useState([]); + const [wageType, setWageType] = useState(); + + const [openNotif] = useContext(AppContext); + const dispatch = useDispatch(); + const userKey = useSelector((state) => state.userSlice.userProfile.key); + + const handleTextChange = (event) => { + setTextValue(event.target.value); + }; + + const handleChange = (event, newValue) => { + setValue(newValue); + refreshDashboard(); + }; + + const [, , selectedDate1, setSelectedDate1, selectedDate2, setSelectedDate2] = + useContext(AppContext); + + const fetchApiData = async (page) => { + dispatch(LOADING_START()); + const response = await axios.get( + `out-province-poultry-requests/?search=filter&value=${textValue}&page=${page}&role=${getRoleFromUrl()}&page_size=${perPage}&date1=${selectedDate1}&date2=${selectedDate2}&state=pending` + ); + dispatch(LOADING_END()); + setData(response.data.results); + setTotalRows(response.data.count); + }; + + const refreshDashboard = () => { + dispatch( + provinceGetFreeSalesDashboardService({ + selectedDate1, + selectedDate2, + textValue, + }) + ).then((r) => { + setDashboardData(r.payload.data); + }); + }; + + const handlePageChange = (page) => { + fetchApiData(page); + setPage(page); + }; + + const handlePerRowsChange = (perRows) => { + setPerPage(perRows); + setPage(1); + }; + + useEffect(() => { + fetchApiData(1); + refreshDashboard(); + + dispatch(avicultureGetWageType()).then((r) => { + setWageType(r.payload.data.status); + }); + }, [dispatch, perPage]); + + useEffect(() => { + if (value === 0) { + fetchApiData(1); + } + refreshDashboard(); + }, [selectedDate1, selectedDate2, value]); + + useEffect(() => { + const d = data?.map((item, i) => { + return [ + page === 1 ? i + 1 : i + perPage * (page - 1) + 1, + , + , + `${item?.registrar?.fullname}`, + item.orderCode, + item.buyer?.firstName + ? `${item.buyer?.firstName} ${item.buyer?.lastName} (${item.buyer?.mobile}) / ${item.buyer.province} - ${item.buyer.city}` + : item?.outProvincePoultryRequestBuyer.type === "killhouse" + ? `کشتارگاه ${item.buyerFullname} (${item.buyerMobile}) / شناسه یکتا ${item.outProvincePoultryRequestBuyer?.killHouseUniqueId} / ${item.buyerProvince} - ${item.buyerCity}` + : `کشتارکن ${item.buyerFullname} (${ + item.buyerMobile + }) / نام کشتارگاه ${ + item.killerKillHouseUnitName ? item.killerKillHouseUnitName : "-" + } / شناسه یکتا ${ + item.killerKillHouseUniqueId ? item.killerKillHouseUniqueId : "-" + } / استان ${ + item.killerKillHouseProvince ? item.killerKillHouseProvince : "-" + } / شهر ${ + item.killerKillHouseCity ? item.killerKillHouseCity : "-" + }`, + item?.outProvincePoultryRequestBuyer?.type === "killhouse" + ? "محل کشتارگاه" + : item?.killerKillHouseUnitName + ? `کشتارگاه ${item?.killerKillHouseUnitName} / ${item?.killerKillHouseProvince} / ${item?.killerKillHouseCity}` + : "-", + item?.hasWage ? item?.payerFullname : "-", + item?.paymentLink ? ( + + {item?.paymentLink.length > 25 + ? `${item?.paymentLink.slice(0, 25)}...` + : item?.paymentLink} + + ) : ( + "-" + ), + `${item.poultry?.unitName} (${item.poultry.user.mobile})`, + formatJustDate(item.createDate), + formatJustDate(item.sendDate), + item.hatching.age, + item.IndexWeight?.toLocaleString(), + item.quantity.toLocaleString(), + Math.floor(item.IndexWeight * item.quantity)?.toLocaleString(), + item?.freezing ? "انجماد" : "عادی", + item?.hasWage ? "دارد" : "ندارد", + item.hatching?.city, + item.hatching?.province, + item.hatching.hatchingLeftOver + ? item.hatching.hatchingLeftOver.toLocaleString() + : item.hatching.leftOver.toLocaleString(), + item.hatching.hatchingQuantity?.toLocaleString(), + item.totalWageAmount?.toLocaleString() + " ریال", + item?.outProvinceDriverInfo?.driverhealthCode || "-", + ]; + }); + + setTableData(d); + }, [data]); + + const handleSubmit = async (event) => { + event.preventDefault(); + dispatch(LOADING_START()); + + try { + const response = await axios.get( + `out-province-poultry-requests/?search=filter&value=${textValue}&page=${page}&page_size=${perPage}&date1=${selectedDate1}&date2=${selectedDate2}&state=pending&role=${getRoleFromUrl()}` + ); + setData(response.data.results); + setTotalRows(response.data.count); + refreshDashboard(); + dispatch(LOADING_END()); + } catch (error) { + console.error("Error fetching data:", error); + dispatch(LOADING_END()); + } + }; + + return ( + + + + + + + + + + + + + + + {value === 0 && ( + + + + + + + + + + ( + + )} + value={selectedDate1} + onChange={(e) => { + setSelectedDate1(moment(e).format("YYYY-MM-DD")); + }} + /> + + + ( + + )} + value={selectedDate2} + onChange={(e) => { + setSelectedDate2(moment(e).format("YYYY-MM-DD")); + }} + /> + +
    + + + + + + + + + + + + + + + + + +
    + {getRoleFromUrl() !== "CityOperator" && ( + + + + )} +
    + + + +
    + )} + {value === 1 && ( + + )} + {value === 2 && ( + + )} + {value === 3 && } + {value === 4 && } +
    +
    +
    + ); +}; diff --git a/src/features/province/components/province-get-case-file/ProvinceGetCaseFile.js b/src/features/province/components/province-get-case-file/ProvinceGetCaseFile.js new file mode 100644 index 0000000..f0a6651 --- /dev/null +++ b/src/features/province/components/province-get-case-file/ProvinceGetCaseFile.js @@ -0,0 +1,1002 @@ +import React, { forwardRef } from "react"; +import { PropTypes } from "prop-types"; +import logo from "../../../../assets/images/logo.png"; +// import logoFooter from "../../../../assets/images/reportFooter.png"; +import "./styles.css"; +import checkIcon from "../../../../assets/images/check-icon-small.png"; +import waitingIcon from "../../../../assets/images/waiting-icon.png"; +import { formatJustDate, formatJustTime } from "../../../../utils/formatTime"; +import moment from "moment"; + +const styles = { + page: { + width: "214mm", + height: "302mm", + display: "flex", + margin: "0 auto", + flexDirection: "column", + position: "relative", + direction: "rtl", + fontFamily: "titr", + fontWeight: "bold", + }, + pageData: { + position: "relative", + display: "flex", + direction: "rtl", + flexDirection: "column", + }, + tableInNewPage: { + pageBreakAfter: "always", + paddingLeft: "40px", + paddingRight: "40px", + direction: "rtl", + fontFamily: "titr", + fontWeight: "bold", + }, + container: { + width: "95%", + alignSelf: "center", + pageBreakInside: "avoid", + }, + p: { + fontFamily: "titr", + fontWeight: "bold", + pAlign: "justify", + }, + span: { + fontFamily: "titr", + fontWeight: "bold", + pAlign: "justify", + }, + invoiceTable: { + width: "195mm", + borderCollapse: "collapse", + alignSelf: "center", + }, + tableCell: { + border: "1px solid #000", + pAlign: "left", + textAlign: "center", + fontSize: 9, + }, + tableCellAlert: { + border: "1px solid #000", + pAlign: "left", + textAlign: "center", + fontSize: 9, + color: "red", + }, + tableCellMobile: { + border: "1px solid #000", + pAlign: "left", + textAlign: "center", + fontSize: 9, + }, + tableInnerCell: { + border: "1px solid #000", + pAlign: "left", + textAlign: "center", + fontSize: 7, + whiteSpace: "nowrap", + }, + tableHeader: { + pageBreakAfter: "auto", + }, + headerRow: { + backgroundColor: "rgba(32, 95, 243, 0.8)", + color: "white", + pageBreakInside: "avoid", + pageBreakAfter: "auto", + }, + logo: { + marginTop: "15px", + width: "100px", + height: "auto", + zIndex: 10, + }, + logoFooter: { + width: "100px", + height: "auto", + }, + contentContainer: { + alignItems: "center", + display: "flex", + justifyContent: "space-between", + marginRight: "20px", + marginLeft: "20px", + }, + contentInLine: { + display: "flex", + flexDirection: "column", + alignItems: "center", + }, + mainTitle: { + fontFamily: "titr", + fontSize: 11, + pAlign: "center", + fontWeight: "bolder", + }, + signature: { + display: "flex", + flexDirection: "column", + alignItems: "flex-end", + marginLeft: "20px", + }, + watermarkContainer: { + position: "fixed", + top: 350, + left: 30, + right: 0, + bottom: 0, + justifyContent: "center", + alignItems: "center", + opacity: 0.15, + zIndex: -1, + userSelect: "none", + }, + watermarkp: { + fontFamily: "nazanin", + fontSize: 100, + fontWeight: "bolder", + color: "grey", + transform: "rotate(-45deg)", + left: "50%", + userSelect: "none", + }, + title: { + fontSize: 12, + fontWeight: "bolder", + pAlign: "center", + }, + titleTopic: { + fontSize: 12, + fontWeight: "bolder", + pAlign: "center", + }, + firsttitle: { + pAlign: "center", + color: "#00008b", + fontWeight: "800", + }, + options: { + marginLeft: "50px", + padding: "10px", + display: "flex", + flexDirection: "column", + alignItems: "flex-start", + }, + divider: { + alignSelf: "center", + width: "120mm", + height: "1px", + backgroundColor: "black", + margin: "0em", + }, + pTitleContainer: { + pAlign: "center", + margin: "15px", + textAlign: "justify", + textJustify: "inter-word", + fontFamily: "nazanin", + fontSize: "20px", + fontWeight: "bolder", + }, + tableHeaderCell: { + backgroundColor: "rgba(211, 211, 211, 0.3)", + fontSize: 10, + border: "1px solid #000", + padding: "4px", + textAlign: "center", + fontWeight: "bold", + }, + footer: { + left: 0, + bottom: 0, + width: "100%", + position: "absolute", + }, + footerContainer: { + alignItems: "center", + display: "flex", + }, + circle: { + borderRadius: "50%", + width: "20px", + height: "20px", + padding: "10px", + background: "#ecf0f1", + border: " 1px solid #000", + color: "#000", + textAlign: "center", + marginRight: "130px", + }, + tableRowEven: { + backgroundColor: "rgba(207, 213, 234, 0.5)", + }, + levelDetails: { + color: "red", + fontSize: 10, + }, +}; + +const ProvinceGetCaseFile = forwardRef((props, ref) => { + const { item } = props; + // const { targetperson } = props; + // const { reportType } = props; + const getSellType = (item) => { + let sellType = ""; + if (item?.directBuying) { + sellType = "خرید مستقیم"; + } else if (item?.union) { + sellType = "خرید خارج از استان"; + } else { + sellType = "اتحادیه"; + } + return sellType; + }; + + // const getItemState = (item) => { + // let sellType = ""; + // if (item?.directBuying) { + // sellType = "خرید مستقیم"; + // } else if (item?.union) { + // sellType = "خرید خارج از استان"; + // } else { + // sellType = "اتحادیه"; + // } + // return sellType; + // }; + + const HeaderPDF = () => { + return ( + <> +
    +
    +
    + + مشخصات پرونده با کد سفارش {item?.orderCode} + + + فروش از طریق {getSellType(item)} + + + این گزارش در تاریخ {formatJustDate(moment())} ساعت{" "} + {formatJustTime(moment())} صادر شده است. + +
    + + اطلاعات پرونده کشتار تاریخ {formatJustDate(item?.sendDate)}{" "} + مرغداری {item?.poultry?.unitName} + +
    + +
    + logo +
    +
    + + ); + }; + + // let pageNumber = 0; + // const FooterPDF = () => { + // pageNumber++; + // return ( + // <> + //
    + //
    + //
    + // logo + + //

    + // گزارش فرآیند کامل کشتار و پخش مرغ گوشتی سامانه رصدیار + // www.rasadyaar.ir + //

    + //
    {pageNumber}
    + //
    + //
    + // + // ); + // }; + + const Table1 = () => { + return ( + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    کد سفارشمرغدارتلفنتاریخ درخواست کشتارآدرستاریخ جوجه ریزیتعداد جوجه ریزیمانده در سالنسفارش کشتار (قطعه)میانگین وزنوزن تقریبی سفارشقیمت پیشنهادینوع فروشفرآیند مالیدامپزشک فارم
    {item?.orderCode}{item?.poultry?.unitName}{item?.poultry?.user?.mobile}{formatJustDate(item?.sendDate)}{item?.poultry?.address?.address}{formatJustDate(item?.sendDate)}{item?.amount?.toLocaleString()} + {item?.hatching?.leftOver?.toLocaleString()} + {item?.quantity?.toLocaleString()}{item?.IndexWeight}{item?.hatching?.weight}{item?.amount?.toLocaleString()} + {item?.freeSaleInProvince === false ? "دولتی" : "آزاد"} + + {item?.financialOperation === "outside-system" + ? "خارج از سامانه" + : "از طریق سامانه"} + + {item?.hatching?.vetFarmInfo + ? `${item?.vetFarm?.vetFarmFullName} (${item?.vetFarm?.vetFarmMobile})` + : "ندارد"} +
    + ); + }; + + const TableCityLevel = () => { + return ( + + + + + + + + + + + + {item?.cityState?.date ? ( + + + + + + + + + + + ) : ( + + )} +
    اپراتورسمتتلفنتعاونی مرغدارآدرسوضعیت
    + {item?.cityState?.cityOperatorFullname} + سمت + {item?.cityState?.cityOperatorMobile} + {item?.cityState?.poultry} + {item?.cityState?.province + " - " + item?.cityState?.city} + + {item?.cityState?.state === "accept" ? "تایید شده" : "رد شده"} +
    + هنوز شهرستان پرونده را تائید نکرده است +
    + ); + }; + + const TableProvinceLevel = () => { + return ( + + + + + + + + + + + + {item?.provinceState?.date ? ( + + + + + + + + + + + ) : ( + + )} +
    اپراتورسمتتلفنتعاونی مرغدارآدرسوضعیت
    + {item?.provinceState?.provinceOperatorFullname} + اپراتور استان + {item?.provinceState?.cityOperatorMobile} + {item?.provinceState?.poultry} + {item?.provinceState?.province + + " - " + + item?.provinceState?.city} + + {item?.provinceState?.state === "accept" + ? "تایید شده" + : "رد شده"} +
    + هنوز استان پرونده را تائید نکرده است +
    + ); + }; + + const TableSalughterAllocationLevel = () => { + return ( + + + + + + + + + + + + + + {item?.provinceKillRequests?.provinceKillRequestSerializer ? ( + + {item?.provinceKillRequests?.provinceKillRequestSerializer.map( + (item, i) => ( + + + + + + + + + + + ) + )} + + ) : ( + + )} +
    ردیفماهیت خریدارخریدارنوع تخصیصتعداد تخصیصیمیانگین وزنوزن تخصیصیوضعیت
    {i + 1} + {item?.killhouseUser?.killer === false + ? "کشتارگاه" + : "کشتارکن"} + + {`${item?.killhouseUser?.killHouseOperator?.user?.fullname} (${item?.killhouseUser?.killHouseOperator?.user?.mobile})`} + + {item?.automatic === false ? "دستی" : "اتوماتیک"} + + {item?.weightInfo?.provinceKillRequestQuantity} + + {item?.weightInfo?.provinceKillRequestIndexWeight} + + {item?.weightInfo?.provinceKillRequestWeight} + + {item?.state === "accepted" + ? "تایید شده" + : item?.state === "rejected" + ? "رد شده" + : "در انتظار تایید"} +
    + داده ای ثبت نشده! +
    + ); + }; + + const TableSlaughterAddCar = () => { + return ( + + + + + + + + + + + + + + + + {item?.killHouseRequests?.killHouseRequestsSerializer ? ( + + {item?.killHouseRequests?.killHouseRequestsSerializer.map( + (item, i) => ( + + + + + + + + + + + + + ) + )} + + ) : ( + + )} +
    ردیفکد بارخریدارماشینرانندهتعدادوزن بارمیانگین وزنکد قرنطینهمحل کشتار
    {i + 1}{item?.barCode} + {`${item?.killhouseUser?.killHouseOperator?.user?.fullname} (${item?.killhouseUser?.killHouseOperator?.user?.mobile})`} + {`${item?.addCar?.driver?.typeCar} (${item?.addCar?.driver?.pelak})`}{`${item?.addCar?.driver?.driverName} (${item?.addCar?.driver?.driverMobile})`} + {item?.quantity.toLocaleString()} + {item?.weightInfo?.weight} + {item?.weightInfo?.indexWeight} + {item?.clearanceCode}{item?.killPlace}
    + داده ای ثبت نشده! +
    + ); + }; + + const TableSVetAcceptDischarge = () => { + return ( + + + + + + + + + + + + + + + + + + + {item?.killHouseRequests?.killHouseRequestVetCheckSerializer ? ( + + {item?.killHouseRequests?.killHouseRequestVetCheckSerializer.map( + (item, i) => ( + + + + + + + + + + + + + + + + ) + )} + + ) : ( + + )} +
    ردیفکد بارخریدارماشینرانندهتعدادوزن بارمیانگین وزنکد قرنطینهتعداد تخلیه شده وزن تخلیه شده وضعیتاطلاعات تخلیه
    {i + 1}{item?.barCode} + {`${item?.killhouseUser?.killHouseOperator?.user?.fullname} (${item?.killhouseUser?.killHouseOperator?.user?.mobile})`} + {`${item?.addCar?.driver?.typeCar} (${item?.addCar?.driver?.pelak})`}{`${item?.addCar?.driver?.driverName} (${item?.addCar?.driver?.driverMobile})`} + {item?.quantity.toLocaleString()} + {item?.weightInfo?.weight} + {item?.weightInfo?.indexWeight} + {item?.clearanceCode} + {item?.vetAcceptedRealQuantity?.toLocaleString()} + + {item?.vetAcceptedRealWeight?.toLocaleString()} + + {item?.vetState === "accepted" + ? "تخلیه شده" + : "در انتظار تخلیه"} + + {item?.vetState === "accepted" + ? `${item?.killHouseVet?.fullname} (${item?.killHouseVet?.mobile})` + : "-"} +
    + داده ای ثبت نشده! +
    + ); + }; + + const TableSlaughterInputBarData = () => { + return ( + + + + + + + + + + + + + + + + + + + {item?.killHouseRequests?.killHouseRequestAssignmentSerializer ? ( + + {item?.killHouseRequests?.killHouseRequestAssignmentSerializer.map( + (item, i) => ( + + + + + + + + + + + + + {" "} + + + ) + )} + + ) : ( + + )} +
    ردیفکد بارخریدارماشینرانندهتعدادوزن بارمیانگین وزنکد قرنطینهتعداد تخلیه شده (دامپزشک)وزن تخلیه شده (دامپزشک)تعداد نهاییوزن خالص واقعی
    {i + 1}{item?.barCode} + {`${item?.killhouseUser?.killHouseOperator?.user?.fullname} (${item?.killhouseUser?.killHouseOperator?.user?.mobile})`} + {`${item?.addCar?.driver?.typeCar} (${item?.addCar?.driver?.pelak})`}{`${item?.addCar?.driver?.driverName} (${item?.addCar?.driver?.driverMobile})`} + {item?.quantity.toLocaleString()} + {item?.weightInfo?.weight} + {item?.weightInfo?.indexWeight} + {item?.clearanceCode} + {item?.vetAcceptedRealQuantity?.toLocaleString()} + + {item?.vetAcceptedRealWeight?.toLocaleString()} + + {item?.acceptedRealQuantity?.toLocaleString()} + + {item?.acceptedRealWeight?.toLocaleString()} +
    + داده ای ثبت نشده! +
    + ); + }; + + const TableSlaughterFinanceInfo = () => { + return ( + + + + + + + + + + + + + + + + + + + {item?.provinceState?.date && ( + + + {/* */} + + + )} +
    ردیفکد بارخریدارماشینرانندهنژادکد قرنطینهتعداد نهاییوزن خالص بارمیانگین وزنمبلغ فاکتوروضعیت + اطلاعات پرداخت (شناسه پرداخت) +
    + {item?.provinceState?.provinceOperatorFullname} +
    + ); + }; + + const TableInspector = () => { + return ( + + + + + + + + + + + + + + + + + + + + {item?.provinceState?.date && ( + + + {/* */} + + + )} +
    ردیفکد بارخریدارماشینرانندهنژادکد قرنطینهتعداد نهاییوزن خالص بارمیانگین وزنمبلغ فاکتوروضعیت پرداختوضعیتنظر بازرس
    + {item?.provinceState?.provinceOperatorFullname} +
    + ); + }; + + return ( +
    +
    +

    سامانه رصدیار

    +
    +
    + +
    +
    +
      +
    • +
      + icon +
      +
      +
      مشخصات درخواست
      +
      + +
      +
      +
    • + +
    • +
      + icon +
      +
      +
      مرحله شهرستان
      +
      + +
      +
      +
    • + +
    • +
      + icon +
      +
      +
      مرحله استان
      +
      + +
      +
      +
    • + +
    • +
      + icon +
      +
      +
      + تخصیصات استان به کشتارگاه + {" ( "} + + تعداد درخواست:{" "} + {item?.provinceKillRequests?.provinceKillRequestsTotalInfo?.poultryRequestQuantity.toLocaleString()} + ، تعداد تخصیصی به کشتارگاه:{" "} + {item?.provinceKillRequests?.provinceKillRequestsTotalInfo?.allocatedQuantity.toLocaleString()} + ، مانده قابل تخصیصی:{" "} + {item?.provinceKillRequests?.provinceKillRequestsTotalInfo?.poultryRequestRemainQuantity.toLocaleString()} + + {" ) "} +
      +
      + +
      +
      +
    • + +
    • +
      + icon +
      +
      +
      + ثبت ماشین توسط خریدار (ایجاد بار) + {" ( "} + + تعداد تخصیص به خریداران:{" "} + {item?.killHouseRequests?.allocatedQuantity?.toLocaleString()} + ، تعداد بارها:{" "} + {item?.killHouseRequests?.numberOfBars?.toLocaleString()}، + تعداد تخصیص به ماشین:{" "} + {item?.killHouseRequests?.killHouseRequestQuantity?.toLocaleString()} + ، مانده قابل تخصیص:{" "} + {item?.killHouseRequests?.remainQuantity?.toLocaleString()} + + {" ) "} +
      +
      + +
      +
      +
    • + +
    • +
      + icon +
      +
      +
      + تایید تخلیه توسط دامپزشک کشتارگاه + {" ( "} + + تعداد بارها:{" "} + {item?.killHouseRequests?.numberOfBars?.toLocaleString()}، + تایید تخلیه:{" "} + {item?.killHouseRequests?.vetAcceptedNumberOfBars?.toLocaleString()} + ، تخلیه نشده:{" "} + {item?.killHouseRequests?.vetRemainNumberOfBars?.toLocaleString()} + + {" ) "} +
      +
      + +
      +
      +
    • + +
    • +
      + icon +
      +
      +
      + ورود اطلاعات بار توسط کشتارگاه + {" ( "} + + تعداد بارها:{" "} + {item?.killHouseRequests?.numberOfBars?.toLocaleString()}، + ورود اطلاعات بار:{" "} + {item?.killHouseRequests?.killHouseRequestAssignment?.toLocaleString()} + ، وارد نشده:{" "} + {item?.killHouseRequests?.assignmentRemainNumberOfBars?.toLocaleString()} + + {" ) "} +
      +
      + +
      +
      +
    • + +
    • +
      + icon +
      +
      +
      اطلاعات مالی
      +
      + +
      +
      +
    • + +
    • +
      + icon +
      +
      +
      بازرس
      +
      + +
      +
      +
    • + +
      +
      + icon +
      +
      +
      + اتمام پرونده + {/* {" ( "} + + پرونده در تاریخ 1400/02/04 خاتمه یافت. + + {" ) "} */} +
      +
      +
      +
    +
    +
    +
    +
    + ); +}); + +ProvinceGetCaseFile.displayName = "ProvinceGetCaseFile"; + +export default ProvinceGetCaseFile; + +ProvinceGetCaseFile.propTypes = { + item: PropTypes.any, +}; diff --git a/src/features/province/components/province-get-case-file/styles.css b/src/features/province/components/province-get-case-file/styles.css new file mode 100644 index 0000000..d6d02f2 --- /dev/null +++ b/src/features/province/components/province-get-case-file/styles.css @@ -0,0 +1,91 @@ +/* ----------------------------timeline---------------------------- */ +.timeline { + width: 100%; + margin: 0; +} + +.base-timeline { + position: relative; +} + +.timeline .base-timeline { + margin: 0; + padding-left: 20px; + padding-right: 20px; +} + +.base-timeline li { + list-style-type: none; + margin: 0; + padding: 0; + position: relative; + display: flex; + align-items: flex-start; +} + +.text-primary { + text-decoration: none; +} + +.timeline-icon { + margin-top: 5px; + color: white; + width: 15px; + height: 15px; + border-radius: 50%; + text-align: center; + line-height: 13px; + align-items: center; + justify-content: center; +} +.icon-image { + width: 9px; + align-self: center; +} + +.timeline-content { + margin-right: 10px; + position: relative; +} + +.act-time { + font-size: 14px; + color: #453939; +} + +.base-timeline-info { + margin-top: 2px; +} + +.base-timeline-info a { + font-size: 14px; + font-weight: bold; + color: #333; +} + +.text-muted { + font-size: 12px; + color: #999; +} + +.base-timeline li + li::before, +.base-timeline li::before { + content: ""; + position: absolute; + top: 10px; + right: 6.5px; + width: 2px; + height: 100%; + background-color: #ddd; + z-index: -1; +} + +.fa-caret-down { + color: white !important; +} + +.bg-primary { + background-color: orange; +} + +/* ----------------------------end timeline---------------------------- */ diff --git a/src/features/province/components/province-get-contradictions-file/Pages.js b/src/features/province/components/province-get-contradictions-file/Pages.js new file mode 100644 index 0000000..319a3f6 --- /dev/null +++ b/src/features/province/components/province-get-contradictions-file/Pages.js @@ -0,0 +1,527 @@ +import { useRef } from "react"; +import { formatJustDate } from "../../../../utils/formatTime"; + +const styles = { + tableInNewPage: { + pageBreakAfter: "always", + paddingLeft: "40px", + paddingRight: "40px", + direction: "rtl", + fontFamily: "titr", + fontWeight: "bold", + }, + container: { + width: "95%", + alignSelf: "center", + pageBreakInside: "avoid", + }, + + invoiceTable: { + width: "100%", + borderCollapse: "collapse", + alignSelf: "center", + marginBottom: "2px", + fontFamily: "titr", + }, + tableCell: { + border: "1px solid #000", + pAlign: "left", + textAlign: "center", + fontSize: 9, + fontWeight: "bolder", + }, + tableCellGreen: { + border: "1px solid #000", + pAlign: "left", + textAlign: "center", + fontSize: 9, + color: "white", + fontWeight: "bolder", + backgroundColor: "rgba(26, 188, 156, 0.7)", + }, + tableCellMobile: { + border: "1px solid #000", + pAlign: "left", + textAlign: "center", + fontSize: 9, + }, + tableInnerCell: { + border: "1px solid #000", + pAlign: "left", + textAlign: "center", + fontSize: 7, + whiteSpace: "nowrap", + }, + tableHeader: { + backgroundColor: "rgba(211, 211, 211, 0.3)", + pageBreakAfter: "auto", + }, + headerRow: { + backgroundColor: "rgba(211, 211, 211, 0.3)", + color: "black", + pageBreakInside: "avoid", + pageBreakAfter: "auto", + }, + + tableHeaderCell: { + backgroundColor: "rgba(211, 211, 211, 0.3)", + fontSize: 10, + border: "1px solid #000", + padding: "4px", + textAlign: "center", + fontWeight: "bolder", + }, + tableHeaderCellGreen: { + backgroundColor: "rgba(26, 188, 156, 0.7)", + fontSize: 10, + border: "1px solid #000", + padding: "4px", + textAlign: "center", + fontWeight: "bolder", + color: "white", + }, + footer: { + left: 0, + bottom: 0, + width: "100%", + position: "absolute", + }, + footerContainer: { + alignItems: "center", + display: "flex", + }, + + tableRowEven: { + backgroundColor: "rgba(170, 183, 255, 0.3)", + }, + titleOfTable: { + marginRight: "20px", + fontSize: "15px", + }, +}; + +export const GetClearanceCode = ({ clearanceCode }) => { + const formRef = useRef(null); + + const handleCodeClick = () => { + if (formRef.current) { + formRef.current.submit(); + } + }; + + return ( +
    + + + + {clearanceCode} + +
    + ); +}; +export const TablePage1 = ({ item }) => { + return ( + + + + + + + + + + + + + + + + + + + + + + + + + +
    تعداد درخواستمجموع درخواست کشتار (قطعه)مجموع درخواست کشتار (وزن)تعداد تخصیص به خریداروزن تخصیص به خریدار مانده قطعه قابل تخصیصوزن قابل تخصیصاپراتور
    + {item?.totalRequests.toLocaleString()} + + {item?.poultryRequestTotalQuantity.toLocaleString()} + + {Math.round(item?.poultryRequestTotalWeight).toLocaleString()} + + {item?.provinceKillRequestsTotalQuantity.toLocaleString()} + + {item?.provinceKillRequestsTotalWeight.toLocaleString()} + + {item?.poultryRequestTotalRemainQuantity.toLocaleString()} + + {Math.round(item?.poultryRequestRemainWeight).toLocaleString()} + + {item?.operatorFullname}
    {item?.operatorMobile} +
    + ); +}; + +export const TablePage1Part2 = ({ items, start, end }) => { + const slicedItems = items?.slice(start - 1, end); + return ( + + + + + + + + + + + + + + + + + {slicedItems?.map((item, i) => ( + + + + + + + + + + + + + ))} + +
    ردیفخریدارسهم کشتار (قطعه)سهم کشتار (وزن)تعداد ماشین هاتخصیص به ماشین (قطعه)تخصیص به ماشین (وزن)مانده قطعه قابل تخصیصمانده وزن قابل تخصیصاپراتور
    {i + start} + {item?.killhouseUser?.name}
    ( + {item?.killhouseUser?.killHouseOperator?.user.mobile}) +
    + {item?.totalInfo?.provinceKillRequestQuantity.toLocaleString()} + + {item?.totalInfo?.provinceKillRequestWeight.toLocaleString()} + + {item?.totalInfo?.killHouseRequestsCount.toLocaleString()} + + {item?.totalInfo?.killHouseRequestQuantity.toLocaleString()} + + {item?.totalInfo?.killHouseRequestWeight.toLocaleString()} + + {item?.totalInfo?.provinceKillRequestRemainQuantity.toLocaleString()} + + {item?.totalInfo?.provinceKillRequestRemainWeight.toLocaleString()} + + { + <> + {item?.totalInfo?.operatorFullname} +
    + {item?.totalInfo?.operatorMobile} + + } +
    + ); +}; + +export const TablePage2 = ({ items, start, end }) => { + const slicedItems = items?.slice(start - 1, end); + return ( + + + + + + + + + + + + + + + + + + + + {slicedItems?.map((item, i) => ( + + + + + + + + + + + + + + + + ))} + +
    ردیفکد بارخریدارتاریخ کشتارفروشندهماشینرانندهنژادتعدادوزن بارمیانگین وزنمحل کشتاردامپزشک
    {i + start}{item?.barCode} + {item?.killhouseUser?.name}
    ( + {item?.killhouseUser?.killHouseOperator?.user.mobile}) +
    + {formatJustDate(item?.killRequest?.reciveDate)} + + {item?.poultryRequest?.poultry?.unitName}
    ( + {item?.poultryRequest?.poultry?.user?.mobile}) +
    {item?.car?.typeCar}{item?.car?.driverName} + {item?.poultryRequest?.chickenBreed} + {item?.quantity?.toLocaleString()} + {item?.weightInfo?.weight?.toLocaleString()} + {item?.weightInfo?.indexWeight}{item?.killPlace} + {item?.vetFarm ? ( + <> + {item?.vetFarm?.vet?.user?.fullname} +
    + {item?.vetFarm?.vet?.user?.mobile} + + ) : ( + "ندارد" + )} +
    + ); +}; + +export const TablePage3 = ({ items, start, end }) => { + const slicedItems = items?.slice(start - 1, end); + return ( + + + + + + + + + + + + + + + + {/* + */} + + + + + {slicedItems?.map((item, i) => ( + + + + + + + + + + + + + + {/* + */} + + + ))} + +
    ردیفکد بارخریدارفروشندهتاریخ کشتارماشینرانندهنژادتعدادوزن بارمیانگین وزنکد قرنطینهتعداد تخلیه شده (دامپزشک)وزن تخلیه شده (دامپزشک)دامپزشک
    {i + start}{item?.barCode} + {item?.killhouseUser?.name}
    ( + {item?.killhouseUser?.killHouseOperator?.user.mobile}) +
    + {item?.poultryRequest?.poultry?.unitName}
    ( + {item?.poultryRequest?.poultry?.user?.mobile}) +
    + {formatJustDate(item?.killRequest?.reciveDate)} + {item?.car?.typeCar}{item?.car?.driverName} + {item?.poultryRequest?.chickenBreed} + {item?.quantity?.toLocaleString()} + {item?.weightInfo?.weight?.toLocaleString()} + {item?.weightInfo?.indexWeight} + + {item?.vetAcceptedRealQuantity}{item?.vetAcceptedRealWeight} + {item?.vetFarm ? ( + <> + {item?.vetFarm?.vet?.user?.fullname} +
    + {item?.vetFarm?.vet?.user?.mobile} + + ) : ( + "ندارد" + )} +
    + ); +}; + +export const TablePage4 = ({ items, start, end }) => { + const slicedItems = items?.slice(start - 1, end); + return ( + + + + + + + + + + + + + + + + + + {/* + */} + + + + + {slicedItems?.map((item, i) => ( + + + + + + + + + + + + + + + + {/* + */} + + + ))} + +
    ردیفکد بارخریدارفروشندهتاریخ کشتارماشینرانندهنژادتعدادوزن بارمیانگین وزنکد قرنطینهتعداد تخلیه شده (دامپزشک)وزن تخلیه شده (دامپزشک)اطلاعات بار تعداداطلاعات بار وزنکاربر
    {i + start}{item?.barCode} + {item?.killhouseUser?.name}
    ( + {item?.killhouseUser?.killHouseOperator?.user.mobile}) +
    + {item?.poultryRequest?.poultry?.unitName}
    ( + {item?.poultryRequest?.poultry?.user?.mobile}) +
    + {formatJustDate(item?.killRequest?.reciveDate)} + {item?.car?.typeCar}{item?.car?.driverName} + {item?.poultryRequest?.chickenBreed} + {item?.quantity?.toLocaleString()} + {item?.weightInfo?.weight?.toLocaleString()} + {item?.weightInfo?.indexWeight} + + + {item?.vetAcceptedRealQuantity.toLocaleString()} + + {item?.vetAcceptedRealWeight.toLocaleString()} + ثبت نشدهثبت نشده + {item?.vetFarm ? ( + <> + {item?.vetFarm?.vet?.user?.fullname} +
    + {item?.vetFarm?.vet?.user?.mobile} + + ) : ( + "ندارد" + )} +
    + ); +}; + +export const TablePage5 = ({ items, start, end }) => { + const slicedItems = items?.slice(start - 1, end); + return ( + + + + + + + + {/* */} + + + + + + + + + + + + + {slicedItems?.map((item, i) => ( + + + + + + {/* */} + + + + + + + + + + + ))} + +
    ردیفکد بارخریدارتاریخ کشتارفروشندهماشینرانندهکد قرنطینهتعدادوزن بارتعداد تخلیه شده (دامپزشک)وزن تخلیه شده (دامپزشک)اطلاعات بار کشتارگاه (تعداد)اطلاعات بار کشتارگاه (وزن)
    {i + start}{item?.barCode} + {item?.killhouseUser?.name}
    ( + {item?.killhouseUser?.killHouseOperator?.user.mobile}) +
    + {formatJustDate(item?.killRequest?.reciveDate)} + + {item?.poultryRequest?.poultry?.unitName}
    ( + {item?.poultryRequest?.poultry?.user?.mobile}) +
    {item?.car?.typeCar}{item?.car?.driverName} + + + {item?.weightInfo?.quantity.toLocaleString()} + + {item?.weightInfo?.weight.toLocaleString()} + + {item?.weightInfo?.killHouseVetQuantity.toLocaleString()} + + {item?.weightInfo?.killHouseVetWeight.toLocaleString()} + + {item?.weightInfo?.assingmentQuantity.toLocaleString()} + + {item?.weightInfo?.assingmentWeight.toLocaleString()} +
    + ); +}; diff --git a/src/features/province/components/province-get-contradictions-file/PagesWeb.js b/src/features/province/components/province-get-contradictions-file/PagesWeb.js new file mode 100644 index 0000000..d413c38 --- /dev/null +++ b/src/features/province/components/province-get-contradictions-file/PagesWeb.js @@ -0,0 +1,527 @@ +import { useRef } from "react"; +import { formatJustDate } from "../../../../utils/formatTime"; + +const styles = { + tableInNewPage: { + pageBreakAfter: "always", + paddingLeft: "40px", + paddingRight: "40px", + direction: "rtl", + fontFamily: "titr", + fontWeight: "bold", + }, + container: { + width: "95%", + alignSelf: "center", + pageBreakInside: "avoid", + }, + + invoiceTable: { + width: "100%", + borderCollapse: "collapse", + alignSelf: "center", + fontFamily: "titr", + marginBottom: "15px", + }, + tableCell: { + border: "1px solid #000", + pAlign: "left", + textAlign: "center", + fontSize: 12, + fontWeight: "bolder", + }, + tableCellGreen: { + border: "1px solid #000", + pAlign: "left", + textAlign: "center", + fontSize: 12, + color: "white", + fontWeight: "bolder", + backgroundColor: "rgba(26, 188, 156, 0.7)", + }, + tableCellMobile: { + border: "1px solid #000", + pAlign: "left", + textAlign: "center", + fontSize: 12, + }, + tableInnerCell: { + border: "1px solid #000", + pAlign: "left", + textAlign: "center", + fontSize: 9, + whiteSpace: "nowrap", + }, + tableHeader: { + backgroundColor: "rgba(211, 211, 211, 0.3)", + pageBreakAfter: "auto", + }, + headerRow: { + backgroundColor: "rgba(211, 211, 211, 0.3)", + color: "black", + pageBreakInside: "avoid", + pageBreakAfter: "auto", + }, + + tableHeaderCell: { + backgroundColor: "rgba(211, 211, 211, 0.3)", + fontSize: 12, + border: "1px solid #000", + padding: "4px", + textAlign: "center", + fontWeight: "bolder", + }, + tableHeaderCellGreen: { + backgroundColor: "rgba(26, 188, 156, 0.7)", + fontSize: 12, + border: "1px solid #000", + padding: "4px", + textAlign: "center", + fontWeight: "bolder", + color: "white", + }, + footer: { + left: 0, + bottom: 0, + width: "100%", + position: "absolute", + }, + footerContainer: { + alignItems: "center", + display: "flex", + }, + + tableRowEven: { + backgroundColor: "rgba(170, 183, 255, 0.3)", + }, + titleOfTable: { + marginRight: "20px", + fontSize: "15px", + }, +}; + +export const GetClearanceCode = ({ clearanceCode }) => { + const formRef = useRef(null); + + const handleCodeClick = () => { + if (formRef.current) { + formRef.current.submit(); + } + }; + + return ( +
    + + + + {clearanceCode} + +
    + ); +}; +export const TablePage1Web = ({ item }) => { + return ( + + + + + + + + + + + + + + + + + + + + + + + + + +
    تعداد درخواستمجموع درخواست کشتار (قطعه)مجموع درخواست کشتار (وزن)تعداد تخصیص به خریداروزن تخصیص به خریدار مانده قطعه قابل تخصیصوزن قابل تخصیصاپراتور
    + {item?.totalRequests.toLocaleString()} + + {item?.poultryRequestTotalQuantity.toLocaleString()} + + {Math.round(item?.poultryRequestTotalWeight).toLocaleString()} + + {item?.provinceKillRequestsTotalQuantity.toLocaleString()} + + {item?.provinceKillRequestsTotalWeight.toLocaleString()} + + {item?.poultryRequestTotalRemainQuantity.toLocaleString()} + + {Math.round(item?.poultryRequestRemainWeight).toLocaleString()} + + {item?.operatorFullname}
    {item?.operatorMobile} +
    + ); +}; + +export const TablePage1Part2Web = ({ items, start, end }) => { + const slicedItems = items?.slice(start - 1, end); + return ( + + + + + + + + + + + + + + + + + {slicedItems?.map((item, i) => ( + + + + + + + + + + + + + ))} + +
    ردیفخریدارسهم کشتار (قطعه)سهم کشتار (وزن)تعداد ماشین هاتخصیص به ماشین (قطعه)تخصیص به ماشین (وزن)مانده قطعه قابل تخصیصمانده وزن قابل تخصیصاپراتور
    {i + start} + {item?.killhouseUser?.name}
    ( + {item?.killhouseUser?.killHouseOperator?.user.mobile}) +
    + {item?.totalInfo?.provinceKillRequestQuantity.toLocaleString()} + + {item?.totalInfo?.provinceKillRequestWeight.toLocaleString()} + + {item?.totalInfo?.killHouseRequestsCount.toLocaleString()} + + {item?.totalInfo?.killHouseRequestQuantity.toLocaleString()} + + {item?.totalInfo?.killHouseRequestWeight.toLocaleString()} + + {item?.totalInfo?.provinceKillRequestRemainQuantity.toLocaleString()} + + {item?.totalInfo?.provinceKillRequestRemainWeight.toLocaleString()} + + { + <> + {item?.totalInfo?.operatorFullname} +
    + {item?.totalInfo?.operatorMobile} + + } +
    + ); +}; + +export const TablePage2Web = ({ items, start, end }) => { + const slicedItems = items?.slice(start - 1, end); + return ( + + + + + + + + + + + + + + + + + + + + {slicedItems?.map((item, i) => ( + + + + + + + + + + + + + + + + ))} + +
    ردیفکد بارخریدارتاریخ کشتارفروشندهماشینرانندهنژادتعدادوزن بارمیانگین وزنمحل کشتاردامپزشک
    {i + start}{item?.barCode} + {item?.killhouseUser?.name}
    ( + {item?.killhouseUser?.killHouseOperator?.user.mobile}) +
    + {formatJustDate(item?.killRequest?.reciveDate)} + + {item?.poultryRequest?.poultry?.unitName}
    ( + {item?.poultryRequest?.poultry?.user?.mobile}) +
    {item?.car?.typeCar}{item?.car?.driverName} + {item?.poultryRequest?.chickenBreed} + {item?.quantity?.toLocaleString()} + {item?.weightInfo?.weight?.toLocaleString()} + {item?.weightInfo?.indexWeight}{item?.killPlace} + {item?.vetFarm ? ( + <> + {item?.vetFarm?.vet?.user?.fullname} +
    + {item?.vetFarm?.vet?.user?.mobile} + + ) : ( + "ندارد" + )} +
    + ); +}; + +export const TablePage3Web = ({ items, start, end }) => { + const slicedItems = items?.slice(start - 1, end); + return ( + + + + + + + + + + + + + + + + {/* + */} + + + + + {slicedItems?.map((item, i) => ( + + + + + + + + + + + + + + {/* + */} + + + ))} + +
    ردیفکد بارخریدارفروشندهتاریخ کشتارماشینرانندهنژادتعدادوزن بارمیانگین وزنکد قرنطینهتعداد تخلیه شده (دامپزشک)وزن تخلیه شده (دامپزشک)دامپزشک
    {i + start}{item?.barCode} + {item?.killhouseUser?.name}
    ( + {item?.killhouseUser?.killHouseOperator?.user.mobile}) +
    + {item?.poultryRequest?.poultry?.unitName}
    ( + {item?.poultryRequest?.poultry?.user?.mobile}) +
    + {formatJustDate(item?.killRequest?.reciveDate)} + {item?.car?.typeCar}{item?.car?.driverName} + {item?.poultryRequest?.chickenBreed} + {item?.quantity?.toLocaleString()} + {item?.weightInfo?.weight?.toLocaleString()} + {item?.weightInfo?.indexWeight} + + {item?.vetAcceptedRealQuantity}{item?.vetAcceptedRealWeight} + {item?.vetFarm ? ( + <> + {item?.vetFarm?.vet?.user?.fullname} +
    + {item?.vetFarm?.vet?.user?.mobile} + + ) : ( + "ندارد" + )} +
    + ); +}; + +export const TablePage4Web = ({ items, start, end }) => { + const slicedItems = items?.slice(start - 1, end); + return ( + + + + + + + + + + + + + + + + + + {/* + */} + + + + + {slicedItems?.map((item, i) => ( + + + + + + + + + + + + + + + + {/* + */} + + + ))} + +
    ردیفکد بارخریدارفروشندهتاریخ کشتارماشینرانندهنژادتعدادوزن بارمیانگین وزنکد قرنطینهتعداد تخلیه شده (دامپزشک)وزن تخلیه شده (دامپزشک)اطلاعات بار تعداداطلاعات بار وزنکاربر
    {i + start}{item?.barCode} + {item?.killhouseUser?.name}
    ( + {item?.killhouseUser?.killHouseOperator?.user.mobile}) +
    + {item?.poultryRequest?.poultry?.unitName}
    ( + {item?.poultryRequest?.poultry?.user?.mobile}) +
    + {formatJustDate(item?.killRequest?.reciveDate)} + {item?.car?.typeCar}{item?.car?.driverName} + {item?.poultryRequest?.chickenBreed} + {item?.quantity?.toLocaleString()} + {item?.weightInfo?.weight?.toLocaleString()} + {item?.weightInfo?.indexWeight} + + + {item?.vetAcceptedRealQuantity.toLocaleString()} + + {item?.vetAcceptedRealWeight.toLocaleString()} + ثبت نشدهثبت نشده + {item?.vetFarm ? ( + <> + {item?.vetFarm?.vet?.user?.fullname} +
    + {item?.vetFarm?.vet?.user?.mobile} + + ) : ( + "ندارد" + )} +
    + ); +}; + +export const TablePage5Web = ({ items, start, end }) => { + const slicedItems = items?.slice(start - 1, end); + return ( + + + + + + + + {/* */} + + + + + + + + + + + + + {slicedItems?.map((item, i) => ( + + + + + + {/* */} + + + + + + + + + + + ))} + +
    ردیفکد بارخریدارتاریخ کشتارفروشندهماشینرانندهکد قرنطینهتعدادوزن بارتعداد تخلیه شده (دامپزشک)وزن تخلیه شده (دامپزشک)اطلاعات بار کشتارگاه (تعداد)اطلاعات بار کشتارگاه (وزن)
    {i + start}{item?.barCode} + {item?.killhouseUser?.name}
    ( + {item?.killhouseUser?.killHouseOperator?.user.mobile}) +
    + {formatJustDate(item?.killRequest?.reciveDate)} + + {item?.poultryRequest?.poultry?.unitName}
    ( + {item?.poultryRequest?.poultry?.user?.mobile}) +
    {item?.car?.typeCar}{item?.car?.driverName} + + + {item?.weightInfo?.quantity.toLocaleString()} + + {item?.weightInfo?.weight.toLocaleString()} + + {item?.weightInfo?.killHouseVetQuantity.toLocaleString()} + + {item?.weightInfo?.killHouseVetWeight.toLocaleString()} + + {item?.weightInfo?.assingmentQuantity.toLocaleString()} + + {item?.weightInfo?.assingmentWeight.toLocaleString()} +
    + ); +}; diff --git a/src/features/province/components/province-get-contradictions-file/ProvinceGetContradictionsFile.js b/src/features/province/components/province-get-contradictions-file/ProvinceGetContradictionsFile.js new file mode 100644 index 0000000..e8151cd --- /dev/null +++ b/src/features/province/components/province-get-contradictions-file/ProvinceGetContradictionsFile.js @@ -0,0 +1,496 @@ +import React, { forwardRef } from "react"; +import { PropTypes } from "prop-types"; +import logo from "../../../../assets/images/logo.png"; +import { formatJustDate } from "../../../../utils/formatTime"; +import moment from "moment"; +import logoFooter from "../../../../assets/images/reportFooter.png"; +import { + TablePage1, + TablePage1Part2, + TablePage2, + TablePage3, + TablePage4, + TablePage5, +} from "./Pages"; + +const styles = { + page: { + width: "210mm", + height: "297mm", + display: "flex", + margin: "0 auto", + flexDirection: "column", + position: "relative", + direction: "rtl", + fontFamily: "titr", + fontWeight: "bold", + }, + pageData: { + position: "relative", + display: "flex", + direction: "rtl", + flexDirection: "column", + }, + tableInNewPage: { + pageBreakAfter: "always", + paddingLeft: "20px", + paddingRight: "20px", + direction: "rtl", + fontFamily: "titr", + fontWeight: "bold", + }, + container: { + width: "95%", + alignSelf: "center", + pageBreakInside: "avoid", + }, + p: { + fontFamily: "titr", + fontWeight: "bold", + pAlign: "justify", + }, + span: { + fontFamily: "titr", + fontWeight: "bold", + pAlign: "justify", + }, + + logo: { + marginTop: "15px", + width: "100px", + height: "auto", + zIndex: 10, + }, + logoFooter: { + width: "100px", + height: "auto", + }, + contentContainer: { + alignItems: "center", + display: "flex", + justifyContent: "space-between", + marginRight: "20px", + marginLeft: "20px", + }, + contentInLine: { + display: "flex", + flexDirection: "column", + alignItems: "center", + }, + mainTitle: { + fontFamily: "titr", + fontSize: 11, + pAlign: "center", + fontWeight: "bolder", + }, + signature: { + display: "flex", + flexDirection: "column", + alignItems: "flex-end", + marginLeft: "20px", + }, + watermarkContainer: { + position: "fixed", + top: 250, + left: 30, + right: 0, + bottom: 0, + justifyContent: "center", + alignItems: "center", + opacity: 0.15, + zIndex: -1, + userSelect: "none", + }, + watermarkp: { + fontFamily: "nazanin", + fontSize: 100, + fontWeight: "bolder", + color: "grey", + transform: "rotate(-45deg)", + left: "50%", + userSelect: "none", + }, + title: { + fontSize: 12, + fontWeight: "bolder", + pAlign: "center", + }, + titleTopic: { + fontSize: 12, + fontWeight: "bolder", + pAlign: "center", + }, + firsttitle: { + pAlign: "center", + color: "#00008b", + fontWeight: "800", + }, + title2: { + fontSize: 10, + marginBottom: 10, + pAlign: "center", + }, + options: { + marginLeft: "50px", + padding: "10px", + display: "flex", + flexDirection: "column", + alignItems: "flex-start", + }, + divider: { + alignSelf: "center", + width: "120mm", + height: "1px", + backgroundColor: "black", + margin: "0em", + }, + divider2: { + alignSelf: "center", + width: "100%", + height: "1px", + backgroundColor: "black", + margin: "0em", + }, + pTitleContainer: { + pAlign: "center", + margin: "15px", + textAlign: "justify", + textJustify: "inter-word", + fontFamily: "nazanin", + fontSize: "20px", + fontWeight: "bolder", + }, + tableHeaderCell: { + backgroundColor: "rgba(211, 211, 211, 0.3)", + fontSize: 10, + border: "1px solid #000", + padding: "4px", + textAlign: "center", + fontWeight: "bold", + }, + footer: { + left: 0, + bottom: 0, + width: "100%", + position: "absolute", + }, + footerContainer: { + alignItems: "center", + display: "flex", + }, + circle: { + borderRadius: "50%", + width: "20px", + height: "20px", + padding: "10px", + background: "#ecf0f1", + border: " 1px solid #000", + color: "#000", + textAlign: "center", + marginRight: "300px", + }, + tableRowEven: { + backgroundColor: "rgba(170, 183, 255, 0.3)", + }, + titleOfTable: { + marginRight: "20px", + fontSize: "15px", + }, + titleOfTable2: { + fontSize: "15px", + }, +}; + +const ProvinceGetContradictionsFile = forwardRef((props, ref) => { + const { item } = props; + const { inDate1 } = props; + const { inDate2 } = props; + + const HeaderPDF = () => { + return ( + <> +
    +
    +
    + + گزارش مغایرت اطلاعات کشتار و عدم فعالیت نقش ها{" "} + + {inDate1 === inDate2 ? ( + + مورخ {formatJustDate(moment(inDate1))} + + ) : ( + + از تاریخ {formatJustDate(moment(inDate1))} {"‌ ‌‌ "} تا تاریخ{" "} + {"‌ "} + {formatJustDate(moment(inDate2))} + + )} +
    + سامانه رصدیار +
    + +
    + logo +
    +
    + + ); + }; + + let pageNumber = 0; + const FooterPDF = () => { + pageNumber++; + return ( + <> +
    +
    +
    + logo + +

    + گزارش مغایرت درخواست کشتار و عدم فعالیت نقش ها +
    + www.rasadyaar.ir +

    +
    {pageNumber}
    +
    +
    + + ); + }; + + const step = 15; + + const iterationsPage1Part2 = Math.ceil( + Math.max(0, (item?.partFour.length - step) / step) + ); + + const generatedComponentsPage1Part2 = []; + + for (let i = 0; i < iterationsPage1Part2; i++) { + const start = step + i * step + 1; + const end = step + (i + 1) * step; + + if (item?.partTwo.length > end - step) { + generatedComponentsPage1Part2.push( +
    + +
    +

    + مغایرت در ثبت ماشین و ایجاد بار +

    + +
    + +
    + ); + } + } + + const iterationsPage3 = Math.ceil( + Math.max(0, (item?.partFour.length - step) / step) + ); + const generatedComponentsPage3 = []; + + for (let i = 0; i < iterationsPage3; i++) { + const start = step + i * step + 1; + const end = step + (i + 1) * step; + + if (item?.partFour.length > end - step) { + generatedComponentsPage3.push( +
    + +
    +

    بارهای تخلیه نشده

    + +
    + +
    + ); + } + } + + const iterationsPage4 = Math.ceil( + Math.max(0, (item?.partFive.length - step) / step) + ); + const generatedComponentsPage4 = []; + + for (let i = 0; i < iterationsPage4; i++) { + const start = step + i * step + 1; + const end = step + (i + 1) * step; + + if (item?.partFour.length > end - step) { + generatedComponentsPage4.push( +
    + +
    +

    + بارهاي تکمیل نشده (بارگزاري سند باسکول و مستندات وزنی) +

    + +
    + +
    + ); + } + } + + const iterationsPage5 = Math.ceil( + Math.max(0, (item?.partSix.length - step) / step) + ); + const generatedComponentsPage5 = []; + + for (let i = 0; i < iterationsPage5; i++) { + const start = step + i * step + 1; + const end = step + (i + 1) * step; + + if (item?.partFour.length > end - step) { + generatedComponentsPage5.push( +
    + +
    +

    مغایرت در اطلاعات بار

    + +
    + +
    + ); + } + } + + return ( +
    +
    +

    سامانه رصدیار

    +
    + +
    + +
    +

    درخواست کشتار و تخصیص

    +
    + +
    +

    مغایرت در ثبت ماشین و ایجاد بار

    + +
    + +
    +
    + +
    + + {generatedComponentsPage1Part2} + + {/* Page 2 */} + +
    + +
    +

    بارهای فاقد کد قرنطینه

    +
    + +
    +
    + +
    + + {item?.partThree.length > 15 && ( +
    + +
    +

    بارهای فاقد کد قرنطینه

    + +
    + +
    + )} + + {item?.partThree.length > 30 && ( +
    + +
    +

    بارهای فاقد کد قرنطینه

    + +
    + +
    + )} + + {item?.partThree.length > 45 && ( +
    + +
    +

    بارهای فاقد کد قرنطینه

    + +
    + +
    + )} + + {/* Page 3 */} + +
    + +
    +

    بارهای تخلیه نشده

    + +
    + +
    +
    + +
    + + {generatedComponentsPage3} + + {/* Page 4 */} + +
    + +
    +

    + بارهاي تکمیل نشده (بارگزاري سند باسکول و مستندات وزنی) +

    + +
    + +
    +
    + +
    + + {generatedComponentsPage4} + + {/* Page 5 */} + +
    + +
    +

    مغایرت در اطلاعات بار

    + +
    + +
    +
    + +
    + {generatedComponentsPage5} +
    + ); +}); + +ProvinceGetContradictionsFile.displayName = "ProvinceGetContradictionsFile"; + +export default ProvinceGetContradictionsFile; + +ProvinceGetContradictionsFile.propTypes = { + item: PropTypes.any, +}; diff --git a/src/features/province/components/province-get-contradictions-file/styles.css b/src/features/province/components/province-get-contradictions-file/styles.css new file mode 100644 index 0000000..d6d02f2 --- /dev/null +++ b/src/features/province/components/province-get-contradictions-file/styles.css @@ -0,0 +1,91 @@ +/* ----------------------------timeline---------------------------- */ +.timeline { + width: 100%; + margin: 0; +} + +.base-timeline { + position: relative; +} + +.timeline .base-timeline { + margin: 0; + padding-left: 20px; + padding-right: 20px; +} + +.base-timeline li { + list-style-type: none; + margin: 0; + padding: 0; + position: relative; + display: flex; + align-items: flex-start; +} + +.text-primary { + text-decoration: none; +} + +.timeline-icon { + margin-top: 5px; + color: white; + width: 15px; + height: 15px; + border-radius: 50%; + text-align: center; + line-height: 13px; + align-items: center; + justify-content: center; +} +.icon-image { + width: 9px; + align-self: center; +} + +.timeline-content { + margin-right: 10px; + position: relative; +} + +.act-time { + font-size: 14px; + color: #453939; +} + +.base-timeline-info { + margin-top: 2px; +} + +.base-timeline-info a { + font-size: 14px; + font-weight: bold; + color: #333; +} + +.text-muted { + font-size: 12px; + color: #999; +} + +.base-timeline li + li::before, +.base-timeline li::before { + content: ""; + position: absolute; + top: 10px; + right: 6.5px; + width: 2px; + height: 100%; + background-color: #ddd; + z-index: -1; +} + +.fa-caret-down { + color: white !important; +} + +.bg-primary { + background-color: orange; +} + +/* ----------------------------end timeline---------------------------- */ diff --git a/src/features/province/components/province-get-deleted-allocated-requests/ProvinceGetDeletedAllocatedRequests.js b/src/features/province/components/province-get-deleted-allocated-requests/ProvinceGetDeletedAllocatedRequests.js new file mode 100644 index 0000000..022599f --- /dev/null +++ b/src/features/province/components/province-get-deleted-allocated-requests/ProvinceGetDeletedAllocatedRequests.js @@ -0,0 +1,278 @@ +import { Button, TextField, Tooltip } from "@mui/material"; +import { DatePicker } from "@mui/x-date-pickers"; +import axios from "axios"; +import moment from "moment"; +import { useContext, useEffect, useState } from "react"; +import { RiFileExcel2Fill } from "react-icons/ri"; +import { useDispatch, useSelector } from "react-redux"; +import { Grid } from "../../../../components/grid/Grid"; +import { AppContext } from "../../../../contexts/AppContext"; +import { SPACING } from "../../../../data/spacing"; +import { formatJustDate } from "../../../../utils/formatTime"; +import { provinceGetDeletedAllocatedRequestsService } from "../../services/province-get-deleted-allocated-requests"; +import ResponsiveTable from "../../../../components/responsive-table/ResponsiveTable"; +import { provinceGetDashboardDeletedKillRequestService } from "../../services/get-dahsnoard-province-kill-request"; +import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl"; +import { RiSearchLine } from "react-icons/ri"; +import { checkPathStartsWith } from "../../../../utils/checkPathStartsWith"; + +export const ProvinceGetDeletedAllocatedRequests = () => { + const dispatch = useDispatch(); + const [dataTable, setDataTable] = useState(); + const [, , selectedDate1, setSelectedDate1, selectedDate2, setSelectedDate2] = + useContext(AppContext); + const selectedSubUser = useSelector( + (state) => state.userSlice.selectedSubUser + ); + const userKey = useSelector((state) => state.userSlice.userProfile.key); + + useEffect(() => { + const currentDate = moment(new Date()).format("YYYY-MM-DD"); + setSelectedDate1(currentDate); + setSelectedDate2(currentDate); + }, []); + + const [textValue, setTextValue] = useState(""); + + const handleTextChange = (event) => { + setTextValue(event.target.value); + }; + + const { provinceGetDeletedAllocatedRequests } = useSelector( + (state) => state.provinceSlice + ); + + useEffect(() => { + dispatch( + provinceGetDeletedAllocatedRequestsService({ + role_key: checkPathStartsWith("slaughter") + ? selectedSubUser?.key || "" + : "", + selectedDate1, + selectedDate2, + textValue, + }) + ); + }, [selectedDate1, selectedDate2, selectedSubUser?.key]); + + const handleSubmit = () => { + dispatch( + provinceGetDeletedAllocatedRequestsService({ + role_key: checkPathStartsWith("slaughter") + ? selectedSubUser?.key || "" + : "", + selectedDate1, + selectedDate2, + textValue, + }) + ); + + dispatch( + provinceGetDashboardDeletedKillRequestService({ + selectedDate1, + selectedDate2, + textValue, + role_key: checkPathStartsWith("slaughter") + ? selectedSubUser?.key || "" + : "", + }) + ).then((r) => { + setDashboardData(r.payload.data); + }); + }; + + useEffect(() => { + const d = provinceGetDeletedAllocatedRequests?.map((item, i) => { + let state = ""; + if (item.allocatedState === "pending") { + state = "در انتظار تایید"; + } else if (item.allocatedState === "accepted") { + state = "تایید شده"; + } else if (item.allocatedState === "rejected") { + state = "رد شده"; + } + return [ + i + 1, + item?.orderCode, + item?.freezing ? "انجماد" : item?.export ? "صادرات" : "عادی", + item?.poultryUnitName, + `${item?.poultryFullName} (${item?.poultryMobile})`, + item?.poultryCity, + formatJustDate(item?.sendDate), + item.poultryQuantity, + formatJustDate(item?.dateOfAllocate), + item?.killHouseName, + item?.killHouseCity, + item?.amount?.toLocaleString() + " ﷼", + item?.killHousePrice?.toLocaleString() + " ﷼", + item?.allocatedQuantity, + state, + item?.allocatedCarState ? "دارد" : "ندارد", + item?.allocatedRemainQuantity, + ]; + }); + setDataTable(d); + }, [provinceGetDeletedAllocatedRequests]); + + const [dashboardData, setDashboardData] = useState([]); + + useEffect(() => { + dispatch( + provinceGetDashboardDeletedKillRequestService({ + selectedDate1, + selectedDate2, + textValue, + role_key: checkPathStartsWith("slaughter") + ? selectedSubUser?.key || "" + : "", + }) + ).then((r) => { + setDashboardData(r.payload.data); + }); + }, [selectedDate1, selectedDate2, selectedSubUser?.key]); + + return ( + + + + + } + value={selectedDate1} + onChange={(e) => { + setSelectedDate1(moment(e).format("YYYY-MM-DD")); + }} + /> + + + } + value={selectedDate2} + onChange={(e) => { + setSelectedDate2(moment(e).format("YYYY-MM-DD")); + }} + /> + + + + + + + + + + + + + + + + + + + + + ); +}; diff --git a/src/features/province/components/province-get-report-file/ProvinceGetReportFile.js b/src/features/province/components/province-get-report-file/ProvinceGetReportFile.js new file mode 100644 index 0000000..d289036 --- /dev/null +++ b/src/features/province/components/province-get-report-file/ProvinceGetReportFile.js @@ -0,0 +1,1195 @@ +import React, { forwardRef } from "react"; +import { PropTypes } from "prop-types"; +import logo from "../../../../assets/images/reportHeader.png"; +import logoFooter from "../../../../assets/images/reportFooter.png"; +import { formatJustDate, formatJustTime } from "../../../../utils/formatTime"; +import moment from "moment"; +import { useCeoName } from "../../../../utils/getCeoName"; +import { useSystemName } from "../../../../utils/getSystemName"; + +const styles = { + page: { + width: "214mm", + height: "302mm", + display: "flex", + margin: "0 auto", + flexDirection: "column", + position: "relative", + direction: "rtl", + fontFamily: "titr", + fontWeight: "bold", + }, + pageData: { + margin: "20px", + position: "relative", + display: "flex", + direction: "rtl", + flexDirection: "column", + }, + tableInNewPage: { + pageBreakAfter: "always", + paddingLeft: "40px", + paddingRight: "40px", + direction: "rtl", + fontFamily: "titr", + fontWeight: "bold", + }, + container: { + width: "95%", + alignSelf: "center", + pageBreakInside: "avoid", + }, + p: { + fontFamily: "titr", + fontWeight: "bold", + pAlign: "justify", + }, + span: { + fontFamily: "titr", + fontWeight: "bold", + pAlign: "justify", + }, + invoiceTable: { + width: "100%", + borderCollapse: "collapse", + alignSelf: "center", + marginBottom: "2px", + }, + tableCell: { + border: "1px solid #000", + pAlign: "left", + textAlign: "center", + fontSize: 10, + }, + tableCellMobile: { + border: "1px solid #000", + pAlign: "left", + textAlign: "center", + fontSize: 10, + }, + tableInnerCell: { + border: "1px solid #000", + pAlign: "left", + textAlign: "center", + fontSize: 8, + whiteSpace: "nowrap", + }, + tableHeader: { + backgroundColor: "rgba(211, 211, 211, 0.3)", + pageBreakAfter: "auto", + }, + headerRow: { + backgroundColor: "rgba(211, 211, 211, 0.3)", + color: "black", + pageBreakInside: "avoid", + pageBreakAfter: "auto", + }, + logo: { + width: "300px", + height: "auto", + }, + logoFooter: { + width: "100px", + height: "auto", + }, + contentContainer: { + alignItems: "center", + display: "flex", + justifyContent: "space-between", + marginRight: "20px", + }, + contentInLine: { + display: "flex", + flexDirection: "column", + alignItems: "center", + }, + mainTitle: { + fontFamily: "titr", + fontSize: 11, + pAlign: "center", + fontWeight: "bolder", + }, + signature: { + display: "flex", + flexDirection: "column", + alignItems: "flex-end", + marginLeft: "20px", + }, + watermarkContainer: { + position: "fixed", + top: 250, + left: 30, + right: 0, + bottom: 0, + justifyContent: "center", + alignItems: "center", + opacity: 0.15, + zIndex: -1, + userSelect: "none", + }, + watermarkp: { + fontFamily: "nazanin", + fontSize: 100, + fontWeight: "bolder", + color: "grey", + transform: "rotate(-45deg)", + left: "50%", + userSelect: "none", + }, + title: { + fontSize: 12, + fontWeight: "bolder", + pAlign: "center", + }, + titleTopic: { + fontSize: 12, + fontWeight: "bolder", + pAlign: "center", + }, + firsttitle: { + marginLeft: "40px", + pAlign: "center", + color: "#00008b", + fontWeight: "800", + }, + title2: { + fontSize: 10, + marginBottom: 10, + pAlign: "center", + }, + options: { + marginLeft: "50px", + padding: "10px", + display: "flex", + flexDirection: "column", + alignItems: "flex-start", + }, + divider: { + width: "100%", + height: "2px", + backgroundColor: "red", + }, + pTitleContainer: { + pAlign: "center", + margin: "15px", + textAlign: "justify", + textJustify: "inter-word", + fontFamily: "nazanin", + fontSize: "20px", + fontWeight: "bolder", + }, + tableHeaderCell: { + backgroundColor: "rgba(211, 211, 211, 0.3)", + fontSize: 10, + border: "1px solid #000", + padding: "4px", + textAlign: "center", + fontWeight: "bold", + }, + footer: { + left: 0, + bottom: 0, + width: "100%", + position: "absolute", + }, + footerContainer: { + alignItems: "center", + display: "flex", + }, + circle: { + borderRadius: "50%", + width: "20px", + height: "20px", + padding: "10px", + background: "#ecf0f1", + border: " 1px solid #000", + color: "#000", + textAlign: "center", + marginRight: "130px", + }, + tableRowEven: { + backgroundColor: "rgba(170, 183, 255, 0.3)", + }, +}; + +const ProvinceGetReportFile = forwardRef((props, ref) => { + const { item } = props; + const { inDate } = props; + const { targetperson } = props; + const { reportType } = props; + const systemName = useSystemName(); + const ceoName = useCeoName(); + + const getItemState = (item) => { + let sellType = ""; + if (item?.directBuying) { + sellType = "خرید مستقیم"; + } else if (item?.union) { + sellType = "خرید خارج از استان"; + } else { + sellType = "اتحادیه"; + } + return sellType; + }; + + function totalCapacity(item) { + return item?.reduce( + (total, currentItem) => total + (currentItem?.quantity || 0), + 0 + ); + } + + function getItemInfoWeight(item) { + let totalQuantity = 0; + item?.forEach((option) => { + if (option?.hatching?.totalWeight) { + if (option?.hatching?.totalWeight !== undefined) { + totalQuantity += option?.hatching?.totalWeight; + } + } + }); + return totalQuantity; + } + + function getItemInfoQuantityPage2(item) { + let totalQuantity = 0; + item?.forEach((option) => { + if (option?.provinceKillRequests) { + option.provinceKillRequests.forEach((request) => { + if (request.info?.quantity !== undefined) { + totalQuantity += request.info.quantity; + } + }); + } + }); + return totalQuantity; + } + + function getItemInfoWeightPage2(item) { + let totalQuantity = 0; + item?.forEach((option) => { + if (option?.provinceKillRequests) { + option.provinceKillRequests.forEach((request) => { + if (request.info?.weight !== undefined) { + totalQuantity += request.info.weight; + } + }); + } + }); + return totalQuantity; + } + + function totalQuantityCar() { + return item?.serializerKillHouseRequestsThirdLetter.reduce( + (total, currentItem) => total + (currentItem?.weightInfo?.weight || 0), + 0 + ); + } + + const HeaderPDF = () => { + return ( + <> +
    +
    + + گزارش فرآیند کشتار وتوزیع مرغ گوشتی سامانه رصدیار + + + {systemName} {" - "} + مورخ {formatJustDate(inDate)} + + + این گزارش در تاریخ {formatJustDate(moment())} ساعت{" "} + {formatJustTime(moment())} صادر شده است. + +
    + +
    + logo +
    +
    + +
    + + ); + }; + + let pageNumber = 0; + const FooterPDF = () => { + pageNumber++; + return ( + <> +
    +
    +
    + logo + +

    + گزارش فرآیند کامل کشتار و پخش مرغ گوشتی سامانه رصدیار + www.rasadyaar.ir +

    +
    {pageNumber}
    +
    +
    + + ); + }; + + const TablePage2 = ({ items, start, end }) => { + const slicedItems = items?.slice(start - 1, end); + return ( + + + + + + + + + + + + + + + + + + {slicedItems?.map((item, i) => ( + + + + + + + + + + + + + + ))} + +
    ردیفکد سفارشنوع فروشتاریخ کشتارمرغدارشهر/تعاونیسن مرغمیانگین وزنوزن تقریبیمانده در سالنتعداد درخواست کشتار
    {i + start}{item.orderCode}{getItemState(item)}{formatJustDate(item?.sendDate)}{`${item?.poultry?.unitName} (${item?.poultry?.user?.mobile})`}{`${ + item?.poultry?.address?.city?.name + }/${ + item?.poultry?.cityOperator + ? item?.poultry?.cityOperator + : "بدون تعاونی" + }`}{item?.hatching?.age}{item?.IndexWeight} + {item?.hatching?.totalWeight?.toLocaleString()} + + {item?.hatching?.leftOver?.toLocaleString()} + + {item?.firstQuantity?.toLocaleString()} +
    + ); + }; + + const TablePage3 = ({ items, start, end }) => { + const slicedItems = items?.slice(start - 1, end); + + return ( + + + + + + + + + + + + + + + + + + {slicedItems?.map((item, i) => ( + + + + + + + + + + + + + + ))} + +
    ردیفمرغدارتلفنشهرتعدادمیانگین وزنیسنخریدارتعدادوزن تقریبی بارمحل کشتار
    {i + start}{item?.poultry?.user?.fullname} + {item?.poultry?.user?.mobile} + + {item?.poultry?.address?.city?.name} + + {item?.quantity.toLocaleString()} + + {item?.IndexWeight.toLocaleString()} + {item?.hatching?.age} + {item?.provinceKillRequests?.map((item, i, array) => ( + <> + {item?.killhouseUser?.killHouseOperator?.user?.fullname + ? item?.killhouseUser?.killHouseOperator?.user?.fullname + : "............"} +
    + {i < array.length - 1 && ( +
    + )} + + ))} +
    + {item?.provinceKillRequests?.map((item, i, array) => ( + <> + {item?.info?.quantity + ? item?.info?.quantity.toLocaleString() + : "............"} +
    + {i < array.length - 1 && ( +
    + )} + + ))} +
    + {item?.provinceKillRequests?.map((item, i, array) => ( + <> + {Math.round(item?.info?.weight) + ? Math.round(item?.info?.weight).toLocaleString() + : "............"} +
    + {i < array.length - 1 && ( +
    + )} + + ))} +
    + {item?.provinceKillRequests?.map((item, i, array) => ( + <> + {item?.info?.killPlace + ? item?.info?.killPlace + : "............"} +
    + {i < array.length - 1 && ( +
    + )} + + ))} +
    + ); + }; + + const TablePage4 = ({ items, start, end }) => { + const slicedItems = items?.slice(start - 1, end); + + return ( + + + + + + + + + + + + + + + + + + {slicedItems?.map((item, i) => ( + + + + + + + + + + + + + + ))} + +
    ردیفکد بارخریدارماشینرانندهنژادتعدادوزن بارمیانگین وزنمرغدارمحل کشتار
    {i + start}{item?.barCode} + {item.killhouseUser?.name} ( + {item.killhouseUser?.killHouseOperator?.user?.mobile}) + + {item.addCar.driver.typeCar} {item?.addCar.driver.pelak} + + {item?.addCar?.driver?.driverName} ( + {item?.addCar?.driver?.driverMobile}) + + {item?.poultryRequest?.chickenBreed} + + {item?.quantity?.toLocaleString()} + + {item?.weightInfo?.weight?.toLocaleString()} + + {item?.weightInfo?.indexWeight?.toLocaleString()} + + {item?.poultryRequest?.poultry?.unitName} ( + {item.poultryRequest.poultry?.user?.mobile}) + {item?.killPlace}
    + ); + }; + + const TablePage5 = ({ items, start, end }) => { + const slicedItems = items?.slice(start - 1, end); + + return ( + + + + + + + + + + + + + + + + {slicedItems?.map((item, i) => ( + + + + + + + + + + + + ))} + +
    ردیفخریدار/تلفنشهرحجم لاشه هاوزن لاشه هالاشه های تخصیص داده شدهوزن تخصیص داده شدهلاشه قابل تخصیصوزن قابل تخصیص
    {i + start}{`${item?.killHouseOperator.user?.fullname} (${item?.killHouseOperator.user?.mobile})`}{item?.systemAddress?.address} + {item?.provinceKillRequestInformation?.totalNumberOfCarcasses.toLocaleString()} + + {item?.provinceKillRequestInformation?.totalWeightOfCarcasses.toLocaleString()} + + {item?.provinceKillRequestInformation?.allocatedTotalNumberOfCarcasses.toLocaleString()} + + {item?.provinceKillRequestInformation?.allocatedTotalWeightOfCarcasses.toLocaleString()} + + {item?.provinceKillRequestInformation?.remainTotalNumberOfCarcasses.toLocaleString()} + + {item?.provinceKillRequestInformation?.remainTotalWeightOfCarcasses.toLocaleString()} +
    + ); + }; + + const TablePage6 = ({ items, start, end }) => { + const slicedItems = items?.slice(start - 1, end); + + return ( + + + + + + + + + + + + + + + + + + + + {slicedItems?.map((item, i) => ( + + + + + + + + + + + + + + + + ))} + +
    ردیفخریدارتاریخ تخصیصماهیتنوع تخصیصنام واحد صنفیموبایل مالکشناسه صنفنوع فعالیتحوزه فعالیتشهرستانحجم لاشهوزن لاشه
    {i + start} + {item?.wareHouse?.killHouse?.killer === "true" + ? "کشتارکن" + : "کشتارگاه"}{" "} + {item?.wareHouse?.killHouse?.name} + {formatJustDate(item?.date)} + {item?.steward ? "مباشر" : "صنف"} + + {item?.type === "manual" ? "دستی" : "اتوماتیک"} + + {item?.steward?.guilds?.guildsName + ? item?.steward?.guilds?.guildsName + : item?.guilds?.guildsName} + + {item?.steward?.guilds?.user.mobile + ? item?.steward?.guilds?.user.mobile + : item?.guilds?.user.mobile} + + {item?.steward?.guilds?.guildsId + ? item?.steward?.guilds?.guildsId + : item?.guilds?.guildsId} + + {item?.steward?.guilds?.typeActivity + ? item?.steward?.guilds?.typeActivity + : item?.guilds?.typeActivity} + + {item?.steward?.guilds?.areaActivity + ? item?.steward?.guilds?.areaActivity + : item?.guilds?.areaActivity} + + {item?.steward?.guilds?.user?.city + ? item?.steward?.guilds?.user?.city + : item?.guilds?.user?.city} + {item?.numberOfCarcasses}{item?.weightOfCarcasses}
    + ); + }; + + return ( +
    +
    +

    سامانه رصدیار

    +
    +
    + +
    +

    {targetperson}

    +

    با سلام

    +

    + احتراماً به پیوست، گزارش کامل فرآیند کشتار و توزیع مرغ گوشتی استان + جهت استحضار بحضورتان ارسال میگردد. +

    +

    خلاصه گزارش:

    +

    + در مورخ{" "} + {reportType === "slaughter" + ? formatJustDate(moment(inDate)) + : formatJustDate(moment(inDate).subtract(1, "days"))}{" "} + تعداد + {item?.serializerPoultryRequestsFirstLetter.length} درخواست کشتار + توسط مرغداران استان برای کشتار{" "} + {totalCapacity(item?.serializerPoultryRequestsFirstLetter) !== + undefined && + totalCapacity( + item?.serializerPoultryRequestsFirstLetter + ).toLocaleString()}{" "} + قطعه مرغ زنده با وزن تقریبی{" "} + {getItemInfoWeight( + item?.serializerPoultryRequestsFirstLetter + ).toLocaleString()}{" "} + کیلوگرم به اتحادیه مرغداران گوشتی استان ارسال گردید بعد از پایش + اطلاعات تعداد{" "} + {getItemInfoQuantityPage2( + item?.serializerPoultryRequestsSecondeLetter + ).toLocaleString()}{" "} + قطعه مرغ با وزن تقریبی{" "} + {Math.round( + getItemInfoWeightPage2( + item?.serializerPoultryRequestsSecondeLetter + ) + ).toLocaleString()}{" "} + کیلوگرم به {item?.serializerKillHouseRequestsFourthPartOne.buyers}{" "} + خریدار تخصیص داده شد .از مجموع ذکر شده تخصیصی به خریداران،{" "} + {item?.serializerKillHouseRequestsThirdLetter.length} + بار (خودرو) به تعداد{" "} + {item?.killHouseRequestsThirdLetterQuantity.toLocaleString()} قطعه و + وزن {totalQuantityCar()?.toLocaleString()} کیلوگرم ایجاد شد از + بارهای ایجاد شده تعداد{" "} + {item?.serializerKillHouseRequestsThirdLetterPartThree} بار توسط + دامپزشک فارم کد قرنطینه دریافت کرده اند و{" "} + {item?.serializerKillHouseRequestsThirdLetterPartTwo} بار به تعداد{" "} + {item?.killHouseRequestsThirdLetterPartTwoQuantity.toLocaleString()}{" "} + قطعه و وزن{" "} + {item?.killHouseRequestsThirdLetterPartTwoWeight?.toLocaleString()}{" "} + کیلوگرم توسط دامپزشک کشتارگاه یا کاربر کشتارگاه عملیات تخلیه و تکمیل + اطلاعات انجام پذیرفته است.از بار های تخلیه (تکمیل) شده توسط خریداران + و کشتارگاه ها بعد از کسر 25 % افت مرغ زنده، مقدار{" "} + {Math.floor( + (item?.killHouseRequestsThirdLetterPartTwoWeight / 100) * 75 + ).toLocaleString()}{" "} + کیلوگرم لاشه مرغ برای توزیع در بین مباشرین و اصناف + {reportType === "broadcast" + ? ` در انبار امروز (${formatJustDate( + inDate + )}) خریداران موجود گردید` + : ` در انبار خریداران موجود گردید`} + {reportType === "slaughter" + ? "." + : ` ، از مجموع موجودی انبار خریداران + و کشتارگاه ها مقدار ${Math.floor( + item?.serializerKillHouseRequestsFourthPartFifth + ).toLocaleString()} کیلوگرم به تعداد ${item?.serializerKillHouseRequestsFourthPartFourth.toLocaleString()} قطعه + بین ${ + item?.serializerKillHouseRequestsFourthPartSixth + } مباشر و صنف توزیع شد.`} +
    +
    + {reportType === "broadcast" && ( + + *باتوجه به اینکه گوشت مرغ پخش شده در تاریخ امروز ( + {formatJustDate(inDate)}) مربوط به اطلاعات و کشتار دیروز ( + {reportType === "slaughter" + ? formatJustDate(moment(inDate)) + : formatJustDate(moment(inDate).subtract(1, "days"))} + ) میباشد مبنای گزارش، تاریخ توزیع گوشت مرغ گرم در بین مباشرین + است. + + )} +

    +
    + ✒️ مدیرعامل + {ceoName} +
    +
    + + +
    + +
    + +
    +

    درخواست کشتار مرغداران:

    + +
    +

    + اطلاعات درخواست:{" "} + + {" "} + تعداد درخواست کشتار ( + {totalCapacity(item?.serializerPoultryRequestsFirstLetter) !== + undefined && + totalCapacity( + item?.serializerPoultryRequestsFirstLetter + ).toLocaleString()}{" "} + قطعه)، وزن کل ( + {getItemInfoWeight( + item?.serializerPoultryRequestsFirstLetter + ).toLocaleString()}{" "} + کیلوگرم). + +

    + + +
    +
    + + +
    + + {item?.serializerPoultryRequestsFirstLetter.length > 18 && ( +
    + +
    +

    درخواست کشتار مرغداران:

    + +
    + +
    + )} + + {item?.serializerPoultryRequestsFirstLetter.length > 40 && ( +
    + +
    +

    درخواست کشتار مرغداران:

    + +
    + +
    + )} + +
    +
    + +
    +

    تخصیص به خریداران توسط اتحادیه:

    + +
    +

    + اطلاعات تخصیص:{" "} + + {" "} + تعداد درخواست کشتار ( + {totalCapacity( + item?.serializerPoultryRequestsSecondeLetter + ) !== undefined && + totalCapacity( + item?.serializerPoultryRequestsSecondeLetter + ).toLocaleString()}{" "} + قطعه)، تخصیص داده شده ( + {getItemInfoQuantityPage2( + item?.serializerPoultryRequestsSecondeLetter + ).toLocaleString()}{" "} + قطعه)، وزن کل تخصیص ({" "} + {Math.round( + getItemInfoWeightPage2( + item?.serializerPoultryRequestsSecondeLetter + ) + ).toLocaleString()}{" "} + کیلوگرم). + +

    + + +
    +
    +
    + +
    + + {item?.serializerPoultryRequestsSecondeLetter.length > 25 && ( +
    + +
    +

    تخصیص به خریداران توسط اتحادیه:

    + +
    + +
    + )} + + {item?.serializerPoultryRequestsSecondeLetter.length > 50 && ( +
    + +
    +

    تخصیص به خریداران توسط اتحادیه:

    + +
    + +
    + )} + +
    +
    + +
    +

    + ثبت خودرو توسط خریدار (ایجاد بار): +

    + +
    + {/*

    + اطلاعات درخواست:{" "} + + {" "} + تعداد درخواست کشتار ( + {totalCapacity(item?.serializerPoultryRequestsFirstLetter) !== + undefined && + totalCapacity( + item?.serializerPoultryRequestsFirstLetter + ).toLocaleString()}{" "} + قطعه)، وزن کل تقریبی ( + {getItemInfoWeight( + item?.serializerPoultryRequestsFirstLetter + ).toLocaleString()}{" "} + کیلوگرم). + +

    */} + +
    +
    +
    + +
    + {item?.serializerKillHouseRequestsThirdLetter.length > 16 && ( +
    + +
    +

    ثبت خودرو توسط خریدار (ایجاد بار):

    + +
    + +
    + )} + + {item?.serializerKillHouseRequestsThirdLetter.length > 34 && ( +
    + +
    +

    ثبت خودرو توسط خریدار (ایجاد بار):

    + +
    + +
    + )} + + {item?.serializerKillHouseRequestsThirdLetter.length > 54 && ( +
    + +
    +

    ثبت خودرو توسط خریدار (ایجاد بار):

    + +
    + +
    + )} + + {item?.serializerKillHouseRequestsThirdLetter.length > 75 && ( +
    + +
    +

    ثبت خودرو توسط خریدار (ایجاد بار):

    + +
    + +
    + )} + + {reportType === "broadcast" && ( + <> +
    + +
    +

    + اطلاعات انبار خریداران و پخش به مباشرین: +

    + +
    +

    + اطلاعات :{" "} + + تعداد خریداران ( + {item?.serializerKillHouseRequestsFourthPartOne?.buyers})، + حجم لاشه ها ( + {Math.floor( + item?.serializerKillHouseRequestsFourthPartOne + ?.totalNumberOfCarcasses + ).toLocaleString()} + ) ، وزن لاشه ها ( + {Math.floor( + item?.serializerKillHouseRequestsFourthPartOne + ?.totalWeightOfCarcasses + ).toLocaleString()} + ) کیلوگرم. + +

    + + +
    +
    + +
    + + {item?.serializerKillHouseRequestsFourthPartTwo.length > 25 && ( +
    + +
    +

    + اطلاعات انبار خریداران و پخش به مباشرین: +

    + +
    + +
    + )} + + {item?.serializerKillHouseRequestsFourthPartTwo.length > 50 && ( +
    + +
    +

    + اطلاعات انبار خریداران و پخش به مباشرین: +

    + +
    + +
    + )} + + )} + +
    + +
    +

    + گزارش توزیع و پخش گوشت مرغ گرم به مباشرین و اصناف:{" "} +

    + +
    +

    + اطلاعات :{" "} + + تعداد تخصیصات: ( + {item?.serializerKillHouseRequestsFourthPartSixth.toLocaleString()} + ) مورد، حجم لاشه ها ( + {item?.serializerKillHouseRequestsFourthPartFourth.toLocaleString()} + ) قطعه، وزن لاشه ها ( + {Math.floor( + item?.serializerKillHouseRequestsFourthPartFifth + ).toLocaleString()} + ) کیلوگرم. + +

    + + +
    +
    + +
    + + {item?.serializerKillHouseRequestsFourthPartThree.length > 26 && ( +
    + +
    +

    + گزارش توزیع و پخش گوشت مرغ گرم به مباشرین و اصناف:{" "} +

    + +
    + +
    + )} + + {item?.serializerKillHouseRequestsFourthPartThree.length > 55 && ( +
    + +
    +

    + گزارش توزیع و پخش گوشت مرغ گرم به مباشرین و اصناف:{" "} +

    + +
    + +
    + )} +
    + ); +}); + +ProvinceGetReportFile.displayName = "ProvinceGetReportFile"; + +export default ProvinceGetReportFile; + +ProvinceGetReportFile.propTypes = { + item: PropTypes.any, +}; diff --git a/src/features/province/components/province-get-report-operations/PorvinceGetReportOperations.js b/src/features/province/components/province-get-report-operations/PorvinceGetReportOperations.js new file mode 100644 index 0000000..544d80c --- /dev/null +++ b/src/features/province/components/province-get-report-operations/PorvinceGetReportOperations.js @@ -0,0 +1,234 @@ +import React from "react"; +import { Grid } from "../../../../components/grid/Grid"; +import { DatePicker } from "@mui/x-date-pickers"; +import { AppContext } from "../../../../contexts/AppContext"; +import { useContext } from "react"; +import moment from "moment"; +import { + Button, + FormControl, + FormControlLabel, + IconButton, + Radio, + RadioGroup, + TextField, + Tooltip, + Typography, +} from "@mui/material"; +import { SPACING } from "../../../../data/spacing"; +import { useState } from "react"; +import { useRef } from "react"; +import { useReactToPrint } from "react-to-print"; +import { useEffect } from "react"; +import ProvinceGetReportFile from "../province-get-report-file/ProvinceGetReportFile"; +import axios from "axios"; +import { useDispatch, useSelector } from "react-redux"; +import { + LOADING_END, + LOADING_START, +} from "../../../../lib/redux/slices/appSlice"; +import { provinceGetProcessData } from "../../services/province-get-report-process"; +import { formatJustDate } from "../../../../utils/formatTime"; +import ArrowBackIcon from "@mui/icons-material/ArrowBack"; +import { useFormik } from "formik"; +import { Yup } from "../../../../lib/yup/yup"; +import { useLocation } from "react-router-dom"; +import { ROUTE_COMMERCE_REQUESTS } from "../../../../routes/routes"; + +export default function PorvinceGetReportOperations() { + const { pathname } = useLocation(); + const [, , selectedDate1, setSelectedDate1] = useContext(AppContext); + + const userInfo = useSelector((state) => state.userSlice); + + const dispatch = useDispatch(); + + const [data, setData] = useState(); + const componentRef = useRef(); + const printPDF = useReactToPrint({ + content: () => componentRef.current, + documentTitle: `گزارش روزانه ${formatJustDate(selectedDate1)}`, + onAfterPrint: () => { + setData(null); + }, + }); + + const setPdfOptions = (item) => { + dispatch(LOADING_START()); + dispatch(provinceGetProcessData({ selectedDate1, value })).then((r) => { + setData(r.payload.data); + dispatch(LOADING_END()); + }); + }; + + useEffect(() => { + if (data) { + printPDF(); + } + }, [data, printPDF]); + + const formik = useFormik({ + initialValues: { + target: "", + }, + validationSchema: Yup.object({ + target: Yup.string() + .typeError("لطفا فیلد را به درستی وارد کنید.!") + .required("این فیلد اجباری است!"), + }), + }); + + const [value, setValue] = React.useState("slaughter"); + + const handleChange = (event) => { + setValue(event.target.value); + }; + + useEffect(() => { + formik.validateForm(); + }, []); + + return ( + +
    + +
    + + + + + + } + value="slaughter" + /> + } + value="broadcast" + /> + + + + + {pathname !== ROUTE_COMMERCE_REQUESTS && ( + + + گیرنده گزارش: + + + + + + )} + + + + تاریخ گزارش: + + + ( + + )} + value={selectedDate1} + onChange={(e) => { + setSelectedDate1(moment(e).format("YYYY-MM-DD")); + }} + /> + + + + { + setSelectedDate1( + moment(selectedDate1) + .subtract(1, "days") + .format("YYYY-MM-DD") + ); + }} + aria-label="delete" + color="secondary" + > + + + + + + + + + + 📌 توجه: بمنظور پرینت صحیح، مشخصه Page size را بر روی A4 تنظیم کنید. + + + + + + + + +
    + ); +} diff --git a/src/features/province/components/province-guild-allocation.js/ProvinceGuildAllocation.js b/src/features/province/components/province-guild-allocation.js/ProvinceGuildAllocation.js new file mode 100644 index 0000000..0a8338f --- /dev/null +++ b/src/features/province/components/province-guild-allocation.js/ProvinceGuildAllocation.js @@ -0,0 +1,200 @@ +import { DatePicker } from "@mui/x-date-pickers"; +import { Button, TextField, Tooltip } from "@mui/material"; +import { useContext, useEffect, useState } from "react"; +import moment from "moment"; +import { Grid } from "../../../../components/grid/Grid"; +import { SPACING } from "../../../../data/spacing"; +import { useDispatch, useSelector } from "react-redux"; +import axios from "axios"; +import { RiFileExcel2Fill } from "react-icons/ri"; +import { AppContext } from "../../../../contexts/AppContext"; +import { totalReportDailyStewardBroadCastService } from "../../../slaughter-house/services/total-report-daily-steward-broadcast"; +import { getProvinceStewardAllocationsService } from "../../services/get-province-steward.allocation"; +import ResponsiveTable from "../../../../components/responsive-table/ResponsiveTable"; + +export const ProvinceGuildAllocation = () => { + const [, , selectedDate1, setSelectedDate1, selectedDate2, setSelectedDate2] = + useContext(AppContext); + // const navigate = useNavigate(); + const dispatch = useDispatch(); + const [dataTable, setDataTable] = useState([]); + const { getProvinceStewardAllocations, totalReportStewardDailyBroadCast } = + useSelector((state) => state.provinceSlice); + + useEffect(() => { + dispatch( + getProvinceStewardAllocationsService({ selectedDate1, selectedDate2 }) + ); + dispatch( + totalReportDailyStewardBroadCastService({ + selectedDate1, + selectedDate2, + }) + ); + }, [selectedDate1, selectedDate2]); + + useEffect(() => { + dispatch( + getProvinceStewardAllocationsService({ selectedDate1, selectedDate2 }) + ); + dispatch( + totalReportDailyStewardBroadCastService({ + selectedDate1, + selectedDate2, + }) + ); + }, []); + + useEffect(() => { + const d = getProvinceStewardAllocations?.map((item, i) => { + return [ + i + 1, + item?.informations?.buyers, + item?.informations?.city, + item?.informations?.totalFreeWeightOfCarcasses?.toLocaleString(), + item?.informations?.totalNumberOfFreeCarcasses?.toLocaleString(), + item?.informations?.totalWeightOfCarcasses?.toLocaleString(), + item?.informations?.totalNumberOfCarcasses?.toLocaleString(), + item?.informations?.finalTotalWeightOfCarcasses?.toLocaleString(), + item?.informations?.finalTotalNumberOfCarcasses?.toLocaleString(), + item?.informations?.totalAllocatedWeight?.toLocaleString(), + item?.informations?.totalAllocatedQuantity?.toLocaleString(), + item?.informations?.totalAcceptedAllocatedWeight?.toLocaleString(), + item?.informations?.totalAcceptedAllocatedQuantity?.toLocaleString(), + item?.informations?.totalRemainQuantity?.toLocaleString(), + item?.informations?.totalRemainWeight?.toLocaleString(), + + + + + , + ]; + }); + setDataTable(d); + }, [getProvinceStewardAllocations]); + + return ( + + + + } + value={selectedDate1} + onChange={(e) => { + setSelectedDate1(moment(e).format("YYYY-MM-DD")); + }} + /> + + + } + value={selectedDate2} + onChange={(e) => { + setSelectedDate2(moment(e).format("YYYY-MM-DD")); + }} + /> + + + + + + + + + + + + + + + ); +}; diff --git a/src/features/province/components/province-guilds-quantity/ProvinceGuildsQuantity.js b/src/features/province/components/province-guilds-quantity/ProvinceGuildsQuantity.js new file mode 100644 index 0000000..33aaaa4 --- /dev/null +++ b/src/features/province/components/province-guilds-quantity/ProvinceGuildsQuantity.js @@ -0,0 +1,77 @@ +import { Popover, Typography } from "@mui/material"; +import { useEffect, useState } from "react"; +import { useDispatch } from "react-redux"; +import { Grid } from "../../../../components/grid/Grid"; +import { SimpleTable } from "../../../../components/simple-table/SimpleTable"; +import { provinceGetGuildsNumbersNamesService } from "../../services/province-get-guilds-numbers-names"; + +export const ProvinceGuildsQuantity = ({ item }) => { + const dispatch = useDispatch(); + const [anchorEl, setAnchorEl] = useState(null); + const [dataTable, setDataTable] = useState([]); + const [data, setData] = useState([]); + + useEffect(() => { + const d = data?.map((item) => { + return [ + item?.guildsName, + item?.user?.fullname, + item?.user?.mobile, + item?.allocationLimit?.toLocaleString(), + item?.address?.city?.name, + ]; + }); + setDataTable(d); + }, [data]); + + const handleClick = (event) => { + setAnchorEl(event.currentTarget); + }; + + const handleClose = () => { + setAnchorEl(null); + }; + + const open = Boolean(anchorEl); + const id = open ? item.key : undefined; + + useEffect(() => { + dispatch(provinceGetGuildsNumbersNamesService({ key: item.key })).then( + (r) => setData(r.payload.data) + ); + }, []); + + return ( + + + {item.guildsQuantity} + + + + + + + + ); +}; diff --git a/src/features/province/components/province-hatching-archive-percent/ProvinceHatchingArchivePercent.js b/src/features/province/components/province-hatching-archive-percent/ProvinceHatchingArchivePercent.js new file mode 100644 index 0000000..a217370 --- /dev/null +++ b/src/features/province/components/province-hatching-archive-percent/ProvinceHatchingArchivePercent.js @@ -0,0 +1,155 @@ +import React, { useContext, useEffect, useState } from "react"; +import { Grid } from "../../../../components/grid/Grid"; +import { + Button, + FormControlLabel, + Radio, + TextField, + Typography, +} from "@mui/material"; +import { useFormik } from "formik"; +import { useDispatch } from "react-redux"; +import { Yup } from "../../../../lib/yup/yup"; +import { AppContext } from "../../../../contexts/AppContext"; +import { + provinceEditHatchingArchivePercent, + provinceGetHatchingArchivePercent, +} from "../../services/province-hatching-archive-percent"; + +export const ProvinceHatchingArchivePercent = () => { + const [isActive, setIsActive] = useState(false); + const dispatch = useDispatch(); + const [openNotif] = useContext(AppContext); + + const formik = useFormik({ + initialValues: { + percent: "", + }, + validationSchema: Yup.object({ + percent: Yup.number() + .required("این فیلد اجباری است") + .min(1, "حداقل مقدار باید 1 باشد") + .max(100, "حداکثر مقدار باید 100 باشد"), + }), + }); + + const fetchData = () => { + dispatch(provinceGetHatchingArchivePercent()).then((r) => { + if (r.payload?.data) { + setIsActive(r.payload.data.active); + formik.setFieldValue("percent", r.payload.data.percent); + } + }); + }; + + useEffect(() => { + fetchData(); + }, []); + + useEffect(() => { + formik.validateForm(); + }, []); + + const handleSubmit = (activeStatus) => { + dispatch( + provinceEditHatchingArchivePercent({ + percent: activeStatus ? parseInt(formik.values.percent) : 0, + active: activeStatus, + }) + ).then((r) => { + if (r.payload?.error) { + openNotif({ + vertical: "top", + horizontal: "center", + msg: r.payload.error, + severity: "error", + }); + } else { + fetchData(); + openNotif({ + vertical: "top", + horizontal: "center", + msg: "عملیات با موفقیت انجام شد.", + severity: "success", + }); + } + }); + }; + + return ( + + + بایگانی خودکار جوجه‌ریزی + + + { + setIsActive(true); + }} + /> + } + label="فعال" + /> + { + setIsActive(false); + handleSubmit(false); + }} + name="hatchingArchivePercent" + /> + } + label="غیر فعال" + /> + + {isActive && ( + <> + + + + + + + + + )} + + ); +}; diff --git a/src/features/province/components/province-kill-broadcast-in-detail/ProvinceKillbroadcastInDetail.js b/src/features/province/components/province-kill-broadcast-in-detail/ProvinceKillbroadcastInDetail.js new file mode 100644 index 0000000..eca54c3 --- /dev/null +++ b/src/features/province/components/province-kill-broadcast-in-detail/ProvinceKillbroadcastInDetail.js @@ -0,0 +1,892 @@ +import React, { useContext, useEffect } from "react"; +import { Grid } from "../../../../components/grid/Grid"; +import { SPACING } from "../../../../data/spacing"; +import { Button, TextField, Tooltip, Typography } from "@mui/material"; +import { useDispatch, useSelector } from "react-redux"; +import { provinceCasesGetTableDetails } from "../../services/province-cases-get-table-details"; +import { AppContext } from "../../../../contexts/AppContext"; +import { DatePicker } from "@mui/x-date-pickers"; +import moment from "moment"; +import axios from "axios"; +import { RiFileExcel2Fill } from "react-icons/ri"; +import { ExcelLink } from "../../../../components/excel-link/ExcelLink"; +import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl"; + +export const ProvinceKillbroadcastInDetail = () => { + const dispatch = useDispatch(); + const [, , selectedDate1, setSelectedDate1, selectedDate2, setSelectedDate2] = + useContext(AppContext); + const { casesTableDetails } = useSelector((item) => item.provinceSlice); + const [openNotif] = useContext(AppContext); + const userKey = useSelector((state) => state.userSlice.userProfile.key); + + useEffect(() => { + const currentDate = moment(new Date()).format("YYYY-MM-DD"); + setSelectedDate1(currentDate); + setSelectedDate2(currentDate); + }, []); + + useEffect(() => { + dispatch( + provinceCasesGetTableDetails({ + selectedDate1: selectedDate1, + selectedDate2: selectedDate2, + }) + ); + }, [selectedDate1, selectedDate2]); + + return ( + + + گزارش کلی فارم های فعال مرغ گوشتی دارای مانده در سالن بیشتر از 10 درصد و + بازه سنی 55 تا 90 روزه + + {(getRoleFromUrl() === "ProvinceOperator" || + getRoleFromUrl() === "SuperAdmin") && ( + + + + )} +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    تعداد فارممجموع جوجه ریزی کلتعداد فارم بایگانیمجموع جوجه ریزی بایگانیتعداد فارم فعالمجموع جوجه ریزی فعالمجموع قطعه کشتار شدهمجموع وزن کشتار شدهجمع کل مانده در سالن مانده در سالن از 90 درصد جوجه ریزیکمترین سنبیشترین سنمجموع وزن تعهد دولتیمجموع قطعه کشتار دولتیمجموع وزن کشتار دولتیمجموع قطعه کشتار آزادمجموع وزن کشتار آزادمجموع تعداد کشتار خارج از استانمجموع وزن کشتار خارج از استان
    + {casesTableDetails?.age55Age90?.poultry?.toLocaleString()} + + {casesTableDetails?.age55Age90?.hatchingQuantity?.toLocaleString()} + + {casesTableDetails?.age55Age90?.lenArchiveHatching?.toLocaleString()} + + {casesTableDetails?.age55Age90?.archiveHatchingQuantity?.toLocaleString()} + + {casesTableDetails?.age55Age90?.lenActiveHatching?.toLocaleString()} + + {casesTableDetails?.age55Age90?.activeHatchingQuantity?.toLocaleString()} + + {casesTableDetails?.age55Age90?.hatchingKilledQuantity?.toLocaleString()} + + {casesTableDetails?.age55Age90?.hatchingKilledWeight?.toLocaleString()} + + {casesTableDetails?.age55Age90?.hatchingLeftOver?.toLocaleString()} + + {casesTableDetails?.age55Age90?.hatchingLeftOverNintyPercent?.toLocaleString()} + + {casesTableDetails?.age55Age90?.minAge?.toLocaleString()} + + {casesTableDetails?.age55Age90?.maxAge?.toLocaleString()} + + {casesTableDetails?.age55Age90?.totalCommitment?.toLocaleString()} + + {casesTableDetails?.age55Age90?.governmentalQuantity?.toLocaleString()} + + {casesTableDetails?.age55Age90?.governmentalWeight?.toLocaleString()} + + {casesTableDetails?.age55Age90?.freeQuantity?.toLocaleString()} + + {casesTableDetails?.age55Age90?.freeWeight?.toLocaleString()} + + {casesTableDetails?.age55Age90?.outProvinceKilledQuantity?.toLocaleString()} + + {casesTableDetails?.age55Age90?.outProvinceKilledWeight?.toLocaleString()} +
    +
    + + + + ( + + )} + value={selectedDate1} + onChange={(e) => { + setSelectedDate1(moment(e).format("YYYY-MM-DD")); + }} + /> + + + ( + + )} + value={selectedDate2} + onChange={(e) => { + setSelectedDate2(moment(e).format("YYYY-MM-DD")); + }} + /> + + + + + + + + + + گزارش بارهای ایجاد شده در فرآیند کشتار مرغ گوشتی + + + + + اطلاعات کلی بارها + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + {" "} + {" "} + + {" "} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + {casesTableDetails?.killRequest?.poultryRequest?.toLocaleString()} + + {casesTableDetails?.killRequest?.poultryRequestQuantity?.toLocaleString()} + + {casesTableDetails?.killRequest?.poultryRequestWeight?.toLocaleString()} + + {casesTableDetails?.killRequest?.minAge?.toLocaleString()} + + {casesTableDetails?.killRequest?.maxAge?.toLocaleString()} + + {casesTableDetails?.killRequest?.avgAge?.toLocaleString()} + + {casesTableDetails?.killRequest?.lenKillRequest?.toLocaleString()} + + {casesTableDetails?.killRequest?.killRequestQuantity?.toLocaleString()} + + {casesTableDetails?.killRequest?.killRequestWeight?.toLocaleString()} + + {casesTableDetails?.killRequest?.avgWeight} + + {casesTableDetails?.killRequest?.lenKillRequestHasCode?.toLocaleString()} + + {casesTableDetails?.killRequest?.quantityOfKillRequestHasCode?.toLocaleString()} + + {casesTableDetails?.killRequest?.lenKillRequestHasQuarantine?.toLocaleString()} + + {casesTableDetails?.killRequest?.quantityOfKillRequestHasQuarantine?.toLocaleString()} + + {casesTableDetails?.killRequest?.lenKillRequestHasNotCode?.toLocaleString()} + + {casesTableDetails?.killRequest?.quantityOfKillRequestHasNotCode?.toLocaleString()} + + {casesTableDetails?.killRequest?.differenceBar?.toLocaleString()} +
    +
    + + + + تفکیک بارهای دولتی، آزاد و خارج از استان + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + + + + + + + {" "} + + + + + + + + مجموع وزن بارهای آزاد + بارهای آزاد احراز شده از قرنطینه + + مجموع حجم بارهای آزاد احراز شده از قرنطینه + + کل بارهای آزاد دارای کد قرنطینه + تعداد بارهای خارج از استانمجموع قطعه بارهای خارج از استان
    + {casesTableDetails?.freeAndGovernmentKillRequest?.lenGovernment?.toLocaleString()} + + {casesTableDetails?.freeAndGovernmentKillRequest?.quantityGovernment?.toLocaleString()} + + {casesTableDetails?.freeAndGovernmentKillRequest?.weightGovernment?.toLocaleString()} + + {casesTableDetails?.freeAndGovernmentKillRequest?.lenGovernmentQuarantineQuantity?.toLocaleString()} + + {casesTableDetails?.freeAndGovernmentKillRequest?.realQuantityBarGovernmentQuarantineQuantity?.toLocaleString()} + + {casesTableDetails?.freeAndGovernmentKillRequest?.lenFree?.toLocaleString()} + + {casesTableDetails?.freeAndGovernmentKillRequest?.quantityFree?.toLocaleString()} + + {casesTableDetails?.freeAndGovernmentKillRequest?.weightFree?.toLocaleString()} + + {casesTableDetails?.freeAndGovernmentKillRequest?.lenFreeQuarantineQuantity?.toLocaleString()} + + {casesTableDetails?.freeAndGovernmentKillRequest?.realQuantityBarFreeQuarantineQuantity?.toLocaleString()} + + {casesTableDetails?.freeAndGovernmentKillRequest?.lenFreeHasCode?.toLocaleString()} + + {casesTableDetails?.freeAndGovernmentKillRequest?.lenOutKillRequest?.toLocaleString()} + + {casesTableDetails?.freeAndGovernmentKillRequest?.quantityOutKillRequest?.toLocaleString()} +
    +
    + + + + اطلاعات بارهای تخلیه شده و تکمیل شده توسط کشتارگاه + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    تعداد بارهای ورودی به کشتارگاه + مجموعه قطعه بارهای ورودی به کشتارگاه + وزن بارهای ورودی به کشتارگاهمیانگین وزنوزن لاشه مرغ بعد از کسر 25% افتتعداد بار تخلیه شده دامپزشکمجموع حجم تخلیه شده دامپزشکمجموع وزن تخلیه شده دامپزشکتعداد بارهای تکمیل شده کشتارگاهمجموع حجم نهایی در کشتارگاهمجموع وزن نهایی در کشتارگاهبارهای تخلیه شده فاقد کد قرنطینه + قطعه بارهای تخلیه شده فاقد کد قرنطینه + + وزن بارهای تخلیه شده فاقد کد قرنطینه +
    + {casesTableDetails?.completeKillRequest?.lenCompleteWithKillHouseAndVet?.toLocaleString()} + + {casesTableDetails?.completeKillRequest?.quantityWithKillHouseAndVet?.toLocaleString()} + + {casesTableDetails?.completeKillRequest?.weightWithKillHouseAndVet?.toLocaleString()} + + {casesTableDetails?.completeKillRequest?.avgWeight} + + {casesTableDetails?.completeKillRequest?.less25?.toLocaleString()} + + {casesTableDetails?.completeKillRequest?.lenCompleteWithVet?.toLocaleString()} + + {casesTableDetails?.completeKillRequest?.quantityCompleteWithVet?.toLocaleString()} + + {casesTableDetails?.completeKillRequest?.weightCompleteWithVet?.toLocaleString()} + + {casesTableDetails?.completeKillRequest?.lenCompleteWithKillHouse?.toLocaleString()} + + {casesTableDetails?.completeKillRequest?.quantityFinalKillHouse?.toLocaleString()} + + {casesTableDetails?.completeKillRequest?.weightFinalKillHouse?.toLocaleString()} + + {casesTableDetails?.completeKillRequest?.lenKillReqsHasNotCode?.toLocaleString()} + + {casesTableDetails?.completeKillRequest?.quantityKillReqsHasNotCode?.toLocaleString()} + + {casesTableDetails?.completeKillRequest?.weightKillReqsHasNotCode?.toLocaleString()} +
    +
    + + + + اطلاعات بارهای تخلیه نشده و تخلیه نشده توسط کشتارگاه + + + +
    + + + + + + + + + + + + + + + + + + + + + +
    تعداد بار تخلیه نشدهمجموع بارهای تخلیه نشدهوزن بارهای تخلیه نشده + بارهای تخلیه شده و عدم تکمیل توسط کشتارگاه + + قطعه بارهای تخلیه شده و عدم تکمیل توسط کشتارگاه + + وزن بارهای تخلیه شده و عدم تکمیل توسط کشتارگاه +
    + {casesTableDetails?.killRequestHasNotAssigment?.lenKillReqsNotAssigment?.toLocaleString()} + + {casesTableDetails?.killRequestHasNotAssigment?.quantityKillReqsNotAssigment?.toLocaleString()} + + {casesTableDetails?.killRequestHasNotAssigment?.weightKillReqsNotAssigment?.toLocaleString()} + + {casesTableDetails?.killRequestHasNotAssigment?.lenKillRequestHasNotComplete?.toLocaleString()} + + {casesTableDetails?.killRequestHasNotAssigment?.quantityKillRequestHasNotComplete?.toLocaleString()} + + {casesTableDetails?.killRequestHasNotAssigment?.weightKillRequestHasNotComplete?.toLocaleString()} +
    +
    + + + + حجم نهایی کم شده از سالن مرغدار (ملاک کشتار) + + + +
    + + + + + + + + + + + + + +
    ملاک قطعه کشتار شدهملاک وزن کشتار شده
    + {casesTableDetails?.finalQuantityAndWeight?.finalQuantity?.toLocaleString()} + + {casesTableDetails?.finalQuantityAndWeight?.finalWeight?.toLocaleString()} +
    +
    + + + + توزیع از کشتارگاه به مباشر و صنف + + + + + + تعداد خریداران:{" "} + {casesTableDetails?.killHouseWareHouseTotalReportDailyBroadCast?.buyers?.toLocaleString()} + + + تعداد مباشر تخصیص داده شده:{" "} + {casesTableDetails?.killHouseWareHouseTotalReportDailyBroadCast?.numberOfSteward?.toLocaleString()} + + + تعداد صنف تخصیص داده شده:{" "} + {casesTableDetails?.killHouseWareHouseTotalReportDailyBroadCast?.numberOfGuild?.toLocaleString()} + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + ورودی از سردخانه + + خرید خارج از استان + + بارهای روزانه + + جمع کل انبار + + توزیع شده + + توزیع/تحویل شده + + مانده انبار +
    تعدادوزنتعدادوزنتعدادوزنتعدادوزنتعدادوزنتعدادوزنتعدادوزن
    + {casesTableDetails?.killHouseWareHouseTotalReportDailyBroadCast?.incomingQuantityOfColdHouse?.toLocaleString()} + + {casesTableDetails?.killHouseWareHouseTotalReportDailyBroadCast?.incomingWeightOfColdHouse?.toLocaleString()} + + {casesTableDetails?.killHouseWareHouseTotalReportDailyBroadCast?.totalNumberOfFreeCarcasses?.toLocaleString()} + + {casesTableDetails?.killHouseWareHouseTotalReportDailyBroadCast?.totalFreeWeightOfCarcasses?.toLocaleString()} + + {casesTableDetails?.killHouseWareHouseTotalReportDailyBroadCast?.totalNumberOfCarcasses?.toLocaleString()} + + {casesTableDetails?.killHouseWareHouseTotalReportDailyBroadCast?.totalWeightOfCarcasses?.toLocaleString()} + + {casesTableDetails?.killHouseWareHouseTotalReportDailyBroadCast?.finalTotalNumberOfCarcasses?.toLocaleString()} + + {casesTableDetails?.killHouseWareHouseTotalReportDailyBroadCast?.finalTotalWeightOfCarcasses?.toLocaleString()} + + {casesTableDetails?.killHouseWareHouseTotalReportDailyBroadCast?.totalAllocatedQuantity?.toLocaleString()} + + {casesTableDetails?.killHouseWareHouseTotalReportDailyBroadCast?.totalAllocatedWeight?.toLocaleString()} + + {casesTableDetails?.killHouseWareHouseTotalReportDailyBroadCast?.totalAcceptedAllocatedQuantity?.toLocaleString()} + + {casesTableDetails?.killHouseWareHouseTotalReportDailyBroadCast?.totalAcceptedAllocatedWeight?.toLocaleString()} + + {casesTableDetails?.killHouseWareHouseTotalReportDailyBroadCast?.totalRemainQuantity?.toLocaleString()} + + {casesTableDetails?.killHouseWareHouseTotalReportDailyBroadCast?.totalRemainWeight?.toLocaleString()} +
    +
    + + + + توزیع از مباشر به صنف + + + + + + تعداد خریداران:{" "} + {casesTableDetails?.stewardWareHouseTotalReportDailyBroadCast?.buyers?.toLocaleString()} + + + تعداد صنف تخصیص داده شده:{" "} + {casesTableDetails?.stewardWareHouseTotalReportDailyBroadCast?.numberOfGuild?.toLocaleString()} + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + ورودی از سردخانه + + خرید خارج از استان + + بارهای روزانه + + جمع کل انبار + + توزیع شده + + توزیع/تحویل شده + + مانده انبار +
    تعدادوزنتعدادوزنتعدادوزنتعدادوزنتعدادوزنتعدادوزنتعدادوزن
    + {casesTableDetails?.stewardWareHouseTotalReportDailyBroadCast?.incomingQuantityOfColdHouse?.toLocaleString()} + + {casesTableDetails?.stewardWareHouseTotalReportDailyBroadCast?.incomingWeightOfColdHouse?.toLocaleString()} + + {casesTableDetails?.stewardWareHouseTotalReportDailyBroadCast?.totalNumberOfFreeCarcasses?.toLocaleString()} + + {casesTableDetails?.stewardWareHouseTotalReportDailyBroadCast?.totalFreeWeightOfCarcasses?.toLocaleString()} + + {casesTableDetails?.stewardWareHouseTotalReportDailyBroadCast?.totalNumberOfCarcasses?.toLocaleString()} + + {casesTableDetails?.stewardWareHouseTotalReportDailyBroadCast?.totalWeightOfCarcasses?.toLocaleString()} + + {casesTableDetails?.stewardWareHouseTotalReportDailyBroadCast?.finalTotalNumberOfCarcasses?.toLocaleString()} + + {casesTableDetails?.stewardWareHouseTotalReportDailyBroadCast?.finalTotalWeightOfCarcasses?.toLocaleString()} + + {casesTableDetails?.stewardWareHouseTotalReportDailyBroadCast?.totalAllocatedQuantity?.toLocaleString()} + + {casesTableDetails?.stewardWareHouseTotalReportDailyBroadCast?.totalAllocatedWeight?.toLocaleString()} + + {casesTableDetails?.stewardWareHouseTotalReportDailyBroadCast?.totalAcceptedAllocatedQuantity?.toLocaleString()} + + {casesTableDetails?.stewardWareHouseTotalReportDailyBroadCast?.totalAcceptedAllocatedWeight?.toLocaleString()} + + {casesTableDetails?.stewardWareHouseTotalReportDailyBroadCast?.totalRemainQuantity?.toLocaleString()} + + {casesTableDetails?.stewardWareHouseTotalReportDailyBroadCast?.totalRemainWeight?.toLocaleString()} +
    +
    +
    + ); +}; diff --git a/src/features/province/components/province-killer-managment/ProvinceKillerManagment.js b/src/features/province/components/province-killer-managment/ProvinceKillerManagment.js new file mode 100644 index 0000000..95737b4 --- /dev/null +++ b/src/features/province/components/province-killer-managment/ProvinceKillerManagment.js @@ -0,0 +1,270 @@ +import { + Button, + FormControl, + FormControlLabel, + InputLabel, + MenuItem, + Radio, + RadioGroup, + Select, + Switch, + TextField, +} from "@mui/material"; +import { useContext, useState } from "react"; +import { useDispatch } from "react-redux"; +import { AdvancedTable } from "../../../../components/advanced-table/AdvancedTable"; +import { Grid } from "../../../../components/grid/Grid"; +import { AppContext } from "../../../../contexts/AppContext"; +import { SPACING } from "../../../../data/spacing"; +import { provinceMakeKillRequestForPoultryService } from "../../services/province-make-kill-request-for-poultry"; +// import PersonAddAlt1Icon from "@mui/icons-material/PersonAddAlt1"; +// import DescriptionIcon from "@mui/icons-material/Description"; +// import HistoryIcon from "@mui/icons-material/History"; +import SettingsIcon from "@mui/icons-material/Settings"; +import CircleIcon from "@mui/icons-material/Circle"; +import { + CLOSE_MODAL, + DRAWER, + OPEN_MODAL, +} from "../../../../lib/redux/slices/appSlice"; + +export const ProvinceKillerManagment = () => { + const dispatch = useDispatch(); + const [openNotif] = useContext(AppContext); + const hours = Array.from({ length: 8 }, (_, i) => i + 8); + const [selectedHour, setSelectedHour] = useState(""); + const [isChecked, setIsChecked] = useState(false); + const [tableRowsdata] = useState([ + [ + "احمد", + {}} />, + + , + + , + "بله", + "بهار لرستان", + + , + + // 1234, + // 1234, + // 1234, + // 1234, + + , + , + + 258, + {}} />, + + , + // , + // , + // , + + + + + + ), + }) + ); + }} + > + بیشتر + , + ], + ]); + + return ( + + + + + + + setIsChecked(!isChecked)} + /> + } + label="محدودیت زمان درخواست کشتار" + labelPlacement="start" + /> + {isChecked && ( + + ساعت پایان درخواست + + + )} + + + + + ); +}; diff --git a/src/features/province/components/province-killhouse-archive-fee/ProvinceKillhouseArchiveFee.js b/src/features/province/components/province-killhouse-archive-fee/ProvinceKillhouseArchiveFee.js new file mode 100644 index 0000000..9c59e27 --- /dev/null +++ b/src/features/province/components/province-killhouse-archive-fee/ProvinceKillhouseArchiveFee.js @@ -0,0 +1,400 @@ +import { + Button, + TextField, + Tooltip, + tooltipClasses, + Typography, +} from "@mui/material"; +import axios from "axios"; +import { useEffect, useState } from "react"; +import { useDispatch } from "react-redux"; +import { Grid } from "../../../../components/grid/Grid"; +import { PageTable } from "../../../../components/page-table/PageTable"; +import { SPACING } from "../../../../data/spacing"; +import { DRAWER, OPEN_MODAL } from "../../../../lib/redux/slices/appSlice"; +import { formatJustDate } from "../../../../utils/formatTime"; +import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl"; +import { SlaughterUnpaidFeesDetails } from "../../../slaughter-house/components/slaughter-unpaid-fees-details/SlaughterUnpaidFeesDetails"; +import KeyboardDoubleArrowUpIcon from "@mui/icons-material/KeyboardDoubleArrowUp"; +import KeyboardDoubleArrowDownIcon from "@mui/icons-material/KeyboardDoubleArrowDown"; +import styled from "styled-components"; +import { getFaUserRole } from "../../../../utils/getFaUserRole"; +import { ProvinceArchiveFeeDetails } from "../province-archive-fee-details/ProvinceArchiveFeeDetails"; +import { IconButton } from "@mui/material"; +import Visibility from "@mui/icons-material/Visibility"; +import Unarchive from "@mui/icons-material/Unarchive"; +import { ProvinceUnarchiveFee } from "../province-unarchive-fee/ProvinceUnarchiveFee"; +import { RiSearchLine } from "react-icons/ri"; + +export const ProvinceKillhouseArchiveFee = ({ killhouseKey }) => { + const dispatch = useDispatch(); + const [data, setData] = useState([]); + const [loading, setLoading] = useState(false); + const [totalRows, setTotalRows] = useState(0); + const [perPage, setPerPage] = useState(10); + + const [textValue, setTextValue] = useState(""); + + const handleTextChange = (event) => { + setTextValue(event.target.value); + }; + + const fetchApiData = async (page, textValue) => { + setLoading(true); + const response = await axios.get( + `province_wage/?search=filter&value=${textValue}&page=${page}&page_size=${perPage}&type=archive&kill_house_key=${killhouseKey}&role=${getRoleFromUrl()}` + ); + setData(response.data.results); + setTotalRows(response.data.count); + setLoading(false); + }; + + const handlePageChange = (page) => { + fetchApiData(page, textValue); + }; + + const handlePerRowsChange = async (newPerPage, page) => { + setLoading(true); + const response = await axios.get( + `province_wage/?search=filter&value=${textValue}&page=${page}&page_size=${newPerPage}&type=archive&kill_house_key=${killhouseKey}&role=${getRoleFromUrl()}` + ); + + setData(response.data.results); + setTotalRows(response.data.count); + setPerPage(newPerPage); + + setLoading(false); + }; + + useEffect(() => { + fetchApiData(1); + }, []); + + const handleSubmit = async (event) => { + event.preventDefault(); + setLoading(true); + + try { + const response = await axios.get( + `province_wage/?search=filter&value=${textValue}&type=archive&kill_house_key=${killhouseKey}&role=${getRoleFromUrl()}` + ); + setData(response.data.results); + setTotalRows(response.data.count); + } catch (error) { + console.error("Error fetching data:", error); + } finally { + setLoading(false); + } + }; + + const updateTable = () => { + fetchApiData(1); + }; + + let columns = [ + { + name: "کدسفارش", + selector: (item) => item?.provinceRequest?.orderCode, + sortable: true, + wrap: true, + allowOverflow: true, + center: true, + width: "90px", + }, + { + name: "مرغدار (تلفن)", + selector: (item) => + `${item?.provinceRequest?.poultryFullname} (${item?.provinceRequest?.poultryMobile})`, + sortable: true, + wrap: true, + allowOverflow: true, + center: true, + // width: "90px", + }, + { + name: "شهر", + selector: (item) => `${item?.provinceRequest?.poultryCity}`, + sortable: true, + wrap: true, + allowOverflow: true, + center: true, + width: "80px", + }, + { + name: "تاریخ کشتار", + selector: (item) => formatJustDate(item?.provinceRequest?.sendDate), + sortable: true, + wrap: true, + allowOverflow: true, + center: true, + width: "80px", + }, + { + name: "محل کشتار", + selector: (item) => item?.provinceRequest?.killPlace, + sortable: true, + wrap: true, + allowOverflow: true, + center: true, + }, + { + name: "نژاد", + selector: (item) => item?.provinceRequest?.breed, + sortable: true, + wrap: true, + allowOverflow: true, + center: true, + width: "80px", + }, + { + name: "تعداد (قطعه)", + selector: (item) => + item?.provinceRequest?.provinceKillRequestQuantity?.toLocaleString(), + sortable: true, + wrap: true, + allowOverflow: true, + center: true, + width: "80px", + }, + { + name: "وزن (کیلوگرم)", + selector: (item) => + item?.provinceRequest?.provinceKillRequestTotalWeight?.toLocaleString(), + sortable: true, + wrap: true, + allowOverflow: true, + center: true, + width: "90px", + }, + { + name: "میانگین وزنی (کیلوگرم)", + selector: (item) => item?.provinceRequest?.indexWeight, + sortable: true, + wrap: true, + allowOverflow: true, + center: true, + width: "90px", + }, + { + name: "تعرفه اتحادیه (ریال)", + selector: (item) => item?.provinceRequest?.wage?.toLocaleString(), + sortable: true, + wrap: true, + allowOverflow: true, + center: true, + width: "90px", + }, + { + name: "مبلغ کل تعرفه (ریال)", + selector: (item) => ( + + ), + sortable: true, + wrap: true, + allowOverflow: true, + center: true, + width: "90px", + }, + { + name: "جزییات سفارش", + selector: (item) => ( + { + dispatch( + DRAWER({ + top: true, + title: "جزییات سفارش", + content: , + }) + ); + }} + > + + + ), + sortable: true, + wrap: true, + allowOverflow: true, + center: true, + width: "90px", + }, + { + name: "اطلاعات بایگانی", + selector: (item) => ( + { + dispatch( + OPEN_MODAL({ + title: "اطلاعات بایگانی", + content: , + }) + ); + }} + > + + + ), + sortable: true, + wrap: true, + allowOverflow: true, + center: true, + width: "90px", + }, + { + name: "خارج کردن از بایگانی", + selector: (item) => { + return ( + { + dispatch( + OPEN_MODAL({ + title: "آیا مطمئن هستید؟", + content: ( + + ), + }) + ); + }} + > + + + ); + }, + sortable: true, + wrap: true, + allowOverflow: true, + center: true, + width: "90px", + }, + ]; + + if (getRoleFromUrl() === "KillHouse") { + columns.pop(); + } + + return ( + + + تعرفه های معوقه{" "} + {data[0]?.provinceRequest?.killHouseUserFullName && + `${data[0]?.provinceRequest?.killer ? "کشتارکن" : "کشتارگاه"} ${ + data[0]?.provinceRequest?.killHouseUserFullName + }`} + + + +
    + + + +
    +
    + } + columns={columns} + data={data} + progressPending={loading} + pagination + paginationServer + paginationTotalRows={totalRows} + onChangeRowsPerPage={handlePerRowsChange} + onChangePage={handlePageChange} + /> + + ); +}; + +const ProvinceUnpaidFeeView = ({ item, updateTable }) => { + const isBigger = + item?.provinceRequest.prevTotalAmount < item?.provinceRequest.totalAmount; + const isSmaller = + item?.provinceRequest.prevTotalAmount > item?.provinceRequest.totalAmount; + + const prevTotalAmount = ( + + {isBigger && "افزایش یافته"} + {isSmaller && "کاهش یافته"} + + مبلغ اولیه: {item?.provinceRequest?.prevTotalAmount?.toLocaleString()} ﷼ + + ویرایش کننده: {item?.totalAmountEditor?.fullname} + تاریخ ویرایش: {formatJustDate(item?.totalAmountEditor?.date)} + سمت: {getFaUserRole(item?.totalAmountEditor?.role)} + تلفن: {item?.totalAmountEditor?.mobile} + + ); + return ( + + {Boolean(item?.provinceRequest?.prevTotalAmount) && isBigger && ( + + + + + {item?.provinceRequest?.totalAmount?.toLocaleString()} + + + + )} + + {Boolean(item?.provinceRequest?.prevTotalAmount) && isSmaller && ( + + + + + {item?.provinceRequest?.totalAmount?.toLocaleString()} + + + + )} + + {!item?.provinceRequest?.prevTotalAmount && ( + + {item?.provinceRequest?.totalAmount?.toLocaleString()} + + )} + + ); +}; + +const HtmlTooltip = styled(({ className, ...props }) => ( + +))(({ theme }) => ({ + [`& .${tooltipClasses.tooltip}`]: { + backgroundColor: "#f5f5f9", + color: "rgba(0, 0, 0, 0.87)", + maxWidth: 220, + border: "1px solid #dadde9", + }, +})); diff --git a/src/features/province/components/province-killhouse-fee/ProvinceKillhouseFee.js b/src/features/province/components/province-killhouse-fee/ProvinceKillhouseFee.js new file mode 100644 index 0000000..2261c3d --- /dev/null +++ b/src/features/province/components/province-killhouse-fee/ProvinceKillhouseFee.js @@ -0,0 +1,449 @@ +import { + Button, + Checkbox, + FormControlLabel, + TextField, + Typography, +} from "@mui/material"; +import axios from "axios"; +import { useContext, useEffect, useState } from "react"; +import { useDispatch } from "react-redux"; +import { Grid } from "../../../../components/grid/Grid"; +import { PageTable } from "../../../../components/page-table/PageTable"; +import { SPACING } from "../../../../data/spacing"; +import { DRAWER } from "../../../../lib/redux/slices/appSlice"; +import { formatJustDate } from "../../../../utils/formatTime"; +import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl"; +import { SlaughterUnpaidFeesDetails } from "../../../slaughter-house/components/slaughter-unpaid-fees-details/SlaughterUnpaidFeesDetails"; + +import { DatePicker } from "@mui/x-date-pickers"; +import moment from "moment"; +import { AppContext } from "../../../../contexts/AppContext"; + +export const ProvinceKillhouseFee = ({ killhouseKey }) => { + const [, , selectedDate1, setSelectedDate1, selectedDate2, setSelectedDate2] = + useContext(AppContext); + const [withDate, setWithDate] = useState(false); + + useEffect(() => { + const currentDate = moment(new Date()).format("YYYY-MM-DD"); + setSelectedDate1(currentDate); + setSelectedDate2(currentDate); + }, []); + + const dispatch = useDispatch(); + const [data, setData] = useState([]); + const [loading, setLoading] = useState(false); + const [totalRows, setTotalRows] = useState(0); + const [perPage, setPerPage] = useState(10); + + const [textValue, setTextValue] = useState(""); + + const handleTextChange = (event) => { + setTextValue(event.target.value); + }; + + const fetchApiData = async (page, textValue) => { + setLoading(true); + const response = await axios.get( + `province_wage/?search=filter&value=${textValue}&page=${page}&page_size=${perPage}&type=unpaid&kill_house_key=${killhouseKey}&role=${getRoleFromUrl()}${ + withDate ? `&date1=${selectedDate1}&date2=${selectedDate2}` : `` + }` + ); + setData(response.data.results); + setTotalRows(response.data.count); + setLoading(false); + }; + + const handlePageChange = (page) => { + fetchApiData(page, textValue); + }; + + const handlePerRowsChange = async (newPerPage, page) => { + setLoading(true); + const response = await axios.get( + `province_wage/?search=filter&value=${textValue}&page=${page}&page_size=${newPerPage}&type=unpaid&kill_house_key=${killhouseKey}&role=${getRoleFromUrl()}${ + withDate ? `&date1=${selectedDate1}&date2=${selectedDate2}` : `` + }` + ); + + setData(response.data.results); + setTotalRows(response.data.count); + setPerPage(newPerPage); + + setLoading(false); + }; + + useEffect(() => { + fetchApiData(1); + }, []); + + useEffect(() => { + fetchApiData(1); + }, [selectedDate1, selectedDate2, withDate]); + + const handleSubmit = async (event) => { + event.preventDefault(); + setLoading(true); + + try { + const response = await axios.get( + `province_wage/?search=filter&value=${textValue}&type=unpaid&kill_house_key=${killhouseKey}&role=${getRoleFromUrl()}&date1=${selectedDate1}&date2=${selectedDate2}` + ); + setData(response.data.results); + setTotalRows(response.data.count); + } catch (error) { + console.error("Error fetching data:", error); + } finally { + setLoading(false); + } + }; + + // const updateTable = () => { + // fetchApiData(1); + // }; + + const columns = [ + { + name: "کدسفارش", + selector: (item) => item?.provinceRequest?.orderCode, + sortable: true, + wrap: true, + allowOverflow: true, + center: true, + // width: "90px", + }, + { + name: "مرغدار (تلفن)", + selector: (item) => + `${item?.provinceRequest?.poultryFullname} (${item?.provinceRequest?.poultryMobile})`, + sortable: true, + wrap: true, + allowOverflow: true, + center: true, + // width: "90px", + }, + { + name: "شهر", + selector: (item) => `${item?.provinceRequest?.poultryCity}`, + sortable: true, + wrap: true, + allowOverflow: true, + center: true, + // width: "80px", + }, + { + name: "تاریخ کشتار", + selector: (item) => formatJustDate(item?.provinceRequest?.sendDate), + sortable: true, + wrap: true, + allowOverflow: true, + center: true, + // width: "80px", + }, + { + name: "محل کشتار", + selector: (item) => item?.provinceRequest?.killPlace, + sortable: true, + wrap: true, + allowOverflow: true, + center: true, + }, + { + name: "نژاد", + selector: (item) => item?.provinceRequest?.breed, + sortable: true, + wrap: true, + allowOverflow: true, + center: true, + // width: "80px", + }, + { + name: "تعداد (قطعه)", + selector: (item) => + item?.provinceRequest?.provinceKillRequestQuantity?.toLocaleString(), + sortable: true, + wrap: true, + allowOverflow: true, + center: true, + // width: "80px", + }, + { + name: "وزن (کیلوگرم)", + selector: (item) => + item?.provinceRequest?.provinceKillRequestTotalWeight?.toLocaleString(), + sortable: true, + wrap: true, + allowOverflow: true, + center: true, + // width: "90px", + }, + { + name: "میانگین وزنی (کیلوگرم)", + selector: (item) => item?.provinceRequest?.indexWeight, + sortable: true, + wrap: true, + allowOverflow: true, + center: true, + // width: "90px", + }, + { + name: "تعرفه اتحادیه (ریال)", + selector: (item) => item?.provinceRequest?.wage?.toLocaleString(), + sortable: true, + wrap: true, + allowOverflow: true, + center: true, + // width: "90px", + }, + { + name: "مبلغ تعرفه (ریال)", + selector: (item) => item?.provinceRequest?.totalAmount?.toLocaleString(), + sortable: true, + wrap: true, + allowOverflow: true, + center: true, + // width: "90px", + }, + // { + // name: "مبلغ کل تعرفه (ریال)", + // selector: (item) => ( + // + // ), + // sortable: true, + // wrap: true, + // allowOverflow: true, + // center: true, + // // width: "90px", + // }, + { + name: "جزییات سفارش", + selector: (item) => ( + + ), + sortable: true, + wrap: true, + allowOverflow: true, + center: true, + // width: "90px", + }, + ]; + + return ( + + + + + + تعرفه های پرداخت نشده{" "} + {data[0]?.provinceRequest?.killHouseUserFullName && + ` ${data[0]?.provinceRequest?.killHouseUserFullName}`} + + + + setWithDate(!withDate)} + color="primary" + /> + } + /> + + + ( + + )} + value={selectedDate1} + onChange={(e) => { + setSelectedDate1(moment(e).format("YYYY-MM-DD")); + }} + /> + + + ( + + )} + value={selectedDate2} + onChange={(e) => { + setSelectedDate2(moment(e).format("YYYY-MM-DD")); + }} + /> + + + +
    + + + +
    +
    +
    + } + columns={columns} + data={data} + progressPending={loading} + pagination + paginationServer + paginationTotalRows={totalRows} + onChangeRowsPerPage={handlePerRowsChange} + onChangePage={handlePageChange} + /> +
    + + ); +}; + +// const ProvinceUnpaidFeeView = ({ item, updateTable }) => { +// const dispatch = useDispatch(); + +// const isBigger = +// item?.provinceRequest.prevTotalAmount < item?.provinceRequest.totalAmount; +// const isSmaller = +// item?.provinceRequest.prevTotalAmount > item?.provinceRequest.totalAmount; + +// const prevTotalAmount = ( +// +// {isBigger && "افزایش یافته"} +// {isSmaller && "کاهش یافته"} +// +// مبلغ اولیه: {item?.provinceRequest?.prevTotalAmount?.toLocaleString()} ﷼ +// +// ویرایش کننده: {item?.totalAmountEditor?.fullname} +// تاریخ ویرایش: {formatJustDate(item?.totalAmountEditor?.date)} +// سمت: {getFaUserRole(item?.totalAmountEditor?.role)} +// تلفن: {item?.totalAmountEditor?.mobile} +// +// ); +// return ( +// +// {Boolean(item?.provinceRequest?.prevTotalAmount) && isBigger && ( +// +// +// +// +// {item?.provinceRequest?.totalAmount?.toLocaleString()} +// +// +// +// )} + +// {Boolean(item?.provinceRequest?.prevTotalAmount) && isSmaller && ( +// +// +// +// +// {item?.provinceRequest?.totalAmount?.toLocaleString()} +// +// +// +// )} + +// {!item?.provinceRequest?.prevTotalAmount && ( +// +// {item?.provinceRequest?.totalAmount?.toLocaleString()} +// +// )} + +// +// +// ); +// }; + +// const HtmlTooltip = styled(({ className, ...props }) => ( +// +// ))(({ theme }) => ({ +// [`& .${tooltipClasses.tooltip}`]: { +// backgroundColor: "#f5f5f9", +// color: "rgba(0, 0, 0, 0.87)", +// maxWidth: 220, +// border: "1px solid #dadde9", +// }, +// })); diff --git a/src/features/province/components/province-killhouse-paid-fee-change-payment-type/ProvinceKillhousePaidFeeChangePaymentType.js b/src/features/province/components/province-killhouse-paid-fee-change-payment-type/ProvinceKillhousePaidFeeChangePaymentType.js new file mode 100644 index 0000000..58363d4 --- /dev/null +++ b/src/features/province/components/province-killhouse-paid-fee-change-payment-type/ProvinceKillhousePaidFeeChangePaymentType.js @@ -0,0 +1,101 @@ +import React, { useContext } from "react"; +import { + Button, + MenuItem, + Select, + FormControl, + InputLabel, + FormHelperText, +} from "@mui/material"; +import { useFormik } from "formik"; +import * as Yup from "yup"; +import { Grid } from "../../../../components/grid/Grid"; +import { useDispatch } from "react-redux"; +import { provinceKillhousesPaidFeesChangePaymentTypeService } from "../../services/province-killhouses-paid-fee-change-payment-type-service"; +import { AppContext } from "../../../../contexts/AppContext"; +import { CLOSE_MODAL } from "../../../../lib/redux/slices/appSlice"; + +const validationSchema = Yup.object({ + paymentType: Yup.string().required("نوع پرداخت را وارد کنید!"), +}); + +export const ProvinceKillhousePaidFeeChangePaymentType = ({ + fetchApiData, + item, +}) => { + const dispatch = useDispatch(); + const [openNotif] = useContext(AppContext); + + const formik = useFormik({ + initialValues: { + paymentType: item?.transactionType ? item?.transactionType : "", + }, + validationSchema: validationSchema, + onSubmit: (values) => { + dispatch( + provinceKillhousesPaidFeesChangePaymentTypeService({ + transaction_key: item?.key, + transaction_type: values.paymentType, + }) + ).then((r) => { + if (r.payload.error) { + openNotif({ + vertical: "top", + horizontal: "center", + msg: r.payload.error, + severity: "error", + }); + } else { + fetchApiData(1); + dispatch(CLOSE_MODAL()); + openNotif({ + vertical: "top", + horizontal: "center", + msg: "عملیات با موفقیت انجام شد.", + severity: "success", + }); + } + }); + }, + }); + + return ( + + + نوع پرداخت + + {formik.touched.paymentType && formik.errors.paymentType ? ( + {formik.errors.paymentType} + ) : null} + + + + ); +}; + +export default ProvinceKillhousePaidFeeChangePaymentType; diff --git a/src/features/province/components/province-killhouse-paid-fee-edit-description/ProvinceKillHousePaidFeeEditDescription.js b/src/features/province/components/province-killhouse-paid-fee-edit-description/ProvinceKillHousePaidFeeEditDescription.js new file mode 100644 index 0000000..1218b9a --- /dev/null +++ b/src/features/province/components/province-killhouse-paid-fee-edit-description/ProvinceKillHousePaidFeeEditDescription.js @@ -0,0 +1,92 @@ +import React, { useContext, useEffect } from "react"; +import { Grid } from "../../../../components/grid/Grid"; +import { Button, TextField } from "@mui/material"; +import { useFormik } from "formik"; +import { Yup } from "../../../../lib/yup/yup"; +import { provincePaidFeesEditDescription } from "../../services/province-paid-fees-edit-description"; +import { AppContext } from "../../../../contexts/AppContext"; +import { useDispatch } from "react-redux"; +import { CLOSE_MODAL } from "../../../../lib/redux/slices/appSlice"; + +export const ProvinceKillHousePaidFeeEditDescription = ({ + fetchApiData, + item, +}) => { + const [openNotif] = useContext(AppContext); + + const dispatch = useDispatch(); + const formik = useFormik({ + initialValues: { + description: item?.description ? item?.description : "", + }, + validationSchema: Yup.object({ + description: Yup.string() + .required("این فیلد اجباری است!") + .typeError("لطفا فیلد را پر کنید!"), + }), + }); + + useEffect(() => { + formik.validateForm(); + }, []); + + return ( + + + + + + + + ); +}; diff --git a/src/features/province/components/province-killhouse-paid-fee/ProvinceKillhousePaidFee.js b/src/features/province/components/province-killhouse-paid-fee/ProvinceKillhousePaidFee.js new file mode 100644 index 0000000..328f1b8 --- /dev/null +++ b/src/features/province/components/province-killhouse-paid-fee/ProvinceKillhousePaidFee.js @@ -0,0 +1,469 @@ +import { + Button, + Checkbox, + IconButton, + Popover, + TextField, + List, + ListItem, + ListItemButton, + ListItemIcon, + Typography, +} from "@mui/material"; +import { DatePicker } from "@mui/x-date-pickers"; +import moment from "moment"; +import { useDispatch } from "react-redux"; +import axios from "axios"; +import ResponsiveTable from "../../../../components/responsive-table/ResponsiveTable"; +import { AppContext } from "../../../../contexts/AppContext"; +import ToggleOffOutlinedIcon from "@mui/icons-material/ToggleOffOutlined"; +import ToggleOnIcon from "@mui/icons-material/ToggleOn"; +import { + LOADING_END, + LOADING_START, + OPEN_MODAL, +} from "../../../../lib/redux/slices/appSlice"; +import { useReactToPrint } from "react-to-print"; +import SuccessTransactionRecipt from "../success-transaction-recipt/SuccessTransactionRecipt"; +import EditIcon from "@mui/icons-material/Edit"; +import { Grid } from "../../../../components/grid/Grid"; +import ProvinceKillhousePaidFeeChangePaymentType from "../province-killhouse-paid-fee-change-payment-type/ProvinceKillhousePaidFeeChangePaymentType"; +import ProvincePaymentFactorFile from "../province-payment-factor-file/ProvincePaymentFactorFile"; +import ArticleIcon from "@mui/icons-material/Article"; +import DescriptionIcon from "@mui/icons-material/Description"; +import { useContext, useEffect, useRef, useState } from "react"; +import PrintIcon from "@mui/icons-material/Print"; +import TuneIcon from "@mui/icons-material/Tune"; +import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl"; +import { formatJustDate, formatJustTime } from "../../../../utils/formatTime"; +import { SPACING } from "../../../../data/spacing"; +import { ProvinceKillHousePaidFeeEditDescription } from "../province-killhouse-paid-fee-edit-description/ProvinceKillHousePaidFeeEditDescription"; +import { RiSearchLine } from "react-icons/ri"; + +export const ProvinceKillhousePaidFee = ({ killhouseKey, type }) => { + const [, , selectedDate1, setSelectedDate1, selectedDate2, setSelectedDate2] = + useContext(AppContext); + const dispatch = useDispatch(); + useEffect(() => { + const currentDate = moment(new Date()).format("YYYY-MM-DD"); + setSelectedDate1(currentDate); + setSelectedDate2(currentDate); + }, []); + + const handleTextChange = (event) => { + setTextValue(event.target.value); + }; + + const [data, setData] = useState([]); + const [totalRows, setTotalRows] = useState(0); + const [perPage, setPerPage] = useState(10); + const [textValue, setTextValue] = useState(""); + const [page, setPage] = useState(1); + const [tableData, setTableData] = useState([]); + const [withDate, setWithDate] = useState(false); + + const fetchApiData = async (page) => { + dispatch(LOADING_START()); + const response = await axios.get( + `internal-transactions/?search=filter&value=${textValue}&page=${page}&page_size=${perPage}&type=paid&${type}=${killhouseKey}&role=${getRoleFromUrl()}${ + withDate ? `&date1=${selectedDate1}&date2=${selectedDate2}` : `` + }` + ); + + dispatch(LOADING_END()); + setData(response.data.results); + setTotalRows(response.data.count); + }; + + const handlePageChange = (page) => { + fetchApiData(page); + setPage(page); + }; + + const handlePerRowsChange = (perRows) => { + setPerPage(perRows); + setPage(1); + }; + + const updateTable = () => { + fetchApiData(page !== 0 ? page : 1); + }; + + const [reciptData, setReciptData] = useState(); + + const componentRef = useRef(); + const printPDF = useReactToPrint({ + content: () => componentRef.current, + documentTitle: `گزارش پرونده `, + }); + + const setPdfOptions = (item) => { + setReciptData(item, printPDF()); + }; + + // factor pdf + + const [factorData, setFactorData] = useState(); + + const componentFactorRef = useRef(); + + const printFactorPDF = useReactToPrint({ + content: () => componentFactorRef.current, + documentTitle: `فاکتور پرداخت`, + pageStyle: ` + @page { + size: landscape; + margin: 0; + dir: rtl; + margin: 20px; + } + body { + -webkit-print-color-adjust: exact; + } + `, + }); + + const setFactorPdfOptions = (item) => { + setFactorData(item); + setTimeout(() => { + printFactorPDF(); + }, 1); + }; + + const KillhousePaidFeeActions = ({ item }) => { + const [anchorEl, setAnchorEl] = useState(null); + + const handleClick = (event) => { + setAnchorEl(event.currentTarget); + }; + + const handleClose = () => { + setAnchorEl(null); + }; + + const open = Boolean(anchorEl); + const id = open ? `paid-fee-actions-${item?.key}` : undefined; + + const handlePrint = () => { + handleClose(); + setPdfOptions(item); + }; + + const handleFactor = (isUnion) => { + handleClose(); + setFactorPdfOptions({ item, isUnion }); + }; + + return ( +
    + + + + + + + + + + + + چاپ رسید + + + + + handleFactor(true)} + > + + + + + فاکتور اتحادیه + + + + + handleFactor(false)} + > + + + + + فاکتور سامانه + + + + + +
    + ); + }; + + useEffect(() => { + const d = data?.map((item, i) => { + return [ + page === 1 ? i + 1 : i + perPage * (page - 1) + 1, + `${formatJustDate(item.date)} ساعت (${formatJustTime(item.date)})`, + getRoleFromUrl() === "SuperAdmin" ? ( + + {item?.transactionType === "wage-gateway-auto" + ? "آنلاین" + : item?.transactionType === "correspondence" + ? "مکاتبات" + : "دستی"} + { + dispatch( + OPEN_MODAL({ + title: "ویرایش نوع پرداخت", + content: ( + + ), + }) + ); + }} + > + + + + ) : item?.transactionType === "wage-gateway-auto" ? ( + "آنلاین" + ) : item?.transactionType === "correspondence" ? ( + "مکاتبات" + ) : ( + "دستی" + ), + `${item?.payerInfo?.fullname} (${item?.payerInfo?.mobile})`, + item?.orderId, + item?.refId, + item?.orderId, + item?.cardHolderPan, + item?.transactionAmount?.toLocaleString(), + getRoleFromUrl() === "SuperAdmin" ? ( + + {item?.description ? item?.description : "-"}{" "} + { + dispatch( + OPEN_MODAL({ + title: "ویرایش توضیحات", + content: ( + + ), + }) + ); + }} + > + + + + ) : item?.description ? ( + item?.description + ) : ( + "-" + ), + , + ]; + }); + + setTableData(d); + }, [data]); + + useEffect(() => { + fetchApiData(1); + }, [dispatch, selectedDate1, selectedDate2, perPage]); + + const handleSubmit = async (event) => { + event.preventDefault(); + dispatch(LOADING_START()); + + try { + const response = await axios.get( + `internal-transactions/?search=filter&value=${textValue}&page=${page}&page_size=${perPage}&type=paid&${type}=${killhouseKey}&role=${getRoleFromUrl()}${ + withDate ? `&date1=${selectedDate1}&date2=${selectedDate2}` : `` + }` + ); + setData(response.data.results); + setTotalRows(response.data.count); + dispatch(LOADING_END()); + } catch (error) { + console.error("Error fetching data:", error); + } + }; + + return ( + + +
    + + +
    + + + } + checkedIcon={} + checked={withDate} + onChange={() => setWithDate(!withDate)} + color="primary" + size="large" + /> + + ( + + )} + value={selectedDate1} + onChange={(e) => { + setSelectedDate1(moment(e).format("YYYY-MM-DD")); + }} + /> + + + ( + + )} + value={selectedDate2} + onChange={(e) => { + setSelectedDate2(moment(e).format("YYYY-MM-DD")); + }} + /> + + + +
    + + + +
    +
    + + +
    + ); +}; diff --git a/src/features/province/components/province-legal-guilds-in-province/ProvinceLegalGuildsForm.js b/src/features/province/components/province-legal-guilds-in-province/ProvinceLegalGuildsForm.js new file mode 100644 index 0000000..a2b5de2 --- /dev/null +++ b/src/features/province/components/province-legal-guilds-in-province/ProvinceLegalGuildsForm.js @@ -0,0 +1,599 @@ +import React, { + useContext, + useEffect, + useState, + useCallback, + useRef, +} from "react"; +import { useFormik } from "formik"; +import * as yup from "yup"; +import { useDispatch } from "react-redux"; +import { + Button, + TextField, + Typography, + Box, + FormControl, + Select, + MenuItem, + InputLabel, +} from "@mui/material"; +import BusinessIcon from "@mui/icons-material/Business"; +import PublicIcon from "@mui/icons-material/Public"; +import PersonIcon from "@mui/icons-material/Person"; +import BadgeIcon from "@mui/icons-material/Badge"; +import { Grid } from "../../../../components/grid/Grid"; +import { SPACING } from "../../../../data/spacing"; +import { CLOSE_MODAL, OPEN_MODAL } from "../../../../lib/redux/slices/appSlice"; +import { AppContext } from "../../../../contexts/AppContext"; +import { provinceGetLegalPersonUnitInfoService } from "../../services/province-get-legal-person-unit-info"; +import { provinceCreateLegalGuildService } from "../../services/province-create-legal-guild"; +import { provinceGetCitiesService } from "../../services/province-get-cities"; +import { provinceGetTypeActivity } from "../../services/provinceGetTypeActivity"; +import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl"; + +let preservedUserData = null; +let preservedUserFound = false; +let preservedNationalCode = ""; + +const extractCityFromAddress = (address) => { + if (!address || typeof address !== "string") { + return ""; + } + + const cityMatch = address.match(/شهرستان\s+([^\s]+(?:\s+[^\s]+)?)/); + if (cityMatch && cityMatch[1]) { + return cityMatch[1].trim(); + } + + const parts = address.split(/\s+/); + for (let i = 0; i < parts.length; i++) { + if (parts[i] === "شهرستان" && parts[i + 1]) { + const cityParts = []; + if (parts[i + 1]) cityParts.push(parts[i + 1]); + if (parts[i + 2] && !["بخش", "شهر", "استان"].includes(parts[i + 2])) { + cityParts.push(parts[i + 2]); + } + return cityParts.join(" "); + } + if (parts[i] === "شهر" && parts[i + 1]) { + return parts[i + 1]; + } + } + + return ""; +}; + +const InfoBox = ({ icon: Icon, label, value, iconSx }) => ( + + + + + {label} + + {value || "-"} + + +); + +const getValidationSchema = (isAdmin, userFound) => + yup.object({ + national_id: yup + .string() + .required("شناسه حقوقی الزامی است") + .matches(/^[0-9]{11}$/, "شناسه حقوقی باید 11 رقم باشد"), + first_name: isAdmin || !userFound ? yup.string() : yup.string(), + last_name: isAdmin || !userFound ? yup.string() : yup.string(), + unit_name: isAdmin || !userFound ? yup.string() : yup.string(), + province: isAdmin || !userFound ? yup.string() : yup.string(), + city: yup.string(), + mobile: + isAdmin || !userFound + ? yup + .string() + .nullable() + .test( + "mobile-format", + "شماره تلفن باید 11 رقم باشد", + (value) => !value || /^[0-9]{11}$/.test(value) + ) + : yup.string(), + type_activity: isAdmin || !userFound ? yup.string() : yup.string(), + }); + +const LegalGuildForm = ({ formik, isAdmin, cities, typeActivities }) => { + return ( +
    + + + + اطلاعات واحد حقوقی + + + + + + + + {isAdmin ? ( + + ) : ( + + )} + + + + {isAdmin ? ( + + ) : ( + + )} + + + + {isAdmin ? ( + + ) : ( + + )} + + + + {isAdmin ? ( + + ) : ( + + )} + + + + + + + + {isAdmin ? ( + + ) : ( + + )} + + + + + شهرستان + + + + + + + + + + {isAdmin ? ( + + + نوع فعالیت + + + + ) : ( + + )} + + + + + + + + + +
    + ); +}; + +const InquiryForm = ({ onInquiry, nationalCode, setNationalCode }) => { + return ( + + + setNationalCode(e.target.value)} + placeholder="شناسه حقوقی 11 رقمی را وارد کنید" + inputProps={{ maxLength: 11 }} + /> + + + + + + ); +}; + +export const ProvinceLegalGuildsForm = ({ onClose, updateTable, guild }) => { + const dispatch = useDispatch(); + const [openNotif] = useContext(AppContext); + const [nationalCode, setNationalCode] = useState( + guild?.user?.national_id || + guild?.national_code || + preservedNationalCode || + "" + ); + const [userData, setUserData] = useState( + guild + ? { + national_id: guild?.user?.national_id || guild?.national_code || "", + first_name: guild?.user?.first_name || "", + last_name: guild?.user?.last_name || "", + unit_name: guild?.guilds_name || "", + province: guild?.address?.province?.name || "", + city: guild?.address?.city?.name || "", + address: guild?.address?.address || "", + mobile: guild?.user?.mobile || "", + type_activity: guild?.type_activity || "", + } + : preservedUserData + ); + const [userFound, setUserFound] = useState(guild ? true : preservedUserFound); + const [cities, setCities] = useState([]); + const [typeActivities, setTypeActivities] = useState([]); + + const currentRole = getRoleFromUrl(); + const isAdmin = currentRole === "AdminX"; + + useEffect(() => { + dispatch(provinceGetCitiesService()).then((r) => { + setCities(r.payload.data || []); + }); + dispatch(provinceGetTypeActivity()).then((r) => { + setTypeActivities(r.payload.data || []); + }); + }, [dispatch]); + + // Restore preserved data on mount + useEffect(() => { + if (preservedUserData) { + setUserData(preservedUserData); + setUserFound(preservedUserFound); + setNationalCode(preservedNationalCode); + } + }, []); + + // Update modal size when userData is available (only once) + const sizeUpdatedRef = useRef(false); + useEffect(() => { + if (userData && !sizeUpdatedRef.current) { + sizeUpdatedRef.current = true; + // Preserve state before remount + preservedUserData = userData; + preservedUserFound = userFound; + preservedNationalCode = nationalCode; + // Update modal with larger size + dispatch( + OPEN_MODAL({ + title: "ثبت واحد حقوقی", + content: ( + + ), + size: { xs: "96vw", md: "90vw", lg: "600px" }, + }) + ); + } + }, [userData, dispatch, onClose, updateTable, userFound, nationalCode]); + + const handleInquiry = useCallback(() => { + if (!nationalCode || nationalCode.length !== 11) { + openNotif({ + vertical: "top", + horizontal: "center", + msg: "لطفا شناسه حقوقی 11 رقمی معتبر وارد کنید", + severity: "error", + }); + return; + } + + dispatch(provinceGetLegalPersonUnitInfoService(nationalCode)).then((r) => { + if (r.payload.error) { + setUserFound(false); + if (isAdmin) { + // Admin can create even if user not found + setUserData({ + is_real_person: false, + first_name: "", + last_name: "", + national_id: nationalCode, + province: "", + unit_name: "", + mobile: "", + type_activity: "", + }); + } else { + openNotif({ + vertical: "top", + horizontal: "center", + msg: r.payload.error, + severity: "error", + }); + } + } else if (r.payload.data) { + setUserFound(true); + const extractedCity = extractCityFromAddress( + r.payload.data.address || "" + ); + setUserData({ + ...r.payload.data, + city: extractedCity, + }); + openNotif({ + vertical: "top", + horizontal: "center", + msg: "اطلاعات با موفقیت دریافت شد", + severity: "success", + }); + } + }); + }, [dispatch, nationalCode, openNotif, isAdmin]); + + const formik = useFormik({ + initialValues: { + national_id: userData?.national_id || userData?.nationalId || "", + first_name: userData?.first_name || userData?.firstName || "", + last_name: userData?.last_name || userData?.lastName || "", + unit_name: userData?.unit_name || userData?.unitName || "", + province: userData?.province || "", + city: userData?.city || "", + address: userData?.address || "", + mobile: userData?.mobile || "", + type_activity: userData?.type_activity || "", + }, + validationSchema: getValidationSchema(isAdmin, userFound), + enableReinitialize: true, + onSubmit: (values) => { + // Find type_activity key from the title + const typeActivityObj = typeActivities.find( + (activity) => activity.title === values.type_activity + ); + const typeActivityKey = typeActivityObj?.key || ""; + + const submitData = { + first_name: values.first_name, + last_name: values.last_name, + national_id: values.national_id, + province: values.province, + address: values.address || "", + unit_name: values.unit_name, + mobile: values.mobile || "", + city: values.city, + type_activity: typeActivityKey, // Send key instead of title + ...(guild?.key && { guilds_key: guild.key }), // Include guild key for editing + }; + + dispatch(provinceCreateLegalGuildService(submitData)).then((r) => { + if (r.payload.error) { + openNotif({ + vertical: "top", + horizontal: "center", + msg: r.payload.error, + severity: "error", + }); + } else { + openNotif({ + vertical: "top", + horizontal: "center", + msg: "عملیات با موفقیت انجام شد.", + severity: "success", + }); + if (updateTable) { + updateTable(); + } + dispatch(CLOSE_MODAL()); + } + }); + }, + }); + + if (!userData && !guild) { + return ( + + ); + } + + return ( + + ); +}; diff --git a/src/features/province/components/province-legal-guilds-in-province/ProvinceLegalGuildsInProvince.js b/src/features/province/components/province-legal-guilds-in-province/ProvinceLegalGuildsInProvince.js new file mode 100644 index 0000000..13ec9aa --- /dev/null +++ b/src/features/province/components/province-legal-guilds-in-province/ProvinceLegalGuildsInProvince.js @@ -0,0 +1,237 @@ +import React, { useEffect, useState } from "react"; +import { useDispatch } from "react-redux"; +import { Button, TextField } from "@mui/material"; +import { DatePicker } from "@mui/x-date-pickers"; +import moment from "moment"; +import { Grid } from "../../../../components/grid/Grid"; +import { SPACING } from "../../../../data/spacing"; +import { CLOSE_MODAL, OPEN_MODAL } from "../../../../lib/redux/slices/appSlice"; +import { provinceGetTotalGuildsService } from "../../services/province-get-total-guilds"; +import { ProvinceLegalGuildsForm } from "./ProvinceLegalGuildsForm"; +import { ProvinceLegalGuildsOperations } from "./ProvinceLegalGuildsOperations"; +import ResponsiveTable from "../../../../components/responsive-table/ResponsiveTable"; +import { RiSearchLine } from "react-icons/ri"; + +export const ProvinceLegalGuildsInProvince = () => { + const dispatch = useDispatch(); + const [data, setData] = useState([]); + const [totalRows, setTotalRows] = useState(0); + const [perPage, setPerPage] = useState(10); + const [textValue, setTextValue] = useState(""); + const [page, setPage] = useState(1); + const [tableData, setTableData] = useState([]); + const [selectedDate1, setSelectedDate1] = useState(null); + const [selectedDate2, setSelectedDate2] = useState(null); + + const handleTextChange = (e) => setTextValue(e.target.value); + + const fetchApiData = async (pageNum) => { + const response = await dispatch( + provinceGetTotalGuildsService({ + search: "filter", + value: textValue, + page: pageNum, + page_size: perPage, + steward: false, + active_state: "all", + is_real_person: false, + ...(selectedDate1 && { + date_from: moment(selectedDate1).format("YYYY-MM-DD"), + }), + ...(selectedDate2 && { + date_to: moment(selectedDate2).format("YYYY-MM-DD"), + }), + }) + ); + + if (response.payload.error) { + console.error("Error fetching data:", response.payload.error); + setData([]); + setTotalRows(0); + } else { + setData(response.payload.data?.results || []); + const count = Number(response.payload.data?.count) || 0; + setTotalRows(count); + } + }; + + const handlePageChange = (pageNum) => { + fetchApiData(pageNum); + setPage(pageNum); + }; + + const handlePerRowsChange = (perRows) => { + setPerPage(Number(perRows)); + setPage(1); + }; + + const updateTableData = () => { + fetchApiData(page !== 0 ? page : 1); + }; + + useEffect(() => { + if (!data || !Array.isArray(data)) { + setTableData([]); + return; + } + const d = data.map((item, i) => { + return [ + page === 1 ? i + 1 : i + perPage * (page - 1) + 1, + item?.nationalId || "-", + item?.guildsName || "-", + `${item?.user?.fullname || "-"}`, + item?.user?.mobile || "-", + item?.address?.province?.name || "-", + item?.address?.city?.name || "-", + item?.typeActivity || "-", + item?.active ? "فعال" : "غیر فعال", + , + ]; + }); + setTableData(d); + }, [data, page, perPage]); + + useEffect(() => { + fetchApiData(1); + setPage(1); + }, [perPage]); + + useEffect(() => { + fetchApiData(1); + }, []); + + const handleSubmit = async (e) => { + e.preventDefault(); + setPage(1); + const response = await dispatch( + provinceGetTotalGuildsService({ + search: "filter", + value: textValue, + page: 1, + page_size: perPage, + steward: false, + active_state: "all", + is_real_person: false, + ...(selectedDate1 && { + date_from: moment(selectedDate1).format("YYYY-MM-DD"), + }), + ...(selectedDate2 && { + date_to: moment(selectedDate2).format("YYYY-MM-DD"), + }), + }) + ); + + if (response.payload.error) { + console.error("Error fetching data:", response.payload.error); + setData([]); + setTotalRows(0); + } else { + setData(response.payload.data?.results || []); + const count = Number(response.payload.data?.count) || 0; + setTotalRows(count); + } + }; + + const handleOpenModal = () => { + dispatch( + OPEN_MODAL({ + title: "ثبت واحد حقوقی", + content: ( + dispatch(CLOSE_MODAL())} + updateTable={updateTableData} + /> + ), + size: 400, + }) + ); + }; + + return ( + + + + +
    + + + + { + setSelectedDate1(newValue); + }} + renderInput={(params) => ( + + )} + /> + + { + setSelectedDate2(newValue); + }} + renderInput={(params) => ( + + )} + /> + + + +
    +
    + + + + +
    + ); +}; diff --git a/src/features/province/components/province-legal-guilds-in-province/ProvinceLegalGuildsOperations.js b/src/features/province/components/province-legal-guilds-in-province/ProvinceLegalGuildsOperations.js new file mode 100644 index 0000000..92a8d41 --- /dev/null +++ b/src/features/province/components/province-legal-guilds-in-province/ProvinceLegalGuildsOperations.js @@ -0,0 +1,161 @@ +import { + Button, + FormControlLabel, + IconButton, + Popover, + Switch, + Tooltip, + Typography, + Box, +} from "@mui/material"; +import EditIcon from "@mui/icons-material/Edit"; +import DeleteIcon from "@mui/icons-material/Delete"; +import { useState } from "react"; +import { useDispatch } from "react-redux"; +import { Grid } from "../../../../components/grid/Grid"; +import { OPEN_MODAL, CLOSE_MODAL } from "../../../../lib/redux/slices/appSlice"; +import { ProvinceLegalGuildsForm } from "./ProvinceLegalGuildsForm"; +import TuneIcon from "@mui/icons-material/Tune"; + +export const ProvinceLegalGuildsOperations = ({ guild, updateTable }) => { + const dispatch = useDispatch(); + const [checked, setChecked] = useState(guild?.active); + const [popoverOpen, setPopoverOpen] = useState(false); + const [anchorEl, setAnchorEl] = useState(null); + + const openPopover = (event) => { + setPopoverOpen(true); + setAnchorEl(event.currentTarget); + }; + + const closePopover = () => { + setPopoverOpen(false); + setAnchorEl(null); + }; + + const handleActivationChange = (event) => { + const newChecked = event.target.checked; + setChecked(newChecked); + }; + + const handleDelete = () => { + closePopover(); + dispatch( + OPEN_MODAL({ + title: "تایید حذف", + size: "auto", + content: ( + + + آیا از حذف این واحد حقوقی اطمینان دارید؟ + + + + + + + ), + }) + ); + }; + + const handleEdit = () => { + closePopover(); + dispatch( + OPEN_MODAL({ + title: "ویرایش واحد حقوقی", + content: ( + dispatch(CLOSE_MODAL())} + updateTable={updateTable} + /> + ), + size: window.innerWidth <= 600 ? "small" : "auto", + }) + ); + }; + + return ( + + + + + + + + +
    + + + } + label={checked ? "فعال" : "غیرفعال"} + style={{ + justifyContent: "center", + alignItems: "center", + display: "flex", + }} + /> + + + +
    +
    +
    + ); +}; diff --git a/src/features/province/components/province-legal-guilds-out-province/ProvinceLegalGuildsOutProvince.js b/src/features/province/components/province-legal-guilds-out-province/ProvinceLegalGuildsOutProvince.js new file mode 100644 index 0000000..3962807 --- /dev/null +++ b/src/features/province/components/province-legal-guilds-out-province/ProvinceLegalGuildsOutProvince.js @@ -0,0 +1,145 @@ +import React, { useEffect, useState } from "react"; +import { Button, TextField } from "@mui/material"; +import ResponsiveTable from "../../../../components/responsive-table/ResponsiveTable"; +import { + LOADING_END, + LOADING_START, +} from "../../../../lib/redux/slices/appSlice"; +import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl"; +import { Grid } from "../../../../components/grid/Grid"; +import { useDispatch } from "react-redux"; +import { RiSearchLine } from "react-icons/ri"; +import { fetchOutProvinceLegalBuyers } from "../../services/province-out-province-buyers"; + +export const ProvinceLegalGuildsOutProvince = () => { + const handleTextChange = (event) => { + setTextValue(event.target.value); + }; + + const dispatch = useDispatch(); + + const [data, setData] = useState([]); + const [totalRows, setTotalRows] = useState(0); + const [perPage, setPerPage] = useState(10); + const [textValue, setTextValue] = useState(""); + const [page, setPage] = useState(1); + const [tableData, setTableData] = useState([]); + + const fetchApiData = async (page) => { + dispatch(LOADING_START()); + try { + const response = await fetchOutProvinceLegalBuyers({ + role: getRoleFromUrl(), + page: page, + pageSize: perPage, + searchValue: textValue, + }); + setData(response.data.results); + setTotalRows(response.data.count); + } catch (error) { + console.error("Error fetching data:", error); + } finally { + dispatch(LOADING_END()); + } + }; + + const handlePageChange = (page) => { + fetchApiData(page); + setPage(page); + }; + + const handlePerRowsChange = (perRows) => { + setPerPage(perRows); + setPage(1); + }; + + useEffect(() => { + const d = data?.map((item, i) => { + const killHouseName = item?.KillHouse?.name || "-"; + const killHouseOperator = + item?.KillHouse?.killHouseOperator?.user?.fullname || ""; + const killHouseInfo = killHouseOperator + ? `${killHouseName} (${killHouseOperator})` + : killHouseName; + + console.log(item); + return [ + page === 1 ? i + 1 : i + perPage * (page - 1) + 1, + item?.unitName || "-", + item?.buyer?.parentLegalPersonNationalCode || "-", + killHouseInfo, + item?.province || "-", + item?.city || "-", + item?.requestsInfo?.numberOfRequests?.toLocaleString() || "0", + item?.requestsInfo?.totalQuantity?.toLocaleString() || "0", + item?.requestsInfo?.totalWeight?.toLocaleString() || "0", + ]; + }); + + setTableData(d); + }, [data, page, perPage]); + + useEffect(() => { + fetchApiData(1); + }, [dispatch, perPage]); + + const handleSubmit = async (event) => { + event.preventDefault(); + fetchApiData(1); + setPage(1); + }; + + return ( + + + +
    + + + +
    +
    + + +
    + ); +}; diff --git a/src/features/province/components/province-manage-buy-req-allow-operation/ProvinceManageBuyReqAllowOperation.js b/src/features/province/components/province-manage-buy-req-allow-operation/ProvinceManageBuyReqAllowOperation.js new file mode 100644 index 0000000..bf6f52a --- /dev/null +++ b/src/features/province/components/province-manage-buy-req-allow-operation/ProvinceManageBuyReqAllowOperation.js @@ -0,0 +1,64 @@ +import { Switch } from "@mui/material"; +import { useState } from "react"; +import { useDispatch } from "react-redux"; +import { Grid } from "../../../../components/grid/Grid"; +import { SPACING } from "../../../../data/spacing"; +import { manageProcessBuyReqService } from "../../services/manage-process-buy-req"; +import { manageProcessBuyReqOperationService } from "../../services/manage-process-buy-req-operation"; + +export const ProvinceManageBuyReqAllowOperation = ({ + item, + getLimitInformation, + isDebt, +}) => { + const dispatch = useDispatch(); + const [isChecked, setIsChecked] = useState( + isDebt + ? item.allowPurchaseRequest.totalLimitation + : item.allowPurchaseRequest.allow + ); + + const handleSwitchChange = () => { + if (isDebt) { + setIsChecked(!isChecked); + dispatch( + manageProcessBuyReqOperationService({ + kill_house_key: item.key, + total_limitation: !isChecked, + }) + ).then((r) => { + dispatch(manageProcessBuyReqService()); + getLimitInformation(); + }); + } else { + setIsChecked(!isChecked); + dispatch( + manageProcessBuyReqOperationService({ + kill_house_key: item.key, + allow: !isChecked, + }) + ).then((r) => { + dispatch(manageProcessBuyReqService()); + getLimitInformation(); + }); + } + }; + + return ( + + + + {/* {!isDebt && {isChecked ? "دارد" : "ندارد"}} */} + + + ); +}; diff --git a/src/features/province/components/province-manage-buy-req-limit-operation/ProvinceManageBuyReqLimitOperation.js b/src/features/province/components/province-manage-buy-req-limit-operation/ProvinceManageBuyReqLimitOperation.js new file mode 100644 index 0000000..0b905b4 --- /dev/null +++ b/src/features/province/components/province-manage-buy-req-limit-operation/ProvinceManageBuyReqLimitOperation.js @@ -0,0 +1,109 @@ +import { Button, Switch, TextField, Typography } from "@mui/material"; +import { useState, useEffect } from "react"; +import { useDispatch } from "react-redux"; +import { Grid } from "../../../../components/grid/Grid"; +import { SPACING } from "../../../../data/spacing"; +import { manageProcessBuyReqService } from "../../services/manage-process-buy-req"; +import { manageProcessBuyReqOperationService } from "../../services/manage-process-buy-req-operation"; +import DoneIcon from "@mui/icons-material/Done"; + +export const ProvinceManageBuyReqLimitOperation = ({ + item, + getLimitInformation, + fetchdata, +}) => { + const dispatch = useDispatch(); + + const [isChecked, setIsChecked] = useState( + item.allowPurchaseRequest.limitation + ); + const [textValue, setTextValue] = useState( + item?.allowPurchaseRequest?.limitationNumber + ); + + useEffect(() => { + setIsChecked(item.allowPurchaseRequest.limitation); + setTextValue(item.allowPurchaseRequest.limitationNumber); + }, [item]); + + const isValidValue = Number(textValue) > 0; + + const handleTextChange = (event) => { + setTextValue(event.target.value); + }; + + const handleSwitchChange = () => { + const newChecked = !isChecked; + setIsChecked(newChecked); + + dispatch( + manageProcessBuyReqOperationService({ + kill_house_key: item.key, + limitation: newChecked, + }) + ); + dispatch(manageProcessBuyReqService()); + getLimitInformation(); + fetchdata(); + }; + + const handleSubmit = () => { + dispatch( + manageProcessBuyReqOperationService({ + kill_house_key: item.key, + limitation: isChecked, + limitation_number: Number(textValue), + }) + ); + dispatch(manageProcessBuyReqService()); + getLimitInformation(); + fetchdata(); + }; + + return ( + + + + + + + محدودیت بر اساس بدهی + + + + {isChecked && ( + + + + + + + + + )} + + ); +}; diff --git a/src/features/province/components/province-manage-buy-req/ProvinceManageBuyReq.js b/src/features/province/components/province-manage-buy-req/ProvinceManageBuyReq.js new file mode 100644 index 0000000..2cd6741 --- /dev/null +++ b/src/features/province/components/province-manage-buy-req/ProvinceManageBuyReq.js @@ -0,0 +1,180 @@ +import { useEffect, useState } from "react"; +import { useDispatch } from "react-redux"; +import { Grid } from "../../../../components/grid/Grid"; +import { manageProcessBuyReqService } from "../../services/manage-process-buy-req"; +import ResponsiveTable from "../../../../components/responsive-table/ResponsiveTable"; +import { IconButton, Tooltip, Typography } from "@mui/material"; +import TuneIcon from "@mui/icons-material/Tune"; +import { ProvinceManageOperationModalBuyReq } from "../province-manage-operation-modal-buy-req/ProvinceManageOperationModalBuyReq"; +import { DRAWER, OPEN_MODAL } from "../../../../lib/redux/slices/appSlice"; +import { PaymentLinkModal } from "../province-manage-payment-link-modal/PaymentLinkModal"; +import AttachmentIcon from "@mui/icons-material/Attachment"; + +export const ProvinceManageBuyReq = () => { + const dispatch = useDispatch(); + const [tableData, setDataTable] = useState([]); + const [data, setData] = useState([]); + // const [anchorEl, setAnchorEl] = useState(null); + + const fetchdata = () => { + dispatch(manageProcessBuyReqService()).then((r) => { + setData(r.payload.data); + }); + }; + + useEffect(() => { + fetchdata(); + }, []); + + // const handleClose = () => { + // setAnchorEl(null); + // }; + useEffect(() => { + const d = data?.map((item, i) => { + const identity = item.killer + ? `کشتارکن ${item?.type === "public" ? "عمومی" : "اختصاصی"} (${ + item?.killHouseForKiller?.killHouseName + })` + : "کشتارگاه"; + return [ + i + 1, + identity, + item.name, + `${item?.killHouseOperator?.user?.fullname} (${item?.killHouseOperator?.user?.mobile})`, + `${item?.systemAddress?.province?.name || ""} - ${ + item?.systemAddress?.city?.name || "" + } - ${item?.systemAddress?.address || ""}`, + item?.wageInfo?.totalAmount?.toLocaleString(), + + { + dispatch( + OPEN_MODAL({ + title: "لینک پرداخت بدهی", + content: , + }) + ); + }} + > + + + , + item?.allowPurchaseRequest?.limitation ? "فعال" : "غیر فعال", + <> + + {item?.maxKillLimit ? item.totalKillCapacity : "-"} + + , + <> + + {item?.maxKillLimit ? `%${item.extraBarKillPercent}` : "-"} + {" "} + , + <> + + {item?.inProvinceSellingLimitationPercent + ? `%${item.inProvinceSellingLimitationPercent}` + : "-"} + {" "} + , + <> + + {item?.outProvinceSellingLimitationPercent + ? `%${item.outProvinceSellingLimitationPercent}` + : "-"} + + , + item?.quota ? "دارد" : "ندارد", + item?.quota + ? item?.quotaMaxKillLimit + ? "بر اساس سقف کشتار" + : item?.quotaRequest + ? "بر اساس اعلام نیازها" + : "بر اساس حجم از سقف کشتار" + : "-", + item?.governmentalQuota ? item?.governmentalQuota : "-", + item?.quotaCustomQuantity ? item?.quotaCustomQuantity : "-", + item?.maximumLoadVolumeIncrease || 0, + item?.maximumLoadVolumeReduction || 0, + item?.wareHouseRemaininggWeightLimitationStatus ? "فعال" : "غیر فعال", + item?.wareHouseRemainingWeightLimitation + ? `${item?.wareHouseRemainingWeightLimitation} کیلوگرم` + : "-", + item?.wareHouseRemainingPercentLimitationStatus ? "فعال" : "غیر فعال", + item?.wareHouseRemainingPercentLimitation + ? `%${item?.wareHouseRemainingPercentLimitation}` + : "-", + item?.wareHouseRemainingWeightArchivePercent + ? `%${item?.wareHouseRemainingWeightArchivePercent}` + : "-", + + { + // handleClose(); + dispatch( + DRAWER({ + right: !(window.innerWidth <= 700), + bottom: window.innerWidth <= 700, + title: "محدودیت پنل", + content: ( + + ), + }) + ); + }} + > + + + , + ]; + }); + setDataTable(d); + }, [data]); + + return ( + + + + ); +}; diff --git a/src/features/province/components/province-manage-carcass-standard-loss-percent/ProvinceManageCarcassStandardLossPercent.js b/src/features/province/components/province-manage-carcass-standard-loss-percent/ProvinceManageCarcassStandardLossPercent.js new file mode 100644 index 0000000..c2a8ff8 --- /dev/null +++ b/src/features/province/components/province-manage-carcass-standard-loss-percent/ProvinceManageCarcassStandardLossPercent.js @@ -0,0 +1,124 @@ +import { Button, Switch, TextField, FormControlLabel } from "@mui/material"; +import { useState, useEffect, useContext } from "react"; +import { useDispatch } from "react-redux"; +import { Grid } from "../../../../components/grid/Grid"; +import { SPACING } from "../../../../data/spacing"; +import { AppContext } from "../../../../contexts/AppContext"; +import { provinceUpdateKillhouseArchivePercentService } from "../../services/province-update-killhouse-archive-percent"; + +export const ProvinceManageCarcassStandardLossPercent = ({ + item, + fetchdata, +}) => { + const [openNotif] = useContext(AppContext); + const dispatch = useDispatch(); + + const [isChecked, setIsChecked] = useState( + item?.wareHouseRemainingWeightArchivePercent !== undefined && + item?.wareHouseRemainingWeightArchivePercent !== null && + item?.wareHouseRemainingWeightArchivePercent > 0 + ); + const [percentValue, setPercentValue] = useState( + item?.wareHouseRemainingWeightArchivePercent || 0 + ); + + useEffect(() => { + const hasValue = + item?.wareHouseRemainingWeightArchivePercent !== undefined && + item?.wareHouseRemainingWeightArchivePercent !== null && + item?.wareHouseRemainingWeightArchivePercent > 0; + setIsChecked(hasValue); + setPercentValue(item?.wareHouseRemainingWeightArchivePercent || 0); + }, [item]); + + const isValidValue = Number(percentValue) >= 0 && Number(percentValue) <= 100; + + const handleTextChange = (event) => { + setPercentValue(event.target.value); + }; + + const handleSwitchChange = () => { + const newChecked = !isChecked; + setIsChecked(newChecked); + if (!newChecked) { + setPercentValue(0); + } + }; + + const handleSubmit = () => { + dispatch( + provinceUpdateKillhouseArchivePercentService({ + kill_house_key: item.key, + ware_house_remaining_weight_archive_percent: isChecked + ? Number(percentValue) + : 0, + }) + ).then((r) => { + if (r.payload.error) { + openNotif({ + vertical: "top", + horizontal: "center", + msg: r.payload.error, + severity: "error", + }); + } else { + fetchdata(); + openNotif({ + vertical: "top", + horizontal: "center", + msg: "عملیات با موفقیت انجام شد.", + severity: "success", + }); + } + }); + }; + + return ( + + + + + } + label="حداکثر افت استاندارد لاشه" + /> + + + + {isChecked && ( + + + + + + )} + + + + + + ); +}; diff --git a/src/features/province/components/province-manage-cars/ProvinceManageCars.js b/src/features/province/components/province-manage-cars/ProvinceManageCars.js new file mode 100644 index 0000000..0b87d73 --- /dev/null +++ b/src/features/province/components/province-manage-cars/ProvinceManageCars.js @@ -0,0 +1,387 @@ +import { + Button, + Card, + IconButton, + List, + ListItemButton, + ListItemIcon, + ListItemText, + Popover, + Tooltip, +} from "@mui/material"; +import { useContext, useEffect, useState } from "react"; +import { useDispatch, useSelector } from "react-redux"; +// import { slaughterGetCars } from "../../services/slaughter-get-cars"; +// import { slaughterDeleteCar } from "../../services/slaughter-delete-car"; +import { Grid } from "../../../../components/grid/Grid"; +import { SPACING } from "../../../../data/spacing"; +// import { SlaughterNewCar } from "../slaughter-new-car/SlaughterNewCar"; +// import { ProvinceRegisterCar } from "../province-register-car/ProvinceRegisterCar"; +import { provinceGetCars } from "../../services/province-get-cars"; +import { + DRAWER, + LOADING_END, + LOADING_START, +} from "../../../../lib/redux/slices/appSlice"; +import { ProvinceRegisterCarForm } from "../province-register-car-form/ProvinceRegisterCarForm"; +import { provinceRemoveCar } from "../../services/province-remove-car"; +import { AppContext } from "../../../../contexts/AppContext"; +import { ProvinceAllocateCarsForm } from "../province-allocate-cars-form/ProvinceAllocateCarsForm"; +import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl"; +import { ManageCarState } from "../manage-car-state/ManageCarState"; +import axios from "axios"; +import { RiFileExcel2Fill } from "react-icons/ri"; +import TuneIcon from "@mui/icons-material/Tune"; +import LocalShippingIcon from "@mui/icons-material/LocalShipping"; +import EditOutlinedIcon from "@mui/icons-material/EditOutlined"; +import DeleteOutlineIcon from "@mui/icons-material/DeleteOutline"; +import ResponsiveTable from "../../../../components/responsive-table/ResponsiveTable"; +import { provinceCarsDashboardService } from "../../services/province-cars-dashboard"; +import { checkPathStartsWith } from "../../../../utils/checkPathStartsWith"; + +export const ProvinceManageCars = () => { + const dispatch = useDispatch(); + const [dataTable, setDataTable] = useState([]); + const [openNotif] = useContext(AppContext); + const { provinceCars } = useSelector((state) => state.provinceSlice); + // const userInfo = useSelector((state) => state.userSlice); + const userKey = useSelector((state) => state.userSlice.userProfile.key); + const selectedSubUser = useSelector( + (state) => state.userSlice.selectedSubUser + ); + useEffect(() => { + dispatch( + provinceGetCars({ + role_key: checkPathStartsWith("province") + ? selectedSubUser?.key || "" + : "", + }) + ); + }, [selectedSubUser?.key]); + + const [dashboardData, setDashboardData] = useState([]); + + useEffect(() => { + dispatch( + provinceCarsDashboardService({ + role_key: checkPathStartsWith("province") + ? selectedSubUser?.key || "" + : "", + }) + ).then((r) => { + setDashboardData(r.payload.data); + }); + }, [dispatch, provinceCars, selectedSubUser?.key]); + + useEffect(() => { + const d = provinceCars?.map((item, i) => { + let carIdentity = "-"; + if (item.type === "rental") { + carIdentity = "اجاره ای"; + } else if (item.type === "exclusive") { + carIdentity = "اختصاصی"; + } + + // const handleDisable = + // getRoleFromUrl() === "ProvinceOperator" || + // getRoleFromUrl() === "SuperAdmin" || + // getRoleFromUrl() === "AdminX" + // ? false + // : true; + + const killhouseList = + item.type === "rental" + ? "همه کشتارگاه ها/کشتارکن ها" + : item?.killHouseList?.map((killHouse, index) => { + const separator = + index + 1 === item.killHouseList.length ? "" : " - "; + return killHouse?.killHouseName + separator; + }); + + return [ + i + 1, + item.typeCar, + carIdentity, + item.pelak, + item.capocity, + parseInt(item.healthCode), + // Number(item.healthCode), + item.driverName, + item.driverMobile, + killhouseList, + , + , + ]; + }); + + setDataTable(d); + }, [provinceCars, dispatch, openNotif]); + + const [tableDataCol] = useState([ + "ردیف", + "مدل خودرو", + "ماهیت", + "پلاک", + "ظرفیت", + "کد بهداشتی", + "نام راننده", + "موبایل راننده", + "کشتارگاه ها/کشتارکن ها", + "وضعیت", + "عملیات", + ]); + return ( + <> + + + + + + + + + + + + + + + + + ); +}; + +const CarActions = ({ item, openNotif }) => { + const dispatch = useDispatch(); + const [anchorEl, setAnchorEl] = useState(null); + + const handleDisable = !( + getRoleFromUrl() === "ProvinceOperator" || + getRoleFromUrl() === "SuperAdmin" || + getRoleFromUrl() === "AdminX" + ); + + const hasForbiddenKillhouse = item.killHouseList?.some( + (killItem) => !killItem.allowState + ); + + const hasAccess = !handleDisable || !hasForbiddenKillhouse; + const isRental = item.type === "rental"; + + const open = Boolean(anchorEl); + const id = open ? `province-cars-popover-${item.key}` : undefined; + + const closePopover = () => setAnchorEl(null); + + const handleAllocate = () => { + closePopover(); + dispatch( + DRAWER({ + right: !(window.innerWidth <= 600), + bottom: window.innerWidth <= 600, + title: "تخصیص/حذف کشتارگاه", + content: ( + + ), + }) + ); + }; + + const handleEdit = () => { + closePopover(); + dispatch( + DRAWER({ + right: !(window.innerWidth <= 600), + bottom: window.innerWidth <= 600, + title: "ویرایش خودرو", + content: ( + + ), + }) + ); + }; + + const handleDelete = () => { + closePopover(); + dispatch(LOADING_START()); + dispatch(provinceRemoveCar(item.key)).then((r) => { + if (r.error) { + if (r.error.message.includes("403")) { + openNotif({ + vertical: "top", + horizontal: "center", + msg: "امکان حذف بدلیل تخصیص بار فعال به خودرو وجود ندارد!", + severity: "error", + }); + } else { + openNotif({ + vertical: "top", + horizontal: "center", + msg: "مشکلی پیش آمده است!", + severity: "error", + }); + } + } else { + dispatch(DRAWER({ right: false, bottom: false, content: null })); + dispatch(provinceGetCars()); + openNotif({ + vertical: "top", + horizontal: "center", + msg: "عملیات با موفقیت انجام شد.", + severity: "success", + }); + } + dispatch(LOADING_END()); + }); + }; + + const actionsDisabled = !hasAccess || (handleDisable && isRental); + + return ( +
    + setAnchorEl(event.currentTarget)} + disabled={!hasAccess} + > + + + + + + + + + + + + + + + + + + + + + + + + +
    + ); +}; diff --git a/src/features/province/components/province-manage-contradictions/ProvinceManageContradictions.js b/src/features/province/components/province-manage-contradictions/ProvinceManageContradictions.js new file mode 100644 index 0000000..7425716 --- /dev/null +++ b/src/features/province/components/province-manage-contradictions/ProvinceManageContradictions.js @@ -0,0 +1,259 @@ +import moment from "moment"; +import React, { useEffect, useState, useContext, useRef } from "react"; +import { useDispatch, useSelector } from "react-redux"; +import { useReactToPrint } from "react-to-print"; +import { Grid } from "../../../../components/grid/Grid"; +import { SPACING } from "../../../../data/spacing"; +import { + Button, + IconButton, + TextField, + Tooltip, + Typography, +} from "@mui/material"; +import { DatePicker } from "@mui/x-date-pickers"; +import axios from "axios"; +import { RiFileExcel2Fill, RiSearchLine } from "react-icons/ri"; +import { AppContext } from "../../../../contexts/AppContext"; +import { BsFillFileEarmarkPdfFill } from "react-icons/bs"; +import { + LOADING_END, + LOADING_START, +} from "../../../../lib/redux/slices/appSlice"; +import { provinceGetContradictionsData } from "../../services/provinceGetContradictionsData"; + +import { Accordion, AccordionDetails, AccordionSummary } from "@mui/material"; +import ExpandMoreIcon from "@mui/icons-material/ExpandMore"; +import ProvinceGetContradictionsFile from "../province-get-contradictions-file/ProvinceGetContradictionsFile"; +import { + TablePage1Part2Web, + TablePage1Web, + TablePage2Web, + TablePage3Web, + TablePage4Web, + TablePage5Web, +} from "../province-get-contradictions-file/PagesWeb"; +import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl"; + +export const ProvinceManageContradictions = () => { + const [, , selectedDate1, setSelectedDate1, selectedDate2, setSelectedDate2] = + useContext(AppContext); + const [data, setData] = useState(); + const [dataTable, setDataTable] = useState(); + + const dispatch = useDispatch(); + + const componentRef = useRef(); + const printPDF = useReactToPrint({ + content: () => componentRef.current, + documentTitle: `گزارش مغایرت درخواست کشتار و عدم فعالیت نقش ها `, + }); + + const handleSubmit = () => { + dispatch(LOADING_START()); + dispatch( + provinceGetContradictionsData({ selectedDate1, selectedDate2 }) + ).then((r) => { + setDataTable(r.payload.data); + dispatch(LOADING_END()); + }); + }; + const userInfo = useSelector((state) => state.userSlice); + + const setPdfOptions = () => { + dispatch(LOADING_START()); + dispatch( + provinceGetContradictionsData({ selectedDate1, selectedDate2 }) + ).then((r) => { + setData(r.payload.data); + dispatch(LOADING_END()); + }); + }; + + useEffect(() => { + const fetchData = () => { + const currentDate = moment(new Date()).format("YYYY-MM-DD"); + const newSelectedDate1 = moment(currentDate) + .subtract(1, "days") + .format("YYYY-MM-DD"); + const newSelectedDate2 = currentDate; + + setSelectedDate1(newSelectedDate1); + setSelectedDate2(newSelectedDate2); + + dispatch(LOADING_START()); + try { + const response = dispatch( + provinceGetContradictionsData({ + selectedDate1: newSelectedDate1, + selectedDate2: newSelectedDate2, + }) + ); + setDataTable(response.payload.data); + } catch (error) { + dispatch(LOADING_END()); + } + }; + + fetchData(); + }, []); + + useEffect(() => { + if (data) { + printPDF(); + } + }, [data]); + + return ( + + +
    + +
    + + دریافت لیست مغایرت ها (حداکثر بازه 7 روزه) + + + } + value={selectedDate1} + onChange={(e) => { + setSelectedDate1(moment(e).format("YYYY-MM-DD")); + }} + /> + + + ( + + )} + value={selectedDate2} + onChange={(e) => { + setSelectedDate2(moment(e).format("YYYY-MM-DD")); + }} + /> + + + + 7 + } + aria-label="delete" + color="success" + onClick={() => { + setPdfOptions(selectedDate1); + }} + > + + + + + + + + +
    + {dataTable && ( + + {dataTable && ( + + {renderAccordion( + "درخواست کشتار و تخصیص", + + )} + {renderAccordion( + "مغایرت در ثبت ماشین و ایجاد بار", + + )} + {renderAccordion( + "بارهای دارای مغایرت تعداد", + + )} + {renderAccordion( + "بارهای فاقد کد قرنطینه", + + )} + {renderAccordion( + "بارهای تخلیه نشده", + + )} + {renderAccordion( + "بارهاي تکمیل نشده (بارگزاري سند باسکول و مستندات وزنی)", + + )} + {renderAccordion( + "مغایرت در اطلاعات بار", + + )} + + )} + + )} +
    + ); +}; + +const renderAccordion = (label, content) => ( + + } + aria-controls="panel-content" + id="panel-header" + > + {label} + + {content} + +); diff --git a/src/features/province/components/province-manage-distributions-submit-commitment-percentet/ProvinceManageDistributionsSubmitCommitmentPercent.js b/src/features/province/components/province-manage-distributions-submit-commitment-percentet/ProvinceManageDistributionsSubmitCommitmentPercent.js new file mode 100644 index 0000000..3ac442b --- /dev/null +++ b/src/features/province/components/province-manage-distributions-submit-commitment-percentet/ProvinceManageDistributionsSubmitCommitmentPercent.js @@ -0,0 +1,138 @@ +import React, { useContext, useState } from "react"; +import { Grid } from "../../../../components/grid/Grid"; +import { IconButton, TextField, Typography, Box } from "@mui/material"; +import CheckIcon from "@mui/icons-material/Check"; +import EditIcon from "@mui/icons-material/Edit"; +import { useFormik } from "formik"; +import * as yup from "yup"; +import { AppContext } from "../../../../contexts/AppContext"; +import { useDispatch } from "react-redux"; +import { provinceManageTradesEditPercents } from "../../services/province-manage-trades-edit-percents"; +import { + provinceManageGuildTradesEditAllPercents, + provinceManageGuildTradesEditPercents, +} from "../../services/province-manage-guilds-trades-edit-percents"; + +const validationSchema = yup.object({ + commitmentPercent: yup + .number() + .min(0, "درصد نمی‌تواند کمتر از ۰ باشد") + .max(100, "درصد نمی‌تواند بیشتر از ۱۰۰ باشد") + .required("درصد تعهد الزامی است") + .integer("درصد باید عدد صحیح باشد"), +}); + +export const ProvinceManageDistributionsSubmitCommitmentPercent = ({ + amount, + updateTable, + item, + isGuild, + isDashboard, +}) => { + const [editMode, setEditMode] = useState(false); + + const [openNotif] = useContext(AppContext); + + const dispatch = useDispatch(); + + const formik = useFormik({ + initialValues: { + commitmentPercent: amount || 0, + }, + validationSchema: validationSchema, + onSubmit: (values) => { + const api = isDashboard + ? provinceManageGuildTradesEditAllPercents + : isGuild + ? provinceManageGuildTradesEditPercents + : provinceManageTradesEditPercents; + dispatch( + api({ + ...(isDashboard ? {} : { key: item?.key }), + out_province_free_buying_commitment_percent: + values?.commitmentPercent, + }) + ).then((r) => { + if (r.payload.error) { + openNotif({ + vertical: "top", + horizontal: "center", + msg: r.payload.error, + severity: "error", + }); + } else { + updateTable(); + openNotif({ + vertical: "top", + horizontal: "center", + msg: "عملیات با موفقیت انجام شد.", + severity: "success", + }); + } + }); + updateTable(); + setEditMode(false); + }, + }); + + const handleEditClick = () => { + formik.setValues({ commitmentPercent: amount || 0 }); + formik.setErrors({}); + setEditMode(true); + }; + + return ( + + {editMode ? ( + + + + + + + ) : ( + + %{amount || 0} + + + + + )} + + ); +}; diff --git a/src/features/province/components/province-manage-distributions-submit-percents/ProvinceManageDistributionsSubmitPercents.js b/src/features/province/components/province-manage-distributions-submit-percents/ProvinceManageDistributionsSubmitPercents.js new file mode 100644 index 0000000..c517a3a --- /dev/null +++ b/src/features/province/components/province-manage-distributions-submit-percents/ProvinceManageDistributionsSubmitPercents.js @@ -0,0 +1,258 @@ +import React, { useContext } from "react"; +import { useFormik } from "formik"; +import * as yup from "yup"; +import { TextField, Box, Button } from "@mui/material"; +import { provinceManageTradesEditPercents } from "../../services/province-manage-trades-edit-percents"; +import { useDispatch } from "react-redux"; +import { AppContext } from "../../../../contexts/AppContext"; +import { CLOSE_MODAL } from "../../../../lib/redux/slices/appSlice"; +import { Grid } from "../../../../components/grid/Grid"; + +const validationSchema = yup + .object({ + percentInsideProvince: yup + .number() + .typeError("باید عدد وارد کنید") + .min(0, "نمی‌تواند کمتر از 0 باشد") + .max(100, "نمی‌تواند بیشتر از 100 باشد") + .required("الزامی"), + percentOutsideProvince: yup + .number() + .typeError("باید عدد وارد کنید") + .min(0, "نمی‌تواند کمتر از 0 باشد") + .max(100, "نمی‌تواند بیشتر از 100 باشد") + .required("الزامی"), + percentSegmentation: yup + .number() + .typeError("باید عدد وارد کنید") + .min(0, "نمی‌تواند کمتر از 0 باشد") + .max(100, "نمی‌تواند بیشتر از 100 باشد") + .required("الزامی"), + }) + .test( + "total-percentage", + "مجموع درصدها نمی‌تواند بیشتر از 100 باشد", + function (values) { + const { + percentInsideProvince, + percentOutsideProvince, + percentSegmentation, + } = values; + const total = + (percentInsideProvince || 0) + + (percentOutsideProvince || 0) + + (percentSegmentation || 0); + return total <= 100; + } + ); + +export const ProvinceManageDistributionsSubmitPercents = ({ + item, + updateTable, + type, +}) => { + const [openNotif] = useContext(AppContext); + const dispatch = useDispatch(); + const formik = useFormik({ + initialValues: { + percentInsideProvince: + type === "gov" + ? item?.inProvinceGovernmentalSellingPercent + : item?.inProvinceFreeSellingPercent || 0, + percentOutsideProvince: + type === "gov" + ? item?.outProvinceGovernmentalSellingPercent + : item?.outProvinceFreeSellingPercent || 0, + percentSegmentation: + type === "gov" + ? item?.segmentationGovernmentalPercent + : item?.segmentationFreeSellingPercent || 0, + percentColdHouse: + type === "gov" + ? item?.coldHouseGovernmentalPercent + : item?.coldHouseFreePercent || 0, + }, + validationSchema: validationSchema, + onSubmit: (values) => { + dispatch( + provinceManageTradesEditPercents({ + key: item?.key, + ...(type === "gov" + ? { + governmental_selling_permission: true, + in_province_governmental_selling_percent: + values.percentInsideProvince, + segmentation_governmental_percent: values.percentSegmentation, + out_province_governmental_selling_percent: + values.percentOutsideProvince, + cold_house_governmental_percent: values.percentColdHouse, + } + : { + free_selling_permission: true, + in_province_free_selling_percent: values.percentInsideProvince, + out_province_free_selling_percent: + values.percentOutsideProvince, + segmentation_free_selling_percent: values.percentSegmentation, + cold_house_free_percent: values.percentColdHouse, + }), + }) + ).then((r) => { + if (r.payload.error) { + openNotif({ + vertical: "top", + horizontal: "center", + msg: r.payload.error, + severity: "error", + }); + } else { + openNotif({ + vertical: "top", + horizontal: "center", + msg: "عملیات با موفقیت انجام شد.", + severity: "success", + }); + } + dispatch(CLOSE_MODAL()); + updateTable(); + }); + }, + }); + + const calculateTotal = () => { + const { + percentInsideProvince, + percentOutsideProvince, + percentSegmentation, + percentColdHouse, + } = formik.values; + return ( + (percentInsideProvince || 0) + + (percentOutsideProvince || 0) + + (percentColdHouse || 0) + + (percentSegmentation || 0) + ); + }; + + const total = calculateTotal(); + + return ( + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ); +}; diff --git a/src/features/province/components/province-manage-distributions/ProvinceManageDistributions.js b/src/features/province/components/province-manage-distributions/ProvinceManageDistributions.js new file mode 100644 index 0000000..75d2dad --- /dev/null +++ b/src/features/province/components/province-manage-distributions/ProvinceManageDistributions.js @@ -0,0 +1,365 @@ +import React, { useContext, useEffect, useState } from "react"; +import { Button, Checkbox, IconButton, TextField } from "@mui/material"; +import axios from "axios"; +import { RiSearchLine } from "react-icons/ri"; +import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl"; +import { + LOADING_END, + LOADING_START, + OPEN_MODAL, +} from "../../../../lib/redux/slices/appSlice"; +import { useDispatch } from "react-redux"; +import { Grid } from "../../../../components/grid/Grid"; +import ResponsiveTable from "../../../../components/responsive-table/ResponsiveTable"; +import { ProvinceManageDistributionsSubmitPercents } from "../province-manage-distributions-submit-percents/ProvinceManageDistributionsSubmitPercents"; +import { provinceManageTradesEditPercents } from "../../services/province-manage-trades-edit-percents"; +import { AppContext } from "../../../../contexts/AppContext"; +import { ProvinceManageDistributionsSubmitCommitmentPercent } from "../province-manage-distributions-submit-commitment-percentet/ProvinceManageDistributionsSubmitCommitmentPercent"; +import EditIcon from "@mui/icons-material/Edit"; + +export const ProvinceManageDistributions = () => { + const handleTextChange = (event) => { + setTextValue(event.target.value); + }; + const [openNotif] = useContext(AppContext); + const dispatch = useDispatch(); + + const [data, setData] = useState([]); + const [totalRows, setTotalRows] = useState(0); + const [perPage, setPerPage] = useState(10); + const [textValue, setTextValue] = useState(""); + const [page, setPage] = useState(1); + const [tableData, setTableData] = useState([]); + + const fetchApiData = async (page) => { + let response; + dispatch(LOADING_START()); + response = await axios.get( + `market-kill-houses/?search=filter&value=${textValue}&role=${getRoleFromUrl()}&page=${page}&page_size=${perPage}` + ); + dispatch(LOADING_END()); + setData(response.data.results); + setTotalRows(response.data.count); + }; + + const handlePageChange = (page) => { + fetchApiData(page); + setPage(page); + }; + + const handlePerRowsChange = (perRows) => { + setPerPage(perRows); + setPage(1); + }; + + const updateTable = () => { + fetchApiData(page !== 0 ? page : 1); + }; + + const openGovModal = (item) => { + dispatch( + OPEN_MODAL({ + title: "فروش دولتی", + content: ( + + ), + }) + ); + }; + + const openFreeModal = (item) => { + dispatch( + OPEN_MODAL({ + title: "فروش آزاد", + content: ( + + ), + }) + ); + }; + + useEffect(() => { + const d = data?.map((item, i) => { + return [ + page === 1 ? i + 1 : i + perPage * (page - 1) + 1, + item?.name, + `${item?.fullname} (${item?.mobile})`, + item?.killer ? "کشتارکن" : "کشتارگاه", + , + { + dispatch( + provinceManageTradesEditPercents({ + key: item?.key, + free_sale_from_free_quota_in_province: + !item?.freeSaleFromFreeQuotaInProvince, + }) + ).then((r) => { + if (r.payload.error) { + openNotif({ + vertical: "top", + horizontal: "center", + msg: r.payload.error, + severity: "error", + }); + } else { + updateTable(); + openNotif({ + vertical: "top", + horizontal: "center", + msg: "عملیات با موفقیت انجام شد.", + severity: "success", + }); + } + }); + }} + />, + { + dispatch( + provinceManageTradesEditPercents({ + key: item?.key, + free_sale_form_governmental_quota: + !item?.freeSaleFormGovernmentalQuota, + }) + ).then((r) => { + if (r.payload.error) { + openNotif({ + vertical: "top", + horizontal: "center", + msg: r.payload.error, + severity: "error", + }); + } else { + updateTable(); + openNotif({ + vertical: "top", + horizontal: "center", + msg: "عملیات با موفقیت انجام شد.", + severity: "success", + }); + } + }); + }} + />, + + + + { + const newValue = !item?.governmentalSellingPermission; + dispatch( + provinceManageTradesEditPercents({ + key: item?.key, + governmental_selling_permission: newValue, + ...(newValue === false + ? { + in_province_governmental_selling_percent: 0, + segmentation_governmental_percent: 0, + out_province_governmental_selling_percent: 0, + } + : {}), + }) + ).then((r) => { + if (newValue === true) { + openGovModal(item); + } else { + openNotif({ + vertical: "top", + horizontal: "center", + msg: "عملیات با موفقیت انجام شد.", + severity: "success", + }); + } + updateTable(); + }); + }} + /> + + + {item?.governmentalSellingPermission && ( + + openGovModal(item)} + color="primary" + > + + + + )} + , + + + { + const newValue = !item?.freeSellingPermission; + dispatch( + provinceManageTradesEditPercents({ + key: item?.key, + free_selling_permission: newValue, + ...(newValue === false + ? { + in_province_free_selling_percent: 0, + out_province_free_selling_percent: 0, + segmentation_free_selling_percent: 0, + } + : {}), + }) + ).then((r) => { + if (newValue === true) { + openFreeModal(item); + } else { + openNotif({ + vertical: "top", + horizontal: "center", + msg: "عملیات با موفقیت انجام شد.", + severity: "success", + }); + } + updateTable(); + }); + }} + /> + + + + {item?.freeSellingPermission && ( + openFreeModal(item)} + color="primary" + > + + + )}{" "} + + , + item?.inProvinceGovernmentalSellingPercent, + item?.outProvinceGovernmentalSellingPercent, + item?.segmentationGovernmentalPercent, + item?.coldHouseGovernmentalPercent, + item?.inProvinceFreeSellingPercent, + item?.outProvinceFreeSellingPercent, + item?.segmentationFreeSellingPercent, + item?.coldHouseFreePercent, + ]; + }); + + setTableData(d); + }, [data]); + + useEffect(() => { + fetchApiData(1); + }, [dispatch, perPage]); + + const handleSubmit = async (event) => { + event.preventDefault(); + dispatch(LOADING_START()); + + try { + const response = await axios.get( + `market-kill-houses/?role=${getRoleFromUrl()}&search=filter&value=${textValue}&page=${1}&page_size=${perPage}` + ); + setData(response.data.results); + setTotalRows(response.data.count); + dispatch(LOADING_END()); + } catch (error) { + console.error("Error fetching data:", error); + } + }; + + return ( + + + +
    + + + +
    +
    + + +
    + ); +}; diff --git a/src/features/province/components/province-manage-fees/ProvinceManageFees.js b/src/features/province/components/province-manage-fees/ProvinceManageFees.js new file mode 100644 index 0000000..9c7130e --- /dev/null +++ b/src/features/province/components/province-manage-fees/ProvinceManageFees.js @@ -0,0 +1,54 @@ +import { TabContext, TabPanel } from "@mui/lab"; +import { Tab, Tabs } from "@mui/material"; +import { useState } from "react"; +import { Grid } from "../../../../components/grid/Grid"; +import { ProvinceArchiveFees } from "../province-archive-fees/ProvinceArchiveFees"; +import { ProvinceFeesOverview } from "../province-fees-overview/ProvinceFeesOverview"; +import { ProvincePaidFees } from "../province-paid-fees/ProvincePaidFees"; +import { ProvinceUnpaidFees } from "../province-unpaid-fees/ProvinceUnpaidFees"; +import { ProvincePaymentByWeight } from "../province-payment-by-weight/ProvincePaymentByWeight"; + +export const ProvinceManageFees = () => { + const [tabValue, setTabValue] = useState("1"); + + const handleTabChange = (event, newValue) => { + setTabValue(newValue); + }; + + return ( + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ); +}; diff --git a/src/features/province/components/province-manage-guild-distributions-submit-percents/ProvinceManageGuildDistributionsSubmitPercents.js b/src/features/province/components/province-manage-guild-distributions-submit-percents/ProvinceManageGuildDistributionsSubmitPercents.js new file mode 100644 index 0000000..4b2e6ae --- /dev/null +++ b/src/features/province/components/province-manage-guild-distributions-submit-percents/ProvinceManageGuildDistributionsSubmitPercents.js @@ -0,0 +1,235 @@ +import React, { useContext } from "react"; +import { useFormik } from "formik"; +import * as yup from "yup"; +import { TextField, Box, Button } from "@mui/material"; +import { useDispatch } from "react-redux"; +import { AppContext } from "../../../../contexts/AppContext"; +import { CLOSE_MODAL } from "../../../../lib/redux/slices/appSlice"; +import { Grid } from "../../../../components/grid/Grid"; +import { + provinceManageGuildTradesEditAllPercents, + provinceManageGuildTradesEditPercents, +} from "../../services/province-manage-guilds-trades-edit-percents"; + +const validationSchema = yup + .object({ + percentInsideProvince: yup + .number() + .typeError("باید عدد وارد کنید") + .min(0, "نمی‌تواند کمتر از 0 باشد") + .max(100, "نمی‌تواند بیشتر از 100 باشد") + .required("الزامی"), + percentOutsideProvince: yup + .number() + .typeError("باید عدد وارد کنید") + .min(0, "نمی‌تواند کمتر از 0 باشد") + .max(100, "نمی‌تواند بیشتر از 100 باشد") + .required("الزامی"), + percentSegmentation: yup + .number() + .typeError("باید عدد وارد کنید") + .min(0, "نمی‌تواند کمتر از 0 باشد") + .max(100, "نمی‌تواند بیشتر از 100 باشد") + .required("الزامی"), + }) + .test( + "total-percentage", + "مجموع درصدها نمی‌تواند بیشتر از 100 باشد", + function (values) { + const { + percentInsideProvince, + percentOutsideProvince, + percentSegmentation, + } = values; + const total = + (percentInsideProvince || 0) + + (percentOutsideProvince || 0) + + (percentSegmentation || 0); + return total <= 100; + } + ); + +export const ProvinceManageGuildDistributionsSubmitPercents = ({ + item, + updateTable, + type, + isDashboard, +}) => { + const [openNotif] = useContext(AppContext); + const dispatch = useDispatch(); + const api = isDashboard + ? provinceManageGuildTradesEditAllPercents + : provinceManageGuildTradesEditPercents; + const formik = useFormik({ + initialValues: { + percentInsideProvince: + type === "gov" + ? item?.inProvinceGovernmentalSellingPercent + : item?.inProvinceFreeSellingPercent || 0, + percentOutsideProvince: + type === "gov" + ? item?.outProvinceGovernmentalSellingPercent + : item?.outProvinceFreeSellingPercent || 0, + percentSegmentation: + type === "gov" + ? item?.segmentationGovernmentalPercent + : item?.segmentationFreeSellingPercent || 0, + }, + validationSchema: validationSchema, + onSubmit: (values) => { + dispatch( + api({ + ...(isDashboard ? {} : { key: item?.key }), + ...(type === "gov" + ? { + governmental_selling_permission: true, + in_province_governmental_selling_percent: + values.percentInsideProvince, + segmentation_governmental_percent: values.percentSegmentation, + out_province_governmental_selling_percent: + values.percentOutsideProvince, + } + : { + free_selling_permission: true, + in_province_free_selling_percent: values.percentInsideProvince, + out_province_free_selling_percent: + values.percentOutsideProvince, + segmentation_free_selling_percent: values.percentSegmentation, + }), + }) + ).then((r) => { + if (r.payload.error) { + openNotif({ + vertical: "top", + horizontal: "center", + msg: r.payload.error, + severity: "error", + }); + } else { + openNotif({ + vertical: "top", + horizontal: "center", + msg: "عملیات با موفقیت انجام شد.", + severity: "success", + }); + } + dispatch(CLOSE_MODAL()); + updateTable(); + }); + }, + }); + + const calculateTotal = () => { + const { + percentInsideProvince, + percentOutsideProvince, + percentSegmentation, + } = formik.values; + return ( + (percentInsideProvince || 0) + + (percentOutsideProvince || 0) + + (percentSegmentation || 0) + ); + }; + + const total = calculateTotal(); + + return ( + + + + + + + + + + + + + + + + + + + + + + + + + ); +}; diff --git a/src/features/province/components/province-manage-guilds-submit-register-code/ProvinceManageGuildsSubmitRegisterCode.js b/src/features/province/components/province-manage-guilds-submit-register-code/ProvinceManageGuildsSubmitRegisterCode.js new file mode 100644 index 0000000..6be9e13 --- /dev/null +++ b/src/features/province/components/province-manage-guilds-submit-register-code/ProvinceManageGuildsSubmitRegisterCode.js @@ -0,0 +1,106 @@ +import React, { useContext } from "react"; +import { useFormik } from "formik"; +import * as yup from "yup"; +import { TextField, Button } from "@mui/material"; +import { Grid } from "../../../../components/grid/Grid"; +import { useDispatch } from "react-redux"; +import { AppContext } from "../../../../contexts/AppContext"; +import { checkKillhouseRequestGuildService } from "../../services/check-killhouse-request-guild"; +import { CLOSE_MODAL } from "../../../../lib/redux/slices/appSlice"; +import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl"; + +const validationSchema = yup.object({ + verificationCode: yup + .string() + .required("کد احراز الزامی است") + .matches(/^\d+$/, "کد احراز باید فقط شامل اعداد باشد") + .min(4, "کد احراز باید حداقل ۴ رقم باشد") + .max(6, "کد احراز حداکثر ۶ رقم می‌باشد"), +}); + +export const ProvinceManageGuildsSubmitRegisterCode = ({ + item, + updateTable, +}) => { + const dispatch = useDispatch(); + + const [openNotif] = useContext(AppContext); + const formik = useFormik({ + initialValues: { + verificationCode: "", + }, + validationSchema: validationSchema, + onSubmit: (values) => { + dispatch( + checkKillhouseRequestGuildService({ + guilds_key: item.key, + state: "accepted", + code: values.verificationCode, + role: getRoleFromUrl(), + }) + ).then((r) => { + if (r.payload.error) { + openNotif({ + vertical: "top", + horizontal: "center", + msg: r.payload.error, + severity: "error", + }); + } else { + updateTable(); + dispatch(CLOSE_MODAL()); + openNotif({ + vertical: "top", + horizontal: "center", + msg: "عملیات با موفقیت انجام شد.", + severity: "success", + }); + } + }); + }, + }); + + return ( + + + + + + ); +}; diff --git a/src/features/province/components/province-manage-operation-modal-buy-req/ProvinceManageOperationModalBuyReq.js b/src/features/province/components/province-manage-operation-modal-buy-req/ProvinceManageOperationModalBuyReq.js new file mode 100644 index 0000000..05c388c --- /dev/null +++ b/src/features/province/components/province-manage-operation-modal-buy-req/ProvinceManageOperationModalBuyReq.js @@ -0,0 +1,281 @@ +import { Typography } from "@mui/material"; +import { Grid } from "../../../../components/grid/Grid"; +import { useDispatch, useSelector } from "react-redux"; +import { ProvinceManageBuyReqAllowOperation } from "../province-manage-buy-req-allow-operation/ProvinceManageBuyReqAllowOperation"; +import { ProvinceManageBuyReqLimitOperation } from "../province-manage-buy-req-limit-operation/ProvinceManageBuyReqLimitOperation"; +import { slaughterGetPermisionState } from "../../../slaughter-house/services/slaughter-get-permision"; +import { ProvinceManagementSellingSlaughterLimitation } from "../province-manage-selling-slaughter-limitaion/ProvinceManagementSellingSlaughterLimitation"; +import { ProvinceManageSellingForceGovernmentalBuy } from "../../../city/components/province-manage-selling-force-governmental-buy/ProvinceManageSellingForceGovernmentalBuy"; +import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl"; +import { ProvinceManagementMaximumLoad } from "../province-management-maximum-load/ProvinceManagementMaximumLoad"; +import { ProvinceManageWarehouseLimitation } from "../province-manage-warehouse-limitation/ProvinceManageWarehouseLimitation"; +import { ProvinceManageCarcassStandardLossPercent } from "../province-manage-carcass-standard-loss-percent/ProvinceManageCarcassStandardLossPercent"; + +export const ProvinceManageOperationModalBuyReq = ({ item, fetchdata }) => { + const { role } = useSelector((state) => state.userSlice); + const dispatch = useDispatch(); + + const getLimitInformation = () => { + if (role.includes("KillHouse")) { + dispatch(slaughterGetPermisionState()); + } + }; + + return ( + + + {/* + + + + + + */} + + + + + + + + مجوز ثبت درخواست + + + + + + + + + محدودیت پنل + + + + {/* + + + + + + + + + + */} + + + + + + + + {getRoleFromUrl() === "AdminX" && ( + + + + + + )} + + + + + + + + + + + + + + + + + + + + + + + + + + ); +}; diff --git a/src/features/province/components/province-manage-payment-link-modal/PaymentLinkModal.js b/src/features/province/components/province-manage-payment-link-modal/PaymentLinkModal.js new file mode 100644 index 0000000..65a7552 --- /dev/null +++ b/src/features/province/components/province-manage-payment-link-modal/PaymentLinkModal.js @@ -0,0 +1,58 @@ +import { Button } from "@mui/material"; +import { getSystemBaseAddress } from "../../../../utils/getSystemBaseAddress"; +import { useDispatch, useSelector } from "react-redux"; +import { Grid } from "../../../../components/grid/Grid"; +import { useContext } from "react"; +import { AppContext } from "../../../../contexts/AppContext"; +import { CLOSE_MODAL } from "../../../../lib/redux/slices/appSlice"; + +export const PaymentLinkModal = ({ item }) => { + const userPath = useSelector((state) => state.userSlice.userPath); + + const paymentLink = `${window.location.origin}/pay/${getSystemBaseAddress( + userPath + )}/${item?.wageInfo?.userToken}`; + + const [openNotif] = useContext(AppContext); + const dispatch = useDispatch(); + + const handleCopyLink = () => { + navigator.clipboard.writeText(paymentLink).then(() => { + openNotif({ + vertical: "top", + horizontal: "center", + msg: "لینک پرداخت کپی شد", + severity: "success", + }); + dispatch(CLOSE_MODAL()); + }); + }; + + return ( + + + + + + + + + + + + ); +}; diff --git a/src/features/province/components/province-manage-poultry-request-operations/ProvinceManagePoultryRequestOperations.js b/src/features/province/components/province-manage-poultry-request-operations/ProvinceManagePoultryRequestOperations.js new file mode 100644 index 0000000..c709b7c --- /dev/null +++ b/src/features/province/components/province-manage-poultry-request-operations/ProvinceManagePoultryRequestOperations.js @@ -0,0 +1,300 @@ +import { + Button, + IconButton, + List, + ListItem, + ListItemButton, + ListItemIcon, + ListItemText, + Popover, + Tooltip, +} from "@mui/material"; +import { useContext, useState } from "react"; +import { useDispatch } from "react-redux"; +import { Grid } from "../../../../components/grid/Grid"; +import { AppContext } from "../../../../contexts/AppContext"; +import { SPACING } from "../../../../data/spacing"; +import { CLOSE_MODAL, OPEN_MODAL } from "../../../../lib/redux/slices/appSlice"; +import { avicultureHatchingRequestsService } from "../../../aviculture/services/aviculture-hatching-requests"; +import { archiveAvicaltureRequestService } from "../../../city/services/archive-avicalture-request"; +import ArchiveIcon from "@mui/icons-material/Archive"; +import DeleteIcon from "@mui/icons-material/Delete"; +import { removeAvicaltureRequestService } from "../../../city/services/remove-avicalture-request"; +import TuneIcon from "@mui/icons-material/Tune"; +import PlagiarismIcon from "@mui/icons-material/Plagiarism"; +import { useNavigate } from "react-router-dom"; +import EditIcon from "@mui/icons-material/Edit"; +import { CityUpdateKillRequest } from "../../../city/components/city-update-kill-request/CityUpdateKillRequest"; +import { ProvincePoultryRequestEnterConfirmationCode } from "../province-poultry-request-enter-confirmation-code/ProvincePoultryRequestEnterConfirmationCode"; +import VpnKeyIcon from "@mui/icons-material/VpnKey"; + +export const ProvinceManagePoultryRequestOperations = ({ + item, + fileUrl, + updateTable, +}) => { + const dispatch = useDispatch(); + const navigate = useNavigate(); + const [openNotif] = useContext(AppContext); + + const [, , selectedDate1, , selectedDate2] = useContext(AppContext); + + const [anchorEl, setAnchorEl] = useState(null); + + const handleClick = (event) => { + setAnchorEl(event.currentTarget); + }; + + const handleClose = () => { + setAnchorEl(null); + }; + + const open = Boolean(anchorEl); + const id = open ? "popover" : undefined; + + return ( + + + + + + + {item.hatching.fileState === "confirmation_code_pending" && ( + + + { + handleClose(); + dispatch( + OPEN_MODAL({ + title: "ورود کد احراز", + content: ( + + ), + }) + ); + }} + > + + + + + + + + )} + + + { + handleClose(); + dispatch( + OPEN_MODAL({ + title: "ویرایش تعداد کشتار", + content: ( + + ), + }) + ); + }} + > + + + + + + + + + + { + handleClose(); + dispatch( + OPEN_MODAL({ + title: "آیا مطمئن هستید؟", + content: ( + + + + + ), + }) + ); + }} + > + + + + + + + + + + { + handleClose(); + navigate(fileUrl + item?.id); + }} + > + + + + + + + + + + { + handleClose(); + dispatch( + OPEN_MODAL({ + title: "آیا مطمئن هستید؟", + content: ( + + + + + ), + }) + ); + }} + > + + + + + + + + + + + ); +}; diff --git a/src/features/province/components/province-manage-poultry-request/ProvinceManagePoultryRequest.js b/src/features/province/components/province-manage-poultry-request/ProvinceManagePoultryRequest.js new file mode 100644 index 0000000..2dcd6f3 --- /dev/null +++ b/src/features/province/components/province-manage-poultry-request/ProvinceManagePoultryRequest.js @@ -0,0 +1,438 @@ +import { Button, TextField, Tooltip, Typography } from "@mui/material"; +import { useContext, useEffect, useState } from "react"; +import { useDispatch, useSelector } from "react-redux"; +import { useLocation } from "react-router-dom"; +import { Grid } from "../../../../components/grid/Grid"; +import { SPACING } from "../../../../data/spacing"; +import { + DRAWER, + LOADING_END, + LOADING_START, +} from "../../../../lib/redux/slices/appSlice"; +import { CityNewKillRequest } from "../../../city/components/city-new-kill-request/CityNewKillRequest"; +import { AppContext } from "../../../../contexts/AppContext"; +import { hourLimitKillRequestService } from "../../../city/services/hour-limit-kill-request"; +import { hourLimitGetKillRequestService } from "../../../city/services/hour-limit-get-kill-request"; +import { DatePicker } from "@mui/x-date-pickers"; +import moment from "moment"; +import { getPoultryRequestsTotalQuantityService } from "../../../city/services/get-poultry-requests-total-quantity"; +import { formatJustDate, formatTime } from "../../../../utils/formatTime"; +import axios from "axios"; +import { RiFileExcel2Fill, RiSearchLine } from "react-icons/ri"; +import { ProvinceManagePoultryRequestOperations } from "../province-manage-poultry-request-operations/ProvinceManagePoultryRequestOperations"; +import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl"; +import { getFaUserRole } from "../../../../utils/getFaUserRole"; +import { deleteDebtorKillhouses } from "../../services/delete-debtor-killhouses"; +import ResponsiveTable from "../../../../components/responsive-table/ResponsiveTable"; + +export const ProvinceManagePoultryRequest = () => { + const authToken = useSelector((state) => state.userSlice.authToken); + const { poultryRequestsTotalQuantity } = useSelector( + (state) => state.citySlice + ); + const { pathname } = useLocation(); + const dispatch = useDispatch(); + const [isChecked, setIsChecked] = useState(false); + const [selectedHour, setSelectedHour] = useState(""); + + const [openNotif] = useContext(AppContext); + + const [data, setData] = useState([]); + const [totalRows, setTotalRows] = useState(0); + const [perPage, setPerPage] = useState(10); + const [textValue, setTextValue] = useState(""); + const [page, setPage] = useState(1); + const [tableData, setTableData] = useState([]); + + const handleTextChange = (event) => { + setTextValue(event.target.value); + }; + + const fetchApiData = async (page) => { + dispatch(LOADING_START()); + const response = await axios.get( + `Poultry_Request/?role=${getRoleFromUrl()}&today&date1=${selectedDate1}&date2=${selectedDate2}&search=filter&value=${ + textValue || "" + }&page=${page}&page_size=${perPage}` + ); + dispatch(LOADING_END()); + setData(response.data.results); + setTotalRows(response.data.count); + }; + + const handlePageChange = (page) => { + fetchApiData(page); + setPage(page); + }; + + const handleSubmit = async (event) => { + event.preventDefault(); + dispatch(LOADING_START()); + + try { + const response = await axios.get( + `Poultry_Request/?role=${getRoleFromUrl()}&today&date1=${selectedDate1}&date2=${selectedDate2}&search=filter&value=${ + textValue || "" + }` + ); + setData(response.data.results); + setTotalRows(response.data.count); + dispatch(LOADING_END()); + } catch (error) { + console.error("Error fetching data:", error); + } + }; + + const [selectedDate, setSelectedDate] = useState( + moment(new Date()).format("YYYY-MM-DD") + ); + + const [, , selectedDate1, setSelectedDate1, selectedDate2, setSelectedDate2] = + useContext(AppContext); + + useEffect(() => { + const currentDate = moment(new Date()).format("YYYY-MM-DD"); + setSelectedDate1(currentDate); + setSelectedDate2(currentDate); + }, []); + + const handlePerRowsChange = (perRows) => { + setPerPage(perRows); + setPage(1); + }; + + useEffect(() => { + dispatch(getPoultryRequestsTotalQuantityService(selectedDate)); + }, [selectedDate]); + + useEffect(() => { + dispatch(hourLimitGetKillRequestService()).then((r) => { + setIsChecked(r.payload.data?.[0]?.active); + setSelectedHour(r.payload.data?.[0]?.hour); + }); + dispatch(deleteDebtorKillhouses()); + }, []); + + useEffect(() => { + if (isChecked && selectedHour) { + dispatch( + hourLimitKillRequestService({ hour: selectedHour, active: isChecked }) + ); + } + if (!isChecked && selectedHour) { + setSelectedHour(null); + dispatch(hourLimitKillRequestService({ hour: 0, active: isChecked })); + } + }, [selectedHour, isChecked]); + + const urlRole = window.location.pathname.split("/")[1]; + const fileUrl = "/" + urlRole + "/file/"; + + const getItemSellState = (item) => { + let sellType = ""; + if (item?.market) { + sellType = "پنل معاملات"; + } else if (item?.directBuying) { + sellType = "خرید مستقیم"; + } else if (item?.union) { + sellType = "خرید خارج از استان"; + } else { + sellType = "اتحادیه"; + } + return sellType; + }; + + useEffect(() => { + const d = data?.map((item, i) => { + return [ + page === 1 ? i + 1 : i + perPage * (page - 1) + 1, + , + item.orderCode, + getItemFreeSaleInProvince(item), + item?.freezing ? "انجماد" : item?.export ? "صادرات" : "عادی", + getItemSellState(item), + formatTime(item?.createDate) + + " " + + `(${item?.registrar?.fullname} - ${getFaUserRole( + item?.registrar?.role + )})`, + formatJustDate(item?.sendDate), + `${item?.poultry?.unitName} (${item?.poultry?.user?.mobile})`, + item?.killHouseList?.length ? item?.killHouseList.join(" - ") : "ندارد", + `${item?.poultry?.address?.city?.name}/${ + item?.poultry?.cityOperator + ? item?.poultry?.cityOperator + : "بدون تعاونی" + }`, + item?.killingAge, + item?.IndexWeight, + item?.hatching?.totalWeight?.toLocaleString(), + item?.firstQuantity.toLocaleString(), + item?.amount.toLocaleString() + " ﷼", + item?.hatching?.leftOver?.toLocaleString(), + item.quantity?.toLocaleString(), + (item.quantity - item?.remainQuantity).toLocaleString(), + item?.remainQuantity?.toLocaleString(), + + {item.hatching.fileState === "province_state_pending" + ? "در انتظار تایید" + : item.hatching.fileState === "allocated_pending" + ? "آماده تخصیص" + : item.hatching.fileState === "confirmation_code_pending" + ? "در انتظار ورود کد احراز" + : "تخصیص داده شده"} + , + ]; + }); + + setTableData(d); + }, [data]); + + useEffect(() => { + fetchApiData(1); + }, [selectedDate1, selectedDate2, perPage]); + + const updateTable = () => { + fetchApiData(1); + }; + + const tableTitle = ( + +
    + + + + + ( + + )} + value={selectedDate1} + onChange={(e) => { + setSelectedDate1(moment(e).format("YYYY-MM-DD")); + }} + /> + + + ( + + )} + value={selectedDate2} + onChange={(e) => { + setSelectedDate2(moment(e).format("YYYY-MM-DD")); + }} + /> + + + {/* */} + + {/* */} + + +
    +
    + ); + + const getItemFreeSaleInProvince = (item) => { + let sellType = ""; + if (item?.freeSaleInProvince) { + sellType = "آزاد"; + } else { + sellType = "دولتی"; + } + return sellType; + }; + + return ( + + + + {pathname !== "/vet-supervisor/hatching" && ( + + )} + + + + + + اطلاعات کشتار + + + ( + + )} + value={selectedDate} + onChange={(e) => { + setSelectedDate(moment(e).format("YYYY-MM-DD")); + }} + /> + + + + + + + + {tableTitle} + + + + + + ); +}; diff --git a/src/features/province/components/province-manage-process-operation/ProvinceManageProcessOperation.js b/src/features/province/components/province-manage-process-operation/ProvinceManageProcessOperation.js new file mode 100644 index 0000000..d80185f --- /dev/null +++ b/src/features/province/components/province-manage-process-operation/ProvinceManageProcessOperation.js @@ -0,0 +1,235 @@ +import { VscComment, VscNewFolder } from "react-icons/vsc"; +import { useLocation } from "react-router-dom"; +import { Grid } from "../../../../components/grid/Grid"; +import LinkItem from "../../../../components/link-item/LinkItem"; +import { NavLink } from "../../../../components/nav-link/NavLink"; +import { SPACING } from "../../../../data/spacing"; +import { + ROUTE_ADMINX_ROUTE_ACCOUNTS, + ROUTE_ADMINX_ROUTE_CRONJOB, + ROUTE_ADMINX_ROUTE_Sms_Submission_Management, + ROUTE_ADMINX_ROUTE_MANAGE_PROCESS_DOCUMENT_STATES, + ROUTE_ADMINX_ROUTE_MANAGE_PROCESS_POLICY_COUNCIL, + ROUTE_ADMINX_ROUTE_MANAGE_PROCESS_WAGE_FRACTIONS, + ROUTE_ADMINX_ROUTE_TICKET_PERMISSION, + ROUTE_PROVINCE_ROUTE_MANAGE_PROCESS_POLICY_COUNCIL, + ROUTE_SUPER_ADMIN_ROUTE_MANAGE_PROCESS_DOCUMENT_STATES, + ROUTE_SUPER_ADMIN_ROUTE_MANAGE_PROCESS_POLICY_COUNCIL, + ROUTE_SUPER_ADMIN_ROUTE_TICKET_PERMISSION, + ROUTE_ADMINX_ROUTE_WEIGHT_RANGE, + ROUTE_ADMINX_ROUTE_WEIGHT_CATEGORY, + ROUTE_SUPER_ADMIN_ROUTE_WEIGHT_RANGE, + ROUTE_SUPER_ADMIN_ROUTE_WEIGHT_CATEGORY, + ROUTE_SUPER_ADMIN_ROUTE_PENALTY, + ROUTE_ADMINX_ROUTE_PENALTY, + ROUTE_ADMINX_ROUTE_RESTRICTION_OF_CARCASS_DISTRIBUTION, + ROUTE_SUPER_ADMIN_ROUTE_RESTRICTION_OF_CARCASS_DISTRIBUTION, + // ROUTE_SUPER_ADMIN_ROUTE_PENALTY, + // ROUTE_ADMINX_ROUTE_PENALTY, +} from "../../../../routes/routes"; +import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl"; +import { VscGripper } from "react-icons/vsc"; +import { + FaDollarSign, + FaFile, + FaMoneyBill, + FaPercent, + FaSms, + FaWeight, + FaBan, + // FaDollarSign, +} from "react-icons/fa"; +export const ProvinceManageProcessOperation = () => { + const { pathname } = useLocation(); + + return ( + + + } + title="شورای سیاست گذاری" + /> + + + {getRoleFromUrl() === "AdminX" && ( + + } + title="سهم بندی" + /> + + )} + + + } + title="وضعیت اسناد" + /> + + {getRoleFromUrl() === "AdminX" && ( + + } + title="حساب ها" + /> + + )} + {(getRoleFromUrl() === "AdminX" || getRoleFromUrl() === "SuperAdmin") && ( + + } + title="مدیریت ارسال تیکت" + /> + + )} + {getRoleFromUrl() === "AdminX" && ( + + } + title="کرونجاب" + /> + + )} + + {getRoleFromUrl() === "AdminX" && ( + + } + title="مدیریت ارسال پیامک" + /> + + )} + + } + title="مدیریت بازه وزنی" + /> + + + + } + title="دسته بندی وزنی" + /> + + + } + title="جریمه" + /> + + + } + title="محدودیت توزیع لاشه" + /> + + + ); +}; diff --git a/src/features/province/components/province-manage-selling-limitation/ProvinceManageSellingLimitaion.js b/src/features/province/components/province-manage-selling-limitation/ProvinceManageSellingLimitaion.js new file mode 100644 index 0000000..a266bf2 --- /dev/null +++ b/src/features/province/components/province-manage-selling-limitation/ProvinceManageSellingLimitaion.js @@ -0,0 +1,124 @@ +import { Switch, TextField, Typography, Button } from "@mui/material"; +import DoneIcon from "@mui/icons-material/Done"; +import { useDispatch } from "react-redux"; +import { useContext, useState } from "react"; +import { Grid } from "../../../../components/grid/Grid"; +import { AppContext } from "../../../../contexts/AppContext"; +import { provincePolicyWagesEditKillhouse } from "../../services/province-policy-wages-edit-killhouse"; +import { SPACING } from "../../../../data/spacing"; + +export const ProvinceManageSellingLimitaion = ({ item, fetchdata }) => { + const dispatch = useDispatch(); + const [openNotif] = useContext(AppContext); + + const [percent, setPercent] = useState( + item?.inProvinceSellingLimitationPercent + ); + const [minimumSaleState, setMinimumSaleState] = useState( + item?.inProvinceSellingLimitation + ); + + const handleToggle = (value) => { + dispatch( + provincePolicyWagesEditKillhouse({ + kill_house_key: item?.key, + in_province_selling_limitation: value, + in_province_selling_limitation_percent: value ? percent || 0 : 0, + }) + ).then((r) => { + setMinimumSaleState(value); + if (r.payload?.error) { + openNotif({ + vertical: "top", + horizontal: "center", + msg: r.payload.error, + severity: "error", + }); + } else { + fetchdata(); + } + }); + }; + + const handleUpdatePercent = () => { + if (percent > 100 || percent < 1) { + openNotif({ + vertical: "top", + horizontal: "center", + msg: "درصد باید عددی بین ۱ تا ۱۰۰ باشد.", + severity: "error", + }); + return; + } + + dispatch( + provincePolicyWagesEditKillhouse({ + kill_house_key: item?.key, + in_province_selling_limitation: true, + in_province_selling_limitation_percent: percent, + }) + ).then((r) => { + if (r.payload?.error) { + openNotif({ + vertical: "top", + horizontal: "center", + msg: r.payload.error, + severity: "error", + }); + } else { + fetchdata(); + } + }); + }; + + return ( + + + + handleToggle(e.target.checked)} + inputProps={{ + "aria-label": "in-province-selling-limitation-switch", + }} + /> + + + حداقل توزیع داخل استان + + + + {minimumSaleState && ( + + + + { + setPercent(e.target.value); + }} + inputProps={{ min: 1, max: 100 }} + /> + + + + + + + )} + + ); +}; diff --git a/src/features/province/components/province-manage-selling-slaughter-limitaion/ProvinceManagementSellingSlaughterLimitation.js b/src/features/province/components/province-manage-selling-slaughter-limitaion/ProvinceManagementSellingSlaughterLimitation.js new file mode 100644 index 0000000..12c9bc9 --- /dev/null +++ b/src/features/province/components/province-manage-selling-slaughter-limitaion/ProvinceManagementSellingSlaughterLimitation.js @@ -0,0 +1,132 @@ +import React, { useContext, useState } from "react"; +import { AppContext } from "../../../../contexts/AppContext"; +import { Grid } from "../../../../components/grid/Grid"; +import { Button, Switch, TextField, Typography } from "@mui/material"; +import { provincePolicyWagesEditKillhouse } from "../../services/province-policy-wages-edit-killhouse"; +import { useDispatch } from "react-redux"; + +export const ProvinceManagementSellingSlaughterLimitation = ({ + item, + fetchdata, +}) => { + const [openNotif] = useContext(AppContext); + const dispatch = useDispatch(); + const [limitEnabled, setLimitEnabled] = useState(item?.maxKillLimit); + const [killCapacity, setKillCapacity] = useState(item?.totalKillCapacity); + const [killPercent, setKillPercent] = useState(item?.extraBarKillPercent); + + const handleToggle = () => { + const newLimit = !limitEnabled; + setLimitEnabled(newLimit); + + dispatch( + provincePolicyWagesEditKillhouse({ + kill_house_key: item?.key, + total_kill_capacity: killCapacity, + extra_bar_kill_percent: killPercent, + max_kill_limit: newLimit, + }) + ).then((r) => { + if (r.payload.error) { + openNotif({ + vertical: "top", + horizontal: "center", + msg: r.payload.error, + severity: "error", + }); + } else { + fetchdata(); + openNotif({ + vertical: "top", + horizontal: "center", + msg: "وضعیت محدودیت با موفقیت تغییر کرد.", + severity: "success", + }); + } + }); + }; + + const handleSubmit = () => { + dispatch( + provincePolicyWagesEditKillhouse({ + kill_house_key: item?.key, + total_kill_capacity: killCapacity, + extra_bar_kill_percent: killPercent, + max_kill_limit: limitEnabled, + }) + ).then((r) => { + if (r.payload.error) { + openNotif({ + vertical: "top", + horizontal: "center", + msg: r.payload.error, + severity: "error", + }); + } else { + fetchdata(); + openNotif({ + vertical: "top", + horizontal: "center", + msg: "محدودیت با موفقیت ویرایش شد.", + severity: "success", + }); + } + }); + }; + + return ( + + + + + + + محدودیت سقف کشتار + + + + {limitEnabled && ( + + + setKillCapacity(e.target.value)} + size="small" + /> + + + setKillPercent(e.target.value)} + size="small" + /> + + + + + + )} + + ); +}; diff --git a/src/features/province/components/province-manage-slaughter-killplace/ProvinceManageSlaughterKillplace.js b/src/features/province/components/province-manage-slaughter-killplace/ProvinceManageSlaughterKillplace.js new file mode 100644 index 0000000..f2f9cbd --- /dev/null +++ b/src/features/province/components/province-manage-slaughter-killplace/ProvinceManageSlaughterKillplace.js @@ -0,0 +1,389 @@ +import { + Button, + FormControlLabel, + IconButton, + Switch, + TextField, + Tooltip, + Typography, +} from "@mui/material"; +import { useContext, useEffect, useState } from "react"; +import { useDispatch, useSelector } from "react-redux"; +import { Grid } from "../../../../components/grid/Grid"; +import { AppContext } from "../../../../contexts/AppContext"; +import { SPACING } from "../../../../data/spacing"; +import { + CLOSE_MODAL, + DRAWER, + OPEN_MODAL, +} from "../../../../lib/redux/slices/appSlice"; +import { slaughterGetKillerKillhousesService } from "../../../slaughter-house/services/slaughter-get-killers-killhouses"; +import { provinceGetSlaughterhousesQuotaService } from "../../services/province-get-slaughterhouses-quota"; +import { provincePurgeNeededRequestService } from "../../services/province-purge-needed-request"; +import { ProvinceCreateKillhouse } from "../province-create-killhouse/ProvinceCreateKillhouse"; +import { ProvinceSelectSlaughterForSlaughter } from "../province-select-slaughter-for-slaughter/ProvinceSelectSlaughterForSlaughter"; +import { ProvinceUpdateSlaughterIdentity } from "../province-update-slaughter-identity/ProvinceUpdateSlaughterIdentity"; +import EditIcon from "@mui/icons-material/Edit"; +import axios from "axios"; +import { ProvinceUpdateKillerIdentity } from "../province-update-killer-identity/ProvinceUpdateKillerIdentity"; +import { RiFileExcel2Fill } from "react-icons/ri"; +import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl"; +import ResponsiveTable from "../../../../components/responsive-table/ResponsiveTable"; +export const ProvinceManageSlaughterKillplace = () => { + const dispatch = useDispatch(); + const [openNotif] = useContext(AppContext); + const [dataTable, setDataTable] = useState(); + const { provinceGetSlaughterhousesQuota } = useSelector( + (state) => state.provinceSlice + ); + + useEffect(() => { + dispatch(provinceGetSlaughterhousesQuotaService()); + dispatch(slaughterGetKillerKillhousesService()); + }, []); + + useEffect(() => { + const d = provinceGetSlaughterhousesQuota?.map((item, i) => { + const killhouseType = item?.killHouse?.killer ? "Killer" : "KillHouse"; + return [ + i + 1, + getRoleFromUrl() === "ProvinceOperator" ? ( + item?.killHouse?.killer ? ( + "کشتارکن" + ) : ( + "کشتارگاه" + ) + ) : ( + + ), + getRoleFromUrl() === "ProvinceOperator" ? ( + item?.killHouse?.killer ? ( + item?.killHouse?.type === "public" ? ( + "عمومی" + ) : ( + "اختصاصی" + ) + ) : ( + "-" + ) + ) : ( + + ), + + {item.killHouse?.name} + { + dispatch( + OPEN_MODAL({ + title: "ویرایش", + content: ( + + ), + }) + ); + }} + > + + + , + + + {item.killHouse?.killHouseOperator?.user?.fullname} ( + {item.killHouse?.killHouseOperator?.user?.mobile}) + + { + dispatch( + OPEN_MODAL({ + title: "ویرایش", + content: , + }) + ); + }} + > + + + , + item.killHouseVet + ? `${item.killHouseVet?.vet?.user?.fullname} (${item.killHouseVet?.vet?.user?.mobile})` + : "-", + `${item.killHouse?.systemAddress?.province?.name} - ${item.killHouse?.systemAddress?.city?.name} - ${item.killHouse?.systemAddress?.address}`, + item?.killHouse?.killer ? ( + + ) : ( + item.killHouse?.name + ), + , + ]; + }); + + setDataTable(d); + }, [provinceGetSlaughterhousesQuota]); + + return ( + + + + + + + + + + + + + + + + ); +}; + +const KillhouseStatus = ({ item }) => { + const dispatch = useDispatch(); + const [isChecked, setIsChecked] = useState(item.killHouse.active); + + const handleSwitchChange = (event) => { + setIsChecked(event.target.checked); + const apiUrl = `${axios.defaults.baseURL}kill_house/0/`; + + const postData = { + kill_house_key: item.killHouse.key, + active: event.target.checked, + }; + + axios + .put(apiUrl, postData) + .then(() => { + dispatch(provinceGetSlaughterhousesQuotaService()); + dispatch(slaughterGetKillerKillhousesService()); + dispatch(CLOSE_MODAL()); + }) + .catch((error) => { + console.error("Error:", error); + }); + }; + + return ( + + } + label={isChecked ? "فعال" : "غیرفعال"} + /> + ); +}; + +const EditKillhouseUnitName = ({ name, item }) => { + const dispatch = useDispatch(); + const [inputValue, setInputValue] = useState(name); + + const handleInputChange = (event) => { + setInputValue(event.target.value); + }; + + return ( + + + + + ); +}; + +const EditKillhouseOwner = ({ item }) => { + const dispatch = useDispatch(); + const [firstName, setFirstName] = useState( + item.killHouse?.killHouseOperator?.user?.firstName + ); + const [lastName, setLastName] = useState( + item.killHouse?.killHouseOperator?.user?.lastName + ); + const [mobile, setMobile] = useState( + item.killHouse?.killHouseOperator?.user?.mobile + ); + + const firstNameChange = (event) => { + setFirstName(event.target.value); + }; + + const lastNameChange = (event) => { + setLastName(event.target.value); + }; + + const mobileChange = (event) => { + setMobile(event.target.value); + }; + + return ( + + + + + + + ); +}; diff --git a/src/features/province/components/province-manage-slaughter-request/ProvinceManageSlaughterRequest.js b/src/features/province/components/province-manage-slaughter-request/ProvinceManageSlaughterRequest.js new file mode 100644 index 0000000..3814e9a --- /dev/null +++ b/src/features/province/components/province-manage-slaughter-request/ProvinceManageSlaughterRequest.js @@ -0,0 +1,273 @@ +import { Button, IconButton, TextField, Tooltip } from "@mui/material"; +import { useContext, useEffect, useState } from "react"; +import { useDispatch, useSelector } from "react-redux"; +import { Grid } from "../../../../components/grid/Grid"; +import { AppContext } from "../../../../contexts/AppContext"; +import DeleteIcon from "@mui/icons-material/Delete"; +import { + DRAWER, + LOADING_END, + LOADING_START, +} from "../../../../lib/redux/slices/appSlice"; +import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl"; +import { getSlaughtersKillRequestService } from "../../../city/services/get-slaughters-kill-request"; +import { slaughterDeleteRequest } from "../../../slaughter-house/services/slaughter-delete-request"; +import { InspectorKillHouseNewRequest } from "../../../inspector/components/inspector-killhouse-new-request/inspector-killhouse-new-request"; +import { SPACING } from "../../../../data/spacing"; +import { DatePicker } from "@mui/x-date-pickers"; +import moment from "moment/moment"; +import { formatJustDate, formatTime } from "../../../../utils/formatTime"; +import axios from "axios"; +import { RiFileExcel2Fill } from "react-icons/ri"; +import ResponsiveTable from "../../../../components/responsive-table/ResponsiveTable"; +import { provinceManageSlaughterRequestDashboard } from "../../services/province-manage-slaughter-request-dashboard"; + +export const ProvinceManageSlaughterRequest = () => { + const dispatch = useDispatch(); + const [ + openNotif, + , + selectedDate1, + setSelectedDate1, + selectedDate2, + setSelectedDate2, + ] = useContext(AppContext); + + useEffect(() => { + const currentDate = moment(new Date()).format("YYYY-MM-DD"); + setSelectedDate1(currentDate); + setSelectedDate2(currentDate); + }, []); + + const { getSlaughtersKillRequest } = useSelector((state) => state.citySlice); + + const [dataTableSlaughterRequests, setDataTableSlaughterRequests] = useState( + [] + ); + + // useEffect(() => { + // dispatch(poultryGetAutoRequestService()).then((r) => + // setAutoPoultryRequestChecked(r.payload.data[0]?.active) + // ); + // }, []); + + // const [autoPoultryRequestChecked, setAutoPoultryRequestChecked] = + // useState(false); + + // const handleChangeAutoPoultryRequestChecked = (event) => { + // setAutoPoultryRequestChecked(event.target.checked); + // dispatch(poultryAutoRequestService({ active: event.target.checked })); + // }; + + useEffect(() => { + dispatch(getSlaughtersKillRequestService({ selectedDate1, selectedDate2 })); + }, [selectedDate1, selectedDate2]); + + useEffect(() => { + const e = getSlaughtersKillRequest?.map((item, i) => { + return [ + i + 1, + item?.killHouse?.killer ? "کشتارکن" : "کشتارگاه", + `${item?.killHouse?.name} (${item.killHouse.killHouseOperator.user.mobile})`, + item?.slaughterHouse?.name + ? item?.slaughterHouse?.name + : "مکان کشتارگاه", + item?.killHouseVet + ? `${item?.killHouseVet?.vet?.user?.fullname} (${item?.killHouseVet?.vet?.user?.mobile})` + : "-", + formatTime(item?.createDate), + formatJustDate(item?.reciveDate), + item?.reciveTime, + item?.killCapacity?.toLocaleString(), + item?.remainQuantity?.toLocaleString(), + (item?.killCapacity - item?.remainQuantity).toLocaleString(), + + { + dispatch(LOADING_START()); + dispatch( + slaughterDeleteRequest({ + id: item.id, + }) + ).then((r) => { + dispatch(LOADING_END()); + if (r.error) { + if (r.error.message.includes("403")) { + openNotif({ + vertical: "top", + horizontal: "center", + msg: "این درخواست از سمت استان پذیرفته شده و قابل حذف نمی باشد!", + severity: "error", + }); + } else { + openNotif({ + vertical: "top", + horizontal: "center", + msg: "مشکلی پیش آمده است!", + severity: "error", + }); + } + } else { + dispatch( + getSlaughtersKillRequestService({ + selectedDate1, + selectedDate2, + }) + ); + + openNotif({ + vertical: "top", + horizontal: "center", + msg: "عملیات با موفقیت انجام شد.", + severity: "success", + }); + } + }); + }} + > + + , + ]; + }); + setDataTableSlaughterRequests(e); + }, [getSlaughtersKillRequest]); + + const [dashboardData, setDashboardData] = useState([]); + + useEffect(() => { + dispatch( + provinceManageSlaughterRequestDashboard({ + selectedDate1, + selectedDate2, + }) + ).then((r) => { + setDashboardData(r.payload.data); + }); + }, [selectedDate1, selectedDate2]); + + return ( + + + {(getRoleFromUrl() === "ProvinceOperator" || + getRoleFromUrl() === "SuperAdmin") && ( + + + + )} + + {/* {getRoleFromUrl() === "ProvinceOperator" && ( + + + } + label="ارسال درخواست کشتار ها بصورت خودکار" + labelPlacement="start" + /> + + )} */} + + + + ( + + )} + value={selectedDate1} + onChange={(e) => { + setSelectedDate1(moment(e).format("YYYY-MM-DD")); + }} + /> + + + ( + + )} + value={selectedDate2} + onChange={(e) => { + setSelectedDate2(moment(e).format("YYYY-MM-DD")); + }} + /> + + + + + + + + + + + + + + + ); +}; diff --git a/src/features/province/components/province-manage-slaughterhouse-quota/ProvinceManageSlaughterhouseQuota.js b/src/features/province/components/province-manage-slaughterhouse-quota/ProvinceManageSlaughterhouseQuota.js new file mode 100644 index 0000000..c8eec63 --- /dev/null +++ b/src/features/province/components/province-manage-slaughterhouse-quota/ProvinceManageSlaughterhouseQuota.js @@ -0,0 +1,57 @@ +import { TextField } from "@mui/material"; +import { useFormik } from "formik"; +import { useEffect } from "react"; +import { Grid } from "../../../../components/grid/Grid"; +import { Yup } from "../../../../lib/yup/yup"; + +const validationSchema = Yup.object({ + percent: Yup.number() + .typeError("لطفا عدد وارد کنید") + .min(0, "باید برابر یا بزرگتر از 0 باشد") + .max(100, "باید کوچکتر یا برابر با 100 باشد") + .required("درصد الزامی است"), +}); + +export const ProvinceManageSlaughterhouseQuota = ({ + percent, + slaughterKey, + onPercentChange, +}) => { + const formik = useFormik({ + initialValues: { + percent: percent, + }, + validationSchema: validationSchema, + onSubmit: (values) => { + // console.log(values); + }, + }); + + useEffect(() => { + formik.setFieldValue("percent", percent); + }, [percent]); + + return ( + + { + onPercentChange(slaughterKey, Number(e.target.value)); + formik.setFieldValue("percent", e.target.value); + }} + onBlur={formik.handleBlur} + error={formik.touched.percent && Boolean(formik.errors.percent)} + helperText={formik.touched.percent && formik.errors.percent} + InputProps={{ + startAdornment: %, + }} + inputProps={{ step: 0.1 }} + style={{ width: 100, textAlign: "center" }} + /> + + ); +}; diff --git a/src/features/province/components/province-manage-slaughters-car-state/ProvinceManageSlaughtersCarState.js b/src/features/province/components/province-manage-slaughters-car-state/ProvinceManageSlaughtersCarState.js new file mode 100644 index 0000000..c15b37c --- /dev/null +++ b/src/features/province/components/province-manage-slaughters-car-state/ProvinceManageSlaughtersCarState.js @@ -0,0 +1,24 @@ +import { Switch } from "@mui/material"; +import { useState } from "react"; +import { useDispatch } from "react-redux"; +import { provinceChangeSlaughterCarPermissionService } from "../../services/province-change-slaughter-car-permission"; +import { provinceGetOnlyKillHousesService } from "../../services/province-get-only-kill-houses"; + +export const ProvinceManageSlaughtersCarState = ({ state, killHouseKey }) => { + const dispatch = useDispatch(); + const [checked, setChecked] = useState(state); + + const handleToggle = () => { + setChecked(!checked); + dispatch( + provinceChangeSlaughterCarPermissionService({ + allow: !state, + kill_house_key: killHouseKey, + }) + ).then((r) => { + dispatch(provinceGetOnlyKillHousesService()); + }); + }; + + return ; +}; diff --git a/src/features/province/components/province-manage-slaughters/ProvinceManageSlaughters.js b/src/features/province/components/province-manage-slaughters/ProvinceManageSlaughters.js new file mode 100644 index 0000000..0870c2c --- /dev/null +++ b/src/features/province/components/province-manage-slaughters/ProvinceManageSlaughters.js @@ -0,0 +1,44 @@ +import { useEffect, useState } from "react"; +import { useDispatch, useSelector } from "react-redux"; +import { AdvancedTable } from "../../../../components/advanced-table/AdvancedTable"; +import { Grid } from "../../../../components/grid/Grid"; +import { provinceGetOnlyKillHousesService } from "../../services/province-get-only-kill-houses"; +import { ProvinceManageSlaughtersCarState } from "../province-manage-slaughters-car-state/ProvinceManageSlaughtersCarState"; + +export const ProvinceManageSlaughters = () => { + const dispatch = useDispatch(); + const [killhouses, setKillhouses] = useState([]); + + const { provinceGetOnlyKillHouses } = useSelector( + (state) => state.provinceSlice + ); + + useEffect(() => { + dispatch(provinceGetOnlyKillHousesService("kill_house")); + }, []); + + useEffect(() => { + const d = provinceGetOnlyKillHouses?.map((item) => { + return [ + item.killer ? "کشتارکن" : "کشتارگاه", + item.name, + , + ]; + }); + setKillhouses(d); + }, [provinceGetOnlyKillHouses]); + + return ( + + + + ); +}; diff --git a/src/features/province/components/province-manage-steward-allocations/ProvinceManageStewardAllocations.js b/src/features/province/components/province-manage-steward-allocations/ProvinceManageStewardAllocations.js new file mode 100644 index 0000000..2d4c7da --- /dev/null +++ b/src/features/province/components/province-manage-steward-allocations/ProvinceManageStewardAllocations.js @@ -0,0 +1,133 @@ +import { Typography } from "@mui/material"; +import { Grid } from "../../../../components/grid/Grid"; +import { SimpleTable } from "../../../../components/simple-table/SimpleTable"; +import { SPACING } from "../../../../data/spacing"; +import { useContext, useEffect, useState } from "react"; +import { SlaughterManageInventoryAllocationOperations } from "../../../slaughter-house/components/slaughter-manage-inventory-allocation-operations/SlaughterManageInventoryAllocationOperations"; +import { formatJustDate } from "../../../../utils/formatTime"; +import { useDispatch, useSelector } from "react-redux"; +import { slaughterManageInventoryAllocationsService } from "../../../slaughter-house/services/salughter-manage-inventory-allocations"; +import { AppContext } from "../../../../contexts/AppContext"; +import { useParams } from "react-router-dom"; + +export const ProvinceManageStewardAllocations = () => { + const dispatch = useDispatch(); + const { id } = useParams(); + const [inventoryAllocationsDataTable, setInventoryAllocationsDataTable] = + useState([]); + + const { slaughterManageInventoryAllocations } = useSelector( + (state) => state.slaughterSlice + ); + + const [, , selectedDate1] = useContext(AppContext); + + useEffect(() => { + dispatch( + slaughterManageInventoryAllocationsService({ + kill_house_key: id, + date: selectedDate1, + }) + ); + }, []); + + useEffect(() => { + const inventoryAllocationsData = slaughterManageInventoryAllocations?.map( + (item, i) => { + let sellType, sellerType; + if (item.sellerType === "guilds") { + sellerType = "صنف"; + } else if (item.sellerType === "steward") { + sellerType = "مباشر"; + } + + if (item.sellType === "free") { + sellType = "آزاد"; + } else { + if (item.type === "manual") { + sellType = "اختصاصی (دستی)"; + } else { + sellType = "اختصاصی (اتوماتیک)"; + } + } + + return [ + i + 1, + item?.guilds + ? item?.guilds?.guildsId + : item?.steward?.guilds?.guildsId, + formatJustDate(item.date), + sellerType, + sellType, + item?.guilds + ? item?.guilds?.guildsName + : item?.steward?.guilds?.guildsName, + item?.guilds + ? item?.guilds?.user.fullname + : item?.steward?.guilds?.user.fullname, + item?.guilds + ? item?.guilds?.user.nationalId + : item?.steward?.guilds?.user.nationalId, + item?.guilds + ? item?.guilds?.user.mobile + : item?.steward?.guilds?.user.mobile, + item?.guilds + ? item?.guilds?.typeActivity + : item?.steward?.guilds?.typeActivity, + item?.guilds + ? item?.guilds?.areaActivity + : item?.steward?.guilds?.areaActivity, + item?.guilds + ? item?.guilds?.licenseNumber + : item?.steward?.guilds?.licenseNumber, + item?.guilds + ? item?.guilds?.address.city.name + : item?.steward?.guilds?.address.city.name, + item?.numberOfCarcasses, + item?.weightOfCarcasses, + item?.loggedRegistrationCode ? item.loggedRegistrationCode : "-", + , + ]; + } + ); + + setInventoryAllocationsDataTable(inventoryAllocationsData); + }, [slaughterManageInventoryAllocations]); + + return ( + + + مدیریت کل تخصیصات + + } + columns={[ + "ردیف", + "شناسه صنف", + "تاریخ ثبت", + "ماهیت", + "نوع تخصیص", + "نام واحد صنفی", + "نام شخص/شرکت", + "کدملی", + "موبایل", + "نوع فعالیت", + "حوزه فعالیت", + "شماره مجوز", + "شهرستان", + "حجم لاشه", + "وزن لاشه", + "کداحراز", + "عملیات", + ]} + data={inventoryAllocationsDataTable} + /> + + ); +}; diff --git a/src/features/province/components/province-manage-trades-set-percents/ProvinceManageTradesSetPercents.js b/src/features/province/components/province-manage-trades-set-percents/ProvinceManageTradesSetPercents.js new file mode 100644 index 0000000..81dc310 --- /dev/null +++ b/src/features/province/components/province-manage-trades-set-percents/ProvinceManageTradesSetPercents.js @@ -0,0 +1,341 @@ +import React, { useState, useMemo, useContext, useEffect } from "react"; +import { Grid } from "../../../../components/grid/Grid"; +import { + TextField, + FormControl, + FormLabel, + RadioGroup, + FormControlLabel, + Radio, + Switch, + Button, +} from "@mui/material"; +import { useFormik } from "formik"; +import { Yup } from "../../../../lib/yup/yup"; +import { useDispatch } from "react-redux"; +import { provinceManageTradesEditPercents } from "../../services/province-manage-trades-edit-percents"; +import { AppContext } from "../../../../contexts/AppContext"; +import { CLOSE_MODAL } from "../../../../lib/redux/slices/appSlice"; + +export const ProvinceManageTradesSetPercents = ({ item, updateTable }) => { + const initialValues = { + market_capacity_percent: item?.marketCapacityPercent ?? 0, + market_light_capacity: item?.marketLightCapacity ?? false, + market_light_capacity_percent: item?.marketLightCapacityPercent ?? 0, + total_kill_capacity: item?.totalKillCapacity ?? 0, + total_kill_capacity_percent: item?.totalKillCapacityPercent ?? 0, + }; + + const dispatch = useDispatch(); + const [openNotif] = useContext(AppContext); + + const [isAbleToBuy, setIsAbleToBuy] = useState(item?.marketBuying || false); + const [hasLimit, setHasLimit] = useState( + item?.marketBuyingLimitation || false + ); + const [isPercentLimit, setIsPercentLimit] = useState( + item?.marketBuyingCapacityPercentStatus || false + ); + const [isLightCapacity, setIsLightCapacity] = useState( + Boolean(initialValues.market_light_capacity) + ); + + const getValidationSchema = (isAble, isLight) => + Yup.object({ + market_capacity_percent: + isAble && isPercentLimit + ? Yup.number() + .required("درصد خرید کل الزامی است") + .min(0, "حداقل مقدار 0 است") + .max(100, "حداکثر مقدار 100 است") + .typeError("فقط عدد مجاز است") + : Yup.number().notRequired(), + total_kill_capacity: + hasLimit && !isPercentLimit + ? Yup.number() + .required("سقف کشتار الزامی است!") + .typeError("فقط عدد مجاز است") + : Yup.number().notRequired(), + total_kill_capacity_percent: + hasLimit && !isPercentLimit + ? Yup.number() + .required("درصد از سقف کشتار الزامی است!") + .typeError("فقط عدد مجاز است") + .min(0, "حداقل مقدار 0 است") + .max(100, "حداکثر مقدار 100 است") + : Yup.number().notRequired(), + market_light_capacity_percent: + isAble && isLightCapacity && hasLimit + ? Yup.number() + .required("درصد خرید سبک الزامی است") + .min(0, "حداقل مقدار 0 است") + .max(100, "حداکثر مقدار 100 است") + .typeError("فقط عدد مجاز است") + : Yup.number().notRequired(), + }); + + const validationSchema = useMemo( + () => getValidationSchema(isAbleToBuy, isLightCapacity), + [isAbleToBuy, isLightCapacity, hasLimit, isPercentLimit] + ); + + useEffect(() => { + formik.validateForm(); + }, [isAbleToBuy, isLightCapacity, hasLimit, isPercentLimit]); + + const formik = useFormik({ + initialValues: { + market_capacity_percent: initialValues.market_capacity_percent ?? "", + total_kill_capacity: initialValues.total_kill_capacity ?? "", + total_kill_capacity_percent: + initialValues.total_kill_capacity_percent ?? "", + market_light_capacity_percent: + initialValues.market_light_capacity_percent ?? "", + }, + validationSchema, + validateOnBlur: true, + validateOnChange: true, + onSubmit: (values, helpers) => { + const cleaned = { + key: item?.key, + market_buying: isAbleToBuy, + market_buying_limitation: hasLimit, + // ...(!isPercentLimit ? { max_kill_limit: true } : {}), + market_buying_capacity_percent_status: + isAbleToBuy && hasLimit && isPercentLimit ? true : false, + market_capacity_percent: + isAbleToBuy && hasLimit && isPercentLimit + ? Number(values.market_capacity_percent) + : 0, + + total_kill_capacity_percent: + isAbleToBuy && hasLimit && !isPercentLimit + ? values?.total_kill_capacity_percent + : 0, + market_light_capacity: isLightCapacity, + market_light_capacity_percent: + isLightCapacity && hasLimit + ? Number(values.market_light_capacity_percent) + : 0, + }; + dispatch(provinceManageTradesEditPercents(cleaned)).then((r) => { + if (r.payload.error) { + openNotif({ + vertical: "top", + horizontal: "center", + msg: r.payload.error, + severity: "error", + }); + } else { + dispatch(CLOSE_MODAL()); + updateTable(); + openNotif({ + vertical: "top", + horizontal: "center", + msg: "عملیات با موفقیت انجام شد.", + severity: "success", + }); + } + }); + + helpers.setSubmitting(false); + }, + }); + + return ( + + + + + اجازه خرید + setIsAbleToBuy(e.target.value === "true")} + > + } label="دارد" /> + } + label="ندارد" + /> + + + + {isAbleToBuy && ( + + + + محدودیت کشتار + setHasLimit(e.target.value === "true")} + > + } + label="دارد" + /> + } + label="ندارد" + /> + + + + + {hasLimit && ( + + + نوع محدودیت + + + setIsPercentLimit(e.target.value === "true") + } + > + } + label="درصد از سقف کشتار" + /> + } + label="درصد از اعلام کشتارها" + /> + + + + )} + + {hasLimit && isPercentLimit && ( + + + + )} + {hasLimit && !isPercentLimit && ( + + + + )} + {hasLimit && !isPercentLimit && ( + + + + )} + + {hasLimit && ( + + + setIsLightCapacity(e.target.checked)} + name="market_light_capacity" + /> + } + label="اولویت خرید سبک" + /> + + + )} + + {isLightCapacity && hasLimit && ( + + + + )} + + )} + + + + + + ); +}; diff --git a/src/features/province/components/province-manage-trades/ProvinceManageTrades.js b/src/features/province/components/province-manage-trades/ProvinceManageTrades.js new file mode 100644 index 0000000..ed1efcd --- /dev/null +++ b/src/features/province/components/province-manage-trades/ProvinceManageTrades.js @@ -0,0 +1,173 @@ +import React, { useEffect, useState } from "react"; +import { Button, IconButton, TextField, Tooltip } from "@mui/material"; +import axios from "axios"; +import { RiSearchLine } from "react-icons/ri"; +import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl"; +import { + LOADING_END, + LOADING_START, + OPEN_MODAL, +} from "../../../../lib/redux/slices/appSlice"; +import { useDispatch } from "react-redux"; +import { Grid } from "../../../../components/grid/Grid"; +import ResponsiveTable from "../../../../components/responsive-table/ResponsiveTable"; +import InventoryIcon from "@mui/icons-material/Inventory"; +import { ProvinceManageTradesSetPercents } from "../province-manage-trades-set-percents/ProvinceManageTradesSetPercents"; + +export const ProvinceManageTrades = () => { + const handleTextChange = (event) => { + setTextValue(event.target.value); + }; + + const dispatch = useDispatch(); + + const [data, setData] = useState([]); + const [totalRows, setTotalRows] = useState(0); + const [perPage, setPerPage] = useState(10); + const [textValue, setTextValue] = useState(""); + const [page, setPage] = useState(1); + const [tableData, setTableData] = useState([]); + + const fetchApiData = async (page) => { + let response; + dispatch(LOADING_START()); + response = await axios.get( + `market-kill-houses/?search=filter&value=${textValue}&role=${getRoleFromUrl()}&page=${page}&page_size=${perPage}` + ); + dispatch(LOADING_END()); + setData(response.data.results); + setTotalRows(response.data.count); + }; + + const handlePageChange = (page) => { + fetchApiData(page); + setPage(page); + }; + + const handlePerRowsChange = (perRows) => { + setPerPage(perRows); + setPage(1); + }; + + const updateTable = () => { + fetchApiData(page !== 0 ? page : 1); + }; + + useEffect(() => { + const d = data?.map((item, i) => { + return [ + page === 1 ? i + 1 : i + perPage * (page - 1) + 1, + item?.name, + `${item?.fullname} (${item?.mobile})`, + item?.killer ? "کشتارکن" : "کشتارگاه", + item?.marketBuying ? "دارد" : "ندارد", + item?.totalKillCapacity?.toLocaleString(), + item?.totalKillCapacityPercent?.toLocaleString(), + `%${item?.marketCapacityPercent}`, + item?.marketLightCapacity ? "دارد" : "ندارد", + item?.marketLightCapacity + ? `%${item?.marketLightCapacityPercent}` + : "-", + + { + dispatch( + OPEN_MODAL({ + title: "تعیین درصد", + content: ( + + ), + }) + ); + }} + > + + + , + ]; + }); + + setTableData(d); + }, [data]); + + useEffect(() => { + fetchApiData(1); + }, [dispatch, perPage]); + + const handleSubmit = async (event) => { + event.preventDefault(); + dispatch(LOADING_START()); + + try { + const response = await axios.get( + `market-kill-houses/?role=${getRoleFromUrl()}&search=filter&value=${textValue}&page=${1}&page_size=${perPage}` + ); + setData(response.data.results); + setTotalRows(response.data.count); + dispatch(LOADING_END()); + } catch (error) { + console.error("Error fetching data:", error); + } + }; + + return ( + + + +
    + + + +
    +
    + + +
    + ); +}; diff --git a/src/features/province/components/province-manage-users/ProvinceManageUsers.js b/src/features/province/components/province-manage-users/ProvinceManageUsers.js new file mode 100644 index 0000000..af59cf9 --- /dev/null +++ b/src/features/province/components/province-manage-users/ProvinceManageUsers.js @@ -0,0 +1,175 @@ +import { + Button, + Chip, + Paper, + Table, + TableBody, + TableCell, + TableContainer, + TableHead, + TableRow, + Typography, +} from "@mui/material"; +import { useEffect, useState } from "react"; +import { useDispatch, useSelector } from "react-redux"; +import { Grid } from "../../../../components/grid/Grid"; +import { SPACING } from "../../../../data/spacing"; +import { formatJustDate } from "../../../../utils/formatTime"; +import { getFaUserRole } from "../../../../utils/getFaUserRole"; +import { provinceGetManageUsersService } from "../../services/province-get-manage-users"; +// import { useSelector } from "react-redux"; +// import { provinceGetManageUsersService } from "../../services/province-get-manage-users"; +import { ProvinceManageUsersRow } from "./ProvinceManageUsersRow"; + +function createData( + image, + userRoles, + userKey, + name, + nationalCode, + phone, + birthDate, + password, + identityDocuments, + rolesTitle, + userState, + rolesData +) { + return { + image, + userRoles, + userKey, + name, + nationalCode, + phone, + birthDate, + password, + identityDocuments, + rolesTitle, + userState, + rolesData, + }; +} + +// const rows = [ +// createData( +// "Frozen yoghurt", +// "4061112233", +// "تلفن", +// "تاریخ تولد", +// "رمزعبور", +// "اسناد", +// "نقش های کاربر", +// "وضعیت" +// ), +// createData( +// "Frozen yoghurt", +// "4061112233", +// "تلفن", +// "تاریخ تولد", +// "رمزعبور", +// "اسناد", +// "نقش های کاربر", +// "وضعیت" +// ), +// createData( +// "Frozen yoghurt", +// "4061112233", +// "تلفن", +// "تاریخ تولد", +// "رمزعبور", +// "اسناد", +// "نقش های کاربر", +// "وضعیت" +// ), +// createData( +// "Frozen yoghurt", +// "4061112233", +// "تلفن", +// "تاریخ تولد", +// "رمزعبور", +// "اسناد", +// "نقش های کاربر", +// "وضعیت" +// ), +// ]; + +export const ProvinceManageUsers = () => { + const dispatch = useDispatch(); + const [tableData, setTableData] = useState([]); + + const { provinceGetManageUsers } = useSelector( + (state) => state.provinceSlice + ); + + useEffect(() => { + dispatch(provinceGetManageUsersService()); + }, []); + + useEffect(() => { + const temp = provinceGetManageUsers?.map((user) => { + const rolesTransformed = user.role?.map((item, i) => ( + + )); + return createData( + user.image, + user.role?.map((item) => item.name), + user.key, + user.fullname, + user.nationalId ? user.nationalId : "-", + user.mobile, + user.birthday ? formatJustDate(user.birthday) : "-", + user.password, + "-", + + {rolesTransformed} + , + user.active, + user.rolesData + ); + }); + + setTableData(temp); + }, [provinceGetManageUsers]); + + return ( + <> + + مدیریت کاربران + + + + + + + + نام و نام خانوادگی + کدملی + تلفن همراه + تاریخ تولد + رمزعبور + اسناد هویتی + نقش ها + وضعیت + عملیات + + + + {tableData?.map((row) => ( + + ))} + +
    +
    + + ); +}; diff --git a/src/features/province/components/province-manage-users/ProvinceManageUsersRoles.js b/src/features/province/components/province-manage-users/ProvinceManageUsersRoles.js new file mode 100644 index 0000000..91f34a0 --- /dev/null +++ b/src/features/province/components/province-manage-users/ProvinceManageUsersRoles.js @@ -0,0 +1,450 @@ +import { + Table, + TableCell, + TableHead, + TableRow, + Typography, +} from "@mui/material"; +import { useEffect, useState } from "react"; +import { useDispatch } from "react-redux"; +import { Grid } from "../../../../components/grid/Grid"; +import { SPACING } from "../../../../data/spacing"; +import { provinceGetManageUsersRolesService } from "../../services/province-get-manage-users-roles"; +import { ProvinceManageUsersRowAdmin } from "./ProvinceManageUsersRowAdmin"; +import { ProvinceManageUsersRowCityOperator } from "./ProvinceManageUsersRowCityOperator"; +import { ProvinceManageUsersRowDriver } from "./ProvinceManageUsersRowDriver"; +import { ProvinceManageUsersRowKillhouseVet } from "./ProvinceManageUsersRowDriverKillhouseVet"; +import { ProvinceManageUsersRowVetFarm } from "./ProvinceManageUsersRowDriverVetFarm"; +import { ProvinceManageUsersRowFinancialOperator } from "./ProvinceManageUsersRowFinancialOperator"; +import { ProvinceManageUsersRowInspectorOperator } from "./ProvinceManageUsersRowInspectorOperator"; +import { ProvinceManageUsersRowJahadCity } from "./ProvinceManageUsersRowJahadCity"; +import { ProvinceManageUsersRowJahadProvince } from "./ProvinceManageUsersRowJahadProvince"; +import { ProvinceManageUsersRowKillHouse } from "./ProvinceManageUsersRowKillHouse"; +import { ProvinceManageUsersRowPoultry } from "./ProvinceManageUsersRowPoultry"; +import { ProvinceManageUsersRowProvinceOperator } from "./ProvinceManageUsersRowProvinceOperator"; + +export const ProvinceManageUsersRoles = ({ userRoles, row }) => { + const dispatch = useDispatch(); + const [data, setData] = useState(); + + useEffect(() => { + dispatch( + provinceGetManageUsersRolesService({ userProfileKey: row.userKey }) + ).then((r) => setData(r.payload.data)); + }, []); + + const poultries = data?.filter((item) => item.roleName === "Poultry"); + const killHouses = data?.filter((item) => item.roleName === "KillHouse"); + const cityOperators = data?.filter( + (item) => item.roleName === "CityOperator" + ); + const provinceOperators = data?.filter( + (item) => item.roleName === "ProvinceOperator" + ); + const financialOperators = data?.filter( + (item) => item.roleName === "ProvinceFinancial" + ); + const drivers = data?.filter((item) => item.roleName === "Driver"); + const killhouseVet = data?.filter((item) => item.roleName === "KillHouseVet"); + const vetFarm = data?.filter((item) => item.roleName === "VetFarm"); + const provinceInspector = data?.filter( + (item) => item.roleName === "ProvinceInspector" + ); + const jahadProvince = data?.filter((item) => item.roleName === "Jahad"); + const jahadCity = data?.filter((item) => item.roleName === "CityJahad"); + const admin = data?.filter((item) => item.roleName === "Admin"); + + return ( + <> + {!!poultries?.length && ( + + + نقش های مرغدار + + + + + شناسه یکتا + نام مرغداری + تعاونی + استان + شهر + آدرس + تعداد سالن + ظرفیت (قطعه) + اسناد هویتی + اطلاعات بانکی + وضعیت + + + {poultries.map((item, i) => { + return ( + + ); + })} +
    +
    + )} + {!!killHouses?.length && ( + + + نقش کشتارگاه + + + + + نام کشتارگاه + استان + شهر + آدرس + ظرفیت + کشتارکن ها + اسناد هویتی + اطلاعات بانکی + وضعیت + + + {killHouses.map((item, i) => { + return ( + + ); + })} +
    +
    + )} + {!!cityOperators?.length && ( + + + نقش شهرستان + + + + + تعاونی + استان + شهر + آدرس + اسناد هویتی + اطلاعات بانکی + + + {cityOperators.map((item, i) => { + return ( + + ); + })} +
    +
    + )} + {!!provinceOperators?.length && ( + + + نقش اپراتور تخصیص + + + + + استان + شهر + آدرس + اسناد هویتی + اطلاعات بانکی + + + {provinceOperators.map((item, i) => { + return ( + + ); + })} +
    +
    + )} + {!!financialOperators?.length && ( + + + نقش اپراتور مالی + + + + + استان + شهر + آدرس + اسناد هویتی + اطلاعات بانکی + + + {financialOperators.map((item, i) => { + return ( + + ); + })} +
    +
    + )} + {!!drivers?.length && ( + + + نقش راننده + + + + + نام و نام خانوادگی + تلفن راننده + مدل خودرو + ظرفیت + کدبهداشتی + شماره پلاک + اطلاعات بانکی + اسناد هویتی + زیرمجموعه کشتارگاه + وضعیت + + + {drivers.map((item, i) => { + return ( + + ); + })} +
    +
    + )} + {!!killhouseVet?.length && ( + + + نقش دامپزشک کشتارگاه + + + + + استان + شهر + آدرس + اسناد هویتی + کشتارگاه زیرمجموعه + اطلاعات بانکی + وضعیت + + + {killhouseVet.map((item, i) => { + return ( + + ); + })} +
    +
    + )} + {!!vetFarm?.length && ( + + + نقش دامپزشک فارم + + + + + استان + شهر + آدرس + اسناد هویتی + اطلاعات بانکی + وضعیت + + + {vetFarm.map((item, i) => { + return ( + + ); + })} +
    +
    + )} + {!!provinceInspector?.length && ( + + + نقش بازرس + + + + + استان + شهر + آدرس + اسناد هویتی + وضعیت + + + {provinceInspector.map((item, i) => { + return ( + + ); + })} +
    +
    + )} + {!!jahadProvince?.length && ( + + + نقش جهاد استان + + + + + استان + شهر + آدرس + اطلاعات بانکی + اسناد هویتی + وضعیت + + + {jahadProvince.map((item, i) => { + return ( + + ); + })} +
    +
    + )} + {!!jahadCity?.length && ( + + + نقش جهاد شهرستان + + + + + استان + شهر + آدرس + اطلاعات بانکی + اسناد هویتی + وضعیت + + + {jahadCity.map((item, i) => { + return ( + + ); + })} +
    +
    + )} + {!!admin?.length && ( + + + نقش ادمین استان + + + + + استان + شهر + آدرس + اسناد هویتی + وضعیت + + + {admin.map((item, i) => { + return ( + + ); + })} +
    +
    + )} + + ); +}; diff --git a/src/features/province/components/province-manage-users/ProvinceManageUsersRow.js b/src/features/province/components/province-manage-users/ProvinceManageUsersRow.js new file mode 100644 index 0000000..26d4383 --- /dev/null +++ b/src/features/province/components/province-manage-users/ProvinceManageUsersRow.js @@ -0,0 +1,66 @@ +import { + Avatar, + Button, + Collapse, + IconButton, + Switch, + TableCell, + TableRow, +} from "@mui/material"; +import KeyboardArrowDownIcon from "@mui/icons-material/KeyboardArrowDown"; +import KeyboardArrowUpIcon from "@mui/icons-material/KeyboardArrowUp"; +import { useState } from "react"; +import { ProvinceManageUsersRoles } from "./ProvinceManageUsersRoles"; +// import { useDispatch } from "react-redux"; +// import { provinceGetManageUsersRolesService } from "../../services/province-get-manage-users-roles"; + +export function ProvinceManageUsersRow(props) { + const { row } = props; + const [open, setOpen] = useState(false); + + const [checked, setChecked] = useState(row.userState); + + const handleChange = () => { + setChecked(!checked); + }; + + return ( + <> + *": { borderBottom: "unset" } }}> + + setOpen(!open)} + > + {open ? : } + + + + {row.image && } + {row.name} + + {row.nationalCode} + {row.phone} + {row.birthDate} + {row.password} + {row.identityDocuments} + {row.rolesTitle} + + + + + + + + + + + + + + + + + ); +} diff --git a/src/features/province/components/province-manage-users/ProvinceManageUsersRowAdmin.js b/src/features/province/components/province-manage-users/ProvinceManageUsersRowAdmin.js new file mode 100644 index 0000000..d78f478 --- /dev/null +++ b/src/features/province/components/province-manage-users/ProvinceManageUsersRowAdmin.js @@ -0,0 +1,25 @@ +import { Switch, TableBody, TableCell, TableRow } from "@mui/material"; +import { useState } from "react"; + +export const ProvinceManageUsersRowAdmin = ({ row, item }) => { + const { details } = item; + const [checked, setChecked] = useState(details.active); + + const handleChange = () => { + setChecked(!checked); + }; + + return ( + + + {details.address.province.name} + {details.address.city.name} + {details.address.address} + {details.identityDocuments} + + + + + + ); +}; diff --git a/src/features/province/components/province-manage-users/ProvinceManageUsersRowCityOperator.js b/src/features/province/components/province-manage-users/ProvinceManageUsersRowCityOperator.js new file mode 100644 index 0000000..ed7e5f8 --- /dev/null +++ b/src/features/province/components/province-manage-users/ProvinceManageUsersRowCityOperator.js @@ -0,0 +1,34 @@ +import { TableBody, TableCell, TableRow } from "@mui/material"; +import { Grid } from "../../../../components/grid/Grid"; + +export const ProvinceManageUsersRowCityOperator = ({ row, item }) => { + const { details } = item; + + return ( + + {/* {row.userRoles.map((userRolesRow) => ( */} + + + {details.unitName} + + {details.address.province.name} + {details.address.city.name} + {details.address.address} + {details.identityDocuments} + + {details.userBankInfo && details.userBankInfo.bankName ? ( + + نام بانک: {details.userBankInfo.bankName} + شماره کارت: {details.userBankInfo.card} + شماره حساب: {details.userBankInfo.account} + شبا: {details.userBankInfo.shaba} + + ) : ( + "-" + )} + + + {/* ))} */} + + ); +}; diff --git a/src/features/province/components/province-manage-users/ProvinceManageUsersRowDriver.js b/src/features/province/components/province-manage-users/ProvinceManageUsersRowDriver.js new file mode 100644 index 0000000..f50ecba --- /dev/null +++ b/src/features/province/components/province-manage-users/ProvinceManageUsersRowDriver.js @@ -0,0 +1,46 @@ +import { Switch, TableBody, TableCell, TableRow } from "@mui/material"; +import { useState } from "react"; +import { Grid } from "../../../../components/grid/Grid"; + +export const ProvinceManageUsersRowDriver = ({ row, item }) => { + const { details } = item; + + const [checked, setChecked] = useState(details.active); + + const handleChange = () => { + setChecked(!checked); + }; + + return ( + + + {details.driverName} + {details.driverMobile} + {details.typeCar} + + {details.capocity.toLocaleString()} + + {details.healthCode} + {details.pelak} + + {details.userBankInfo && details.userBankInfo.bankName ? ( + + نام بانک: {details.userBankInfo.bankName} + شماره کارت: {details.userBankInfo.card} + شماره حساب: {details.userBankInfo.account} + شبا: {details.userBankInfo.shaba} + + ) : ( + "-" + )} + + {details.identityDocuments} + - + + + + + {/* ))} */} + + ); +}; diff --git a/src/features/province/components/province-manage-users/ProvinceManageUsersRowDriverKillhouseVet.js b/src/features/province/components/province-manage-users/ProvinceManageUsersRowDriverKillhouseVet.js new file mode 100644 index 0000000..4d6b8f8 --- /dev/null +++ b/src/features/province/components/province-manage-users/ProvinceManageUsersRowDriverKillhouseVet.js @@ -0,0 +1,43 @@ +import { Switch, TableBody, TableCell, TableRow } from "@mui/material"; +import { useState } from "react"; +import { Grid } from "../../../../components/grid/Grid"; + +export const ProvinceManageUsersRowKillhouseVet = ({ row, item }) => { + const { details } = item; + + const [checked, setChecked] = useState(details.vet.active); + + const handleChange = () => { + setChecked(!checked); + }; + + return ( + + + + {details.vet.address.province.name} + + {details.vet.address.city.name} + {details.vet.address.address} + {details.vet.identityDocuments} + {details.killHouse.name} + + {details.vet.userBankInfo && details.vet.userBankInfo.bankName ? ( + + نام بانک: {details.vet.userBankInfo.bankName} + شماره کارت: {details.vet.userBankInfo.card} + شماره حساب: {details.vet.userBankInfo.account} + شبا: {details.vet.userBankInfo.shaba} + + ) : ( + "-" + )} + + + + + + {/* ))} */} + + ); +}; diff --git a/src/features/province/components/province-manage-users/ProvinceManageUsersRowDriverVetFarm.js b/src/features/province/components/province-manage-users/ProvinceManageUsersRowDriverVetFarm.js new file mode 100644 index 0000000..690783a --- /dev/null +++ b/src/features/province/components/province-manage-users/ProvinceManageUsersRowDriverVetFarm.js @@ -0,0 +1,39 @@ +import { Switch, TableBody, TableCell, TableRow } from "@mui/material"; +import { useState } from "react"; +import { Grid } from "../../../../components/grid/Grid"; + +export const ProvinceManageUsersRowVetFarm = ({ row, item }) => { + const { details } = item; + + const [checked, setChecked] = useState(details?.active); + + const handleChange = () => { + setChecked(!checked); + }; + + return ( + + + {details.address.province.name} + {details.address.city.name} + {details.address.address} + {details.identityDocuments} + + {details.userBankInfo && details.userBankInfo.bankName ? ( + + نام بانک: {details.userBankInfo.bankName} + شماره کارت: {details.userBankInfo.card} + شماره حساب: {details.userBankInfo.account} + شبا: {details.userBankInfo.shaba} + + ) : ( + "-" + )} + + + + + + + ); +}; diff --git a/src/features/province/components/province-manage-users/ProvinceManageUsersRowFinancialOperator.js b/src/features/province/components/province-manage-users/ProvinceManageUsersRowFinancialOperator.js new file mode 100644 index 0000000..5504860 --- /dev/null +++ b/src/features/province/components/province-manage-users/ProvinceManageUsersRowFinancialOperator.js @@ -0,0 +1,31 @@ +import { TableBody, TableCell, TableRow } from "@mui/material"; +import { Grid } from "../../../../components/grid/Grid"; + +export const ProvinceManageUsersRowFinancialOperator = ({ row, item }) => { + const { details } = item; + + return ( + + {/* {row.userRoles.map((userRolesRow) => ( */} + + {details.address.province.name} + {details.address.city.name} + {details.address.address} + {details.identityDocuments} + + {details.userBankInfo && details.userBankInfo.bankName ? ( + + نام بانک: {details.userBankInfo.bankName} + شماره کارت: {details.userBankInfo.card} + شماره حساب: {details.userBankInfo.account} + شبا: {details.userBankInfo.shaba} + + ) : ( + "-" + )} + + + {/* ))} */} + + ); +}; diff --git a/src/features/province/components/province-manage-users/ProvinceManageUsersRowInspectorOperator.js b/src/features/province/components/province-manage-users/ProvinceManageUsersRowInspectorOperator.js new file mode 100644 index 0000000..1aacf2b --- /dev/null +++ b/src/features/province/components/province-manage-users/ProvinceManageUsersRowInspectorOperator.js @@ -0,0 +1,27 @@ +import { Switch, TableBody, TableCell, TableRow } from "@mui/material"; +import { useState } from "react"; + +export const ProvinceManageUsersRowInspectorOperator = ({ row, item }) => { + const { details } = item; + const [checked, setChecked] = useState(details.active); + + const handleChange = () => { + setChecked(!checked); + }; + + return ( + + {/* {row.userRoles.map((userRolesRow) => ( */} + + {details.address.province.name} + {details.address.city.name} + {details.address.address} + {details.identityDocuments} + + + + + {/* ))} */} + + ); +}; diff --git a/src/features/province/components/province-manage-users/ProvinceManageUsersRowJahadCity.js b/src/features/province/components/province-manage-users/ProvinceManageUsersRowJahadCity.js new file mode 100644 index 0000000..3cf25b2 --- /dev/null +++ b/src/features/province/components/province-manage-users/ProvinceManageUsersRowJahadCity.js @@ -0,0 +1,38 @@ +import { Switch, TableBody, TableCell, TableRow } from "@mui/material"; +import { useState } from "react"; +import { Grid } from "../../../../components/grid/Grid"; + +export const ProvinceManageUsersRowJahadCity = ({ row, item }) => { + const { details } = item; + const [checked, setChecked] = useState(details.active); + + const handleChange = () => { + setChecked(!checked); + }; + + return ( + + + {details.address.province.name} + {details.address.city.name} + {details.address.address} + {details.identityDocuments} + + {details.userBankInfo && details.userBankInfo.bankName ? ( + + نام بانک: {details.userBankInfo.bankName} + شماره کارت: {details.userBankInfo.card} + شماره حساب: {details.userBankInfo.account} + شبا: {details.userBankInfo.shaba} + + ) : ( + "-" + )} + + + + + + + ); +}; diff --git a/src/features/province/components/province-manage-users/ProvinceManageUsersRowJahadProvince.js b/src/features/province/components/province-manage-users/ProvinceManageUsersRowJahadProvince.js new file mode 100644 index 0000000..392f808 --- /dev/null +++ b/src/features/province/components/province-manage-users/ProvinceManageUsersRowJahadProvince.js @@ -0,0 +1,40 @@ +import { Switch, TableBody, TableCell, TableRow } from "@mui/material"; +import { useState } from "react"; +import { Grid } from "../../../../components/grid/Grid"; + +export const ProvinceManageUsersRowJahadProvince = ({ row, item }) => { + const { details } = item; + const [checked, setChecked] = useState(details.active); + + const handleChange = () => { + setChecked(!checked); + }; + + return ( + + {/* {row.userRoles.map((userRolesRow) => ( */} + + {details.address.province.name} + {details.address.city.name} + {details.address.address} + {details.identityDocuments} + + {details.userBankInfo && details.userBankInfo.bankName ? ( + + نام بانک: {details.userBankInfo.bankName} + شماره کارت: {details.userBankInfo.card} + شماره حساب: {details.userBankInfo.account} + شبا: {details.userBankInfo.shaba} + + ) : ( + "-" + )} + + + + + + {/* ))} */} + + ); +}; diff --git a/src/features/province/components/province-manage-users/ProvinceManageUsersRowKillHouse.js b/src/features/province/components/province-manage-users/ProvinceManageUsersRowKillHouse.js new file mode 100644 index 0000000..5230706 --- /dev/null +++ b/src/features/province/components/province-manage-users/ProvinceManageUsersRowKillHouse.js @@ -0,0 +1,57 @@ +import { Switch, TableBody, TableCell, TableRow } from "@mui/material"; +import { useState } from "react"; +import { Grid } from "../../../../components/grid/Grid"; + +export const ProvinceManageUsersRowKillHouse = ({ row, item }) => { + const { details } = item; + + const [checked, setChecked] = useState(details.active); + + const handleChange = () => { + setChecked(!checked); + }; + + return ( + + {/* {row.userRoles.map((userRolesRow) => ( */} + + + {details.name} + + + {details.systemAddress.province.name} + + {details.systemAddress.city.name} + {details.systemAddress.address} + + {details.capacity.toLocaleString()} + + {"-"} + {details.identityDocuments} + + {details.killHouseOperator.userBankInfo && + details.killHouseOperator.userBankInfo.bankName ? ( + + + نام بانک: {details.killHouseOperator.userBankInfo.bankName} + + + شماره کارت: {details.killHouseOperator.userBankInfo.card} + + + شماره حساب: {details.killHouseOperator.userBankInfo.account} + + شبا: {details.killHouseOperator.userBankInfo.shaba} + + ) : ( + "-" + )} + + + + + + {/* ))} */} + + ); +}; diff --git a/src/features/province/components/province-manage-users/ProvinceManageUsersRowPoultry.js b/src/features/province/components/province-manage-users/ProvinceManageUsersRowPoultry.js new file mode 100644 index 0000000..6af53f2 --- /dev/null +++ b/src/features/province/components/province-manage-users/ProvinceManageUsersRowPoultry.js @@ -0,0 +1,52 @@ +import { Switch, TableBody, TableCell, TableRow } from "@mui/material"; +import { useState } from "react"; +import { Grid } from "../../../../components/grid/Grid"; + +export const ProvinceManageUsersRowPoultry = ({ row, item }) => { + const { details } = item; + + const [checked, setChecked] = useState(details.active); + + const handleChange = () => { + setChecked(!checked); + }; + + return ( + + {/* {row.userRoles.map((userRolesRow) => ( */} + + + {details.breedingUniqueId} + + {details.unitName} + + {details.cityOperator ? details.cityOperator : "-"} + + {details.address.province.name} + {details.address.city.name} + {details.address.address} + {details.numberOfHalls} + + {details.totalCapacity.toLocaleString()} + + - + + {details.userBankInfo && details.userBankInfo.bankName ? ( + + نام بانک: {details.userBankInfo.bankName} + شماره کارت: {details.userBankInfo.card} + شماره حساب: {details.userBankInfo.account} + شبا: {details.userBankInfo.shaba} + + ) : ( + "-" + )} + + + + + + {/* ))} */} + + ); +}; diff --git a/src/features/province/components/province-manage-users/ProvinceManageUsersRowProvinceOperator.js b/src/features/province/components/province-manage-users/ProvinceManageUsersRowProvinceOperator.js new file mode 100644 index 0000000..71a5f45 --- /dev/null +++ b/src/features/province/components/province-manage-users/ProvinceManageUsersRowProvinceOperator.js @@ -0,0 +1,31 @@ +import { TableBody, TableCell, TableRow } from "@mui/material"; +import { Grid } from "../../../../components/grid/Grid"; + +export const ProvinceManageUsersRowProvinceOperator = ({ row, item }) => { + const { details } = item; + + return ( + + {/* {row.userRoles.map((userRolesRow) => ( */} + + {details.address.province.name} + {details.address.city.name} + {details.address.address} + {details.identityDocuments} + + {details.userBankInfo && details.userBankInfo.bankName ? ( + + نام بانک: {details.userBankInfo.bankName} + شماره کارت: {details.userBankInfo.card} + شماره حساب: {details.userBankInfo.account} + شبا: {details.userBankInfo.shaba} + + ) : ( + "-" + )} + + + {/* ))} */} + + ); +}; diff --git a/src/features/province/components/province-manage-warehouse-limitation/ProvinceManageWarehouseLimitation.js b/src/features/province/components/province-manage-warehouse-limitation/ProvinceManageWarehouseLimitation.js new file mode 100644 index 0000000..8764da3 --- /dev/null +++ b/src/features/province/components/province-manage-warehouse-limitation/ProvinceManageWarehouseLimitation.js @@ -0,0 +1,247 @@ +import React, { useContext, useState } from "react"; +import { AppContext } from "../../../../contexts/AppContext"; +import { Grid } from "../../../../components/grid/Grid"; +import { Button, Switch, TextField, Typography } from "@mui/material"; +import { provinceUpdateKillerIdentityService } from "../../services/province-update-killer-identity"; +import { useDispatch } from "react-redux"; + +export const ProvinceManageWarehouseLimitation = ({ item, fetchdata }) => { + const [openNotif] = useContext(AppContext); + + const dispatch = useDispatch(); + + // Weight limitation states + const [weightLimitEnabled, setWeightLimitEnabled] = useState( + item?.wareHouseRemainingWeightLimitationStatus || false + ); + const [weightLimit, setWeightLimit] = useState( + item?.wareHouseRemainingWeightLimitation || "" + ); + + // Percent limitation states + const [percentLimitEnabled, setPercentLimitEnabled] = useState( + item?.wareHouseRemainingPercentLimitationStatus || false + ); + const [percentLimit, setPercentLimit] = useState( + item?.wareHouseRemainingPercentLimitation || "" + ); + + const handleWeightToggle = () => { + setWeightLimitEnabled(!weightLimitEnabled); + }; + + const handlePercentToggle = () => { + setPercentLimitEnabled(!percentLimitEnabled); + }; + + const handleSubmit = () => { + dispatch( + provinceUpdateKillerIdentityService({ + kill_house_key: item?.key, + ware_house_remaining_weight_limitation_status: weightLimitEnabled, + ware_house_remaining_weight_limitation: weightLimitEnabled + ? weightLimit + : 0, + ware_house_remaining_percent_limitation_status: percentLimitEnabled, + ware_house_remaining_percent_limitation: percentLimitEnabled + ? percentLimit + : 0, + }) + ).then((r) => { + if (r.payload.error) { + openNotif({ + vertical: "top", + horizontal: "center", + msg: r.payload.error, + severity: "error", + }); + } else { + fetchdata(); + openNotif({ + vertical: "top", + horizontal: "center", + msg: "محدودیت‌های انبار با موفقیت ویرایش شد.", + severity: "success", + }); + } + }); + }; + + return ( + + + + محدودیت سقف انبار + + + + {/* Weight Limitation Section */} + + + + + + + + محدودیت مانده انبار + + + + + {weightLimitEnabled && ( + + + setWeightLimit(e.target.value)} + size="small" + inputProps={{ min: 0 }} + sx={{ + "& .MuiInputLabel-root": { + fontSize: { xs: "0.875rem", sm: "1rem" }, + }, + "& .MuiInputBase-input": { + fontSize: { xs: "0.875rem", sm: "1rem" }, + }, + }} + /> + + + )} + + + {/* Percent Limitation Section */} + + + + + + + + محدودیت مانده کشتار روزانه + + + + + {percentLimitEnabled && ( + + + setPercentLimit(e.target.value)} + size="small" + inputProps={{ min: 0, max: 100 }} + sx={{ + "& .MuiInputLabel-root": { + fontSize: { xs: "0.875rem", sm: "1rem" }, + }, + "& .MuiInputBase-input": { + fontSize: { xs: "0.875rem", sm: "1rem" }, + }, + }} + /> + + + )} + + + {/* Submit Button */} + + + + + ); +}; diff --git a/src/features/province/components/province-management-maximum-load/ProvinceManagementMaximumLoad.js b/src/features/province/components/province-management-maximum-load/ProvinceManagementMaximumLoad.js new file mode 100644 index 0000000..59e309e --- /dev/null +++ b/src/features/province/components/province-management-maximum-load/ProvinceManagementMaximumLoad.js @@ -0,0 +1,111 @@ +import React, { useContext } from "react"; +import { Button, TextField, Typography } from "@mui/material"; +import { useFormik } from "formik"; +import * as yup from "yup"; +import { AppContext } from "../../../../contexts/AppContext"; +import { useDispatch } from "react-redux"; +import { provinceUpdateKillerIdentityService } from "../../services/province-update-killer-identity"; + +const validationSchema = yup.object({ + maximumIncrease: yup + .number() + .typeError("لطفا یک عدد وارد کنید") + .min(0, "عددی بین 0 تا 100 وارد کنید!") + .max(100, "عددی بین 0 تا 100 وارد کنید!") + .required("این فیلد اجباری است"), + maximumDecrease: yup + .number() + .typeError("لطفا یک عدد وارد کنید") + .min(0, "عددی بین 0 تا 100 وارد کنید!") + .max(100, "عددی بین 0 تا 100 وارد کنید!") + .required("این فیلد اجباری است"), +}); + +export const ProvinceManagementMaximumLoad = ({ item, fetchdata }) => { + const [openNotif] = useContext(AppContext); + const dispatch = useDispatch(); + const formik = useFormik({ + initialValues: { + maximumIncrease: item?.maximumLoadVolumeIncrease || 0, + maximumDecrease: item?.maximumLoadVolumeReduction || 0, + }, + validationSchema: validationSchema, + onSubmit: (values) => { + dispatch( + provinceUpdateKillerIdentityService({ + kill_house_key: item?.key, + maximum_load_volume_increase: values.maximumIncrease, + maximum_load_volume_reduction: values.maximumDecrease, + }) + ).then((r) => { + if (r.payload.error) { + openNotif({ + vertical: "top", + horizontal: "center", + msg: r.payload.error, + severity: "error", + }); + } else { + fetchdata(); + openNotif({ + vertical: "top", + horizontal: "center", + msg: "عملیات با موفقیت انجام شد.", + severity: "success", + }); + } + }); + }, + }); + + return ( +
    + + درصد افزایش/کاهش حجم ورود اطلاعات بار + + + + + + + + ); +}; diff --git a/src/features/province/components/province-mandatory-slaughterhouse-verification-code/ProvinceMandatorySlaughterhouseVerificationCode.js b/src/features/province/components/province-mandatory-slaughterhouse-verification-code/ProvinceMandatorySlaughterhouseVerificationCode.js new file mode 100644 index 0000000..96354a4 --- /dev/null +++ b/src/features/province/components/province-mandatory-slaughterhouse-verification-code/ProvinceMandatorySlaughterhouseVerificationCode.js @@ -0,0 +1,111 @@ +import { FormControlLabel, Radio, Typography } from "@mui/material"; +import { useContext, useEffect, useState } from "react"; +import { useDispatch } from "react-redux"; +import axios from "axios"; +import { Grid } from "../../../../components/grid/Grid"; +import { + LOADING_END, + LOADING_START, +} from "../../../../lib/redux/slices/appSlice"; +import { AppContext } from "../../../../contexts/AppContext"; + +export const ProvinceMandatorySlaughterhouseVerificationCode = () => { + const [isActive, setIsActive] = useState(false); + const [dataId, setDataId] = useState(null); + const dispatch = useDispatch(); + const [openNotif] = useContext(AppContext); + + useEffect(() => { + const fetchData = async () => { + try { + dispatch(LOADING_START()); + const response = await axios.get( + "/allow_register_code_for_kill_house_free_sale_bar_information" + ); + if (response.data) { + setIsActive(response.data.active); + setDataId(response.data.id); + } + dispatch(LOADING_END()); + } catch (error) { + console.error("Error fetching data:", error); + dispatch(LOADING_END()); + } + }; + + fetchData(); + }, [dispatch]); + + // Update value + const handleUpdate = async (newValue) => { + if (dataId === null) return; + + try { + dispatch(LOADING_START()); + await axios.put( + `/allow_register_code_for_kill_house_free_sale_bar_information/${dataId}/`, + { + active: newValue, + } + ); + setIsActive(newValue); + openNotif({ + vertical: "top", + horizontal: "center", + msg: "تغییرات با موفقیت ثبت شد", + severity: "success", + }); + dispatch(LOADING_END()); + } catch (error) { + console.error("Error updating data:", error); + openNotif({ + vertical: "top", + horizontal: "center", + msg: "خطا در ثبت تغییرات", + severity: "error", + }); + dispatch(LOADING_END()); + } + }; + + return ( + + اجباری بودن کد احراز کشتارگاه + + handleUpdate(true)} + /> + } + label="فعال" + /> + handleUpdate(false)} + /> + } + label="غیر فعال" + /> + + + ); +}; diff --git a/src/features/province/components/province-mandatory-supervisor-authentication-code/ProvinceMandatorySuperVisorAuthenticationCode.js b/src/features/province/components/province-mandatory-supervisor-authentication-code/ProvinceMandatorySuperVisorAuthenticationCode.js new file mode 100644 index 0000000..c273d81 --- /dev/null +++ b/src/features/province/components/province-mandatory-supervisor-authentication-code/ProvinceMandatorySuperVisorAuthenticationCode.js @@ -0,0 +1,110 @@ +import { FormControlLabel, Radio, Typography } from "@mui/material"; +import { useContext, useEffect, useState } from "react"; +import { useDispatch } from "react-redux"; +import axios from "axios"; +import { Grid } from "../../../../components/grid/Grid"; +import { + LOADING_END, + LOADING_START, +} from "../../../../lib/redux/slices/appSlice"; +import { AppContext } from "../../../../contexts/AppContext"; + +export const ProvinceMandatorySuperVisorAuthenticationCode = () => { + const [isActive, setIsActive] = useState(false); + const [dataId, setDataId] = useState(null); + const dispatch = useDispatch(); + const [openNotif] = useContext(AppContext); + + useEffect(() => { + const fetchData = async () => { + try { + dispatch(LOADING_START()); + const response = await axios.get( + "/allow_register_code_for_steward_free_sale_bar_information" + ); + if (response.data) { + setIsActive(response.data.active); + setDataId(response.data.id); + } + dispatch(LOADING_END()); + } catch (error) { + console.error("Error fetching data:", error); + dispatch(LOADING_END()); + } + }; + + fetchData(); + }, [dispatch]); + + const handleUpdate = async (newValue) => { + if (dataId === null) return; + + try { + dispatch(LOADING_START()); + await axios.put( + `/allow_register_code_for_steward_free_sale_bar_information/${dataId}/`, + { + active: newValue, + } + ); + setIsActive(newValue); + openNotif({ + vertical: "top", + horizontal: "center", + msg: "تغییرات با موفقیت ثبت شد", + severity: "success", + }); + dispatch(LOADING_END()); + } catch (error) { + console.error("Error updating data:", error); + openNotif({ + vertical: "top", + horizontal: "center", + msg: "خطا در ثبت تغییرات", + severity: "error", + }); + dispatch(LOADING_END()); + } + }; + + return ( + + اجباری بودن کد احراز مباشر + + handleUpdate(true)} + /> + } + label="فعال" + /> + handleUpdate(false)} + /> + } + label="غیر فعال" + /> + + + ); +}; diff --git a/src/features/province/components/province-national-info-Slaughterhouse/ProvinceNationalInfoSlaughterhouse.js b/src/features/province/components/province-national-info-Slaughterhouse/ProvinceNationalInfoSlaughterhouse.js new file mode 100644 index 0000000..a078945 --- /dev/null +++ b/src/features/province/components/province-national-info-Slaughterhouse/ProvinceNationalInfoSlaughterhouse.js @@ -0,0 +1,487 @@ +import { useContext, useEffect, useState } from "react"; +import { AppContext } from "../../../../contexts/AppContext"; +import { useDispatch } from "react-redux"; +import moment from "moment"; +import { + LOADING_END, + LOADING_START, +} from "../../../../lib/redux/slices/appSlice"; +import axios from "axios"; +import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl"; +import { Grid } from "../../../../components/grid/Grid"; +import { + Autocomplete, + Button, + Checkbox, + IconButton, + Popover, + List, + ListItemButton, + ListItemIcon, + ListItemText, + TextField, + Tooltip, + Typography, +} from "@mui/material"; +import { RiSearchLine } from "react-icons/ri"; +import ResponsiveTable from "../../../../components/responsive-table/ResponsiveTable"; +import { DatePicker } from "@mui/x-date-pickers"; +import { useParams } from "react-router-dom"; +import { getSamasatProvinces } from "../../../../utils/getSamasatProvinces"; +import { provinceNationalInfoSlaughterhouseGetDashboardService } from "../../../city/services/province-national-info-slughter-house-service"; +import RemoveRedEyeIcon from "@mui/icons-material/RemoveRedEye"; +import TuneIcon from "@mui/icons-material/Tune"; +import DownloadIcon from "@mui/icons-material/Download"; +import { + ROUTE_ADMINX_ROUTE_NATIONAL_INFO_SLAUGHTER, + ROUTE_PROVINCE_SUPERVISOR_ROUTE_NATIONAL_INFO_SLAUGHTER, + ROUTE_SUPER_ADMIN_ROUTE_NATIONAL_INFO_SLAUGHTER, +} from "../../../../routes/routes"; +import { RiFileExcel2Fill } from "react-icons/ri"; +import ToggleOffOutlinedIcon from "@mui/icons-material/ToggleOffOutlined"; +import ToggleOnIcon from "@mui/icons-material/ToggleOn"; + +const SlaughterActionsMenu = ({ excelHref, onView }) => { + const [anchorEl, setAnchorEl] = useState(null); + + const handleOpen = (event) => { + setAnchorEl(event.currentTarget); + }; + + const handleClose = () => { + setAnchorEl(null); + }; + + const open = Boolean(anchorEl); + const id = open ? "slaughter-actions-menu" : undefined; + + const options = [ + { + key: "excel", + label: "دانلود اکسل", + color: "success.main", + icon: , + action: () => { + window.open(excelHref, "_blank", "noopener"); + }, + }, + { + key: "details", + label: "نمایش جزئیات", + color: "primary.main", + icon: , + action: onView, + }, + ]; + + return ( + + + + + + + + + {options.map((option) => ( + { + handleClose(); + option.action(); + }} + sx={{ + borderRadius: 1, + mb: 0.5, + color: option.color, + "&:last-of-type": { + mb: 0, + }, + }} + > + + {option.icon} + + + {option.label} + + } + /> + + ))} + + + + ); +}; + +export const ProvinceNationalInfoSlaughterhouse = () => { + const [, , selectedDate1, setSelectedDate1, selectedDate2, setSelectedDate2] = + useContext(AppContext); + const dispatch = useDispatch(); + useEffect(() => { + const currentDate = moment(new Date()).format("YYYY-MM-DD"); + setSelectedDate1(currentDate); + setSelectedDate2(currentDate); + }, []); + + const [selectedProvince, setSelectedProvince] = useState(""); + + const handleTextChange = (event) => { + setTextValue(event.target.value); + }; + const [withDate, setWithDate] = useState(false); + + const [data, setData] = useState([]); + const [dashboardData, setDashboardData] = useState([]); + + const [totalRows, setTotalRows] = useState(0); + const [perPage, setPerPage] = useState(10); + const [textValue, setTextValue] = useState(""); + const [page, setPage] = useState(1); + const [tableData, setTableData] = useState([]); + const { key } = useParams(); + + const getDashboardData = () => { + dispatch( + provinceNationalInfoSlaughterhouseGetDashboardService({ + date1: withDate ? selectedDate1 : null, + date2: withDate ? selectedDate2 : null, + search: textValue, + province: key || selectedProvince ? selectedProvince : "", + role: getRoleFromUrl(), + }) + ).then((r) => { + setDashboardData(r.payload.data); + }); + }; + + const fetchApiData = async (page) => { + dispatch(LOADING_START()); + const response = await axios.get( + `https://rsibackend.rasadyar.com/app/total-killhouse/?search=${textValue}&role=${getRoleFromUrl()}${ + withDate ? `&date1=${selectedDate1}&date2=${selectedDate2}` : `` + }&page=${page}&page_size=${perPage}&province=${ + key || selectedProvince ? selectedProvince : "" + }` + ); + + getDashboardData(); + dispatch(LOADING_END()); + setData(response.data.results); + setTotalRows(response.data.count); + }; + + const handlePageChange = (page) => { + fetchApiData(page); + setPage(page); + }; + + const handlePerRowsChange = (perRows) => { + setPerPage(perRows); + setPage(1); + }; + + // const updateTable = () => { + // fetchApiData(page !== 0 ? page : 1); + // }; + + useEffect(() => { + const d = data?.map((item, i) => { + return [ + page === 1 ? i + 1 : i + perPage * (page - 1) + 1, + item?.UnitName, + item?.PartIdCode, + item?.Province, + item?.City, + item?.info?.bars?.toLocaleString(), + item?.info?.totalBarsQuantity?.toLocaleString(), + item?.info?.inputBars?.toLocaleString(), + item?.info?.totalInputBarsQuantity?.toLocaleString(), + item?.info?.totalInputBarsPercent[0] + ? item?.info?.totalInputBarsPercent[0]?.toFixed(1) + : item?.info?.totalInputBarsPercent, + item?.info?.outputBars?.toLocaleString(), + item?.info?.totalOutputBarsQuantity?.toLocaleString(), + item?.info?.totalOutputBarsPercent?.toFixed(1), + + window.open( + getRoleFromUrl() === "AdminX" + ? `${ROUTE_ADMINX_ROUTE_NATIONAL_INFO_SLAUGHTER}/${item.PartIdCode}/${item?.UnitName}` + : getRoleFromUrl() === "SuperAdmin" + ? `${ROUTE_SUPER_ADMIN_ROUTE_NATIONAL_INFO_SLAUGHTER}/${item.PartIdCode}/${item?.UnitName}` + : `${ROUTE_PROVINCE_SUPERVISOR_ROUTE_NATIONAL_INFO_SLAUGHTER}/${item.PartIdCode}/${item?.UnitName}`, + "_blank" + ) + } + />, + ]; + }); + + setTableData(d); + }, [data]); + + useEffect(() => { + fetchApiData(1); + }, [ + dispatch, + selectedDate1, + selectedDate2, + perPage, + selectedProvince, + withDate, + ]); + + const handleSubmit = async (event) => { + event.preventDefault(); + dispatch(LOADING_START()); + + try { + const response = await axios.get( + `https://rsibackend.rasadyar.com/app/total-killhouse/?role=${getRoleFromUrl()}&search=${textValue}${ + withDate ? `&date1=${selectedDate1}&date2=${selectedDate2}` : `` + }&page=${1}&page_size=${perPage}&province=${ + key || selectedProvince ? selectedProvince : "" + }` + ); + + setData(response.data.results); + setTotalRows(response.data.count); + getDashboardData(); + dispatch(LOADING_END()); + } catch (error) { + console.error("Error fetching data:", error); + } + }; + + const getProvinceList = () => { + return [{ name: "همه" }, ...getSamasatProvinces()]; + }; + + return ( + + + {!key && ( + + { + return { + label: i.name, + }; + })} + onChange={(event, value) => { + if (value.label !== "همه") { + setSelectedProvince(value.label); + } else { + setSelectedProvince(""); + } + }} + renderInput={(params) => ( + + )} + /> + + )} + + + } + checkedIcon={} + checked={withDate} + onChange={() => setWithDate(!withDate)} + color="primary" + size="large" + /> + + ( + + )} + value={selectedDate1} + onChange={(e) => { + setSelectedDate1(moment(e).format("YYYY-MM-DD")); + }} + /> + + + ( + + )} + value={selectedDate2} + onChange={(e) => { + setSelectedDate2(moment(e).format("YYYY-MM-DD")); + }} + /> + + + +
    + + + +
    + + + + + + + +
    + + + + + +
    + ); +}; diff --git a/src/features/province/components/province-national-info-farm/ProvinceNationalInfoFarm.js b/src/features/province/components/province-national-info-farm/ProvinceNationalInfoFarm.js new file mode 100644 index 0000000..e22a9ed --- /dev/null +++ b/src/features/province/components/province-national-info-farm/ProvinceNationalInfoFarm.js @@ -0,0 +1,353 @@ +import { Grid } from "../../../../components/grid/Grid"; +import React, { useContext, useEffect, useState } from "react"; +import { + Button, + Checkbox, + FormControlLabel, + IconButton, + Tab, + Tabs, + TextField, + Tooltip, +} from "@mui/material"; +import RemoveRedEyeIcon from "@mui/icons-material/RemoveRedEye"; + +import { DatePicker } from "@mui/x-date-pickers"; +import moment from "moment"; +import { useDispatch } from "react-redux"; +import axios from "axios"; +import { RiSearchLine } from "react-icons/ri"; +import { AppContext } from "../../../../contexts/AppContext"; +import { + LOADING_END, + LOADING_START, +} from "../../../../lib/redux/slices/appSlice"; +import ResponsiveTable from "../../../../components/responsive-table/ResponsiveTable"; +import { useParams } from "react-router-dom"; +import { formatJustDate } from "../../../../utils/formatTime"; + +import { BackButton } from "../../../../components/back-button/BackButton"; +import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl"; +import { + ROUTE_ADMINX_ROUTE_NATIONAL_INFO, + ROUTE_PROVINCE_SUPERVISOR_ROUTE_NATIONAL_INFO, + ROUTE_SUPER_ADMIN_ROUTE_NATIONAL_INFO, +} from "../../../../routes/routes"; +import { nationalInfoGetDashboardService } from "../../../city/services/national-info-get-dashboard-info-service"; + +export const ProvinceNationalInfoFarm = () => { + const [, , selectedDate1, setSelectedDate1, selectedDate2, setSelectedDate2] = + useContext(AppContext); + const dispatch = useDispatch(); + useEffect(() => { + const currentDate = moment(new Date()).format("YYYY-MM-DD"); + setSelectedDate1(currentDate); + setSelectedDate2(currentDate); + }, []); + + const handleTextChange = (event) => { + setTextValue(event.target.value); + }; + + const { key, name } = useParams(); + + const [dashboardData, setDashboardData] = useState([]); + const [data, setData] = useState([]); + const [totalRows, setTotalRows] = useState(0); + const [perPage, setPerPage] = useState(10); + const [textValue, setTextValue] = useState(""); + const [page, setPage] = useState(1); + const [tableData, setTableData] = useState([]); + const [withDate, setWithDate] = useState(false); + const [value, setValue] = useState("0"); + + const handleChange = (event, newValue) => { + setValue(newValue); + }; + + const getDashboardData = () => { + dispatch( + nationalInfoGetDashboardService({ + date1: withDate ? selectedDate1 : null, + date2: withDate ? selectedDate2 : null, + search: textValue, + system_code: key, + }) + ).then((r) => { + setDashboardData(r.payload.data); + }); + }; + + const fetchApiData = async (page) => { + let response; + dispatch(LOADING_START()); + response = await axios.get( + `https://rsibackend.rasadyar.com/app/hatchings/?search=${textValue}${ + withDate ? `&date1=${selectedDate1}&date2=${selectedDate2}` : `` + }&page=${page}&page_size=${perPage}&system_code=${key}&state=${ + value === "0" ? "pending" : "archive" + }` + ); + dispatch(LOADING_END()); + getDashboardData(); + setData(response.data.results); + setTotalRows(response.data.count); + }; + + const handlePageChange = (page) => { + fetchApiData(page); + setPage(page); + }; + + const handlePerRowsChange = (perRows) => { + setPerPage(perRows); + setPage(1); + }; + + // const updateTable = () => { + // fetchApiData(page !== 0 ? page : 1); + // }; + + useEffect(() => { + const d = data?.map((item, i) => { + return [ + page === 1 ? i + 1 : i + perPage * (page - 1) + 1, + item?.poultry?.Province || "-", + item?.poultry?.City || "-", + item?.poultry?.UnitName, + `${item?.poultry?.FirstName} ${item?.poultry?.LastName || ""}`, + item?.RequestCode, + item?.CertId, + item?.CapacityFemale?.toLocaleString(), + formatJustDate(item?.Date), + Math.floor(item?.Age), + item?.ChickCountSum?.toLocaleString(), + item?.Period?.toLocaleString(), + item?.Evacuation?.toLocaleString(), + item?.info?.percentHatchingLicense?.toFixed(2), + item?.LeftOver?.toLocaleString(), + Math.floor(item?.KillingAve), + item?.info?.numberLoads?.toLocaleString(), + item?.info?.loadVolume?.toLocaleString(), + + + window.open( + getRoleFromUrl() === "AdminX" + ? `${ROUTE_ADMINX_ROUTE_NATIONAL_INFO}/${item.RequestCode}/${item?.poultry?.UnitName}` + : getRoleFromUrl() === "SuperAdmin" + ? `${ROUTE_SUPER_ADMIN_ROUTE_NATIONAL_INFO}/${item.RequestCode}/${item?.poultry?.UnitName}` + : `${ROUTE_PROVINCE_SUPERVISOR_ROUTE_NATIONAL_INFO}/${item.RequestCode}/${item?.poultry?.UnitName}`, + "_blank" + ) + } + > + + + , + ]; + }); + + setTableData(d); + }, [data]); + + useEffect(() => { + fetchApiData(1); + }, [dispatch, selectedDate1, selectedDate2, perPage, withDate, value]); + + const handleSubmit = async (event) => { + event.preventDefault(); + dispatch(LOADING_START()); + + try { + const response = await axios.get( + `https://rsibackend.rasadyar.com/app/hatchings/?search=${textValue}${ + withDate ? `&date1=${selectedDate1}&date2=${selectedDate2}` : `` + }&page=${1}&page_size=${perPage}&system_code=${key}&state=${ + value === "0" ? "pending" : "archive" + }` + ); + setData(response.data.results); + setTotalRows(response.data.count); + + dispatch(LOADING_END()); + getDashboardData(); + } catch (error) { + console.error("Error fetching data:", error); + } + }; + + return ( + + + + + + + + + + + + +
    + + + +
    + + + setWithDate(!withDate)} + color="primary" + /> + } + /> + + + ( + + )} + value={selectedDate1} + onChange={(e) => { + setSelectedDate1(moment(e).format("YYYY-MM-DD")); + }} + /> + + + ( + + )} + value={selectedDate2} + onChange={(e) => { + setSelectedDate2(moment(e).format("YYYY-MM-DD")); + }} + /> + + +
    + + + + + + +
    + ); +}; diff --git a/src/features/province/components/province-national-info-farms/ProvinceNationalInfoFarms.js b/src/features/province/components/province-national-info-farms/ProvinceNationalInfoFarms.js new file mode 100644 index 0000000..72bc557 --- /dev/null +++ b/src/features/province/components/province-national-info-farms/ProvinceNationalInfoFarms.js @@ -0,0 +1,452 @@ +import React, { useEffect, useState } from "react"; +import { + Autocomplete, + Button, + IconButton, + Popover, + List, + ListItemButton, + ListItemIcon, + ListItemText, + TextField, + Tooltip, + Typography, +} from "@mui/material"; + +import axios from "axios"; +import { RiSearchLine } from "react-icons/ri"; +import ResponsiveTable from "../../../../components/responsive-table/ResponsiveTable"; +import { Grid } from "../../../../components/grid/Grid"; +import { + LOADING_END, + LOADING_START, +} from "../../../../lib/redux/slices/appSlice"; +import { useDispatch } from "react-redux"; +import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl"; +import { useNavigate, useParams } from "react-router-dom"; +import { + ROUTE_ADMINX_ROUTE_NATIONAL_INFO_FARM, + ROUTE_PROVINCE_SUPERVISOR_ROUTE_NATIONAL_INFO_FARM, + ROUTE_SUPER_ADMIN_ROUTE_NATIONAL_INFO_FARM, +} from "../../../../routes/routes"; +import RemoveRedEyeIcon from "@mui/icons-material/RemoveRedEye"; +import TuneIcon from "@mui/icons-material/Tune"; +import DownloadIcon from "@mui/icons-material/Download"; +import { provinceNationalFarmManagementInfoDashboardService } from "../../services/province-national-info-farm-management-info-dashboard-service"; +import { getSamasatProvinces } from "../../../../utils/getSamasatProvinces"; + +const FarmActionsMenu = ({ excelHref, onView }) => { + const [anchorEl, setAnchorEl] = useState(null); + + const handleOpen = (event) => { + setAnchorEl(event.currentTarget); + }; + + const handleClose = () => { + setAnchorEl(null); + }; + + const open = Boolean(anchorEl); + const id = open ? "farm-actions-menu" : undefined; + + const options = [ + { + key: "excel", + label: "دانلود اکسل", + color: "success.main", + icon: , + action: () => { + window.open(excelHref, "_blank", "noopener"); + }, + }, + { + key: "view", + label: "نمایش جزئیات", + color: "primary.main", + icon: , + action: onView, + }, + ]; + + return ( + + + + + + + + + {options.map((option) => ( + { + handleClose(); + option.action(); + }} + sx={{ + borderRadius: 1, + mb: 0.5, + color: option.color, + "&:last-of-type": { + mb: 0, + }, + }} + > + + {option.icon} + + + {option.label} + + } + /> + + ))} + + + + ); +}; + +export const ProvinceNationalInfoFarms = () => { + const navigate = useNavigate(); + const handleTextChange = (event) => { + setTextValue(event.target.value); + }; + + const [selectedProvince, setSelectedProvince] = useState(""); + + const [data, setData] = useState([]); + const [totalRows, setTotalRows] = useState(0); + const [perPage, setPerPage] = useState(10); + const [textValue, setTextValue] = useState(""); + const [dashboardData, setDashboardData] = useState([]); + const [page, setPage] = useState(1); + const [tableData, setTableData] = useState([]); + const dispatch = useDispatch(); + const { key } = useParams(); + + const getDashboardData = () => { + dispatch( + provinceNationalFarmManagementInfoDashboardService({ + search: textValue, + province: selectedProvince === "همه" ? "" : selectedProvince, + }) + ).then((r) => { + setDashboardData(r.payload.data); + }); + }; + + const fetchApiData = async (page) => { + dispatch(LOADING_START()); + const response = await axios.get( + `https://rsibackend.rasadyar.com/app/poultry-info/?search=${textValue}&role=${getRoleFromUrl()}&page=${page}&page_size=${perPage}&province=${ + key || selectedProvince ? selectedProvince : "" + }` + ); + dispatch(LOADING_END()); + getDashboardData(); + setData(response.data.results); + setTotalRows(response.data.count); + }; + + const handlePageChange = (page) => { + fetchApiData(page); + setPage(page); + }; + + const handlePerRowsChange = (perRows) => { + setPerPage(perRows); + setPage(1); + }; + + // const updateTable = () => { + // fetchApiData(page !== 0 ? page : 1); + // }; + + useEffect(() => { + const d = data?.map((item, i) => { + const name = (item.FirstName + "" + item.LastName).replace("null", ""); + return [ + page === 1 ? i + 1 : i + perPage * (page - 1) + 1, + name, + item?.Mobile, + item?.UnitName, + item?.EpidemiologicCode, + item?.SystemCode, + item?.UnitId, + item?.UserIsActiveDescription, + item?.info?.capacity?.toLocaleString(), + item?.Province, + item?.City, + item?.info?.countHatching?.toLocaleString(), + item?.info?.totalHatching?.toLocaleString(), + item?.info?.totalEvacuation?.toLocaleString(), + item?.info?.totalEvacuationPercent?.toLocaleString(), + item?.info?.totalKilling?.toLocaleString(), + item?.info?.totalKillingPercent?.toLocaleString(), + item?.info?.totalLeftover?.toLocaleString(), + item?.info?.totalLeftOverPercent?.toLocaleString(), + item?.info?.carsCount?.toLocaleString(), + item?.info?.totalCars?.toLocaleString(), + { + navigate( + getRoleFromUrl() === "AdminX" + ? `${ROUTE_ADMINX_ROUTE_NATIONAL_INFO_FARM}/${item?.SystemCode}/${name}` + : getRoleFromUrl() === "SuperAdmin" + ? `${ROUTE_SUPER_ADMIN_ROUTE_NATIONAL_INFO_FARM}/${item?.SystemCode}/${name}` + : `${ROUTE_PROVINCE_SUPERVISOR_ROUTE_NATIONAL_INFO_FARM}/${item?.SystemCode}/${name}` + ); + }} + />, + ]; + }); + + setTableData(d); + }, [data]); + + useEffect(() => { + fetchApiData(1); + }, [dispatch, perPage, selectedProvince]); + + const handleSubmit = async (event) => { + event.preventDefault(); + dispatch(LOADING_START()); + + try { + const response = await axios.get( + `https://rsibackend.rasadyar.com/app/poultry-info/?role=${getRoleFromUrl()}&search=${textValue}&page=${1}&page_size=${perPage}&province=${ + key || selectedProvince ? selectedProvince : "" + }` + ); + setData(response.data.results); + setTotalRows(response.data.count); + dispatch(LOADING_END()); + getDashboardData(); + } catch (error) { + console.error("Error fetching data:", error); + } + }; + + const getProvinceList = () => { + return [{ name: "همه" }, ...getSamasatProvinces()]; + }; + + const getProvince = (item) => { + if (!key && (selectedProvince === "همه" || !selectedProvince)) { + return [item ? item?.provinceCount?.toLocaleString() : "تعداد استان"]; + } else { + return []; + } + }; + return ( + + + {!key && ( + + { + return { + label: i.name, + }; + })} + onChange={(event, value) => { + if (value.label !== "همه") { + setSelectedProvince(value.label); + } else { + setSelectedProvince(""); + } + }} + renderInput={(params) => ( + + )} + /> + + )} + + +
    + + + +
    +
    + + + + + + + +
    + ); +}; diff --git a/src/features/province/components/province-national-info-overview/ProvinceNationalInfoOverview.js b/src/features/province/components/province-national-info-overview/ProvinceNationalInfoOverview.js new file mode 100644 index 0000000..6b14d30 --- /dev/null +++ b/src/features/province/components/province-national-info-overview/ProvinceNationalInfoOverview.js @@ -0,0 +1,283 @@ +import { useDispatch } from "react-redux"; +import { useNavigate } from "react-router-dom"; +import { CLOSE_MODAL } from "../../../../lib/redux/slices/appSlice"; +import { + ROUTE_ADMINX_ROUTE_NATIONAL_INFO, + ROUTE_PROVINCE_SUPERVISOR_ROUTE_NATIONAL_INFO, + ROUTE_SUPER_ADMIN_ROUTE_NATIONAL_INFO, +} from "../../../../routes/routes"; +import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl"; +import { Grid } from "../../../../components/grid/Grid"; +import { Button, Typography, Box } from "@mui/material"; +import { useEffect, useState } from "react"; +import { + Egg as EggIcon, + Numbers as NumbersIcon, + LocationCity as CityIcon, + TrendingUp as TrendingUpIcon, + TrendingDown as TrendingDownIcon, + ShowChart as ChartIcon, + Home as FarmIcon, + CalendarToday as AgeIcon, + Info as InfoIcon, + ArrowForward as ArrowForwardIcon, +} from "@mui/icons-material"; +import { provinceNationalFarmManagementInfoDashboardService } from "../../services/province-national-info-farm-management-info-dashboard-service"; + +export const ProvinceNationalInfoOverview = ({ provinceId }) => { + const dispatch = useDispatch(); + const navigate = useNavigate(); + const [provinceData, setProvinceData] = useState(null); + + useEffect(() => { + dispatch( + provinceNationalFarmManagementInfoDashboardService({ + province: provinceId, + }) + ).then((r) => { + setProvinceData(r.payload.data); + }); + }, []); + + const handleNavigate = () => { + dispatch(CLOSE_MODAL()); + navigate( + getRoleFromUrl() === "AdminX" + ? `${ROUTE_ADMINX_ROUTE_NATIONAL_INFO}/${provinceId}` + : getRoleFromUrl() === "SuperAdmin" + ? `${ROUTE_SUPER_ADMIN_ROUTE_NATIONAL_INFO}/${provinceId}` + : `${ROUTE_PROVINCE_SUPERVISOR_ROUTE_NATIONAL_INFO}/${provinceId}` + ); + }; + + const StatItem = ({ icon, label, value, color = "text.primary" }) => ( + + + {icon} + + + + + {label}: {value} + + + + + ); + + return ( + + + + کل جوجه ریزی ها + } + label="تعداد فارم ها" + value={provinceData?.poultryCount?.toLocaleString() || 0} + /> + } + label="تعداد کل جوجه ریزی" + value={provinceData?.totalHatchingCount?.toLocaleString() || 0} + /> + } + label="حجم کل جوجه ریزی" + value={provinceData?.totalHatchingQuantity?.toLocaleString() || 0} + /> + } + label="تلفات" + value={provinceData?.totalHatchingEvacuation?.toLocaleString() || 0} + color="error.main" + /> + } + label="درصد تلفات " + value={ + provinceData?.totalHatchingEvacuationPercent?.toLocaleString() || + 0 + } + color="error.main" + /> + } + label="کشتار شده" + value={ + provinceData?.totalHatchingKillingQuantity?.toLocaleString() || 0 + } + /> + } + label="درصد کشتار" + value={ + provinceData?.totalHatchingKillingQuantityPercent?.toLocaleString() || + 0 + } + /> + } + label="مانده در سالن" + value={provinceData?.totalHatchingLeftOver?.toLocaleString() || 0} + /> + } + label="درصد مانده در سالن" + value={ + provinceData?.totalHatchingLeftOverPercent?.toLocaleString() || 0 + } + /> + } + label="میانگین سن کشتار" + value={Math.floor(provinceData?.totalHatchingKillingAge) || 0} + /> + } + label="تعداد شهرستان" + value={Math.floor(provinceData?.cityCount?.toLocaleString()) || 0} + /> + + + + جوجه ریزی های فعال + + } + label="تعداد جوجه ریزی " + value={ + Math.floor( + provinceData?.totalActiveHatchingCount?.toLocaleString() + ) || 0 + } + color="success.main" + /> + } + label="حجم جوجه ریزی " + value={provinceData?.totalActiveHatchingQuantity?.toLocaleString()} + color="success.main" + /> + + } + label="تلفات" + value={provinceData?.totalActiveHatchingEvacuation?.toLocaleString()} + color="success.main" + /> + } + label="درصد تلفات " + value={Math.floor( + provinceData?.totalActiveHatchingEvacuationPercent?.toLocaleString() + )} + color="success.main" + /> + + } + label="کشتار شده " + value={ + Math.floor( + provinceData?.totalActiveHatchingKillingQuantity + ).toLocaleString() || 0 + } + /> + } + label="درصد کشتار " + value={ + Math.floor( + provinceData?.totalActiveHatchingKillingQuantityPercent + ) || 0 + } + /> + + } + label="مانده در سالن " + value={ + provinceData?.totalActiveHatchingLeftOver?.toLocaleString() || 0 + } + /> + + } + label="درصد مانده در سالن " + value={Math.floor( + provinceData?.totalActiveHatchingLeftOverPercent?.toLocaleString() + )} + /> + } + label="میانگین سن کشتار" + value={ + Math.floor( + provinceData?.totalActiveHatchingKillingAge + )?.toLocaleString() || 0 + } + /> + + + + + + + ); +}; diff --git a/src/features/province/components/province-national-info/ProvinceNationalInfo.js b/src/features/province/components/province-national-info/ProvinceNationalInfo.js new file mode 100644 index 0000000..b69b62d --- /dev/null +++ b/src/features/province/components/province-national-info/ProvinceNationalInfo.js @@ -0,0 +1,49 @@ +import React, { useState } from "react"; +import { Grid } from "../../../../components/grid/Grid"; +import { BackButton } from "../../../../components/back-button/BackButton"; +import { Tab, Tabs } from "@mui/material"; +import { ProvinceNationalInfoSlaughterhouse } from "../province-national-info-Slaughterhouse/ProvinceNationalInfoSlaughterhouse"; +import { NationalInfoHatchings } from "../../../city/components/national-info-hatchings/NationalInfoHatchings"; +import { ProvinceNationalInfoFarms } from "../province-national-info-farms/ProvinceNationalInfoFarms"; +import { NationalInfoTransports } from "../../../city/components/national-info-bars/NationalInfoTransports"; + +export const ProvinceNationalInfo = () => { + const [value, setValue] = useState(0); + + const handleChangeTab = (event, newValue) => { + setValue(newValue); + }; + + return ( + + + + + + + + + + + + + + + {value === 0 && } + {value === 1 && } + {value === 2 && } + {value === 3 && } + + + ); +}; diff --git a/src/features/province/components/province-need-request-form/ProvinceNeedRequestForm.js b/src/features/province/components/province-need-request-form/ProvinceNeedRequestForm.js new file mode 100644 index 0000000..63e2a1c --- /dev/null +++ b/src/features/province/components/province-need-request-form/ProvinceNeedRequestForm.js @@ -0,0 +1,287 @@ +import { + Button, + FormControl, + FormHelperText, + InputLabel, + MenuItem, + Select, + TextField, + Typography, + Grid, +} from "@mui/material"; +import React, { useState, useContext } from "react"; +import { AnimatePresence, motion } from "framer-motion"; +import { useFormik } from "formik"; +import { Yup } from "../../../../lib/yup/yup"; +import { useDispatch } from "react-redux"; +import { + DRAWER, + LOADING_END, + LOADING_START, +} from "../../../../lib/redux/slices/appSlice"; +import { provinceNeedRequestFormService } from "../../services/province-need-request-form"; +import { getSlaughtersKillRequestService } from "../../../city/services/get-slaughters-kill-request"; +import { AppContext } from "../../../../contexts/AppContext"; +import { NumberInput } from "../../../../components/number-format-custom/NumberFormatCustom"; + +export function ProvinceNeedRequestForm({ killRequestKey, quantity, item }) { + const [isDenied, setIsDenied] = useState(false); + const [, , selectedDate1, , selectedDate2] = useContext(AppContext); + const [openNotif] = useContext(AppContext); + const dispatch = useDispatch(); + + const formik = useFormik({ + initialValues: { + rejectText: "", + number: "", + race: "", + }, + validationSchema: Yup.object({ + rejectText: Yup.string() + .required("این فیلد اجباری است!") + .typeError("لطفا دلیل خود را بیان کنید."), + }), + }); + + const acceptButtonText = "تایید"; + const rejectButtonText = "رد"; + const handleAccept = () => { + const requestData = { + state: "accepted", + kill_request_key: killRequestKey, + }; + + if (formik.values.number) { + requestData.quantity = formik.values.number; + } + + if (formik.values.race) { + requestData.breed = formik.values.race; + } + + dispatch(LOADING_START()); + dispatch(provinceNeedRequestFormService(requestData)).then((r) => { + dispatch(LOADING_END()); + openNotif({ + vertical: "top", + horizontal: "center", + msg: r.error ? "مشکلی پیش آمده است!" : "عملیات با موفقیت انجام شد.", + severity: r.error ? "error" : "success", + }); + if (!r.error) { + dispatch( + getSlaughtersKillRequestService({ + selectedDate1, + selectedDate2, + }) + ); + dispatch( + DRAWER({ + right: false, + bottom: false, + top: false, + content: null, + }) + ); + } + }); + }; + return ( + + + توضیحات + + + لطفاً نیاز اولیه کشتار را بررسی کرده و در صورت تأیید یا رد، اقدام لازم + را انجام دهید.{" "} + + + شما می‌توانید حجم و نژاد مرغ درخواستی را به‌دلخواه ویرایش کنید.{" "} + + + درخواست کشتارگاه: + + + + + تعداد درخواستی: {quantity.toLocaleString()} قطعه + + + + نژاد: {item?.chickenBreed} + + + + + {isDenied ? ( + + + + + + + + + + + + + + ) : ( + + + + + + + + نژاد مرغ + + + {formik.touched.race && formik.errors.race} + + + + + + + + + + + + )} + + + ); +} diff --git a/src/features/province/components/province-need-requests/ProvinceNeedRequests.js b/src/features/province/components/province-need-requests/ProvinceNeedRequests.js new file mode 100644 index 0000000..9c2c958 --- /dev/null +++ b/src/features/province/components/province-need-requests/ProvinceNeedRequests.js @@ -0,0 +1,438 @@ +import { Button, TextField, Tooltip, Typography } from "@mui/material"; +import { useContext, useEffect, useState } from "react"; +import { useDispatch, useSelector } from "react-redux"; +// import { useLocation } from "react-router-dom"; +import { Grid } from "../../../../components/grid/Grid"; +import { SPACING } from "../../../../data/spacing"; +import { + // DRAWER, + LOADING_END, + LOADING_START, +} from "../../../../lib/redux/slices/appSlice"; +// import { CityNewKillRequest } from "../../../city/components/city-new-kill-request/CityNewKillRequest"; +import { AppContext } from "../../../../contexts/AppContext"; +import { hourLimitKillRequestService } from "../../../city/services/hour-limit-kill-request"; +import { hourLimitGetKillRequestService } from "../../../city/services/hour-limit-get-kill-request"; +import { DatePicker } from "@mui/x-date-pickers"; +import moment from "moment"; +import { getPoultryRequestsTotalQuantityService } from "../../../city/services/get-poultry-requests-total-quantity"; +import { formatJustDate, formatTime } from "../../../../utils/formatTime"; +import axios from "axios"; +import { RiFileExcel2Fill, RiSearchLine } from "react-icons/ri"; +import { ProvinceManagePoultryRequestOperations } from "../province-manage-poultry-request-operations/ProvinceManagePoultryRequestOperations"; +import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl"; +import { getFaUserRole } from "../../../../utils/getFaUserRole"; +import { deleteDebtorKillhouses } from "../../services/delete-debtor-killhouses"; +import ResponsiveTable from "../../../../components/responsive-table/ResponsiveTable"; + +export const ProvinceNeedRequests = () => { + const authToken = useSelector((state) => state.userSlice.authToken); + const { poultryRequestsTotalQuantity } = useSelector( + (state) => state.citySlice + ); + // const { pathname } = useLocation(); + const dispatch = useDispatch(); + const [isChecked, setIsChecked] = useState(false); + const [selectedHour, setSelectedHour] = useState(""); + + const [openNotif] = useContext(AppContext); + + const [data, setData] = useState([]); + const [totalRows, setTotalRows] = useState(0); + const [perPage, setPerPage] = useState(10); + const [textValue, setTextValue] = useState(""); + const [page, setPage] = useState(1); + const [tableData, setTableData] = useState([]); + + const handleTextChange = (event) => { + setTextValue(event.target.value); + }; + + const fetchApiData = async (page) => { + dispatch(LOADING_START()); + const response = await axios.get( + `Poultry_Request/?role=${getRoleFromUrl()}&today&date1=${selectedDate1}&date2=${selectedDate2}&search=filter&value=${ + textValue || "" + }&page=${page}&page_size=${perPage}` + ); + dispatch(LOADING_END()); + setData(response.data.results); + setTotalRows(response.data.count); + }; + + const handlePageChange = (page) => { + fetchApiData(page); + setPage(page); + }; + + const handleSubmit = async (event) => { + event.preventDefault(); + dispatch(LOADING_START()); + + try { + const response = await axios.get( + `Poultry_Request/?role=${getRoleFromUrl()}&today&date1=${selectedDate1}&date2=${selectedDate2}&search=filter&value=${ + textValue || "" + }` + ); + setData(response.data.results); + setTotalRows(response.data.count); + dispatch(LOADING_END()); + } catch (error) { + console.error("Error fetching data:", error); + } + }; + + const [selectedDate, setSelectedDate] = useState( + moment(new Date()).format("YYYY-MM-DD") + ); + + const [, , selectedDate1, setSelectedDate1, selectedDate2, setSelectedDate2] = + useContext(AppContext); + + useEffect(() => { + const currentDate = moment(new Date()).format("YYYY-MM-DD"); + setSelectedDate1(currentDate); + setSelectedDate2(currentDate); + }, []); + + const handlePerRowsChange = (perRows) => { + setPerPage(perRows); + setPage(1); + }; + + useEffect(() => { + dispatch(getPoultryRequestsTotalQuantityService(selectedDate)); + }, [selectedDate]); + + useEffect(() => { + dispatch(hourLimitGetKillRequestService()).then((r) => { + setIsChecked(r.payload.data?.[0]?.active); + setSelectedHour(r.payload.data?.[0]?.hour); + }); + dispatch(deleteDebtorKillhouses()); + }, []); + + useEffect(() => { + if (isChecked && selectedHour) { + dispatch( + hourLimitKillRequestService({ hour: selectedHour, active: isChecked }) + ); + } + if (!isChecked && selectedHour) { + setSelectedHour(null); + dispatch(hourLimitKillRequestService({ hour: 0, active: isChecked })); + } + }, [selectedHour, isChecked]); + + const urlRole = window.location.pathname.split("/")[1]; + const fileUrl = "/" + urlRole + "/file/"; + + const getItemSellState = (item) => { + let sellType = ""; + if (item?.market) { + sellType = "پنل معاملات"; + } else if (item?.directBuying) { + sellType = "خرید مستقیم"; + } else if (item?.union) { + sellType = "خرید خارج از استان"; + } else { + sellType = "اتحادیه"; + } + return sellType; + }; + + useEffect(() => { + const d = data?.map((item, i) => { + return [ + page === 1 ? i + 1 : i + perPage * (page - 1) + 1, + , + item.orderCode, + getItemFreeSaleInProvince(item), + item?.freezing ? "انجماد" : item?.export ? "صادرات" : "عادی", + getItemSellState(item), + formatTime(item?.createDate) + + " " + + `(${item?.registrar?.fullname} - ${getFaUserRole( + item?.registrar?.role + )})`, + formatJustDate(item?.sendDate), + `${item?.poultry?.unitName} (${item?.poultry?.user?.mobile})`, + item?.killHouseList?.length ? item?.killHouseList.join(" - ") : "ندارد", + `${item?.poultry?.address?.city?.name}/${ + item?.poultry?.cityOperator + ? item?.poultry?.cityOperator + : "بدون تعاونی" + }`, + item?.hatching?.age, + item?.IndexWeight, + item?.hatching?.totalWeight?.toLocaleString(), + item?.firstQuantity.toLocaleString(), + item?.amount.toLocaleString() + " ﷼", + item?.hatching?.leftOver?.toLocaleString(), + item.quantity?.toLocaleString(), + (item.quantity - item?.remainQuantity).toLocaleString(), + item?.remainQuantity?.toLocaleString(), + + {item.hatching.fileState === "province_state_pending" + ? "در انتظار تایید" + : item.hatching.fileState === "allocated_pending" + ? "آماده تخصیص" + : item.hatching.fileState === "confirmation_code_pending" + ? "در انتظار ورود کد احراز" + : "تخصیص داده شده"} + , + ]; + }); + + setTableData(d); + }, [data]); + + useEffect(() => { + fetchApiData(1); + }, [selectedDate1, selectedDate2, perPage]); + + const updateTable = () => { + fetchApiData(1); + }; + + const tableTitle = ( + +
    + + + + + ( + + )} + value={selectedDate1} + onChange={(e) => { + setSelectedDate1(moment(e).format("YYYY-MM-DD")); + }} + /> + + + ( + + )} + value={selectedDate2} + onChange={(e) => { + setSelectedDate2(moment(e).format("YYYY-MM-DD")); + }} + /> + + + {/* */} + + {/* */} + + +
    +
    + ); + + const getItemFreeSaleInProvince = (item) => { + let sellType = ""; + if (item?.freeSaleInProvince) { + sellType = "آزاد"; + } else { + sellType = "دولتی"; + } + return sellType; + }; + + return ( + + + {/* + {pathname !== "/vet-supervisor/hatching" && ( + + )} + */} + + + + + اطلاعات کشتار + + + ( + + )} + value={selectedDate} + onChange={(e) => { + setSelectedDate(moment(e).format("YYYY-MM-DD")); + }} + /> + + + + + + + + {tableTitle} + + + + + + ); +}; diff --git a/src/features/province/components/province-new-requests/ProvinceNewRequests.js b/src/features/province/components/province-new-requests/ProvinceNewRequests.js new file mode 100644 index 0000000..781ec41 --- /dev/null +++ b/src/features/province/components/province-new-requests/ProvinceNewRequests.js @@ -0,0 +1,96 @@ +import { Card } from "@mui/material"; +import { useEffect, useState } from "react"; +import { AdvancedTable } from "../../../../components/advanced-table/AdvancedTable"; +import PlagiarismIcon from "@mui/icons-material/Plagiarism"; +import { useNavigate } from "react-router-dom"; +import useProvinceNewRequests from "../../hooks/useProvinceNewRequests"; +import { ROUTE_PROVINCE_FILE } from "../../../../routes/routes"; +import IconButton from "@mui/material/IconButton"; +import { useDispatch } from "react-redux"; +import { DRAWER } from "../../../../lib/redux/slices/appSlice"; +import ProvinceCheckRequest from "../../../file/components/province-check-request/ProvinceCheckRequest"; +import CreateIcon from "@mui/icons-material/Create"; +import { format } from "date-fns-jalali"; + +export const ProvinceNewRequests = () => { + const navigate = useNavigate(); + const dispatch = useDispatch(); + const provinceNewRequestsData = useProvinceNewRequests(); + const [dataTable, setDataTable] = useState([]); + + useEffect(() => { + const d = provinceNewRequestsData?.map((item, i) => { + return [ + i + 1, + item?.poultryRequest?.orderCode, + format(new Date(item?.poultryRequest?.createDate), "yyyy/MM/dd"), + format(new Date(item?.poultryRequest?.sendDate), "yyyy/MM/dd"), + item?.poultryRequest?.process?.poultry?.poultryName, + item?.poultryRequest?.process?.poultry?.poultryMobile, + item?.poultryRequest?.process?.poultry?.poultryCity, + item?.poultryRequest?.process?.poultry?.poultryProvince, + item?.poultryRequest?.process?.poultry?.age, + item?.poultryRequest?.process?.poultry?.poultryQuantity, + + dispatch( + DRAWER({ + right: !(window.innerWidth <= 600), + bottom: window.innerWidth <= 600, + content: ( + + ), + title: "انجام عملیات استان", + }) + ) + } + > + + , + { + navigate( + ROUTE_PROVINCE_FILE + + item?.poultryRequest?.process?.poultry?.poultryRequestId + ); + }} + > + + , + ]; + }); + setDataTable(d); + }, [provinceNewRequestsData]); + + const [tableDataCol] = useState([ + "ردیف", + "کد سفارش", + "تاریخ ثبت درخواست", + "تاریخ درخواست", + "مرغدار", + "تلفن مرغدار", + "شهر", + "استان", + "سن مرغ", + "تعداد", + "عملیات", + "مشاهده", + ]); + return ( + + + + ); +}; diff --git a/src/features/province/components/province-paid-fees-chain-company/ProvincePaidFeesChainCompany.js b/src/features/province/components/province-paid-fees-chain-company/ProvincePaidFeesChainCompany.js new file mode 100644 index 0000000..b531a3a --- /dev/null +++ b/src/features/province/components/province-paid-fees-chain-company/ProvincePaidFeesChainCompany.js @@ -0,0 +1,300 @@ +import { + Button, + Checkbox, + FormControlLabel, + TextField, + Tooltip, + Typography, +} from "@mui/material"; +import axios from "axios"; +import { useContext, useEffect, useState } from "react"; +import { RiFileExcel2Fill, RiSearchLine } from "react-icons/ri"; +import { useSelector } from "react-redux"; +import { useNavigate } from "react-router-dom"; +import { Grid } from "../../../../components/grid/Grid"; +import { PageTable } from "../../../../components/page-table/PageTable"; +import { SPACING } from "../../../../data/spacing"; +import { + ROUTE_ADMINX_PAYING_FEES_REQUESTS, + ROUTE_PROVINCE_PAYING_FEES_REQUESTS, + ROUTE_SUPER_ADMIN_PAYING_FEES_REQUESTS, +} from "../../../../routes/routes"; +import moment from "moment"; +import { DatePicker } from "@mui/x-date-pickers"; +import { AppContext } from "../../../../contexts/AppContext"; +import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl"; + +export const ProvincePaidFeesChainCompany = () => { + const authToken = useSelector((state) => state.userSlice.authToken); + const navigate = useNavigate(); + const [data, setData] = useState([]); + const [loading, setLoading] = useState(false); + const [totalRows, setTotalRows] = useState(0); + const [perPage, setPerPage] = useState(10); + const [withDate, setWithDate] = useState(false); + + const [textValue, setTextValue] = useState(""); + + const handleTextChange = (event) => { + setTextValue(event.target.value); + }; + + const [, , selectedDate1, setSelectedDate1, selectedDate2, setSelectedDate2] = + useContext(AppContext); + + useEffect(() => { + const currentDate = moment(new Date()).format("YYYY-MM-DD"); + setSelectedDate1(currentDate); + setSelectedDate2(currentDate); + }, []); + + const fetchApiData = async (page, textValue) => { + setLoading(true); + const response = await axios.get( + `chain-company-total-transactions/?search=filter&value=${textValue}&type=paid&page=${page}&role=${getRoleFromUrl()}&page_size=${perPage}${ + withDate ? `&date1=${selectedDate1}&date2=${selectedDate2}` : `` + }` + ); + setData(response.data.results); + setTotalRows(response.data.count); + setLoading(false); + }; + + const handlePageChange = (page) => { + fetchApiData(page, textValue); + }; + + const handlePerRowsChange = async (newPerPage, page) => { + setLoading(true); + const response = await axios.get( + `chain-company-total-transactions/?search=filter&value=${textValue}&type=paid&page=${page}&role=${getRoleFromUrl()}&page_size=${newPerPage}${ + withDate ? `&date1=${selectedDate1}&date2=${selectedDate2}` : `` + }` + ); + + setData(response.data.results); + setTotalRows(response.data.count); + setPerPage(newPerPage); + + setLoading(false); + }; + + useEffect(() => { + fetchApiData(1); + }, []); + + const handleSubmit = async (event) => { + event.preventDefault(); + setLoading(true); + + try { + const response = await axios.get( + `chain-company-total-transactions/?search=filter&value=${textValue}&role=${getRoleFromUrl()}&type=paid${ + withDate ? `&date1=${selectedDate1}&date2=${selectedDate2}` : `` + }` + ); + setData(response.data.results); + setTotalRows(response.data.count); + } catch (error) { + console.error("Error fetching data:", error); + } finally { + setLoading(false); + } + }; + + useEffect(() => { + fetchApiData(1); + }, [selectedDate1, selectedDate2, withDate]); + + const columns = [ + { + name: "خریدار", + selector: (item) => { + return `${item?.info?.company} - ${item?.info?.companyUserFullname} (${item?.info?.companyUserMobile})`; + }, + sortable: true, + wrap: true, + allowOverflow: true, + center: true, + // width: "90px", + }, + { + name: "شهر", + selector: (item) => `${item?.info?.companyUserCity}`, + sortable: true, + wrap: true, + allowOverflow: true, + center: true, + // width: "80px", + }, + { + name: "تعداد تراکنش", + selector: (item) => item?.info?.totalPaidCount, + sortable: true, + wrap: true, + allowOverflow: true, + center: true, + // width: "90px", + }, + { + name: "سهم شما از واریزی (﷼)", + selector: (item) => item?.info?.totalPaidWage?.toLocaleString(), + sortable: true, + wrap: true, + allowOverflow: true, + center: true, + // width: "90px", + }, + { + name: "جزییات سفارش", + selector: (item) => { + return ( + + ); + }, + sortable: true, + wrap: true, + allowOverflow: true, + center: true, + // width: "90px", + }, + ]; + + return ( + + + + پرداختی های شرکت های زنجیره + + + setWithDate(!withDate)} + color="primary" + /> + } + /> + + + ( + + )} + value={selectedDate1} + onChange={(e) => { + setSelectedDate1(moment(e).format("YYYY-MM-DD")); + }} + /> + + + ( + + )} + value={selectedDate2} + onChange={(e) => { + setSelectedDate2(moment(e).format("YYYY-MM-DD")); + }} + /> + + +
    + + + + + + + + +
    +
    + } + columns={columns} + data={data} + progressPending={loading} + pagination + paginationServer + paginationTotalRows={totalRows} + onChangeRowsPerPage={handlePerRowsChange} + onChangePage={handlePageChange} + /> + + ); +}; diff --git a/src/features/province/components/province-paid-fees/ProvincePaidFees.js b/src/features/province/components/province-paid-fees/ProvincePaidFees.js new file mode 100644 index 0000000..3746f50 --- /dev/null +++ b/src/features/province/components/province-paid-fees/ProvincePaidFees.js @@ -0,0 +1,268 @@ +import { + Button, + Checkbox, + FormControlLabel, + IconButton, + TextField, + Tooltip, +} from "@mui/material"; +import axios from "axios"; +import { useContext, useEffect, useState } from "react"; +import { RiFileExcel2Fill } from "react-icons/ri"; +import { useDispatch, useSelector } from "react-redux"; +import { useNavigate } from "react-router-dom"; +import { Grid } from "../../../../components/grid/Grid"; +import { SPACING } from "../../../../data/spacing"; +import { + ROUTE_ADMINX_PAYING_FEES_REQUESTS, + ROUTE_COMMERCE_PAYING_FEES_REQUESTS, + ROUTE_PROVINCE_PAYING_FEES_REQUESTS, + ROUTE_SUPER_ADMIN_PAYING_FEES_REQUESTS, +} from "../../../../routes/routes"; +import moment from "moment"; +import { DatePicker } from "@mui/x-date-pickers"; +import { AppContext } from "../../../../contexts/AppContext"; +import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl"; +import { + LOADING_END, + LOADING_START, +} from "../../../../lib/redux/slices/appSlice"; +import ResponsiveTable from "../../../../components/responsive-table/ResponsiveTable"; +import { RiSearchLine } from "react-icons/ri"; +import VisibilityIcon from "@mui/icons-material/Visibility"; + +export const ProvincePaidFees = () => { + const navigate = useNavigate(); + const [data, setData] = useState([]); + const [totalRows, setTotalRows] = useState(0); + const [perPage, setPerPage] = useState(10); + const [withDate, setWithDate] = useState(false); + const userKey = useSelector((state) => state.userSlice.userProfile.key); + const [textValue, setTextValue] = useState(""); + const [tableData, setTableData] = useState([]); + const [page, setPage] = useState(1); + const dispatch = useDispatch(); + + const handleTextChange = (event) => { + setTextValue(event.target.value); + }; + + const [, , selectedDate1, setSelectedDate1, selectedDate2, setSelectedDate2] = + useContext(AppContext); + + useEffect(() => { + const currentDate = moment(new Date()).format("YYYY-MM-DD"); + setSelectedDate1(currentDate); + setSelectedDate2(currentDate); + }, []); + + const fetchApiData = async (page) => { + let response; + dispatch(LOADING_START()); + response = await axios.get( + `kill_house_total_transactions_wage/?search=filter&value=${textValue}&type=paid&page=${page}&role=${getRoleFromUrl()}&page_size=${perPage}${ + withDate ? `&date1=${selectedDate1}&date2=${selectedDate2}` : `` + }` + ); + dispatch(LOADING_END()); + setData(response.data.results); + setTotalRows(response.data.count); + }; + + const handlePageChange = (page) => { + fetchApiData(page); + setPage(page); + }; + + const handlePerRowsChange = (perRows) => { + setPerPage(perRows); + setPage(1); + }; + useEffect(() => { + fetchApiData(1); + }, []); + + const handleSubmit = async (event) => { + event.preventDefault(); + dispatch(LOADING_START()); + + try { + const response = await axios.get( + `kill_house_total_transactions_wage/?search=filter&value=${textValue}&role=${getRoleFromUrl()}&type=paid${ + withDate ? `&date1=${selectedDate1}&date2=${selectedDate2}` : `` + }` + ); + setData(response.data.results); + setTotalRows(response.data.count); + dispatch(LOADING_END()); + } catch (error) { + console.error("Error fetching data:", error); + } + }; + + useEffect(() => { + fetchApiData(1); + }, [selectedDate1, selectedDate2, withDate]); + + useEffect(() => { + const d = data?.map((item, i) => { + return [ + page === 1 ? i + 1 : i + perPage * (page - 1) + 1, + `${item?.info?.killer ? "کشتارکن" : "کشتارگاه"} ${ + item?.info?.killHouseName + } - ${item?.info?.killHouseFullname} (${item?.info?.killHouseMobile})`, + `${item?.info?.killHouseCity}`, + item?.info?.totalPaidCount, + item?.info?.totalPaidWage?.toLocaleString(), + { + navigate( + getRoleFromUrl() === "ProvinceOperator" + ? `${ROUTE_PROVINCE_PAYING_FEES_REQUESTS}/kill_house_key/${item.key}` + : getRoleFromUrl() === "SuperAdmin" + ? `${ROUTE_SUPER_ADMIN_PAYING_FEES_REQUESTS}/kill_house_key/${item.key}` + : getRoleFromUrl() === "AdminX" + ? `${ROUTE_ADMINX_PAYING_FEES_REQUESTS}/kill_house_key/${item.key}` + : getRoleFromUrl() === "Commerce" + ? `${ROUTE_COMMERCE_PAYING_FEES_REQUESTS}/kill_house_key/${item.key}` + : "-" + ); + }} + > + + , + ]; + }); + + setTableData(d); + }, [data]); + + return ( + + + + + + setWithDate(!withDate)} + color="primary" + /> + } + /> + + + ( + + )} + value={selectedDate1} + onChange={(e) => { + setSelectedDate1(moment(e).format("YYYY-MM-DD")); + }} + /> + + + ( + + )} + value={selectedDate2} + onChange={(e) => { + setSelectedDate2(moment(e).format("YYYY-MM-DD")); + }} + /> + + +
    + + + + + + + + +
    +
    + +
    + ); +}; diff --git a/src/features/province/components/province-payment-by-weight-killhouses/ProvincePaymentByWeightKillhouses.js b/src/features/province/components/province-payment-by-weight-killhouses/ProvincePaymentByWeightKillhouses.js new file mode 100644 index 0000000..e125cc7 --- /dev/null +++ b/src/features/province/components/province-payment-by-weight-killhouses/ProvincePaymentByWeightKillhouses.js @@ -0,0 +1,608 @@ +import React, { useContext, useEffect, useState } from "react"; +import { Grid } from "../../../../components/grid/Grid"; +import { useDispatch, useSelector } from "react-redux"; +import { provincePaymentByWeightGetKillHousesService } from "../../services/province-payment-by-weight-killhouse"; +import ResponsiveTable from "../../../../components/responsive-table/ResponsiveTable"; +import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl"; +import { + Button, + Checkbox, + FormControlLabel, + TextField, + Tooltip, +} from "@mui/material"; +import { RiFileExcel2Fill } from "react-icons/ri"; +import { DatePicker } from "@mui/x-date-pickers"; +import moment from "moment"; +import axios from "axios"; +import { AppContext } from "../../../../contexts/AppContext"; +import { SPACING } from "../../../../data/spacing"; +import { provincePaymentByWeightGetDashboard } from "../../services/province-payment-by-weight-dashboard"; + +export const ProvincePaymentByWeightKillhouses = () => { + const [tableData, setTableData] = useState([]); + const dispatch = useDispatch(); + const [withDate, setWithDate] = useState(false); + + const [, , selectedDate1, setSelectedDate1, selectedDate2, setSelectedDate2] = + useContext(AppContext); + + useEffect(() => { + const currentDate = moment(new Date()).format("YYYY-MM-DD"); + setSelectedDate1(currentDate); + setSelectedDate2(currentDate); + }, []); + + const [dashboardData, setDashboardData] = useState([]); + + useEffect(() => { + dispatch( + provincePaymentByWeightGetDashboard({ + selectedDate1, + selectedDate2, + withDate, + }) + ).then((r) => { + setDashboardData(r.payload.data); + }); + }, [selectedDate1, selectedDate2, withDate]); + + const getData = () => { + dispatch( + provincePaymentByWeightGetKillHousesService({ + selectedDate1, + selectedDate2, + withDate, + }) + ).then((r) => { + let d = []; + switch (getRoleFromUrl()) { + case "AdminX": + d = r.payload?.data?.map((item, i) => { + return [ + i + 1, + item?.info?.type, + item?.info?.killHouseName, + item?.info?.fullname, + item?.info?.mobile, + item?.info?.city, + item?.info?.lenProvinceKillRequests?.toLocaleString(), + item?.info?.totalKilledQuantity?.toLocaleString(), + item?.info?.totalKilledWeight?.toLocaleString(), + item?.info?.lenKillHouseRequests?.toLocaleString(), + item?.info?.acceptedRealQuantity?.toLocaleString(), + item?.info?.acceptedRealWeight?.toLocaleString(), + item?.info?.lenSlaughterTransactions?.toLocaleString(), + item?.info?.off?.toLocaleString(), + item?.info?.totalWage?.toLocaleString(), + item?.info?.companyTotalWage?.toLocaleString(), + item?.info?.unionTotalWage?.toLocaleString(), + item?.info?.guildsTotalWage?.toLocaleString(), + item?.info?.otherTotalWage?.toLocaleString(), + item?.info?.notPaied?.toLocaleString(), + item?.info?.companyTotalUnpaidWage?.toLocaleString(), + item?.info?.unionTotalUnpaidWage?.toLocaleString(), + item?.info?.guildsTotalUnpaidWage?.toLocaleString(), + item?.info?.otherTotalUnpaidWage?.toLocaleString(), + item?.info?.totalPaidWage?.toLocaleString(), + item?.info?.unionTotalPaidWage?.toLocaleString(), + item?.info?.companyTotalPaidWage?.toLocaleString(), + item?.info?.guildsTotalPaidWage?.toLocaleString(), + item?.info?.otherTotalPaidWage?.toLocaleString(), + ]; + }); + break; + case "SuperAdmin": + d = r.payload?.data?.map((item, i) => { + return [ + i + 1, + item?.info?.type, + item?.info?.killHouseName, + item?.info?.fullname, + item?.info?.mobile, + item?.info?.city, + item?.info?.lenProvinceKillRequests?.toLocaleString(), + item?.info?.totalKilledQuantity?.toLocaleString(), + item?.info?.totalKilledWeight?.toLocaleString(), + item?.info?.lenKillHouseRequests?.toLocaleString(), + item?.info?.acceptedRealQuantity?.toLocaleString(), + item?.info?.acceptedRealWeight?.toLocaleString(), + item?.info?.lenSlaughterTransactions?.toLocaleString(), + item?.info?.off?.toLocaleString(), + item?.info?.totalWage?.toLocaleString(), + item?.info?.companyTotalWage?.toLocaleString(), + item?.info?.unionTotalWage?.toLocaleString(), + item?.info?.guildsTotalWage?.toLocaleString(), + item?.info?.notPaied?.toLocaleString(), + item?.info?.companyTotalUnpaidWage?.toLocaleString(), + item?.info?.unionTotalUnpaidWage?.toLocaleString(), + item?.info?.guildsTotalUnpaidWage?.toLocaleString(), + item?.info?.totalPaidWage?.toLocaleString(), + item?.info?.unionTotalPaidWage?.toLocaleString(), + item?.info?.companyTotalPaidWage?.toLocaleString(), + item?.info?.guildsTotalPaidWage?.toLocaleString(), + ]; + }); + break; + case "ProvinceOperator": + d = r.payload?.data?.map((item, i) => { + return [ + i + 1, + item?.info?.type, + item?.info?.killHouseName, + item?.info?.fullname, + item?.info?.mobile, + item?.info?.city, + item?.info?.totalKilledQuantity?.toLocaleString(), + item?.info?.totalKilledWeight?.toLocaleString(), + item?.info?.lenKillHouseRequests?.toLocaleString(), + item?.info?.acceptedRealQuantity?.toLocaleString(), + item?.info?.acceptedRealWeight?.toLocaleString(), + item?.info?.lenSlaughterTransactions?.toLocaleString(), + item?.info?.unionTotalWage?.toLocaleString(), + item?.info?.unionTotalUnpaidWage?.toLocaleString(), + item?.info?.unionTotalPaidWage?.toLocaleString(), + ]; + }); + break; + default: + d = r.payload?.data?.map((item, i) => { + return [ + i + 1, + item?.info?.type, + item?.info?.killHouseName, + item?.info?.fullname, + item?.info?.mobile, + item?.info?.city, + item?.info?.lenProvinceKillRequests?.toLocaleString(), + item?.info?.totalKilledQuantity?.toLocaleString(), + item?.info?.totalKilledWeight?.toLocaleString(), + item?.info?.lenKillHouseRequests?.toLocaleString(), + item?.info?.acceptedRealQuantity?.toLocaleString(), + item?.info?.acceptedRealWeight?.toLocaleString(), + item?.info?.lenSlaughterTransactions?.toLocaleString(), + item?.info?.unionTotalWage?.toLocaleString(), + item?.info?.unionTotalUnpaidWage?.toLocaleString(), + item?.info?.unionTotalPaidWage?.toLocaleString(), + ]; + }); + break; + } + + setTableData(d); + }); + }; + + const userKey = useSelector((state) => state.userSlice.userProfile.key); + + useEffect(() => { + getData(); + }, []); + + return ( + + + + + + setWithDate(!withDate)} + color="primary" + /> + } + /> + + + ( + + )} + value={selectedDate1} + onChange={(e) => { + setSelectedDate1(moment(e).format("YYYY-MM-DD")); + }} + /> + + + ( + + )} + value={selectedDate2} + onChange={(e) => { + setSelectedDate2(moment(e).format("YYYY-MM-DD")); + }} + /> + + + + + {(getRoleFromUrl() === "SuperAdmin" || + getRoleFromUrl() === "AdminX") && ( + + + + + + )} + + + + + + + + + + ); +}; diff --git a/src/features/province/components/province-payment-by-weight-overview/ProvincePaymentByWeightOverview.js b/src/features/province/components/province-payment-by-weight-overview/ProvincePaymentByWeightOverview.js new file mode 100644 index 0000000..be3a88d --- /dev/null +++ b/src/features/province/components/province-payment-by-weight-overview/ProvincePaymentByWeightOverview.js @@ -0,0 +1,1076 @@ +import { + Accordion, + AccordionDetails, + AccordionSummary, + Button, + Checkbox, + IconButton, + TextField, + Tooltip, + Typography, +} from "@mui/material"; +import React, { useContext, useEffect, useState } from "react"; +import { Grid } from "../../../../components/grid/Grid"; +import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl"; +import { ProvincePaymentPayDept } from "../province-payment-pay-dept/ProvincePaymentPayDept"; +import { OPEN_MODAL } from "../../../../lib/redux/slices/appSlice"; +import { useDispatch, useSelector } from "react-redux"; +import ArrowDownwardIcon from "@mui/icons-material/ArrowDownward"; +import { provincePaymentGetKillersOfKillhousesInfo } from "../../services/province-payment-get-killers-of-killhouses-info"; +import ResponsiveTable from "../../../../components/responsive-table/ResponsiveTable"; +import { provinceGetWagesOfKillhousesService } from "../../services/province-get-wages-of-killhouses"; +import { provinceGetPaymentByWeightOverview } from "../../services/province-get-payment-by-weight-overview"; +import { getSystemBaseAddress } from "../../../../utils/getSystemBaseAddress"; +import { SimpleTable } from "../../../../components/simple-table/SimpleTable"; +import { AppContext } from "../../../../contexts/AppContext"; +import axios from "axios"; +import SystemUpdateAltIcon from "@mui/icons-material/SystemUpdateAlt"; +import VisibilityIcon from "@mui/icons-material/Visibility"; +import moment from "moment"; +import { DatePicker } from "@mui/x-date-pickers"; +import ToggleOffOutlinedIcon from "@mui/icons-material/ToggleOffOutlined"; +import ToggleOnIcon from "@mui/icons-material/ToggleOn"; +import { useNavigate } from "react-router-dom"; +import { + ROUTE_ADMINX_ROUTE_KILLERS_WAGES, + ROUTE_PROVINCE_ROUTE_KILLERS_WAGES, + ROUTE_SUPER_ADMIN_ROUTE_KILLERS_WAGES, +} from "../../../../routes/routes"; +import { checkPathStartsWith } from "../../../../utils/checkPathStartsWith"; + +export const ProvincePaymentByWeightOverviewTable = () => { + const dispatch = useDispatch(); + const [tableData, setTableData] = useState(); + const [tableDataShares, setTableDataShares] = useState([]); + const [tableDataOfWages, setTableDataOfWages] = useState(); + const { provincePaymentKillersOfKillhouses } = useSelector( + (item) => item.provinceSlice + ); + const userPath = useSelector((state) => state.userSlice.userPath); + const [openNotif] = useContext(AppContext); + const userKey = useSelector((state) => state.userSlice.userProfile.key); + const selectedSubUser = useSelector( + (state) => state.userSlice.selectedSubUser + ); + const [withDate, setWithDate] = useState(false); + + const navigate = useNavigate(); + + const [, , selectedDate1, setSelectedDate1, selectedDate2, setSelectedDate2] = + useContext(AppContext); + useEffect(() => { + const currentDate = moment(new Date()).format("YYYY-MM-DD"); + setSelectedDate1(currentDate); + setSelectedDate2(currentDate); + }, []); + + useEffect(() => { + if (getRoleFromUrl() === "KillHouse") { + dispatch( + provincePaymentGetKillersOfKillhousesInfo({ + role_key: checkPathStartsWith("province") + ? selectedSubUser?.key || "" + : "", + }) + ); + } + }, [selectedSubUser?.key]); + + const { provincePaymentByWeightOverview } = useSelector( + (item) => item.provinceSlice + ); + + useEffect(() => { + const d = provincePaymentByWeightOverview?.wageInfo?.shares?.map( + (item, i) => { + return [ + i + 1, + item?.name, + item?.outProvincePoultryRequestWage?.toLocaleString(), + item?.provinceKillRequestWage?.toLocaleString(), + item?.freeSellCarcassesWage?.toLocaleString(), + item?.freeBuyingCarcassesWage?.toLocaleString(), + item?.freeBuyingLiveWage?.toLocaleString(), + parseInt(Math.floor(item?.totalWage / 1000) * 1000)?.toLocaleString(), + parseInt( + Math.floor(item?.totalPaidWage / 1000) * 1000 + )?.toLocaleString(), + parseInt( + Math.floor(item?.totalUnpaidWage / 1000) * 1000 + )?.toLocaleString(), + ]; + } + ); + + setTableDataShares(d); + }, [provincePaymentByWeightOverview]); + + useEffect(() => { + dispatch( + provinceGetPaymentByWeightOverview({ + date1: withDate ? selectedDate1 : null, + date2: withDate ? selectedDate2 : null, + role: getRoleFromUrl(), + role_key: checkPathStartsWith("province") + ? selectedSubUser?.key || "" + : "", + }) + ); + }, [dispatch, selectedDate1, selectedDate2, withDate, selectedSubUser?.key]); + + useEffect(() => { + if (provincePaymentByWeightOverview) { + const d = provincePaymentKillersOfKillhouses?.map((item, i) => { + if ( + provincePaymentByWeightOverview?.wageInfo?.wageCountingType === "live" + ) { + return [ + item?.name, + Math.ceil(item?.wageInfo?.totalWage)?.toLocaleString(), + Math.ceil(item?.wageInfo?.totalPaidWage)?.toLocaleString(), + Math.ceil(item?.wageInfo?.off)?.toLocaleString(), + Math.ceil(item?.wageInfo?.totalUnpaidWage)?.toLocaleString(), + {`${window.location.origin}/pay/${getSystemBaseAddress( + userPath + )}/${item?.wageInfo?.userToken}`}, + Math.ceil( + item?.wageInfo?.totalProvinceLiveWeight + )?.toLocaleString(), + Math.ceil( + item?.wageInfo?.provinceKillRequestsTotalWage + )?.toLocaleString(), + Math.ceil( + item?.wageInfo?.freeBarsOutProvinceCarcasesTotalWeight + )?.toLocaleString(), + Math.ceil( + item?.wageInfo?.freeBarsOutProvinceCarcasesTotalWage + )?.toLocaleString(), + Math.ceil( + item?.wageInfo?.freeBarsCarcasesTotalWeight + )?.toLocaleString(), + Math.ceil( + item?.wageInfo?.freeBarsCarcasesTotalWage + )?.toLocaleString(), + Math.ceil( + item?.wageInfo?.freeBarsLiveTotalWeight + )?.toLocaleString(), + Math.ceil(item?.wageInfo?.freeBarsLiveTotalWage)?.toLocaleString(), + ]; + } else { + return [ + item?.name, + Math.ceil(item?.wageInfo?.totalWage)?.toLocaleString(), + Math.ceil(item?.wageInfo?.totalPaidWage)?.toLocaleString(), + Math.ceil(item?.wageInfo?.off)?.toLocaleString(), + Math.ceil(item?.wageInfo?.totalUnpaidWage)?.toLocaleString(), + {`${window.location.origin}/pay/${getSystemBaseAddress( + userPath + )}/${item?.wageInfo?.userToken}`}, + Math.ceil( + item?.wageInfo?.totalProvinceLiveWeight + )?.toLocaleString(), + Math.ceil( + item?.wageInfo?.totalProvinceCarcassesWeight + )?.toLocaleString(), + Math.ceil( + item?.wageInfo?.provinceKillRequestsTotalWeight + )?.toLocaleString(), + Math.ceil( + item?.wageInfo?.provinceKillRequestsTotalWage + )?.toLocaleString(), + Math.ceil( + item?.wageInfo?.freeBarsOutProvinceCarcasesTotalWeight + )?.toLocaleString(), + Math.ceil( + item?.wageInfo?.freeBarsOutProvinceCarcasesTotalWage + )?.toLocaleString(), + Math.ceil( + item?.wageInfo?.freeBarsCarcasesTotalWeight + )?.toLocaleString(), + Math.ceil( + item?.wageInfo?.freeBarsCarcasesTotalWage + )?.toLocaleString(), + Math.ceil( + item?.wageInfo?.freeBarsLiveTotalWeight + )?.toLocaleString(), + Math.ceil(item?.wageInfo?.freeBarsLiveTotalWage)?.toLocaleString(), + ]; + } + }); + + setTableData(d); + } + }, [provincePaymentKillersOfKillhouses, provincePaymentByWeightOverview]); + + const getKillHouseShares = (item, name) => { + const d = item?.map((item, i) => { + return [ + i + 1, + item?.name, + item?.provinceKillRequestWage?.toLocaleString(), + item?.returnProvinceKillRequestWage?.toLocaleString(), + item?.freeSellCarcassesWage?.toLocaleString(), + item?.freeBuyingCarcassesWage?.toLocaleString(), + item?.freeBuyingLiveWage?.toLocaleString(), + parseInt(Math.floor(item?.totalWage / 1000) * 1000)?.toLocaleString(), + parseInt( + Math.floor(item?.totalPaidWage / 1000) * 1000 + )?.toLocaleString(), + parseInt( + Math.floor(item?.totalUnpaidWage / 1000) * 1000 + )?.toLocaleString(), + ]; + }); + return ( + { + dispatch( + OPEN_MODAL({ + title: "سهم بندی تعرفه کشتارگاه " + name, + size: 1000, + content: ( + + + + ), + }) + ); + }} + > + + + ); + }; + + useEffect(() => { + if (getRoleFromUrl() !== "KillHouse" && provincePaymentByWeightOverview) { + dispatch( + provinceGetWagesOfKillhousesService({ + date1: withDate ? selectedDate1 : null, + date2: withDate ? selectedDate2 : null, + role_key: checkPathStartsWith("province") + ? selectedSubUser?.key || "" + : "", + }) + ).then((r) => { + const d = r.payload.data?.map((item, i) => { + if ( + provincePaymentByWeightOverview?.wageInfo?.wageCountingType === + "live" + ) { + return [ + i + 1, + item?.name, + Math.ceil(item?.wageInfo?.totalWage)?.toLocaleString(), + getKillHouseShares(item?.shares, item?.name), + Math.ceil(item?.wageInfo?.totalPaidWage)?.toLocaleString(), + Math.ceil(item?.wageInfo?.off)?.toLocaleString(), + Math.ceil(item?.wageInfo?.totalUnpaidWage)?.toLocaleString(), + Math.ceil( + item?.wageInfo?.totalProvinceLiveWeight + )?.toLocaleString(), + Math.ceil( + item?.wageInfo?.provinceKillRequestsTotalWage + )?.toLocaleString(), + Math.ceil( + item?.wageInfo?.freeBarsOutProvinceCarcasesTotalWeight + )?.toLocaleString(), + Math.ceil( + item?.wageInfo?.freeBarsOutProvinceCarcasesTotalWage + )?.toLocaleString(), + Math.ceil( + item?.wageInfo?.freeBarsCarcasesTotalWeight + )?.toLocaleString(), + Math.ceil( + item?.wageInfo?.freeBarsCarcasesTotalWage + )?.toLocaleString(), + Math.ceil( + item?.wageInfo?.freeBarsLiveTotalWeight + )?.toLocaleString(), + Math.ceil( + item?.wageInfo?.freeBarsLiveTotalWage + )?.toLocaleString(), + Math.ceil( + item?.wageInfo?.returnTotalProvinceLiveWeight + )?.toLocaleString(), + Math.ceil( + item?.wageInfo?.totalReturnPureProvinceCarcassesPrice + )?.toLocaleString(), + { + navigate( + getRoleFromUrl() === "ProvinceOperator" + ? ROUTE_PROVINCE_ROUTE_KILLERS_WAGES + "/" + item?.key + : getRoleFromUrl() === "SuperAdmin" + ? ROUTE_SUPER_ADMIN_ROUTE_KILLERS_WAGES + "/" + item?.key + : ROUTE_ADMINX_ROUTE_KILLERS_WAGES + "/" + item?.key + ); + }} + > + + , + ]; + } else { + return [ + i + 1, + item?.name, + Math.ceil(item?.wageInfo?.totalWage)?.toLocaleString(), + getKillHouseShares(item?.shares, item?.name), + Math.ceil(item?.wageInfo?.totalPaidWage)?.toLocaleString(), + Math.ceil(item?.wageInfo?.off)?.toLocaleString(), + Math.ceil(item?.wageInfo?.totalUnpaidWage)?.toLocaleString(), + Math.ceil( + item?.wageInfo?.totalProvinceLiveWeight + )?.toLocaleString(), + Math.ceil( + item?.wageInfo?.totalProvinceCarcassesWeight + )?.toLocaleString(), + Math.ceil( + item?.wageInfo?.provinceKillRequestsTotalWeight + )?.toLocaleString(), + Math.ceil( + item?.wageInfo?.provinceKillRequestsTotalWage + )?.toLocaleString(), + Math.ceil( + item?.wageInfo?.freeBarsOutProvinceCarcasesTotalWeight + )?.toLocaleString(), + Math.ceil( + item?.wageInfo?.freeBarsOutProvinceCarcasesTotalWage + )?.toLocaleString(), + Math.ceil( + item?.wageInfo?.freeBarsCarcasesTotalWeight + )?.toLocaleString(), + Math.ceil( + item?.wageInfo?.freeBarsCarcasesTotalWage + )?.toLocaleString(), + Math.ceil( + item?.wageInfo?.freeBarsLiveTotalWeight + )?.toLocaleString(), + Math.ceil( + item?.wageInfo?.freeBarsLiveTotalWage + )?.toLocaleString(), + Math.ceil( + item?.wageInfo?.returnTotalProvinceLiveWeight + )?.toLocaleString(), + Math.ceil( + item?.wageInfo?.totalReturnPureProvinceCarcassesPrice + )?.toLocaleString(), + { + navigate( + getRoleFromUrl() === "ProvinceOperator" + ? ROUTE_PROVINCE_ROUTE_KILLERS_WAGES + "/" + item?.key + : getRoleFromUrl() === "SuperAdmin" + ? ROUTE_SUPER_ADMIN_ROUTE_KILLERS_WAGES + "/" + item?.key + : ROUTE_ADMINX_ROUTE_KILLERS_WAGES + "/" + item?.key + ); + }} + > + + , + ]; + } + }); + + setTableDataOfWages(d); + }); + } + }, [ + dispatch, + provincePaymentByWeightOverview, + selectedDate1, + selectedDate2, + withDate, + ]); + + const getWageDetailsColumns = () => { + if ( + provincePaymentByWeightOverview?.wageInfo?.wageCountingType === "live" + ) { + return [ + "وزن کل فروش زنده به خارج استان", + "تعرفه کل فروش به خارج استان (ریال)", + "کل وزن زنده کشتار داخل استان (کیلوگرم)", + "تعرفه کشتار داخل استان (ریال)", + "وزن توزیع لاشه به خارج استان (کیلوگرم)", + "تعرفه توزیع لاشه خارج استان (ریال)", + "وزن لاشه ورودی به استان (کیلوگرم)", + "تعرفه لاشه ورودی به استان (ریال)", + "وزن مرغ زنده ورودی به استان (کیلوگرم)", + "تعرفه مرغ زنده ورودی به استان (ریال)", + "وزن خریدهای بازگشتی (کیلوگرم)", + "تعرفه خریدهای بازگشتی (ریال)", + ]; + } else { + return [ + "وزن کل فروش زنده به خارج استان", + "تعرفه کل فروش به خارج استان (ریال)", + "کل وزن زنده کشتار داخل استان (کیلوگرم)", + "وزن لاشه کشتار داخل استان (کیلوگرم)", + "وزن توزیع لاشه داخل استان (کیلوگرم)", + "تعرفه توزیع لاشه داخل استان (ریال)", + "وزن توزیع لاشه به خارج استان (کیلوگرم)", + "تعرفه توزیع لاشه خارج استان (ریال)", + "وزن لاشه ورودی به استان (کیلوگرم)", + "تعرفه لاشه ورودی به استان (ریال)", + "وزن مرغ زنده ورودی به استان (کیلوگرم)", + "تعرفه مرغ زنده ورودی به استان (ریال)", + "وزن خریدهای بازگشتی (کیلوگرم)", + "تعرفه خریدهای بازگشتی (ریال)", + ]; + } + }; + + const getDetailsKillhouseColumns = () => { + if ( + provincePaymentByWeightOverview?.wageInfo?.wageCountingType === "live" + ) { + return [ + "کل تعرفه (ریال)", + "کل تعرفه پرداخت شده (ریال)", + "تخفیف (ریال)", + "کل تعرفه پرداخت نشده (ریال)", + "کل وزن زنده کشتار داخل استان (کیلوگرم)", + "تعرفه کشتار داخل استان (ریال)", + "وزن توزیع لاشه به خارج استان (کیلوگرم)", + "تعرفه توزیع لاشه خارج استان (ریال)", + "وزن لاشه ورودی به استان (کیلوگرم)", + "تعرفه لاشه ورودی به استان (ریال)", + "وزن مرغ زنده ورودی به استان (کیلوگرم)", + "تعرفه مرغ زنده ورودی به استان (ریال)", + ]; + } else { + return [ + "کل تعرفه (ریال)", + "کل تعرفه پرداخت شده (ریال)", + "تخفیف (ریال)", + "کل تعرفه پرداخت نشده (ریال)", + "کل وزن زنده کشتار داخل استان (کیلوگرم)", + "وزن لاشه کشتار داخل استان (کیلوگرم)", + "وزن توزیع لاشه داخل استان (کیلوگرم)", + "تعرفه توزیع لاشه داخل استان (ریال)", + "وزن توزیع لاشه به خارج استان (کیلوگرم)", + "تعرفه توزیع لاشه خارج استان (ریال)", + "وزن لاشه ورودی به استان (کیلوگرم)", + "تعرفه لاشه ورودی به استان (ریال)", + "وزن مرغ زنده ورودی به استان (کیلوگرم)", + "تعرفه مرغ زنده ورودی به استان (ریال)", + ]; + } + }; + + const getDetailsAllKillhousesColumns = () => { + if ( + provincePaymentByWeightOverview?.wageInfo?.wageCountingType === "live" + ) { + return [ + "ردیف", + "کشتارگاه", + "کل تعرفه (ریال)", + "سهم بندی", + "کل تعرفه پرداخت شده (ریال)", + "تخفیف (ریال)", + "کل تعرفه پرداخت نشده (ریال)", + "کل وزن زنده کشتار داخل استان (کیلوگرم)", + "تعرفه کشتار داخل استان (ریال)", + "وزن توزیع لاشه به خارج استان (کیلوگرم)", + "تعرفه توزیع لاشه خارج استان (ریال)", + "وزن لاشه ورودی به استان (کیلوگرم)", + "تعرفه لاشه ورودی به استان (ریال)", + "وزن مرغ زنده ورودی به استان (کیلوگرم)", + "تعرفه مرغ زنده ورودی به استان (ریال)", + "وزن خریدهای بازگشتی (کیلوگرم)", + "تعرفه خریدهای بازگشتی (ریال)", + "کشتارکن", + ]; + } else { + return [ + "ردیف", + "کشتارگاه", + "کل تعرفه (ریال)", + "سهم بندی", + "کل تعرفه پرداخت شده (ریال)", + "تخفیف (ریال)", + "کل تعرفه پرداخت نشده (ریال)", + "کل وزن زنده کشتار داخل استان (کیلوگرم)", + "وزن لاشه کشتار داخل استان (کیلوگرم)", + "وزن توزیع لاشه داخل استان (کیلوگرم)", + "تعرفه توزیع لاشه داخل استان (ریال)", + "وزن توزیع لاشه به خارج استان (کیلوگرم)", + "تعرفه توزیع لاشه خارج استان (ریال)", + "وزن لاشه ورودی به استان (کیلوگرم)", + "تعرفه لاشه ورودی به استان (ریال)", + "وزن مرغ زنده ورودی به استان (کیلوگرم)", + "تعرفه مرغ زنده ورودی به استان (ریال)", + "وزن خریدهای بازگشتی (کیلوگرم)", + "تعرفه خریدهای بازگشتی (ریال)", + "کشتارکن", + ]; + } + }; + + const getDetailsKillhouseData = () => { + if ( + provincePaymentByWeightOverview?.wageInfo?.wageCountingType === "live" + ) { + return [ + [ + Math.ceil( + provincePaymentByWeightOverview?.wageInfo?.totalWage + )?.toLocaleString(), + Math.ceil( + provincePaymentByWeightOverview?.wageInfo?.totalPaidWage + )?.toLocaleString(), + Math.ceil( + provincePaymentByWeightOverview?.wageInfo?.off + )?.toLocaleString(), + Math.ceil( + provincePaymentByWeightOverview?.wageInfo?.totalUnpaidWage + )?.toLocaleString(), + Math.ceil( + provincePaymentByWeightOverview?.wageInfo?.totalProvinceLiveWeight + )?.toLocaleString(), + Math.ceil( + provincePaymentByWeightOverview?.wageInfo + ?.provinceKillRequestsTotalWage + )?.toLocaleString(), + Math.ceil( + provincePaymentByWeightOverview?.wageInfo + ?.freeBarsOutProvinceCarcasesTotalWeight + )?.toLocaleString(), + Math.ceil( + provincePaymentByWeightOverview?.wageInfo + ?.freeBarsOutProvinceCarcasesTotalWage + )?.toLocaleString(), + Math.ceil( + provincePaymentByWeightOverview?.wageInfo + ?.freeBarsCarcasesTotalWeight + )?.toLocaleString(), + Math.ceil( + provincePaymentByWeightOverview?.wageInfo?.freeBarsCarcasesTotalWage + )?.toLocaleString(), + Math.ceil( + provincePaymentByWeightOverview?.wageInfo?.freeBarsLiveTotalWeight + )?.toLocaleString(), + Math.ceil( + provincePaymentByWeightOverview?.wageInfo?.freeBarsLiveTotalWage + )?.toLocaleString(), + ], + ]; + } else { + return [ + [ + Math.ceil( + provincePaymentByWeightOverview?.wageInfo?.totalWage + )?.toLocaleString(), + Math.ceil( + provincePaymentByWeightOverview?.wageInfo?.totalPaidWage + )?.toLocaleString(), + Math.ceil( + provincePaymentByWeightOverview?.wageInfo?.off + )?.toLocaleString(), + Math.ceil( + provincePaymentByWeightOverview?.wageInfo?.totalUnpaidWage + )?.toLocaleString(), + Math.ceil( + provincePaymentByWeightOverview?.wageInfo?.totalProvinceLiveWeight + )?.toLocaleString(), + Math.ceil( + provincePaymentByWeightOverview?.wageInfo + ?.totalProvinceCarcassesWeight + )?.toLocaleString(), + Math.ceil( + provincePaymentByWeightOverview?.wageInfo + ?.provinceKillRequestsTotalWeight + )?.toLocaleString(), + Math.ceil( + provincePaymentByWeightOverview?.wageInfo + ?.provinceKillRequestsTotalWage + )?.toLocaleString(), + Math.ceil( + provincePaymentByWeightOverview?.wageInfo + ?.freeBarsOutProvinceCarcasesTotalWeight + )?.toLocaleString(), + Math.ceil( + provincePaymentByWeightOverview?.wageInfo + ?.freeBarsOutProvinceCarcasesTotalWage + )?.toLocaleString(), + Math.ceil( + provincePaymentByWeightOverview?.wageInfo + ?.freeBarsCarcasesTotalWeight + )?.toLocaleString(), + Math.ceil( + provincePaymentByWeightOverview?.wageInfo?.freeBarsCarcasesTotalWage + )?.toLocaleString(), + Math.ceil( + provincePaymentByWeightOverview?.wageInfo?.freeBarsLiveTotalWeight + )?.toLocaleString(), + Math.ceil( + provincePaymentByWeightOverview?.wageInfo?.freeBarsLiveTotalWage + )?.toLocaleString(), + ], + ]; + } + }; + + return ( + + + } + checkedIcon={} + checked={withDate} + onChange={() => setWithDate(!withDate)} + color="primary" + size="large" + /> + + ( + + )} + value={selectedDate1} + onChange={(e) => { + setSelectedDate1(moment(e).format("YYYY-MM-DD")); + }} + /> + + + ( + + )} + value={selectedDate2} + onChange={(e) => { + setSelectedDate2(moment(e).format("YYYY-MM-DD")); + }} + /> + + + + + + {(getRoleFromUrl() === "KillHouse" || + getRoleFromUrl() === "ChainCompany") && ( + + + + )} + {/* {(getRoleFromUrl() === "KillHouse" || + getRoleFromUrl() === "ChainCompany") && ( + + + + )} */} + + + {(getRoleFromUrl() === "AdminX" || + getRoleFromUrl() === "ProvinceOperator" || + getRoleFromUrl() === "SuperAdmin") && ( + + { + openNotif({ + vertical: "top", + horizontal: "center", + msg: "فایل اکسل در حال دانلود می باشد، این علمیات ممکن است زمان بر باشد لطفا صبر کنید.", + severity: "success", + }); + const link = `${ + axios.defaults.baseURL + }kill_house_total_transactions_wage_payid_admin_x_excel/?date1=${selectedDate1}&date2=${selectedDate2}&key=${userKey}&role=${getRoleFromUrl()}${ + checkPathStartsWith("province") + ? `&role_key=${selectedSubUser?.key}` + : "" + }`; + window.location.href = link; + }} + > + + + + )} + + } + isDashboard + noPagination + title="اطلاعات کلی تعرفه" + columns={[ + "کل تعرفه (ریال)", + "کل تعرفه پرداخت شده (ریال)", + "تخفیف (ریال)", + "کل تعرفه پرداخت نشده (ریال)", + ]} + data={[ + [ + // Math.ceil( + // provincePaymentByWeightOverview?.wageInfo?.totalWeight + // )?.toLocaleString(), + Math.ceil( + provincePaymentByWeightOverview?.wageInfo?.totalWage + )?.toLocaleString(), + Math.ceil( + provincePaymentByWeightOverview?.wageInfo?.totalPaidWage + )?.toLocaleString(), + Math.ceil( + provincePaymentByWeightOverview?.wageInfo?.off + )?.toLocaleString(), + Math.ceil( + provincePaymentByWeightOverview?.wageInfo?.totalUnpaidWage + )?.toLocaleString(), + ], + ]} + /> + + {getRoleFromUrl() !== "KillHouse" && ( + + )} + + {getRoleFromUrl() !== "KillHouse" && ( + + )} + + + + + + + + + + + {getRoleFromUrl() === "KillHouse" && ( + + } + aria-controls="panel1-content" + id="panel1-header" + > + + کشتارکن ها + + + + + + + + + )} + + ); +}; diff --git a/src/features/province/components/province-payment-by-weight/ProvincePaymentByWeight.js b/src/features/province/components/province-payment-by-weight/ProvincePaymentByWeight.js new file mode 100644 index 0000000..11066a9 --- /dev/null +++ b/src/features/province/components/province-payment-by-weight/ProvincePaymentByWeight.js @@ -0,0 +1,283 @@ +import React, { useEffect, useState } from "react"; +import { useSelector } from "react-redux"; +import { Tab, Tabs, ToggleButton, ToggleButtonGroup } from "@mui/material"; +import { Grid } from "../../../../components/grid/Grid"; +import { SPACING } from "../../../../data/spacing"; +import { TabContext, TabPanel } from "@mui/lab"; +import { ProvincePaymentByWeightOverviewTable } from "../province-payment-by-weight-overview/ProvincePaymentByWeightOverview"; +import { ProvincePaidFees } from "../province-paid-fees/ProvincePaidFees"; +import { ProvincePaidFeesChainCompany } from "../province-paid-fees-chain-company/ProvincePaidFeesChainCompany"; +import { ProvinceUnpaidFees } from "../province-unpaid-fees/ProvinceUnpaidFees"; +import { ProvinceDailyBars } from "../province-daily-bars/ProvinceDailyBars"; +import { ProvincePaymentChcikenAlive } from "../province-payment-chicken-alive/ProvincePaymentChickenAlive"; +import { ProvincePaymentChains } from "../province-payment-chains/ProvincePaymentChains"; +import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl"; +import { ProvinceKillhousePaidFee } from "../province-killhouse-paid-fee/ProvinceKillhousePaidFee"; +import { ProvinceKillhouseFee } from "../province-killhouse-fee/ProvinceKillhouseFee"; +import { ProvinceDailyBarsDetails } from "../province-daily-bars-details/ProvinceDailyBarsDetails"; +import { ProvincePaymentLiveChickenDetails } from "../province-payment-live-chicken-detail/ProvincePaymentLiveChickenDetails"; +import { ProvincePaymentChainDetails } from "../province-payment-chain-detail/ProvincePaymentChainDetails"; +import { ProvinceWagePaymentTransactions } from "../province-wage-payment-transactions/ProvinceWagePaymentTransactions"; +import { ProvincePaymentByWeightKillhouses } from "../province-payment-by-weight-killhouses/ProvincePaymentByWeightKillhouses"; + +export const ProvincePaymentByWeight = () => { + const { slaughterExclusiveState } = useSelector( + (item) => item.slaughterSlice + ); + + const [tabValue, setTabValue] = useState("1"); + + const handleTabChange = (event, newValue) => { + setTabValue(newValue); + }; + const [tabValueWages, setTabValueWages] = useState(); + + const handleTabWagesChange = (event, newValue) => { + setTabValueWages(newValue); + }; + + const [tabValuePayments, setTabValuePayments] = useState("1"); + + const handleTabPaymentsChange = (event, newValue) => { + setTabValuePayments(newValue); + }; + + useEffect(() => { + let role = getRoleFromUrl(); + if (role !== "ChainCompany") { + setTabValueWages("1"); + } + }, []); + + return ( + + + + + + {getRoleFromUrl() !== "ParentCompany" && ( + + + + + {/* {(getRoleFromUrl() === "SuperAdmin" || + getRoleFromUrl() === "AdminX") && ( + + )} + {getRoleFromUrl() === "ProvinceOperator" && ( + + )} */} + + + )} + + {getRoleFromUrl() !== "ParentCompany" && ( + + + + + + + + + + {getRoleFromUrl() === "SuperAdmin" || + getRoleFromUrl() === "AdminX" || + getRoleFromUrl() === "ProvinceOperator" ? ( + <> + + + کشتارگاه + شرکت زنجیره + {(getRoleFromUrl() === "SuperAdmin" || + getRoleFromUrl() === "AdminX" || + getRoleFromUrl() === "ProvinceOperator" || + getRoleFromUrl() === "Guilds") && ( + تراکنش ها + )} + + + + {tabValuePayments === "1" ? ( + + ) : tabValuePayments === "2" ? ( + + ) : ( + + )} + + + ) : ( + <> + {getRoleFromUrl === "KillHouse" ? ( + + ) : ( + + )} + + )} + + + + + + + {(getRoleFromUrl() === "ProvinceOperator" || + getRoleFromUrl() === "SuperAdmin" || + getRoleFromUrl() === "AdminX" || + getRoleFromUrl() === "Commerce" || + getRoleFromUrl() === "KillHouse") && ( + + + {!slaughterExclusiveState && ( + + )} + + {(getRoleFromUrl() === "KillHouse" || + getRoleFromUrl() === "SuperAdmin" || + getRoleFromUrl() === "AdminX" || + getRoleFromUrl() === "Commerce") && ( + + )} + {getRoleFromUrl() !== "KillHouse" && + getRoleFromUrl() !== "ChainCompany" && ( + + )} + + )} + + {getRoleFromUrl() === "ChainCompany" && ( + + )} + + + {getRoleFromUrl() === "SuperAdmin" || + getRoleFromUrl() === "AdminX" || + getRoleFromUrl() === "ProvinceOperator" || + getRoleFromUrl() === "Commerce" ? ( + + ) : ( + + )} + + + {getRoleFromUrl() === "SuperAdmin" || + getRoleFromUrl() === "AdminX" || + getRoleFromUrl() === "ProvinceOperator" || + getRoleFromUrl() === "Commerce" ? ( + + ) : ( + + )} + + + + {getRoleFromUrl() === "SuperAdmin" || + getRoleFromUrl() === "AdminX" || + getRoleFromUrl() === "ProvinceOperator" || + getRoleFromUrl() === "Commerce" ? ( + + ) : ( + + )} + + + {getRoleFromUrl() === "SuperAdmin" || + getRoleFromUrl() === "AdminX" || + getRoleFromUrl() === "ProvinceOperator" || + getRoleFromUrl() === "Commerce" ? ( + + ) : ( + + )} + + + {getRoleFromUrl() === "SuperAdmin" || + getRoleFromUrl() === "AdminX" || + getRoleFromUrl() === "ProvinceOperator" || + getRoleFromUrl() === "Commerce" ? ( + + ) : ( + + )} + + + + + + )} + + ); +}; diff --git a/src/features/province/components/province-payment-chain-detail/ProvincePaymentChainDetails.js b/src/features/province/components/province-payment-chain-detail/ProvincePaymentChainDetails.js new file mode 100644 index 0000000..a032035 --- /dev/null +++ b/src/features/province/components/province-payment-chain-detail/ProvincePaymentChainDetails.js @@ -0,0 +1,242 @@ +import { Button, TextField, Typography } from "@mui/material"; +import axios from "axios"; +import { useContext, useEffect, useState } from "react"; +import { Grid } from "../../../../components/grid/Grid"; +import { PageTable } from "../../../../components/page-table/PageTable"; +import { SPACING } from "../../../../data/spacing"; +import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl"; +import { AppContext } from "../../../../contexts/AppContext"; +import { DatePicker } from "@mui/x-date-pickers"; +import moment from "moment"; +import { formatJustDate } from "../../../../utils/formatTime"; +import { RiSearchLine } from "react-icons/ri"; + +export const ProvincePaymentChainDetails = ({ killhouseKey, type }) => { + const [, , selectedDate1, setSelectedDate1, selectedDate2, setSelectedDate2] = + useContext(AppContext); + + useEffect(() => { + const currentDate = moment(new Date()).format("YYYY-MM-DD"); + setSelectedDate1(currentDate); + setSelectedDate2(currentDate); + }, []); + + const [data, setData] = useState([]); + const [loading, setLoading] = useState(false); + const [totalRows, setTotalRows] = useState(0); + const [perPage, setPerPage] = useState(10); + + const [textValue, setTextValue] = useState(""); + + const handleTextChange = (event) => { + setTextValue(event.target.value); + }; + + const fetchApiData = async (page, textValue) => { + setLoading(true); + const response = await axios.get( + `chain-allocation-total-wage/?search=filter&value=${textValue}&page=${page}&page_size=${perPage}&type=paid&chain_company_key=${killhouseKey}&role=${getRoleFromUrl()}&date1=${selectedDate1}&date2=${selectedDate2}` + ); + setData(response.data.results); + setTotalRows(response.data.count); + setLoading(false); + }; + + const handlePageChange = (page) => { + fetchApiData(page, textValue); + }; + + const handlePerRowsChange = async (newPerPage, page) => { + setLoading(true); + const response = await axios.get( + `chain-allocation-total-wage/?search=filter&value=${textValue}&page=${page}&page_size=${newPerPage}&type=paid&chain_company_key=${killhouseKey}&role=${getRoleFromUrl()}&date1=${selectedDate1}&date2=${selectedDate2}` + ); + + setData(response.data.results); + setTotalRows(response.data.count); + setPerPage(newPerPage); + + setLoading(false); + }; + + useEffect(() => { + fetchApiData(1); + }, []); + + useEffect(() => { + fetchApiData(1); + }, [selectedDate1, selectedDate2, perPage]); + + const handleSubmit = async (event) => { + event.preventDefault(); + setLoading(true); + + try { + const response = await axios.get( + `chain-allocation-total-wage/?search=filter&value=${textValue}&type=paid&chain_company_key=${killhouseKey}&role=${getRoleFromUrl()}&date1=${selectedDate1}&date2=${selectedDate2}` + ); + setData(response.data.results); + setTotalRows(response.data.count); + } catch (error) { + console.error("Error fetching data:", error); + } finally { + setLoading(false); + } + }; + + const columns = [ + { + name: "ردیف", + selector: (item, i) => { + return i + 1; + }, + sortable: false, + wrap: true, + allowOverflow: true, + center: true, + width: "30px", + }, + { + name: "تاریخ ایجاد", + selector: (item) => { + return formatJustDate(item?.createDate); + }, + sortable: false, + wrap: true, + allowOverflow: true, + center: true, + width: "auto", + }, + { + name: "مرغداری", + selector: (item, i) => { + return `${item?.poultryHatching?.poultry?.unitName} (${item?.poultryHatching?.poultry?.user?.mobile})`; + }, + sortable: false, + wrap: true, + allowOverflow: true, + center: true, + width: "auto", + }, + { + name: "شرکت زنجیره", + selector: (item, i) => { + return `${item?.chainCompany?.name} (${item?.chainCompany?.user.mobile})`; + }, + sortable: false, + wrap: true, + allowOverflow: true, + center: true, + width: "auto", + }, + { + name: "کد قرنطینه", + selector: (item, i) => { + return item?.quarantineCode ? item?.quarantineCode : "-"; + }, + sortable: false, + wrap: true, + allowOverflow: true, + center: true, + width: "auto", + }, + { + name: "تعداد", + selector: (item) => { + return item?.quantity; + }, + sortable: false, + wrap: true, + allowOverflow: true, + center: true, + width: "auto", + }, + { + name: "وزن", + selector: (item) => { + return item?.weight; + }, + sortable: false, + wrap: true, + allowOverflow: true, + center: true, + width: "60px", + }, + ]; + + return ( + + + سفارشات زنجیره + + + ( + + )} + value={selectedDate1} + onChange={(e) => { + setSelectedDate1(moment(e).format("YYYY-MM-DD")); + }} + /> + + + ( + + )} + value={selectedDate2} + onChange={(e) => { + setSelectedDate2(moment(e).format("YYYY-MM-DD")); + }} + /> + + +
    + + + +
    +
    + } + columns={columns} + data={data} + progressPending={loading} + pagination + paginationServer + paginationTotalRows={totalRows} + onChangeRowsPerPage={handlePerRowsChange} + onChangePage={handlePageChange} + /> + + ); +}; diff --git a/src/features/province/components/province-payment-chains/ProvincePaymentChains.js b/src/features/province/components/province-payment-chains/ProvincePaymentChains.js new file mode 100644 index 0000000..74492c8 --- /dev/null +++ b/src/features/province/components/province-payment-chains/ProvincePaymentChains.js @@ -0,0 +1,306 @@ +import { + Button, + Checkbox, + FormControlLabel, + TextField, + Tooltip, + Typography, +} from "@mui/material"; +import axios from "axios"; +import { useContext, useEffect, useState } from "react"; +import { RiFileExcel2Fill, RiSearchLine } from "react-icons/ri"; +import { useSelector } from "react-redux"; +import { useNavigate } from "react-router-dom"; +import { Grid } from "../../../../components/grid/Grid"; +import { PageTable } from "../../../../components/page-table/PageTable"; +import { SPACING } from "../../../../data/spacing"; +import { + ROUTE_ADMINX_PAYING_FEES_REQUESTS, + ROUTE_PROVINCE_PAYING_FEES_REQUESTS, + ROUTE_SUPER_ADMIN_PAYING_FEES_REQUESTS, +} from "../../../../routes/routes"; +import moment from "moment"; +import { DatePicker } from "@mui/x-date-pickers"; +import { AppContext } from "../../../../contexts/AppContext"; +import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl"; + +export const ProvincePaymentChains = () => { + const authToken = useSelector((state) => state.userSlice.authToken); + const navigate = useNavigate(); + const [data, setData] = useState([]); + const [loading, setLoading] = useState(false); + const [totalRows, setTotalRows] = useState(0); + const [perPage, setPerPage] = useState(10); + const [withDate, setWithDate] = useState(false); + const [textValue, setTextValue] = useState(""); + + const handleTextChange = (event) => { + setTextValue(event.target.value); + }; + + const [, , selectedDate1, setSelectedDate1, selectedDate2, setSelectedDate2] = + useContext(AppContext); + + useEffect(() => { + const currentDate = moment(new Date()).format("YYYY-MM-DD"); + setSelectedDate1(currentDate); + setSelectedDate2(currentDate); + }, []); + + const fetchApiData = async (page, textValue) => { + setLoading(true); + const response = await axios.get( + `chain-company-total-allocations/?search=filter&value=${textValue}&type=live&page=${page}&role=${getRoleFromUrl()}&page_size=${perPage}${ + withDate ? `&date1=${selectedDate1}&date2=${selectedDate2}` : `` + }` + ); + setData(response.data.results); + setTotalRows(response.data.count); + setLoading(false); + }; + + const handlePageChange = (page) => { + fetchApiData(page, textValue); + }; + + const handlePerRowsChange = async (newPerPage, page) => { + setLoading(true); + const response = await axios.get( + `chain-company-total-allocations/?search=filter&value=${textValue}&type=live&page=${page}&role=${getRoleFromUrl()}&page_size=${newPerPage}${ + withDate ? `&date1=${selectedDate1}&date2=${selectedDate2}` : `` + }` + ); + + setData(response.data.results); + setTotalRows(response.data.count); + setPerPage(newPerPage); + + setLoading(false); + }; + + useEffect(() => { + fetchApiData(1); + }, []); + + const handleSubmit = async (event) => { + event.preventDefault(); + setLoading(true); + + try { + const response = await axios.get( + `chain-company-total-allocations/?search=filter&value=${textValue}&type=live${ + withDate ? `&date1=${selectedDate1}&date2=${selectedDate2}` : `` + }` + ); + setData(response.data.results); + setTotalRows(response.data.count); + } catch (error) { + console.error("Error fetching data:", error); + } finally { + setLoading(false); + } + }; + + useEffect(() => { + fetchApiData(1); + }, [selectedDate1, selectedDate2, withDate]); + + const columns = [ + { + name: "شرکت زنجیره", + selector: (item) => `${item?.info?.company}`, + sortable: true, + wrap: true, + allowOverflow: true, + center: true, + // width: "80px", + }, + { + name: "تعداد پرونده", + selector: (item) => item?.info?.totalCount?.toLocaleString(), + sortable: true, + wrap: true, + allowOverflow: true, + center: true, + // width: "90px", + }, + { + name: "حجم", + selector: (item) => item.info?.totalQuantity?.toLocaleString(), + sortable: true, + wrap: true, + allowOverflow: true, + center: true, + // width: "90px", + }, + { + name: "وزن سفارشات (کیلوگرم)", + selector: (item) => item.info?.totalWeight?.toLocaleString(), + sortable: true, + wrap: true, + allowOverflow: true, + center: true, + // width: "90px", + }, + { + name: "مبلغ کل", + selector: (item) => `${item.info?.totalWage?.toLocaleString()} ریال`, + sortable: true, + wrap: true, + allowOverflow: true, + center: true, + // width: "90px", + }, + { + name: "جزییات سفارش", + selector: (item) => { + return ( + + ); + }, + sortable: true, + wrap: true, + allowOverflow: true, + center: true, + // width: "90px", + }, + ]; + + return ( + + + + زنجیره ها + + + setWithDate(!withDate)} + color="primary" + /> + } + /> + + + ( + + )} + value={selectedDate1} + onChange={(e) => { + setSelectedDate1(moment(e).format("YYYY-MM-DD")); + }} + /> + + + ( + + )} + value={selectedDate2} + onChange={(e) => { + setSelectedDate2(moment(e).format("YYYY-MM-DD")); + }} + /> + + +
    + + + + + + + + +
    +
    + } + columns={columns} + data={data} + progressPending={loading} + pagination + paginationServer + paginationTotalRows={totalRows} + onChangeRowsPerPage={handlePerRowsChange} + onChangePage={handlePageChange} + /> + + ); +}; diff --git a/src/features/province/components/province-payment-chicken-alive/ProvincePaymentChickenAlive.js b/src/features/province/components/province-payment-chicken-alive/ProvincePaymentChickenAlive.js new file mode 100644 index 0000000..dd38eed --- /dev/null +++ b/src/features/province/components/province-payment-chicken-alive/ProvincePaymentChickenAlive.js @@ -0,0 +1,324 @@ +import { + Button, + Checkbox, + FormControlLabel, + TextField, + Tooltip, + Typography, +} from "@mui/material"; +import axios from "axios"; +import { useContext, useEffect, useState } from "react"; +import { RiFileExcel2Fill, RiSearchLine } from "react-icons/ri"; +import { useSelector } from "react-redux"; +import { useNavigate } from "react-router-dom"; +import { Grid } from "../../../../components/grid/Grid"; +import { PageTable } from "../../../../components/page-table/PageTable"; +import { SPACING } from "../../../../data/spacing"; +import { + ROUTE_ADMINX_PAYING_FEES_REQUESTS, + ROUTE_PROVINCE_PAYING_FEES_REQUESTS, + ROUTE_SUPER_ADMIN_PAYING_FEES_REQUESTS, +} from "../../../../routes/routes"; +import moment from "moment"; +import { DatePicker } from "@mui/x-date-pickers"; +import { AppContext } from "../../../../contexts/AppContext"; +import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl"; + +export const ProvincePaymentChcikenAlive = ({ type }) => { + const authToken = useSelector((state) => state.userSlice.authToken); + const navigate = useNavigate(); + const [data, setData] = useState([]); + const [loading, setLoading] = useState(false); + const [totalRows, setTotalRows] = useState(0); + const [perPage, setPerPage] = useState(10); + const [withDate, setWithDate] = useState(false); + const [textValue, setTextValue] = useState(""); + + const handleTextChange = (event) => { + setTextValue(event.target.value); + }; + + const [, , selectedDate1, setSelectedDate1, selectedDate2, setSelectedDate2] = + useContext(AppContext); + + useEffect(() => { + const currentDate = moment(new Date()).format("YYYY-MM-DD"); + setSelectedDate1(currentDate); + setSelectedDate2(currentDate); + }, []); + + const fetchApiData = async (page, textValue) => { + setLoading(true); + const response = await axios.get( + `kill_house_free_bar_total_wage/?search=filter&value=${textValue}&type=${ + type === "live_chicken" ? "live" : "carcass" + }&page=${page}&role=${getRoleFromUrl()}&page_size=${perPage}${ + withDate ? `&date1=${selectedDate1}&date2=${selectedDate2}` : `` + }` + ); + setData(response.data.results); + setTotalRows(response.data.count); + setLoading(false); + }; + + const handlePageChange = (page) => { + fetchApiData(page, textValue); + }; + + const handlePerRowsChange = async (newPerPage, page) => { + setLoading(true); + const response = await axios.get( + `kill_house_free_bar_total_wage/?search=filter&value=${textValue}&type=${ + type === "live_chicken" ? "live" : "carcass" + }&page=${page}&role=${getRoleFromUrl()}&page_size=${newPerPage}${ + withDate ? `&date1=${selectedDate1}&date2=${selectedDate2}` : `` + }` + ); + + setData(response.data.results); + setTotalRows(response.data.count); + setPerPage(newPerPage); + + setLoading(false); + }; + + useEffect(() => { + fetchApiData(1); + }, []); + + const handleSubmit = async (event) => { + event.preventDefault(); + setLoading(true); + + try { + const response = await axios.get( + `kill_house_free_bar_total_wage/?search=filter&value=${textValue}&type=${ + type === "live_chicken" ? "live" : "carcass" + }${withDate ? `&date1=${selectedDate1}&date2=${selectedDate2}` : ``}` + ); + setData(response.data.results); + setTotalRows(response.data.count); + } catch (error) { + console.error("Error fetching data:", error); + } finally { + setLoading(false); + } + }; + + useEffect(() => { + fetchApiData(1); + }, [selectedDate1, selectedDate2, withDate]); + + const columns = [ + { + name: "خریدار", + selector: (item) => { + const type = item?.info?.killer ? "کشتارکن" : "کشتارگاه"; + return `${type} ${item?.info?.killHouseName} - ${item?.info?.killHouseFullname} (${item?.info?.killHouseMobile})`; + }, + sortable: true, + wrap: true, + allowOverflow: true, + center: true, + // width: "90px", + }, + { + name: "شهر", + selector: (item) => `${item?.info?.killHouseCity}`, + sortable: true, + wrap: true, + allowOverflow: true, + center: true, + // width: "80px", + }, + { + name: "تعداد پرونده", + selector: (item) => item?.info?.totalCount?.toLocaleString(), + sortable: true, + wrap: true, + allowOverflow: true, + center: true, + // width: "90px", + }, + { + name: "حجم", + selector: (item) => item.info?.totalQuantity?.toLocaleString(), + sortable: true, + wrap: true, + allowOverflow: true, + center: true, + // width: "90px", + }, + { + name: "وزن سفارشات (کیلوگرم)", + selector: (item) => item.info?.totalWeight?.toLocaleString(), + sortable: true, + wrap: true, + allowOverflow: true, + center: true, + // width: "90px", + }, + { + name: "مبلغ کل", + selector: (item) => `${item.info?.totalWage?.toLocaleString()} ریال`, + sortable: true, + wrap: true, + allowOverflow: true, + center: true, + // width: "90px", + }, + { + name: "جزییات سفارش", + selector: (item) => { + return ( + + ); + }, + sortable: true, + wrap: true, + allowOverflow: true, + center: true, + // width: "90px", + }, + ]; + + return ( + + + + + خرید {type === "live_chicken" ? "مرغ زنده" : "لاشه"} آزاد + + + + setWithDate(!withDate)} + color="primary" + /> + } + /> + + + ( + + )} + value={selectedDate1} + onChange={(e) => { + setSelectedDate1(moment(e).format("YYYY-MM-DD")); + }} + /> + + + ( + + )} + value={selectedDate2} + onChange={(e) => { + setSelectedDate2(moment(e).format("YYYY-MM-DD")); + }} + /> + + +
    + + + + + + + + +
    +
    + } + columns={columns} + data={data} + progressPending={loading} + pagination + paginationServer + paginationTotalRows={totalRows} + onChangeRowsPerPage={handlePerRowsChange} + onChangePage={handlePageChange} + /> + + ); +}; diff --git a/src/features/province/components/province-payment-factor-file/ProvincePaymentFactorFile.js b/src/features/province/components/province-payment-factor-file/ProvincePaymentFactorFile.js new file mode 100644 index 0000000..b7e5693 --- /dev/null +++ b/src/features/province/components/province-payment-factor-file/ProvincePaymentFactorFile.js @@ -0,0 +1,600 @@ +import React, { forwardRef } from "react"; +import { PropTypes } from "prop-types"; +import signature from "../../../../assets/images/signature.png"; +import moment from "moment"; +import { formatJustDate, formatJustTime } from "../../../../utils/formatTime"; +import PersianDate from "persian-date"; + +const styles = { + documentTitle: { + display: "flex", + justifyContent: "center", + alignItems: "center", + fontSize: "12px", + }, + row: { + display: "flex", + justifyContent: "space-between", + alignItems: "start", + gap: "5px", + direction: "rtl", + }, + column: { + display: "flex", + height: "100px", + borderStyle: "solid", + borderWidth: "1px", + justifyContent: "center", + alignItems: "center", + fontSize: "12px", + }, + itemsColumn: { + display: "flex", + height: "100px", + borderStyle: "solid", + borderWidth: "1px", + justifyContent: "center", + alignItems: "center", + fontSize: "12px", + }, + item: { + display: "flex", + gap: "5px", + marginTop: "10px", + alignItems: "center", + }, + itemTitle: { fontSize: "12px", fontWeight: "bolder" }, + itemText: { fontSize: "10px" }, + invoiceTable: { + width: "100%", + borderCollapse: "collapse", + alignSelf: "center", + }, + tableCell: { + border: "1px solid #000", + pAlign: "left", + textAlign: "center", + fontSize: 11, + padding: "10px", + fontFamily: "iranyekan", + }, + tableCellTexts: { + border: "1px solid #000", + pAlign: "left", + textAlign: "center", + fontSize: 12, + padding: "10px", + fontFamily: "iranyekan", + }, + tableCellAlert: { + border: "1px solid #000", + pAlign: "left", + textAlign: "center", + fontSize: 9, + color: "red", + }, + tableCellMobile: { + border: "1px solid #000", + pAlign: "left", + textAlign: "center", + fontSize: 9, + }, + tableInnerCell: { + border: "1px solid #000", + pAlign: "left", + textAlign: "center", + fontSize: 7, + whiteSpace: "nowrap", + }, + tableHeader: { + pageBreakAfter: "auto", + }, + headerRow: { + backgroundColor: "#eee", + pageBreakInside: "avoid", + pageBreakAfter: "auto", + }, + tableHeaderCell: { + backgroundColor: "#eee", + fontSize: 10, + border: "1px solid #000", + padding: "4px", + textAlign: "center", + fontWeight: "bold", + minWidth: "100px", + }, + tableHeaderCellText: { + backgroundColor: "#eee", + fontSize: 10, + border: "1px solid #000", + padding: "4px", + textAlign: "center", + fontWeight: "bold", + minWidth: "260px", + }, +}; + +const ProvincePaymentFactorFile = forwardRef( + ({ item, isUnion, union, user }, ref) => { + const sellerItems = [ + { + title: "فروشنده", + text: isUnion ? union?.unitName || "-" : "هوشمند سازان ", + }, + { + title: "شناسه ملی", + text: isUnion ? union?.unitNationalId || "-" : "14013838372", + }, + { + title: "شماره ثبت", + text: isUnion ? union?.unitRegistrationNumber || "-" : "17514", + }, + { + title: "استان", + text: isUnion ? union?.unitProvince || "-" : "البرز", + }, + { + title: "شهرستان", + text: isUnion ? union?.unitCity || "-" : "کرج", + }, + { + title: "تلفن", + text: isUnion ? union?.mobile || "-" : "(021)28421237", + }, + { + title: "کد پستی", + text: isUnion ? union?.unitPostalCode || "-" : "3139735185", + }, + { + title: "نشانی", + text: isUnion ? union?.unitAddress || "-" : "نبش بلوار سرداران", + }, + ]; + + const buyerItems = [ + { + title: "فروشنده", + text: user?.unitName || "-", + }, + { + title: "شناسه ملی", + text: user?.unitNationalId || "-", + }, + { + title: "شماره ثبت", + text: user?.unitRegistrationNumber || "-", + }, + { + title: "استان", + text: user?.unitProvince || "-", + }, + { + title: "شهرستان", + text: user?.unitCity || "-", + }, + { + title: "تلفن", + text: user?.mobile || "-", + }, + { + title: "کد پستی", + text: user?.unitPostalCode || "-", + }, + { + title: "نشانی", + text: user?.unitAddress || "-", + }, + ]; + + return ( +
    +
    +

    صورتحسـاب فروش کالا و خدمات

    +
    +
    +
    + + فروشنده + +
    +
    +
    + {sellerItems?.map((option, i) => ( +
    + {option.title}: + {option.text} +
    + ))} +
    +
    +
    +
    +
    + + شماره فاکتور: {"‌"} + + + {moment(new PersianDate()).format("YYMMDD")} + +
    +
    + + تاریخ: {"‌"} + + + {new PersianDate().toLocale("fa").format("YYYY/MM/DD")} + +
    +
    +
    +
    + + {/* second row */} + +
    +
    + + خریدار + +
    +
    +
    + {buyerItems?.map((option, i) => ( +
    + {option.title}: + {option.text} +
    + ))} +
    +
    +
    +
    + + {/* table row */} + +
    + + + + + + + + + + + + + + {isUnion ? ( + <> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ) : ( + + + + + + + + + + )} + + {isUnion ? ( + + + + + + + + + ) : ( + + + + + + + + + )} + + + + + +
    + ردیف + شرح خدمتمبلغ واحد (ریال) + جمع مالیات و عوارض ارزش افزوده (ریال) + مبلغ کل (ریال)تخفیف (ریال) + جمع کل پس از تخفیف +
    ( با احتساب مالیات و عوارض ) ریال +
    1 + تعرفه استفاده از سامانه رصدیار +
    + (سهم اتحادیه مرغداران گوشتی) +
    + {((item?.unionShare / 100) * 90).toLocaleString()} + + {((item?.unionShare / 100) * 10).toLocaleString()} + + {item?.unionShare.toLocaleString()} + 0 + {item?.unionShare.toLocaleString()} +
    2 + تعرفه استفاده از سامانه رصدیار +
    + (سهم صنف پروتئین) +
    + {((item?.guildsShare / 100) * 90).toLocaleString()} + + {" "} + {((item?.guildsShare / 100) * 10).toLocaleString()} + + {item?.guildsShare.toLocaleString()} + 0 + {item?.guildsShare.toLocaleString()} +
    3 + تعرفه استفاده از سامانه رصدیار +
    + (سهم دامپزشک فارم) +
    + {" "} + {((item?.otherShare / 100) * 90).toLocaleString()} + + {((item?.otherShare / 100) * 10).toLocaleString()} + + {item?.otherShare.toLocaleString()} + 0 + {item?.otherShare.toLocaleString()} +
    1 + تعرفه استفاده از سامانه رصدیار +
    + (سهم شرکت هوشمند سازان) +
    + {((item?.companyShare / 100) * 90).toLocaleString()} + + {((item?.companyShare / 100) * 10).toLocaleString()} + + {item?.companyShare.toLocaleString()} + 0 + {item?.companyShare.toLocaleString()} +
    + جمع کل + + {( + ((item?.unionShare + + item?.guildsShare + + item?.otherShare) / + 100) * + 90 + ).toLocaleString()} + + {( + ((item?.unionShare + + item?.guildsShare + + item?.otherShare) / + 100) * + 10 + ).toLocaleString()} + + {" "} + {( + item?.unionShare + + item?.guildsShare + + item?.otherShare + ).toLocaleString()} + 0 + {" "} + {( + item?.unionShare + + item?.guildsShare + + item?.otherShare + ).toLocaleString()} +
    + جمع کل + + {((item?.companyShare / 100) * 90).toLocaleString()} + + {((item?.companyShare / 100) * 10).toLocaleString()} + + {item?.companyShare.toLocaleString()} + 0 + {item?.companyShare.toLocaleString()} +
    +
    +
    +
    + + {" "} + مهر و امضای فروشنده: + + {!isUnion && ( + امضا + )} +
    +
    + مهر و امضای خریدار: +
    +
    +
    +
    + {isUnion && ( + + * توجه: مبلغ کل به حساب اتحادیه مرغداران گوشتی استان + واریز گردیده است . + + )} +
    +
    +
    +
    +
    +
    + + اطلاعات تراکنش{" "} + +
    +
    + + تاریخ پرداخت:{" "} + {item?.date && + `${formatJustDate(item?.date)} ساعت (${formatJustTime( + item?.date + )})`} + +
    +
    + + نوع پرداخت:{" "} + {item?.transactionType === "wage-gateway-auto" + ? "آنلاین" + : item?.transactionType === "correspondence" + ? "مکاتبات" + : "دستی"} + +
    +
    + کد پیگیری: {item?.refId} +
    +
    + + شماره کارت: {item?.cardHolderPan} + +
    +
    +
    +
    + ); + } +); + +ProvincePaymentFactorFile.displayName = "ProvincePaymentFactorFile"; + +export default ProvincePaymentFactorFile; + +ProvincePaymentFactorFile.propTypes = { + item: PropTypes.object, +}; diff --git a/src/features/province/components/province-payment-live-chicken-detail/ProvincePaymentLiveChickenDetails.js b/src/features/province/components/province-payment-live-chicken-detail/ProvincePaymentLiveChickenDetails.js new file mode 100644 index 0000000..644d3bb --- /dev/null +++ b/src/features/province/components/province-payment-live-chicken-detail/ProvincePaymentLiveChickenDetails.js @@ -0,0 +1,236 @@ +import { Button, TextField, Typography } from "@mui/material"; +import axios from "axios"; +import { useContext, useEffect, useState } from "react"; +import { Grid } from "../../../../components/grid/Grid"; +import { PageTable } from "../../../../components/page-table/PageTable"; +import { SPACING } from "../../../../data/spacing"; +import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl"; +import { AppContext } from "../../../../contexts/AppContext"; +import { DatePicker } from "@mui/x-date-pickers"; +import moment from "moment"; +import { RiSearchLine } from "react-icons/ri"; + +export const ProvincePaymentLiveChickenDetails = ({ killhouseKey, type }) => { + const [, , selectedDate1, setSelectedDate1, selectedDate2, setSelectedDate2] = + useContext(AppContext); + + useEffect(() => { + const currentDate = moment(new Date()).format("YYYY-MM-DD"); + setSelectedDate1(currentDate); + setSelectedDate2(currentDate); + }, []); + + const [data, setData] = useState([]); + const [loading, setLoading] = useState(false); + const [totalRows, setTotalRows] = useState(0); + const [perPage, setPerPage] = useState(10); + + const [textValue, setTextValue] = useState(""); + + const handleTextChange = (event) => { + setTextValue(event.target.value); + }; + + const fetchApiData = async (page, textValue) => { + setLoading(true); + const response = await axios.get( + `kill_house_free_bar_wage_total/?search=filter&value=${textValue}&page=${page}&page_size=${perPage}&kill_house_key=${killhouseKey}&role=${getRoleFromUrl()}&date1=${selectedDate1}&date2=${selectedDate2}&type=${type}` + ); + setData(response.data.results); + setTotalRows(response.data.count); + setLoading(false); + }; + + const handlePageChange = (page) => { + fetchApiData(page, textValue); + }; + + const handlePerRowsChange = async (newPerPage, page) => { + setLoading(true); + const response = await axios.get( + `kill_house_free_bar_wage_total/?search=filter&value=${textValue}&page=${page}&page_size=${newPerPage}&kill_house_key=${killhouseKey}&role=${getRoleFromUrl()}&date1=${selectedDate1}&date2=${selectedDate2}&type=${type}` + ); + + setData(response.data.results); + setTotalRows(response.data.count); + setPerPage(newPerPage); + + setLoading(false); + }; + + useEffect(() => { + fetchApiData(1); + }, []); + + useEffect(() => { + fetchApiData(1); + }, [selectedDate1, selectedDate2, perPage]); + + const handleSubmit = async (event) => { + event.preventDefault(); + setLoading(true); + + try { + const response = await axios.get( + `kill_house_free_bar_wage_total/?search=filter&value=${textValue}&kill_house_key=${killhouseKey}&role=${getRoleFromUrl()}&date1=${selectedDate1}&date2=${selectedDate2}&type=${type}` + ); + setData(response.data.results); + setTotalRows(response.data.count); + } catch (error) { + console.error("Error fetching data:", error); + } finally { + setLoading(false); + } + }; + + const columns = [ + { + name: "نام خریدار", + selector: (item) => { + return `${item.killHouse?.killHouseOperator?.user?.fullname} (${item.killHouse?.killHouseOperator?.user?.mobile})`; + }, + sortable: true, + wrap: true, + allowOverflow: true, + center: true, + // width: "90px", + }, + { + name: "نام فروشنده", + selector: (item) => { + return item?.poultryName; + }, + sortable: true, + wrap: true, + allowOverflow: true, + center: true, + // width: "90px", + }, + { + name: "شهر", + selector: (item) => { + return item?.city; + }, + sortable: true, + wrap: true, + allowOverflow: true, + center: true, + // width: "90px", + }, + { + name: "تعداد", + selector: (item) => { + return type === "live" + ? item?.quantity.toLocaleString() + : item?.numberOfCarcasses.toLocaleString(); + }, + sortable: true, + wrap: true, + allowOverflow: true, + center: true, + // width: "90px", + }, + { + name: "وزن", + selector: (item) => { + return type === "live" + ? item?.liveWeight.toLocaleString() + : item?.weightOfCarcasses.toLocaleString(); + }, + sortable: true, + wrap: true, + allowOverflow: true, + center: true, + // width: "90px", + }, + { + name: "مبلغ کل", + selector: (item) => { + return item?.totalAmount?.toLocaleString(); + }, + sortable: true, + wrap: true, + allowOverflow: true, + center: true, + // width: "90px", + }, + ]; + + return ( + + + + بارهای {type === "live" ? "مرغ زنده" : "لاشه"} + + + + ( + + )} + value={selectedDate1} + onChange={(e) => { + setSelectedDate1(moment(e).format("YYYY-MM-DD")); + }} + /> + + + ( + + )} + value={selectedDate2} + onChange={(e) => { + setSelectedDate2(moment(e).format("YYYY-MM-DD")); + }} + /> + + +
    + + + +
    +
    + } + columns={columns} + data={data} + progressPending={loading} + pagination + paginationServer + paginationTotalRows={totalRows} + onChangeRowsPerPage={handlePerRowsChange} + onChangePage={handlePageChange} + /> + + ); +}; diff --git a/src/features/province/components/province-payment-pay-dept/ProvincePaymentPayDept.js b/src/features/province/components/province-payment-pay-dept/ProvincePaymentPayDept.js new file mode 100644 index 0000000..3bfbba6 --- /dev/null +++ b/src/features/province/components/province-payment-pay-dept/ProvincePaymentPayDept.js @@ -0,0 +1,127 @@ +import React from "react"; +import { TextField, Button, InputAdornment, Typography } from "@mui/material"; +import { useFormik } from "formik"; +import * as Yup from "yup"; +import { Grid } from "../../../../components/grid/Grid"; +import Num2persian from "num2persian"; +import { SlaughterPayFeesGateway } from "../../../slaughter-house/components/slaughter-pay-fees-gateway/SlaughterPayFeesGateway"; +import { useDispatch } from "react-redux"; +import { CLOSE_MODAL, OPEN_MODAL } from "../../../../lib/redux/slices/appSlice"; + +export const ProvincePaymentPayDept = () => { + const validationSchema = Yup.object({ + paymentAmount: Yup.number() + .required("مبلغ اجباری است") + .positive("یک عدد مثبت وارد کنید!") + .min(200000, "حداقل مبلغ دویست هزار ریال است!"), + // .max( + // 2000000000, + // "در هر بار پرداخت، حداکثر مبلغ 200 میلیون تومان میتوانید پرداخت کنید!" + // ), + }); + + const dispatch = useDispatch(); + + // Initialize Formik + const formik = useFormik({ + initialValues: { + paymentAmount: "", + }, + validationSchema, + onSubmit: (values) => { + dispatch(CLOSE_MODAL()); + dispatch( + OPEN_MODAL({ + title: "واریز بدهی از طریق درگاه پرداخت", + content: ( + 1999937500 + // ? 1999937500 + // : parseInt(formik.values.paymentAmount) + // } + amount={formik.values.paymentAmount} + isZarinPal + /> + ), + }) + ); + }, + }); + // const getValueWIthTax = (value) => { + // return Number(value / 10) + Number(value); + // }; + + return ( + +
    + + + ریال + } + /> + + + + {formik.values.paymentAmount > 0 ? ( + + {Num2persian(formik.values.paymentAmount)} ریال + + ) : ( + + مبلغ را وارد کنید + + )} + + {/* + {formik.values.paymentAmount > 0 && ( + + با احتساب ده درصد ارزش افزوده:{" "} + {getValueWIthTax( + formik.values.paymentAmount + ).toLocaleString()}{" "} + ریال + + )} + */} + + + + + +
    +
    + ); +}; diff --git a/src/features/province/components/province-place-full-info/MainPlaceInfo.js b/src/features/province/components/province-place-full-info/MainPlaceInfo.js new file mode 100644 index 0000000..a74644d --- /dev/null +++ b/src/features/province/components/province-place-full-info/MainPlaceInfo.js @@ -0,0 +1,323 @@ +import React, { useContext, useEffect, useState } from "react"; +import { useDispatch } from "react-redux"; +import { motion } from "framer-motion"; +import { + Typography, + Box, + Card, + CardContent, + Grid, + Divider, + Pagination, + TextField, + FormControl, + InputLabel, + Select, + MenuItem, +} from "@mui/material"; +import PersonIcon from "@mui/icons-material/Person"; +import PhoneIcon from "@mui/icons-material/Phone"; +import InventoryIcon from "@mui/icons-material/Inventory"; +import { DatePicker } from "@mui/x-date-pickers"; +import CheckCircleIcon from "@mui/icons-material/CheckCircle"; +import ErrorIcon from "@mui/icons-material/Error"; +import Chip from "@mui/material/Chip"; +import { + LOADING_END, + LOADING_START, +} from "../../../../lib/redux/slices/appSlice"; +import { getStewardTransactions } from "../../services/getStewardTransactions"; +import { convertToIranianTime } from "../../../../utils/formatTime"; +import { getPosProviderName } from "../../../../utils/getPosProviderName"; +import { AppContext } from "../../../../contexts/AppContext"; +import moment from "moment"; + +const MainPlaceFullInfo = ({ item }) => { + const dispatch = useDispatch(); + const [transactionData, setTransactionData] = useState(); + const [page, setPage] = useState(1); + const [transactionMode, setTransactionMode] = useState("0"); + + const [, , selectedDate1, setSelectedDate1, selectedDate2, setSelectedDate2] = + useContext(AppContext); + const [renderFinished, setRenderFinished] = useState(false); + + useEffect(() => { + const currentDate = moment(new Date()).format("YYYY-MM-DD"); + setSelectedDate1(currentDate); + setSelectedDate2(currentDate); + setRenderFinished(true); + }, []); + + const fetchTransactions = (pageIndex) => { + dispatch(LOADING_START()); + dispatch( + getStewardTransactions({ + key: item.shop, + datefrom: convertToIranianTime(selectedDate1), + dateto: convertToIranianTime(selectedDate2), + page: pageIndex, + mode: transactionMode, + }) + ).then((r) => { + dispatch(LOADING_END()); + setTransactionData(r.payload.data); + }); + }; + + useEffect(() => { + if (renderFinished) { + fetchTransactions(1); + } + }, [selectedDate1, selectedDate2, renderFinished, transactionMode]); + + const handleChangePage = (newPage) => { + setPage(newPage); + fetchTransactions(newPage); + }; + + const handleChangeTransactionMode = (event) => { + setTransactionMode(event.target.value); + }; + + return ( + + + + + + + + + نام مالک: {item.guild_info.fullname} + + + + + + + + {" "} + + + شماره همراه: {item.guild_info.mobile} + + + + + + + + {" "} + + + موجودی: {item?.ware_house_info.quantity.toLocaleString()} + + + + + + + + + + } + value={selectedDate1} + onChange={(e) => { + setSelectedDate1(moment(e).format("YYYY-MM-DD")); + }} + /> + + + + + } + value={selectedDate2} + onChange={(e) => { + setSelectedDate2(moment(e).format("YYYY-MM-DD")); + }} + /> + + + + + + + + فیلتر تراکنش ها + + + + + + + + + + + {transactionData?.items?.map((item, index) => ( + + + + + + + {page > 1 ? page * 20 - 20 + index + 1 : index + 1} - + + + {item?.name} + + {!item?.name.includes("موفق") ? ( + + ) : ( + + )} + + + + + تاریخ:{" "} + {convertToIranianTime(item?.date)} + + {item?.product.length === 1 && ( + + محصول: {item?.product[0]?.name} + + )} + {item?.product.length > 1 && ( + + محصولات:{" "} + {item?.product?.map((productItem, index) => ( + {productItem.name} / + ))} + + )} + + مبلغ: {item?.price.toLocaleString()}{" "} + ریال + + + از سرویس:{" "} + {getPosProviderName(item?.posProvider)} + + + + + + + ))} + + + + { + handleChangePage(newPage); + }} + /> + + + + + ); +}; + +export default MainPlaceFullInfo; diff --git a/src/features/province/components/province-policey-kronjon/ProcincePolicyKronjob.js b/src/features/province/components/province-policey-kronjon/ProcincePolicyKronjob.js new file mode 100644 index 0000000..cf11db8 --- /dev/null +++ b/src/features/province/components/province-policey-kronjon/ProcincePolicyKronjob.js @@ -0,0 +1,238 @@ +import { useContext, useState } from "react"; +import axios from "axios"; +import { Box, Typography } from "@mui/material"; +import { GrCloudlinux } from "react-icons/gr"; +import { motion } from "framer-motion"; +import { AppContext } from "../../../../contexts/AppContext"; +import { Grid } from "../../../../components/grid/Grid"; +import { SPACING } from "../../../../data/spacing"; + +const ProcincePolicyKronjob = () => { + const [openNotif] = useContext(AppContext); + + const handleCronjobClick = async (title, link) => { + try { + const response = await axios.get(link); + if (response.status === 200) { + openNotif({ + vertical: "top", + horizontal: "center", + msg: `"${title}" با موفقیت ارسال شد`, + severity: "success", + }); + } + } catch (error) { + openNotif({ + vertical: "top", + horizontal: "center", + msg: `خطا در ارسال "${title}"`, + severity: "error", + }); + } + }; + + const [reportList, setReportList] = useState([ + { + disabled: false, + title: "اس ام اس های بدهی ساعت 9 صبح", + description: "اس ام اس های بدهی", + link: `${axios.defaults.baseURL}send_gate_way_sms_manual/`, + }, + { + disabled: false, + title: " اس ام اس های بسته شدن پنل برای بدهی", + description: " اس ام اس های بسته شدن پنل برای بدهی", + link: `${axios.defaults.baseURL}send_deactivate_panel_debt_sms_manual/`, + }, + { + disabled: false, + title: "وارد کردن بارهای خارج استان به انبار", + description: "وارد کردن بارهای خارج استان به انبار", + link: `${axios.defaults.baseURL}add_free_bar_to_warehouse_manual/`, + }, + { + disabled: false, + title: "ساخت بارهای خارج استان", + description: "ساخت بارهای خارج استان", + link: `${axios.defaults.baseURL}create_kill_house_free_bar/`, + }, + { + disabled: false, + title: "آپدیت جوجه ریزی ها", + description: "آپدیت جوجه ریزی ها", + link: `${axios.defaults.baseURL}api_update_poultry_hatching_from_rsi/`, + }, + { + disabled: false, + title: "تیکت اخطاریه بار های واردنشده به انبار خارج استانی", + description: "تیکت اخطاریه بار های واردنشده به انبار خارج استانی", + link: `${axios.defaults.baseURL}warning_free_bar_to_warehouse_manual/`, + isTicket: true, + }, + { + disabled: false, + title: "تیکت تخصیصات بدون بار", + description: "تیکت تخصیصات بدون بار", + link: `${axios.defaults.baseURL}warning_province_kill_request_without_bar_manual/`, + isTicket: true, + }, + { + disabled: false, + title: "وارد کردن بارهای داخل استانی به انبار", + description: "وارد کردن بارهای داخل استانی به انبار", + link: `${axios.defaults.baseURL}add_to_warehouse_manual/`, + }, + { + disabled: false, + title: "خارج کردن تمام افراد", + description: "خارج کردن تمام افراد", + link: `${axios.defaults.baseURL}remove_access_token_manual/`, + }, + { + disabled: false, + title: "چک کردن تعداد کد قرنطینه داخل استان", + description: "چک کردن تعداد کد قرنطینه داخل استان", + link: `${axios.defaults.baseURL}find_gid_code_manual/`, + }, + { + disabled: false, + title: "آپدیت سن جموجه ریزی", + description: "آپدیت سن جموجه ریزی", + link: `${axios.defaults.baseURL}update_chicken_age_from_login_manual/`, + }, + { + disabled: false, + title: "چک کردن کد قرنطینه خارج استان", + description: "چک کردن کد قرنطینه خارج استان", + link: `${axios.defaults.baseURL}get_gid_out_province_manual/`, + }, + { + disabled: false, + title: "پیغام تعرفه کل ساعت 4 ایتا", + description: "پیغام تعرفه کل ساعت 4 ایتا", + link: `${axios.defaults.baseURL}daily_manual_transaction_for_eata/`, + }, + { + disabled: + process.env.NODE_ENV === "development" || + axios.defaults.baseURL.includes("testbackend.rasadyar.com"), + title: "ارسال دستی پیامک گزارش توزیع گوشت مرغ داخل استان", + description: "ارسال دستی پیامک گزارش توزیع گوشت مرغ داخل استان", + link: `${axios.defaults.baseURL}send_daily_distribution_report_sms_manual/`, + }, + { + disabled: + process.env.NODE_ENV === "development" || + axios.defaults.baseURL.includes("testbackend.rasadyar.com"), + title: "ارسال دستی پیامک اطلاعات کشتار مرغ گوشتی", + description: "ارسال دستی پیامک اطلاعات کشتار مرغ گوشتی", + link: `${axios.defaults.baseURL}send_daily_slaughter_statistics_sms_manual/`, + }, + { + disabled: false, + title: "ارسال دستی بارها به ایتا", + description: "ارسال دستی بارها به ایتا", + link: `${axios.defaults.baseURL}send_all_bar_to_eitaa/`, + }, + { + disabled: false, + title: "ارسال دستی تخصیصات به ایتا فقط برای مرکزی کار میکنه", + description: "ارسال دستی تخصیصات به ایتا فقط برای مرکزی کار میکنه", + link: `${axios.defaults.baseURL}bot_eitaa_for_province_kill_request/`, + }, + ]); + + return ( + + + + + {(reportList || []).map((item, i) => ( + + { + if (!item?.disabled) { + const updatedList = reportList.map((report, index) => + index === i ? { ...report, disabled: true } : report + ); + setReportList(updatedList); + handleCronjobClick(item?.title, item?.link); + } + }} + sx={{ cursor: "pointer" }} + > + + + + {item?.icon || ( + + )} + + + {item?.title || ""} + + + {item?.description || ""} + + + + + + ))} + + + + + ); +}; + +export default ProcincePolicyKronjob; diff --git a/src/features/province/components/province-policy-accounts-edit-account/ProvincePolicyAccountsEditAccount.js b/src/features/province/components/province-policy-accounts-edit-account/ProvincePolicyAccountsEditAccount.js new file mode 100644 index 0000000..ba33210 --- /dev/null +++ b/src/features/province/components/province-policy-accounts-edit-account/ProvincePolicyAccountsEditAccount.js @@ -0,0 +1,96 @@ +import React, { useContext, useEffect } from "react"; +import { Button, TextField, Typography } from "@mui/material"; +import { useFormik } from "formik"; +import { useDispatch } from "react-redux"; +import { CLOSE_MODAL } from "../../../../lib/redux/slices/appSlice"; +import { provincePolicyEditAccountsSevice } from "../../services/province-policy-get-accounts"; +import { Yup } from "../../../../lib/yup/yup"; +import { AppContext } from "../../../../contexts/AppContext"; +import { Grid } from "../../../../components/grid/Grid"; + +export const ProvincePolicyAccountsEditAccount = ({ fetchData, item }) => { + const [openNotif] = useContext(AppContext); + + const dispatch = useDispatch(); + const formik = useFormik({ + initialValues: { + account: item?.account ? item?.account : "", + }, + validationSchema: Yup.object({ + account: Yup.string() + .required("این فیلد اجباری است!") + .typeError("لطفا فیلد را پر کنید!") + .max(26, "شماره شبا نامعتبر است!") + .min(26, "شماره شبا نامعتبر است!"), + }), + }); + + useEffect(() => { + formik.validateForm(); + }, []); + + return ( + + + ویرایش حساب {item?.name} + + + + + + + + ); +}; diff --git a/src/features/province/components/province-policy-accounts-operations/ProvincePolicyAccountsOperations.js b/src/features/province/components/province-policy-accounts-operations/ProvincePolicyAccountsOperations.js new file mode 100644 index 0000000..f5f7491 --- /dev/null +++ b/src/features/province/components/province-policy-accounts-operations/ProvincePolicyAccountsOperations.js @@ -0,0 +1,182 @@ +import { + Button, + IconButton, + List, + ListItemButton, + ListItemIcon, + ListItemText, + Popover, + Typography, +} from "@mui/material"; +import { useContext, useState } from "react"; +import DeleteIcon from "@mui/icons-material/Delete"; +import TuneIcon from "@mui/icons-material/Tune"; +import EditIcon from "@mui/icons-material/Edit"; +import { Grid } from "../../../../components/grid/Grid"; +import { useDispatch } from "react-redux"; +import { + CLOSE_MODAL, + DRAWER, + OPEN_MODAL, +} from "../../../../lib/redux/slices/appSlice"; + +import { AppContext } from "../../../../contexts/AppContext"; +import { ProvincePolicyAccountsSubmitBeneficiary } from "../province-policy-accounts-submit-beneficiary/ProvincePolicyAccountsSubmitBeneficiary"; +import { provincePolicyDeleteBeneficiaryAccountsSevice } from "../../services/province-policy-get-accounts"; + +export const ProvincePolicyAccountsOperations = ({ item, fetchData }) => { + const [anchorEl, setAnchorEl] = useState(null); + const dispatch = useDispatch(); + const handleClick = (event) => { + setAnchorEl(event.currentTarget); + }; + + const [openNotif] = useContext(AppContext); + + const handleClose = () => { + setAnchorEl(null); + }; + + const open = Boolean(anchorEl); + const id = open ? "popover" : undefined; + + return ( + + + + + + + { + handleClose(); + dispatch( + DRAWER({ + right: !(window.innerWidth <= 600), + bottom: window.innerWidth <= 600, + content: ( + + ), + title: " ویرایش حساب ذینفع", + }) + ); + }} + > + + + + + ویرایش + + } + /> + + { + handleClose(); + dispatch( + OPEN_MODAL({ + title: "حذف حساب", + content: ( + + + آیا از حذف حساب اطمینان دارید؟ + + + + + + + + + + + ), + }) + ); + }} + > + + + + + حذف + + } + /> + + + + + ); +}; diff --git a/src/features/province/components/province-policy-accounts-submit-beneficiary/ProvincePolicyAccountsSubmitBeneficiary.js b/src/features/province/components/province-policy-accounts-submit-beneficiary/ProvincePolicyAccountsSubmitBeneficiary.js new file mode 100644 index 0000000..2868143 --- /dev/null +++ b/src/features/province/components/province-policy-accounts-submit-beneficiary/ProvincePolicyAccountsSubmitBeneficiary.js @@ -0,0 +1,145 @@ +import React, { useContext } from "react"; +import { Grid } from "../../../../components/grid/Grid"; +import { useFormik } from "formik"; +import * as Yup from "yup"; +import { TextField, Button } from "@mui/material"; +import { useDispatch } from "react-redux"; +import { + provincePolicyEditBeneficiaryAccountsSevice, + provincePolicySubmitBeneficiaryAccountsSevice, +} from "../../services/province-policy-get-accounts"; +import { AppContext } from "../../../../contexts/AppContext"; +import { DRAWER } from "../../../../lib/redux/slices/appSlice"; + +const validationSchema = Yup.object().shape({ + sheba: Yup.string() + .required("شبا الزامی است") + .matches( + /^IR[0-9]{24}$/, + "شماره شبا باید با IR شروع شود و شامل 24 رقم باشد" + ), + name: Yup.string().required("نام ذینفع الزامی است"), + percentage: Yup.number() + .required("درصد الزامی است") + .min(0, "درصد نمی‌تواند کمتر از 0 باشد") + .max(100, "درصد نمی‌تواند بیشتر از 100 باشد"), +}); + +export const ProvincePolicyAccountsSubmitBeneficiary = ({ + fetchData, + item, +}) => { + const [openNotif] = useContext(AppContext); + const dispatch = useDispatch(); + + const handleFinishSubmit = (r) => { + if (r.payload.error) { + openNotif({ + vertical: "top", + horizontal: "center", + msg: r.payload.error, + severity: "error", + }); + } else { + fetchData(); + openNotif({ + vertical: "top", + horizontal: "center", + msg: "عملیات با موفقیت انجام شد.", + severity: "success", + }); + dispatch(DRAWER({ right: false, bottom: false, content: null })); + } + }; + const formik = useFormik({ + initialValues: { + name: item?.name || "", + sheba: item?.shaba || "IR", + percentage: item?.percent || "", + }, + validationSchema: validationSchema, + onSubmit: (values) => { + if (item) { + dispatch( + provincePolicyEditBeneficiaryAccountsSevice({ + name: values.name, + percent: values.percentage, + shaba: values.sheba, + account_key: item?.key, + }) + ).then((r) => { + handleFinishSubmit(r); + }); + } else { + dispatch( + provincePolicySubmitBeneficiaryAccountsSevice({ + name: values.name, + percent: values.percentage, + shaba: values.sheba, + }) + ).then((r) => { + handleFinishSubmit(r); + }); + } + }, + }); + + return ( + + + + + + + + + + ); +}; diff --git a/src/features/province/components/province-policy-accounts/ProvincePolicyAccounts.js b/src/features/province/components/province-policy-accounts/ProvincePolicyAccounts.js new file mode 100644 index 0000000..ccffe5b --- /dev/null +++ b/src/features/province/components/province-policy-accounts/ProvincePolicyAccounts.js @@ -0,0 +1,210 @@ +import React, { useContext, useEffect, useState } from "react"; +import { Grid } from "../../../../components/grid/Grid"; +import ResponsiveTable from "../../../../components/responsive-table/ResponsiveTable"; +import { useDispatch } from "react-redux"; +import { + provincePolicyEditBeneficiaryAccountsSevice, + provincePolicyGetAccountsSevice, + provincePolicyGetBeneficiaryAccountsSevice, +} from "../../services/province-policy-get-accounts"; +import { DRAWER, OPEN_MODAL } from "../../../../lib/redux/slices/appSlice"; +import { Button, Checkbox, IconButton, Tab, Tabs } from "@mui/material"; +import EditIcon from "@mui/icons-material/Edit"; +import { ProvincePolicyAccountsEditAccount } from "../province-policy-accounts-edit-account/ProvincePolicyAccountsEditAccount"; +import { ProvincePolicyAccountsSubmitBeneficiary } from "../province-policy-accounts-submit-beneficiary/ProvincePolicyAccountsSubmitBeneficiary"; +import { ProvincePolicyAccountsOperations } from "../province-policy-accounts-operations/ProvincePolicyAccountsOperations"; +import { AppContext } from "../../../../contexts/AppContext"; + +export const ProvincePolicyAccounts = () => { + const dispatch = useDispatch(); + + const [tableData, setTableData] = useState(); + const [tableBeneficiaryData, setTableBeneficiaryData] = useState(); + const [data, setData] = useState(); + const [beneficiaryData, setBeneficiaryData] = useState(); + + const [value, setValue] = useState(0); + + const handleChange = (event, newValue) => { + setValue(newValue); + }; + + const fetchData = () => { + dispatch(provincePolicyGetAccountsSevice()).then((r) => { + setData(r.payload.data); + }); + dispatch(provincePolicyGetBeneficiaryAccountsSevice()).then((r) => { + setBeneficiaryData(r.payload.data); + }); + }; + + const [openNotif] = useContext(AppContext); + + const handleFinishSubmit = (r) => { + if (r.payload.error) { + openNotif({ + vertical: "top", + horizontal: "center", + msg: r.payload.error, + severity: "error", + }); + } else { + fetchData(); + openNotif({ + vertical: "top", + horizontal: "center", + msg: "عملیات با موفقیت انجام شد.", + severity: "success", + }); + } + }; + + useEffect(() => { + const d = data?.map((item, i) => { + return [ + i + 1, + item?.name, + item?.account, + + { + // dispatch(inspectorUpdateUserProfile()); + dispatch( + OPEN_MODAL({ + title: "ویرایش حساب", + content: ( + + ), + }) + ); + }} + > + + , + ]; + }); + + setTableData(d); + + const b = beneficiaryData?.map((option, index) => { + return [ + index + 1, + option?.name, + option?.percent, + option?.shaba, + + dispatch( + provincePolicyEditBeneficiaryAccountsSevice({ + in_province: !option?.inProvince, + account_key: option?.key, + }) + ).then((r) => { + handleFinishSubmit(r); + }) + } + />, + + dispatch( + provincePolicyEditBeneficiaryAccountsSevice({ + out_province: !option?.outProvince, + account_key: option?.key, + }) + ).then((r) => { + handleFinishSubmit(r); + }) + } + />, + , + ]; + }); + + setTableBeneficiaryData(b); + }, [data, beneficiaryData]); + + useEffect(() => { + fetchData(); + }, [dispatch, value]); + return ( + + + + + + + {value === 0 && ( + + )} + + {value === 1 && ( + + + + + )} + + ); +}; diff --git a/src/features/province/components/province-policy-add-weight-range/ProvincePolicyAddWeightRange.js b/src/features/province/components/province-policy-add-weight-range/ProvincePolicyAddWeightRange.js new file mode 100644 index 0000000..19fd6bb --- /dev/null +++ b/src/features/province/components/province-policy-add-weight-range/ProvincePolicyAddWeightRange.js @@ -0,0 +1,237 @@ +import React, { useContext, useEffect } from "react"; +import { TextField, Button } from "@mui/material"; +import { useFormik } from "formik"; +import * as Yup from "yup"; +import { Grid } from "../../../../components/grid/Grid"; +import { useDispatch } from "react-redux"; +import { + provincePolicyEditWeightRange, + provincePolicySubmitWeightRange, +} from "../../services/province-policy-get-weight-range"; +import { AppContext } from "../../../../contexts/AppContext"; +import { CLOSE_MODAL } from "../../../../lib/redux/slices/appSlice"; + +function normalizeWeightInput(raw) { + let v = String(raw).replace(/[^0-9.]/g, ""); + + const firstDot = v.indexOf("."); + if (firstDot !== -1) { + v = v.slice(0, firstDot + 1) + v.slice(firstDot + 1).replace(/\./g, ""); + } + + if (v.length === 2 && !v.includes(".")) { + v = `${v[0]}.${v[1]}`; + } + + const parts = v.split("."); + if (parts[0]?.length > 1) { + const first = parts[0][0]; + const rest = parts[0]?.slice(1) + (parts[1] || ""); + v = rest ? `${first}.${rest.replace(/\D/g, "").slice(0, 1)}` : `${first}`; + } + + if (v.includes(".")) { + const [a, b = ""] = v.split("."); + v = `${a}.${b.slice(0, 1)}`; + } + + v = v.replace(/^0(\d)/, "$1"); + + if (v === ".") v = ""; + + const n = parseFloat(v); + if (!Number.isNaN(n)) { + if (n >= 10) v = "9.9"; + if (n < 0) v = "0"; + } + + return v; +} + +const validationSchema = Yup.object({ + from_age: Yup.number() + .required("این فیلد اجباری است!") + .typeError("لطفا عدد وارد کنید!"), + to_age: Yup.number() + .required("این فیلد اجباری است!") + .typeError("لطفا عدد وارد کنید!"), + from_weight: Yup.string() + .required("این فیلد اجباری است!") + .test("is-weight", "Format: d.d and < 10", (val) => { + if (val === undefined || val === null || val === "") return true; + return /^\d(\.\d)?$/.test(String(val)) && parseFloat(val) < 10; + }), + to_weight: Yup.string() + .required("این فیلد اجباری است!") + .test("is-weight", "Format: d.d and < 10", (val, ctx) => { + if (val === undefined || val === null || val === "") return true; + const ok = /^\d(\.\d)?$/.test(String(val)) && parseFloat(val) < 10; + if (!ok) return false; + const fw = parseFloat(ctx.parent.from_weight); + const tw = parseFloat(val); + if (!Number.isNaN(fw) && !Number.isNaN(tw)) { + return ( + tw >= fw || + ctx.createError({ + message: "حداکثر وزن از حداقل وزن باید بیشتر باشد!", + }) + ); + } + return true; + }), +}); + +export const ProvincePolicyAddWeightRange = ({ item, fetchData }) => { + const dispatch = useDispatch(); + + const [openNotif] = useContext(AppContext); + const formik = useFormik({ + initialValues: { + from_age: item?.fromAge, + to_age: item?.toAge, + from_weight: item?.fromWeight, + to_weight: item?.toWeight, + }, + validationSchema, + validateOnChange: true, + validateOnBlur: true, + onSubmit: (values) => { + const payload = { + from_age: Number(values.from_age), + to_age: Number(values.to_age), + from_weight: + values.from_weight === "" ? null : Number(values.from_weight), + to_weight: values.to_weight === "" ? null : Number(values.to_weight), + }; + + const service = item + ? provincePolicyEditWeightRange + : provincePolicySubmitWeightRange; + dispatch( + service({ + ...payload, + ...(item ? { id: item?.id } : {}), + }) + ).then((r) => { + if (r.payload.error) { + openNotif({ + vertical: "top", + horizontal: "center", + msg: r.payload.error, + severity: "error", + }); + } else { + openNotif({ + vertical: "top", + horizontal: "center", + msg: "عملیات با موفقیت انجام شد.", + severity: "success", + }); + dispatch(CLOSE_MODAL()); + fetchData(); + } + }); + }, + }); + + useEffect(() => { + formik.validateForm(); + }, []); + + const blockNonNumericKeys = (e) => { + const blocked = ["e", "E", "+", "-", ","]; + if (blocked.includes(e.key)) e.preventDefault(); + }; + + const handleWeightChange = (field) => (e) => { + const next = normalizeWeightInput(e.target.value); + formik.setFieldValue(field, next); + }; + + return ( + + + + + + + + + + + + ); +}; diff --git a/src/features/province/components/province-policy-approved-killhouse-price/ProvincePolicyApprovedKillHousePrice.js b/src/features/province/components/province-policy-approved-killhouse-price/ProvincePolicyApprovedKillHousePrice.js new file mode 100644 index 0000000..0a99a49 --- /dev/null +++ b/src/features/province/components/province-policy-approved-killhouse-price/ProvincePolicyApprovedKillHousePrice.js @@ -0,0 +1,209 @@ +import React, { useContext, useEffect, useState } from "react"; +import { Button, Checkbox, FormControlLabel, TextField } from "@mui/material"; +import { Yup } from "../../../../lib/yup/yup"; +import { useFormik } from "formik"; +import { useDispatch } from "react-redux"; +import { getKillhouseApprovedPriceState } from "../../services/get-approved-price-state"; +import { provinceEditKillhouseApprovedPrice } from "../../services/province-edit-approved-price"; +import { AppContext } from "../../../../contexts/AppContext"; +import { Grid } from "../../../../components/grid/Grid"; + +export const ProvincePolicyApprovedKillHousePrice = ({ approvedState }) => { + const dispatch = useDispatch(); + const [openNotif] = useContext(AppContext); + const [checked, setChecked] = useState(false); + const [data, setData] = useState(); + + useEffect(() => { + dispatch(getKillhouseApprovedPriceState()).then((r) => { + setData(r.payload.data); + if (r.payload.data?.active) { + setChecked(true); + } + }); + }, []); + + const formik = useFormik({ + initialValues: { + kill_house_price: "", + steward_price: "", + guild_price: "", + }, + validationSchema: Yup.object({ + kill_house_price: Yup.number().required("این فیلد اجباری است"), + steward_price: Yup.number().required("این فیلد اجباری است"), + guild_price: Yup.number().required("این فیلد اجباری است"), + }), + }); + + useEffect(() => { + formik.validateForm(); + }, []); + + useEffect(() => { + if (data?.killHousePrice && checked) { + formik.setFieldValue("kill_house_price", data?.killHousePrice); + formik.setFieldValue("steward_price", data?.stewardPrice); + formik.setFieldValue("guild_price", data?.guildPrice); + } + }, [data]); + + const handleChange = (event) => { + setChecked(event.target.checked); + if (event.target.checked === false) { + dispatch( + provinceEditKillhouseApprovedPrice({ + active: false, + }) + ).then((r) => { + if (r.payload.error) { + openNotif({ + vertical: "top", + horizontal: "center", + msg: r.payload.error, + severity: "error", + }); + } else { + openNotif({ + vertical: "top", + horizontal: "center", + msg: "عملیات با موفقیت انجام شد.", + severity: "success", + }); + } + }); + } + }; + + useEffect(() => { + if (checked && approvedState) { + setChecked(false); + dispatch( + provinceEditKillhouseApprovedPrice({ + active: false, + }) + ); + } + }, [approvedState]); + + return ( + + + + + } + label="قیمت مصوب کشتارگاه، صنف و مباشر" + /> + + + {checked && ( + <> + + + + + + + + + + + + + + + + + + )} + + + ); +}; diff --git a/src/features/province/components/province-policy-approved-price/ProvincePolicyApprovedPrice.js b/src/features/province/components/province-policy-approved-price/ProvincePolicyApprovedPrice.js new file mode 100644 index 0000000..03c99d7 --- /dev/null +++ b/src/features/province/components/province-policy-approved-price/ProvincePolicyApprovedPrice.js @@ -0,0 +1,254 @@ +import React, { useContext, useEffect, useState } from "react"; +import { Grid } from "../../../../components/grid/Grid"; +import { + Button, + Checkbox, + Divider, + FormControlLabel, + TextField, +} from "@mui/material"; +import { Yup } from "../../../../lib/yup/yup"; +import { useFormik } from "formik"; +import { useDispatch } from "react-redux"; +import { getApprovedPriceState } from "../../services/get-approved-price-state"; +import { provinceEditApprovedPrice } from "../../services/province-edit-approved-price"; +import { AppContext } from "../../../../contexts/AppContext"; +import { ProvincePolicyAvicultureCommit } from "../province-policy-aviculture-commit/ProvincePolicyAvicultureCommit"; +import { ProvincePolicyApprovedKillHousePrice } from "../province-policy-approved-killhouse-price/ProvincePolicyApprovedKillHousePrice"; + +export const ProvincePolicyApprovedPrice = () => { + const dispatch = useDispatch(); + const [openNotif] = useContext(AppContext); + const [checked, setChecked] = useState(false); + const [killHousePriceCheck, setKillHousePriceCheck] = useState(false); + const [data, setData] = useState(); + + useEffect(() => { + dispatch(getApprovedPriceState()).then((r) => { + setData(r.payload.data); + if (r.payload.data?.approved) { + setChecked(true); + } + }); + }, []); + + const formik = useFormik({ + initialValues: { + minWeight: "", + maxWeight: "", + minPrice: "", + maxPrice: "", + }, + validationSchema: Yup.object({ + minWeight: Yup.number().required("این فیلد اجباری است"), + maxWeight: Yup.number().required("این فیلد اجباری است"), + minPrice: Yup.number().required("این فیلد اجباری است"), + maxPrice: Yup.number().required("این فیلد اجباری است"), + }), + }); + + useEffect(() => { + formik.validateForm(); + }, []); + + useEffect(() => { + if (data?.highestPrice && checked) { + formik.setFieldValue("minWeight", data?.lowestWeight); + formik.setFieldValue("maxWeight", data?.highestWeight); + formik.setFieldValue("minPrice", data?.lowestPrice); + formik.setFieldValue("maxPrice", data?.highestPrice); + } + }, [data]); + + const handleChange = (event) => { + setChecked(event.target.checked); + if (event.target.checked === false) { + setKillHousePriceCheck(true); + dispatch( + provinceEditApprovedPrice({ + approved: false, + }) + ).then((r) => { + if (r.error) { + openNotif({ + vertical: "top", + horizontal: "center", + msg: "مشکلی پیش آمده است!", + severity: "error", + }); + } else { + openNotif({ + vertical: "top", + horizontal: "center", + msg: "عملیات با موفقیت انجام شد.", + severity: "success", + }); + } + }); + } + }; + + return ( + + + + + } + label="قیمت مصوب مرغ زنده" + /> + + + {checked && ( + <> + + + + + + + + + + + + + + + + + + + + + + )} + + + + + + + + + + + ); +}; diff --git a/src/features/province/components/province-policy-automatic-accept-direct-buying/ProvincePolicyAutomaticAcceptDirectBuying.js b/src/features/province/components/province-policy-automatic-accept-direct-buying/ProvincePolicyAutomaticAcceptDirectBuying.js new file mode 100644 index 0000000..a89ec62 --- /dev/null +++ b/src/features/province/components/province-policy-automatic-accept-direct-buying/ProvincePolicyAutomaticAcceptDirectBuying.js @@ -0,0 +1,200 @@ +import React, { useContext, useEffect, useState } from "react"; +import { Grid } from "../../../../components/grid/Grid"; +import { + Button, + FormControl, + FormControlLabel, + Radio, + RadioGroup, + Typography, +} from "@mui/material"; +import { Yup } from "../../../../lib/yup/yup"; +import { useFormik } from "formik"; +import { useDispatch } from "react-redux"; +import { AppContext } from "../../../../contexts/AppContext"; +import { + getAutomaticDirectBuyingPermissionState, + provinceAutomaticDirectBuyingPermission, +} from "../../services/province-automatic-direct-buying-permission"; +import TimePicker from "../../../../components/date-picker/CustomDatePicker"; + +export const ProvincePolicyAutomaticAcceptDirectBuying = () => { + const dispatch = useDispatch(); + const [openNotif] = useContext(AppContext); + + const [value, setValue] = useState("inactive"); + const [data, setData] = useState(); + + useEffect(() => { + dispatch(getAutomaticDirectBuyingPermissionState()).then((r) => { + setData(r.payload.data); + if (r.payload.data?.allow) { + setValue("active"); + } + }); + }, []); + + const formik = useFormik({ + initialValues: { + hour: "", + hour2: "", + minute: "", + minute2: "", + }, + validationSchema: Yup.object({ + hour: Yup.string().required("این فیلد اجباری است"), + hour2: Yup.string().required("این فیلد اجباری است"), + }), + }); + + useEffect(() => { + formik.validateForm(); + }, []); + + useEffect(() => { + if (data?.allow) { + formik.setFieldValue("hour", data?.startTime); + formik.setFieldValue("hour2", data?.endTime); + formik.validateForm(); + } + }, [data]); + + const handleChangeRadioButton = (event) => { + setValue(event.target.value); + }; + + return ( + + + تایید خودکار خرید مستقیم + + + + + + } + label="فعال" + /> + { + dispatch( + provinceAutomaticDirectBuyingPermission({ + allow: false, + }) + ).then((r) => { + if (r.error) { + openNotif({ + vertical: "top", + horizontal: "center", + msg: "مشکلی پیش آمده است!", + severity: "error", + }); + } else { + openNotif({ + vertical: "top", + horizontal: "center", + msg: "عملیات با موفقیت انجام شد.", + severity: "success", + }); + } + }); + }} + value="inactive" + control={} + label="غیر فعال" + /> + + + + {value === "active" && ( + + + { + formik.setFieldValue("hour", newTime); + }} + label="از" + /> + + + { + formik.setFieldValue("hour2", newTime); + }} + label="تا" + /> + + + )} + + {value === "active" && ( + + + + )} + + ); +}; diff --git a/src/features/province/components/province-policy-aviculture-commit/ProvincePolicyAvicultureCommit.js b/src/features/province/components/province-policy-aviculture-commit/ProvincePolicyAvicultureCommit.js new file mode 100644 index 0000000..cb8252b --- /dev/null +++ b/src/features/province/components/province-policy-aviculture-commit/ProvincePolicyAvicultureCommit.js @@ -0,0 +1,192 @@ +import { + Button, + Checkbox, + FormControl, + FormControlLabel, + InputAdornment, + Radio, + RadioGroup, + TextField, +} from "@mui/material"; +import { useContext, useEffect, useState } from "react"; +import { Grid } from "../../../../components/grid/Grid"; +import { useDispatch } from "react-redux"; +import { SPACING } from "../../../../data/spacing"; +import { provinceGetPolicyAvicultureCommitService } from "../../services/province-get-policy-aviculture-commit"; +import { provinceUpdatePolicyAvicultureCommitService } from "../../services/province-update-policy-aviculture-commit"; +import { AppContext } from "../../../../contexts/AppContext"; + +export const ProvincePolicyAvicultureCommit = ({ approvedState }) => { + const dispatch = useDispatch(); + const [openNotif] = useContext(AppContext); + const [numberValue, setNumberValue] = useState(""); + const [checked, setChecked] = useState(false); + const [freeSaleKey, setFreeSaleKey] = useState(); + const [selectedValue, setSelectedValue] = useState("byWeight"); + + useEffect(() => { + dispatch(provinceGetPolicyAvicultureCommitService()).then((r) => { + setChecked(r.payload.data.allow); + setFreeSaleKey(r.payload.data.key); + if (r.payload.data.type === "weight") { + setSelectedValue("byWeight"); + setNumberValue(r.payload.data.weight); + } else { + setSelectedValue("byPercent"); + setNumberValue(r.payload.data.percent); + } + }); + }, []); + + const handleChange = (event) => { + setChecked(event.target.checked); + dispatch( + provinceUpdatePolicyAvicultureCommitService({ + free_sale_key: freeSaleKey, + allow: event.target.checked, + // weight: Number(numberValue), + }) + ).then((r) => { + if (r.payload.error) { + openNotif({ + vertical: "top", + horizontal: "center", + msg: r.payload.error, + severity: "error", + }); + setChecked(false); + } else { + openNotif({ + vertical: "top", + horizontal: "center", + msg: "عملیات با موفقیت انجام شد.", + severity: "success", + }); + } + }); + }; + + const handleChangeNumber = (event) => { + const newValue = event.target.value; + if (/^\d*$/.test(newValue) || newValue === "") { + setNumberValue(newValue); + } + }; + + const handleRadioChange = (event) => { + setSelectedValue(event.target.value); + }; + + useEffect(() => { + if (!approvedState && freeSaleKey) { + setChecked(false); + dispatch( + provinceUpdatePolicyAvicultureCommitService({ + free_sale_key: freeSaleKey, + allow: false, + // weight: Number(numberValue), + }) + ); + } + }, [approvedState]); + + return ( + + + } + label="تعهد تحویل مرغ به نرخ دولتی" + /> + + {checked && ( + + + + + } + label="بر اساس درصد تحویل" + /> + } + label="بر اساس وزن قطعه" + /> + + + + {selectedValue && ( + + + + {selectedValue === "byWeight" ? "کیلوگرم" : "درصد"} + + ), + }} + size="small" + value={numberValue} + onChange={handleChangeNumber} + inputProps={{ inputMode: "numeric", pattern: "[0-9]*" }} + /> + + + + + + )} + + )} + + ); +}; diff --git a/src/features/province/components/province-policy-council-allow-aggregate-bar-info/ProvincePolicyCouncilAllowAggegateBarInfo.js b/src/features/province/components/province-policy-council-allow-aggregate-bar-info/ProvincePolicyCouncilAllowAggegateBarInfo.js new file mode 100644 index 0000000..c974734 --- /dev/null +++ b/src/features/province/components/province-policy-council-allow-aggregate-bar-info/ProvincePolicyCouncilAllowAggegateBarInfo.js @@ -0,0 +1,166 @@ +import React, { useContext, useEffect, useState } from "react"; +import { Grid } from "../../../../components/grid/Grid"; +import { + Button, + FormControlLabel, + Radio, + TextField, + Typography, +} from "@mui/material"; +import { useFormik } from "formik"; +import { useDispatch } from "react-redux"; +import { Yup } from "../../../../lib/yup/yup"; +import { AppContext } from "../../../../contexts/AppContext"; +import { + provincePolicyEditAggregateBarInfoAllowStatus, + provincePolicyGetAggregateBarInfoAllowStatus, +} from "../../services/province-policy-get-aggregate-bar-info-allow-state"; + +export const ProvincePolicyCouncilAllowAggegateBarInfo = () => { + const [aggregateStatus, setAggregateStatus] = useState(false); + const dispatch = useDispatch(); + const [openNotif] = useContext(AppContext); + + const formik = useFormik({ + initialValues: { + maxLimit: "", + }, + validationSchema: Yup.object({ + maxLimit: Yup.number().required("این فیلد اجباری است"), + }), + }); + + const fetchData = () => { + dispatch(provincePolicyGetAggregateBarInfoAllowStatus()).then((r) => { + setAggregateStatus(r.payload.data.allow); + formik.setFieldValue("maxLimit", r.payload.data.limitation); + }); + }; + + useEffect(() => { + fetchData(); + }, []); + + useEffect(() => { + formik.validateForm(); + }, []); + + return ( + + + مجوز ادغام بار (کد قرنطینه) + + + { + setAggregateStatus(true); + }} + /> + } + label="فعال" + /> + { + dispatch( + provincePolicyEditAggregateBarInfoAllowStatus({ + allow: false, + }) + ).then((r) => { + if (r.payload.error) { + openNotif({ + vertical: "top", + horizontal: "center", + msg: r.payload.error, + severity: "error", + }); + } else { + fetchData(); + openNotif({ + vertical: "top", + horizontal: "center", + msg: "عملیات با موفقیت انجام شد.", + severity: "success", + }); + } + }); + }} + name="item6" + /> + } + label="غیر فعال" + /> + + {aggregateStatus && ( + <> + + + + + + + + + )} + + ); +}; diff --git a/src/features/province/components/province-policy-council-allow-export/ProvincePolicyCouncilAllowExport.js b/src/features/province/components/province-policy-council-allow-export/ProvincePolicyCouncilAllowExport.js new file mode 100644 index 0000000..c2b11d9 --- /dev/null +++ b/src/features/province/components/province-policy-council-allow-export/ProvincePolicyCouncilAllowExport.js @@ -0,0 +1,187 @@ +import React, { useContext, useEffect, useState } from "react"; +import { Grid } from "../../../../components/grid/Grid"; +import { + Button, + Checkbox, + FormControlLabel, + Radio, + TextField, + Typography, +} from "@mui/material"; +import { useFormik } from "formik"; +import { useDispatch } from "react-redux"; +import { Yup } from "../../../../lib/yup/yup"; +import { AppContext } from "../../../../contexts/AppContext"; +import { provincePolicyGetExportAllowStatus } from "../../services/province-policy-get-export-allow-state"; +import { provincePolicyEditExportAllowState } from "../../services/province-policy-edit-export-allow-state"; + +export const ProvincePolicyCouncilAllowExport = () => { + const [exportStatus, setExportStatus] = useState(false); + const [isLimited, setIsLimited] = useState(false); + const dispatch = useDispatch(); + const [openNotif] = useContext(AppContext); + + const formik = useFormik({ + initialValues: { + maxLimit: "", + }, + validationSchema: Yup.object({ + maxLimit: Yup.number() + .required("این فیلد اجباری است") + .max(100, "درصدی بین 1 تا 100 وارد کنید!") + .min(1, "درصدی بین 1 تا 100 وارد کنید!"), + }), + }); + + const fetchData = () => { + dispatch(provincePolicyGetExportAllowStatus()).then((r) => { + setExportStatus(r.payload.data.allow); + formik.setFieldValue("maxLimit", r.payload.data.limitation); + }); + }; + + useEffect(() => { + fetchData(); + }, []); + + useEffect(() => { + formik.validateForm(); + }, []); + + return ( + + + مجوز صادرات + + + { + setExportStatus(true); + }} + /> + } + label="فعال" + /> + { + dispatch( + provincePolicyEditExportAllowState({ + allow: false, + }) + ).then((r) => { + if (r.payload.error) { + openNotif({ + vertical: "top", + horizontal: "center", + msg: r.payload.error, + severity: "error", + }); + } else { + fetchData(); + openNotif({ + vertical: "top", + horizontal: "center", + msg: "عملیات با موفقیت انجام شد.", + severity: "success", + }); + } + }); + }} + name="item6" + /> + } + label="غیر فعال" + /> + + {exportStatus && ( + <> + + setIsLimited(!isLimited)} + color="primary" + /> + } + label="درصد محدودیت جوجه ریزی" + /> + + + {isLimited && ( + + + + )} + + + + + + )} + + ); +}; diff --git a/src/features/province/components/province-policy-council-allow-free-sale/ProvincePolicyCouncilAllowFreeSale.js b/src/features/province/components/province-policy-council-allow-free-sale/ProvincePolicyCouncilAllowFreeSale.js new file mode 100644 index 0000000..930e7a6 --- /dev/null +++ b/src/features/province/components/province-policy-council-allow-free-sale/ProvincePolicyCouncilAllowFreeSale.js @@ -0,0 +1,190 @@ +import React, { useContext, useEffect, useState } from "react"; +import { Grid } from "../../../../components/grid/Grid"; +import { + Button, + Checkbox, + FormControlLabel, + Radio, + TextField, + Typography, +} from "@mui/material"; +import { useFormik } from "formik"; +import { useDispatch } from "react-redux"; +import { provincePolicyGetFreeSaleStatus } from "../../services/province-policy-get-free-sale-state"; +import { Yup } from "../../../../lib/yup/yup"; +import { provincePolicyEditFreeSaleAllowState } from "../../services/province-policy-edit-free-sale-allow-state"; +import { AppContext } from "../../../../contexts/AppContext"; + +export const ProvincePolicyCouncilAllowFreeSale = () => { + const [freeSale, setFreeSale] = useState(false); + const [isLimited, setIsLimited] = useState(false); + const dispatch = useDispatch(); + const [openNotif] = useContext(AppContext); + + const formik = useFormik({ + initialValues: { + maxLimit: "", + }, + validationSchema: Yup.object({ + maxLimit: Yup.number() + .required("این فیلد اجباری است") + .max(100, "درصدی بین 1 تا 100 وارد کنید!") + .min(1, "درصدی بین 1 تا 100 وارد کنید!"), + }), + }); + + const fetchData = () => { + dispatch(provincePolicyGetFreeSaleStatus()).then((r) => { + setFreeSale(r.payload.data.allow); + if (r.payload.data.limitationStatus) { + setIsLimited(true); + } + formik.setFieldValue("maxLimit", r.payload.data.limitation); + }); + }; + + useEffect(() => { + fetchData(); + }, []); + + useEffect(() => { + formik.validateForm(); + }, []); + + return ( + + + حداکثر فروش به خارج استان + + + { + setFreeSale(true); + }} + /> + } + label="فعال" + /> + { + dispatch( + provincePolicyEditFreeSaleAllowState({ + allow: false, + }) + ).then((r) => { + if (r.payload.error) { + openNotif({ + vertical: "top", + horizontal: "center", + msg: r.payload.error, + severity: "error", + }); + } else { + fetchData(); + openNotif({ + vertical: "top", + horizontal: "center", + msg: "عملیات با موفقیت انجام شد.", + severity: "success", + }); + } + }); + }} + name="item6" + /> + } + label="بدون محدودیت" + /> + + {freeSale && ( + <> + + setIsLimited(!isLimited)} + color="primary" + /> + } + label="درصد محدودیت جوجه ریزی" + /> + + + {isLimited && ( + + + + )} + + + + + + )} + + ); +}; diff --git a/src/features/province/components/province-policy-council-maximum-bar-quantity/ProvincePolicyCouncilMaximumBarQuantity.js b/src/features/province/components/province-policy-council-maximum-bar-quantity/ProvincePolicyCouncilMaximumBarQuantity.js new file mode 100644 index 0000000..9781d4b --- /dev/null +++ b/src/features/province/components/province-policy-council-maximum-bar-quantity/ProvincePolicyCouncilMaximumBarQuantity.js @@ -0,0 +1,167 @@ +import React, { useContext, useEffect, useState } from "react"; +import { Grid } from "../../../../components/grid/Grid"; +import { + Button, + FormControlLabel, + Radio, + TextField, + Typography, +} from "@mui/material"; +import { useFormik } from "formik"; +import { useDispatch } from "react-redux"; +import { Yup } from "../../../../lib/yup/yup"; +import { AppContext } from "../../../../contexts/AppContext"; +import { + provincePolicyEditMaximumBarQuantityStatus, + provincePolicyGetMaximumBarQuantityStatus, +} from "../../services/province-policy-get-maximum-bar-quantity"; + +export const ProvincePolicyCouncilMaximumBarQuantity = () => { + const [maximumQuantity, setMaximumQuantity] = useState(false); + const dispatch = useDispatch(); + const [openNotif] = useContext(AppContext); + + const formik = useFormik({ + initialValues: { + maxLimit: "", + }, + validationSchema: Yup.object({ + maxLimit: Yup.number().required("این فیلد اجباری است"), + }), + }); + + const fetchData = () => { + dispatch(provincePolicyGetMaximumBarQuantityStatus()).then((r) => { + setMaximumQuantity(r.payload.data.allow); + formik.setFieldValue("maxLimit", r.payload.data.limitation); + }); + }; + + useEffect(() => { + fetchData(); + }, []); + + useEffect(() => { + formik.validateForm(); + }, []); + + return ( + + + حداکثر حجم بار تخصیصی به خودرو + + + { + setMaximumQuantity(true); + }} + /> + } + label="فعال" + /> + { + dispatch( + provincePolicyEditMaximumBarQuantityStatus({ + allow: false, + }) + ).then((r) => { + if (r.payload.error) { + openNotif({ + vertical: "top", + horizontal: "center", + msg: r.payload.error, + severity: "error", + }); + } else { + fetchData(); + openNotif({ + vertical: "top", + horizontal: "center", + msg: "عملیات با موفقیت انجام شد.", + severity: "success", + }); + } + }); + }} + name="item6" + /> + } + label="غیر فعال" + /> + + {maximumQuantity && ( + <> + + + + + + + + + )} + + ); +}; diff --git a/src/features/province/components/province-policy-council-slaughter-submit-buying-price/ProvincePolicyCouncilSlaughterSubmitBuyingPrice.js b/src/features/province/components/province-policy-council-slaughter-submit-buying-price/ProvincePolicyCouncilSlaughterSubmitBuyingPrice.js new file mode 100644 index 0000000..152f09e --- /dev/null +++ b/src/features/province/components/province-policy-council-slaughter-submit-buying-price/ProvincePolicyCouncilSlaughterSubmitBuyingPrice.js @@ -0,0 +1,117 @@ +import React, { useContext, useEffect, useState } from "react"; +import { Grid } from "../../../../components/grid/Grid"; +import { FormControlLabel, Radio, Typography } from "@mui/material"; +import { useDispatch } from "react-redux"; +import { AppContext } from "../../../../contexts/AppContext"; +import { + provincePolicyEditSlaughterSubmitBuyingPriceStatus, + provincePolicyGetSLaughterSubmitBuyingPriceStatus, +} from "../../services/province-policy-get-slaughter-buying-price-status"; + +export const ProvincePolicyCouncilSlaughterSubmitBuyingPrice = () => { + const [submitStatus, SetSubmitStatus] = useState(false); + const dispatch = useDispatch(); + const [openNotif] = useContext(AppContext); + + const fetchData = () => { + dispatch(provincePolicyGetSLaughterSubmitBuyingPriceStatus()).then((r) => { + SetSubmitStatus(r.payload.data.allow); + }); + }; + + useEffect(() => { + fetchData(); + }, []); + + return ( + + + ثبت قیمت خرید توسط کشتارگاه + + + { + SetSubmitStatus(true); + dispatch( + provincePolicyEditSlaughterSubmitBuyingPriceStatus({ + allow: true, + }) + ).then((r) => { + if (r.payload.error) { + openNotif({ + vertical: "top", + horizontal: "center", + msg: r.payload.error, + severity: "error", + }); + } else { + fetchData(); + openNotif({ + vertical: "top", + horizontal: "center", + msg: "عملیات با موفقیت انجام شد.", + severity: "success", + }); + } + }); + }} + /> + } + label="فعال" + /> + { + SetSubmitStatus(false); + dispatch( + provincePolicyEditSlaughterSubmitBuyingPriceStatus({ + allow: false, + }) + ).then((r) => { + if (r.payload.error) { + openNotif({ + vertical: "top", + horizontal: "center", + msg: r.payload.error, + severity: "error", + }); + } else { + fetchData(); + openNotif({ + vertical: "top", + horizontal: "center", + msg: "عملیات با موفقیت انجام شد.", + severity: "success", + }); + } + }); + }} + /> + } + label="غیر فعال" + /> + + + ); +}; diff --git a/src/features/province/components/province-policy-council-validate-poultry-with-sms/ProvincePolicyCouncilValidatePoultryWithSms.js b/src/features/province/components/province-policy-council-validate-poultry-with-sms/ProvincePolicyCouncilValidatePoultryWithSms.js new file mode 100644 index 0000000..8295a68 --- /dev/null +++ b/src/features/province/components/province-policy-council-validate-poultry-with-sms/ProvincePolicyCouncilValidatePoultryWithSms.js @@ -0,0 +1,119 @@ +import React, { useContext, useEffect, useState } from "react"; +import { Grid } from "../../../../components/grid/Grid"; +import { FormControlLabel, Radio, Typography } from "@mui/material"; +import { useDispatch } from "react-redux"; +import { AppContext } from "../../../../contexts/AppContext"; +import { + provincePolicyEditValidatePoultryWithSmsStatusService, + provincePolicyValidatePoultryWithSmsStatusService, +} from "../../services/province-policy-validate-poultry-wth-sms-service"; + +export const ProvincePolicyCouncilValidatePoultryWithSms = () => { + const [submitStatus, SetSubmitStatus] = useState(false); + const dispatch = useDispatch(); + const [openNotif] = useContext(AppContext); + + const fetchData = () => { + dispatch(provincePolicyValidatePoultryWithSmsStatusService()).then((r) => { + SetSubmitStatus(r.payload.data.poultryStatus); + }); + }; + + useEffect(() => { + fetchData(); + }, []); + + return ( + + + + احراز پیامکی قیمت مرغ برای مرغدار + + + + { + SetSubmitStatus(true); + dispatch( + provincePolicyEditValidatePoultryWithSmsStatusService({ + poultry_status: true, + }) + ).then((r) => { + if (r.payload.error) { + openNotif({ + vertical: "top", + horizontal: "center", + msg: r.payload.error, + severity: "error", + }); + } else { + fetchData(); + openNotif({ + vertical: "top", + horizontal: "center", + msg: "عملیات با موفقیت انجام شد.", + severity: "success", + }); + } + }); + }} + /> + } + label="فعال" + /> + { + SetSubmitStatus(false); + dispatch( + provincePolicyEditValidatePoultryWithSmsStatusService({ + poultry_status: false, + }) + ).then((r) => { + if (r.payload.error) { + openNotif({ + vertical: "top", + horizontal: "center", + msg: r.payload.error, + severity: "error", + }); + } else { + fetchData(); + openNotif({ + vertical: "top", + horizontal: "center", + msg: "عملیات با موفقیت انجام شد.", + severity: "success", + }); + } + }); + }} + /> + } + label="غیر فعال" + /> + + + ); +}; diff --git a/src/features/province/components/province-policy-council/ProvincePolicyCouncil.js b/src/features/province/components/province-policy-council/ProvincePolicyCouncil.js new file mode 100644 index 0000000..96742df --- /dev/null +++ b/src/features/province/components/province-policy-council/ProvincePolicyCouncil.js @@ -0,0 +1,642 @@ +import { + Checkbox, + FormControl, + FormControlLabel, + IconButton, + InputLabel, + MenuItem, + Radio, + Select, + Tab, + Tabs, + Tooltip, + Typography, +} from "@mui/material"; +import { useEffect, useState } from "react"; +import { useDispatch } from "react-redux"; + +import { useNavigate } from "react-router-dom"; +import LiveHelpIcon from "@mui/icons-material/LiveHelp"; +import { Grid } from "../../../../components/grid/Grid"; +import { + ROUTE_ADMINX_ROUTE_POLICY_COUNCIL_FREE_SALE, + ROUTE_PROVINCE_ROUTE_POLICY_COUNCIL_FREE_SALE, + ROUTE_PROVINCE_ROUTE_POLICY_COUNCIL_POULTRY_CHOOSE_SLAUGHTER, + ROUTE_SUPER_ADMIN_ROUTE_POLICY_COUNCIL_FREE_SALE, +} from "../../../../routes/routes"; +import { provinceGetPolicyPoultryChooseKillHouseService } from "../../services/province-get-policy-poultry-choose-kill-house"; +import { provincePolicyFreeSaleService } from "../../services/province-policy-free-sale"; +import { provincePolicyGetFreeSaleService } from "../../services/province-policy-get-free-sale"; +import { provincePolicyPoultryChooseKillHouseService } from "../../services/province-policy-poultry-choose-kill-house"; +import TuneIcon from "@mui/icons-material/Tune"; +import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl"; +import { hourLimitKillRequestService } from "../../../city/services/hour-limit-kill-request"; +import { provincePolicyAutoAcceptSlaughterService } from "../../services/province-policy-auto-accept-slaughter"; +import { provincePolicyGetAutoAcceptSlaughterService } from "../../services/province-policy-get-auto-accept-slaughter"; +import { provincePolicyAutoAllocateCarService } from "../../services/province-policy-auto-allocate-car"; +import { provincePolicyGetAutoAllocateCarService } from "../../services/province-policy-get-auto-allocate-car"; + +import { ProvinceApplyDefaultLosses } from "../province-apply-default-losses/ProvinceApplyDefaultLosses"; +import { ProvinceSlaughterDirectBuyPermission } from "../province-slaughter-direct-buy-permission/ProvinceSlaughterDirectBuyPermission"; +import { ProvincePolicyKillhouseHourLimit } from "../province-policy-killhouse-hour-limit/ProvincePolicyKillhouseHourLimit"; +import { hourLimitGetKillRequestService } from "../../../city/services/hour-limit-get-kill-request"; +import { ProvincePolicyProvinceFee } from "../province-policy-province-fee/ProvincePolicyProvinceFee"; +import { provinceGetEvacuationPermit } from "../../services/province-get-evacuation-permit"; + +import { provinceEditEvacuationPermit } from "../../services/province-edit-evacuation-permit"; +import { provinceGetSellForFreezingStatus } from "../../services/province-get-sell-for-freezing-status"; +import { provinceSetSellForFreezing } from "../../services/province-set-sell-for-freezing-access"; +import ProvincePolicyLimitAccess from "../province-policy-limit-access/ProvincePolicyLimitAccess"; +import { ProvincePolicyApprovedPrice } from "../province-policy-approved-price/ProvincePolicyApprovedPrice"; +import { ProvincePolicySlaughterAge } from "../province-policy-slaughter-age/ProvincePolicySlaughterAge"; +import { ProvincePolicyTimeRange } from "../province-policy-time-range/ProvincePolicyTimeRange"; +import ProvincePolicyWageFractions from "../province-policy-wage-fractions/ProvincePolicyWageFractions"; +import { ProvincePolicyCouncilAllowFreeSale } from "../province-policy-council-allow-free-sale/ProvincePolicyCouncilAllowFreeSale"; +import { ProvincePolicyCouncilAllowExport } from "../province-policy-council-allow-export/ProvincePolicyCouncilAllowExport"; +import { ProvincePolicyCouncilAllowAggegateBarInfo } from "../province-policy-council-allow-aggregate-bar-info/ProvincePolicyCouncilAllowAggegateBarInfo"; +import { ProvincePolicyCouncilMaximumBarQuantity } from "../province-policy-council-maximum-bar-quantity/ProvincePolicyCouncilMaximumBarQuantity"; +import { ProvincePolicyCouncilSlaughterSubmitBuyingPrice } from "../province-policy-council-slaughter-submit-buying-price/ProvincePolicyCouncilSlaughterSubmitBuyingPrice"; +import { ProvincePolicyAutomaticAcceptDirectBuying } from "../province-policy-automatic-accept-direct-buying/ProvincePolicyAutomaticAcceptDirectBuying"; +import { ProvincePolicyCouncilValidatePoultryWithSms } from "../province-policy-council-validate-poultry-with-sms/ProvincePolicyCouncilValidatePoultryWithSms"; +import { ProvincePolicyDropLimit } from "../province-policy-slaughter-drop-limit/ProvincePolicyDropLimit"; +import { ProvincePolicyUploadSlaughterInProvinceImage } from "../province-policy-upload-image_slaughter_in_province/ProvincePolicyUploadSlaughterInProvinceImage"; +import { ProvincePolicyUploadImageSlaughterOutProvince } from "../province_policy_upload_image_slaughter_out_province/ProvincePolicyUploadImageSlaughterOutProvince"; +import { ProvincePolicyUploadStewardInProvinceImage } from "../province-policy-steward-in-province-Upload-image/ProvincePolicyUploadStewardInProvinceImage"; +import { ProvincePolicyUploadImageStewardOutProvince } from "../province-policy-steward-out-province-upload-image/ProvincePolicyUploadImageStewardOutProvince"; + +import { ProvincePolicyDirectBuying } from "../province-policy-direct-buying/ProvincePolicyDirectBuying"; +import { ProvincePolicyTradeTimeRange } from "../province-policy-trade-time-range/ProvincePolicyTradeTimeRange"; +import { ProvinceMandatorySuperVisorAuthenticationCode } from "../province-mandatory-supervisor-authentication-code/ProvinceMandatorySuperVisorAuthenticationCode"; +import { ProvinceMandatorySlaughterhouseVerificationCode } from "../province-mandatory-slaughterhouse-verification-code/ProvinceMandatorySlaughterhouseVerificationCode"; +import { ProvincePolicyDirectPurchaseBarLimitation } from "../province-policy-direct-purchase-bar-limitation/ProvincePolicyDirectPurchaseBarLimitation"; +import { ManageEvacuations } from "../manage-evacuations/ManageEvacuations"; +import { ProvincePolicyMarketDailyLimitation } from "../province-policy-market-daily-limitation/ProvincePolicyMarketDailyLimitation"; +import { ProvinceHatchingArchivePercent } from "../province-hatching-archive-percent/ProvinceHatchingArchivePercent"; + +export const ProvincePolicyCouncil = () => { + const [isFirstLoad, setIsFirstLoad] = useState(true); + const [value, setValue] = useState("0"); + const [freeSale, setFreeSale] = useState(false); + + const [poultryChooseSlaughter, setPoultryChooseSlaughter] = useState(false); + const [autoAcceptSlaughter, setAutoAcceptSlaughter] = useState(false); + const [autoCarAllocateSlaughter, setAutoCarAllocateSlaughter] = + useState(false); + + const dispatch = useDispatch(); + const navigate = useNavigate(); + const hours = Array.from({ length: 8 }, (_, i) => i + 8); + const [isChecked, setIsChecked] = useState(false); + const [selectedHour, setSelectedHour] = useState(""); + const [evacuationBeforeQuarantineCode, setEvacuationBeforeQuarantineCode] = + useState("optional"); + const [sellForFreezing, setSellForFreezing] = useState(false); + + const [hovered, setHovered] = useState(false); + + const [mandatory, setMandatory] = useState(false); + + const handleChange = (event) => { + if (event.target.name === "item1") { + setFreeSale(event.target.checked); + dispatch( + provincePolicyFreeSaleService({ + allow: event.target.checked, + }) + ); + } + + if (event.target.name === "item6") { + setPoultryChooseSlaughter(event.target.checked); + dispatch( + provincePolicyPoultryChooseKillHouseService({ + allow: event.target.checked, + mandatory, + }) + ); + } + + if (event.target.name === "autoAcceptSlaughter") { + setAutoAcceptSlaughter(event.target.checked); + dispatch( + provincePolicyAutoAcceptSlaughterService({ + allow: event.target.checked, + }) + ); + } + + if (event.target.name === "autoCarAllocateSlaughter") { + setAutoCarAllocateSlaughter(event.target.checked); + dispatch( + provincePolicyAutoAllocateCarService({ + allow: event.target.checked, + }) + ); + } + }; + + useEffect(() => { + dispatch(provincePolicyGetFreeSaleService()).then((r) => { + setFreeSale(r.payload.data); + }); + + dispatch(provinceGetPolicyPoultryChooseKillHouseService()).then((r) => { + setPoultryChooseSlaughter(r.payload.data.allowState); + setMandatory(r.payload.data.mandatory); + }); + + dispatch(provincePolicyGetAutoAcceptSlaughterService()).then((r) => { + setAutoAcceptSlaughter(r.payload.data); + }); + + dispatch(provincePolicyGetAutoAllocateCarService()).then((r) => { + setAutoCarAllocateSlaughter(r.payload.data); + }); + + dispatch(provinceGetEvacuationPermit()).then((r) => { + setEvacuationBeforeQuarantineCode(r.payload.data.type); + }); + + dispatch(provinceGetSellForFreezingStatus()).then((r) => { + setSellForFreezing(r.payload.data.permission); + }); + }, []); + + useEffect(() => { + setIsFirstLoad(false); + if (!isFirstLoad) { + dispatch( + provincePolicyPoultryChooseKillHouseService({ + allow: poultryChooseSlaughter, + mandatory, + }) + ); + } + }, [mandatory]); + + useEffect(() => { + if (isChecked && selectedHour) { + dispatch( + hourLimitKillRequestService({ hour: selectedHour, active: isChecked }) + ); + } + if (!isChecked && selectedHour) { + setSelectedHour(null); + dispatch(hourLimitKillRequestService({ hour: 0, active: isChecked })); + } + }, [selectedHour, isChecked]); + + useEffect(() => { + dispatch(hourLimitGetKillRequestService()).then((r) => { + setIsChecked(r.payload.data.active); + setSelectedHour(r.payload.data.hour); + }); + }, []); + + const handleChangeEvacuationPermit = (e) => { + dispatch(provinceEditEvacuationPermit({ type: e })).then(() => { + dispatch(provinceGetEvacuationPermit()).then((r) => { + setEvacuationBeforeQuarantineCode(r.payload.data.type); + }); + }); + }; + + const handleChangeSellForFreezing = (e) => { + dispatch(provinceSetSellForFreezing({ permission: e })).then(() => { + dispatch(provinceGetSellForFreezingStatus()).then((r) => { + setSellForFreezing(r.payload.data.permission); + }); + }); + }; + const handleChangeTab = (event, newValue) => { + setValue(newValue); + }; + + return ( + + + مدیریت فرآیند + + + + + + {/* */} + + + + + {value === "0" && ( + + + + + + } + label="مدیر اجرایی (اتحادیه)" + /> + + + + } + label="مجوز فروش به خارج استان (زنده)" + /> + + { + navigate( + getRoleFromUrl() === "ProvinceOperator" + ? ROUTE_PROVINCE_ROUTE_POLICY_COUNCIL_FREE_SALE + : getRoleFromUrl() === "SuperAdmin" + ? ROUTE_SUPER_ADMIN_ROUTE_POLICY_COUNCIL_FREE_SALE + : ROUTE_ADMINX_ROUTE_POLICY_COUNCIL_FREE_SALE + ); + }} + > + + + + + + + + + + تخلیه با کد قرنطینه + + { + handleChangeEvacuationPermit("force"); + }} + /> + } + label="اجباری" + /> + { + handleChangeEvacuationPermit("optional"); + }} + name="item6" + /> + } + label="اختیاری" + /> + + + + + مجوز فروش مرغ برای انجماد + + + { + handleChangeSellForFreezing(true); + }} + /> + } + label="فعال" + /> + { + handleChangeSellForFreezing(false); + }} + name="item6" + /> + } + label="غیر فعال" + /> + + + + + + + + + + + + + + + + + + + + + + + + + + + )} + + {value === "1" && ( + + + + + } + label="اولویت بندی کشتارگاه توسط مرغدار" + /> + + { + navigate( + ROUTE_PROVINCE_ROUTE_POLICY_COUNCIL_POULTRY_CHOOSE_SLAUGHTER + ); + }} + > + + + + {poultryChooseSlaughter && ( + <> + setMandatory(true)} + /> + } + label="اجباری" + /> + setMandatory(false)} + value={false} + name="item6" + /> + } + label="اختیاری" + /> + + )} + + + } + label="فروش خارج از شبکه" + /> + + } + label="فعال سازی پنل بورس" + /> + + + } + label="تسویه حساب مالی" + /> + + setHovered(true)} + onMouseLeave={() => setHovered(false)} + > + + + + + + {(getRoleFromUrl() === "ProvinceOperator" || + getRoleFromUrl() === "SuperAdmin") && ( + + )} + {(getRoleFromUrl() === "ProvinceOperator" || + getRoleFromUrl() === "SuperAdmin") && ( + + setIsChecked(!isChecked)} + /> + } + label="محدودیت زمان درخواست کشتار مرغدار" + /> + {isChecked && ( + + ساعت پایان درخواست + + + )} + + )} + + } + label="تایید خودکار حجم تخصیصی به کشتارگاه" + /> + + } + label="ایجاد خودروی حمل بار برای کشتارگاه" + /> + + } + label="عدم امکان وارد کردن اطلاعات بار در صورت تایید نکردن تخلیه دامپزشک کشتارگاه" + /> + + + {/* */} + + + )} + + {value === "2" && ( + + + + )} + + {value === "3" && ( + + + + )} + {value === "4" && ( + + + + )} + + ); +}; diff --git a/src/features/province/components/province-policy-direct-buying/ProvincePolicyDirectBuying.js b/src/features/province/components/province-policy-direct-buying/ProvincePolicyDirectBuying.js new file mode 100644 index 0000000..b90e6a1 --- /dev/null +++ b/src/features/province/components/province-policy-direct-buying/ProvincePolicyDirectBuying.js @@ -0,0 +1,252 @@ +import { + FormControlLabel, + Button, + Radio, + Typography, + TextField, +} from "@mui/material"; +import { useEffect, useState, useContext } from "react"; +import { useDispatch } from "react-redux"; + +import { useFormik } from "formik"; + +import { Grid } from "../../../../components/grid/Grid"; +import { Yup } from "../../../../lib/yup/yup"; + +import { directEditBuyingVerification } from "../../services/direct-edit-buying-verification"; +import { directBuyingVerification } from "../../services/direct-buying-verification"; + +import { paymentGetDeadLines } from "../../services/payment-get-deadlines"; +import { paymentEditDeadLines } from "../../services/payment-edit-deadlines"; + +import { AppContext } from "../../../../contexts/AppContext"; + +export const ProvincePolicyDirectBuying = () => { + const dispatch = useDispatch(); + const [openNotif] = useContext(AppContext); + + const [directVerificationBuying, setDirectBuyingVerifivation] = + useState(false); + const [paymentDeadLine, setPaymentDeadLine] = useState(false); + + const formik = useFormik({ + initialValues: { + payment_deadline_days: "", + }, + validationSchema: Yup.object({ + payment_deadline_days: Yup.number() + .required("این فیلد اجباری است") + .min(0, "حداقل مقدار باید 0 باشد") + .max(100, "حداکثر مقدار باید 100 باشد"), + }), + }); + + useEffect(() => { + dispatch(directBuyingVerification()).then((r) => { + const isMandatory = r.payload.data?.poultryCodeMandatory; + setDirectBuyingVerifivation(isMandatory); + }); + + dispatch(paymentGetDeadLines()).then((r) => { + const isPaymentDeadline = r.payload?.data?.paymentDeadline ?? false; + setPaymentDeadLine(isPaymentDeadline); + + if (isPaymentDeadline && r.payload?.data?.paymentDeadlineDays) { + formik.setFieldValue( + "payment_deadline_days", + r.payload.data.paymentDeadlineDays + ); + } + }); + }, []); + + const handleChangeDirectBuyingVerification = (e) => { + dispatch(directEditBuyingVerification({ poultry_code_mandatory: e })).then( + () => { + dispatch(directBuyingVerification()).then((r) => { + setDirectBuyingVerifivation(r.payload?.data?.poultryCodeMandatory); + }); + } + ); + }; + + const handleChangePaymentDeadLines = (value) => { + const isActive = value === true; + if (!isActive) { + dispatch( + paymentEditDeadLines({ + payment_deadline: false, + payment_deadline_days: 0, + }) + ).then((r) => { + if (r.error) { + openNotif({ + vertical: "top", + horizontal: "center", + msg: "مشکلی پیش آمده است!", + severity: "error", + }); + } else { + openNotif({ + vertical: "top", + horizontal: "center", + msg: "غیرفعال شد.", + severity: "success", + }); + } + }); + } + + setPaymentDeadLine(isActive); + }; + + const handleSubmitPaymentDeadline = () => { + dispatch( + paymentEditDeadLines({ + payment_deadline: true, + payment_deadline_days: parseInt(formik.values.payment_deadline_days), + }) + ).then((r) => { + if (r.error) { + openNotif({ + vertical: "top", + horizontal: "center", + msg: "مشکلی پیش آمده است!", + severity: "error", + }); + } else { + openNotif({ + vertical: "top", + horizontal: "center", + msg: "تنظیمات با موفقیت ذخیره شد.", + + severity: "success", + }); + } + }); + }; + + return ( + <> + + ثبت کداحراز خرید مستقیم مرغدار + + { + handleChangeDirectBuyingVerification(true); + }} + /> + } + label="اجباری" + /> + { + handleChangeDirectBuyingVerification(false); + }} + name="item6" + /> + } + label="اختیاری" + /> + + + + + حداکثر مهلت تسویه با مرغدار + + + handleChangePaymentDeadLines(true)} + /> + } + label="فعال" + /> + + handleChangePaymentDeadLines(false)} + name="item6" + /> + } + label="غیر فعال" + /> + + + {paymentDeadLine !== false && ( + <> + + + + + + + + )} + + + ); +}; diff --git a/src/features/province/components/province-policy-direct-purchase-bar-limitation/ProvincePolicyDirectPurchaseBarLimitation.js b/src/features/province/components/province-policy-direct-purchase-bar-limitation/ProvincePolicyDirectPurchaseBarLimitation.js new file mode 100644 index 0000000..e163884 --- /dev/null +++ b/src/features/province/components/province-policy-direct-purchase-bar-limitation/ProvincePolicyDirectPurchaseBarLimitation.js @@ -0,0 +1,252 @@ +import React, { useContext, useEffect, useState } from "react"; +import { Grid } from "../../../../components/grid/Grid"; +import { useDispatch } from "react-redux"; +import { + Button, + FormControl, + FormControlLabel, + Radio, + RadioGroup, + Typography, +} from "@mui/material"; +import TimePicker from "../../../../components/date-picker/CustomDatePicker"; +import { AppContext } from "../../../../contexts/AppContext"; +import { + provincePolicyGetDirectPurchaseBarLimitation, + provincePolicyEditDirectPurchaseBarLimitation, +} from "../../services/province-policy-direct-purchase-bar-limitation"; + +const DEFAULT_LIMITATION = { + id: null, + key: null, + active: false, + start_time: "08:00:00", + end_time: "18:00:00", + allowBuying: null, +}; + +export const ProvincePolicyDirectPurchaseBarLimitation = () => { + const dispatch = useDispatch(); + const [openNotif] = useContext(AppContext); + const [limitation, setLimitation] = useState(DEFAULT_LIMITATION); + + useEffect(() => { + dispatch(provincePolicyGetDirectPurchaseBarLimitation()).then((r) => { + if (r.payload?.data) { + const d = r.payload.data; + setLimitation({ + id: d.id, + key: d.key, + active: d.active, + start_time: d.startTime, + end_time: d.endTime, + allowBuying: d.allowBuying ?? null, + }); + } + }); + }, [dispatch]); + + const handleActiveChange = (e) => { + const nextActive = e.target.value === "true"; + const nextLimitation = { ...limitation, active: nextActive }; + setLimitation(nextLimitation); + + if (!nextActive) { + dispatch( + provincePolicyEditDirectPurchaseBarLimitation({ + id: limitation.id, + data: { active: false }, + }) + ).then((r) => { + if (r.payload?.error) { + openNotif({ + vertical: "top", + horizontal: "center", + msg: r.payload.error, + severity: "error", + }); + } else if (r.payload?.data) { + const d = r.payload.data; + setLimitation((prev) => ({ + ...prev, + id: d.id ?? prev.id, + key: d.key ?? prev.key, + active: d.active ?? prev.active, + start_time: d.startTime ?? prev.start_time, + end_time: d.endTime ?? prev.end_time, + allowBuying: d.allowBuying ?? prev.allowBuying, + })); + openNotif({ + vertical: "top", + horizontal: "center", + msg: "عملیات با موفقیت انجام شد.", + severity: "success", + }); + } + }); + } + }; + + const handleAllowBuyingChange = (e) => { + const value = e.target.value === "بلی"; + setLimitation((prev) => ({ ...prev, allowBuying: value })); + }; + + const handleSave = () => { + dispatch( + provincePolicyEditDirectPurchaseBarLimitation({ + id: limitation.id, + data: { + active: limitation.active, + start_time: limitation.start_time, + end_time: limitation.end_time, + allow_buying: limitation.allowBuying, + }, + }) + ).then((r) => { + if (r.payload?.error) { + openNotif({ + vertical: "top", + horizontal: "center", + msg: r.payload.error, + severity: "error", + }); + } else if (r.payload?.data) { + const d = r.payload.data; + setLimitation({ + id: d.id ?? limitation.id, + key: d.key ?? limitation.key, + active: d.active ?? limitation.active, + start_time: d.startTime ?? limitation.start_time, + end_time: d.endTime ?? limitation.end_time, + allowBuying: d.allowBuying ?? limitation.allowBuying, + }); + openNotif({ + vertical: "top", + horizontal: "center", + msg: "عملیات با موفقیت انجام شد.", + severity: "success", + }); + } + }); + }; + + return ( + + + بازه‌ی اضطراری خرید و ایجاد بعدی + + + + + + + } label="فعال" /> + } + label="غیر فعال" + /> + + + + + {limitation.active && ( + + + + setLimitation((prev) => ({ ...prev, start_time: newTime })) + } + label="از" + /> + + + + setLimitation((prev) => ({ ...prev, end_time: newTime })) + } + label="تا" + /> + + + )} + + {limitation.active && ( + + + اجازه خرید دارد؟ + + + + } label="بلی" /> + } label="خیر" /> + + + + )} + + {limitation.active && ( + + + + )} + + + ); +}; diff --git a/src/features/province/components/province-policy-document-states/ProvincePolicyDocumentStates.js b/src/features/province/components/province-policy-document-states/ProvincePolicyDocumentStates.js new file mode 100644 index 0000000..20f435a --- /dev/null +++ b/src/features/province/components/province-policy-document-states/ProvincePolicyDocumentStates.js @@ -0,0 +1,471 @@ +import React, { useContext, useEffect, useState } from "react"; +import { Grid } from "../../../../components/grid/Grid"; +import { + Button, + Checkbox, + FormControlLabel, + IconButton, + List, + ListItemButton, + ListItemIcon, + ListItemText, + Popover, + TextField, + Tooltip, + Typography, +} from "@mui/material"; +import { useDispatch } from "react-redux"; +import { + getDocumentStates, + submitDocumentStates, +} from "../../services/getDocumentStates"; +import { SimpleTable } from "../../../../components/simple-table/SimpleTable"; +import { CLOSE_MODAL, OPEN_MODAL } from "../../../../lib/redux/slices/appSlice"; +import { useFormik } from "formik"; +import { Yup } from "../../../../lib/yup/yup"; +import { + provincePolicyDeleteDocumentState, + provincePolicyEditDocumentState, + provincePolicySubmitDocumentState, +} from "../../services/province-policy-submit-document-state"; +import { AppContext } from "../../../../contexts/AppContext"; +import EditIcon from "@mui/icons-material/Edit"; +import DeleteIcon from "@mui/icons-material/Delete"; +import TuneIcon from "@mui/icons-material/Tune"; + +// import { AppContext } from "../../../../contexts/AppContext"; + +export const ProvincePolicyDocumentStates = () => { + const dispatch = useDispatch(); + const [tableData, setTableData] = useState([]); + const [editPriorityMode, setEditPriorityMode] = useState(false); + const [priorities, setPriorities] = useState([]); + const [data, setData] = useState([]); + + const handleTextChange = (event, i) => { + const newlist = [...priorities]; + newlist[i] = { ...newlist[i], value: parseInt(event.target.value) }; + setPriorities(newlist); + }; + + const [openNotif] = useContext(AppContext); + + const fetchData = () => { + dispatch(getDocumentStates()).then((r) => { + setData(r.payload.data); + const fields = r.payload.data?.map((item) => { + return { key: item?.key, value: item?.priorityId }; + }); + setPriorities(fields); + }); + }; + + useEffect(() => { + const d = data?.map((item, i) => { + return [ + editPriorityMode ? ( + handleTextChange(e, i)} + /> + ) : ( + item?.priorityId + ), + item?.title, + item?.sms ? "دارد" : "ندارد", + item?.isError ? ( + + ندارد + + ) : ( + + دارد + + ), + + { + dispatch( + OPEN_MODAL({ + title: "ویرایش وضعیت", + content: ( + + ), + }) + ); + }} + onDelete={() => { + dispatch(provincePolicyDeleteDocumentState(item?.id)).then( + (r) => { + if (r.payload.error) { + openNotif({ + vertical: "top", + horizontal: "center", + msg: r.payload.error, + severity: "error", + }); + } else { + fetchData(); + openNotif({ + vertical: "top", + horizontal: "center", + msg: "عملیات با موفقیت انجام شد.", + severity: "success", + }); + } + } + ); + }} + /> + , + ]; + }); + setTableData(d); + }, [data, priorities, editPriorityMode]); + + useEffect(() => { + fetchData(); + }, []); + + const DocumentStateActions = ({ onEdit, onDelete }) => { + const [anchorEl, setAnchorEl] = useState(null); + const open = Boolean(anchorEl); + + const handleOpen = (event) => { + setAnchorEl(event.currentTarget); + }; + + const handleClose = () => { + setAnchorEl(null); + }; + + const handleEdit = () => { + onEdit(); + handleClose(); + }; + + const handleDelete = () => { + onDelete(); + handleClose(); + }; + + return ( + + + + + + + + + + + + + + ویرایش + + } + /> + + + + + + + حذف + + } + /> + + + + + ); + }; + + return ( + + + وضعیت اسناد + + + {editPriorityMode ? ( + + + + + ) : ( + + )} + + + + + ); +}; + +const ProvincePolicyDocumentStatesModal = ({ fetchData, isEdit, item }) => { + const [sms, setSms] = useState(item?.sms ? true : false); + const [isError, setIsError] = useState(item?.isError ? true : false); + const dispatch = useDispatch(); + const handleChangeSms = (event) => { + setSms(event.target.checked); + }; + + const handleChangeIsError = (event) => { + setIsError(event.target.checked); + }; + + const formik = useFormik({ + initialValues: { + stateTitle: item?.title ? item?.title : "", + priority: item?.priorityId ? item?.priorityId : 1, + }, + validationSchema: Yup.object({ + stateTitle: Yup.string() + .required("این فیلد اجباری است!") + .typeError("لطفا عنوان وضعیت را وارد کنید!"), + priority: Yup.number() + .required("این فیلد اجباری است!") + .typeError("لطفا عنوان وضعیت را وارد کنید!") + .min(1, "عدد مثبت وارد کنید!"), + }), + }); + + useEffect(() => { + formik.validateForm(); + }, []); + + const [openNotif] = useContext(AppContext); + + return ( + + + {isEdit && ( + + )} + + + + } + label="ارسال پیامک" + /> + + + } + label="محدود کننده" + /> + + + + + ); +}; diff --git a/src/features/province/components/province-policy-edit-fine/ProvincePolicyEditFine.js b/src/features/province/components/province-policy-edit-fine/ProvincePolicyEditFine.js new file mode 100644 index 0000000..a68ab05 --- /dev/null +++ b/src/features/province/components/province-policy-edit-fine/ProvincePolicyEditFine.js @@ -0,0 +1,156 @@ +import React, { useContext, useState } from "react"; +import { Grid } from "../../../../components/grid/Grid"; +import { + Button, + TextField, + Radio, + RadioGroup, + FormControlLabel, +} from "@mui/material"; +import { Yup } from "../../../../lib/yup/yup"; +import { useFormik } from "formik"; +import { useDispatch } from "react-redux"; +import { AppContext } from "../../../../contexts/AppContext"; +import { CLOSE_MODAL } from "../../../../lib/redux/slices/appSlice"; +import { provincePolicyEditFinePermission } from "../../services/province-policy-edit-fine-permission"; +import TimePicker from "../../../../components/date-picker/CustomDatePicker"; + +export const ProvincePolicyEditFine = ({ item, fetchData }) => { + const dispatch = useDispatch(); + const [openNotif] = useContext(AppContext); + + const [range, setRange] = useState({ + start_time: item?.startTime || "01:00:00", + end_time: item?.endTime || "24:00:00", + fine: item?.fine || false, + }); + + const formik = useFormik({ + initialValues: { + fine_coefficient: item?.fineCoefficient || 0, + }, + validationSchema: Yup.object({ + fine_coefficient: Yup.number() + .typeError("لطفا فیلد را به صورت عددی وارد کنید!") + .required("این فیلد اجباری است!"), + }), + onSubmit: async (values) => { + const payload = { + key: item?.key, + fine: range.fine, + start_time: range.fine ? range.start_time : "00:00:00", + end_time: range.fine ? range.end_time : "00:00:00", + fine_coefficient: range.fine ? values.fine_coefficient : 0, + }; + + dispatch(provincePolicyEditFinePermission(payload)).then((r) => { + if (r.payload.error) { + openNotif({ + vertical: "top", + horizontal: "center", + msg: r.payload.error, + severity: "error", + }); + } else { + openNotif({ + vertical: "top", + horizontal: "center", + msg: "عملیات با موفقیت انجام شد.", + severity: "success", + }); + fetchData(); + dispatch(CLOSE_MODAL()); + } + }); + }, + }); + + return ( + +
    + + + + setRange((prev) => ({ + ...prev, + fine: e.target.value === "active", + })) + } + > + } + label="فعال" + /> + } + label="غیرفعال" + /> + + + + {range.fine && ( + + + + + setRange((prev) => ({ ...prev, start_time: newTime })) + } + label="از" + /> + + setRange((prev) => ({ ...prev, end_time: newTime })) + } + label="تا" + /> + + + )} + + + +
    +
    + ); +}; diff --git a/src/features/province/components/province-policy-edit-weight-category/ProvincePolicyEditWeightCategory.js b/src/features/province/components/province-policy-edit-weight-category/ProvincePolicyEditWeightCategory.js new file mode 100644 index 0000000..b3db0ff --- /dev/null +++ b/src/features/province/components/province-policy-edit-weight-category/ProvincePolicyEditWeightCategory.js @@ -0,0 +1,105 @@ +import React, { useContext } from "react"; +import { Grid } from "../../../../components/grid/Grid"; +import { Button, TextField } from "@mui/material"; +import { Yup } from "../../../../lib/yup/yup"; +import { useFormik } from "formik"; +import { useDispatch } from "react-redux"; +import { provincePolicyEditWeightCategory } from "../../services/province-policy-get-weight-category"; +import { AppContext } from "../../../../contexts/AppContext"; +import { CLOSE_MODAL } from "../../../../lib/redux/slices/appSlice"; + +export const ProvincePolicyEditWeightCategory = ({ item, fetchData }) => { + const dispatch = useDispatch(); + const [openNotif] = useContext(AppContext); + + const formik = useFormik({ + initialValues: { + min_value: item?.minValue || "", + max_value: item?.maxValue || "", + }, + validationSchema: Yup.object({ + min_value: Yup.number() + .typeError("لطفا فیلد را به صورت عددی وارد کنید.!") + .required("این فیلد اجباری است!"), + max_value: Yup.number() + .typeError("لطفا فیلد را به صورت عددی وارد کنید.!") + .required("این فیلد اجباری است!"), + }), + + onSubmit: async (values) => { + dispatch( + provincePolicyEditWeightCategory({ ...values, key: item?.key }) + ).then((r) => { + if (r.payload.error) { + openNotif({ + vertical: "top", + horizontal: "center", + msg: r.payload.error, + severity: "error", + }); + } else { + openNotif({ + vertical: "top", + horizontal: "center", + msg: "عملیات با موفقیت انجام شد.", + severity: "success", + }); + fetchData(); + dispatch(CLOSE_MODAL()); + } + }); + }, + }); + + return ( + +
    + + + + + + + +
    +
    + ); +}; diff --git a/src/features/province/components/province-policy-killhouse-guilds/ProvincePolicyKillhouseGuilds.js b/src/features/province/components/province-policy-killhouse-guilds/ProvincePolicyKillhouseGuilds.js new file mode 100644 index 0000000..2f01e33 --- /dev/null +++ b/src/features/province/components/province-policy-killhouse-guilds/ProvincePolicyKillhouseGuilds.js @@ -0,0 +1,54 @@ +import { Checkbox, FormControlLabel, IconButton, Tooltip } from "@mui/material"; +import { useEffect, useState } from "react"; +import { useDispatch } from "react-redux"; +import { Grid } from "../../../../components/grid/Grid"; +import { SPACING } from "../../../../data/spacing"; +// import { updateLossesPermissionService } from "../../services/update-losses-permission"; +import TuneIcon from "@mui/icons-material/Tune"; +import { useNavigate } from "react-router-dom"; +import { ROUTE_PROVINCE_ROUTE_POLICY_COUNCIL_KILLHOUSE_GUILDS } from "../../../../routes/routes"; +import { postKillhouseGuildPermissionService } from "../../services/post-killhouse-guild-permission"; +import { getKillhouseGuildsPermissionService } from "../../services/get-killhouse-guilds-permission"; + +export const ProvincePolicyKillhouseGuilds = () => { + const navigate = useNavigate(); + const [isChecked, setIsChecked] = useState(false); + const dispatch = useDispatch(); + + useEffect(() => { + dispatch(getKillhouseGuildsPermissionService()).then((r) => { + setIsChecked(r.payload.data.allowState); + }); + }, []); + + const handleChange = (event) => { + dispatch( + postKillhouseGuildPermissionService({ + allow: event.target.checked, + }) + ); + setIsChecked(event.target.checked); + }; + + return ( + + + } + label="اجازه ثبت صنف به کشتارگاه ها" + /> + + { + navigate(ROUTE_PROVINCE_ROUTE_POLICY_COUNCIL_KILLHOUSE_GUILDS); + }} + > + + + + + ); +}; diff --git a/src/features/province/components/province-policy-killhouse-hour-limit/ProvincePolicyKillhouseHourLimit.js b/src/features/province/components/province-policy-killhouse-hour-limit/ProvincePolicyKillhouseHourLimit.js new file mode 100644 index 0000000..57a1cc3 --- /dev/null +++ b/src/features/province/components/province-policy-killhouse-hour-limit/ProvincePolicyKillhouseHourLimit.js @@ -0,0 +1,76 @@ +import { + Checkbox, + FormControl, + FormControlLabel, + InputLabel, + MenuItem, + Select, +} from "@mui/material"; +import { useEffect, useState } from "react"; +import { useDispatch } from "react-redux"; +import { Grid } from "../../../../components/grid/Grid"; +import { getHourLimitKillRequestKillhouseService } from "../../../city/services/get-hour-limit-kill-request-killhouse"; +import { hourLimitKillRequestKillhouseService } from "../../../city/services/hour-limit-kill-request-killhouse"; + +export const ProvincePolicyKillhouseHourLimit = () => { + const dispatch = useDispatch(); + const hours = Array.from({ length: 8 }, (_, i) => i + 8); + const [isChecked, setIsChecked] = useState(false); + const [selectedHour, setSelectedHour] = useState(""); + + useEffect(() => { + dispatch(getHourLimitKillRequestKillhouseService()).then((r) => { + setIsChecked(r.payload.data.active); + setSelectedHour(r.payload.data.hour); + }); + }, []); + + useEffect(() => { + if (isChecked && selectedHour) { + dispatch( + hourLimitKillRequestKillhouseService({ + hour: selectedHour, + active: isChecked, + }) + ); + } + if (!isChecked && selectedHour) { + setSelectedHour(null); + dispatch( + hourLimitKillRequestKillhouseService({ hour: 0, active: isChecked }) + ); + } + }, [selectedHour, isChecked]); + + return ( + + setIsChecked(!isChecked)} + /> + } + label="محدودیت زمان درخواست کشتار کشتارگاه" + /> + {isChecked && ( + + ساعت پایان درخواست + + + )} + + ); +}; diff --git a/src/features/province/components/province-policy-limit-access/ProvincePolicyLimitAccess.js b/src/features/province/components/province-policy-limit-access/ProvincePolicyLimitAccess.js new file mode 100644 index 0000000..c9ff755 --- /dev/null +++ b/src/features/province/components/province-policy-limit-access/ProvincePolicyLimitAccess.js @@ -0,0 +1,176 @@ +import React, { useEffect, useState } from "react"; +import Checkbox from "@mui/material/Checkbox"; +import FormControlLabel from "@mui/material/FormControlLabel"; +import { Grid } from "../../../../components/grid/Grid"; +import { useDispatch } from "react-redux"; +import { provinceGetLimitation } from "../../services/province-get-limitation"; +import { toUnderscore } from "../../../../utils/toCamelCase"; +import { provincePolicyUpdateLimitations } from "../../services/province-policy-update-limitation"; + +const ProvincePolicyLimitAccess = () => { + const dispatch = useDispatch(); + const [checkedItems, setCheckedItems] = useState(); + + useEffect(() => { + dispatch(provinceGetLimitation()).then((r) => { + setCheckedItems(r.payload.data); + }); + }, []); + + const handleChange = (event) => { + const { name, checked } = event.target; + setCheckedItems((prevCheckedItems) => { + const updatedCheckedItems = { + ...prevCheckedItems, + [name]: checked, + }; + handleSubmit(updatedCheckedItems); + return updatedCheckedItems; + }); + }; + + const handleSubmit = (updatedCheckedItems) => { + const newObject = {}; + for (const key in updatedCheckedItems) { + if (Object.prototype.hasOwnProperty.call(updatedCheckedItems, key)) { + const newKey = toUnderscore(key); + newObject[newKey] = updatedCheckedItems[key]; + } + } + dispatch(provincePolicyUpdateLimitations(newObject)); + }; + + return ( + <> + {checkedItems && ( + + + } + label="محدودیت کد قرنطینه برای بار داخل استان" + /> + + + } + label="بار خارج از استان" + /> + + } + label="محدودیت تخصیص استان به کشتارگاه" + /> + + } + label="محدودیت ایجاد بار برای کشتارگاه" + /> + + } + label="محدودیت تایید تخلیه برای دامپزشک" + /> + + } + label="محدودیت تایید تخلیه ورود اطلاعات بار" + /> + + } + label="محدودیت ورود اطلاعات بار کشتارگاه " + /> + + } + label="محدودیت ورود بار به انبار کشتارگاه" + /> + + } + label="محدودیت تخصیص کشتارگاه به مباشر یا صنف" + /> + + } + label="محدودیت انجماد برای کشتارگاه" + /> + + } + label="محدودیت فروش آزاد برای کشتارگاه" + /> + + } + label="محدودیت خرید آزاد برای کشتارگاه" + /> + + )} + + ); +}; + +export default ProvincePolicyLimitAccess; diff --git a/src/features/province/components/province-policy-manage-penalty/provincePolicyManagePenalty.js b/src/features/province/components/province-policy-manage-penalty/provincePolicyManagePenalty.js new file mode 100644 index 0000000..91f44d1 --- /dev/null +++ b/src/features/province/components/province-policy-manage-penalty/provincePolicyManagePenalty.js @@ -0,0 +1,84 @@ +import { useEffect, useState } from "react"; +import { Grid } from "../../../../components/grid/Grid"; + +import { useDispatch } from "react-redux"; + +import EditIcon from "@mui/icons-material/Edit"; + +import { IconButton } from "@mui/material"; + +import { provincePolicyGetFinePermission } from "../../services/province-policy-get-fine-permission"; +import { OPEN_MODAL } from "../../../../lib/redux/slices/appSlice"; +import { ProvincePolicyEditFine } from "../province-policy-edit-fine/ProvincePolicyEditFine"; +import ResponsiveTable from "../../../../components/responsive-table/ResponsiveTable"; + +export const ProvincePolicyManagePenalty = () => { + const dispatch = useDispatch(); + + const [data, setData] = useState(); + const [tableData, setTableData] = useState(); + + const fetchData = () => { + dispatch(provincePolicyGetFinePermission()).then((r) => { + setData(r.payload.data); + }); + }; + + useEffect(() => { + fetchData(); + }, []); + + useEffect(() => { + const d = data?.map((item, i) => { + return [ + i + 1, + item?.name, + item?.startTime && + item?.endTime && + item?.startTime !== "00:00:00" && + item?.endTime !== "00:00:00" + ? `از ${item?.startTime.slice(0, 5)} تا ${item?.endTime.slice(0, 5)}` + : "-", + + item?.fineCoefficient, + item?.fine ? "فعال" : "غیر فعال", + + { + dispatch( + OPEN_MODAL({ + title: "ویرایش جریمه", + content: ( + + ), + }) + ); + }} + > + + + , + ]; + }); + + setTableData(d); + }, [data]); + + return ( + + + + ); +}; diff --git a/src/features/province/components/province-policy-manage-weight-category/ProvincePolicyManageWeightCategory.js b/src/features/province/components/province-policy-manage-weight-category/ProvincePolicyManageWeightCategory.js new file mode 100644 index 0000000..a3d92d6 --- /dev/null +++ b/src/features/province/components/province-policy-manage-weight-category/ProvincePolicyManageWeightCategory.js @@ -0,0 +1,76 @@ +import React, { useEffect, useState } from "react"; +import { Grid } from "../../../../components/grid/Grid"; +import ResponsiveTable from "../../../../components/responsive-table/ResponsiveTable"; +import { IconButton } from "@mui/material"; +import { useDispatch } from "react-redux"; +import { OPEN_MODAL } from "../../../../lib/redux/slices/appSlice"; +import EditIcon from "@mui/icons-material/Edit"; +import { provincePolicyGetWeightCategory } from "../../services/province-policy-get-weight-category"; +import { ProvincePolicyEditWeightCategory } from "../province-policy-edit-weight-category/ProvincePolicyEditWeightCategory"; + +export const ProvincePolicyManageWeightCategory = () => { + const dispatch = useDispatch(); + + const [data, setData] = useState(); + const [tableData, setTableData] = useState(); + + const fetchData = () => { + dispatch(provincePolicyGetWeightCategory()).then((r) => { + setData(r.payload.data); + }); + }; + + useEffect(() => { + fetchData(); + }, []); + + useEffect(() => { + const d = data?.map((item, i) => { + return [ + i + 1, + item?.name, + item?.minValue, + item?.maxValue, + + { + dispatch( + OPEN_MODAL({ + title: "ویرایش دسته بندی وزنی", + content: ( + + ), + }) + ); + }} + > + + + , + ]; + }); + + setTableData(d); + }, [data]); + + return ( + + + + ); +}; diff --git a/src/features/province/components/province-policy-manage-weight-range/ProvincePolicyManageWeightRange.js b/src/features/province/components/province-policy-manage-weight-range/ProvincePolicyManageWeightRange.js new file mode 100644 index 0000000..050fd4e --- /dev/null +++ b/src/features/province/components/province-policy-manage-weight-range/ProvincePolicyManageWeightRange.js @@ -0,0 +1,228 @@ +import React, { useContext, useEffect, useState } from "react"; +import { Grid } from "../../../../components/grid/Grid"; +import ResponsiveTable from "../../../../components/responsive-table/ResponsiveTable"; +import { + Button, + IconButton, + List, + ListItemButton, + ListItemIcon, + ListItemText, + Popover, + Typography, +} from "@mui/material"; +import { useDispatch } from "react-redux"; +import { + provincePolicyDeleteWeightRange, + provincePolicyGetWeightRange, +} from "../../services/province-policy-get-weight-range"; +import { CLOSE_MODAL, OPEN_MODAL } from "../../../../lib/redux/slices/appSlice"; +import { ProvincePolicyAddWeightRange } from "../province-policy-add-weight-range/ProvincePolicyAddWeightRange"; +import EditIcon from "@mui/icons-material/Edit"; +import { AppContext } from "../../../../contexts/AppContext"; +import DeleteIcon from "@mui/icons-material/Delete"; +import TuneIcon from "@mui/icons-material/Tune"; + +export const ProvincePolicyManageWeightRange = () => { + const dispatch = useDispatch(); + + const [openNotif] = useContext(AppContext); + + const [data, setData] = useState(); + const [tableData, setTableData] = useState(); + + const fetchData = () => { + dispatch(provincePolicyGetWeightRange()).then((r) => { + setData(r.payload.data); + }); + }; + + useEffect(() => { + fetchData(); + }, []); + + useEffect(() => { + const d = data?.map((item, i) => { + return [ + i + 1, + item?.fromAge, + item?.toAge, + item?.fromWeight, + item?.toWeight, + { + dispatch( + OPEN_MODAL({ + title: "ویرایش بازه", + content: ( + + ), + }) + ); + }} + onDelete={() => { + dispatch( + OPEN_MODAL({ + title: "آیا مطمئن هستید؟", + content: ( + + + + + + + + + ), + }) + ); + }} + />, + ]; + }); + + setTableData(d); + }, [data]); + + const WeightRangeActions = ({ onEdit, onDelete }) => { + const [anchorEl, setAnchorEl] = useState(null); + const open = Boolean(anchorEl); + + const handleOpen = (event) => { + setAnchorEl(event.currentTarget); + }; + + const handleClose = () => { + setAnchorEl(null); + }; + + const handleEdit = () => { + onEdit(); + handleClose(); + }; + + const handleDelete = () => { + onDelete(); + handleClose(); + }; + + return ( + + + + + + + + + + + + ویرایش + + } + /> + + + + + + + حذف + + } + /> + + + + + ); + }; + + return ( + + + + + + ); +}; diff --git a/src/features/province/components/province-policy-market-daily-limitation/ProvincePolicyMarketDailyLimitation.js b/src/features/province/components/province-policy-market-daily-limitation/ProvincePolicyMarketDailyLimitation.js new file mode 100644 index 0000000..852c02f --- /dev/null +++ b/src/features/province/components/province-policy-market-daily-limitation/ProvincePolicyMarketDailyLimitation.js @@ -0,0 +1,158 @@ +import React, { useContext, useEffect, useState } from "react"; +import { Grid } from "../../../../components/grid/Grid"; +import { + Button, + FormControlLabel, + Radio, + TextField, + Typography, +} from "@mui/material"; +import { useFormik } from "formik"; +import { useDispatch } from "react-redux"; +import { Yup } from "../../../../lib/yup/yup"; +import { AppContext } from "../../../../contexts/AppContext"; +import { + provincePolicyEditMarketDailyLimitation, + provincePolicyGetMarketDailyLimitation, +} from "../../services/province-policy-market-daily-limitation"; +import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl"; + +export const ProvincePolicyMarketDailyLimitation = () => { + const [isActive, setIsActive] = useState(false); + const dispatch = useDispatch(); + const [openNotif] = useContext(AppContext); + + const formik = useFormik({ + initialValues: { + quantity: "", + }, + validationSchema: Yup.object({ + quantity: Yup.number() + .required("این فیلد اجباری است") + .min(1, "حداقل مقدار باید 1 باشد"), + }), + }); + + const fetchData = () => { + dispatch(provincePolicyGetMarketDailyLimitation()).then((r) => { + if (r.payload?.data) { + setIsActive(r.payload.data.active); + formik.setFieldValue("quantity", r.payload.data.quantity); + } + }); + }; + + useEffect(() => { + fetchData(); + }, []); + + useEffect(() => { + formik.validateForm(); + }, []); + + const handleSubmit = (activeStatus) => { + const registerRole = getRoleFromUrl(); + + dispatch( + provincePolicyEditMarketDailyLimitation({ + quantity: activeStatus ? parseInt(formik.values.quantity) : 0, + active: activeStatus, + register_role: registerRole, + }) + ).then((r) => { + if (r.payload?.error) { + openNotif({ + vertical: "top", + horizontal: "center", + msg: r.payload.error, + severity: "error", + }); + } else { + fetchData(); + openNotif({ + vertical: "top", + horizontal: "center", + msg: "عملیات با موفقیت انجام شد.", + severity: "success", + }); + } + }); + }; + + return ( + + + سقف کشتار پنل معاملات + + + { + setIsActive(true); + }} + /> + } + label="فعال" + /> + { + setIsActive(false); + handleSubmit(false); + }} + name="marketDailyLimit" + /> + } + label="غیر فعال" + /> + + {isActive && ( + <> + + + + + + + + + )} + + ); +}; diff --git a/src/features/province/components/province-policy-mobile-message-operations/ProvincePolicyMobileMessageOperations.js b/src/features/province/components/province-policy-mobile-message-operations/ProvincePolicyMobileMessageOperations.js new file mode 100644 index 0000000..c2ee6fc --- /dev/null +++ b/src/features/province/components/province-policy-mobile-message-operations/ProvincePolicyMobileMessageOperations.js @@ -0,0 +1,170 @@ +import { + FormControlLabel, + IconButton, + Popover, + Switch, + Tooltip, +} from "@mui/material"; +import React, { useContext, useState } from "react"; +import { useDispatch } from "react-redux"; +import TuneIcon from "@mui/icons-material/Tune"; +import EditIcon from "@mui/icons-material/Edit"; +import { Grid } from "../../../../components/grid/Grid"; +import { + provinceDeleteMovingTextService, + provinceUpdateMobileMessagesActiveTextService, +} from "../../services/province-get-mobile-messages"; +import { OPEN_MODAL } from "../../../../lib/redux/slices/appSlice"; +import { ProvincePolicyMobileMessageSubmit } from "../province-policy-mobile-message-submit/ProvincePolicyMobileMessageSubmit"; +import { AppContext } from "../../../../contexts/AppContext"; +import DeleteIcon from "@mui/icons-material/Delete"; + +export const ProvincePolicyMobileMessageOperations = ({ + item, + fetchApiData, +}) => { + const dispatch = useDispatch(); + const [openNotif] = useContext(AppContext); + + const [anchorEl, setAnchorEl] = useState(null); + + const handleClick = (event) => { + setAnchorEl(event.currentTarget); + }; + + const handleClose = () => { + setAnchorEl(null); + }; + + const open = Boolean(anchorEl); + const id = open ? "popover" : undefined; + + return ( +
    + + + + +
    + + + { + dispatch( + provinceUpdateMobileMessagesActiveTextService({ + moving_text_key: item?.key, + active: !item?.active, + }) + ).then((r) => { + if (r.payload.error) { + openNotif({ + vertical: "top", + horizontal: "center", + msg: r.payload.error, + severity: "error", + }); + } else { + openNotif({ + vertical: "top", + horizontal: "center", + msg: "عملیات با موفقیت انجام شد.", + severity: "success", + }); + fetchApiData(1); + } + }); + }} + /> + } + /> + + + { + handleClose(); + dispatch( + OPEN_MODAL({ + title: "ویرایش متن متحرک", + content: ( + + ), + }) + ); + }} + > + + + + + { + dispatch(provinceDeleteMovingTextService(item?.id)).then( + (r) => { + if (r.payload.error) { + openNotif({ + vertical: "top", + horizontal: "center", + msg: "مشکلی پیش آمده است", + severity: "error", + }); + } else { + fetchApiData(1); + + openNotif({ + vertical: "top", + horizontal: "center", + msg: "عملیات با موفقیت انجام شد.", + severity: "success", + }); + } + } + ); + }} + > + + + + +
    +
    +
    + ); +}; diff --git a/src/features/province/components/province-policy-mobile-message-submit/ProvincePolicyMobileMessageSubmit.js b/src/features/province/components/province-policy-mobile-message-submit/ProvincePolicyMobileMessageSubmit.js new file mode 100644 index 0000000..09a3af4 --- /dev/null +++ b/src/features/province/components/province-policy-mobile-message-submit/ProvincePolicyMobileMessageSubmit.js @@ -0,0 +1,121 @@ +import React, { useContext, useEffect } from "react"; +import { Button, TextField } from "@mui/material"; +import { useFormik } from "formik"; +import { AppContext } from "../../../../contexts/AppContext"; +import { useDispatch } from "react-redux"; +import { Yup } from "../../../../lib/yup/yup"; +import { Grid } from "../../../../components/grid/Grid"; +import { CLOSE_MODAL } from "../../../../lib/redux/slices/appSlice"; +import { + provinceSubmitNewMovingText, + provinceUpdateMobileMessagesActiveTextService, +} from "../../services/province-get-mobile-messages"; +export const ProvincePolicyMobileMessageSubmit = ({ + fetchApiData, + item, + isEdit, +}) => { + const [openNotif] = useContext(AppContext); + + const dispatch = useDispatch(); + const formik = useFormik({ + initialValues: { + movingText: item?.movingText ? item?.movingText : "", + }, + validationSchema: Yup.object({ + movingText: Yup.string() + .required("این فیلد اجباری است!") + .typeError("لطفا فیلد را پر کنید!"), + }), + }); + + useEffect(() => { + formik.validateForm(); + }, []); + + return ( + + + + + + + + ); +}; diff --git a/src/features/province/components/province-policy-mobile-message/ProvincePolicyMobileMessage.js b/src/features/province/components/province-policy-mobile-message/ProvincePolicyMobileMessage.js new file mode 100644 index 0000000..cc3df77 --- /dev/null +++ b/src/features/province/components/province-policy-mobile-message/ProvincePolicyMobileMessage.js @@ -0,0 +1,246 @@ +import { Button, Checkbox, TextField, Typography } from "@mui/material"; +import React, { useContext, useEffect, useState } from "react"; +import { getFaUserRole } from "../../../../utils/getFaUserRole"; +import { Grid } from "../../../../components/grid/Grid"; +import { PageTable } from "../../../../components/page-table/PageTable"; +import axios from "axios"; +import { SPACING } from "../../../../data/spacing"; +import { provinceUpdateMobileMessagesActiveService } from "../../services/province-get-mobile-messages"; +import { AppContext } from "../../../../contexts/AppContext"; +import { useDispatch } from "react-redux"; +import { OPEN_MODAL } from "../../../../lib/redux/slices/appSlice"; +import { ProvincePolicyMobileMessageSubmit } from "../province-policy-mobile-message-submit/ProvincePolicyMobileMessageSubmit"; +import { ProvincePolicyMobileMessageOperations } from "../province-policy-mobile-message-operations/ProvincePolicyMobileMessageOperations"; +import { RiSearchLine } from "react-icons/ri"; + +export const ProvincePolicyMobileMessage = () => { + const [openNotif] = useContext(AppContext); + const [data, setData] = useState([]); + const [loading, setLoading] = useState(false); + const [totalRows, setTotalRows] = useState(0); + const [perPage, setPerPage] = useState(10); + const [textValue, setTextValue] = useState(""); + const handleTextChange = (event) => { + setTextValue(event.target.value); + }; + const dispatch = useDispatch(); + const fetchApiData = async (page, textValue) => { + setLoading(true); + const response = await axios.get( + `moving-text/?search=filter&value=${textValue}&page=${page}&page_size=${perPage}` + ); + + setData(response.data.results); + setTotalRows(response.data.count); + setLoading(false); + }; + + const handlePageChange = (page) => { + fetchApiData(page, textValue); + }; + + const handlePerRowsChange = async (newPerPage, page) => { + setLoading(true); + const response = await axios.get( + `moving-text/?search=filter&value=${textValue}&page=${page}&page_size=${newPerPage}` + ); + + setData(response.data.results); + setTotalRows(response.data.count); + setPerPage(newPerPage); + + setLoading(false); + }; + + useEffect(() => { + fetchApiData(1); + }, []); + + const handleSubmit = async (event) => { + event.preventDefault(); + setLoading(true); + + try { + const response = await axios.get( + `moving-text/?search=filter&value=${textValue}` + ); + setData(response.data.results); + setTotalRows(response.data.count); + } catch (error) { + console.error("Error fetching data:", error); + } finally { + setLoading(false); + } + }; + + useEffect(() => { + fetchApiData(1); + }, []); + + const columns = [ + { + name: "ردیف", + selector: (item, i) => i + 1, + sortable: true, + wrap: true, + allowOverflow: true, + center: true, + width: "60px", + }, + { + name: "عملیات", + selector: (item) => ( + + ), + sortable: true, + wrap: true, + allowOverflow: true, + center: true, + // width: "80px", + }, + { + name: "وضعیت", + selector: (item) => (item?.active ? "فعال" : "غیر فعال"), + sortable: true, + wrap: true, + allowOverflow: true, + center: true, + // width: "80px", + }, + + { + name: "متن", + selector: (item) => item?.movingText, + sortable: true, + wrap: true, + allowOverflow: true, + center: true, + // width: "80px", + }, + ]; + + const [secondaryColumns, setSecondaryColumns] = useState([]); + + useEffect(() => { + if (data?.length) { + const d = data[0]?.roles?.map((option, index) => { + return { + name: ( + + {getFaUserRole(option?.role)} + + ), + selector: (item) => { + return ( + { + dispatch( + provinceUpdateMobileMessagesActiveService({ + moving_text_role_key: item?.roles[index]?.key, + active: !item?.roles[index]?.active, + }) + ).then((r) => { + if (r.payload.error) { + openNotif({ + vertical: "top", + horizontal: "center", + msg: r.payload.error, + severity: "error", + }); + } else { + openNotif({ + vertical: "top", + horizontal: "center", + msg: "عملیات با موفقیت انجام شد.", + severity: "success", + }); + fetchApiData(1); + } + }); + }} + /> + ); + }, + sortable: false, + wrap: true, + allowOverflow: true, + center: true, + }; + }); + setSecondaryColumns(d); + } + }, [data]); + + const tableTitle = ( + + + متن متحرک +
    + + + +
    +
    + ); + + return ( + + + + + + + ); +}; diff --git a/src/features/province/components/province-policy-province-fee/ProvincePolicyProvinceFee.js b/src/features/province/components/province-policy-province-fee/ProvincePolicyProvinceFee.js new file mode 100644 index 0000000..570f47f --- /dev/null +++ b/src/features/province/components/province-policy-province-fee/ProvincePolicyProvinceFee.js @@ -0,0 +1,78 @@ +import { Button, InputAdornment, TextField, Typography } from "@mui/material"; +import { useContext, useEffect, useState } from "react"; +import { useDispatch } from "react-redux"; +import { Grid } from "../../../../components/grid/Grid"; +import { AppContext } from "../../../../contexts/AppContext"; +import { SPACING } from "../../../../data/spacing"; +import { getPolicyProvinceFeeService } from "../../services/get-policy-province-fee"; +import { policyChangeProvinceFeeService } from "../../services/policy-change-province-fee"; + +export const ProvincePolicyProvinceFee = () => { + const dispatch = useDispatch(); + const [openNotif] = useContext(AppContext); + const [textValue, setTextValue] = useState(); + + const handleChange = (e) => { + setTextValue(e.target.value); + }; + + useEffect(() => { + dispatch(getPolicyProvinceFeeService()).then((r) => { + setTextValue(r.payload.data.provinceUnion); + }); + }, []); + + return ( + + + مبلغ تعرفه استان: + + + ﷼, + }} + /> + + + + + + ); +}; diff --git a/src/features/province/components/province-policy-slaughter-age/ProvincePolicySlaughterAge.js b/src/features/province/components/province-policy-slaughter-age/ProvincePolicySlaughterAge.js new file mode 100644 index 0000000..a4a98f9 --- /dev/null +++ b/src/features/province/components/province-policy-slaughter-age/ProvincePolicySlaughterAge.js @@ -0,0 +1,185 @@ +import React, { useContext, useEffect, useState } from "react"; +import { Grid } from "../../../../components/grid/Grid"; +import { + Button, + FormControl, + FormControlLabel, + Radio, + RadioGroup, + TextField, + Typography, +} from "@mui/material"; +import { Yup } from "../../../../lib/yup/yup"; +import { useFormik } from "formik"; +import { useDispatch } from "react-redux"; +import { AppContext } from "../../../../contexts/AppContext"; +import { getMinMaxSlaughterAgeState } from "../../services/get-min-max-age-state"; +import { provinceEditMinMaxAge } from "../../services/province-edit-min-max-age"; + +export const ProvincePolicySlaughterAge = () => { + const dispatch = useDispatch(); + const [openNotif] = useContext(AppContext); + + const [value, setValue] = useState("inactive"); + const [data, setData] = useState(); + + useEffect(() => { + dispatch(getMinMaxSlaughterAgeState()).then((r) => { + setData(r.payload.data); + if (r.payload.data?.active) { + setValue("active"); + } + }); + }, []); + + const formik = useFormik({ + initialValues: { + minAge: "", + maxAge: "", + }, + validationSchema: Yup.object({ + minAge: Yup.number().required("این فیلد اجباری است"), + maxAge: Yup.number().required("این فیلد اجباری است"), + }), + }); + + useEffect(() => { + formik.validateForm(); + }, []); + + useEffect(() => { + if (data?.minimum) { + formik.setFieldValue("minAge", data?.minimum); + formik.setFieldValue("maxAge", data?.maximum); + formik.validateForm(); + } + }, [data]); + + const handleChangeRadioButton = (event) => { + setValue(event.target.value); + }; + + return ( + + حداقل و حداکثر سن کشتار + + + } label="فعال" /> + { + dispatch( + provinceEditMinMaxAge({ + active: false, + }) + ).then((r) => { + if (r.error) { + openNotif({ + vertical: "top", + horizontal: "center", + msg: "مشکلی پیش آمده است!", + severity: "error", + }); + } else { + openNotif({ + vertical: "top", + horizontal: "center", + msg: "عملیات با موفقیت انجام شد.", + severity: "success", + }); + } + }); + }} + value="inactive" + control={} + label="غیر فعال" + /> + + + {value === "active" && ( + <> + + + + + + + + + + + + + + )} + + ); +}; diff --git a/src/features/province/components/province-policy-slaughter-drop-limit/ProvincePolicyDropLimit.js b/src/features/province/components/province-policy-slaughter-drop-limit/ProvincePolicyDropLimit.js new file mode 100644 index 0000000..a706340 --- /dev/null +++ b/src/features/province/components/province-policy-slaughter-drop-limit/ProvincePolicyDropLimit.js @@ -0,0 +1,132 @@ +import { useContext, useEffect, useState } from "react"; +import { useDispatch } from "react-redux"; +import { AppContext } from "../../../../contexts/AppContext"; +import { useFormik } from "formik"; +import { Yup } from "../../../../lib/yup/yup"; +import { Grid } from "../../../../components/grid/Grid"; +import { Button, TextField, Typography } from "@mui/material"; +import { provincePolicyGetDropLimitService } from "../../services/province-policy-drop-limit"; +import { provinceEditDropLimitedService } from "../../services/province-policy-edit-drop-limited"; + +export const ProvincePolicyDropLimit = () => { + const dispatch = useDispatch(); + const [openNotif] = useContext(AppContext); + const [data, setData] = useState(); + + useEffect(() => { + dispatch(provincePolicyGetDropLimitService()).then((r) => { + setData(r.payload.data); + }); + }, []); + + const formik = useFormik({ + initialValues: { + limitDown: "", + limitUp: "", + }, + validationSchema: Yup.object({ + limitDown: Yup.number() + .required("این فیلد اجباری است") + .min(0, "حداقل مقدار باید 0 باشد") + .max(100, "حداکثر مقدار باید 100 باشد"), + limitUp: Yup.number() + .required("این فیلد اجباری است") + .min(0, "حداقل مقدار باید 0 باشد") + .max(100, "حداکثر مقدار باید 100 باشد"), + }), + }); + + useEffect(() => { + formik.validateForm(); + }, []); + + useEffect(() => { + if (data?.killHouseLimitPercentDown) { + formik.setFieldValue("limitDown", data?.killHouseLimitPercentDown); + formik.setFieldValue("limitUp", data?.killHouseLimitPercentUp); + formik.validateForm(); + } + }, [data]); + + return ( + + حداقل و حداکثرافت برای کشتارگاه + + + + + + + + + + + + + + + + ); +}; diff --git a/src/features/province/components/province-policy-steward-in-province-Upload-image/ProvincePolicyUploadStewardInProvinceImage.js b/src/features/province/components/province-policy-steward-in-province-Upload-image/ProvincePolicyUploadStewardInProvinceImage.js new file mode 100644 index 0000000..2b4672f --- /dev/null +++ b/src/features/province/components/province-policy-steward-in-province-Upload-image/ProvincePolicyUploadStewardInProvinceImage.js @@ -0,0 +1,117 @@ +import { useContext, useEffect, useState } from "react"; +import { useDispatch } from "react-redux"; +import { AppContext } from "../../../../contexts/AppContext"; +import { + provincePolicyGEditUploadImageService, + provincePolicyGetUploadImageService, +} from "../../services/province-policy-upload-image"; +import { Grid } from "../../../../components/grid/Grid"; +import { FormControlLabel, Radio, Typography } from "@mui/material"; + +export const ProvincePolicyUploadStewardInProvinceImage = () => { + const [submitStatus, SetSubmitStatus] = useState(false); + const dispatch = useDispatch(); + const [openNotif] = useContext(AppContext); + + const fetchData = () => { + dispatch(provincePolicyGetUploadImageService()).then((r) => { + SetSubmitStatus(r.payload.data.stewardAllocation); + }); + }; + + useEffect(() => { + fetchData(); + }, []); + + return ( + + + سند توزیع داخل استان مباشر + + + { + SetSubmitStatus(true); + dispatch( + provincePolicyGEditUploadImageService({ + steward_allocation: true, + }) + ).then((r) => { + if (r.payload.error) { + openNotif({ + vertical: "top", + horizontal: "center", + msg: r.payload.error, + severity: "error", + }); + } else { + fetchData(); + openNotif({ + vertical: "top", + horizontal: "center", + msg: "عملیات با موفقیت انجام شد.", + severity: "success", + }); + } + }); + }} + /> + } + label="اجباری" + /> + { + SetSubmitStatus(false); + dispatch( + provincePolicyGEditUploadImageService({ + steward_allocation: false, + }) + ).then((r) => { + if (r.payload.error) { + openNotif({ + vertical: "top", + horizontal: "center", + msg: r.payload.error, + severity: "error", + }); + } else { + fetchData(); + openNotif({ + vertical: "top", + horizontal: "center", + msg: "عملیات با موفقیت انجام شد.", + severity: "success", + }); + } + }); + }} + /> + } + label="اختیاری" + /> + + + ); +}; diff --git a/src/features/province/components/province-policy-steward-out-province-upload-image/ProvincePolicyUploadImageStewardOutProvince.js b/src/features/province/components/province-policy-steward-out-province-upload-image/ProvincePolicyUploadImageStewardOutProvince.js new file mode 100644 index 0000000..f8c4852 --- /dev/null +++ b/src/features/province/components/province-policy-steward-out-province-upload-image/ProvincePolicyUploadImageStewardOutProvince.js @@ -0,0 +1,117 @@ +import { useContext, useEffect, useState } from "react"; +import { useDispatch } from "react-redux"; +import { AppContext } from "../../../../contexts/AppContext"; +import { + provincePolicyGEditUploadImageService, + provincePolicyGetUploadImageService, +} from "../../services/province-policy-upload-image"; +import { Grid } from "../../../../components/grid/Grid"; +import { FormControlLabel, Radio, Typography } from "@mui/material"; + +export const ProvincePolicyUploadImageStewardOutProvince = () => { + const [submitStatus, SetSubmitStatus] = useState(false); + const dispatch = useDispatch(); + const [openNotif] = useContext(AppContext); + + const fetchData = () => { + dispatch(provincePolicyGetUploadImageService()).then((r) => { + SetSubmitStatus(r.payload.data.steward_free_sale); + }); + }; + + useEffect(() => { + fetchData(); + }, []); + + return ( + + + سند توزیع خارج استان مباشر + + + { + SetSubmitStatus(true); + dispatch( + provincePolicyGEditUploadImageService({ + steward_free_sale: true, + }) + ).then((r) => { + if (r.payload.error) { + openNotif({ + vertical: "top", + horizontal: "center", + msg: r.payload.error, + severity: "error", + }); + } else { + fetchData(); + openNotif({ + vertical: "top", + horizontal: "center", + msg: "عملیات با موفقیت انجام شد.", + severity: "success", + }); + } + }); + }} + /> + } + label="اجباری" + /> + { + SetSubmitStatus(false); + dispatch( + provincePolicyGEditUploadImageService({ + steward_free_sale: false, + }) + ).then((r) => { + if (r.payload.error) { + openNotif({ + vertical: "top", + horizontal: "center", + msg: r.payload.error, + severity: "error", + }); + } else { + fetchData(); + openNotif({ + vertical: "top", + horizontal: "center", + msg: "عملیات با موفقیت انجام شد.", + severity: "success", + }); + } + }); + }} + /> + } + label="اختیاری" + /> + + + ); +}; diff --git a/src/features/province/components/province-policy-submit-wage/ProvincePolicySubmitWage.js b/src/features/province/components/province-policy-submit-wage/ProvincePolicySubmitWage.js new file mode 100644 index 0000000..53b7640 --- /dev/null +++ b/src/features/province/components/province-policy-submit-wage/ProvincePolicySubmitWage.js @@ -0,0 +1,121 @@ +import React, { useContext, useEffect } from "react"; +import { Grid } from "../../../../components/grid/Grid"; +import { Button, TextField } from "@mui/material"; +import { Yup } from "../../../../lib/yup/yup"; +import { useFormik } from "formik"; +import { AppContext } from "../../../../contexts/AppContext"; +import { useDispatch } from "react-redux"; +import { provincePolicyCreateWage } from "../../services/province-policy-create-wage"; +import { CLOSE_MODAL } from "../../../../lib/redux/slices/appSlice"; +import { provincePolicyEditShareType } from "../../services/province-policy-edit-share-type"; + +export const ProvincePolicySubmitWage = ({ + fetchData, + item, + itsEdit, + fetchDataShareTypes, +}) => { + const [openNotif] = useContext(AppContext); + const dispatch = useDispatch(); + + const formik = useFormik({ + initialValues: { + wageName: item?.name ? item?.name : "", + }, + validationSchema: Yup.object({ + wageName: Yup.string().typeError("لطفا فیلد را به درستی وارد کنید.!"), + }), + }); + + useEffect(() => { + formik.validateForm(); + }, []); + + return ( + + + + + + + + + ); +}; diff --git a/src/features/province/components/province-policy-ticket-permission/ProvincePolicyTicketPermission.js b/src/features/province/components/province-policy-ticket-permission/ProvincePolicyTicketPermission.js new file mode 100644 index 0000000..802e233 --- /dev/null +++ b/src/features/province/components/province-policy-ticket-permission/ProvincePolicyTicketPermission.js @@ -0,0 +1,140 @@ +import React, { useContext, useEffect, useState } from "react"; +import { Grid } from "../../../../components/grid/Grid"; +import ResponsiveTable from "../../../../components/responsive-table/ResponsiveTable"; +import { getRoleList } from "../../../../utils/getRoleList"; +import { useDispatch } from "react-redux"; +import { provincePolicyGetTicketPermissions } from "../../services/province-policy-get-ticket-permissions"; +import { getFaUserRole } from "../../../../utils/getFaUserRole"; +import { + FormControl, + IconButton, + InputLabel, + MenuItem, + Select, +} from "@mui/material"; +import CheckIcon from "@mui/icons-material/Check"; +import SaveIcon from "@mui/icons-material/Save"; +import { AppContext } from "../../../../contexts/AppContext"; +import { provincePolicySubmitTicketPermission } from "../../services/province-policy-submit-ticket-permission"; + +export const ProvincePolicyTicketPermission = () => { + const dispatch = useDispatch(); + + const [openNotif] = useContext(AppContext); + + const [data, setData] = useState(); + const [tableData, setTableData] = useState(); + + useEffect(() => { + dispatch(provincePolicyGetTicketPermissions()).then((r) => { + setData(r.payload.data); + }); + }, []); + + const handleChangeRoles = (event, i) => { + const { + target: { value }, + } = event; + + const updatedData = [...data]; + updatedData[i] = { + ...updatedData[i], + roles: typeof value === "string" ? value.split(",") : value, + }; + + setData(updatedData); + }; + + useEffect(() => { + const d = data?.map((item, i) => { + return [ + i + 1, + getFaUserRole(item?.role) !== "نامشخص" + ? getFaUserRole(item?.role) + : item?.role, + + + + مجوز ارسال تیکت + + + + , + { + dispatch( + provincePolicySubmitTicketPermission({ + roles: item?.roles, + role: item?.role, + }) + ).then((r) => { + if (r.payload.error) { + openNotif({ + vertical: "top", + horizontal: "center", + msg: r.payload.error, + severity: "error", + }); + return; + } else { + openNotif({ + vertical: "top", + horizontal: "center", + msg: "عملیات با موفقیت انجام شد.", + severity: "success", + }); + } + }); + }} + > + + , + ]; + }); + + setTableData(d); + }, [data]); + + return ( + + + + ); +}; diff --git a/src/features/province/components/province-policy-time-range/ProvincePolicyTimeRange.js b/src/features/province/components/province-policy-time-range/ProvincePolicyTimeRange.js new file mode 100644 index 0000000..fce4f5b --- /dev/null +++ b/src/features/province/components/province-policy-time-range/ProvincePolicyTimeRange.js @@ -0,0 +1,252 @@ +import React, { useContext, useEffect, useState } from "react"; +import { Grid } from "../../../../components/grid/Grid"; +import { provincePolicyGetTimeRagnge } from "../../services/province-policy-get-time-range"; +import { provincePolicyEditTimeRange } from "../../services/province-policy-edit-time-range"; +import { useDispatch } from "react-redux"; +import { + Button, + FormControl, + FormControlLabel, + Radio, + RadioGroup, + Typography, +} from "@mui/material"; +import TimePicker from "../../../../components/date-picker/CustomDatePicker"; +import { AppContext } from "../../../../contexts/AppContext"; + +export const ProvincePolicyTimeRange = () => { + const dispatch = useDispatch(); + const [openNotif] = useContext(AppContext); + + const [timeRange, setTimeRange] = useState([ + { + start: "01:00:00", + end: "24:00:00", + name: "poultry_request", + active: true, + }, + { start: "01:00:00", end: "24:00:00", name: "kill_request", active: false }, + { + start: "01:00:00", + end: "24:00:00", + name: "province_kill_request", + active: false, + }, + { + start: "01:00:00", + end: "24:00:00", + name: "kill_house_request", + active: false, + }, + { + start: "01:00:00", + end: "24:00:00", + name: "vet_farm_check_request", + active: false, + }, + ]); + + useEffect(() => { + dispatch(provincePolicyGetTimeRagnge()).then((r) => { + const apiTimeRange = r.payload.data.timeRange; + + setTimeRange((prevTimeRange) => + prevTimeRange.map((item) => { + const updatedItem = apiTimeRange.find( + (apiItem) => apiItem.name === item.name + ); + return updatedItem ? { ...item, ...updatedItem } : item; + }) + ); + }); + }, []); + + const getRageFaName = (item) => { + let range = "درخواست کشتار مرغدار"; + switch (item) { + case "poultry_request": + range = "درخواست کشتار مرغدار"; + break; + case "kill_request": + range = "ثبت اعلام نیاز کشتارگاه"; + break; + case "province_kill_request": + range = "تخصیص استان به کشتارگاه"; + break; + case "kill_house_request": + range = "ایجاد بار کشتارگاه"; + break; + case "vet_farm_check_request": + range = "ثبت کد قرنطینه"; + break; + default: + break; + } + return range; + }; + + return ( + + + {timeRange?.map((item, i) => ( + + + {getRageFaName(item?.name)} + + + + + + { + const updatedObjects = timeRange.map((obj, index) => + index === i + ? { ...obj, active: e.target.value === "true" } + : obj + ); + setTimeRange(updatedObjects); + + if (e.target.value === "false") { + dispatch( + provincePolicyEditTimeRange({ + time_range: updatedObjects, + }) + ).then((r) => { + if (r.payload.error) { + openNotif({ + vertical: "top", + horizontal: "center", + msg: r.payload.error, + severity: "error", + }); + } else { + openNotif({ + vertical: "top", + horizontal: "center", + msg: "عملیات با موفقیت انجام شد.", + severity: "success", + }); + } + }); + } + }} + row + > + } + label="فعال" + /> + } + label="غیر فعال" + /> + + + + {timeRange[i].active === true && ( + + + { + const objects = timeRange; + objects[i].start = newTime; + setTimeRange(objects); + }} + label="از" + /> + + + { + const objects = timeRange; + objects[i].end = newTime; + setTimeRange(objects); + }} + label="تا" + /> + + + )} + + {timeRange[i].active === true && ( + + + + )} + + + ))} + + + ); +}; diff --git a/src/features/province/components/province-policy-trade-time-range/ProvincePolicyTradeTimeRange.js b/src/features/province/components/province-policy-trade-time-range/ProvincePolicyTradeTimeRange.js new file mode 100644 index 0000000..078515f --- /dev/null +++ b/src/features/province/components/province-policy-trade-time-range/ProvincePolicyTradeTimeRange.js @@ -0,0 +1,171 @@ +import React, { useContext, useEffect, useState } from "react"; +import { Grid } from "../../../../components/grid/Grid"; +import { useDispatch } from "react-redux"; +import { + Button, + FormControl, + FormControlLabel, + Radio, + RadioGroup, + Typography, +} from "@mui/material"; +import TimePicker from "../../../../components/date-picker/CustomDatePicker"; +import { AppContext } from "../../../../contexts/AppContext"; +import { + provincePolicyEditTradeTimeRange, + provincePolicyGetTradeTimeRagnge, +} from "../../services/province-policy-edit-trade-time-range"; + +const DEFAULT_RANGE = { + start_time: "01:00:00", + end_time: "24:00:00", + allow: false, +}; + +export const ProvincePolicyTradeTimeRange = () => { + const dispatch = useDispatch(); + const [openNotif] = useContext(AppContext); + const [range, setRange] = useState(DEFAULT_RANGE); + + useEffect(() => { + dispatch(provincePolicyGetTradeTimeRagnge()).then((r) => { + const d = r.payload.data; + setRange({ + start_time: d.startTime, + end_time: d.endTime, + allow: d.allow, + }); + }); + }, [dispatch]); + + const handleActiveChange = (e) => { + const nextActive = e.target.value === "true"; + const nextRange = { ...range, allow: nextActive }; + setRange(nextRange); + + if (!nextActive) { + dispatch(provincePolicyEditTradeTimeRange({ allow: false })).then((r) => { + if (r.payload?.error) { + openNotif({ + vertical: "top", + horizontal: "center", + msg: r.payload.error, + severity: "error", + }); + } else { + openNotif({ + vertical: "top", + horizontal: "center", + msg: "عملیات با موفقیت انجام شد.", + severity: "success", + }); + } + }); + } + }; + + const handleSave = () => { + dispatch(provincePolicyEditTradeTimeRange(range)).then((r) => { + if (r.payload?.error) { + openNotif({ + vertical: "top", + horizontal: "center", + msg: r.payload.error, + severity: "error", + }); + } else { + openNotif({ + vertical: "top", + horizontal: "center", + msg: "عملیات با موفقیت انجام شد.", + severity: "success", + }); + } + }); + }; + + return ( + + + بازه نمایش معاملات + + + + + + + } label="فعال" /> + } + label="غیر فعال" + /> + + + + + {range.allow && ( + + + + setRange((prev) => ({ ...prev, start_time: newTime })) + } + label="از" + /> + + + + setRange((prev) => ({ ...prev, end_time: newTime })) + } + label="تا" + /> + + + )} + + {range.allow && ( + + + + )} + + + ); +}; diff --git a/src/features/province/components/province-policy-upload-image_slaughter_in_province/ProvincePolicyUploadSlaughterInProvinceImage.js b/src/features/province/components/province-policy-upload-image_slaughter_in_province/ProvincePolicyUploadSlaughterInProvinceImage.js new file mode 100644 index 0000000..10c196a --- /dev/null +++ b/src/features/province/components/province-policy-upload-image_slaughter_in_province/ProvincePolicyUploadSlaughterInProvinceImage.js @@ -0,0 +1,118 @@ +import React, { useContext, useEffect, useState } from "react"; +import { Grid } from "../../../../components/grid/Grid"; +import { FormControlLabel, Radio, Typography } from "@mui/material"; +import { useDispatch } from "react-redux"; +import { AppContext } from "../../../../contexts/AppContext"; + +import { + provincePolicyGEditUploadImageService, + provincePolicyGetUploadImageService, +} from "../../services/province-policy-upload-image"; + +export const ProvincePolicyUploadSlaughterInProvinceImage = () => { + const [submitStatus, SetSubmitStatus] = useState(false); + const dispatch = useDispatch(); + const [openNotif] = useContext(AppContext); + + const fetchData = () => { + dispatch(provincePolicyGetUploadImageService()).then((r) => { + SetSubmitStatus(r.payload.data.killHouseAllocation); + }); + }; + + useEffect(() => { + fetchData(); + }, []); + + return ( + + + سند توزیع داخل استان کشتارگاه + + + { + SetSubmitStatus(true); + dispatch( + provincePolicyGEditUploadImageService({ + kill_house_allocation: true, + }) + ).then((r) => { + if (r.payload.error) { + openNotif({ + vertical: "top", + horizontal: "center", + msg: r.payload.error, + severity: "error", + }); + } else { + fetchData(); + openNotif({ + vertical: "top", + horizontal: "center", + msg: "عملیات با موفقیت انجام شد.", + severity: "success", + }); + } + }); + }} + /> + } + label="اجباری" + /> + { + SetSubmitStatus(false); + dispatch( + provincePolicyGEditUploadImageService({ + kill_house_allocation: false, + }) + ).then((r) => { + if (r.payload.error) { + openNotif({ + vertical: "top", + horizontal: "center", + msg: r.payload.error, + severity: "error", + }); + } else { + fetchData(); + openNotif({ + vertical: "top", + horizontal: "center", + msg: "عملیات با موفقیت انجام شد.", + severity: "success", + }); + } + }); + }} + /> + } + label="اختیاری" + /> + + + ); +}; diff --git a/src/features/province/components/province-policy-wage-fractions/ProvincePolicyWageFractions.js b/src/features/province/components/province-policy-wage-fractions/ProvincePolicyWageFractions.js new file mode 100644 index 0000000..9ee33d6 --- /dev/null +++ b/src/features/province/components/province-policy-wage-fractions/ProvincePolicyWageFractions.js @@ -0,0 +1,175 @@ +import React, { useContext, useEffect, useState } from "react"; +import { useFormik } from "formik"; +import * as Yup from "yup"; +import { TextField, Button, Grid, Typography } from "@mui/material"; +import { useDispatch } from "react-redux"; +import { provincePolicyGetPaymentFractions } from "../../services/province-policy-get-payment-fractions"; +import { provincePolicyEditPaymentFractions } from "../../services/province-policy-edit-payment-fractions"; +import { AppContext } from "../../../../contexts/AppContext"; + +const ProvincePolicyWageFractions = () => { + const dispatch = useDispatch(); + const [openNotif] = useContext(AppContext); + const [percentage, setPercentages] = useState(); + const formik = useFormik({ + initialValues: { + website: "", + union: "", + guilds: "", + other: "", + }, + validationSchema: Yup.object({ + website: Yup.number() + .required("این فیلد اجباری است!") + .min(0, "درصدی بیش از 0 وارد کنید!"), + union: Yup.number() + .required("این فیلد اجباری است!") + .min(0, "درصدی بیش از 0 وارد کنید!"), + guilds: Yup.number() + .required("این فیلد اجباری است!") + .min(0, "درصدی بیش از 0 وارد کنید!"), + other: Yup.number() + .required("این فیلد اجباری است!") + .min(0, "درصدی بیش از 0 وارد کنید!"), + }), + onSubmit: (values) => { + dispatch( + provincePolicyEditPaymentFractions({ + company: values.website, + union: values.union, + guilds: values.guilds, + other: values.other, + }) + ).then((r) => { + if (r.payload.error) { + openNotif({ + vertical: "top", + horizontal: "center", + msg: r.error, + severity: "error", + }); + } else { + openNotif({ + vertical: "top", + horizontal: "center", + msg: "عملیات با موفقیت انجام شد.", + severity: "success", + }); + } + }); + }, + }); + + useEffect(() => { + formik.validateForm(); + }, []); + + useEffect(() => { + dispatch(provincePolicyGetPaymentFractions()).then((r) => { + setPercentages(r.payload.data); + }); + }, []); + + useEffect(() => { + if (percentage?.company || percentage?.guilds || percentage?.union) { + formik.setFieldValue("website", percentage.company); + formik.setFieldValue("union", percentage.union); + formik.setFieldValue("guilds", percentage.guilds); + formik.setFieldValue("other", percentage.other); + } + }, [percentage]); + + return ( +
    + + + + سهم بندی کارمزدها + + + + + + + + + + + + + + + + + مجموع:{" "} + {Number(formik.values.guilds) + + Number(formik.values.union) + + Number(formik.values.website) + + Number(formik.values.other)}{" "} + درصد + + + + + + +
    + ); +}; + +export default ProvincePolicyWageFractions; diff --git a/src/features/province/components/province-policy-wage-setup-killhouses/ProvincePolicyWagesSetupKillhouses.js b/src/features/province/components/province-policy-wage-setup-killhouses/ProvincePolicyWagesSetupKillhouses.js new file mode 100644 index 0000000..1afa4f8 --- /dev/null +++ b/src/features/province/components/province-policy-wage-setup-killhouses/ProvincePolicyWagesSetupKillhouses.js @@ -0,0 +1,162 @@ +import React, { useContext, useEffect, useState } from "react"; +import { Grid } from "../../../../components/grid/Grid"; +import { useDispatch } from "react-redux"; +import { provincePolicyWageSetupGetKillhouses } from "../../services/province-policy-wage-setup-get-killhouses"; +import { IconButton, TextField } from "@mui/material"; +import ResponsiveTable from "../../../../components/responsive-table/ResponsiveTable"; +import { provincePolicyWagesEditKillhouse } from "../../services/province-policy-wages-edit-killhouse"; +import SaveIcon from "@mui/icons-material/Save"; +import { AppContext } from "../../../../contexts/AppContext"; +// import ResponsiveTable from "../../../../components/responsive-table/ResponsiveTable"; + +export const ProvincePolicyWagesSetupKillhouses = () => { + const [openNotif] = useContext(AppContext); + + const dispatch = useDispatch(); + const [data, setData] = useState(); + const [tableData, setTableData] = useState(); + + const updateTable = () => { + dispatch(provincePolicyWageSetupGetKillhouses()).then((r) => { + setData(r.payload.data); + }); + }; + + useEffect(() => { + updateTable(); + }, []); + + const handleFormCheck = (item) => { + if ( + parseInt(item?.companyGatewayPercent) + + parseInt(item.unionGatewayPercent) + + parseInt(item.guildsGatewayPercent) + + parseInt(item.otherGatewayPercent) > + 100 + ) { + return true; + } else { + return false; + } + }; + + useEffect(() => { + const d = data?.map((item, i) => { + return [ + i + 1, + item?.name, + item?.killHouseOperator?.user?.mobile, + handleCompanyChange(event, i)} + size="small" + />, + handleUnionChange(event, i)} + size="small" + />, + handleGuildChange(event, i)} + size="small" + />, + handleOtherChange(event, i)} + size="small" + />, + { + dispatch( + provincePolicyWagesEditKillhouse({ + kill_house_key: item?.key, + company_gateway_percent: parseInt(item?.companyGatewayPercent), + union_gateway_percent: parseInt(item.unionGatewayPercent), + guilds_gateway_percent: parseInt(item.guildsGatewayPercent), + other_gateway_percent: parseInt(item.otherGatewayPercent), + }) + ).then((r) => { + if (r.payload.error) { + openNotif({ + vertical: "top", + horizontal: "center", + msg: r.payload.error, + severity: "error", + }); + } else { + updateTable(); + openNotif({ + vertical: "top", + horizontal: "center", + msg: "عملیات با موفقیت انجام شد.", + severity: "success", + }); + } + }); + }} + > + + , + ]; + }); + + setTableData(d); + }, [data]); + + const handleCompanyChange = (event, rowIndex) => { + const newData = [...data]; + newData[rowIndex].companyGatewayPercent = Number(event.target.value); + setData(newData); + }; + const handleUnionChange = (event, rowIndex) => { + const newData = [...data]; + newData[rowIndex].unionGatewayPercent = Number(event.target.value); + setData(newData); + }; + const handleGuildChange = (event, rowIndex) => { + const newData = [...data]; + newData[rowIndex].guildsGatewayPercent = Number(event.target.value); + setData(newData); + }; + const handleOtherChange = (event, rowIndex) => { + const newData = [...data]; + newData[rowIndex].otherGatewayPercent = Number(event.target.value); + setData(newData); + }; + + return ( + + + + ); +}; diff --git a/src/features/province/components/province-policy-wage-setup/ProvincePolicyWagesSetup.js b/src/features/province/components/province-policy-wage-setup/ProvincePolicyWagesSetup.js new file mode 100644 index 0000000..762f0f8 --- /dev/null +++ b/src/features/province/components/province-policy-wage-setup/ProvincePolicyWagesSetup.js @@ -0,0 +1,282 @@ +import React, { useContext, useEffect, useState } from "react"; +import { useDispatch } from "react-redux"; +import { provincePolicyGetWageFractions } from "../../services/province-policy-get-wage-fractions"; +import { Grid } from "../../../../components/grid/Grid"; +import { + Accordion, + AccordionDetails, + AccordionSummary, + Button, + Checkbox, + IconButton, + InputAdornment, + Tab, + Tabs, + TextField, +} from "@mui/material"; +import { OPEN_MODAL } from "../../../../lib/redux/slices/appSlice"; +import { ProvincePolicySubmitWage } from "../province-policy-submit-wage/ProvincePolicySubmitWage"; +import { provincePolicyEditWage } from "../../services/province-policy-edit-wage"; +import { AppContext } from "../../../../contexts/AppContext"; +import { provincePolicyGetShareType } from "../../services/province-policy-get-wages"; +import EditIcon from "@mui/icons-material/Edit"; +import ExpandMoreIcon from "@mui/icons-material/ExpandMore"; +import ResponsiveTable from "../../../../components/responsive-table/ResponsiveTable"; +import { ProvincePolicyWagesSetupKillhouses } from "../province-policy-wage-setup-killhouses/ProvincePolicyWagesSetupKillhouses"; +import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl"; +import SaveIcon from "@mui/icons-material/Save"; + +const ProvincePolicyWagesSetup = () => { + const dispatch = useDispatch(); + const [data, setData] = useState(); + const [shareTypes, setShareTypes] = useState(); + const [dataShareTypes, setDataShareTypes] = useState(); + const [wages, setWages] = useState(); + const [openNotif] = useContext(AppContext); + + const [activeTab, setActiveTab] = useState(0); + + const handleTabChange = (event, newValue) => { + setActiveTab(newValue); + }; + + const fetchData = () => { + dispatch(provincePolicyGetWageFractions()).then((r) => { + setData(r.payload.data); + }); + }; + + const fetchDataShareTypes = () => { + dispatch(provincePolicyGetShareType()).then((r) => { + setDataShareTypes(r.payload.data); + }); + }; + + useEffect(() => { + if (activeTab === 0) { + fetchData(); + fetchDataShareTypes(); + } + }, [dispatch, activeTab]); + + useEffect(() => { + const d = data?.map((item, i) => { + return [ + i + 1, + item.name, + handleStatusChange(event, i, item)} + inputProps={{ "aria-label": "controlled" }} + />, + handleAmountChange(event, i)} + size="small" + InputProps={{ + endAdornment: ریال, + }} + />, + + {item?.percentages?.map((percentItem, j) => ( + handlePercentageChange(event, i, j)} + size="small" + /> + ))} + , + handleEditClick(item)} + > + + , + ]; + }); + + setWages(d); + + const s = dataShareTypes?.map((item, i) => { + return [ + i + 1, + item?.name, + { + dispatch( + OPEN_MODAL({ + title: "ویرایش نقش", + content: ( + + ), + }) + ); + }} + > + + , + ]; + }); + + setShareTypes(s); + }, [data, dataShareTypes]); + + const handlePercentageChange = (event, rowIndex, percentIndex) => { + const newData = [...data]; + newData[rowIndex].percentages[percentIndex].percent = Number( + event.target.value + ); + setData(newData); + }; + + const handleAmountChange = (event, rowIndex) => { + const newData = [...data]; + newData[rowIndex].amount = Number(event.target.value); + setData(newData); + }; + const handleStatusChange = (event, rowIndex, item) => { + const newData = [...data]; + newData[rowIndex].status = !newData[rowIndex].status; + setData(newData, handleEditClick(item)); + }; + + const handleValidationCheck = (index) => { + if (data[index].percentages.length) { + let sum = 0; + data[index].percentages.forEach((percentItem) => { + sum += percentItem.percent; + }); + + if (sum !== 100) { + return true; + } else { + return false; + } + } + }; + + const handleEditClick = (item) => { + dispatch(provincePolicyEditWage(item)).then((r) => { + fetchData(); + if (r.payload.error) { + openNotif({ + vertical: "top", + horizontal: "center", + msg: r.payload.error, + severity: "error", + }); + } else { + openNotif({ + vertical: "top", + horizontal: "center", + msg: "عملیات با موفقیت انجام شد.", + severity: "success", + }); + } + }); + }; + + return ( + + {getRoleFromUrl() === "AdminX" && ( + + + + + )} + {activeTab === 0 && ( + <> + + + + + + } + aria-controls="panel1-content" + id="panel1-header" + > + سهامداران + + + + + + + + + + + )} + + {activeTab === 1 && } + + ); +}; + +export default ProvincePolicyWagesSetup; diff --git a/src/features/province/components/province-poultry-request-enter-confirmation-code/ProvincePoultryRequestEnterConfirmationCode.js b/src/features/province/components/province-poultry-request-enter-confirmation-code/ProvincePoultryRequestEnterConfirmationCode.js new file mode 100644 index 0000000..b030337 --- /dev/null +++ b/src/features/province/components/province-poultry-request-enter-confirmation-code/ProvincePoultryRequestEnterConfirmationCode.js @@ -0,0 +1,102 @@ +import React, { useContext, useEffect } from "react"; +import { Grid, TextField, Button } from "@mui/material"; +import { useFormik } from "formik"; +import * as yup from "yup"; +import { useDispatch } from "react-redux"; +import { provincePoultryRequestEnterConfirmationCodeService } from "../../services/province-poultry-request-enter-confirmation-code"; +import { AppContext } from "../../../../contexts/AppContext"; +import { CLOSE_MODAL } from "../../../../lib/redux/slices/appSlice"; + +export const ProvincePoultryRequestEnterConfirmationCode = ({ + updateTable, + item, +}) => { + const [openNotif] = useContext(AppContext); + const dispatch = useDispatch(); + const validationSchema = yup.object({ + verificationCode: yup + .string() + .required("کد احراز الزامی است") + .matches(/^\d+$/, "کد احراز باید عددی باشد") + .length(5, "کد احراز باید 5 رقم باشد"), + }); + + const formik = useFormik({ + initialValues: { + verificationCode: "", + }, + validationSchema: validationSchema, + onSubmit: (values) => { + dispatch( + provincePoultryRequestEnterConfirmationCodeService({ + poultry_request_key: item?.key, + confirmation_code: values?.verificationCode, + }) + ).then((r) => { + updateTable(); + if (r.payload.error) { + openNotif({ + vertical: "top", + horizontal: "center", + msg: r.payload.error, + severity: "error", + }); + } else { + updateTable(); + openNotif({ + vertical: "top", + horizontal: "center", + msg: "عملیات با موفقیت انجام شد.", + severity: "success", + }); + dispatch(CLOSE_MODAL()); + } + }); + }, + }); + + useEffect(() => { + formik.validateForm(); + }, [dispatch]); + + return ( + + + + + + + + + ); +}; diff --git a/src/features/province/components/province-poultry-science-experts-add-poultry/ProvincePoultryScienceExpertsAddPoultry.js b/src/features/province/components/province-poultry-science-experts-add-poultry/ProvincePoultryScienceExpertsAddPoultry.js new file mode 100644 index 0000000..cee1a2d --- /dev/null +++ b/src/features/province/components/province-poultry-science-experts-add-poultry/ProvincePoultryScienceExpertsAddPoultry.js @@ -0,0 +1,96 @@ +import React, { useContext, useState } from "react"; +import { Grid } from "../../../../components/grid/Grid"; +import { Autocomplete, Button, TextField } from "@mui/material"; +import { useDispatch } from "react-redux"; +import { provincePoultryScienceExpertsEditPoultryService } from "../../services/province-poultry-science-experts-add-poultry-service"; +import { AppContext } from "../../../../contexts/AppContext"; +import { CLOSE_MODAL } from "../../../../lib/redux/slices/appSlice"; + +export const ProvincePoultryScienceExpertsAddPoultry = ({ + item, + updateTable, + poultryExperts, +}) => { + const [poultryId, setPoultryId] = useState(); + const dispatch = useDispatch(); + const [openNotif] = useContext(AppContext); + + const poultryExpertOptions = poultryExperts + ? poultryExperts.map((i) => ({ + id: i.id, + label: `${i.unitName || "-"} (${i.user?.fullname || "-"} - ${ + i.user?.mobile || "-" + })`, + })) + : []; + + const poultryItemOptions = item?.poultry + ? item.poultry.map((poultry) => ({ + id: poultry.id, + label: `${poultry.unitName || "-"} (${ + poultry.user?.fullname || "-" + } - ${poultry.user?.mobile || "-"})`, + })) + : []; + + const allOptions = [ + ...poultryItemOptions, + ...poultryExpertOptions.filter( + (expert) => !poultryItemOptions.some((item) => item.id === expert.id) + ), + ]; + + const defaultSelectedItems = poultryItemOptions; + + const handleSubmit = () => { + dispatch( + provincePoultryScienceExpertsEditPoultryService({ + poultry: poultryId, + poultry_science_id: item.id, + }) + ).then((r) => { + if (r.payload.error) { + openNotif({ + vertical: "top", + horizontal: "center", + msg: r.payload.error, + severity: "error", + }); + } else { + updateTable(); + dispatch(CLOSE_MODAL()); + openNotif({ + vertical: "top", + horizontal: "center", + msg: "عملیات با موفقیت انجام شد.", + severity: "success", + }); + } + }); + }; + + return ( + + + option.label} + isOptionEqualToValue={(option, value) => option.id === value.id} + onChange={(e, value) => { + setPoultryId(value.map((opt) => opt.id)); + }} + renderInput={(params) => ( + + )} + /> + + + + ); +}; diff --git a/src/features/province/components/province-poultry-science-experts/ProvincePoultryScienceExperts.js b/src/features/province/components/province-poultry-science-experts/ProvincePoultryScienceExperts.js new file mode 100644 index 0000000..3a9b956 --- /dev/null +++ b/src/features/province/components/province-poultry-science-experts/ProvincePoultryScienceExperts.js @@ -0,0 +1,196 @@ +import React, { useContext, useEffect, useState } from "react"; +import { + Button, + IconButton, + TextField, + Tooltip, + Typography, +} from "@mui/material"; +import moment from "moment"; +import { useDispatch } from "react-redux"; +import axios from "axios"; +import { RiSearchLine } from "react-icons/ri"; +import ResponsiveTable from "../../../../components/responsive-table/ResponsiveTable"; +import { Grid } from "../../../../components/grid/Grid"; +import { + LOADING_END, + LOADING_START, + OPEN_MODAL, +} from "../../../../lib/redux/slices/appSlice"; +import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl"; +import { AppContext } from "../../../../contexts/AppContext"; +import AddIcon from "@mui/icons-material/Add"; +import { ProvincePoultryScienceExpertsAddPoultry } from "../province-poultry-science-experts-add-poultry/ProvincePoultryScienceExpertsAddPoultry"; +import { provincePoultryScienceExpertsAllPoultryService } from "../../services/province-poultry-science-experts-add-poultry-service"; + +export const ProvincePoultryScienceExperts = () => { + const [, , , setSelectedDate1, , setSelectedDate2] = useContext(AppContext); + const dispatch = useDispatch(); + useEffect(() => { + const currentDate = moment(new Date()).format("YYYY-MM-DD"); + setSelectedDate1(currentDate); + setSelectedDate2(currentDate); + }, []); + + const handleTextChange = (event) => { + setTextValue(event.target.value); + }; + + const [data, setData] = useState([]); + const [poultryExperts, setPoultryExperts] = useState([]); + const [totalRows, setTotalRows] = useState(0); + const [perPage, setPerPage] = useState(10); + const [textValue, setTextValue] = useState(""); + const [page, setPage] = useState(1); + const [tableData, setTableData] = useState([]); + + const fetchApiData = async (page) => { + let response; + dispatch(LOADING_START()); + response = await axios.get( + `poultry_science/?search=filter&value=${textValue}&role=${getRoleFromUrl()}&page=${page}&page_size=${perPage}` + ); + dispatch(LOADING_END()); + setData(response.data.results); + setTotalRows(response.data.count); + }; + + const handlePageChange = (page) => { + fetchApiData(page); + setPage(page); + }; + + const handlePerRowsChange = (perRows) => { + setPerPage(perRows); + setPage(1); + }; + + const getExperts = () => { + dispatch(provincePoultryScienceExpertsAllPoultryService()).then((r) => { + setPoultryExperts(r.payload.data); + }); + }; + + const updateTable = () => { + getExperts(); + fetchApiData(page !== 0 ? page : 1); + }; + + useEffect(() => { + updateTable(); + }, [dispatch]); + + useEffect(() => { + const d = data?.map((item, i) => { + return [ + page === 1 ? i + 1 : i + perPage * (page - 1) + 1, + item?.user?.fullname, + item?.user?.mobile, + + {item?.poultry?.length + ? item?.poultry + ?.map( + (opt, idx) => + `${opt.unitName} (${opt.user?.fullname} - ${opt.user?.mobile})` + ) + ?.join(" - ") + : "-"} + , + + { + dispatch( + OPEN_MODAL({ + title: "افزودن مرغدار زیرمجموعه", + content: ( + + ), + }) + ); + }} + > + + + , + ]; + }); + + setTableData(d); + }, [data]); + + useEffect(() => { + fetchApiData(1); + }, [dispatch, perPage]); + + const handleSubmit = async (event) => { + event.preventDefault(); + dispatch(LOADING_START()); + + try { + const response = await axios.get( + `poultry_science/?role=${getRoleFromUrl()}&search=filter&value=${textValue}&page=${1}&page_size=${perPage}` + ); + setData(response.data.results); + setTotalRows(response.data.count); + dispatch(LOADING_END()); + } catch (error) { + console.error("Error fetching data:", error); + } + }; + + return ( + + + +
    + + + +
    +
    + + +
    + ); +}; diff --git a/src/features/province/components/province-pricing-operations/ProvincePricingOperations.js b/src/features/province/components/province-pricing-operations/ProvincePricingOperations.js new file mode 100644 index 0000000..5c89076 --- /dev/null +++ b/src/features/province/components/province-pricing-operations/ProvincePricingOperations.js @@ -0,0 +1,28 @@ +import { Grid } from "../../../../components/grid/Grid"; +import { SPACING } from "../../../../data/spacing"; +import { NavLink } from "../../../../components/nav-link/NavLink"; +import { useLocation } from "react-router-dom"; +import { Button } from "@mui/material"; +import { ROUTE_PROVINCE_PRICING } from "../../../../routes/routes"; + +export const ProvincePricingOperations = () => { + const { pathname } = useLocation(); + + return ( + + + + + + ); +}; diff --git a/src/features/province/components/province-pricing/ProvincePricing.js b/src/features/province/components/province-pricing/ProvincePricing.js new file mode 100644 index 0000000..7cec9a4 --- /dev/null +++ b/src/features/province/components/province-pricing/ProvincePricing.js @@ -0,0 +1,194 @@ +import { useEffect, useState } from "react"; +import { useDispatch } from "react-redux"; +import { + DRAWER, + LOADING_END, + LOADING_START, +} from "../../../../lib/redux/slices/appSlice"; +import axios from "axios"; +import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl"; +import { formatJustDate } from "../../../../utils/formatTime"; +import { Grid } from "../../../../components/grid/Grid"; +import { Button } from "@mui/material"; +import { SPACING } from "../../../../data/spacing"; +import { ProvinceSubmitPricing } from "../province-submit-pricing/ProvinceSubmitPricing"; +import CustomCard from "../../../../components/custom-card/CustomCard"; +import ResponsiveTable from "../../../../components/responsive-table/ResponsiveTable"; +import { ProvincePriceEdit } from "../province-edit-price/ProvincePriceEdit"; + +export const ProvincePricing = () => { + const dispatch = useDispatch(); + + const [data, setData] = useState([]); + const [dataTable, setDataTable] = useState([]); + const [totalRows, setTotalRows] = useState(0); + const [perPage, setPerPage] = useState(10); + const [page, setPage] = useState(1); + + const fetchApiData = async (page) => { + try { + dispatch(LOADING_START()); + const response = await axios.get( + `chicken-commission-prices/?role=${getRoleFromUrl()}&page=${page}&page_size=${perPage}` + ); + dispatch(LOADING_END()); + setData(response.data.results); + setTotalRows(response.data.count); + } catch (error) { + console.error("Error fetching pricing data:", error); + dispatch(LOADING_END()); + } + }; + + const handlePageChange = (page) => { + fetchApiData(page); + setPage(page); + }; + + const handlePerRowsChange = (perRows) => { + setPerPage(perRows); + setPage(1); + }; + + const updateTable = () => { + fetchApiData(page !== 0 ? page : 1); + }; + + useEffect(() => { + fetchApiData(1); + }, [dispatch, perPage]); + + useEffect(() => { + const d = data?.map((item, i) => [ + i + 1, + formatJustDate(item?.date), + item?.chickenAveragePrice?.toLocaleString() + " ﷼", + item?.killHousePrice?.toLocaleString() + " ﷼", + item?.wholesalerPrice?.toLocaleString() + " ﷼", + item?.retailerPrice?.toLocaleString() + " ﷼", + item?.priceInfo?.killHousePrice?.toLocaleString() + " ﷼", + item?.priceInfo?.wholesalePrice?.toLocaleString() + " ﷼", + item?.priceInfo?.retailPrice?.toLocaleString() + " ﷼", + , + ]); + + setDataTable(d); + }, [data]); + + const role = getRoleFromUrl(); + + const renderPriceCards = () => { + if (!data || data.length === 0) return null; + + const latestData = data[0]; + + const priceCards = [ + { + title: "قیمت مرغ زنده", + value: latestData?.chickenAveragePrice?.toLocaleString() + " ریال", + date: formatJustDate(latestData?.createDate), + }, + { + title: "قیمت درب کشتارگاه", + value: + latestData?.priceInfo?.killHousePrice?.toLocaleString() + " ریال", + date: formatJustDate(latestData?.createDate), + }, + { + title: "قیمت عمده فروشی", + value: + latestData?.priceInfo?.wholesalePrice?.toLocaleString() + " ریال", + date: formatJustDate(latestData?.createDate), + }, + { + title: "قیمت خرده فروشی", + value: latestData?.priceInfo?.retailPrice?.toLocaleString() + " ریال", + date: formatJustDate(latestData?.createDate), + }, + ]; + + return ( + + {priceCards.map((card, index) => ( + + + + ))} + + ); + }; + + return ( + <> + + {(role === "ProvinceFinancial" || role === "ProvinceOperator") && ( + + + + + + )} + + + {/* نمایش کارت‌های قیمت */} + {renderPriceCards()} + + + + + + ); +}; diff --git a/src/features/province/components/province-profile/ProvinceProfile.js b/src/features/province/components/province-profile/ProvinceProfile.js new file mode 100644 index 0000000..cbcdee6 --- /dev/null +++ b/src/features/province/components/province-profile/ProvinceProfile.js @@ -0,0 +1,59 @@ +import { Box } from "@mui/system"; +import { useEffect } from "react"; +import { useDispatch, useSelector } from "react-redux"; +import { Grid } from "../../../../components/grid/Grid"; +import { SimpleTable } from "../../../../components/simple-table/SimpleTable"; +import { SPACING } from "../../../../data/spacing"; +import { + LOADING_END, + LOADING_START, +} from "../../../../lib/redux/slices/appSlice"; +// import { ChangeCardInfo } from "../../../authentication/components/change-card-info/ChangeCardInfo"; +import { provinceGetProfile } from "../../services/province-get-profile"; + +export const ProvinceProfile = () => { + const dispatch = useDispatch(); + const { profile } = useSelector((state) => state.provinceSlice); + + useEffect(() => { + dispatch(LOADING_START()); + dispatch(provinceGetProfile()).then((r) => { + dispatch(LOADING_END()); + }); + }, []); + + return ( + + + + + <> + + + + {/* + + */} + + + + + + ); +}; diff --git a/src/features/province/components/province-quarantine-invoice/ProvinceQuarantineInvoice.js b/src/features/province/components/province-quarantine-invoice/ProvinceQuarantineInvoice.js new file mode 100644 index 0000000..14cef34 --- /dev/null +++ b/src/features/province/components/province-quarantine-invoice/ProvinceQuarantineInvoice.js @@ -0,0 +1,356 @@ +import React, { forwardRef } from "react"; +import logo from "../../../../assets/images/ChickenLogo.png"; +import { PropTypes } from "prop-types"; +import { formatJustDate } from "../../../../utils/formatTime"; +import { useCeoName } from "../../../../utils/getCeoName"; +import { useSystemName } from "../../../../utils/getSystemName"; + +const styles = { + page: { + width: "210mm", + margin: "0 auto", + display: "flex", + flexDirection: "column", + position: "relative", + direction: "rtl", + fontFamily: "nazanin", + fontWeight: "bold", + }, + container: { + width: "95%", + alignSelf: "center", + pageBreakInside: "avoid", + }, + p: { + fontFamily: "nazanin", + fontWeight: "bold", + pAlign: "justify", + }, + span: { + fontFamily: "nazanin", + fontWeight: "bold", + pAlign: "justify", + }, + invoiceTable: { + width: "100%", + borderCollapse: "collapse", + alignSelf: "center", + }, + tableCell: { + border: "1px solid #000", + pAlign: "left", + textAlign: "center", + fontSize: 11, + }, + tableCellMobile: { + border: "1px solid #000", + pAlign: "left", + textAlign: "center", + fontSize: 10, + }, + tableInnerCell: { + border: "1px solid #000", + pAlign: "left", + textAlign: "center", + fontSize: 8, + whiteSpace: "nowrap", + }, + tableHeader: { + pageBreakAfter: "auto", + }, + headerRow: { + color: "black", + pageBreakInside: "avoid", + pageBreakAfter: "auto", + }, + logo: { + width: "60px", + height: "auto", + marginBottom: "10px", + }, + contentContainer: { + display: "flex", + justifyContent: "space-between", + marginTop: "20px", + marginLeft: "100px", + marginRight: "30px", + }, + contentInLine: { + display: "flex", + flexDirection: "column", + alignItems: "center", + }, + mainTitle: { + fontFamily: "nazanin", + fontSize: 11, + pAlign: "center", + fontWeight: "bolder", + }, + signature: { + display: "flex", + flexDirection: "column", + alignItems: "flex-end", + marginLeft: "20px", + }, + watermarkContainer: { + position: "fixed", + top: 450, + left: 0, + right: 30, + bottom: 0, + justifyContent: "center", + alignItems: "center", + opacity: 0.2, + zIndex: -1, + }, + watermarkp: { + fontSize: 100, + fontWeight: "bolder", + color: "grey", + transform: "rotate(-45deg)", + left: "50%", + }, + title: { + fontSize: 12, + fontWeight: "bolder", + pAlign: "center", + }, + titleTopic: { + marginTop: "10px", + fontSize: 12, + fontWeight: "bolder", + pAlign: "center", + }, + firsttitle: { + fontSize: 14, + fontWeight: "bolder", + marginLeft: "40px", + pAlign: "center", + }, + title2: { + fontSize: 10, + marginBottom: 10, + pAlign: "center", + }, + options: { + padding: "10px", + marginTop: "15px", + display: "flex", + flexDirection: "column", + alignItems: "flex-start", + }, + divider: { + width: "100%", + height: "2px", + backgroundColor: "red", + marginBottom: 15, + }, + pTitleContainer: { + pAlign: "right", + margin: "15px", + textAlign: "justify", + textJustify: "inter-word", + }, + tableHeaderCell: { + backgroundColor: "rgba(255, 229, 153, 0.5)", + fontSize: 10, + border: "1px solid #000", + padding: "4px", + textAlign: "center", + fontWeight: "bold", + }, + footer: { + pageBreakAfter: "always", + position: "fixed", + left: 0, + bottom: 0, + width: "100%", + }, +}; + +const ProvinceQuarantineInvoice = forwardRef((props, ref) => { + const { sDate } = props; + const { date } = props; + const { fnumber } = props; + const { receiver } = props; + const { item } = props; + const { price } = props; + const systemName = useSystemName(); + const ceoName = useCeoName(); + + // function getAddressContent(systemName) { + // switch (systemName) { + // case "استان اردبیل": + // return "آدرس : اردبیل، شهرک کارشناسان ،جنب ساختمان نظام مهندسی، ساختمان فرهنگ، طبقه دوم تلفن : 33749254 تلفاکس : 33749253 "; + + // case "استان همدان": + // return "همدان، بلوار آیت اله مدنی، کوچه امامزاده یحیی یک تلفن: 081 32523689 "; + + // case "استان آذربایجان شرقی": + // return "تبریز خیابان راه آهن نبش کوی اشکان ساختمان ۱۴ طبقه دوم تلفن: 041 34502363"; + + // default: + // return "خرم آباد، مطهری، شرکت مهندسی نرم افزار آرتا مهر آرتان تلفن: 09011110919"; + // } + // } + + return ( +
    +
    +
    + logo + + اتحادیه سراسری تعاونی‌های کشاورزی پرورش دهندگان مرغ گوشتی ایران + + + اتحادیه شرکت های تعاونی کشاورزی مرغداران {" ‌"} {systemName} + +
    + +
    + بسمه تعالی +
    + +
    + شماره: {fnumber} + تاریخ: {formatJustDate(date)} + پیوست: +
    +
    + +
    +

    سامانه رصدیار

    +
    + +
    + +

    + + {receiver} +
    + با سلام +
    +
    +
    + احتراماً بدینوسیله واحد + {" ‌"} + {item?.poultry?.unitName + ? item?.poultry?.unitName + : "..................."}{" "} + {" ‌"} + به مالکیت/ مستاجر + {" ‌"} + {item?.poultry?.user?.fullname + ? item?.poultry?.user?.fullname + : "..................."} + {" ‌"} + به کد سیستمی + {" ‌"} + {item?.poultry?.systemCode + ? item?.poultry?.systemCode + : "..................."} + {" ‌"} + به ظرفیت پروانه + {" ‌"} + {item?.poultry?.totalCapacity + ? item?.poultry?.totalCapacity.toLocaleString() + : "..................."} + {" ‌"} + قطعه و تعداد جوجه ریزي{" "} + {item?.hatching?.hatchingQuantity.toLocaleString()} قطعه در سالن با کد + یکتا + {" ‌"}{" "} + {item?.poultry?.breedingUniqueId + ? item?.poultry?.breedingUniqueId + : "..................."} + {" ‌"}و مسئول فنی فارم آقاي/خانم + {" ‌"} + {item?.hatching?.vetFarmName + ? item?.hatching?.vetFarmName + : "..................."} + {" ‌"} + تلفن تماس: + {" ‌"} + {item?.hatching?.vetFarmMobile + ? item?.hatching?.vetFarmMobile + : "..................."} + {" ‌"} + در راستاي اجراي شیوه نامه ابلاغی مقام عالی وزارت جهاد کشاورزي براي کشتار + {" ‌"} + {item?.quantity.toLocaleString()} + {" ‌"} قطعه مرغ با میانگین وزنی + {item?.IndexWeight ? item?.IndexWeight : "..................."} + {" ‌"} + کیلوگرم و سن {" ‌"} + {item?.hatching?.age ? item?.hatching?.age : "..................."}{" "} + {" ‌"} + روز به تاریخ کشتار {formatJustDate(sDate)} طبق جدول ذیل جهت اخذ مجوز + کشتار به حضورتان معرفی می گردد. لازم به توضیح است قیمت مصوب دولتی + {" ‌"} + {price.toLocaleString()} + {" ‌"} + ریال براي مرغ زنده ملاك فروش خواهد بود. +
    +
    + اعتبار این معرفینامه از تاریخ صدور 24 ساعت می باشد. +

    + +
    +

    اطلاعات تخصیص:

    + + + + + + + + + + + + {item?.provinceKillRequests?.map((item, i) => ( + + + + + + + ))} + +
    ردیفخریدارتعدادوزن تقریبی بار
    {i + 1} + {item?.killhouseUser?.killHouseOperator?.user?.fullname} + {item?.info?.quantity} + {" "} + {Math.round(item?.info?.weight)} +
    + +
    +
    +
    + {ceoName} + + مدیرعامل اتحادیه مرغداران{" ‌"} + {systemName} + +
    +
    +
    + + {/*
    +
    +

    + {getAddressContent(systemName)} +

    +
    */} +
    +
    + ); +}); + +ProvinceQuarantineInvoice.displayName = "ProvinceQuarantineInvoice"; + +export default ProvinceQuarantineInvoice; + +ProvinceQuarantineInvoice.propTypes = { + item: PropTypes.any, +}; diff --git a/src/features/province/components/province-register-car-form/ProvinceRegisterCarForm.js b/src/features/province/components/province-register-car-form/ProvinceRegisterCarForm.js new file mode 100644 index 0000000..696b659 --- /dev/null +++ b/src/features/province/components/province-register-car-form/ProvinceRegisterCarForm.js @@ -0,0 +1,402 @@ +import React, { useContext, useEffect, useState } from "react"; +import { useFormik } from "formik"; +import * as Yup from "yup"; +import { + TextField, + Button, + Grid, + FormControl, + FormHelperText, + Select, + MenuItem, + InputLabel, + InputAdornment, + FormControlLabel, + Radio, + RadioGroup, + Typography, +} from "@mui/material"; +import { CarPelak } from "../../../../components/car-pelak/CarPelak"; +import { useDispatch, useSelector } from "react-redux"; +import { provinceRegisterCarService } from "../../services/province-register-car"; +import { AppContext } from "../../../../contexts/AppContext"; +import { DRAWER } from "../../../../lib/redux/slices/appSlice"; +import { provinceGetCars } from "../../services/province-get-cars"; +import { provinceGetCitiesService } from "../../services/province-get-cities"; +import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl"; +import { provinceEditCarService } from "../../services/province-edit-car"; + +const validationSchema = Yup.object({ + driver_mobile: Yup.string().required("شماره موبایل راننده الزامی است"), + last_name: Yup.string().required("نام خانوادگی الزامی است"), + first_name: Yup.string().required("نام الزامی است"), + city_name: Yup.string().required("نام شهر الزامی است"), + type_car: Yup.string().required("نوع خودرو الزامی است"), + pelak: Yup.string().required("پلاک الزامی است"), + capocity: Yup.string().required("ظرفیت الزامی است"), + health_code: Yup.string().required("کد سلامت الزامی است"), +}); + +export const ProvinceRegisterCarForm = ({ + first_name, + last_name, + driver_mobile, + city_name, + type_car, + pelak, + capocity, + health_code, + driverKey, + type, +}) => { + const dispatch = useDispatch(); + const [openNotif] = useContext(AppContext); + const { provinceGetCities } = useSelector((state) => state.provinceSlice); + + const formik = useFormik({ + initialValues: { + driver_mobile: driver_mobile, + last_name: last_name, + first_name: first_name, + city_name: city_name, + type_car: type_car, + pelak: "", + capocity: capocity, + health_code: health_code, + type: type ? type : "exclusive", + }, + validationSchema: validationSchema, + onSubmit: () => { + // Handle form submission + + handleSubmitForm(); + }, + }); + + const [driverPelak, setDriverPelak] = useState([]); + + useEffect(() => { + if (pelak) { + const pelakParts = pelak.split(" "); + setDriverPelak(pelakParts); + } + }, [pelak]); + + useEffect(() => { + formik.setFieldValue( + "pelak", + driverPelak.length ? driverPelak.join(" ").trim() : "" + ); + }, [driverPelak]); + + const handleSubmitForm = () => { + const { values, errors } = formik; + + if (errors?.length) { + return; + } + if (driverKey) { + dispatch( + provinceEditCarService({ + driver_mobile: values.driver_mobile, + last_name: values.last_name, + first_name: values.first_name, + city_name: values.city_name, + type_car: values.type_car, + pelak: driverPelak.join(" "), + capocity: values.capocity, + health_code: values.health_code, + role: getRoleFromUrl(), + driver_key: driverKey, + type: values.type, + }) + ).then((r) => { + if (r.payload.error) { + openNotif({ + vertical: "top", + horizontal: "center", + msg: r.payload.error, + severity: "error", + }); + } else { + dispatch(provinceGetCars()); + dispatch(DRAWER({ right: false, bottom: false, content: null })); + openNotif({ + vertical: "top", + horizontal: "center", + msg: "عملیات با موفقیت انجام شد.", + severity: "success", + }); + } + }); + } else { + dispatch( + provinceRegisterCarService({ + driver_mobile: values.driver_mobile, + last_name: values.last_name, + first_name: values.first_name, + city_name: values.city_name, + type_car: values.type_car, + pelak: driverPelak.join(" "), + capocity: values.capocity, + health_code: values.health_code, + role: getRoleFromUrl(), + type: values.type, + }) + ).then((r) => { + if (r.payload.error) { + openNotif({ + vertical: "top", + horizontal: "center", + msg: r.payload.error, + severity: "error", + }); + } else { + dispatch(provinceGetCars()); + dispatch(DRAWER({ right: false, bottom: false, content: null })); + openNotif({ + vertical: "top", + horizontal: "center", + msg: "عملیات با موفقیت انجام شد.", + severity: "success", + }); + } + }); + } + }; + + const carPelakHandleChange = (pelak1, pelak2, pelak3, pelak4) => { + setDriverPelak([pelak1, pelak2, pelak3, pelak4]); + }; + + useEffect(() => { + dispatch(provinceGetCitiesService()).then(() => + formik.setFieldValue("city_name", city_name) + ); + }, []); + + return ( +
    + + + + + + + + + + + + + + + + + {provinceGetCities?.length && ( + + + شهر + + {formik.touched.city_name && formik.errors.city_name && ( + {formik.errors.city_name} + )} + + + )} + + + + نوع خودرو + + {formik.touched.type_car && formik.errors.type_car && ( + {formik.errors.type_car} + )} + + + + + + + + کیلوگرم + ), + }} + value={formik.values.capocity} + onChange={formik.handleChange} + onBlur={formik.handleBlur} + error={formik.touched.capocity && Boolean(formik.errors.capocity)} + helperText={formik.touched.capocity && formik.errors.capocity} + /> + + + + + + + + + ماهیت خودرو + + + {(getRoleFromUrl() === "ProvinceOperator" || + getRoleFromUrl() === "SuperAdmin" || + getRoleFromUrl() === "AdminX") && ( + } + label={ + + + اجاره ای{" "} + + (نمایش برای تمام کشتارگاه ها) + + + + } + /> + )} + + } + label="اختصاصی" + /> + + + + + + + +
    + ); +}; diff --git a/src/features/province/components/province-register-car/ProvinceRegisterCar.js b/src/features/province/components/province-register-car/ProvinceRegisterCar.js new file mode 100644 index 0000000..f47a13b --- /dev/null +++ b/src/features/province/components/province-register-car/ProvinceRegisterCar.js @@ -0,0 +1,664 @@ +import { + Button, + FormControl, + Grid, + IconButton, + InputLabel, + MenuItem, + Select, + TextField, + Typography, +} from "@mui/material"; +import { SPACING } from "../../../../data/spacing"; +import SendIcon from "@mui/icons-material/Send"; +import { useFormik } from "formik"; +import { Yup } from "../../../../lib/yup/yup"; +import { useEffect } from "react"; +import { + DRAWER, + LOADING_END, + LOADING_START, +} from "../../../../lib/redux/slices/appSlice"; +// import { slaughterNewCar } from "../../services/slaughter-new-car"; +import { useDispatch } from "react-redux"; +import { AppContext } from "../../../../contexts/AppContext"; +import { useContext } from "react"; +import SearchIcon from "@mui/icons-material/Search"; +import { useState } from "react"; +import { provinceGetDriverByHealthCode } from "../../services/province-get-driver-by-health-code"; +import { provinceSubmitCar } from "../../services/province-submit-car"; +import { provinceGetCars } from "../../services/province-get-cars"; +import { provinceRemoveCar } from "../../services/province-remove-car"; +import { NumberInput } from "../../../../components/number-format-custom/NumberFormatCustom"; + +export const ProvinceRegisterCar = () => { + const dispatch = useDispatch(); + const [openNotif] = useContext(AppContext); + const [userExist, setUserExist] = useState(false); + const [userData, setUserData] = useState(); + const [userKey, setUserKey] = useState(); + const [userChecked, setUserChecked] = useState(false); + + const formik = useFormik({ + initialValues: { + driver_name: "", + driver_mobile: "", + type_car: "ایسوزو", + type_weight: "سنگین", + capocity: "", + pelak1: "33", + pelak2: "الف", + pelak3: "", + pelak4: "", + // name: "", + }, + validationSchema: Yup.object({ + driver_name: Yup.string() + .matches( + /^[ض‌ص‌ث‌ق‌ف‌غ‌ع‌ه‌خ‌خ‌ح‌ج‌چ‌ش‌س‌ی‌ب‌ل‌ا‌ت‌ن‌ن‌م‌ک‌گ‌ظ‌ط‌ز‌ر‌ذ‌د‌و‌پ‌آ‌ژ ]+$/, + "فقط حروف فارسی وارد کنید" + ) + .required("این فیلد اجباری است!") + .typeError("لطفا فیلد را به درستی وارد کنید!"), + driver_mobile: Yup.string() + .test("len", "شماره تلفن باید با 0 شروع شود", (val, context) => { + return context.originalValue && context.originalValue.startsWith("0"); + }) + .test("len", "شماره تماس 11 رقم باید باشد", (val, context) => { + if (context.originalValue) { + return context.originalValue.length === 11; + } + }) + .required("این فیلد اجباری است!") + .typeError("لطفا عدد وارد کنید!"), + type_weight: Yup.string() + .required("این فیلد اجباری است!") + .typeError("لطفا فیلد را به درستی وارد کنید!"), + capocity: Yup.string() + .required("این فیلد اجباری است!") + .typeError("لطفا فیلد را به درستی وارد کنید!"), + pelak1: Yup.number() + .required("این فیلد اجباری است!") + .typeError("لطفا عدد وارد کنید!"), + pelak2: Yup.string() + .required("این فیلد اجباری است!") + .typeError("لطفا فیلد را به درستی وارد کنید!"), + pelak3: Yup.number() + .required("این فیلد اجباری است!") + .typeError("لطفا عدد وارد کنید!"), + pelak4: Yup.number() + .required("این فیلد اجباری است!") + .typeError("لطفا عدد وارد کنید!"), + name: Yup.string().typeError("لطفا فیلد را به درستی وارد کنید!"), + }), + }); + + useEffect(() => { + formik.setFieldValue("pelak2", "الف"); + formik.validateForm(); + formik2.validateForm(); + }, []); + + const formik2 = useFormik({ + initialValues: { + health_code_check: "", + }, + validationSchema: Yup.object({ + health_code_check: Yup.number() + .required("این فیلد اجباری است!") + .typeError("لطفا فیلد را به درستی وارد کنید!"), + }), + }); + + return ( + + + + + {!userChecked && ( + <> + ثبت با کد بهداشتی + + + { + if (formik2.values.health_code_check) { + dispatch(LOADING_START()); + dispatch( + provinceGetDriverByHealthCode( + formik2.values.health_code_check + ) + ).then((r) => { + if (r.error) { + if (r.error.message.includes("403")) { + openNotif({ + vertical: "top", + horizontal: "center", + msg: "این هم اکنون در کشتارگاه فعال است. یک راننده جدید ثبت کنید!", + severity: "error", + }); + } else { + openNotif({ + vertical: "top", + horizontal: "center", + msg: "مشکلی پیش آمده است!", + severity: "error", + }); + } + } else { + setUserChecked(true); + if (r.payload.data[0]) { + setUserData(r.payload.data[0]); + setUserExist(true); + setUserKey(r.payload.data[0]?.key); + } else { + openNotif({ + vertical: "top", + horizontal: "center", + msg: "راننده پیدا نشد. یک راننده جدید ثبت کنید!", + severity: "error", + }); + setUserExist(false); + formik.setFieldValue( + "health_code", + formik2.values.health_code_check + ); + } + } + + dispatch(LOADING_END()); + }); + } + }} + > + + + + + )} + {userChecked && ( + <> + {userExist ? ( + <> + + + prop.palette.grey["A700"]} + > + نام راننده: + + + {userData.driverName} + {" "} + + + + prop.palette.grey["A700"]} + > + موبایل: + + + {userData.driverMobile} + + + + + prop.palette.grey["A700"]} + > + خودرو: + + + {userData.typeCar} + {" "} + + + + prop.palette.grey["A700"]} + > + پلاک: + + + {userData.pelak} + {" "} + + + + prop.palette.grey["A700"]} + > + ظرفیت: + + + {userData.capocity} + {" "} + + + + + ) : ( + <> + مشخصات خودرو جدید + + + + + + + + مدل خودرو + + + + + + {/* */} + + + مشخصات پلاک + + + + حرف + + + + + + + + { + formik.setFieldValue("pelak4", e.target.value); + }} + error={ + formik.touched.pelak4 + ? Boolean(formik.errors.pelak4) + : null + } + onBlur={formik.handleBlur} + helperText={ + formik.touched.pelak4 && Boolean(formik.errors.pelak4) + ? formik.errors.pelak4 + : null + } + /> + + + + + + )} + + )} + + + + + ); +}; diff --git a/src/features/province/components/province-rejected-requests/ProvinceRejectedRequests.js b/src/features/province/components/province-rejected-requests/ProvinceRejectedRequests.js new file mode 100644 index 0000000..43ed877 --- /dev/null +++ b/src/features/province/components/province-rejected-requests/ProvinceRejectedRequests.js @@ -0,0 +1,73 @@ +import { Card } from "@mui/material"; +import { useEffect, useState } from "react"; +import { AdvancedTable } from "../../../../components/advanced-table/AdvancedTable"; +import PlagiarismIcon from "@mui/icons-material/Plagiarism"; +import { useNavigate } from "react-router-dom"; +import { ROUTE_PROVINCE_FILE } from "../../../../routes/routes"; +import IconButton from "@mui/material/IconButton"; +import { useDispatch, useSelector } from "react-redux"; +import { provinceGetRejectedRequests } from "../../services/province-get-rejected-requests"; +import { formatJustDate } from "../../../../utils/formatTime"; + +export const ProvinceRejectedRequests = () => { + const navigate = useNavigate(); + const dispatch = useDispatch(); + const { provinceRejectedRequests } = useSelector( + (state) => state.provinceSlice + ); + const [dataTable, setDataTable] = useState([]); + + useEffect(() => { + dispatch(provinceGetRejectedRequests()); + }, []); + + useEffect(() => { + const d = provinceRejectedRequests?.map((item, i) => { + return [ + i + 1, + item.orderCode, + formatJustDate(item?.createDate), + formatJustDate(item?.sendDate), + item.fullname, + item.mobile, + item.city, + item.province, + item.poultryQuantity, + { + navigate(ROUTE_PROVINCE_FILE + item.id); + }} + > + + , + ]; + }); + setDataTable(d); + }, [provinceRejectedRequests]); + + const [tableDataCol] = useState([ + "ردیف", + "کد سفارش", + "تاریخ ثبت درخواست", + "تاریخ درخواست", + "مرغدار", + "تلفن مرغدار", + "شهر", + "استان", + // "سن مرغ", + "تعداد", + "مشاهده", + ]); + return ( + + + + ); +}; diff --git a/src/features/province/components/province-requests-operations/ProvinceRequestsOperations.js b/src/features/province/components/province-requests-operations/ProvinceRequestsOperations.js new file mode 100644 index 0000000..c03b42f --- /dev/null +++ b/src/features/province/components/province-requests-operations/ProvinceRequestsOperations.js @@ -0,0 +1,260 @@ +import { Grid } from "../../../../components/grid/Grid"; +import { SPACING } from "../../../../data/spacing"; +import { NavLink } from "../../../../components/nav-link/NavLink"; +import { useLocation } from "react-router-dom"; +import { + ROUTE_PROVINCE_CITY_NEW_REQUESTS, + ROUTE_PROVINCE_STATEMENTـOFـNEED_REQUESTS, + ROUTE_PROVINCE_ALLOCATION_REQUESTS, + ROUTE_PROVINCE_FREE_SALES_REQUESTS, + ROUTE_PROVINCE_AUTO_ALLOCATION_REQUESTS, + ROUTE_PROVINCE_ALLOCATED_REQUESTS, + ROUTE_PROVINCE_PAYING_FEES_REQUESTS, + ROUTE_PROVINCEـFREE_BUY, + ROUTE_PROVINCE_ISSUANCE_OF_LETTER, + ROUTE_PROVINCE_TRANSACTIONS, + ROUTE_PROVINCE_CHAINS, + ROUTE_PROVINCEـEXPORT, + // ROUTE_PROVINCE_ROUTE_AGENT_SHARE, +} from "../../../../routes/routes"; +import LinkItem from "../../../../components/link-item/LinkItem"; +import { VscFolderActive, VscNewFolder } from "react-icons/vsc"; +// import { FaFilePdf } from "react-icons/fa"; +import { FaHornbill } from "react-icons/fa"; +import ExpandMoreIcon from "@mui/icons-material/ExpandMore"; + +import { + FaTruckLoading, + FaFile, + FaFilePdf, + FaExchangeAlt, +} from "react-icons/fa"; + +import { + MdCreateNewFolder, + MdImportExport, + MdOutlineRuleFolder, +} from "react-icons/md"; +import { LineWithText } from "../../../../components/line-with-text/LineWithText"; +import { OPEN_MODAL } from "../../../../lib/redux/slices/appSlice"; +import { useDispatch } from "react-redux"; +import PorvinceGetReportOperations from "../province-get-report-operations/PorvinceGetReportOperations"; +import { + Accordion, + AccordionDetails, + AccordionSummary, + Typography, +} from "@mui/material"; +// import { IoLogoUsd } from "react-icons/io"; + +export const ProvinceRequestsOperations = () => { + const { pathname } = useLocation(); + const dispatch = useDispatch(); + return ( + + + + + + + + } + title="درخواست های کشتار" + description="درخواست های کشتار مرغدار در انتظار بررسی" + /> + + + } + title="اعلام نیاز خریداران" + description="درخواست های کشتار در انتظار بررسی" + /> + + {/* + } + title="در انتظار تایید" + description="درخواست های در انتظار تایید توسط استان" + /> + */} + + + } + title="تخصیصات" + description="مشاهده و تخصیص درخواست ها" + /> + + + } + title="تعرفه ها" + /> + + + + + + + + + + + } + title="خرید مستقیم" + /> + + + } + title="صادرات" + /> + + + } + title="فروش به خارج استان" + /> + + + + } + title="زنجیره ها" + /> + + + } + title="مدیریت تخصیصات" + /> + + + + + + + }> + + نظارت درخواست ها + + + + + + } + title="تخصیصات خودکار" + /> + + + } + title="صدور نامه" + description="ارسال نامه سیستمی" + /> + + + dispatch( + OPEN_MODAL({ + title: "اطلاعات گزارش", + content: , + }) + ) + } + > + } + title="گزارش روزانه" + description="گزارش روزانه" + /> + + + } + title="تراکنش ها" + /> + + + + + + + ); +}; diff --git a/src/features/province/components/province-restriction-carcass-distribution/ProvinceRestrictionCarcassDistribution.js b/src/features/province/components/province-restriction-carcass-distribution/ProvinceRestrictionCarcassDistribution.js new file mode 100644 index 0000000..cb5f155 --- /dev/null +++ b/src/features/province/components/province-restriction-carcass-distribution/ProvinceRestrictionCarcassDistribution.js @@ -0,0 +1,103 @@ +import { useContext, useEffect, useState } from "react"; +import { useDispatch } from "react-redux"; +import axios from "axios"; +import { Grid } from "../../../../components/grid/Grid"; +import ResponsiveTable from "../../../../components/responsive-table/ResponsiveTable"; +import { + LOADING_END, + LOADING_START, + OPEN_MODAL, +} from "../../../../lib/redux/slices/appSlice"; +import { AppContext } from "../../../../contexts/AppContext"; +import { IconButton } from "@mui/material"; +import EditIcon from "@mui/icons-material/Edit"; +import { ProvinceRestrictionCarcassDistributionEdit } from "./ProvinceRestrictionCarcassDistributionEdit.js"; + +export const ProvinceRestrictionCarcassDistribution = () => { + const dispatch = useDispatch(); + const [openNotif] = useContext(AppContext); + + const [data, setData] = useState([]); + const [tableData, setTableData] = useState([]); + + const fetchData = async () => { + dispatch(LOADING_START()); + try { + const response = await axios.get("restriction_carcass_distribution/"); + dispatch(LOADING_END()); + setData(response?.data || []); + } catch (error) { + dispatch(LOADING_END()); + openNotif({ + vertical: "top", + horizontal: "center", + msg: error?.response?.data?.message || "خطا در دریافت اطلاعات", + severity: "error", + }); + console.error("Error fetching data:", error); + } + }; + + useEffect(() => { + fetchData(); + }, []); + + const getDistributionTypeLabel = (type) => { + const types = { + KillHouse: "کشتارگاه", + Steward: "مباشر", + }; + return types[type] || type; + }; + + useEffect(() => { + const d = data?.map((item, i) => { + return [ + i + 1, + getDistributionTypeLabel(item?.distributionType), + item?.out ? "خارج استان" : "داخل استان", + item?.time || "-", + item?.allow ? "فعال" : "غیر فعال", + + { + dispatch( + OPEN_MODAL({ + title: "ویرایش محدودیت توزیع لاشه", + content: ( + + ), + }) + ); + }} + > + + + , + ]; + }); + + setTableData(d); + }, [data]); + + return ( + <> + + + ); +}; diff --git a/src/features/province/components/province-restriction-carcass-distribution/ProvinceRestrictionCarcassDistributionEdit.js b/src/features/province/components/province-restriction-carcass-distribution/ProvinceRestrictionCarcassDistributionEdit.js new file mode 100644 index 0000000..c23c538 --- /dev/null +++ b/src/features/province/components/province-restriction-carcass-distribution/ProvinceRestrictionCarcassDistributionEdit.js @@ -0,0 +1,102 @@ +import React, { useContext, useState } from "react"; +import { Grid } from "../../../../components/grid/Grid"; +import { Button, Radio, RadioGroup, FormControlLabel } from "@mui/material"; +import { useDispatch } from "react-redux"; +import { AppContext } from "../../../../contexts/AppContext"; +import { + CLOSE_MODAL, + LOADING_END, + LOADING_START, +} from "../../../../lib/redux/slices/appSlice"; +import TimePicker from "../../../../components/date-picker/CustomDatePicker"; +import axios from "axios"; + +export const ProvinceRestrictionCarcassDistributionEdit = ({ + item, + fetchData, +}) => { + const dispatch = useDispatch(); + const [openNotif] = useContext(AppContext); + + const [formData, setFormData] = useState({ + time: item?.time || "16:00:00", + allow: item?.allow !== undefined ? item?.allow : true, + }); + + const handleSubmit = async (e) => { + e.preventDefault(); + + dispatch(LOADING_START()); + try { + await axios.put(`restriction_carcass_distribution/${item?.id}/`, { + time: formData.time, + allow: formData.allow, + }); + + dispatch(LOADING_END()); + openNotif({ + vertical: "top", + horizontal: "center", + msg: "عملیات با موفقیت انجام شد.", + severity: "success", + }); + fetchData(); + dispatch(CLOSE_MODAL()); + } catch (error) { + dispatch(LOADING_END()); + openNotif({ + vertical: "top", + horizontal: "center", + msg: error?.response?.data?.message || "خطا در ویرایش اطلاعات", + severity: "error", + }); + console.error("Error updating data:", error); + } + }; + + return ( + +
    + + + + setFormData((prev) => ({ + ...prev, + allow: e.target.value === "allow", + })) + } + > + } + label="فعال" + /> + } + label="غیر فعال" + /> + + + + + + setFormData((prev) => ({ ...prev, time: newTime })) + } + label="زمان" + /> + + + + +
    +
    + ); +}; diff --git a/src/features/province/components/province-return-purchases/ProvinceReturnPurchases.js b/src/features/province/components/province-return-purchases/ProvinceReturnPurchases.js new file mode 100644 index 0000000..893d826 --- /dev/null +++ b/src/features/province/components/province-return-purchases/ProvinceReturnPurchases.js @@ -0,0 +1,283 @@ +import { Button, Tab, Tabs, TextField } from "@mui/material"; +import { useContext, useEffect, useState } from "react"; +import { Grid } from "../../../../components/grid/Grid"; +import { SPACING } from "../../../../data/spacing"; +import { ReturnedAllocated } from "./ProvinceReturnedAllocated"; +import { ReturnedCargo } from "./ProvinceReturnedCargo"; +import ResponsiveTable from "../../../../components/responsive-table/ResponsiveTable"; +import { DatePicker } from "@mui/x-date-pickers"; +import moment from "moment"; +import { RiSearchLine } from "react-icons/ri"; +import axios from "axios"; +import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl"; +import { AppContext } from "../../../../contexts/AppContext"; +import { useDispatch, useSelector } from "react-redux"; +import { + LOADING_END, + LOADING_START, +} from "../../../../lib/redux/slices/appSlice"; +import { checkPathStartsWith } from "../../../../utils/checkPathStartsWith"; + +export const ProvinceReturnPurchases = () => { + const dispatch = useDispatch(); + const [selectedTab, setSelectedTab] = useState(0); + const [data, setData] = useState([]); + const [totalRows, setTotalRows] = useState(0); + const [perPage, setPerPage] = useState(10); + const [page, setPage] = useState(1); + const [dashboardData, setDashboardData] = useState({}); + const [, , selectedDate1, setSelectedDate1, selectedDate2, setSelectedDate2] = + useContext(AppContext); + + const [textValue, setTextValue] = useState(""); + const selectedSubUser = useSelector( + (state) => state.userSlice.selectedSubUser + ); + useEffect(() => { + const currentDate = moment(new Date()).format("YYYY-MM-DD"); + setSelectedDate1(currentDate); + setSelectedDate2(currentDate); + }, []); + + const fetchDashboard = async () => { + try { + const response = await axios.get( + `return-requests-dashboard/?role=${getRoleFromUrl()}${ + checkPathStartsWith("province") + ? `&role_key=${selectedSubUser?.key}` + : "" + }&date1=${selectedDate1}&date2=${selectedDate2}` + ); + setDashboardData(response.data); + } catch (error) { + console.error("Error fetching dashboard data:", error); + } + }; + + const handleTextChange = (event) => { + setTextValue(event.target.value); + }; + + const handleTabChange = (event, newValue) => { + setSelectedTab(newValue); + setPage(1); + }; + + const fetchApiData = async (page) => { + dispatch(LOADING_START()); + try { + const endpoint = + selectedTab === 0 + ? "return-province-kill-requests" + : "return-kill-house-requests"; + + const response = await axios.get( + `${endpoint}/?role=${getRoleFromUrl()}${ + checkPathStartsWith("province") + ? `&role_key=${selectedSubUser?.key}` + : "" + }&date1=${selectedDate1}&date2=${selectedDate2}&search=filter&value=${textValue}&page_size=${perPage}&page=${page}` + ); + setData(response.data.results); + setTotalRows(response.data.count); + dispatch(LOADING_END()); + } catch (error) { + console.error("Error fetching data:", error); + dispatch(LOADING_END()); + } + }; + + const handlePageChange = (page) => { + fetchApiData(page); + setPage(page); + }; + + const handlePerRowsChange = (perRows) => { + setPerPage(perRows); + setPage(1); + }; + + useEffect(() => { + fetchApiData(1); + fetchDashboard(); + }, [ + selectedDate1, + selectedDate2, + perPage, + selectedTab, + selectedSubUser?.key, + ]); + + const handleSubmit = () => { + fetchApiData(page); + fetchDashboard(); + }; + + const updateTable = () => { + fetchApiData(page); + fetchDashboard(); + }; + + return ( + + + + } + value={selectedDate1} + onChange={(e) => { + setSelectedDate1(moment(e).format("YYYY-MM-DD")); + }} + /> + + + } + value={selectedDate2} + onChange={(e) => { + setSelectedDate2(moment(e).format("YYYY-MM-DD")); + }} + /> + + + + + + + + + + + + + + + + + {selectedTab === 0 && ( + + )} + {selectedTab === 1 && ( + + )} + + ); +}; diff --git a/src/features/province/components/province-return-purchases/ProvinceReturnPurchasesOperations.js b/src/features/province/components/province-return-purchases/ProvinceReturnPurchasesOperations.js new file mode 100644 index 0000000..f43f253 --- /dev/null +++ b/src/features/province/components/province-return-purchases/ProvinceReturnPurchasesOperations.js @@ -0,0 +1,156 @@ +import { + Button, + Dialog, + DialogActions, + DialogContent, + DialogContentText, + DialogTitle, + IconButton, + Popover, + Tooltip, +} from "@mui/material"; +import { useContext, useState } from "react"; +import { useDispatch } from "react-redux"; +import { Grid } from "../../../../components/grid/Grid"; +import CheckCircleIcon from "@mui/icons-material/CheckCircle"; +import TuneIcon from "@mui/icons-material/Tune"; +import { AppContext } from "../../../../contexts/AppContext"; +import { activateReturnedRequest } from "../../services/activate-returned-request"; +import { activateReturnedCargo } from "../../services/activate-returned-cargo"; +import { SPACING } from "../../../../data/spacing"; + +export const ProvinceReturnPurchasesOperations = ({ + item, + updateTable, + type = "allocated", +}) => { + const dispatch = useDispatch(); + const [anchorEl, setAnchorEl] = useState(null); + const [openDialog, setOpenDialog] = useState(false); + const [openNotif] = useContext(AppContext); + + const handleClick = (event) => { + setAnchorEl(event.currentTarget); + }; + + const handleClose = () => { + setAnchorEl(null); + }; + + const handleOpenDialog = () => { + setOpenDialog(true); + }; + + const handleCloseDialog = () => { + setOpenDialog(false); + }; + + const open = Boolean(anchorEl); + const id = open ? "popover" : undefined; + + const handleActivate = () => { + handleCloseDialog(); + const activateAction = + type === "cargo" ? activateReturnedCargo : activateReturnedRequest; + + dispatch( + activateAction({ + key: item?.key, + }) + ).then((r) => { + if (r.payload?.error || r.error) { + openNotif({ + vertical: "top", + horizontal: "center", + msg: "مشکلی پیش آمده است!", + severity: "error", + }); + } else { + handleClose(); + updateTable(); + openNotif({ + vertical: "top", + horizontal: "center", + msg: "عملیات با موفقیت انجام شد.", + severity: "success", + }); + } + }); + }; + + return ( +
    + + + + +
    + + + + + +
    +
    + + + {"تایید فعال سازی"} + + + آیا از فعال سازی این تخصیص بازگشتی اطمینان دارید؟ + + + + + + + + + +
    + ); +}; diff --git a/src/features/province/components/province-return-purchases/ProvinceReturnedAllocated.js b/src/features/province/components/province-return-purchases/ProvinceReturnedAllocated.js new file mode 100644 index 0000000..336c353 --- /dev/null +++ b/src/features/province/components/province-return-purchases/ProvinceReturnedAllocated.js @@ -0,0 +1,163 @@ +import { useContext, useEffect, useState } from "react"; +import { Grid } from "../../../../components/grid/Grid"; +import { SPACING } from "../../../../data/spacing"; +import { formatJustDate, formatTime } from "../../../../utils/formatTime"; +import ResponsiveTable from "../../../../components/responsive-table/ResponsiveTable"; +import { Button, Tooltip } from "@mui/material"; +import axios from "axios"; +import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl"; +import { RiFileExcel2Fill } from "react-icons/ri"; +import { AppContext } from "../../../../contexts/AppContext"; +import { useSelector } from "react-redux"; +import { ProvinceReturnPurchasesOperations } from "./ProvinceReturnPurchasesOperations"; +import { checkPathStartsWith } from "../../../../utils/checkPathStartsWith"; + +export const ReturnedAllocated = ({ + data, + page, + perPage, + totalRows, + handlePageChange, + handlePerRowsChange, + textValue, + updateTable, +}) => { + const [dataTable, setDataTable] = useState(); + const [, , selectedDate1, , selectedDate2] = useContext(AppContext); + const userKey = useSelector((state) => state.userSlice.userProfile.key); + const selectedSubUser = useSelector( + (state) => state.userSlice.selectedSubUser + ); + + useEffect(() => { + const d = data?.map((item, i) => { + let state = ""; + if (item.state === "pending") { + state = "در انتظار تایید"; + } else if (item.state === "accepted") { + state = "تایید شده"; + } else if (item.state === "rejected") { + state = "رد شده"; + } + + let requestType = ""; + if (item?.market) { + requestType = "پنل معاملات"; + } else if (item?.directBuying) { + requestType = "خرید مستقیم"; + } else if (item?.warehouse) { + requestType = "انبار"; + } else { + requestType = "اتحادیه"; + } + + const rows = [ + page === 1 ? i + 1 : i + perPage * (page - 1) + 1, + item?.orderCode || "-", + requestType, + item?.poultryUnitName, + `${item?.poultryFullname} (${item?.poultryMobile})`, + item?.poultryCity, + formatJustDate(item?.killingDate), + item?.poultryRequestQuantity?.toLocaleString(), + formatTime(item?.createDate), + item?.killhouseUser.name || "-", + item?.killhouseUser.city || "-", + item?.poultryAmount?.toLocaleString() + " ﷼", + item?.killHousePrice?.toLocaleString() + " ﷼", + item?.quantity?.toLocaleString(), + state, + item?.firstCarAllocatedQuantity > 0 ? "دارد" : "ندارد", + (item?.quantity - item?.totalKilledQuantity)?.toLocaleString(), + (item?.returner + ? `${item?.returner.fullname} (${item?.returner?.mobile})` + : "سیستم") + + " " + + formatTime(item?.modifyDate), + ]; + + if (["AdminX", "SuperAdmin"].includes(getRoleFromUrl())) { + if (item?.returnTrash === true) { + rows.push( + + ); + } else { + rows.push("-"); + } + } + + return rows; + }); + + setDataTable(d); + }, [data, page, perPage]); + + const columns = [ + "ردیف", + "کدسفارش", + "نوع درخواست", + "نام فارم", + "نام مرغدار", + "شهر مرغدار", + "تاریخ کشتار", + "تعداد درخواست", + "تاریخ ثبت تخصیص", + "نام کشتارگاه", + "شهر کشتارگاه", + "قیمت مرغدار", + "قیمت کشتارگاه", + "تعداد تخصیص", + "وضعیت تایید", + "وضعیت تخصیص ماشین", + "مانده قابل تخصیص", + "برگشت دهنده", + ]; + + if (["AdminX", "SuperAdmin"].includes(getRoleFromUrl())) { + columns.push("عملیات"); + } + + return ( + + + + + + + + + + + + ); +}; diff --git a/src/features/province/components/province-return-purchases/ProvinceReturnedCargo.js b/src/features/province/components/province-return-purchases/ProvinceReturnedCargo.js new file mode 100644 index 0000000..d9b19fe --- /dev/null +++ b/src/features/province/components/province-return-purchases/ProvinceReturnedCargo.js @@ -0,0 +1,182 @@ +import { useContext, useEffect, useState } from "react"; +import { Grid } from "../../../../components/grid/Grid"; +import ResponsiveTable from "../../../../components/responsive-table/ResponsiveTable"; +import { formatTime } from "../../../../utils/formatTime"; +import { Button, Tooltip } from "@mui/material"; +import axios from "axios"; +import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl"; +import { AppContext } from "../../../../contexts/AppContext"; +import { useSelector } from "react-redux"; +import { RiFileExcel2Fill } from "react-icons/ri"; +import { ProvinceReturnPurchasesOperations } from "./ProvinceReturnPurchasesOperations"; +import { checkPathStartsWith } from "../../../../utils/checkPathStartsWith"; + +export const ReturnedCargo = ({ + data, + page, + perPage, + totalRows, + handlePageChange, + handlePerRowsChange, + textValue, + updateTable, +}) => { + const [dataTable, setDataTable] = useState(); + const [, , selectedDate1, , selectedDate2] = useContext(AppContext); + const selectedSubUser = useSelector( + (state) => state.userSlice.selectedSubUser + ); + const userKey = useSelector((state) => state.userSlice.userProfile.key); + useEffect(() => { + const mappedData = data?.map((item, i) => { + let state = ""; + if (item.state === "pending") { + state = "در انتظار تایید"; + } else if (item.state === "accepted") { + state = "تایید شده"; + } else if (item.state === "rejected") { + state = "رد شده"; + } + + let requestType = ""; + if (item?.poultryRequest?.market) { + requestType = "پنل معاملات"; + } else if (item?.poultryRequest?.directBuying) { + requestType = "خرید مستقیم"; + } else if (item?.warehouse) { + requestType = "انبار"; + } else { + requestType = "اتحادیه"; + } + + let killType = ""; + if (item?.poultryRequest?.freezing) { + killType = "انجماد"; + } else if (item?.poultryRequest?.export) { + killType = "صادرات"; + } else { + killType = "عادی"; + } + + const rows = [ + page === 1 ? i + 1 : i + perPage * (page - 1) + 1, + item?.barCode || "-", + item?.poultryRequest?.orderCode || "-", + requestType, + killType, + item?.poultryRequest?.poultry?.unitName || "-", + `${item?.poultryRequest?.poultry?.user?.fullname || "-"} (${ + item?.poultryRequest?.poultry?.user?.mobile || "-" + })`, + item?.poultryRequest?.poultry?.address?.city?.name || "-", + item?.killRequest?.reciveDate + ? formatTime(item?.killRequest?.reciveDate) + : "-", + item?.quantity?.toLocaleString(), + item?.createDate ? formatTime(item?.createDate) : "-", + item?.killhouseUser?.name || item?.killer?.name || "-", + item?.killhouseUser?.killHouseOperator?.user?.city?.name || + item?.killer?.killHouseOperator?.user?.city?.name || + "-", + item?.weightInfo?.weight?.toLocaleString() || "-", + item?.weightInfo?.indexWeight?.toLocaleString() || "-", + item?.acceptedRealQuantity?.toLocaleString(), + item?.acceptedRealWeight?.toLocaleString(), + item?.poultryRequest?.amount?.toLocaleString() + " ﷼" || "-", + item?.weightInfo?.killHousePrice?.toLocaleString() + " ﷼" || "-", + state, + item?.car?.pelak || "-", + item?.car?.driverName || "-", + item?.nonReceipt ? "دارد" : "ندارد", + item?.nonReceiptMessage || "-", + (item?.nonReceipt && item?.mainNonReceipt ? `کاربر` : "سیستم") + + " " + + formatTime(item?.modifyDate), + ]; + + if (["AdminX", "SuperAdmin"].includes(getRoleFromUrl())) { + if (item?.returnTrash === true) { + rows.push( + + ); + } else { + rows.push("-"); + } + } + + return rows; + }); + setDataTable(mappedData); + }, [data, page, perPage]); + + const columns = [ + "ردیف", + "کد بار", + "کدسفارش", + "نوع درخواست", + "نوع کشتار", + "نام فارم", + "نام مرغدار", + "شهر مرغدار", + "تاریخ درخواست کشتار", + "تعداد بار", + "تاریخ ثبت بار", + "نام کشتارگاه", + "شهر کشتارگاه", + "وزن", + "میانگین وزنی", + "تعداد نهایی", + "وزن نهایی", + "قیمت مرغدار", + "قیمت کشتارگاه", + "وضعیت تایید", + "پلاک خودرو", + "نام راننده", + "عدم دریافت", + "پیام عدم دریافت", + "نوع برگشت", + ]; + + if (["AdminX", "SuperAdmin"].includes(getRoleFromUrl())) { + columns.push("عملیات"); + } + + return ( + + + + + + + + + + + + ); +}; diff --git a/src/features/province/components/province-sale-dispenser-with-in-dashboard/ProvinceSaleDispenserWithinDashboard.js b/src/features/province/components/province-sale-dispenser-with-in-dashboard/ProvinceSaleDispenserWithinDashboard.js new file mode 100644 index 0000000..dc679c0 --- /dev/null +++ b/src/features/province/components/province-sale-dispenser-with-in-dashboard/ProvinceSaleDispenserWithinDashboard.js @@ -0,0 +1,27 @@ +import { Grid } from "../../../../components/grid/Grid"; +import ResponsiveTable from "../../../../components/responsive-table/ResponsiveTable"; + +export const ProvinceSaleDispenserWithinDashboard = ({ dashboardData }) => { + return ( + + + + ); +}; diff --git a/src/features/province/components/province-sale-dispenser/ProvinceSaleInDispenser.js b/src/features/province/components/province-sale-dispenser/ProvinceSaleInDispenser.js new file mode 100644 index 0000000..24d3e3e --- /dev/null +++ b/src/features/province/components/province-sale-dispenser/ProvinceSaleInDispenser.js @@ -0,0 +1,326 @@ +import { useDispatch, useSelector } from "react-redux"; +import { AppContext } from "../../../../contexts/AppContext"; +import { useContext, useEffect, useState } from "react"; +import { + LOADING_END, + LOADING_START, +} from "../../../../lib/redux/slices/appSlice"; +import axios from "axios"; +import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl"; +import { formatJustDate } from "../../../../utils/formatTime"; +import { Grid } from "../../../../components/grid/Grid"; +import { DatePicker } from "@mui/x-date-pickers"; +import { + Autocomplete, + Button, + FormControl, + TextField, + Tooltip, +} from "@mui/material"; +import moment from "moment"; +import { RiFileExcel2Fill, RiSearchLine } from "react-icons/ri"; +import ResponsiveTable from "../../../../components/responsive-table/ResponsiveTable"; +import { ProvinceSaleDispenserWithinDashboard } from "../province-sale-dispenser-with-in-dashboard/ProvinceSaleDispenserWithinDashboard"; +import { provinceDispenserWithInGetDashboard } from "../../services/province-dispenser-with-in-sale-dashboard"; +import { provinceDispenserGetStewardService } from "../../services/province-dispenser-get-steward"; +import { ProvinceDispenserStewardSaleInOperation } from "../province-dispenser-steward-sale-in-operation/ProvinceDispenserStewardSaleInOperation"; +import ShowImage from "../../../../components/show-image/ShowImage"; +import { getAllocationType } from "../../../../utils/getAllocationType"; + +export const ProvinceSaleInDispenser = ({ priceInfo }) => { + const { slaughterProducts } = useSelector((state) => state.slaughterSlice); + const dispatch = useDispatch(); + const [, , selectedDate1, setSelectedDate1, selectedDate2, setSelectedDate2] = + useContext(AppContext); + const [dashboardData, setDashboardData] = useState([]); + const [openNotif] = useContext(AppContext); + const userKey = useSelector((state) => state.userSlice.userProfile.key); + const [data, setData] = useState([]); + const [totalRows, setTotalRows] = useState(0); + const [perPage, setPerPage] = useState(10); + const [textValue, setTextValue] = useState(""); + const [page, setPage] = useState(1); + const [tableData, setTableData] = useState([]); + const [steward, setSteward] = useState([]); + const [selectedSteward, setselectedSteward] = useState(null); + + const fetchApiData = async (page) => { + dispatch(LOADING_START()); + try { + const response = await axios.get( + `/in-province-allocation/?search=filter&value=${textValue}&role=${getRoleFromUrl()}&date1=${selectedDate1}&date2=${selectedDate2}&page=${ + page || 1 + }&page_size=${perPage}&type=Steward${ + selectedSteward + ? `&steward_key=${selectedSteward}` + : "&steward_key=all" + }` + ); + setData(response.data.results); + setTotalRows(response.data.count); + } catch (error) { + console.error("Error fetching data:", error); + } finally { + dispatch(LOADING_END()); + } + }; + const fetchsteward = () => { + dispatch(provinceDispenserGetStewardService()).then((r) => { + setSteward(r.payload.data); + }); + }; + const handlePageChange = (page) => { + fetchApiData(page); + setPage(page); + }; + + const handleTextChange = (event) => { + setTextValue(event.target.value); + }; + + const getAllocationData = (item) => { + if (!item) return "-"; + + switch (item?.allocationType) { + case "steward_steward": + return `${item?.toStewards?.name || "-"} - ${ + item?.toStewards?.user?.fullname || "-" + } (${item?.toStewards?.user?.mobile || "-"})`; + case "steward_guild": + return `${item?.toGuilds?.guildsName || "-"} - ${ + item?.toGuilds?.user?.fullname || "-" + } (${item?.toGuilds?.user?.mobile || "-"})`; + case "ColdHouse": + return `${item?.toColdHouse?.name || "-"}`; + default: + return `${item?.toKillHouse?.name || "-"} - ${ + item?.toKillHouse?.killHouseOperator?.user?.fullname || "-" + } (${item?.toKillHouse?.killHouseOperator?.user?.mobile || "-"})`; + } + }; + + const handlePerRowsChange = (perRows) => { + setPerPage(perRows); + setPage(1); + }; + + const fetchDashboardData = () => { + dispatch( + provinceDispenserWithInGetDashboard({ + search: "filter", + role: getRoleFromUrl(), + selectedDate1, + selectedDate2, + steward_key: selectedSteward || "all", + }) + ).then((r) => { + setDashboardData(r.payload.data); + }); + }; + + useEffect(() => { + const d = data?.map((item, i) => { + return [ + page === 1 ? i + 1 : i + perPage * (page - 1) + 1, + formatJustDate(item?.date) || "-", + getAllocationType(item), + item?.steward + ? `${item?.steward?.guildsName?.toLocaleString()} ${item?.steward?.user?.fullname?.toLocaleString()} ${ + item?.steward?.user?.mobile?.toLocaleString() || "-" + }` + : `${item?.guilds?.guildsName?.toLocaleString()} ${item?.guilds?.user?.fullname?.toLocaleString()} ${ + item?.guilds?.user?.mobile?.toLocaleString() || "-" + }`, + getAllocationData(item), + item?.sellType === "exclusive" ? "اختصاصی" : "آزاد", + (item?.amount?.toLocaleString() || "0") + " ریال", + (item?.totalAmount?.toLocaleString() || "0") + " ریال", + item?.weightOfCarcasses?.toLocaleString() || "0", + item?.reciverWeightOfCarcasses?.toLocaleString() || "0", + item?.registrationCode || "-", + item?.registrationCode ? "ارسال شده" : "ارسال نشده", + , + + item?.receiverState === "accepted" + ? "تایید شده" + : item?.receiverState === "rejected" + ? "رد شده" + : "در انتظار تایید", + , + ]; + }); + setTableData(d); + }, [data, page, perPage, priceInfo, slaughterProducts]); + + useEffect(() => { + fetchApiData(1); + fetchDashboardData(); + fetchsteward(); + }, [dispatch, selectedDate1, selectedDate2, perPage, selectedSteward]); + + const handleSubmit = async (event) => { + event.preventDefault(); + fetchApiData(1); + fetchDashboardData(); + }; + + return ( + + + + + + + + ( + + )} + value={selectedDate1} + onChange={(newValue) => { + setSelectedDate1(moment(newValue).format("YYYY-MM-DD")); + }} + /> + + + ( + + )} + value={selectedDate2} + onChange={(newValue) => { + setSelectedDate2(moment(newValue).format("YYYY-MM-DD")); + }} + /> + + +
    + + + `(${option?.guildsName}) ${option?.user?.fullname}` + } + value={ + selectedSteward + ? steward.find((item) => item.key === selectedSteward) || + null + : null + } + onChange={(event, newValue) => { + setselectedSteward(newValue ? newValue.key : null); + }} + renderInput={(params) => ( + + )} + noOptionsText="مباشری یافت نشد" + isOptionEqualToValue={(option, value) => + option.key === value.key + } + /> + + + + + +
    + + + +
    + + +
    +
    + ); +}; diff --git a/src/features/province/components/province-segmentation/ProvinceSegmentation.js b/src/features/province/components/province-segmentation/ProvinceSegmentation.js new file mode 100644 index 0000000..dfb5516 --- /dev/null +++ b/src/features/province/components/province-segmentation/ProvinceSegmentation.js @@ -0,0 +1,235 @@ +import { useContext, useEffect, useState } from "react"; +import { useDispatch } from "react-redux"; +import moment from "moment"; +import { Button, TextField } from "@mui/material"; +import { DatePicker } from "@mui/x-date-pickers"; +import { RiSearchLine } from "react-icons/ri"; +import axios from "axios"; +import { AppContext } from "../../../../contexts/AppContext"; +import { stawardGetSegmentDashboardService } from "../../../guild/services/steward-get-dashboard-service"; +import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl"; +import { + LOADING_END, + LOADING_START, +} from "../../../../lib/redux/slices/appSlice"; +import { SPACING } from "../../../../data/spacing"; +import { Grid } from "../../../../components/grid/Grid"; +import ResponsiveTable from "../../../../components/responsive-table/ResponsiveTable"; + +export const ProvinceSegmentation = () => { + const [data, setData] = useState([]); + const [tableData, setTableData] = useState([]); + const [totalRows, setTotalRows] = useState(0); + const [perPage, setPerPage] = useState(10); + const [textValue, setTextValue] = useState(""); + const [page, setPage] = useState(1); + const [dashboardData, setDashboardData] = useState([]); + const [, , selectedDate1, setSelectedDate1, selectedDate2, setSelectedDate2] = + useContext(AppContext); + const dispatch = useDispatch(); + + // const userKey = useSelector((state) => state.userSlice.userProfile.key); + + const getDashboardData = () => { + dispatch( + stawardGetSegmentDashboardService({ + value: textValue, + date1: selectedDate1, + date2: selectedDate2, + role: getRoleFromUrl(), + }) + ).then((r) => { + setDashboardData(r.payload.data); + }); + }; + + useEffect(() => { + const currentDate = moment(new Date()).format("YYYY-MM-DD"); + setSelectedDate1(currentDate); + setSelectedDate2(currentDate); + }, []); + + const fetchApiData = async (page) => { + dispatch(LOADING_START()); + const response = await axios.get( + `kill-house-segmentation-info/?search=filter&value=${textValue}&date1=${selectedDate1}&date2=${selectedDate2}&page=${page}&page_size=${perPage}&role=${getRoleFromUrl()}` + ); + + getDashboardData(); + dispatch(LOADING_END()); + setData(response.data.results); + setTotalRows(response.data.count); + }; + + const handlePageChange = (page) => { + fetchApiData(page); + setPage(page); + }; + // const updateTable = () => { + // fetchApiData(page); + // }; + + const handlePerRowsChange = (perRows) => { + setPerPage(perRows); + setPage(1); + }; + + const handleTextChange = (event) => { + setTextValue(event.target.value); + }; + + useEffect(() => { + fetchApiData(1); + }, []); + + useEffect(() => { + const d = data?.map((item, i) => { + return [ + page === 1 ? i + 1 : i + perPage * (page - 1) + 1, + item?.name, + item?.info?.totalCount?.toLocaleString(), + item?.info?.totalWeight?.toLocaleString(), + item?.info?.totalSelfCount?.toLocaleString(), + item?.info?.totalSelfWeight?.toLocaleString(), + item?.info?.totalOtherCount?.toLocaleString(), + item?.info?.totalOtherWeight?.toLocaleString(), + ]; + }); + + setTableData(d); + }, [data]); + + useEffect(() => { + fetchApiData(1); + }, [selectedDate1, selectedDate2, perPage]); + + const handleSubmit = async (event) => { + event.preventDefault(); + dispatch(LOADING_START()); + try { + const response = await axios.get( + `kill-house-segmentation-info/?search=filter&value=${textValue}&date1=${selectedDate1}&date2=${selectedDate2}&page=${page}&role=${getRoleFromUrl()}` + ); + setData(response.data.results); + setTotalRows(response.data.count); + getDashboardData(); + dispatch(LOADING_END()); + } catch (error) { + console.error("Error fetching data:", error); + } + }; + + return ( + + + + + +
    + + + + + ( + + )} + value={selectedDate1} + onChange={(e) => + setSelectedDate1(moment(e).format("YYYY-MM-DD")) + } + /> + + + ( + + )} + value={selectedDate2} + onChange={(e) => + setSelectedDate2(moment(e).format("YYYY-MM-DD")) + } + /> + + {/* + + */} + +
    + + +
    +
    + ); +}; diff --git a/src/features/province/components/province-select-slaughter-for-slaughter/ProvinceSelectSlaughterForSlaughter.js b/src/features/province/components/province-select-slaughter-for-slaughter/ProvinceSelectSlaughterForSlaughter.js new file mode 100644 index 0000000..09e20aa --- /dev/null +++ b/src/features/province/components/province-select-slaughter-for-slaughter/ProvinceSelectSlaughterForSlaughter.js @@ -0,0 +1,78 @@ +import { MenuItem, Select } from "@mui/material"; +import { useContext, useState } from "react"; +import { useDispatch, useSelector } from "react-redux"; +import { Grid } from "../../../../components/grid/Grid"; +import { AppContext } from "../../../../contexts/AppContext"; +import { slaughterGetKillerKillhousesService } from "../../../slaughter-house/services/slaughter-get-killers-killhouses"; +import { provinceGetSlaughterhousesQuotaService } from "../../services/province-get-slaughterhouses-quota"; +import { provinceUpdateSlaughterKillplaceService } from "../../services/province-update-slaughter-killplace"; + +export const ProvinceSelectSlaughterForSlaughter = ({ + // onSlaughterChange, + killHouseForKiller, + slaughterKey, + disabled, +}) => { + const dispatch = useDispatch(); + const [openNotif] = useContext(AppContext); + const [selectedValue, setSelectedValue] = useState(killHouseForKiller?.key); + const { slaughterGetKillerKillhouses } = useSelector( + (state) => state.slaughterSlice + ); + + // console.log(killHouseForKiller, "uuuuu"); + + // useEffect(() => { + // setSelectedValue(killHouseForKiller?.key); + // }, []); + + const handleChange = (event) => { + dispatch( + provinceUpdateSlaughterKillplaceService({ + percentage_key: slaughterKey, + kill_house_key: event.target.value, + }) + ).then((r) => { + if (r.payload.error) { + openNotif({ + vertical: "top", + horizontal: "center", + msg: r.payload.error, + severity: "error", + }); + } else { + dispatch(provinceGetSlaughterhousesQuotaService()); + dispatch(slaughterGetKillerKillhousesService()); + openNotif({ + vertical: "top", + horizontal: "center", + msg: "عملیات با موفقیت انجام شد.", + severity: "success", + }); + } + }); + setSelectedValue(event.target.value); + }; + + return ( + + + + ); +}; diff --git a/src/features/province/components/province-send-letter-daily-slaughter/ProvinceSendLetterDailySlaughter.js b/src/features/province/components/province-send-letter-daily-slaughter/ProvinceSendLetterDailySlaughter.js new file mode 100644 index 0000000..c5f6593 --- /dev/null +++ b/src/features/province/components/province-send-letter-daily-slaughter/ProvinceSendLetterDailySlaughter.js @@ -0,0 +1,180 @@ +import React, { useContext } from "react"; +import { Button, TextField, Tooltip } from "@mui/material"; +import { Grid } from "../../../../components/grid/Grid"; +import { Yup } from "../../../../lib/yup/yup"; +import { useFormik } from "formik"; +import { DatePicker } from "@mui/x-date-pickers"; +import moment from "moment"; +import { AppContext } from "../../../../contexts/AppContext"; +import ProvinceSendLetterFactor from "../province-send-letter-factor/ProvinceSendLetterFactor"; +import { useReactToPrint } from "react-to-print"; +import { useRef } from "react"; +import { LineWithText } from "../../../../components/line-with-text/LineWithText"; +import { useEffect } from "react"; +import { provinceGetAllocationLetter } from "../../services/province-get-allocation-letter"; +import { useDispatch } from "react-redux"; +import { useState } from "react"; + +export const ProvinceSendLetterDailySlaughter = () => { + const [, , selectedDate1, setSelectedDate1, selectedDate2, setSelectedDate2] = + useContext(AppContext); + + useEffect(() => { + const currentDate = moment(new Date()).format("YYYY-MM-DD"); + setSelectedDate1(currentDate); + setSelectedDate2(currentDate); + }, []); + const componentRef = useRef(); + + const [factorData, setFactorData] = useState(null); + const dispatch = useDispatch(); + + const handleDownloadFactor = () => { + try { + const result = dispatch(provinceGetAllocationLetter(selectedDate1)); + setFactorData(result); + } catch (error) { + console.error(error); + } + }; + + const printPDF = useReactToPrint({ + content: () => componentRef.current, + documentTitle: "گزارش روزانه", + onAfterPrint: () => { + setFactorData(null); + }, + }); + + useEffect(() => { + if (factorData) { + printPDF(); + } + }, [factorData, printPDF]); + + const formik = useFormik({ + initialValues: { + receiver: "", + formNumber: "", + }, + validationSchema: Yup.object({ + receiver: Yup.string() + .required("این فیلد اجباری است!") + .typeError("لطفا مشخصات دریافت کننده را وارد کنید!"), + formNumber: Yup.string() + .required("این فیلد اجباری است!") + .typeError("لطفا عدد وارد کنید!"), + }), + }); + + useEffect(() => { + formik.validateForm(); + }, []); + + return ( + + + + + + + + + + + + + } + value={selectedDate1} + onChange={(e) => { + setSelectedDate1(moment(e).format("YYYY-MM-DD")); + }} + /> + + + } + value={selectedDate2} + onChange={(e) => { + setSelectedDate2(moment(e).format("YYYY-MM-DD")); + }} + /> + + + + + + + +
    + +
    +
    + ); +}; diff --git a/src/features/province/components/province-send-letter-declaration-need-factor/ProvinceSendLetterDeclarationNeedFactor.js b/src/features/province/components/province-send-letter-declaration-need-factor/ProvinceSendLetterDeclarationNeedFactor.js new file mode 100644 index 0000000..5c4e663 --- /dev/null +++ b/src/features/province/components/province-send-letter-declaration-need-factor/ProvinceSendLetterDeclarationNeedFactor.js @@ -0,0 +1,346 @@ +import React, { forwardRef } from "react"; +import logo from "../../../../assets/images/ChickenLogo.png"; +import { PropTypes } from "prop-types"; +import { formatJustDate } from "../../../../utils/formatTime"; +import { useCeoName } from "../../../../utils/getCeoName"; +import { useSystemName } from "../../../../utils/getSystemName"; + +const styles = { + page: { + width: "210mm", + margin: "0 auto", + display: "flex", + flexDirection: "column", + position: "relative", + direction: "rtl", + fontFamily: "nazanin", + fontWeight: "bold", + }, + container: { + width: "95%", + alignSelf: "center", + pageBreakInside: "avoid", + }, + p: { + fontFamily: "nazanin", + fontWeight: "bold", + pAlign: "justify", + }, + span: { + fontFamily: "nazanin", + fontWeight: "bold", + pAlign: "justify", + }, + invoiceTable: { + width: "100%", + borderCollapse: "collapse", + alignSelf: "center", + }, + tableCell: { + border: "1px solid #000", + pAlign: "left", + textAlign: "center", + fontSize: 11, + }, + tableCellMobile: { + border: "1px solid #000", + pAlign: "left", + textAlign: "center", + fontSize: 10, + }, + tableInnerCell: { + border: "1px solid #000", + pAlign: "left", + textAlign: "center", + fontSize: 8, + whiteSpace: "nowrap", + }, + tableHeader: { + pageBreakAfter: "auto", + }, + headerRow: { + color: "black", + pageBreakInside: "avoid", + pageBreakAfter: "auto", + }, + tableRowEven: { + backgroundColor: "rgba(170, 183, 255, 0.3)", + }, + logo: { + width: "60px", + height: "auto", + marginBottom: "10px", + }, + contentContainer: { + display: "flex", + justifyContent: "space-between", + marginTop: "20px", + marginLeft: "100px", + marginRight: "30px", + }, + contentInLine: { + display: "flex", + flexDirection: "column", + alignItems: "center", + }, + mainTitle: { + fontFamily: "nazanin", + fontSize: 11, + pAlign: "center", + fontWeight: "bolder", + }, + signature: { + display: "flex", + flexDirection: "column", + alignItems: "flex-end", + marginLeft: "20px", + }, + watermarkContainer: { + position: "fixed", + top: 450, + left: 0, + right: 30, + bottom: 0, + justifyContent: "center", + alignItems: "center", + opacity: 0.2, + zIndex: -1, + }, + watermarkp: { + fontSize: 100, + fontWeight: "bolder", + color: "grey", + transform: "rotate(-45deg)", + left: "50%", + }, + title: { + fontSize: 12, + fontWeight: "bolder", + pAlign: "center", + }, + titleTopic: { + marginTop: "10px", + fontSize: 12, + fontWeight: "bolder", + pAlign: "center", + }, + firsttitle: { + fontSize: 14, + fontWeight: "bolder", + marginLeft: "40px", + pAlign: "center", + }, + title2: { + fontSize: 10, + marginBottom: 10, + pAlign: "center", + }, + options: { + padding: "10px", + marginTop: "15px", + display: "flex", + flexDirection: "column", + alignItems: "flex-start", + }, + divider: { + width: "100%", + height: "2px", + backgroundColor: "red", + marginBottom: 15, + }, + pTitleContainer: { + pAlign: "right", + margin: "15px", + textAlign: "justify", + textJustify: "inter-word", + }, + tableHeaderCell: { + backgroundColor: "rgba(255, 229, 153, 0.5)", + fontSize: 10, + border: "1px solid #000", + padding: "4px", + textAlign: "center", + fontWeight: "bold", + }, + footer: { + pageBreakAfter: "always", + position: "fixed", + left: 0, + bottom: 0, + width: "100%", + }, +}; + +const ProvinceSendLetterDeclarationNeedFactor = forwardRef((props, ref) => { + const { sDate } = props; + const { date } = props; + const { fnumber } = props; + const { receiver } = props; + const { item } = props; + const systemName = useSystemName(); + const ceoName = useCeoName(); + + const totalCapacity = item?.reduce( + (total, currentItem) => total + (currentItem?.quantity || 0), + 0 + ); + + function getItemInfoWeight(item) { + let totalQuantity = 0; + item?.forEach((option) => { + if (option?.hatching?.totalWeight) { + if (option?.hatching?.totalWeight !== undefined) { + totalQuantity += option?.hatching?.totalWeight; + } + } + }); + return totalQuantity; + } + + const getItemState = (item) => { + let sellType = ""; + if (item?.directBuying) { + sellType = "خرید مستقیم"; + } else if (item?.union) { + sellType = "خرید خارج از استان"; + } else { + sellType = "اتحادیه"; + } + return sellType; + }; + + return ( +
    +
    +
    + logo + + اتحادیه سراسری تعاونی‌های کشاورزی پرورش دهندگان مرغ گوشتی ایران + + + اتحادیه شرکت های تعاونی کشاورزی مرغداران {" ‌"} {systemName} + +
    + +
    + بسمه تعالی +
    + +
    + شماره: {fnumber} + تاریخ: {formatJustDate(date)} + پیوست: +
    +
    + +
    + +

    + + {receiver} +
    + با سلام +
    +
    +
    + احتراما گزارش درخواست کشتار مرغداران مرغ گوشتی استان مورخ{" "} + {formatJustDate(sDate)}، به حضورتان ارسال میگردد. +

    + +
    +

    + اطلاعات درخواست:{" "} + + {" "} + تعداد درخواست کشتار ( + {totalCapacity !== undefined && totalCapacity.toLocaleString()}{" "} + قطعه)، وزن کل تقریبی ({getItemInfoWeight(item).toLocaleString()}{" "} + کیلوگرم). + +

    + + + + + + + + + + + + + + + + + + + {item?.map((item, i) => ( + + + + + + + + + + + + + + ))} + +
    ردیفکد سفارشنوع فروشتاریخ کشتارمرغدارشهر/تعاونیسن مرغمیانگین وزنوزن تقریبیمانده در سالنتعداد درخواست کشتار
    {i + 1}{item.orderCode}{getItemState(item)} + {formatJustDate(item?.sendDate)} + {`${item?.poultry?.unitName} (${item?.poultry?.user?.mobile})`}{`${ + item?.poultry?.address?.city?.name + }/${ + item?.poultry?.cityOperator + ? item?.poultry?.cityOperator + : "بدون تعاونی" + }`}{item?.hatching?.age}{item?.IndexWeight} + {item?.hatching?.totalWeight?.toLocaleString()} + + {item?.hatching?.leftOver?.toLocaleString()} + + {item?.firstQuantity?.toLocaleString()} +
    +
    + +
    +
    +
    + {ceoName} + + مدیرعامل اتحادیه مرغداران{" ‌"} + {systemName} + +
    +
    +
    +

    سامانه رصدیار

    +
    +
    + + {/*
    +
    +

    + {getAddressContent(systemName)} +

    +
    */} +
    + ); +}); + +ProvinceSendLetterDeclarationNeedFactor.displayName = + "ProvinceSendLetterDeclarationNeedFactor"; + +export default ProvinceSendLetterDeclarationNeedFactor; + +ProvinceSendLetterDeclarationNeedFactor.propTypes = { + item: PropTypes.any, +}; diff --git a/src/features/province/components/province-send-letter-declaration-need/ProvinceSendLetterDeclarationNeed.js b/src/features/province/components/province-send-letter-declaration-need/ProvinceSendLetterDeclarationNeed.js new file mode 100644 index 0000000..8de7c41 --- /dev/null +++ b/src/features/province/components/province-send-letter-declaration-need/ProvinceSendLetterDeclarationNeed.js @@ -0,0 +1,183 @@ +import React, { useContext } from "react"; +import { Button, TextField, Tooltip } from "@mui/material"; +import { Grid } from "../../../../components/grid/Grid"; +import { Yup } from "../../../../lib/yup/yup"; +import { useFormik } from "formik"; +import { DatePicker } from "@mui/x-date-pickers"; +import moment from "moment"; +import { AppContext } from "../../../../contexts/AppContext"; +import { useReactToPrint } from "react-to-print"; +import { useRef } from "react"; +import { LineWithText } from "../../../../components/line-with-text/LineWithText"; +import { useEffect } from "react"; +import { useState } from "react"; +import ProvinceSendLetterDeclarationNeedFactor from "../province-send-letter-declaration-need-factor/ProvinceSendLetterDeclarationNeedFactor"; +import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl"; +import axios from "axios"; +import { useDispatch } from "react-redux"; +import { + LOADING_END, + LOADING_START, +} from "../../../../lib/redux/slices/appSlice"; + +export const ProvinceSendLetterDeclarationNeed = () => { + const [, , selectedDate1, setSelectedDate1, selectedDate2, setSelectedDate2] = + useContext(AppContext); + const componentRef = useRef(); + + const [factorData, setFactorData] = useState(null); + const dispatch = useDispatch(); + + const handleDownloadFactor = async () => { + try { + dispatch(LOADING_START()); + let response = await axios.get( + `Poultry_Request/?role=${getRoleFromUrl()}&today&date1=${selectedDate1}&date2=${selectedDate1}&search=filter&value=${""}&page=1&page_size=1000` + ); + dispatch(LOADING_END()); + setFactorData(response.data.results); + } catch (error) { + console.error(error); + } + }; + + const printPDF = useReactToPrint({ + content: () => componentRef.current, + documentTitle: "گزارش اعلام کشتار مرغ", + onAfterPrint: () => { + setFactorData(null); + }, + }); + + useEffect(() => { + if (factorData) { + printPDF(); + } + }, [factorData, printPDF]); + + const formik = useFormik({ + initialValues: { + receiver: "", + formNumber: "", + }, + validationSchema: Yup.object({ + receiver: Yup.string() + .required("این فیلد اجباری است!") + .typeError("لطفا مشخصات دریافت کننده را وارد کنید!"), + formNumber: Yup.string() + .required("این فیلد اجباری است!") + .typeError("لطفا عدد وارد کنید!"), + }), + }); + + useEffect(() => { + formik.validateForm(); + }, []); + + return ( + + + + + + + + + + + + + } + value={selectedDate1} + onChange={(e) => { + setSelectedDate1(moment(e).format("YYYY-MM-DD")); + }} + /> + + + } + value={selectedDate2} + onChange={(e) => { + setSelectedDate2(moment(e).format("YYYY-MM-DD")); + }} + /> + + + + + + + +
    + +
    +
    + ); +}; diff --git a/src/features/province/components/province-send-letter-factor-report/ProvinceSendLetterFactorReport.js b/src/features/province/components/province-send-letter-factor-report/ProvinceSendLetterFactorReport.js new file mode 100644 index 0000000..8bd02a3 --- /dev/null +++ b/src/features/province/components/province-send-letter-factor-report/ProvinceSendLetterFactorReport.js @@ -0,0 +1,405 @@ +import React, { forwardRef } from "react"; +import logo from "../../../../assets/images/ChickenLogo.png"; +import { useSystemName } from "../../../../utils/getSystemName"; +import { PropTypes } from "prop-types"; +import { formatJustDate, formatJustTime } from "../../../../utils/formatTime"; +import { useCeoName } from "../../../../utils/getCeoName"; + +const styles = { + page: { + width: "210mm", + height: "297mm", + display: "flex", + margin: "0 auto", + flexDirection: "column", + position: "relative", + direction: "rtl", + fontFamily: "nazanin", + fontWeight: "bold", + }, + container: { + width: "95%", + alignSelf: "center", + pageBreakInside: "avoid", + }, + p: { + fontFamily: "nazanin", + fontWeight: "bold", + pAlign: "justify", + }, + span: { + fontFamily: "nazanin", + fontWeight: "bold", + pAlign: "justify", + }, + invoiceTable: { + width: "100%", + borderCollapse: "collapse", + alignSelf: "center", + }, + tableCell: { + border: "1px solid #000", + pAlign: "left", + textAlign: "center", + fontSize: 12, + }, + tableCellMobile: { + border: "1px solid #000", + pAlign: "left", + textAlign: "center", + fontSize: 10, + }, + tableInnerCell: { + border: "1px solid #000", + pAlign: "left", + textAlign: "center", + fontSize: 8, + whiteSpace: "nowrap", + }, + tableHeader: { + pageBreakAfter: "auto", + }, + headerRow: { + color: "black", + pageBreakInside: "avoid", + pageBreakAfter: "auto", + }, + tableRowEven: { + backgroundColor: "rgba(170, 183, 255, 0.3)", + }, + logo: { + width: "60px", + height: "auto", + marginBottom: "10px", + }, + contentContainer: { + display: "flex", + justifyContent: "space-between", + marginTop: "20px", + marginLeft: "100px", + marginRight: "30px", + }, + contentInLine: { + display: "flex", + flexDirection: "column", + alignItems: "center", + }, + mainTitle: { + fontFamily: "nazanin", + fontSize: 11, + pAlign: "center", + fontWeight: "bolder", + }, + signature: { + display: "flex", + flexDirection: "column", + alignItems: "flex-end", + marginLeft: "20px", + }, + watermarkContainer: { + position: "fixed", + top: 450, + left: 0, + right: 30, + bottom: 0, + justifyContent: "center", + alignItems: "center", + opacity: 0.2, + zIndex: -1, + }, + watermarkp: { + fontSize: 100, + fontWeight: "bolder", + color: "grey", + transform: "rotate(-45deg)", + left: "50%", + }, + title: { + fontSize: 12, + fontWeight: "bolder", + pAlign: "center", + }, + titleTopic: { + marginTop: "10px", + fontSize: 12, + fontWeight: "bolder", + pAlign: "center", + }, + firsttitle: { + fontSize: 14, + fontWeight: "bolder", + marginLeft: "40px", + pAlign: "center", + }, + title2: { + fontSize: 10, + marginBottom: 10, + pAlign: "center", + }, + options: { + padding: "10px", + marginTop: "15px", + display: "flex", + flexDirection: "column", + alignItems: "flex-start", + }, + divider: { + width: "100%", + height: "2px", + backgroundColor: "red", + marginBottom: 5, + }, + pTitleContainer: { + pAlign: "right", + margin: "15px", + textAlign: "justify", + textJustify: "inter-word", + }, + tableHeaderCell: { + backgroundColor: "rgba(255, 229, 153, 0.5)", + fontSize: 12, + border: "1px solid #000", + padding: "4px", + textAlign: "center", + fontWeight: "bold", + }, + footer: { + pageBreakAfter: "always", + position: "fixed", + left: 0, + bottom: 0, + width: "100%", + }, +}; + +const ProvinceSendLetterFactorReport = forwardRef((props, ref) => { + const { sDate } = props; + const { date } = props; + const { fnumber } = props; + const { receiver } = props; + const { item } = props; + const { itemOutProvince } = props; + const systemName = useSystemName(); + const ceoName = useCeoName(); + + return ( +
    +
    +
    +
    + logo + + اتحادیه سراسری تعاونی‌های کشاورزی پرورش دهندگان مرغ گوشتی ایران + + + اتحادیه شرکت های تعاونی کشاورزی مرغداران {" ‌"} {systemName} + +
    + +
    + بسمه تعالی +
    + +
    + شماره: {fnumber} + تاریخ: {formatJustDate(date)} + پیوست: - +
    +
    + +
    + +

    + + {receiver} +
    + با سلام +
    +
    + احتراماً گزارش تخصیص مورخ {formatJustDate(sDate)}، مرغ گوشتی استان جهت + استحضار بحضورتان ارسال میگردد. +

    + +
    + + + + + + + + + + + + + + + + {item?.map((item, i) => + item?.provinceKillRequest?.map((pkRequest, pkIndex) => ( + + {pkIndex === 0 && ( + <> + + + + + + )} + + + + + {pkIndex === 0 && ( + + )} + + )) + )} + +
    ردیفنام خریدارتلفنشهرمرغدارتلفنتعدادمیانگین وزنجمع کل
    + {i + 1} + + {item?.name} + + {item?.killHouseOperator?.user?.mobile} + + {item?.killHouseOperator?.user?.city?.cityName} + {pkRequest?.poultry}{pkRequest?.poultryMobile}{pkRequest?.quantity}{pkRequest?.IndexWeight} + {item?.totalQuantity} +
    +
    + + {/*
    +
    +

    + {getAddressContent(systemName)} +

    +
    */} +
    +
    +
    +
    + logo + + اتحادیه سراسری تعاونی‌های کشاورزی پرورش دهندگان مرغ گوشتی ایران + + + اتحادیه شرکت های تعاونی کشاورزی مرغداران {" ‌"} {systemName} + +
    + +
    + بسمه تعالی +
    + +
    + شماره: {fnumber} + تاریخ: {formatJustDate(date)} + پیوست: - +
    +
    + +
    + +

    + + گزارش فروش خارج از استان مورخ {formatJustDate(sDate)} + +

    + +
    + + + + + + + + + + + + + + + {itemOutProvince?.map((item, i) => ( + + + + + + + + + + + ))} + +
    ردیفنام مرغدارنام خریدارتلفنشهرمیانگین وزنتعداد کلنوع
    {i + 1} + {item?.poultry?.unitName} ({item?.poultry?.user?.mobile}) + + {item?.buyer?.firstName} {item?.buyer?.lastName} + {item?.buyer?.mobile}{item?.buyer?.city}{item?.IndexWeight}{item?.quantity} + {item?.freezing ? "انجماد" : "معمولی"} +
    +
    +
    + + این گزارش در تاریخ {formatJustDate(date)} و ساعت{" "} + {formatJustTime(date)} صادر شده است. + +
    + +
    +
    +
    + {ceoName} + + مدیرعامل اتحادیه مرغداران{" ‌"} + {systemName} + +
    +
    +
    +

    سامانه رصدیار

    +
    +
    + + {/*
    +
    +

    + {getAddressContent(systemName)} +

    +
    */} +
    +
    + ); +}); + +ProvinceSendLetterFactorReport.displayName = "ProvinceSendLetterFactorReport"; + +export default ProvinceSendLetterFactorReport; + +ProvinceSendLetterFactorReport.propTypes = { + item: PropTypes.any, +}; diff --git a/src/features/province/components/province-send-letter-factor/ProvinceSendLetterFactor.js b/src/features/province/components/province-send-letter-factor/ProvinceSendLetterFactor.js new file mode 100644 index 0000000..72e0658 --- /dev/null +++ b/src/features/province/components/province-send-letter-factor/ProvinceSendLetterFactor.js @@ -0,0 +1,392 @@ +import React, { forwardRef } from "react"; +import logo from "../../../../assets/images/ChickenLogo.png"; +import { useSystemName } from "../../../../utils/getSystemName"; +import { PropTypes } from "prop-types"; +import { formatJustDate } from "../../../../utils/formatTime"; +import { useCeoName } from "../../../../utils/getCeoName"; + +const styles = { + page: { + width: "210mm", + margin: "0 auto", + display: "flex", + flexDirection: "column", + position: "relative", + direction: "rtl", + fontFamily: "nazanin", + fontWeight: "bold", + }, + container: { + width: "95%", + alignSelf: "center", + pageBreakInside: "avoid", + }, + p: { + fontFamily: "nazanin", + fontWeight: "bold", + pAlign: "justify", + }, + span: { + fontFamily: "nazanin", + fontWeight: "bold", + pAlign: "justify", + }, + invoiceTable: { + width: "100%", + borderCollapse: "collapse", + alignSelf: "center", + }, + tableCell: { + border: "1px solid #000", + pAlign: "left", + textAlign: "center", + fontSize: 11, + }, + tableCellMobile: { + border: "1px solid #000", + pAlign: "left", + textAlign: "center", + fontSize: 10, + }, + tableInnerCell: { + border: "1px solid #000", + pAlign: "left", + textAlign: "center", + fontSize: 8, + whiteSpace: "nowrap", + }, + tableHeader: { + pageBreakAfter: "auto", + }, + headerRow: { + color: "black", + pageBreakInside: "avoid", + pageBreakAfter: "auto", + }, + tableRowEven: { + backgroundColor: "rgba(170, 183, 255, 0.3)", + }, + logo: { + width: "60px", + height: "auto", + marginBottom: "10px", + }, + contentContainer: { + display: "flex", + justifyContent: "space-between", + marginTop: "20px", + marginLeft: "100px", + marginRight: "30px", + }, + contentInLine: { + display: "flex", + flexDirection: "column", + alignItems: "center", + }, + mainTitle: { + fontFamily: "nazanin", + fontSize: 11, + pAlign: "center", + fontWeight: "bolder", + }, + signature: { + display: "flex", + flexDirection: "column", + alignItems: "flex-end", + marginLeft: "20px", + }, + watermarkContainer: { + position: "fixed", + top: 450, + left: 0, + right: 30, + bottom: 0, + justifyContent: "center", + alignItems: "center", + opacity: 0.2, + zIndex: -1, + }, + watermarkp: { + fontSize: 100, + fontWeight: "bolder", + color: "grey", + transform: "rotate(-45deg)", + left: "50%", + }, + title: { + fontSize: 12, + fontWeight: "bolder", + pAlign: "center", + }, + titleTopic: { + marginTop: "10px", + fontSize: 12, + fontWeight: "bolder", + pAlign: "center", + }, + firsttitle: { + fontSize: 14, + fontWeight: "bolder", + marginLeft: "40px", + pAlign: "center", + }, + title2: { + fontSize: 10, + marginBottom: 10, + pAlign: "center", + }, + options: { + padding: "10px", + marginTop: "15px", + display: "flex", + flexDirection: "column", + alignItems: "flex-start", + }, + divider: { + width: "100%", + height: "2px", + backgroundColor: "red", + marginBottom: 15, + }, + pTitleContainer: { + pAlign: "right", + margin: "15px", + textAlign: "justify", + textJustify: "inter-word", + }, + tableHeaderCell: { + backgroundColor: "rgba(255, 229, 153, 0.5)", + fontSize: 10, + border: "1px solid #000", + padding: "4px", + textAlign: "center", + fontWeight: "bold", + }, + footer: { + pageBreakAfter: "always", + position: "fixed", + left: 0, + bottom: 0, + width: "100%", + }, +}; + +const ProvinceSendLetterFactor = forwardRef((props, ref) => { + const { sDate } = props; + const { date } = props; + const { fnumber } = props; + const { receiver } = props; + const { item } = props; + const systemName = useSystemName(); + const ceoName = useCeoName(); + + const totalCapacity = item?.reduce( + (total, currentItem) => total + (currentItem?.quantity || 0), + 0 + ); + + function getItemInfoQuantity(item) { + let totalQuantity = 0; + item?.forEach((option) => { + if (option?.provinceKillRequests) { + option.provinceKillRequests.forEach((request) => { + if (request.info?.quantity !== undefined) { + totalQuantity += request.info.quantity; + } + }); + } + }); + return totalQuantity; + } + + function getItemInfoWeight(item) { + let totalQuantity = 0; + item?.forEach((option) => { + if (option?.provinceKillRequests) { + option.provinceKillRequests.forEach((request) => { + if (request.info?.weight !== undefined) { + totalQuantity += request.info.weight; + } + }); + } + }); + return totalQuantity; + } + + return ( +
    +
    +
    + logo + + اتحادیه سراسری تعاونی‌های کشاورزی پرورش دهندگان مرغ گوشتی ایران + + + اتحادیه شرکت های تعاونی کشاورزی مرغداران {" ‌"} {systemName} + +
    + +
    + بسمه تعالی +
    + +
    + شماره: {fnumber} + تاریخ: {formatJustDate(date)} + پیوست: +
    +
    + +
    + +

    + + {receiver} +
    + با سلام +
    +
    +
    + احتراماً گزارش تخصیص و کشتار مورخ {formatJustDate(sDate)}، مرغ گوشتی + استان جهت استحضار بحضورتان ارسال میگردد. +

    + +
    +

    + اطلاعات تخصیص:{" "} + + {" "} + تعداد درخواست کشتار ( + {totalCapacity !== undefined && totalCapacity.toLocaleString()}{" "} + قطعه)، تخصیص داده شده ({getItemInfoQuantity(item).toLocaleString()}{" "} + قطعه)، وزن کل تخصیص ({" "} + {Math.round(getItemInfoWeight(item)).toLocaleString()} کیلوگرم). + +

    + + + + + + + + + + + + + + + + + + + {item?.map((item, i) => ( + + + + + + + + + + + + + + ))} + +
    ردیفمرغدارتلفنشهرتعدادمیانگین وزنیسنخریدارتعدادوزن تقریبی بارمحل کشتار
    {i + 1} + {item?.poultry?.user?.fullname} + + {item?.poultry?.user?.mobile} + + {item?.poultry?.address?.city?.name} + + {item?.quantity.toLocaleString()} + + {item?.IndexWeight.toLocaleString()} + {item?.hatching?.age} + {item?.provinceKillRequests?.map((item, i, array) => ( + <> + {item?.killhouseUser?.killHouseOperator?.user?.fullname + ? item?.killhouseUser?.killHouseOperator?.user?.fullname + : "............"} +
    + {i < array.length - 1 && ( +
    + )} + + ))} +
    + {item?.provinceKillRequests?.map((item, i, array) => ( + <> + {item?.info?.quantity + ? item?.info?.quantity.toLocaleString() + : "............"} +
    + {i < array.length - 1 && ( +
    + )} + + ))} +
    + {item?.provinceKillRequests?.map((item, i, array) => ( + <> + {Math.round(item?.info?.weight) + ? Math.round(item?.info?.weight).toLocaleString() + : "............"} +
    + {i < array.length - 1 && ( +
    + )} + + ))} +
    + {item?.provinceKillRequests?.map((item, i, array) => ( + <> + {item?.info?.killPlace + ? item?.info?.killPlace + : "............"} +
    + {i < array.length - 1 && ( +
    + )} + + ))} +
    +
    + +
    +
    +
    + {ceoName} + + مدیرعامل اتحادیه مرغداران{" ‌"} + {systemName} + +
    +
    +
    +

    سامانه رصدیار

    +
    +
    + + {/*
    +
    +

    + {getAddressContent(systemName)} +

    +
    */} +
    + ); +}); + +ProvinceSendLetterFactor.displayName = "ProvinceSendLetterFactor"; + +export default ProvinceSendLetterFactor; + +ProvinceSendLetterFactor.propTypes = { + item: PropTypes.any, +}; diff --git a/src/features/province/components/province-send-letter-transfer-slaughter/ProvinceSendLetterTransferSlaughter.js b/src/features/province/components/province-send-letter-transfer-slaughter/ProvinceSendLetterTransferSlaughter.js new file mode 100644 index 0000000..c1c313b --- /dev/null +++ b/src/features/province/components/province-send-letter-transfer-slaughter/ProvinceSendLetterTransferSlaughter.js @@ -0,0 +1,256 @@ +import React, { useContext } from "react"; +import { Autocomplete, Button, TextField, Tooltip } from "@mui/material"; +import { Grid } from "../../../../components/grid/Grid"; +import { Yup } from "../../../../lib/yup/yup"; +import { useFormik } from "formik"; +import { DatePicker } from "@mui/x-date-pickers"; +import moment from "moment"; +import { AppContext } from "../../../../contexts/AppContext"; +import { useReactToPrint } from "react-to-print"; +import { useRef } from "react"; +import { LineWithText } from "../../../../components/line-with-text/LineWithText"; +import { useEffect } from "react"; +import { useDispatch } from "react-redux"; +import { useState } from "react"; +import { provinceGetSlaughterLetter } from "../../services/province-get-slaughter-letter"; +import { provinceGetQuarantineLetter } from "../../services/province-get-quarantine-letter"; +import ProvinceQuarantineInvoice from "../province-quarantine-invoice/ProvinceQuarantineInvoice"; +import { NumberInput } from "../../../../components/number-format-custom/NumberFormatCustom"; + +export const ProvinceSendLetterTransferSlaughter = () => { + const [, , selectedDate1, setSelectedDate1, selectedDate2, setSelectedDate2] = + useContext(AppContext); + const componentRef = useRef(); + const [options, setOptions] = useState(""); + const [selectedOption, setSelectedOption] = useState(null); + + const [factorData, setFactorData] = useState(null); + const dispatch = useDispatch(); + + const handleDownloadFactor = () => { + const result = dispatch( + provinceGetQuarantineLetter(formik2.values.userInfoCheck) + ); + setFactorData(result); + }; + + const printPDF = useReactToPrint({ + content: () => componentRef.current, + documentTitle: "فاکتور قرنطینه", + onAfterPrint: () => { + setFactorData(null); + }, + }); + + useEffect(() => { + if (factorData) { + printPDF(); + } + }, [factorData, printPDF]); + + const formik = useFormik({ + initialValues: { + receiver: "", + formNumber: "", + price: "", + }, + validationSchema: Yup.object({ + receiver: Yup.string() + .required("این فیلد اجباری است!") + .typeError("لطفا مشخصات دریافت کننده را وارد کنید!"), + formNumber: Yup.string() + .required("این فیلد اجباری است!") + .typeError("لطفا عدد وارد کنید!"), + price: Yup.string() + .required("این فیلد اجباری است!") + .typeError("لطفا عدد وارد کنید!"), + }), + }); + + const formik2 = useFormik({ + initialValues: { + userInfoCheck: "", + }, + validationSchema: Yup.object({ + userInfoCheck: Yup.string() + .required("این فیلد اجباری است!") + .typeError("لطفا فیلد را به درستی وارد کنید!"), + }), + }); + + useEffect(() => { + formik.validateForm(); + formik2.validateForm(); + }, []); + + useEffect(() => { + dispatch(provinceGetSlaughterLetter(selectedDate1)).then((r) => { + setOptions(r.payload.data); + setSelectedOption(null); + }); + }, [selectedDate1]); + + return ( + + + + + + + } + value={selectedDate1} + onChange={(e) => { + setSelectedDate1(moment(e).format("YYYY-MM-DD")); + }} + /> + + + + { + return option.disabled <= 0; + }} + options={ + options + ? options?.map((i) => ({ + id: i.orderCode, + label: i?.poultry?.unitName + ` (${i.poultry?.user?.mobile})`, + })) + : [] + } + getOptionLabel={(option) => option.label} + value={selectedOption} + onChange={(event, newValue) => { + setSelectedOption(newValue); + formik2.setFieldValue("userInfoCheck", newValue ? newValue.id : ""); + }} + onBlur={formik2.handleBlur} + renderInput={(params) => ( + + )} + /> + + + + + + + + } + value={selectedDate2} + onChange={(e) => { + setSelectedDate2(moment(e).format("YYYY-MM-DD")); + }} + /> + + + + + + + + + + + + + + + + +
    + +
    +
    + ); +}; diff --git a/src/features/province/components/province-send-letter/ProvinceSendLetter.js b/src/features/province/components/province-send-letter/ProvinceSendLetter.js new file mode 100644 index 0000000..877fd10 --- /dev/null +++ b/src/features/province/components/province-send-letter/ProvinceSendLetter.js @@ -0,0 +1,38 @@ +import React, { useState } from "react"; +import { Tab, Tabs } from "@mui/material"; +import { Grid } from "../../../../components/grid/Grid"; + +import { ProvinceSendLetterDailySlaughter } from "../province-send-letter-daily-slaughter/ProvinceSendLetterDailySlaughter"; +import { ProvinceSendLetterTransferSlaughter } from "../province-send-letter-transfer-slaughter/ProvinceSendLetterTransferSlaughter"; +import { ProvinceSendLetterDeclarationNeed } from "../province-send-letter-declaration-need/ProvinceSendLetterDeclarationNeed"; + +export const ProvinceSendLetter = () => { + const [tabValue, setTabValue] = useState("1"); + + const handleTabChange = (event, newValue) => { + setTabValue(newValue); + }; + + return ( + + + + + + + + + + {tabValue === "1" && } + {tabValue === "2" && } + {tabValue === "3" && } + + + ); +}; diff --git a/src/features/province/components/province-send-report-new-report/ProvinceSendReportNewReport.js b/src/features/province/components/province-send-report-new-report/ProvinceSendReportNewReport.js new file mode 100644 index 0000000..7456478 --- /dev/null +++ b/src/features/province/components/province-send-report-new-report/ProvinceSendReportNewReport.js @@ -0,0 +1,91 @@ +import React, { useContext, useEffect, useState } from "react"; +import { Grid } from "../../../../components/grid/Grid"; +import { + Button, + FormControl, + InputLabel, + MenuItem, + Select, +} from "@mui/material"; +import { + provinceSendReportGetReports, + provinceSendReportSubmitReport, +} from "../../services/province-send-report-get-times"; +import { useDispatch } from "react-redux"; +import { AppContext } from "../../../../contexts/AppContext"; +import { CLOSE_MODAL } from "../../../../lib/redux/slices/appSlice"; + +export const ProvinceSendReportNewReport = ({ fetchApiData }) => { + const [report, setReport] = useState([]); + const [allReports, setAllReports] = useState(); + + const [openNotif] = useContext(AppContext); + + const dispatch = useDispatch(); + + const handleChangeReport = (event) => { + const { + target: { value }, + } = event; + setReport(typeof value === "string" ? value.split(",") : value); + }; + + useEffect(() => { + dispatch(provinceSendReportGetReports()).then((r) => { + setAllReports(r.payload.data); + }); + }, [dispatch]); + + return ( + + + گزارش + + + + + ); +}; diff --git a/src/features/province/components/province-send-report-new-user/ProvinceSendReportNewUser.js b/src/features/province/components/province-send-report-new-user/ProvinceSendReportNewUser.js new file mode 100644 index 0000000..2dabf36 --- /dev/null +++ b/src/features/province/components/province-send-report-new-user/ProvinceSendReportNewUser.js @@ -0,0 +1,197 @@ +import React, { useContext } from "react"; +import { + Grid, + TextField, + Button, + FormControl, + InputLabel, + Select, + MenuItem, +} from "@mui/material"; +import { useFormik } from "formik"; +import * as Yup from "yup"; +import { useDispatch } from "react-redux"; +import { + provinceSendReportEditUser, + provinceSendReportNewUser, +} from "../../services/province-send-report-new-user"; +import { AppContext } from "../../../../contexts/AppContext"; +import { CLOSE_MODAL } from "../../../../lib/redux/slices/appSlice"; +import { getRoleList } from "../../../../utils/getRoleList"; + +export const ProvinceSendReportNewUser = ({ fetchApiData, isEdit, item }) => { + const dispatch = useDispatch(); + const [openNotif] = useContext(AppContext); + + const validationSchema = Yup.object({ + firstname: Yup.string().required("این فیلد اجباری است"), + lastname: Yup.string().required("این فیلد اجباری است"), + mobile: Yup.number() + .required("این فیلد اجباری است!") + .typeError("لطفا اعداد انگلیسی وارد کنید!") + .test("len", "شماره تلفن باید 11 رقم باشد!", (val, context) => { + return context.originalValue && context.originalValue.length === 11; + }), + post: Yup.string().required("این فیلد اجباری است"), + city: Yup.string().required("این فیلد اجباری است"), + }); + + const formik = useFormik({ + initialValues: { + firstname: item?.firstname ? item?.firstname : "", + lastname: item?.lastname ? item?.lastname : "", + mobile: item?.mobile ? item?.mobile : "", + post: item?.position ? item?.position : "", + city: item?.city ? item?.city : "", + }, + validationSchema: validationSchema, + onSubmit: (values) => { + if (isEdit) { + dispatch( + provinceSendReportEditUser({ + user_key: item?.key, + firstname: values.firstname, + lastname: values.lastname, + mobile: values.mobile, + position: values.post, + city: values.city, + }) + ).then((r) => { + if (r.payload.error) { + openNotif({ + vertical: "top", + horizontal: "center", + msg: r.payload.error, + severity: "error", + }); + } else { + openNotif({ + vertical: "top", + horizontal: "center", + msg: "عملیات با موفقیت انجام شد.", + severity: "success", + }); + dispatch(CLOSE_MODAL()); + fetchApiData(1); + } + }); + } else { + dispatch( + provinceSendReportNewUser({ + firstname: values.firstname, + lastname: values.lastname, + mobile: values.mobile, + position: values.post, + city: values.city, + }) + ).then((r) => { + if (r.payload.error) { + openNotif({ + vertical: "top", + horizontal: "center", + msg: r.payload.error, + severity: "error", + }); + } else { + openNotif({ + vertical: "top", + horizontal: "center", + msg: "عملیات با موفقیت انجام شد.", + severity: "success", + }); + dispatch(CLOSE_MODAL()); + fetchApiData(1); + } + }); + } + }, + }); + + const handleChangePosition = (e) => { + formik.setFieldValue("post", e.target.value); + }; + + return ( + + + + + + + + + سمت + + + + + + ); +}; diff --git a/src/features/province/components/province-send-report-operations/ProvinceSendReportOperations.js b/src/features/province/components/province-send-report-operations/ProvinceSendReportOperations.js new file mode 100644 index 0000000..c35c2e6 --- /dev/null +++ b/src/features/province/components/province-send-report-operations/ProvinceSendReportOperations.js @@ -0,0 +1,156 @@ +import React, { useContext, useState } from "react"; +import { + Button, + FormControlLabel, + IconButton, + Popover, + Switch, +} from "@mui/material"; +import TuneIcon from "@mui/icons-material/Tune"; +// import CancelIcon from "@mui/icons-material/Delete"; +// import EditIcon from "@mui/icons-material/Edit"; +import { Grid } from "../../../../components/grid/Grid"; +import { useDispatch } from "react-redux"; +import { ProvinceSendReportNewUser } from "../province-send-report-new-user/ProvinceSendReportNewUser"; +import { OPEN_MODAL } from "../../../../lib/redux/slices/appSlice"; +import { + provinceSendReportDeleteUser, + provinceSendReportEditUser, +} from "../../services/province-send-report-new-user"; +import { AppContext } from "../../../../contexts/AppContext"; + +export const ProvinceSendReportOperations = ({ item, fetchApiData }) => { + const [anchorEl, setAnchorEl] = useState(null); + const [openNotif] = useContext(AppContext); + + const dispatch = useDispatch(); + const handleClick = (event) => { + setAnchorEl(event.currentTarget); + }; + + const handleClose = () => { + setAnchorEl(null); + }; + + const open = Boolean(anchorEl); + const id = open ? "popover" : undefined; + + return ( + + + + + + + + + + { + dispatch( + provinceSendReportEditUser({ + user_key: item?.key, + active: !item?.active, + }) + ).then((r) => { + if (r.payload.error) { + openNotif({ + vertical: "top", + horizontal: "center", + msg: r.payload.error, + severity: "error", + }); + } else { + openNotif({ + vertical: "top", + horizontal: "center", + msg: "عملیات با موفقیت انجام شد.", + severity: "success", + }); + fetchApiData(1); + } + }); + }} + /> + } + label={item?.active ? "فعال" : "غیر فعال"} + /> + + + + ); +}; diff --git a/src/features/province/components/province-send-report-send-time/ProvinceSendReportSendTime.js b/src/features/province/components/province-send-report-send-time/ProvinceSendReportSendTime.js new file mode 100644 index 0000000..2f48052 --- /dev/null +++ b/src/features/province/components/province-send-report-send-time/ProvinceSendReportSendTime.js @@ -0,0 +1,121 @@ +import React, { useContext, useEffect, useState } from "react"; +import { useDispatch } from "react-redux"; +import { + provinceSendReportGetTimes, + provinceSendReportUpdateSendTime, +} from "../../services/province-send-report-get-times"; +import { Grid } from "../../../../components/grid/Grid"; +import { + Button, + FormControl, + InputLabel, + MenuItem, + Select, +} from "@mui/material"; +import { AppContext } from "../../../../contexts/AppContext"; +import { CLOSE_MODAL } from "../../../../lib/redux/slices/appSlice"; + +export const ProvinceSendReportSendTime = ({ fetchApiData }) => { + const [openNotif] = useContext(AppContext); + const dispatch = useDispatch(); + const [time, setTime] = useState(12); + const [delay, setDelay] = useState("روزانه"); + + useEffect(() => { + dispatch(provinceSendReportGetTimes()).then((r) => { + setTime(r.payload?.data?.hour); + setDelay(r?.payload?.data?.type); + }); + }, []); + + const handleChangeTime = (e) => { + setTime(e.target.value); + }; + + const handleChangeDelay = (e) => { + setDelay(e.target.value); + }; + + return ( + + + ارسال + + + + ساعت + + + + + ); +}; diff --git a/src/features/province/components/province-send-report/ProvinceSendReport.js b/src/features/province/components/province-send-report/ProvinceSendReport.js new file mode 100644 index 0000000..ac69ae0 --- /dev/null +++ b/src/features/province/components/province-send-report/ProvinceSendReport.js @@ -0,0 +1,445 @@ +import React, { useContext, useEffect, useState } from "react"; +import { Grid } from "../../../../components/grid/Grid"; +import { + Button, + Checkbox, + Divider, + IconButton, + TextField, + Tooltip, + Typography, +} from "@mui/material"; +import { useDispatch } from "react-redux"; +import { OPEN_MODAL } from "../../../../lib/redux/slices/appSlice"; +import { ProvinceSendReportSendTime } from "../province-send-report-send-time/ProvinceSendReportSendTime"; +import { ProvinceSendReportNewReport } from "../province-send-report-new-report/ProvinceSendReportNewReport"; +import { ProvinceSendReportNewUser } from "../province-send-report-new-user/ProvinceSendReportNewUser"; +import { PageTable } from "../../../../components/page-table/PageTable"; +import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl"; +import axios from "axios"; +import { getFaUserRole } from "../../../../utils/getFaUserRole"; +import { ProvinceSendReportOperations } from "../province-send-report-operations/ProvinceSendReportOperations"; +import { AppContext } from "../../../../contexts/AppContext"; +import { provinceSendReportUpdateReportStatus } from "../../services/province-send-report-get-times"; +import PublishedWithChangesIcon from "@mui/icons-material/PublishedWithChanges"; +import { RiSearchLine } from "react-icons/ri"; + +export const ProvinceSendReport = () => { + const dispatch = useDispatch(); + + const [data, setData] = useState([]); + const [loading, setLoading] = useState(false); + const [totalRows, setTotalRows] = useState(0); + const [perPage, setPerPage] = useState(10); + + const [textValue, setTextValue] = useState(""); + const [openNotif] = useContext(AppContext); + const handleTextChange = (event) => { + setTextValue(event.target.value); + }; + + const fetchApiData = async (page, textValue) => { + setLoading(true); + const response = await axios.get( + `reports-users/?search=filter&value=${textValue}&page=${page}&role=${getRoleFromUrl()}&page_size=${perPage}` + ); + setData(response.data.results); + setTotalRows(response.data.count); + setLoading(false); + }; + + const handlePageChange = (page) => { + fetchApiData(page, textValue); + }; + + const handlePerRowsChange = async (newPerPage, page) => { + setLoading(true); + const response = await axios.get( + `reports-users/?search=filter&value=${textValue}&page=${page}&role=${getRoleFromUrl()}&page_size=${newPerPage}` + ); + + setData(response.data.results); + setTotalRows(response.data.count); + setPerPage(newPerPage); + + setLoading(false); + }; + + useEffect(() => { + fetchApiData(1); + }, []); + + const handleSubmit = async (event) => { + event.preventDefault(); + setLoading(true); + + try { + const response = await axios.get( + `reports-users/?search=filter&value=${textValue}&role=${getRoleFromUrl()}` + ); + setData(response.data.results); + setTotalRows(response.data.count); + } catch (error) { + console.error("Error fetching data:", error); + } finally { + setLoading(false); + } + }; + + let columns = [ + { + name: "عملیات", + selector: (item, i) => { + return ( + + ); + }, + sortable: false, + wrap: true, + allowOverflow: true, + center: true, + }, + { + name: "ردیف", + selector: (item, i) => { + return i + 1; + }, + sortable: false, + wrap: true, + allowOverflow: true, + center: true, + }, + { + name: "وضعیت", + selector: (item, i) => { + return item?.active ? "فعال" : "غیر فعال"; + }, + sortable: false, + wrap: true, + allowOverflow: true, + center: true, + }, + { + name: "نام و نام خانوادگی", + selector: (item, i) => { + return item?.firstname + " " + item?.lastname; + }, + sortable: false, + wrap: true, + allowOverflow: true, + center: true, + }, + { + name: "موبایل", + selector: (item, i) => { + return item?.mobile; + }, + sortable: false, + wrap: true, + allowOverflow: true, + center: true, + }, + { + name: "شهر", + selector: (item, i) => { + return item?.city; + }, + sortable: false, + wrap: true, + allowOverflow: true, + center: true, + }, + { + name: "سمت", + selector: (item, i) => { + return getFaUserRole(item?.position); + }, + sortable: false, + wrap: true, + allowOverflow: true, + center: true, + }, + // { + // name: "سمت", + // selector: (item, i) => { + // return item?.userPosition ? item?.userPosition : "-"; + // }, + // sortable: false, + // wrap: true, + // allowOverflow: true, + // center: true, + // }, + ]; + + const [forAll, setForAll] = useState(false); + + const setForAllFunction = (option) => { + dispatch( + provinceSendReportUpdateReportStatus({ + report_key: option?.report?.key, + active: forAll, + }) + ).then((r) => { + if (r.payload.error) { + openNotif({ + vertical: "top", + horizontal: "center", + msg: r.payload.error, + severity: "error", + }); + } else { + openNotif({ + vertical: "top", + horizontal: "center", + msg: "عملیات با موفقیت انجام شد.", + severity: "success", + }); + fetchApiData(1); + } + }); + }; + + const [secondaryColumns, setSecondaryColumns] = useState([]); + + useEffect(() => { + if (data?.length) { + const d = data[0]?.userReports?.map((option, index) => { + return { + name: ( + + + {option?.report?.title} + + + { + setForAll(!forAll, setForAllFunction(option)); + }} + > + + + + + ), + selector: (item, i) => { + return ( + { + dispatch( + provinceSendReportUpdateReportStatus({ + user_report_key: item?.userReports[index]?.key, + active: !item?.userReports[index]?.active, + }) + ).then((r) => { + if (r.payload.error) { + openNotif({ + vertical: "top", + horizontal: "center", + msg: r.payload.error, + severity: "error", + }); + } else { + openNotif({ + vertical: "top", + horizontal: "center", + msg: "عملیات با موفقیت انجام شد.", + severity: "success", + }); + fetchApiData(1); + } + }); + }} + /> + ); + }, + sortable: false, + wrap: true, + allowOverflow: true, + center: true, + }; + }); + setSecondaryColumns(d); + } + }, [data]); + + return ( + + {/* + + + + + + + } + data={[["1"]]} + columns={[ + "ردیف", + "وضعیت", + "نام و نام خانوادگی", + "موبایل", + "شهر", + "سمت", + "گزارش مغایرت", + "گزارش کشتار و پخش", + "گزارش تخصیص روزانه", + "گزارش پایش کشتارگاه", + "گزارش پایش کشتار", + "گزارش توزیع مباشرین و صنف", + "عملیات", + ]} + /> */} + + + + + + + + + + + + + + لیست گزارشات +
    + + + +
    + } + columns={[...columns, ...secondaryColumns]} + data={data} + progressPending={loading} + pagination + paginationServer + paginationTotalRows={totalRows} + onChangeRowsPerPage={handlePerRowsChange} + onChangePage={handlePageChange} + /> + + + ); +}; diff --git a/src/features/province/components/province-settlement-extend-settlement/ProvinceSettlementExtendSettlement.js b/src/features/province/components/province-settlement-extend-settlement/ProvinceSettlementExtendSettlement.js new file mode 100644 index 0000000..fdab3a3 --- /dev/null +++ b/src/features/province/components/province-settlement-extend-settlement/ProvinceSettlementExtendSettlement.js @@ -0,0 +1,66 @@ +import { Button, TextField } from "@mui/material"; +import React, { useContext, useState } from "react"; +import { Grid } from "../../../../components/grid/Grid"; +import { useDispatch } from "react-redux"; +import { AppContext } from "../../../../contexts/AppContext"; +import { SPACING } from "../../../../data/spacing"; +import { adminFreeBuyEditPayment } from "../../services/admin-free-buy-edit-payment"; +import { CLOSE_MODAL } from "../../../../lib/redux/slices/appSlice"; + +export const ProvinceSettlementExtendSettlement = ({ + updateTable_data, + item, +}) => { + const dispatch = useDispatch(); + const [openNotif] = useContext(AppContext); + const [text, setText] = useState(""); + + const handleTextChange = (event) => { + setText(event.target.value); + }; + return ( + + + + + ); +}; diff --git a/src/features/province/components/province-settlement-operation/provinceSettlementOperation.js b/src/features/province/components/province-settlement-operation/provinceSettlementOperation.js new file mode 100644 index 0000000..e879a08 --- /dev/null +++ b/src/features/province/components/province-settlement-operation/provinceSettlementOperation.js @@ -0,0 +1,311 @@ +import { Box, IconButton, Popover, Tooltip, Typography } from "@mui/material"; +import { Grid } from "../../../../components/grid/Grid"; +import DoneOutlineIcon from "@mui/icons-material/DoneOutline"; +import CloudUploadIcon from "@mui/icons-material/CloudUpload"; +import { useDispatch } from "react-redux"; +import { DRAWER, OPEN_MODAL } from "../../../../lib/redux/slices/appSlice"; +import { useContext, useState } from "react"; +import { AppContext } from "../../../../contexts/AppContext"; +import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl"; +import TuneIcon from "@mui/icons-material/Tune"; +import { killhouseFreeBuyEditPayment } from "../../services/killhouse-free-buy-edit-payment"; +import DoneAllIcon from "@mui/icons-material/DoneAll"; +import ArchiveIcon from "@mui/icons-material/Archive"; +import EventRepeatIcon from "@mui/icons-material/EventRepeat"; +import CloseIcon from "@mui/icons-material/Close"; +import { ProvinceSettlementRejectSettlement } from "../province-settlement-reject-settlement/ProvinceSettlementRejectSettlement"; +import { ProvinceSettlementExtendSettlement } from "../province-settlement-extend-settlement/ProvinceSettlementExtendSettlement"; +import { ProvinceSettlementSubmitDocument } from "../province-settlement-submit-document/ProvinceSettlementSubmitDocument"; +import { alpha, useTheme } from "@mui/material/styles"; + +export const ProvinceSettlementOperation = ({ + item, + item_key, + updateTable_data, +}) => { + const dispatch = useDispatch(); + const [openNotif] = useContext(AppContext); + const [anchorEl, setAnchorEl] = useState(null); + const theme = useTheme(); + const role = getRoleFromUrl(); + const isKillHouse = role === "KillHouse"; + const isFinalAccepted = item?.finalAccept === true; + const isPaymentActionDisabled = !item?.paymentDeadlineState === "pending"; + const isUploadDisabled = isKillHouse ? isFinalAccepted : false; + const showFinalApprovalAction = isFinalAccepted !== true || isKillHouse; + const showApproveRequestAction = !isKillHouse && isFinalAccepted; + const showExtendDeadlineAction = !isKillHouse; + const showRejectAction = !isKillHouse && isFinalAccepted; + const showArchiveAction = !isKillHouse; + + const renderAction = ({ + title, + IconComponent, + colorKey, + onClick, + disabled = false, + hidden = false, + }) => { + if (hidden) { + return null; + } + + const paletteMain = + theme.palette[colorKey]?.main ?? theme.palette.primary.main; + const hoverBackground = alpha(paletteMain, 0.1); + + const handleActivation = () => { + if (disabled) { + return; + } + onClick(); + }; + + const handleKeyDown = (event) => { + if (event.key === "Enter" || event.key === " ") { + event.preventDefault(); + handleActivation(); + } + }; + + return ( + + + + + + + {title} + + + + + + ); + }; + + const handleClick = (event) => { + setAnchorEl(event.currentTarget); + }; + + const handleClose = () => { + setAnchorEl(null); + }; + + const open = Boolean(anchorEl); + const id = open ? "popover" : undefined; + + // const isReject = item?.paymentDeadlineState === "pending"; + + const handleFinalApproval = (payload) => { + handleClose(); + + const settlementAmount = item?.generalInfo?.totalPaidAmount || 0; + const totalPrice = item?.generalInfo?.totalAmount || 0; + + const minimumPrice = (parseInt(totalPrice) / 100) * 90; + const maximumPrice = + (parseInt(totalPrice) / 100) * 10 + parseInt(totalPrice); + + if (settlementAmount < minimumPrice || settlementAmount > maximumPrice) { + openNotif({ + vertical: "top", + horizontal: "center", + msg: "مبلغ تسویه با شروط تسویه حساب مطابقت ندارد", + severity: "error", + }); + return; + } + + dispatch(killhouseFreeBuyEditPayment(payload)).then((r) => { + if (r.error) { + openNotif({ + vertical: "top", + horizontal: "center", + msg: r.error, + severity: "error", + }); + } else { + updateTable_data(); + openNotif({ + vertical: "top", + horizontal: "center", + msg: "عملیات با موفقیت انجام شد", + severity: "success", + }); + dispatch( + DRAWER({ + right: false, + bottom: false, + left: false, + content: null, + }) + ); + } + }); + }; + + const handleReject = (type) => { + handleClose(); + + dispatch( + OPEN_MODAL({ + title: type === "reject" ? "برگشت درخواست" : "بایگانی درخواست", + content: ( + + ), + }) + ); + }; + + return ( + + + + + + + + + {renderAction({ + title: "بارگذاری سند", + IconComponent: CloudUploadIcon, + colorKey: "success", + disabled: isUploadDisabled, + onClick: () => { + handleClose(); + dispatch( + DRAWER({ + title: "بارگزاری سند", + top: !(window.innerWidth <= 600), + bottom: window.innerWidth <= 600, + size: 1000, + content: ( + + ), + }) + ); + }, + })} + + {renderAction({ + title: "تایید نهایی", + IconComponent: DoneOutlineIcon, + colorKey: "success", + disabled: isFinalAccepted, + hidden: !showFinalApprovalAction, + onClick: () => + handleFinalApproval({ + key: item.key, + final_accept: true, + role, + }), + })} + + {renderAction({ + title: "تایید درخواست", + IconComponent: DoneAllIcon, + colorKey: "primary", + hidden: !showApproveRequestAction, + onClick: () => + handleFinalApproval({ + key: item.key, + state: "accepted", + role, + check: true, + }), + })} + + {renderAction({ + title: "تمدید مهلت تسویه", + IconComponent: EventRepeatIcon, + colorKey: "primary", + hidden: !showExtendDeadlineAction, + disabled: isPaymentActionDisabled, + onClick: () => { + handleClose(); + dispatch( + OPEN_MODAL({ + title: "تمدید مهلت تسویه", + content: ( + + ), + }) + ); + }, + })} + + {renderAction({ + title: "رد درخواست", + IconComponent: CloseIcon, + colorKey: "error", + hidden: !showRejectAction, + disabled: isPaymentActionDisabled, + onClick: () => handleReject("reject"), + })} + + {renderAction({ + title: "بایگانی", + IconComponent: ArchiveIcon, + colorKey: "error", + hidden: !showArchiveAction, + disabled: isPaymentActionDisabled, + onClick: () => handleReject("archive"), + })} + + + + + ); +}; diff --git a/src/features/province/components/province-settlement-pdf-kill-request/ProvinceSettlementPdfKillRequest.js b/src/features/province/components/province-settlement-pdf-kill-request/ProvinceSettlementPdfKillRequest.js new file mode 100644 index 0000000..a292f0c --- /dev/null +++ b/src/features/province/components/province-settlement-pdf-kill-request/ProvinceSettlementPdfKillRequest.js @@ -0,0 +1,28 @@ +import { IconButton } from "@mui/material"; +import PictureAsPdfIcon from "@mui/icons-material/PictureAsPdf"; +import axios from "axios"; +import { useSelector } from "react-redux"; +import { checkPathStartsWith } from "../../../../utils/checkPathStartsWith"; + +function PdfKillRequest({ pdf_key }) { + const selectedSubUser = useSelector( + (state) => state.userSlice.selectedSubUser + ); + return ( + + + + + + ); +} + +export default PdfKillRequest; diff --git a/src/features/province/components/province-settlement-reject-settlement/ProvinceSettlementRejectSettlement.js b/src/features/province/components/province-settlement-reject-settlement/ProvinceSettlementRejectSettlement.js new file mode 100644 index 0000000..6869905 --- /dev/null +++ b/src/features/province/components/province-settlement-reject-settlement/ProvinceSettlementRejectSettlement.js @@ -0,0 +1,71 @@ +import { Button, TextField } from "@mui/material"; +import React, { useContext, useState } from "react"; +import { Grid } from "../../../../components/grid/Grid"; +import { useDispatch } from "react-redux"; +import { AppContext } from "../../../../contexts/AppContext"; +import { SPACING } from "../../../../data/spacing"; +import { adminFreeBuyEditPayment } from "../../services/admin-free-buy-edit-payment"; +import { CLOSE_MODAL } from "../../../../lib/redux/slices/appSlice"; + +export const ProvinceSettlementRejectSettlement = ({ + updateTable_data, + item, + type, +}) => { + const dispatch = useDispatch(); + const [openNotif] = useContext(AppContext); + const [text, setText] = useState(""); + + const handleTextChange = (event) => { + setText(event.target.value); + }; + + return ( + + + + + ); +}; diff --git a/src/features/province/components/province-settlement-submit-document/ProvinceSettlementSubmitDocument.js b/src/features/province/components/province-settlement-submit-document/ProvinceSettlementSubmitDocument.js new file mode 100644 index 0000000..8b62400 --- /dev/null +++ b/src/features/province/components/province-settlement-submit-document/ProvinceSettlementSubmitDocument.js @@ -0,0 +1,477 @@ +import { useEffect, useState, useCallback } from "react"; +import { + Box, + Grid, + Card, + CardContent, + IconButton, + Typography, + Divider, + Stack, + InputAdornment, + TextField, +} from "@mui/material"; +import DoneIcon from "@mui/icons-material/Done"; +import DeleteOutlineIcon from "@mui/icons-material/DeleteOutline"; +import { DatePicker } from "@mui/x-date-pickers"; +import { useFormik } from "formik"; +import { Yup } from "../../../../lib/yup/yup"; +import moment from "moment"; +import { useDispatch, useSelector } from "react-redux"; + +import { freeBuyingPayment } from "../../services/free-buying-payment"; +import { adminSettlementDirectBuying } from "../../services/admin-settlement-direct-buying-payment"; +import { freeBuyDeletePaymentService } from "../../services/free-buying-delete-payment"; +import { fixBase64 } from "../../../../utils/toBase64"; +import { resizeImage } from "../../../../utils/resizeImage"; +import { formatJustDate } from "../../../../utils/formatTime"; + +import { ImageUpload } from "../../../../components/image-upload/ImageUpload"; +import ShowImage from "../../../../components/show-image/ShowImage"; +import { checkPathStartsWith } from "../../../../utils/checkPathStartsWith"; + +export const ProvinceSettlementSubmitDocument = ({ + modal_key, + updateTable_modal, +}) => { + const dispatch = useDispatch(); + const [paymentData, setPaymentData] = useState([]); + const [directBuyImages, setDirectBuyImages] = useState([[]]); + const [localItems, setLocalItems] = useState([ + { amount: "", date: "", image: "" }, + ]); + const selectedSubUser = useSelector( + (state) => state.userSlice.selectedSubUser + ); + const formik = useFormik({ + initialValues: { + province_kill_request_key: modal_key, + items: localItems, + }, + validationSchema: Yup.object({ + items: Yup.array().of( + Yup.object().shape({ + amount: Yup.number() + .typeError("مبلغ باید یک عدد معتبر باشد") + .required("وارد کردن مبلغ الزامی است") + .positive("مبلغ باید عددی مثبت باشد") + .integer("مبلغ باید عدد صحیح باشد"), + date: Yup.date() + .typeError("تاریخ معتبر وارد کنید") + .required("تاریخ پرداخت الزامی است") + .max(new Date(), "تاریخ نمی‌تواند از امروز بیشتر باشد"), + image: Yup.string().required("بارگزاری سند الزامی است"), + }) + ), + }), + onSubmit: () => {}, + enableReinitialize: true, + }); + + const isItemFilled = useCallback( + (item) => !!(item.amount || item.date || item.image), + [] + ); + + const handleDateChange = useCallback( + (date, index) => { + const formattedDateTime = moment(date).toISOString(); + const newItems = [...localItems]; + newItems[index] = { ...newItems[index], date: formattedDateTime }; + setLocalItems(newItems); + formik.setFieldValue(`items[${index}].date`, formattedDateTime, false); + }, + [localItems, formik] + ); + + const handleAmountChange = useCallback( + (value, index) => { + const newItems = [...localItems]; + newItems[index] = { ...newItems[index], amount: value }; + setLocalItems(newItems); + formik.setFieldValue(`items[${index}].amount`, value, false); + }, + [localItems, formik] + ); + + const directBuyImgHandler = useCallback( + (imageList, index) => { + setDirectBuyImages((prev) => { + const newArr = [...prev]; + newArr[index] = imageList; + return newArr; + }); + + if (imageList[0]) { + const file = imageList[0]?.file; + resizeImage(file, (resizedDataUrl) => { + const optimizedBase64 = fixBase64(resizedDataUrl); + const newItems = [...localItems]; + newItems[index] = { ...newItems[index], image: optimizedBase64 }; + setLocalItems(newItems); + formik.setFieldValue(`items[${index}].image`, optimizedBase64, false); + }); + } else { + const newItems = [...localItems]; + newItems[index] = { ...newItems[index], image: "" }; + setLocalItems(newItems); + formik.setFieldValue(`items[${index}].image`, "", false); + } + }, + [localItems, formik] + ); + + const removeFormItem = useCallback( + (index) => { + const newItems = localItems.filter((_, i) => i !== index); + const newImages = directBuyImages.filter((_, i) => i !== index); + + setLocalItems( + newItems.length ? newItems : [{ amount: "", date: "", image: "" }] + ); + setDirectBuyImages(newImages.length ? newImages : [[]]); + formik.setFieldValue( + "items", + newItems.length ? newItems : [{ amount: "", date: "", image: "" }], + false + ); + }, + [localItems, directBuyImages, formik] + ); + + const validateItem = useCallback( + async (index) => { + await formik.setTouched( + { + items: formik.values.items.map((item, i) => + i === index ? { amount: true, date: true, image: true } : item + ), + }, + false + ); + + const errors = await formik.validateForm(); + return !(errors.items && errors.items[index]); + }, + [formik] + ); + + const submitItem = useCallback( + async (index) => { + const item = localItems[index]; + if (!isItemFilled(item)) { + removeFormItem(index); + return; + } + const isValid = await validateItem(index); + if (!isValid) return; + + const payload = { + province_kill_request_key: modal_key, + amount: item.amount, + date: item.date, + image: item.image, + }; + + dispatch(adminSettlementDirectBuying(payload)).then((action) => { + if (action.payload?.status === 200 || action.payload?.status === 201) { + const newItems = [...localItems]; + newItems[index] = { amount: "", date: "", image: "" }; + setLocalItems(newItems); + + setDirectBuyImages((prev) => { + const newArr = [...prev]; + newArr[index] = []; + return newArr; + }); + + dispatch( + freeBuyingPayment({ + role_key: checkPathStartsWith("province") + ? selectedSubUser?.key || "" + : "", + province_kill_request_key: modal_key, + }) + ).then((action) => { + const response = action.payload?.data; + if (response && Array.isArray(response)) { + setPaymentData( + response.map((p) => ({ ...p, date: formatJustDate(p.date) })) + ); + } + }); + updateTable_modal(); + } + }); + }, + [ + localItems, + isItemFilled, + removeFormItem, + validateItem, + dispatch, + modal_key, + updateTable_modal, + ] + ); + + useEffect(() => { + if (!modal_key) return; + dispatch( + freeBuyingPayment({ + province_kill_request_key: modal_key, + role_key: checkPathStartsWith("province") + ? selectedSubUser?.key || "" + : "", + }) + ).then((action) => { + const response = action.payload?.data; + if (response && Array.isArray(response)) { + setPaymentData( + response.map((p) => ({ ...p, date: formatJustDate(p.date) })) + ); + } + }); + }, [dispatch, modal_key]); + + const CardShell = useCallback( + ({ children, highlight = false }) => ( + + {children} + + ), + [] + ); + + return ( + + {paymentData.map((payment) => ( + + + + {payment.image && ( + + + + + + )} + + + ریال + ), + }} + /> + + + {payment.date && ( + + + + )} + + + { + dispatch( + freeBuyDeletePaymentService({ key: payment.key }) + ).then((action) => { + if ( + action.payload?.status === 200 || + action.payload?.status === 201 + ) { + setPaymentData((d) => + d.filter((p) => p.key !== payment.key) + ); + } + }); + updateTable_modal(); + }} + > + + + + + + + ))} + + {localItems?.map((item, index) => ( + + + + + + directBuyImgHandler(imageList, index) + } + maxNumber={1} + title={"بارگذاری"} + /> + {formik.touched.items?.[index]?.image && + formik.errors.items?.[index]?.image && ( + + {formik.errors.items[index].image} + + )} + + + + handleAmountChange(e.target.value, index)} + onBlur={formik.handleBlur} + error={ + formik.touched.items?.[index]?.amount && + Boolean(formik.errors.items?.[index]?.amount) + } + helperText={ + formik.touched.items?.[index]?.amount && + formik.errors.items?.[index]?.amount + } + InputProps={{ + inputMode: "numeric", + endAdornment: ( + ریال + ), + }} + /> + + + + handleDateChange(d, index)} + renderInput={(params) => ( + + )} + /> + + + + + {isItemFilled(item) && formik.values.items?.[index]?.date && ( + submitItem(index)} + disabled={formik.isSubmitting} + sx={{ + border: "1px solid", + borderColor: isItemFilled(item) + ? "primary.main" + : "warning.main", + }} + > + + + )} + + + + + + ))} + + {(paymentData?.length > 0 || localItems?.length > 0) && ( + + + + مبلغ کل + + + {( + paymentData?.reduce((sum, p) => sum + (p?.amount || 0), 0) + + (localItems?.reduce( + (sum, it) => sum + (Number(it.amount) || 0), + 0 + ) || 0) + )?.toLocaleString()}{" "} + ریال + + + + + )} + + ); +}; diff --git a/src/features/province/components/province-settlement/ProvinceSettlement.js b/src/features/province/components/province-settlement/ProvinceSettlement.js new file mode 100644 index 0000000..ad12043 --- /dev/null +++ b/src/features/province/components/province-settlement/ProvinceSettlement.js @@ -0,0 +1,366 @@ +import { useState, useEffect, useContext } from "react"; +import { + Button, + TextField, + Tooltip, + Tab, + Tabs, + Box, + Checkbox, +} from "@mui/material"; +import ToggleOffOutlinedIcon from "@mui/icons-material/ToggleOffOutlined"; +import ToggleOnIcon from "@mui/icons-material/ToggleOn"; +import { Grid } from "../../../../components/grid/Grid"; +import moment from "moment/moment"; + +import axios from "axios"; +import { useDispatch, useSelector } from "react-redux"; + +import { RiFileExcel2Fill, RiSearchLine } from "react-icons/ri"; +import { + LOADING_END, + LOADING_START, +} from "../../../../lib/redux/slices/appSlice"; +import { DatePicker } from "@mui/x-date-pickers"; +import { ProvinceSettlementOperation } from "../../components/province-settlement-operation/provinceSettlementOperation"; + +import { SPACING } from "../../../../data/spacing"; +import ResponsiveTable from "../../../../components/responsive-table/ResponsiveTable"; +import { formatJustDate } from "../../../../utils/formatTime"; +import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl"; +import { AppContext } from "../../../../contexts/AppContext"; +import ProvinceSettlementPdfKillRequest from "../province-settlement-pdf-kill-request/ProvinceSettlementPdfKillRequest"; +import { checkPathStartsWith } from "../../../../utils/checkPathStartsWith"; + +export const ProvinceSettlement = () => { + const dispatch = useDispatch(); + const [, , selectedDate1, setSelectedDate1, selectedDate2, setSelectedDate2] = + useContext(AppContext); + + const userKey = useSelector((state) => state.userSlice.userProfile.key); + const [tableData, setTableData] = useState([]); + const [data, setData] = useState([]); + const [totalRows, setTotalRows] = useState(0); + const [perPage, setPerPage] = useState(10); + const [withDate, setWithDate] = useState(false); + const [page, setPage] = useState(1); + const [value, setValue] = useState("0"); + const [textValue, setTextValue] = useState(""); + const selectedSubUser = useSelector( + (state) => state.userSlice.selectedSubUser + ); + + const fetchApiData = async (page) => { + dispatch(LOADING_START()); + const response = await axios.get( + `direct-buying-requests/?role=${getRoleFromUrl()}${ + checkPathStartsWith("province") + ? `&role_key=${selectedSubUser?.key}` + : "" + }&status=${value === "0" ? "active" : "archive"}&search=filter&value=${ + textValue || "" + }${ + withDate ? `&date1=${selectedDate1}&date2=${selectedDate2}` : `` + }&page=${page}&page_size=${perPage}` + ); + dispatch(LOADING_END()); + setData(response.data.results); + setTotalRows(response.data.count); + }; + + useEffect(() => { + fetchApiData(1); + }, [ + dispatch, + selectedDate1, + selectedDate2, + perPage, + value, + withDate, + selectedSubUser?.key, + ]); + + const updateTable = () => { + fetchApiData(page !== 0 ? page : 1); + }; + + useEffect(() => { + const d = data?.map((item, i) => { + let paymentStatusText; + switch (item?.paymentDeadlineState) { + case "pending": + paymentStatusText = "بارگزاری سند مالی"; + break; + case "checking": + paymentStatusText = "بررسی مالی اتحادیه"; + break; + case "accepted": + paymentStatusText = "تایید شده"; + break; + + case "rejected": + paymentStatusText = "برگشت داده شده"; + break; + case "archive": + paymentStatusText = "بایگانی شده"; + break; + default: + paymentStatusText = "وضعیت نامشخص"; + } + return [ + page === 1 ? i + 1 : i + perPage * (page - 1) + 1, + + formatJustDate(item?.killRequest?.createDate), + formatJustDate(item?.killRequest?.reciveDate), + `${item?.killRequest?.killHouse?.name} (${item?.killRequest?.killHouse?.mobile})`, + item?.killRequest?.freeDirectBuying ? "آزاد" : "دولتی", + item?.killRequest?.killHouse + ? item?.killRequest?.killHouse?.name + : item?.killRequest?.slaughterHouse, + + `${item?.killRequest?.poultry?.fullname} (${item?.killRequest?.poultry.mobile})`, + + item?.generalInfo?.age, + + `${ + item?.killRequest?.chickenBreed + ? item?.killRequest?.chickenBreed + : "-" + }`, + item?.totalKilledQuantity?.toLocaleString(), + item?.generalInfo?.IndexWeight, + + item?.totalKilledWeight?.toLocaleString(), + + item?.killRequest?.amount?.toLocaleString(), + + item?.generalInfo?.totalAmount?.toLocaleString(), + + formatJustDate(item?.paymentDeadlineDate), + item?.extensionPaymentDeadlineDate + ? formatJustDate(item?.extensionPaymentDeadlineDate) + : "-", + , + item?.generalInfo?.totalPaidAmount.toLocaleString(), + + paymentStatusText, + item?.paymentDeadlineCheckerFullname, + formatJustDate(item?.paymentDeadlineCheckDate), + item?.paymentDeadlineArchiveMessage, + ...(value === "0" + ? [ + , + ] + : []), + ]; + }); + + setTableData(d); + }, [data]); + + const handlePageChange = (page) => { + fetchApiData(page); + setPage(page); + }; + + const handlePerRowsChange = (perRows) => { + setPerPage(perRows); + setPage(1); + }; + + const handleChange = (event, newValue) => { + setValue(newValue); + }; + + const handleTextChange = (event) => { + setTextValue(event.target.value); + }; + + const handleSubmit = async (event) => { + event.preventDefault(); + dispatch(LOADING_START()); + + try { + const response = await axios.get( + `direct-buying-requests/?role=${getRoleFromUrl()}${ + checkPathStartsWith("province") + ? `&role_key=${selectedSubUser?.key}` + : "" + }&status=${value === "0" ? "active" : "archive"}${ + withDate ? `&date1=${selectedDate1}&date2=${selectedDate2}` : `` + }&search=filter&value=${textValue || ""}` + ); + setData(response.data.results); + setTotalRows(response.data.count); + dispatch(LOADING_END()); + } catch (error) { + console.error("Error fetching data:", error); + } + }; + + return ( + <> + +
    + + + } + checkedIcon={} + checked={withDate} + onChange={() => setWithDate(!withDate)} + color="primary" + size="large" + /> + + ( + + )} + value={selectedDate1} + onChange={(e) => { + setSelectedDate1(moment(e).format("YYYY-MM-DD")); + }} + /> + + + ( + + )} + value={selectedDate2} + onChange={(e) => { + setSelectedDate2(moment(e).format("YYYY-MM-DD")); + }} + /> + + + + + + + + + + + + +
    +
    + + + + + + + + + + ); +}; + +export default ProvinceSettlement; diff --git a/src/features/province/components/province-show-stewards-transactions/ProvinceShowStewardsTransactions.js b/src/features/province/components/province-show-stewards-transactions/ProvinceShowStewardsTransactions.js new file mode 100644 index 0000000..7d3d5ed --- /dev/null +++ b/src/features/province/components/province-show-stewards-transactions/ProvinceShowStewardsTransactions.js @@ -0,0 +1,261 @@ +import { useContext, useEffect, useState } from "react"; +import { AppContext } from "../../../../contexts/AppContext"; +import { useDispatch } from "react-redux"; +import moment from "moment"; +import { + LOADING_END, + LOADING_START, +} from "../../../../lib/redux/slices/appSlice"; +import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl"; +import axios from "axios"; +import { Grid } from "../../../../components/grid/Grid"; +import { Button, Checkbox, TextField, Tooltip } from "@mui/material"; +import { DatePicker } from "@mui/x-date-pickers"; +import { RiFileExcel2Fill, RiSearchLine } from "react-icons/ri"; +import ResponsiveTable from "../../../../components/responsive-table/ResponsiveTable"; +import { useParams, useLocation } from "react-router-dom"; +import { formatTime } from "../../../../utils/formatTime"; +import { getPosProviderName } from "../../../../utils/getPosProviderName"; +import ToggleOffOutlinedIcon from "@mui/icons-material/ToggleOffOutlined"; +import ToggleOnIcon from "@mui/icons-material/ToggleOn"; + +export const ProvinceShowStewardsTransactions = ({ name }) => { + const [, , selectedDate1, setSelectedDate1, selectedDate2, setSelectedDate2] = + useContext(AppContext); + const [withDate, setWithDate] = useState(false); + const [openNotif] = useContext(AppContext); + const { key } = useParams(); + const location = useLocation(); + + const dispatch = useDispatch(); + useEffect(() => { + const currentDate = moment(new Date()).format("YYYY-MM-DD"); + setSelectedDate1(currentDate); + setSelectedDate2(currentDate); + }, []); + + // Read filterDate from URL query parameters + useEffect(() => { + const urlParams = new URLSearchParams(location.search); + const filterDate = urlParams.get("filterDate"); + if (filterDate === "on") { + setWithDate(true); + } else if (filterDate === "off") { + setWithDate(false); + } + }, [location.search]); + + const handleTextChange = (event) => { + setTextValue(event.target.value); + }; + + const [data, setData] = useState([]); + const [totalRows, setTotalRows] = useState(0); + const [perPage, setPerPage] = useState(10); + const [textValue, setTextValue] = useState(""); + const [page, setPage] = useState(1); + const [tableData, setTableData] = useState([]); + + const fetchApiData = async (page) => { + dispatch(LOADING_START()); + const response = await axios.get( + `details-pos-machine-transactions/?search=filter&value=${textValue}&role=${getRoleFromUrl()}${ + withDate ? `&date1=${selectedDate1}&date2=${selectedDate2}` : `` + }&page=${page}&page_size=${perPage}&key=${key}` + ); + dispatch(LOADING_END()); + setData(response.data.results); + setTotalRows(response.data.count); + }; + + const handlePageChange = (page) => { + fetchApiData(page); + setPage(page); + }; + + const handlePerRowsChange = (perRows) => { + setPerPage(perRows); + setPage(1); + }; + + // const updateTable = () => { + // fetchApiData(page !== 0 ? page : 1); + // }; + + useEffect(() => { + const d = data?.map((item, i) => { + return [ + page === 1 ? i + 1 : i + perPage * (page - 1) + 1, + item.paid ? "موفق" : "ناموفق", + formatTime(item?.date), + item?.product?.name, + item?.currentPrice?.toLocaleString(), + item?.weight?.toLocaleString(), + item?.price?.toLocaleString(), + getPosProviderName(item?.posProvider), + ]; + }); + + setTableData(d); + }, [data]); + + useEffect(() => { + fetchApiData(1); + }, [dispatch, selectedDate1, selectedDate2, perPage, withDate]); + + const handleSubmit = async (event) => { + event.preventDefault(); + dispatch(LOADING_START()); + + try { + const response = await axios.get( + `details-pos-machine-transactions/?role=${getRoleFromUrl()}&search=filter&value=${textValue}${ + withDate ? `&date1=${selectedDate1}&date2=${selectedDate2}` : `` + }&page=${1}&page_size=${perPage}&key=${key}` + ); + setData(response.data.results); + setTotalRows(response.data.count); + dispatch(LOADING_END()); + } catch (error) { + console.error("Error fetching data:", error); + } + }; + + return ( + + + + } + checkedIcon={} + checked={withDate} + onChange={() => setWithDate(!withDate)} + color="primary" + size="large" + /> + + ( + + )} + value={selectedDate1} + onChange={(e) => { + setSelectedDate1(moment(e).format("YYYY-MM-DD")); + }} + /> + + + ( + + )} + value={selectedDate2} + onChange={(e) => { + setSelectedDate2(moment(e).format("YYYY-MM-DD")); + }} + /> + + + +
    + + + +
    + + + {/* */} + + {/* */} + +
    + + +
    + ); +}; diff --git a/src/features/province/components/province-slaughter-direct-buy-permission/ProvinceSlaughterDirectBuyPermission.js b/src/features/province/components/province-slaughter-direct-buy-permission/ProvinceSlaughterDirectBuyPermission.js new file mode 100644 index 0000000..2aec49e --- /dev/null +++ b/src/features/province/components/province-slaughter-direct-buy-permission/ProvinceSlaughterDirectBuyPermission.js @@ -0,0 +1,79 @@ +import { Checkbox, FormControlLabel, IconButton, Tooltip } from "@mui/material"; +import { useEffect, useState } from "react"; +import { useDispatch } from "react-redux"; +import { Grid } from "../../../../components/grid/Grid"; +import { SPACING } from "../../../../data/spacing"; +import { getDirectBuyPermissionService } from "../../services/get-direct-buy-permission"; +import { postDirectBuyPermissionService } from "../../services/post-direct-buy-permission"; +// import { updateLossesPermissionService } from "../../services/update-losses-permission"; +import TuneIcon from "@mui/icons-material/Tune"; +import { useNavigate } from "react-router-dom"; +import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl"; +import { + ROUTE_ADMINX_ROUTE_POLICY_COUNCIL_DIRECT_BUY, + ROUTE_PROVINCE_ROUTE_POLICY_COUNCIL_DIRECT_BUY, + ROUTE_SUPER_ADMIN_ROUTE_POLICY_COUNCIL_DIRECT_BUY, +} from "../../../../routes/routes"; + +export const ProvinceSlaughterDirectBuyPermission = () => { + const navigate = useNavigate(); + const [isChecked, setIsChecked] = useState(false); + const dispatch = useDispatch(); + + useEffect(() => { + dispatch(getDirectBuyPermissionService()).then((r) => { + setIsChecked(r.payload.data.allowState); + }); + }, []); + + // useEffect(() => { + // if (!isChecked) { + // dispatch( + // postDirectBuyPermissionService({ + // allow: false, + // }) + // ); + // } else + // }, [isChecked]); + + const handleChange = (event) => { + dispatch( + postDirectBuyPermissionService({ + allow: event.target.checked, + }) + ); + setIsChecked(event.target.checked); + }; + + return ( + + + } + label="دسترسی کشتارگاه/کشتارکن برای ثبت خرید مستقیم" + /> + + { + navigate( + `${ + getRoleFromUrl() === "AdminX" + ? ROUTE_ADMINX_ROUTE_POLICY_COUNCIL_DIRECT_BUY + : getRoleFromUrl() === "SuperAdmin" + ? ROUTE_SUPER_ADMIN_ROUTE_POLICY_COUNCIL_DIRECT_BUY + : getRoleFromUrl() === "ProvinceFinancial" + ? ROUTE_PROVINCE_ROUTE_POLICY_COUNCIL_DIRECT_BUY + : "" + }` + ); + }} + > + + + + + ); +}; diff --git a/src/features/province/components/province-slaughter-operations/ProvinceSlaughterOperations.js b/src/features/province/components/province-slaughter-operations/ProvinceSlaughterOperations.js new file mode 100644 index 0000000..0916c0f --- /dev/null +++ b/src/features/province/components/province-slaughter-operations/ProvinceSlaughterOperations.js @@ -0,0 +1,212 @@ +import { Grid } from "../../../../components/grid/Grid"; +import { SPACING } from "../../../../data/spacing"; +import { NavLink } from "../../../../components/nav-link/NavLink"; +import { useLocation } from "react-router-dom"; +import { + ROUTE_ADMINX_ROUTE_GUILDS_SETTINGS, + ROUTE_ADMINX_ROUTE_MANAGE_DISTRIBUTIONS, + ROUTE_ADMINX_ROUTE_MANAGE_PROCESS_BUY_REQ, + ROUTE_ADMINX_ROUTE_MANAGE_PROCESS_KILLPLACE, + ROUTE_ADMINX_ROUTE_MANAGE_PROCESS_SLAUGHTER, + ROUTE_ADMINX_ROUTE_POLICY_COUNCIL_KILLHOUSE_GUILDS, + ROUTE_ADMINX_ROUTE_SLAUGHTER_TRADE_PANEL, + ROUTE_ADMINX_SLAUGHTERS_MONITORING_BUYERS, + ROUTE_PROVINCE_ROUTE_GUILDS_SETTINGS, + ROUTE_PROVINCE_ROUTE_MANAGE_PROCESS_BUY_REQ, + ROUTE_PROVINCE_ROUTE_MANAGE_PROCESS_KILLPLACE, + ROUTE_PROVINCE_ROUTE_MANAGE_PROCESS_SLAUGHTER, + ROUTE_PROVINCE_ROUTE_POLICY_COUNCIL_KILLHOUSE_GUILDS, + ROUTE_PROVINCE_SLAUGHTERS_MONITORING_BUYERS, + ROUTE_SUPER_ADMIN_ROUTE_GUILDS_SETTINGS, + ROUTE_SUPER_ADMIN_ROUTE_MANAGE_DISTRIBUTIONS, + ROUTE_SUPER_ADMIN_ROUTE_MANAGE_PROCESS_BUY_REQ, + ROUTE_SUPER_ADMIN_ROUTE_MANAGE_PROCESS_KILLPLACE, + ROUTE_SUPER_ADMIN_ROUTE_MANAGE_PROCESS_SLAUGHTER, + ROUTE_SUPER_ADMIN_ROUTE_POLICY_COUNCIL_KILLHOUSE_GUILDS, + ROUTE_SUPER_ADMIN_ROUTE_SLAUGHTER_TRADE_PANEL, + ROUTE_SUPER_ADMIN_SLAUGHTERS_MONITORING_BUYERS, +} from "../../../../routes/routes"; +import LinkItem from "../../../../components/link-item/LinkItem"; +import { + VscGraphLine, + VscLiveShare, + VscNewFolder, + VscOrganization, +} from "react-icons/vsc"; +import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl"; +import { IoIosPeople } from "react-icons/io"; + +export const ProvinceSlaughterOperations = () => { + const { pathname } = useLocation(); + + return ( + + + } + title="خریداران" + /> + + {(getRoleFromUrl() === "SuperAdmin" || getRoleFromUrl() === "AdminX") && ( + + } + title="مجوز خرید" + /> + + )} + + } + title="دسترسی خودرو" + /> + + + + } + title="مجوزهای توزیع" + /> + + + } + title="مجوز ثبت صنف به کشتارگاه ها" + /> + + + {(getRoleFromUrl() === "AdminX" || getRoleFromUrl() === "SuperAdmin") && ( + + } + title="پنل معاملاتی" + /> + + )} + {(getRoleFromUrl() === "AdminX" || getRoleFromUrl() === "SuperAdmin") && ( + + } + title="مدیریت توزیع" + /> + + )} + {(getRoleFromUrl() === "AdminX" || getRoleFromUrl() === "SuperAdmin") && ( + + } + title="پایش خریداران" + /> + + )} + + ); +}; diff --git a/src/features/province/components/province-slaughter-surveillance/ProvinceSlaughterSurveillance.js b/src/features/province/components/province-slaughter-surveillance/ProvinceSlaughterSurveillance.js new file mode 100644 index 0000000..6aea793 --- /dev/null +++ b/src/features/province/components/province-slaughter-surveillance/ProvinceSlaughterSurveillance.js @@ -0,0 +1,441 @@ +import React, { useContext, useEffect } from "react"; +import { Grid } from "../../../../components/grid/Grid"; +import { SPACING } from "../../../../data/spacing"; +import { Button, TextField, Tooltip, Typography } from "@mui/material"; +import { useDispatch, useSelector } from "react-redux"; +import { AppContext } from "../../../../contexts/AppContext"; +import { DatePicker } from "@mui/x-date-pickers"; +import moment from "moment"; +import axios from "axios"; +import { RiFileExcel2Fill } from "react-icons/ri"; +import { formatJustDate } from "../../../../utils/formatTime"; +import { provinceGetSlaughterSurveillanceService } from "../../services/province-get-slaughter-surverillance-service"; +import { useSystemName } from "../../../../utils/getSystemName"; + +export const ProvinceSlaughterSurveillance = () => { + const dispatch = useDispatch(); + const [, , selectedDate1, setSelectedDate1, selectedDate2, setSelectedDate2] = + useContext(AppContext); + const { slaughterSurveillance } = useSelector((item) => item.provinceSlice); + const [openNotif] = useContext(AppContext); + const systemName = useSystemName(); + + useEffect(() => { + const currentDate = moment(new Date()).format("YYYY-MM-DD"); + setSelectedDate1(currentDate); + setSelectedDate2(currentDate); + }, []); + + useEffect(() => { + dispatch( + provinceGetSlaughterSurveillanceService({ + selectedDate1: selectedDate1, + selectedDate2: selectedDate2, + }) + ); + }, [selectedDate1, selectedDate2]); + + return ( + + + + ( + + )} + value={selectedDate1} + onChange={(e) => { + setSelectedDate1(moment(e).format("YYYY-MM-DD")); + }} + /> + + + ( + + )} + value={selectedDate2} + onChange={(e) => { + setSelectedDate2(moment(e).format("YYYY-MM-DD")); + }} + /> + + + {/* */} + + {/* */} + + + + + گزارش جامع خریداران در فرآیند کشتار مرغ گوشتی {systemName} + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    تعداد کل بارهای ایجاد شده (زنده)وزن کل بارهای ایجاد شده (زنده)حجم کل بارهای تحویلی کشتارگاه (زنده)وزن کل بارهای تحویلی کشتارگاه (زنده)وزن تحویلی با افت 25 درصدتعداد ورودی به انبار کشتارگاه (لاشه)وزن ورودی به انبار کشتارگاه (لاشه) + درصد لاشه ورودی به انبار کشتارگاه نسبت به بار تحویلی کشتارگاه + + درصد وزن لاشه ورودی به انبار کشتارگاه نسبت به بار تحویلی + کشتارگاه + درصد تعداد بار تحویلی نسبت به بار ایحاد شدهدرصد وزن بار تحویلی نسبت به بار ایحاد شده
    + {slaughterSurveillance?.allKillRequest?.quantityOfCreateBar?.toLocaleString()} + + {slaughterSurveillance?.allKillRequest?.weightOfCreateBar?.toLocaleString()} + + {slaughterSurveillance?.allKillRequest?.quantityOfReceiveBar?.toLocaleString()} + + {slaughterSurveillance?.allKillRequest?.weightOfReceiveBar?.toLocaleString()} + + {slaughterSurveillance?.allKillRequest?.weightWithTwentyFivePercentReceive?.toLocaleString()} + + {slaughterSurveillance?.allKillRequest?.quantityWarehouse?.toLocaleString()} + + {slaughterSurveillance?.allKillRequest?.weightWarehouse?.toLocaleString()} + + {slaughterSurveillance?.allKillRequest?.quantityPercentWarehouse?.toLocaleString()} + % + + {slaughterSurveillance?.allKillRequest?.weightPercentWarehouse?.toLocaleString()} + % + + {slaughterSurveillance?.allKillRequest?.quantityPercentReceive?.toLocaleString()} + % + + {slaughterSurveillance?.allKillRequest?.weightPercentReceive?.toLocaleString()} + % +
    +
    + + + + اطلاعات کلی توزیع و پخش مرغ گرم از تاریخ{" "} + {formatJustDate( + slaughterSurveillance?.generalBroadcastInformations?.date1 + )}{" "} + تا تاریخ{" "} + {formatJustDate( + slaughterSurveillance?.generalBroadcastInformations?.date2 + )} + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    تعداد خریدارانتعداد کشتار داخل استانوزن کشتار داخل استانتعداد خرید خارج استانوزن خرید خارج استانتعداد جمع کل انباروزن جمع کل انبارتعداد توزیع شدهوزن توزیع شدهتعداد توزیع / تحویل شدهوزن توزیع / تحویل شدهتعداد مانده انباروزن مانده انباردرصد توزیع نسبت به ورودی به انبارتعداد مباشر تخصیص داده شدهتعداد صنف تخصیص داده شده
    + {slaughterSurveillance?.generalBroadcastInformations?.numberOfBuyer?.toLocaleString()} + + {slaughterSurveillance?.generalBroadcastInformations?.quantityOfKillRequestInProvince?.toLocaleString()} + + {slaughterSurveillance?.generalBroadcastInformations?.weightOfKillRequestInProvince?.toLocaleString()} + + {slaughterSurveillance?.generalBroadcastInformations?.quantityOfKillRequestOutProvince?.toLocaleString()} + + {slaughterSurveillance?.generalBroadcastInformations?.weightOfKillRequestOutProvince?.toLocaleString()} + + {slaughterSurveillance?.generalBroadcastInformations?.quantityCarcasses?.toLocaleString()} + + {slaughterSurveillance?.generalBroadcastInformations?.weightCarcasses?.toLocaleString()} + + {slaughterSurveillance?.generalBroadcastInformations?.allocatedQuantity?.toLocaleString()} + + {slaughterSurveillance?.generalBroadcastInformations?.allocatedWeight?.toLocaleString()} + + {slaughterSurveillance?.generalBroadcastInformations?.acceptedAllocatedQuantity?.toLocaleString()} + + {slaughterSurveillance?.generalBroadcastInformations?.acceptedAllocatedWeight?.toLocaleString()} + + {slaughterSurveillance?.generalBroadcastInformations?.remainQuantity?.toLocaleString()} + + {slaughterSurveillance?.generalBroadcastInformations?.remainWeight?.toLocaleString()} + + % + {slaughterSurveillance?.generalBroadcastInformations?.percentWarehouse?.toLocaleString()} + + {slaughterSurveillance?.generalBroadcastInformations?.numberOfStewards?.toLocaleString()} + + {slaughterSurveillance?.generalBroadcastInformations?.numberOfGiulds?.toLocaleString()} +
    +
    + + + + + + اطلاعات کلی بارها و توزیع خریداران + + + + + *وزن (کیلوگرام)، حجم (قطعه) + + + +
    + + + + {" "} + {" "} + + + + + + + + + {" "} + {" "} + {" "} + + + + {" "} + + + + + + + + + + + + + + + + + + + + + + + + + + + {slaughterSurveillance?.killRequestAndBroadcast?.map((item, i) => { + return ( + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ); + })} + +
    + ردیف + + خریدار + + شهرستان + + حجم کل بارهای ایجاد شده توسط کشتارگاه ( زنده) + + حجم کل بارهای تحویلی توسط کشتارگاه( زنده) + + وزن تحویلی با افت 25% + + درصد حجم بار ایجاد شده به تحویلی{" "} + + ورودی به انبار کشتارگاه(لاشه) + + درصد لاشه ورودی به انبار کشتارگاه نسبت به بارتحویلی کشتارگاه (با + افت 25 %) + + خرید خارج از استان + + جمع کل انبار + + توزیع شده + + توزیع/تحویل شده + + مانده انبار + + درصد وزن مانده در انبار به ورودی انبار + + تعداد مباشر/ صنف + + بارهای تخلیه شده و عدم تکمیل(تحویل) +
    حجموزنحجموزنحجموزنحجموزنحجموزنحجموزنحجموزنحجموزنحجموزنتعداد بارحجم بار وزن بار
    {i + 1}{item?.name}{item?.city} + {item?.killReqQuantity?.toLocaleString()} + + {item?.killReqWeight?.toLocaleString()} + + {item?.quantityReceiver?.toLocaleString()} + + {item?.weightReceiver?.toLocaleString()} + + {item?.twentyFivePercentWeight?.toLocaleString()} + + %{parseInt(item?.receiverPercent?.toLocaleString())} + + {item?.quantityOfCarcasses?.toLocaleString()} + + {item?.weightOfCarcasses?.toLocaleString()} + + %{parseInt(item?.quantityOfLashePercent?.toLocaleString())} + + %{parseInt(item?.weightOfLashePercent?.toLocaleString())} + + {item?.quantityOutProvince?.toLocaleString()} + + {item?.weightOutProvince?.toLocaleString()} + + {item?.totalNumberOfCarcasses?.toLocaleString()} + + {item?.totalWeightOfCarcasses?.toLocaleString()} + + {item?.allocatedQuantity?.toLocaleString()} + + {item?.allocatedWeight?.toLocaleString()} + + {item?.acceptedAllocatedQuantity?.toLocaleString()} + + {item?.acceptedAllocatedWeight?.toLocaleString()} + + {item?.remainQuantity?.toLocaleString()} + + {item?.remainWeight?.toLocaleString()} + + %{parseInt(item?.remainPercent?.toLocaleString())} + + {item?.stewardAndGuild?.toLocaleString()} + + {item?.lenKillReqNotComplete?.toLocaleString()} + + {item?.quantityKillReqNotComplete?.toLocaleString()} + + {item?.weightKillReqNotComplete?.toLocaleString()} +
    +
    +
    + ); +}; diff --git a/src/features/province/components/province-slaughterhouse-quota/ProvinceSlaughterhouseQuota.js b/src/features/province/components/province-slaughterhouse-quota/ProvinceSlaughterhouseQuota.js new file mode 100644 index 0000000..c8834e3 --- /dev/null +++ b/src/features/province/components/province-slaughterhouse-quota/ProvinceSlaughterhouseQuota.js @@ -0,0 +1,266 @@ +import { Button, Typography, Checkbox } from "@mui/material"; +import { useContext, useEffect, useState } from "react"; +import { useDispatch, useSelector } from "react-redux"; +import { Grid } from "../../../../components/grid/Grid"; +import { SimpleTable } from "../../../../components/simple-table/SimpleTable"; +import { AppContext } from "../../../../contexts/AppContext"; +import { SPACING } from "../../../../data/spacing"; +import { slaughterGetKillerKillhousesService } from "../../../slaughter-house/services/slaughter-get-killers-killhouses"; +import { provinceGetSlaughterhousesQuotaService } from "../../services/province-get-slaughterhouses-quota"; +import { provinceSetSlaughterhousesQuotaService } from "../../services/province-set-slaughterhouses-quota"; +import { ProvinceGuildsQuantity } from "../province-guilds-quantity/ProvinceGuildsQuantity"; +import { ProvinceManageSlaughterhouseQuota } from "../province-manage-slaughterhouse-quota/ProvinceManageSlaughterhouseQuota"; +import { ProvinceSelectSlaughterForSlaughter } from "../province-select-slaughter-for-slaughter/ProvinceSelectSlaughterForSlaughter"; +// import { ProvinceSelectSlaughterForSlaughter } from "../province-select-slaughter-for-slaughter/ProvinceSelectSlaughterForSlaughter"; +import { formatJustDate } from "../../../../utils/formatTime"; + +export const ProvinceSlaughterhouseQuota = () => { + const dispatch = useDispatch(); + const [dataTable, setDataTable] = useState(); + const [allPercent, setAllPercent] = useState([]); + const [openNotif] = useContext(AppContext); + const { provinceGetSlaughterhousesQuota } = useSelector( + (state) => state.provinceSlice + ); + + const onPercentChange = (keyToFind, percent) => { + // remove the slaughter that updated + setAllPercent((prevState) => { + const tempArr = prevState.filter((item) => item.key !== keyToFind); + const itemToAdd = prevState.filter((item) => item.key === keyToFind)[0]; + const objectToAdd = { + key: keyToFind, + percent, + killer_kill_house_key: itemToAdd?.killer_kill_house_key, + }; + tempArr.push(objectToAdd); + return tempArr; + }); + }; + + const onSlaughterChange = (keyToFind, slughterKey) => { + // remove the slaughter that updated + setAllPercent((prevState) => { + const index = prevState.findIndex((obj) => obj.key === keyToFind); + const removedItem = prevState[index]; + const tempArr = prevState.filter((item) => item.key !== keyToFind); + const objectToAdd = { + ...removedItem, + killer_kill_house_key: slughterKey, + }; + tempArr.push(objectToAdd); + return tempArr; + }); + }; + + useEffect(() => { + dispatch(provinceGetSlaughterhousesQuotaService()); + dispatch(slaughterGetKillerKillhousesService()); + }, []); + + useEffect(() => { + const tempKeyAndPercent = []; + const d = provinceGetSlaughterhousesQuota?.map((item, i) => { + const killhouseType = item?.killHouse?.killer ? "کشتارکن" : "کشتارگاه"; + tempKeyAndPercent.push({ + key: item.key, + percent: item.percent, + killer_kill_house_key: item?.killHouseForKiller?.key, + }); + return [ + , + i + 1, + killhouseType, + item.killHouse?.name, + item.killHouse?.killHouseOperator?.user?.fullname, + `${item.killHouse?.systemAddress?.province?.name} - ${item.killHouse?.systemAddress?.city?.name} - ${item.killHouse?.systemAddress?.address}`, + item?.killHouse?.killer ? ( + + ) : ( + item.killHouse?.name + ), + , + , + item.guildsWeight, + ]; + }); + setAllPercent(tempKeyAndPercent); + + setDataTable(d); + }, [provinceGetSlaughterhousesQuota]); + + const sum = allPercent?.reduce( + (accumulator, currentValue) => accumulator + currentValue.percent, + 0 + ); + + return ( + + + + + تاریخ آخرین بروزرسانی:{" "} + {provinceGetSlaughterhousesQuota?.length && + formatJustDate( + provinceGetSlaughterhousesQuota[0]?.lastGuildsUpdateDate + )} + + + + + + + + + + جمع کل درصد ها + {sum.toFixed(2)}% + + + + ); +}; diff --git a/src/features/province/components/province-sms-announcement/ProvinceSmsAnnouncement.js b/src/features/province/components/province-sms-announcement/ProvinceSmsAnnouncement.js new file mode 100644 index 0000000..d95c7eb --- /dev/null +++ b/src/features/province/components/province-sms-announcement/ProvinceSmsAnnouncement.js @@ -0,0 +1,191 @@ +import React, { useContext, useEffect, useState } from "react"; +import { useFormik } from "formik"; +import * as Yup from "yup"; +import { + Radio, + RadioGroup, + FormControlLabel, + TextField, + Button, + Grid, + Container, + FormControl, + InputLabel, + Select, + MenuItem, +} from "@mui/material"; +import { useDispatch } from "react-redux"; +import { provinceSmsSetAnnouncement } from "../../services/province-sms-set-announcement"; +import { AppContext } from "../../../../contexts/AppContext"; +import { getAnnouncement } from "../../../authentication/services/get-announcement"; + +export const ProvinceSmsAnnouncement = () => { + const [openNotif] = useContext(AppContext); + const [target, setTarget] = useState(0); + const [data, setData] = useState([]); + + const handleChange = (event) => { + setTarget(event.target.value); + }; + const dispatch = useDispatch(); + + useEffect(() => { + dispatch(getAnnouncement()).then((r) => { + setData(r.payload.data); + formik.setFieldValue( + "status", + r.payload.data[0]?.active === true ? "true" : "false" + ); + formik.setFieldValue("announcement", r.payload.data[0]?.description); + }); + }, []); + + const initialValues = { + status: "", + announcement: "", + }; + + const validationSchema = Yup.object().shape({ + status: Yup.string().required("لطفا وضعیت را انتخاب کنید"), + announcement: Yup.string().when("status", { + is: "true", + then: Yup.string().required("لطفا متن اعلان را وارد کنید!"), + }), + }); + + useEffect(() => { + if (data.length) { + formik.setFieldValue( + "status", + data[target].active === true ? "true" : "false" + ); + if (data[target].description) { + formik.setFieldValue("announcement", data[target].description); + } else { + formik.setFieldValue("announcement", ""); + } + } + }, [target]); + + const onSubmit = (values) => { + dispatch( + provinceSmsSetAnnouncement({ + active: values.status === "true" ? true : false, + description: values.announcement, + key: data[target].key, + }) + ).then((r) => { + if (r.error) { + openNotif({ + vertical: "top", + horizontal: "center", + msg: "مشکلی پیش آمده است!", + severity: "error", + }); + } else { + openNotif({ + vertical: "top", + horizontal: "center", + msg: "عملیات با موفقیت انجام شد.", + severity: "success", + }); + } + }); + }; + + const formik = useFormik({ + initialValues, + validationSchema, + onSubmit, + }); + + return ( + +
    +
    + + + + + مقصد + + + + + + + } + label="فعال" + /> + } + label="غیر فعال" + /> + + + {formik.values.status === "true" && ( + + + + )} + + + + +
    +
    +
    + ); +}; diff --git a/src/features/province/components/province-sms-manage/ProvinceSmsManage.js b/src/features/province/components/province-sms-manage/ProvinceSmsManage.js new file mode 100644 index 0000000..f4fefa6 --- /dev/null +++ b/src/features/province/components/province-sms-manage/ProvinceSmsManage.js @@ -0,0 +1,252 @@ +import React, { useContext, useEffect, useState } from "react"; +import { + Checkbox, + FormControlLabel, + FormGroup, + Button, + Typography, +} from "@mui/material"; +import { Grid } from "../../../../components/grid/Grid"; +import { SPACING } from "../../../../data/spacing"; +import { useDispatch, useSelector } from "react-redux"; +import { provinceSmsLincenseService } from "../../services/province-sms-license"; +import { provinceGetSmsLincenseService } from "../../services/province-get-sms-license"; +import { AppContext } from "../../../../contexts/AppContext"; + +export function ProvinceSmsManageComponent() { + const [openNotif] = useContext(AppContext); + const [checkedValues, setCheckedValues] = useState({ + hatching: false, + poultry_request: false, + city_approval: false, + province_approval: false, + kill_request: false, + province_kill_request: false, + farm_veterinarian_approval: false, + kill_house_house_veterinarian_approval: false, + assingment_information: false, + confirmation_of_assingment_information: false, + invoice_payment: false, + invoice_payment_confirmation: false, + inspector_approval: false, + kill_house_request: false, + }); + + const dispatch = useDispatch(); + + const handleChange = (event) => { + setCheckedValues({ + ...checkedValues, + [event.target.name]: event.target.checked, + }); + }; + + const { provinceGetSmsLincense } = useSelector( + (store) => store.provinceSlice + ); + + useEffect(() => { + dispatch(provinceGetSmsLincenseService()); + }, []); + + useEffect(() => { + if (provinceGetSmsLincense?.length) { + setCheckedValues({ + hatching: provinceGetSmsLincense[0]?.hatching, + poultry_request: provinceGetSmsLincense[0]?.poultryRequest, + city_approval: provinceGetSmsLincense[0]?.cityApproval, + province_approval: provinceGetSmsLincense[0]?.provinceApproval, + kill_request: provinceGetSmsLincense[0]?.killRequest, + province_kill_request: provinceGetSmsLincense[0]?.provinceKillRequest, + farm_veterinarian_approval: + provinceGetSmsLincense[0]?.farmVeterinarianApproval, + kill_house_house_veterinarian_approval: + provinceGetSmsLincense[0]?.killHouseHouseVeterinarianApproval, + assingment_information: + provinceGetSmsLincense[0]?.assingmentInformation, + confirmation_of_assingment_information: + provinceGetSmsLincense[0]?.confirmationOfAssingmentInformation, + invoice_payment: provinceGetSmsLincense[0]?.invoicePayment, + invoice_payment_confirmation: + provinceGetSmsLincense[0]?.invoicePaymentConfirmation, + inspector_approval: provinceGetSmsLincense[0]?.inspectorApproval, + kill_house_request: provinceGetSmsLincense[0]?.killHouseRequest, + }); + } + }, [provinceGetSmsLincense]); + + const handleSubmit = (event) => { + event.preventDefault(); + dispatch(provinceSmsLincenseService(checkedValues)).then((r) => { + openNotif({ + vertical: "top", + horizontal: "center", + msg: "عملیات با موفقیت انجام شد.", + severity: "success", + }); + }); + // You can do something else with the checkedValues here, like submitting them to a server + }; + + return ( + + + + با تغییر دادن این سطوح، می‌توانید تنظیم کنید که کاربران شما پیامک‌های + خودکار را در چه زمان‌هایی دریافت کنند. + + + +
    + + + } + label="جوجه ریزی مرغدار" + /> + + } + label="درخواست کشتار مرغدار" + /> + + } + label="تاییدیه شهرستان" + /> + + } + label="تاییدیه استان" + /> + + } + label="درخواست کشتار کشتارگاه" + /> + + } + label="تخصیص استان" + /> + + } + label="تاییدیه دامپزشک فارم" + /> + + } + label="تخصیص کشتارگاه" + /> + + } + label="تاییدیه دامپزشک" + /> + + } + label="ورود اطلاعات بار" + /> + + } + label="تاییدیه اطلاعات بار/صدور فاکتور" + /> + + } + label="پرداخت فاکتور" + /> + + } + label="تاییدیه پرداخت فاکتور" + /> + + } + label="تاییدیه بازرس" + /> + + + + +
    +
    +
    + ); +} diff --git a/src/features/province/components/province-sms-submission-management-operation/ProvinceSmsSubmisionManagementOperation.js b/src/features/province/components/province-sms-submission-management-operation/ProvinceSmsSubmisionManagementOperation.js new file mode 100644 index 0000000..50a0c0a --- /dev/null +++ b/src/features/province/components/province-sms-submission-management-operation/ProvinceSmsSubmisionManagementOperation.js @@ -0,0 +1,131 @@ +import { IconButton, Tooltip, TextField, Button, Box } from "@mui/material"; +import { Grid } from "../../../../components/grid/Grid"; +import TuneIcon from "@mui/icons-material/Tune"; +import { useDispatch } from "react-redux"; +import { OPEN_MODAL, CLOSE_MODAL } from "../../../../lib/redux/slices/appSlice"; +import { useContext } from "react"; +import { AppContext } from "../../../../contexts/AppContext"; +import { managementSendSms } from "../../services/province-management-send-sms"; +import { Formik, Form } from "formik"; +import * as Yup from "yup"; + +export const ProvinceSmsSubmisionManagementOperation = ({ + item, + item_id, + updateTable_data, +}) => { + const dispatch = useDispatch(); + const [openNotif] = useContext(AppContext); + + const handleOpenModal = () => { + dispatch( + OPEN_MODAL({ + title: "ویرایش", + content: , + }) + ); + }; + + const UsernamePasswordForm = () => { + const validationSchema = Yup.object({ + username: Yup.string() + .required("نام کاربری الزامی است") + .min(3, "حداقل ۳ کاراکتر وارد کنید"), + password: Yup.string() + .required("رمز عبور الزامی است") + .min(6, "حداقل ۶ کاراکتر وارد کنید"), + }); + + return ( + { + const payload = { + id: item_id, + username: values.username, + password: values.password, + }; + + dispatch(managementSendSms(payload)).then((r) => { + setSubmitting(false); + if (r.error) { + openNotif({ + vertical: "top", + horizontal: "center", + msg: r.error, + severity: "error", + }); + } else { + updateTable_data(); + dispatch(CLOSE_MODAL()); + openNotif({ + vertical: "top", + horizontal: "center", + msg: "ویرایش با موفقیت انجام شد", + severity: "success", + }); + } + }); + }} + > + {({ + values, + errors, + touched, + handleChange, + handleBlur, + isSubmitting, + }) => ( +
    + + + + + +
    + )} +
    + ); + }; + + return ( + + + + + + + + ); +}; diff --git a/src/features/province/components/province-sms-submission-management/provinceSmsSubmissionManagement.js b/src/features/province/components/province-sms-submission-management/provinceSmsSubmissionManagement.js new file mode 100644 index 0000000..86fa904 --- /dev/null +++ b/src/features/province/components/province-sms-submission-management/provinceSmsSubmissionManagement.js @@ -0,0 +1,89 @@ +import { useState, useEffect, useCallback } from "react"; +import { Grid } from "../../../../components/grid/Grid"; +import axios from "axios"; +import { useDispatch } from "react-redux"; +import { + LOADING_END, + LOADING_START, +} from "../../../../lib/redux/slices/appSlice"; +import { SPACING } from "../../../../data/spacing"; +import ResponsiveTable from "../../../../components/responsive-table/ResponsiveTable"; +import { ProvinceSmsSubmisionManagementOperation } from "../province-sms-submission-management-operation/ProvinceSmsSubmisionManagementOperation"; + +export const ProvinceSmsSubmissionManagement = () => { + const dispatch = useDispatch(); + + const [data, setData] = useState([]); + const [page, setPage] = useState(1); + const [perPage, setPerPage] = useState(10); + const [tableData, setTableData] = useState([]); + const [totalRows, setTotalRows] = useState(0); + + const fetchApiData = useCallback(async () => { + dispatch(LOADING_START()); + try { + const response = await axios.get(`management-send-sms/`); + dispatch(LOADING_END()); + setData(response?.data || []); + setTotalRows(response?.data?.count || 0); + } catch (error) { + dispatch(LOADING_END()); + console.error("Error fetching users:", error); + } + }, [dispatch]); + + useEffect(() => { + fetchApiData(1); + }, [fetchApiData]); + + const updateTable = useCallback(() => { + fetchApiData(1); + }, [fetchApiData]); + + const handlePageChange = (page) => { + setPage(page); + fetchApiData(page); + }; + + const handlePerRowsChange = (newPerPage, page) => { + setPerPage(newPerPage); + }; + + useEffect(() => { + const d = data?.map((item, i) => { + return [ + page === 1 ? i + 1 : i + perPage * (page - 1) + 1, + item?.name, + item?.username, + item?.password, + , + ]; + }); + setTableData(d); + }, [data]); + + return ( + <> + + + + + ); +}; diff --git a/src/features/province/components/province-sms/province-sms-component.js b/src/features/province/components/province-sms/province-sms-component.js new file mode 100644 index 0000000..07e4ec3 --- /dev/null +++ b/src/features/province/components/province-sms/province-sms-component.js @@ -0,0 +1,399 @@ +import { Button, TextField, Tooltip, Typography } from "@mui/material"; +import React, { useContext, useEffect, useState } from "react"; +import { Grid } from "../../../../components/grid/Grid"; +import { SelectCheck } from "../../../../components/select-check/SelectCheck"; +import { ROLES } from "../../../../data/roles"; +import { SPACING } from "../../../../data/spacing"; +import { getFaUserRole } from "../../../../utils/getFaUserRole"; +import { useFormik } from "formik"; +import * as Yup from "yup"; +import { useDispatch } from "react-redux"; +import { provinceGetUsersByRolesService } from "../../services/province-get-users-by-roles"; +import { provinceSendSmsService } from "../../services/province-send-sms"; +import { AppContext } from "../../../../contexts/AppContext"; +import AddIcon from "@mui/icons-material/Add"; +import RefreshIcon from "@mui/icons-material/Refresh"; +import { RiFileExcel2Fill } from "react-icons/ri"; +import { AdvancedTable } from "../../../../components/advanced-table/AdvancedTable"; + +export function ProvinceSmsComponent() { + const dispatch = useDispatch(); + const [openNotif] = useContext(AppContext); + + const [provinceGetUsersByRoles, setProvinceGetUsersByRoles] = useState([]); + const [usersForSelect, setUsersForSelect] = useState([]); + const [selectedUsers, setSelectedUsers] = useState([]); + + useEffect(() => { + if (provinceGetUsersByRoles.length) { + const d = provinceGetUsersByRoles.map((item) => { + return { label: item.fullname, value: item.key }; + }); + setUsersForSelect(d); + } + }, [provinceGetUsersByRoles]); + + const [rolesForSelect] = useState( + ROLES.map((role, i) => ({ + label: getFaUserRole(role), + value: role, + })) + ); + + const validationSchema = Yup.object().shape({ + selectedRoles: Yup.array().required("لطفا نقش را انتخاب کنید"), + inputText: Yup.string().required("لطفا متن پیامک را وارد کنید"), + }); + + const onSubmit = () => { + dispatch( + provinceSendSmsService({ + user: selectedUsers, + message: formik.values.inputText, + role: formik.values.selectedRoles, + }) + ).then((r) => { + if (r.payload.status === 200) { + openNotif({ + vertical: "top", + horizontal: "center", + msg: "عملیات با موفقیت انجام شد.", + severity: "success", + }); + } + }); + }; + + const formik = useFormik({ + initialValues: { + selectedRoles: [], + inputText: "", + }, + validationSchema, + onSubmit, + }); + + useEffect(() => { + formik.validateForm(); + }, []); + + const handleCalculatePrice = (message) => { + const isPersianMessage = /[آ-ی]/.test(message); + + let price = 0; + + if (isPersianMessage) { + price = handleCountMessages(message) * 980; + } else { + price = handleCountMessages(message) * 1320; + } + + if (formik.values.selectedRoles.length) { + if (selectedUsers.length > 0) { + return price * selectedUsers.length + " ریال"; + } else { + return price * usersForSelect.length + " ریال"; + } + } else { + return "نامشخص (پیامک برای کل کاربران ارسال میشود) "; + } + }; + + const handleCountMessages = (message) => { + const charCountPerLatinPage = [160, 146, 153, 153]; + const charCountPerPersianPage = [70, 64, 67, 67]; + + const isPersianMessage = /[آ-ی]/.test(message); + + const charCountPerPage = isPersianMessage + ? charCountPerPersianPage + : charCountPerLatinPage; + + let totalChars = message.length; + let pageCount = 0; + + while (totalChars > 0) { + const charCountOnCurrentPage = + charCountPerPage[pageCount] || + charCountPerPage[charCountPerPage.length - 1]; + + if (totalChars >= charCountOnCurrentPage) { + totalChars -= charCountOnCurrentPage; + pageCount++; + } else { + pageCount++; + break; + } + } + + return pageCount; + }; + + useEffect(() => { + if (formik.values.selectedRoles.length) { + dispatch( + provinceGetUsersByRolesService({ + role: formik.values.selectedRoles.join(","), + }) + ).then((r) => setProvinceGetUsersByRoles(r.payload.data)); + } + }, [formik.values.selectedRoles]); + + return ( + + + +
    + + formik.setFieldValue("selectedRoles", e)} + options={rolesForSelect} + /> + + {formik.errors.selectedOption && ( + prop.palette.grey["A700"]} + > + {formik.errors.selectedOption} + + )} + + + {!!usersForSelect.length && ( + + + setSelectedUsers(e)} + options={usersForSelect} + /> + + + + + + تعداد کاربر انتخابی: + + + + prop.palette.grey["A700"]} + > + {selectedUsers.length > 0 ? selectedUsers.length : "همه"} + + + + + )} + + + + + + + {formik.errors.inputText && ( + prop.palette.grey["A700"]} + > + {formik.errors.inputText} + + )} + + + + + تعداد کاراکتر: + + + + prop.palette.grey["A700"]} + > + {formik.values.inputText.length} + + + + + + + + تعداد پیامک: + + + + prop.palette.grey["A700"]} + > + {handleCountMessages(formik.values.inputText)} + + + + + + + + + + + +
    +
    +
    + + + + + مانده حساب: + + prop.palette.grey["A700"]} + > + 230,000 ریال + + + + + محاسبه تقریبی هزینه پیام: + + prop.palette.grey["A700"]} + > + {handleCalculatePrice(formik.values.inputText).toLocaleString()}{" "} + + + + + + + + + + + + + + + +
    + ); +} diff --git a/src/features/province/components/province-steward-edit-sale-out-operation/ProvinceStewardEditSaleOutOperation.js b/src/features/province/components/province-steward-edit-sale-out-operation/ProvinceStewardEditSaleOutOperation.js new file mode 100644 index 0000000..10d15a0 --- /dev/null +++ b/src/features/province/components/province-steward-edit-sale-out-operation/ProvinceStewardEditSaleOutOperation.js @@ -0,0 +1,148 @@ +import { useContext } from "react"; +import { useDispatch } from "react-redux"; +import { AppContext } from "../../../../contexts/AppContext"; +import { Yup } from "../../../../lib/yup/yup"; +import { useFormik } from "formik"; +import { CLOSE_MODAL } from "../../../../lib/redux/slices/appSlice"; +import { Grid } from "../../../../components/grid/Grid"; +import { Button, TextField } from "@mui/material"; +import { NumberInput } from "../../../../components/number-format-custom/NumberFormatCustom"; +import moment from "moment"; +import { DatePicker } from "@mui/x-date-pickers"; +import { provinceDispenserStewardEditSaleOutService } from "../../services/province-dispenser-steward-edit-sale-out"; +import { fetchSlaughterBroadcastAndProducts } from "../../../slaughter-house/services/handle-fetch-slaughter-products"; + +export const ProvinceStewardEditSaleOutOperation = ({ + editData, + fetchData, + fetchApiData, + fetchDashboardData, +}) => { + const dispatch = useDispatch(); + const [openNotif] = useContext(AppContext); + + const validationSchema = Yup.object({ + weight: Yup.number().min(1, "یک مقدار مثبت وارد کنید!"), + quarantineCode: Yup.string(), + date: Yup.date(), + }); + + const formik = useFormik({ + initialValues: { + weight: editData?.weightOfCarcasses || "", + quarantineCode: editData?.clearanceCode || "", + date: editData?.date ? moment(editData.date) : moment(), + }, + validationSchema, + enableReinitialize: true, + }); + + const successSubmit = () => { + dispatch(CLOSE_MODAL()); + openNotif({ + vertical: "top", + horizontal: "center", + msg: "وزن با موفقیت ویرایش شد.", + severity: "success", + }); + dispatch(fetchSlaughterBroadcastAndProducts()); + fetchApiData(1); + fetchDashboardData(); + }; + + return ( + + + + + { + formik.setFieldValue("date", value); + }} + onBlur={() => formik.setFieldTouched("date", true)} + renderInput={(params) => ( + + )} + /> + + + + ); +}; diff --git a/src/features/province/components/province-steward-show-cold-houses-list-operations/ProvinceStewardShowColdHousesListOperations.js b/src/features/province/components/province-steward-show-cold-houses-list-operations/ProvinceStewardShowColdHousesListOperations.js new file mode 100644 index 0000000..0a6e5b1 --- /dev/null +++ b/src/features/province/components/province-steward-show-cold-houses-list-operations/ProvinceStewardShowColdHousesListOperations.js @@ -0,0 +1,82 @@ +import { IconButton, Popover, Tooltip } from "@mui/material"; +import React, { useState } from "react"; +import EditIcon from "@mui/icons-material/Edit"; +import TuneIcon from "@mui/icons-material/Tune"; +import { Grid } from "../../../../components/grid/Grid"; +import { useDispatch } from "react-redux"; +import { DRAWER } from "../../../../lib/redux/slices/appSlice"; +import { ProvinceColdHousesListAddColdHouse } from "../province-cold-houses-list-add-cold-house/ProvinceColdHousesListAddColdHouse"; + +export const ProvinceStewardShowColdHousesListOperations = ({ + item, + updateTable, +}) => { + const [anchorEl, setAnchorEl] = useState(null); + const dispatch = useDispatch(); + const handleClick = (event) => { + setAnchorEl(event.currentTarget); + }; + + const handleClose = () => { + setAnchorEl(null); + }; + + const open = Boolean(anchorEl); + const id = open ? "popover" : undefined; + + return ( +
    + + + + +
    + + + { + handleClose(); + dispatch( + DRAWER({ + title: "ویرایش سردخانه", + right: !(window.innerWidth <= 600), + bottom: window.innerWidth <= 600, + content: ( + + ), + }) + ); + }} + > + + + + +
    +
    +
    + ); +}; diff --git a/src/features/province/components/province-steward-show-cold-houses-list/ProvinceStewardShowColdHousesList.js b/src/features/province/components/province-steward-show-cold-houses-list/ProvinceStewardShowColdHousesList.js new file mode 100644 index 0000000..7f4f1fb --- /dev/null +++ b/src/features/province/components/province-steward-show-cold-houses-list/ProvinceStewardShowColdHousesList.js @@ -0,0 +1,185 @@ +import React, { useEffect, useState } from "react"; +import { Button, TextField } from "@mui/material"; + +import axios from "axios"; +import ResponsiveTable from "../../../../components/responsive-table/ResponsiveTable"; +import { Grid } from "../../../../components/grid/Grid"; +import { + DRAWER, + LOADING_END, + LOADING_START, +} from "../../../../lib/redux/slices/appSlice"; +import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl"; +import { useParams } from "react-router-dom"; +import { useDispatch } from "react-redux"; +import { ProvinceStewardShowColdHousesListOperations } from "../province-steward-show-cold-houses-list-operations/ProvinceStewardShowColdHousesListOperations"; +import { ProvinceColdHousesListAddColdHouse } from "../province-cold-houses-list-add-cold-house/ProvinceColdHousesListAddColdHouse"; +import { RiSearchLine } from "react-icons/ri"; + +export const ProvinceStewardShowColdHousesList = () => { + const dispatch = useDispatch(); + const handleTextChange = (event) => { + setTextValue(event.target.value); + }; + + const { key, name, type } = useParams(); + + const [data, setData] = useState([]); + const [totalRows, setTotalRows] = useState(0); + const [perPage, setPerPage] = useState(10); + const [textValue, setTextValue] = useState(""); + const [page, setPage] = useState(1); + const [tableData, setTableData] = useState([]); + + const fetchApiData = async (page) => { + let response; + dispatch(LOADING_START()); + response = await axios.get( + `cold-house-for-province/?search=filter&value=${textValue}&role=${getRoleFromUrl()}&page=${page}&page_size=${perPage}${ + type === "steward" ? `&type=Steward&steward_key=${key}` : "" + }${type === "killhouse" ? `&type=KillHouse&kill_house_key=${key}` : ""}` + ); + dispatch(LOADING_END()); + setData(response.data.results); + setTotalRows(response.data.count); + }; + + const handlePageChange = (page) => { + fetchApiData(page); + setPage(page); + }; + + const handlePerRowsChange = (perRows) => { + setPerPage(perRows); + setPage(1); + }; + + const updateTable = () => { + fetchApiData(page !== 0 ? page : 1); + }; + + useEffect(() => { + const d = data?.map((item, i) => { + return [ + page === 1 ? i + 1 : i + perPage * (page - 1) + 1, + item?.name, + item?.city, + item?.address, + item?.totalInputWeight?.toLocaleString(), + item?.totalAllocatedWeight?.toLocaleString(), + item?.totalRemainWeight?.toLocaleString(), + item?.active ? "فعال" : "غیر فعال", + item?.broadcast ? "دارد" : "ندارد", + item?.relocate ? "دارد" : "ندارد", + item?.capacity, + , + ]; + }); + + setTableData(d); + }, [data]); + + useEffect(() => { + fetchApiData(1); + }, [dispatch, perPage]); + + const handleSubmit = async (event) => { + event.preventDefault(); + dispatch(LOADING_START()); + + try { + const response = await axios.get( + `cold-house-for-province/?role=${getRoleFromUrl()}&search=filter&value=${textValue}&page=${1}&page_size=${perPage}${ + type === "steward" ? `&type=Steward&steward_key=${key}` : "" + }${type === "killhouse" ? `&type=KillHouse&kill_house_key=${key}` : ""}` + ); + setData(response.data.results); + setTotalRows(response.data.count); + dispatch(LOADING_END()); + } catch (error) { + console.error("Error fetching data:", error); + } + }; + + return ( + + + + + +
    + + + +
    +
    + + +
    + ); +}; diff --git a/src/features/province/components/province-sub-sector-city-shares-deposits-deposits-operations/ProvinceSubSectorCitySharesDepositsDepositsOperations.js b/src/features/province/components/province-sub-sector-city-shares-deposits-deposits-operations/ProvinceSubSectorCitySharesDepositsDepositsOperations.js new file mode 100644 index 0000000..7ec85b4 --- /dev/null +++ b/src/features/province/components/province-sub-sector-city-shares-deposits-deposits-operations/ProvinceSubSectorCitySharesDepositsDepositsOperations.js @@ -0,0 +1,195 @@ +import React, { useContext, useState } from "react"; +import { + Button, + IconButton, + Popover, + List, + ListItemButton, + ListItemIcon, + ListItemText, + Typography, +} from "@mui/material"; +import EditIcon from "@mui/icons-material/Edit"; +import TuneIcon from "@mui/icons-material/Tune"; +import DeleteIcon from "@mui/icons-material/Delete"; +import { useDispatch } from "react-redux"; +import { Grid } from "../../../../components/grid/Grid"; +import { + CLOSE_MODAL, + DRAWER, + OPEN_MODAL, +} from "../../../../lib/redux/slices/appSlice"; +import { ProvinceSubSectorCitySharesDepositsSubmit } from "../province-sub-sector-city-shares-deposits-submit/ProvinceSubSectorCitySharesDepositsSubmit"; +import { AppContext } from "../../../../contexts/AppContext"; +import { provinceSubSectorCitySharesWageDetailsDeleteDepositService } from "../../services/province-sub-sectors-services"; + +export const ProvinceSubSectorCitySharesDepositsDepositsOperations = ({ + item, + updateTable, + type, +}) => { + const dispatch = useDispatch(); + + const [anchorEl, setAnchorEl] = useState(null); + + const handleClick = (event) => { + setAnchorEl(event.currentTarget); + }; + + const handleClose = () => { + setAnchorEl(null); + }; + + const open = Boolean(anchorEl); + const id = open ? "popover" : undefined; + + const [openNotif] = useContext(AppContext); + + const handleEdit = () => { + handleClose(); + dispatch( + DRAWER({ + title: "ویرایش واریزی", + right: !(window.innerWidth <= 600), + bottom: window.innerWidth <= 600, + content: ( + + ), + }) + ); + }; + + const handleDelete = () => { + handleClose(); + dispatch( + OPEN_MODAL({ + title: "آیا مطمئن هستید؟", + content: ( + + + + + ), + }) + ); + }; + + const options = [ + { + key: "edit", + label: "ویرایش", + color: "primary.main", + icon: , + action: handleEdit, + }, + { + key: "delete", + label: "حذف", + color: "error.main", + icon: , + action: handleDelete, + }, + ]; + + return ( + + + + + + + {options.map((option) => ( + + + {option.icon} + + + {option.label} + + } + /> + + ))} + + + + ); +}; diff --git a/src/features/province/components/province-sub-sector-city-shares-deposits-deposits/ProvinceSubSectorCitySharesDepositsDeposits.js b/src/features/province/components/province-sub-sector-city-shares-deposits-deposits/ProvinceSubSectorCitySharesDepositsDeposits.js new file mode 100644 index 0000000..7746c76 --- /dev/null +++ b/src/features/province/components/province-sub-sector-city-shares-deposits-deposits/ProvinceSubSectorCitySharesDepositsDeposits.js @@ -0,0 +1,229 @@ +import React, { useContext, useEffect, useState } from "react"; +import { Button, TextField, Tooltip } from "@mui/material"; +import { DatePicker } from "@mui/x-date-pickers"; +import moment from "moment"; +import { useDispatch, useSelector } from "react-redux"; +import axios from "axios"; +import { AppContext } from "../../../../contexts/AppContext"; +import { + DRAWER, + LOADING_END, + LOADING_START, +} from "../../../../lib/redux/slices/appSlice"; +import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl"; +import { Grid } from "../../../../components/grid/Grid"; +import ResponsiveTable from "../../../../components/responsive-table/ResponsiveTable"; +import { ProvinceSubSectorCitySharesDepositsSubmit } from "../province-sub-sector-city-shares-deposits-submit/ProvinceSubSectorCitySharesDepositsSubmit"; +import { formatJustDate } from "../../../../utils/formatTime"; +import ShowImage from "../../../../components/show-image/ShowImage"; +import { ProvinceSubSectorCitySharesDepositsDepositsOperations } from "../province-sub-sector-city-shares-deposits-deposits-operations/ProvinceSubSectorCitySharesDepositsDepositsOperations"; +import { RiFileExcel2Fill } from "react-icons/ri"; +import { RiSearchLine } from "react-icons/ri"; + +export const ProvinceSubSectorCitySharesDepositsDeposits = () => { + const [, , selectedDate1, setSelectedDate1, selectedDate2, setSelectedDate2] = + useContext(AppContext); + const dispatch = useDispatch(); + const userKey = useSelector((state) => state.userSlice.userProfile.key); + + useEffect(() => { + const currentDate = moment(new Date()).format("YYYY-MM-DD"); + setSelectedDate1(currentDate); + setSelectedDate2(currentDate); + }, []); + + const handleTextChange = (event) => { + setTextValue(event.target.value); + }; + + const [data, setData] = useState([]); + const [totalRows, setTotalRows] = useState(0); + const [perPage, setPerPage] = useState(10); + const [textValue, setTextValue] = useState(""); + const [page, setPage] = useState(1); + const [tableData, setTableData] = useState([]); + + const fetchApiData = async (page) => { + let response; + dispatch(LOADING_START()); + response = await axios.get( + `sub-sector-transactions/?search=filter&value=${textValue}&role=${getRoleFromUrl()}&date1=${selectedDate1}&date2=${selectedDate2}&page=${page}&page_size=${perPage}&type=city` + ); + dispatch(LOADING_END()); + setData(response.data.results); + setTotalRows(response.data.count); + }; + + const handlePageChange = (page) => { + fetchApiData(page); + setPage(page); + }; + + const handlePerRowsChange = (perRows) => { + setPerPage(perRows); + setPage(1); + }; + + const updateTable = () => { + fetchApiData(page !== 0 ? page : 1); + }; + + useEffect(() => { + const d = data?.map((item, i) => { + return [ + page === 1 ? i + 1 : i + perPage * (page - 1) + 1, + item?.cityOperator?.unitName, + item?.cityOperator?.user?.city, + `${item?.cityOperator?.user?.fullname} (${item?.cityOperator?.user?.mobile})`, + formatJustDate(item?.createDate), + item?.fromAccount, + item?.toAccount, + item?.type === "online" ? "آنلاین" : "توسط بانک", + item?.amount?.toLocaleString(), + , + , + ]; + }); + + setTableData(d); + }, [data]); + + useEffect(() => { + fetchApiData(1); + }, [dispatch, selectedDate1, selectedDate2, perPage]); + + const handleSubmit = async (event) => { + event.preventDefault(); + dispatch(LOADING_START()); + + try { + const response = await axios.get( + `sub-sector-transactions/?role=${getRoleFromUrl()}&search=filter&value=${textValue}&date1=${selectedDate1}&date2=${selectedDate2}&page=${1}&page_size=${perPage}&type=city` + ); + setData(response.data.results); + setTotalRows(response.data.count); + dispatch(LOADING_END()); + } catch (error) { + console.error("Error fetching data:", error); + } + }; + + return ( + + + + + ( + + )} + value={selectedDate1} + onChange={(e) => { + setSelectedDate1(moment(e).format("YYYY-MM-DD")); + }} + /> + + + ( + + )} + value={selectedDate2} + onChange={(e) => { + setSelectedDate2(moment(e).format("YYYY-MM-DD")); + }} + /> + + +
    + + + +
    + + + + + +
    + + +
    + ); +}; diff --git a/src/features/province/components/province-sub-sector-city-shares-deposits-submit/ProvinceSubSectorCitySharesDepositsSubmit.js b/src/features/province/components/province-sub-sector-city-shares-deposits-submit/ProvinceSubSectorCitySharesDepositsSubmit.js new file mode 100644 index 0000000..f81f379 --- /dev/null +++ b/src/features/province/components/province-sub-sector-city-shares-deposits-submit/ProvinceSubSectorCitySharesDepositsSubmit.js @@ -0,0 +1,344 @@ +import React, { useContext, useEffect, useState } from "react"; +import { Grid } from "../../../../components/grid/Grid"; +import { + Autocomplete, + Button, + FormControlLabel, + Radio, + RadioGroup, + TextField, +} from "@mui/material"; +import { Yup } from "../../../../lib/yup/yup"; +import { useFormik } from "formik"; +import moment from "moment"; +import { DatePicker } from "@mui/x-date-pickers"; +import { ImageUpload } from "../../../../components/image-upload/ImageUpload"; +import { fixBase64 } from "../../../../utils/toBase64"; +import { + provinceSubSectorCitySharesGeyCitisService, + provinceSubSectorCitySharesWageDetailsEditDepositService, + provinceSubSectorCitySharesWageDetailsSubmitDepositService, + provinceSubSectorStewardSharesGeyVetFarmsService, + provinceSubSectorVetFarmSharesGeyVetFarmsService, +} from "../../services/province-sub-sectors-services"; +import { useDispatch } from "react-redux"; +import { DRAWER } from "../../../../lib/redux/slices/appSlice"; +import { AppContext } from "../../../../contexts/AppContext"; +import { resizeImage } from "../../../../utils/resizeImage"; +import ShowImage from "../../../../components/show-image/ShowImage"; + +export const ProvinceSubSectorCitySharesDepositsSubmit = ({ + updateTable, + isEdit, + item, + type, +}) => { + const [openNotif] = useContext(AppContext); + const [profileImages, setProfileImages] = useState([]); + const [receiverOptions, setReceiverOptions] = useState([]); + const dispatch = useDispatch(); + useEffect(() => { + if (!isEdit) { + if (type === "city") { + dispatch(provinceSubSectorCitySharesGeyCitisService()).then((r) => { + setReceiverOptions(r.payload.data); + }); + } else if (type === "vet") { + dispatch(provinceSubSectorVetFarmSharesGeyVetFarmsService()).then( + (r) => { + setReceiverOptions(r.payload.data); + } + ); + } else { + dispatch(provinceSubSectorStewardSharesGeyVetFarmsService()).then( + (r) => { + setReceiverOptions(r.payload.data); + } + ); + } + } + }, []); + + const formik = useFormik({ + initialValues: { + from_account: isEdit ? item?.fromAccount : "", + to_account: isEdit ? item?.toAccount : "", + receiver_key: isEdit ? "check" : "", + type: isEdit ? item?.type : "online", + amount: isEdit ? item?.amount : "", + transaction_image: isEdit ? [item?.image] : "", + selectedDate1: isEdit + ? item?.createDate + : moment(new Date()).format("YYYY-MM-DD hh:mm:ss"), + }, + validationSchema: Yup.object({ + from_account: Yup.string().required("این فیلد اجباری است!"), + // .matches(/^\d{16}$/, "شماره حساب باید 16 رقمی باشد!"), + to_account: Yup.string().required("این فیلد اجباری است!"), + amount: Yup.number() + .required("این فیلد اجباری است!") + .typeError("لطفا عدد وارد کنید!"), + receiver_key: Yup.string().required("این فیلد اجباری است!"), + transaction_image: Yup.array().required("این فیلد اجباری است!"), + }), + }); + + const factorPaymentHandler = (imageList, addUpdateIndex) => { + if (imageList.length === 0) { + formik.setFieldValue("transaction_image", []); + setProfileImages([]); + } else { + const resizedImagesPromises = imageList.map( + (image) => + new Promise((resolve) => { + const file = image.file; + resizeImage(file, (resizedDataUrl) => { + resolve(fixBase64(resizedDataUrl)); + }); + }) + ); + + Promise.all(resizedImagesPromises).then((resizedImages) => { + formik.setFieldValue("transaction_image", resizedImages); + setProfileImages(imageList); + }); + } + }; + useEffect(() => { + formik.validateForm(); + }, []); + + return ( + + + {!isEdit && ( + ({ + id: i.key, + label: + type === "city" + ? `${i.unitName} / ${i.user?.fullname} ` + : `${i.user?.fullname} / ${i.user?.mobile} `, + item: i, + })) + : [] + } + value={formik.values.guild} + onChange={(e, item) => { + formik.setFieldValue("receiver_key", item?.id); + formik.validateForm(); + }} + error={ + formik.touched.receiver_key && Boolean(formik.errors.receiver_key) + } + helperText={ + formik.touched.receiver_key && formik.errors.receiver_key + } + getOptionLabel={(option) => option.label} + renderInput={(params) => ( + + )} + /> + )} + + + + } + value={formik.values.selectedDate1} + onChange={(e) => { + formik.setFieldValue( + "selectedDate1", + moment(e).format("YYYY-MM-DD hh:mm:ss") + ); + }} + /> + + + + + + + + + + + + + + + + } label="آنلاین" /> + } label="توسط بانک" /> + + + + + {isEdit && formik.values.transaction_image[0]?.includes("https") && ( + + + + )} + + + + ); +}; diff --git a/src/features/province/components/province-sub-sector-city-shares-deposits/ProvinceSubSectorCitySharesDeposits.js b/src/features/province/components/province-sub-sector-city-shares-deposits/ProvinceSubSectorCitySharesDeposits.js new file mode 100644 index 0000000..60edc86 --- /dev/null +++ b/src/features/province/components/province-sub-sector-city-shares-deposits/ProvinceSubSectorCitySharesDeposits.js @@ -0,0 +1,142 @@ +import React, { useEffect, useState } from "react"; +import { Grid } from "../../../../components/grid/Grid"; +import ResponsiveTable from "../../../../components/responsive-table/ResponsiveTable"; +import { useDispatch } from "react-redux"; +import { + provinceSubSectorCitySharesDepositssDashboard, + provinceSubSectorCitySharesWageDetailsService, +} from "../../services/province-sub-sectors-services"; +import { SPACING } from "../../../../data/spacing"; +import { Tab, Tabs } from "@mui/material"; +import { ProvinceSubSectorCitySharesDepositsDeposits } from "../province-sub-sector-city-shares-deposits-deposits/ProvinceSubSectorCitySharesDepositsDeposits"; + +export const ProvinceSubSectorCitySharesDeposits = () => { + const dispatch = useDispatch(); + const [selectedTab, setSelectedTab] = useState(0); + + const handleTabChange = (event, newValue) => { + setSelectedTab(newValue); + }; + const [tableData, setTableData] = useState([]); + const [dashboardData, setDashboardData] = useState([]); + + useEffect(() => { + dispatch(provinceSubSectorCitySharesDepositssDashboard()).then((r) => { + setDashboardData(r.payload.data); + }); + + if (selectedTab === 0) { + dispatch(provinceSubSectorCitySharesWageDetailsService()).then((r) => { + const d = r.payload.data?.map((item, i) => { + return [ + i + 1, + item?.unitName, + item?.user?.city, + `${item?.user?.fullname} (${item?.user?.mobile})`, + Math.round( + item?.wageInfo?.outProvincePoultryRequestAmount + )?.toLocaleString(), + Math.round( + item?.wageInfo?.totalPureInternalProvinceCarcassesAmount + )?.toLocaleString(), + Math.round( + item?.wageInfo?.totalPureExternalProvinceCarcassesWeight + )?.toLocaleString(), + Math.round(item?.wageInfo?.totalWageAmount)?.toLocaleString(), + Math.round(item?.wageInfo?.numberOfCityDeposit)?.toLocaleString(), + Math.round(item?.wageInfo?.cityDeposit)?.toLocaleString(), + Math.round(item?.wageInfo?.totalRemainWageAmount)?.toLocaleString(), + ]; + }); + setTableData(d); + }); + } + }, [dispatch, selectedTab]); + + return ( + + + + + + + + + + + + + {selectedTab === 0 && ( + + )} + + {selectedTab === 1 && } + + ); +}; diff --git a/src/features/province/components/province-sub-sector-city-shares-shares-edit/ProvinceSubSectorCitySharesSharesEdit.js b/src/features/province/components/province-sub-sector-city-shares-shares-edit/ProvinceSubSectorCitySharesSharesEdit.js new file mode 100644 index 0000000..a45ac93 --- /dev/null +++ b/src/features/province/components/province-sub-sector-city-shares-shares-edit/ProvinceSubSectorCitySharesSharesEdit.js @@ -0,0 +1,86 @@ +import React, { useContext, useEffect } from "react"; +import { Grid } from "../../../../components/grid/Grid"; +import { Button, TextField } from "@mui/material"; +import { useFormik } from "formik"; +import { Yup } from "../../../../lib/yup/yup"; +import { useDispatch } from "react-redux"; +import { AppContext } from "../../../../contexts/AppContext"; +import { provinceSubSectorCitySharesSharesService } from "../../services/province-sub-sectors-services"; +import { CLOSE_MODAL } from "../../../../lib/redux/slices/appSlice"; + +export const ProvinceSubSectorCitySharesSharesEdit = ({ + updateTable, + item, +}) => { + const dispatch = useDispatch(); + const [openNotif] = useContext(AppContext); + + const formik = useFormik({ + initialValues: { + percent: item?.percent ? item?.percent : "", + }, + validationSchema: Yup.object({ + percent: Yup.number() + .typeError("لطفا فیلد را به درستی وارد کنید!") + .max(100, "درصد صحیح وارد کنید") + .required("این فیلد اجباری است!"), + }), + }); + + useEffect(() => { + formik.validateForm(); + }, []); + + return ( + + + + + ); +}; diff --git a/src/features/province/components/province-sub-sector-city-shares-shares/ProvinceSubSectorCitySharesShares.js b/src/features/province/components/province-sub-sector-city-shares-shares/ProvinceSubSectorCitySharesShares.js new file mode 100644 index 0000000..d1b61be --- /dev/null +++ b/src/features/province/components/province-sub-sector-city-shares-shares/ProvinceSubSectorCitySharesShares.js @@ -0,0 +1,105 @@ +import React, { useEffect, useState } from "react"; +import { Grid } from "../../../../components/grid/Grid"; +import ResponsiveTable from "../../../../components/responsive-table/ResponsiveTable"; +import { useDispatch } from "react-redux"; +import { provinceSubSectorCitySharesService } from "../../services/province-sub-sectors-services"; +import { IconButton } from "@mui/material"; +import { OPEN_MODAL } from "../../../../lib/redux/slices/appSlice"; +import { ProvinceSubSectorCitySharesSharesEdit } from "../province-sub-sector-city-shares-shares-edit/ProvinceSubSectorCitySharesSharesEdit"; +import EditIcon from "@mui/icons-material/Edit"; + +export const ProvinceSubSectorCitySharesShares = () => { + const dispatch = useDispatch(); + const [tableData, setTableData] = useState([]); + + const getWageTypeFaType = (type) => { + let wageType = ""; + switch (type) { + case "province-kill-request": + wageType = "تعرفه کشتار و توزیع داخل استان"; + break; + case "carcasse-sell": + wageType = "تعرفه کشتار داخل استان و توزیع خارج استان"; + break; + case "poultry-sell-out-province": + wageType = "فروش زنده به خارج استان"; + break; + + default: + wageType = "تعرفه کشتار و توزیع داخل استان"; + break; + } + + return wageType; + }; + + const fetchData = () => { + dispatch(provinceSubSectorCitySharesService("city")).then((r) => { + const d = r.payload.data.map((item, i) => { + return [ + i + 1, + getWageTypeFaType(item?.percentageOfWageType?.wageType?.enName), + item?.percentageOfWageType?.wageType?.amount?.toLocaleString(), + Math.round( + (item?.percentageOfWageType?.wageType?.amount / 100) * + item?.percentageOfWageType?.wageType?.percentages?.filter( + (item) => item?.name === "اتحادیه" + )[0]?.percent + ), + item?.percent, + { + dispatch( + OPEN_MODAL({ + title: "ویرایش", + content: ( + + ), + }) + ); + }} + > + + , + ]; + }); + + setTableData(d); + }); + }; + useEffect(() => { + fetchData(); + }, [dispatch]); + + return ( + + + + + + ); +}; diff --git a/src/features/province/components/province-sub-sector-city-shares-wage-details/ProvinceSubSectorCitySharesWageDetails.js b/src/features/province/components/province-sub-sector-city-shares-wage-details/ProvinceSubSectorCitySharesWageDetails.js new file mode 100644 index 0000000..125ab77 --- /dev/null +++ b/src/features/province/components/province-sub-sector-city-shares-wage-details/ProvinceSubSectorCitySharesWageDetails.js @@ -0,0 +1,312 @@ +import React, { useContext, useEffect, useState } from "react"; +import { Grid } from "../../../../components/grid/Grid"; +import ResponsiveTable from "../../../../components/responsive-table/ResponsiveTable"; +import { useDispatch, useSelector } from "react-redux"; +import { + provinceSubSectorCitySharesWageDetailsDashboard, + provinceSubSectorCitySharesWageDetailsService, +} from "../../services/province-sub-sectors-services"; +import { Checkbox, IconButton, TextField, Tooltip } from "@mui/material"; +import SystemUpdateAltIcon from "@mui/icons-material/SystemUpdateAlt"; +import { AppContext } from "../../../../contexts/AppContext"; +import axios from "axios"; +import { DatePicker } from "@mui/x-date-pickers"; +import ToggleOffOutlinedIcon from "@mui/icons-material/ToggleOffOutlined"; +import ToggleOnIcon from "@mui/icons-material/ToggleOn"; +import moment from "moment"; + +export const ProvinceSubSectorCitySharesWageDetails = () => { + const userKey = useSelector((state) => state.userSlice.userProfile.key); + const [, , selectedDate1, setSelectedDate1, selectedDate2, setSelectedDate2] = + useContext(AppContext); + const [withDate, setWithDate] = useState(false); + + useEffect(() => { + const currentDate = moment(new Date()).format("YYYY-MM-DD"); + setSelectedDate1(currentDate); + setSelectedDate2(currentDate); + }, []); + + const dispatch = useDispatch(); + const [openNotif] = useContext(AppContext); + const [tableData, setTableData] = useState([]); + const [dashboardData, setDashboardData] = useState([]); + + useEffect(() => { + dispatch( + provinceSubSectorCitySharesWageDetailsDashboard({ + date1: withDate ? selectedDate1 : null, + date2: withDate ? selectedDate2 : null, + }) + ).then((r) => { + setDashboardData(r.payload.data); + }); + + dispatch( + provinceSubSectorCitySharesWageDetailsService({ + date1: withDate ? selectedDate1 : null, + date2: withDate ? selectedDate2 : null, + }) + ).then((r) => { + const d = r.payload.data?.map((item, i) => { + return [ + i + 1, + item?.unitName, + item?.user?.city, + `${item?.user?.fullname} (${item?.user?.mobile})`, + Math.round(item?.wageInfo?.poultries), + Math.round(item?.wageInfo?.hatchings), + Math.round(item?.wageInfo?.hatchingsQuantity)?.toLocaleString(), + Math.round( + item?.wageInfo?.totalProvinceKillRequestsQuantity + )?.toLocaleString(), + Math.round( + item?.wageInfo?.totalProvinceKillRequestsWeight + )?.toLocaleString(), + Math.round( + item?.wageInfo?.totalProvinceCarcassesWeight + )?.toLocaleString(), + Math.round( + item?.wageInfo?.totalPureInternalProvinceCarcassesWeight + )?.toLocaleString(), + Math.round( + item?.wageInfo?.totalPureExternalProvinceCarcassesWeight + )?.toLocaleString(), + Math.round( + item?.wageInfo?.outProvincePoultryRequestQuantity + )?.toLocaleString(), + Math.round( + item?.wageInfo?.outProvincePoultryRequestWeight + )?.toLocaleString(), + Math.round(item?.wageInfo?.totalKilledQuantity)?.toLocaleString(), + parseFloat(item?.wageInfo?.hatchingKillingPercent)?.toFixed(1), + Math.round( + item?.wageInfo?.outProvincePoultryRequestAmount + )?.toLocaleString(), + Math.round( + item?.wageInfo?.totalPureInternalProvinceCarcassesAmount + )?.toLocaleString(), + Math.round( + item?.wageInfo?.totalPureExternalProvinceCarcassesAmount + )?.toLocaleString(), + Math.round(item?.wageInfo?.totalWageAmount)?.toLocaleString(), + Math.round(item?.wageInfo?.cityDeposit)?.toLocaleString(), + Math.round(item?.wageInfo?.totalRemainWageAmount)?.toLocaleString(), + ]; + }); + setTableData(d); + }); + }, [dispatch, selectedDate1, selectedDate2, withDate]); + + return ( + + + } + checkedIcon={} + checked={withDate} + onChange={() => setWithDate(!withDate)} + color="primary" + size="large" + /> + + ( + + )} + value={selectedDate1} + onChange={(e) => { + setSelectedDate1(moment(e).format("YYYY-MM-DD")); + }} + /> + + + ( + + )} + value={selectedDate2} + onChange={(e) => { + setSelectedDate2(moment(e).format("YYYY-MM-DD")); + }} + /> + + + + + + + + + { + openNotif({ + vertical: "top", + horizontal: "center", + msg: "فایل اکسل در حال دانلود می باشد، این علمیات ممکن است زمان بر باشد لطفا صبر کنید.", + severity: "success", + }); + const link = `${ + axios.defaults.baseURL + }sub_section_of_cooperative_share_detail/?key=${userKey}${ + withDate + ? `&date1=${selectedDate1}&date2=${selectedDate2}` + : `` + }`; + window.location.href = link; + }} + > + + + + + } + columns={[ + "ردیف", + "تعاونی", + "شهر", + "کاربر", + "تعداد فارم", + "تعداد کل جوجه ریزی", + "حجم کل جوجه ریزی", + "حجم کل کشتار شده داخل استان", + "وزن کل کشتار شده داخل استان", + "وزن لاشه کشتار شده داخل استان", + "وزن لاشه توزیع داخل استان", + "وزن لاشه توزیع خارج استان", + "حجم فروش خارج از استان", + "وزن فروش خارج از استان", + "حجم کل کشتار شده", + "درصد کشتار شده نسبت به جوجه ریزی", + "تعرفه زنده خارج استان", + "تعرفه کشتار و توزیع داخل استان", + "تعرفه کشتار و توزیع خارج استان", + "مجموع تعرفه", + "واریزی اتحادیه", + "مانده تعرفه", + ]} + data={tableData} + title="جزئیات تعرفه" + /> + + ); +}; diff --git a/src/features/province/components/province-sub-sector-city-shares/ProvinceSubSectorCityShares.js b/src/features/province/components/province-sub-sector-city-shares/ProvinceSubSectorCityShares.js new file mode 100644 index 0000000..c2fd2f3 --- /dev/null +++ b/src/features/province/components/province-sub-sector-city-shares/ProvinceSubSectorCityShares.js @@ -0,0 +1,44 @@ +import React, { useState } from "react"; +import { Grid } from "../../../../components/grid/Grid"; +import { SPACING } from "../../../../data/spacing"; +import { Tab, Tabs } from "@mui/material"; +import { ProvinceSubSectorCitySharesWageDetails } from "../province-sub-sector-city-shares-wage-details/ProvinceSubSectorCitySharesWageDetails"; +import { ProvinceSubSectorCitySharesDeposits } from "../province-sub-sector-city-shares-deposits/ProvinceSubSectorCitySharesDeposits"; +import { ProvinceSubSectorCitySharesShares } from "../province-sub-sector-city-shares-shares/ProvinceSubSectorCitySharesShares"; + +export const ProvinceSubSectorCityShares = () => { + const [selectedTab, setSelectedTab] = useState(0); + + const handleTabChange = (event, newValue) => { + setSelectedTab(newValue); + }; + + return ( + + + + + + + + + + {selectedTab === 0 && } + {selectedTab === 1 && } + {selectedTab === 2 && } + + ); +}; diff --git a/src/features/province/components/province-sub-sector-steward-shares-deposits/ProvinceSubSectorStewardSharesDeposits.js b/src/features/province/components/province-sub-sector-steward-shares-deposits/ProvinceSubSectorStewardSharesDeposits.js new file mode 100644 index 0000000..d66b829 --- /dev/null +++ b/src/features/province/components/province-sub-sector-steward-shares-deposits/ProvinceSubSectorStewardSharesDeposits.js @@ -0,0 +1,229 @@ +import React, { useContext, useEffect, useState } from "react"; +import { Button, TextField, Tooltip } from "@mui/material"; +import { DatePicker } from "@mui/x-date-pickers"; +import moment from "moment"; +import { useDispatch, useSelector } from "react-redux"; +import axios from "axios"; +import { AppContext } from "../../../../contexts/AppContext"; +import { + DRAWER, + LOADING_END, + LOADING_START, +} from "../../../../lib/redux/slices/appSlice"; +import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl"; +import { Grid } from "../../../../components/grid/Grid"; +import ResponsiveTable from "../../../../components/responsive-table/ResponsiveTable"; +import { ProvinceSubSectorCitySharesDepositsSubmit } from "../province-sub-sector-city-shares-deposits-submit/ProvinceSubSectorCitySharesDepositsSubmit"; +import { formatJustDate } from "../../../../utils/formatTime"; +import ShowImage from "../../../../components/show-image/ShowImage"; +import { ProvinceSubSectorCitySharesDepositsDepositsOperations } from "../province-sub-sector-city-shares-deposits-deposits-operations/ProvinceSubSectorCitySharesDepositsDepositsOperations"; +import { RiFileExcel2Fill } from "react-icons/ri"; +import { RiSearchLine } from "react-icons/ri"; + +export const ProvinceSubSectorStewardSharesDeposits = () => { + const [, , selectedDate1, setSelectedDate1, selectedDate2, setSelectedDate2] = + useContext(AppContext); + const dispatch = useDispatch(); + const userKey = useSelector((state) => state.userSlice.userProfile.key); + + useEffect(() => { + const currentDate = moment(new Date()).format("YYYY-MM-DD"); + setSelectedDate1(currentDate); + setSelectedDate2(currentDate); + }, []); + + const handleTextChange = (event) => { + setTextValue(event.target.value); + }; + + const [data, setData] = useState([]); + const [totalRows, setTotalRows] = useState(0); + const [perPage, setPerPage] = useState(10); + const [textValue, setTextValue] = useState(""); + const [page, setPage] = useState(1); + const [tableData, setTableData] = useState([]); + + const fetchApiData = async (page) => { + let response; + dispatch(LOADING_START()); + response = await axios.get( + `sub-sector-transactions/?search=filter&value=${textValue}&role=${getRoleFromUrl()}&date1=${selectedDate1}&date2=${selectedDate2}&page=${page}&page_size=${perPage}&type=guild` + ); + dispatch(LOADING_END()); + setData(response.data.results); + setTotalRows(response.data.count); + }; + + const handlePageChange = (page) => { + fetchApiData(page); + setPage(page); + }; + + const handlePerRowsChange = (perRows) => { + setPerPage(perRows); + setPage(1); + }; + + const updateTable = () => { + fetchApiData(page !== 0 ? page : 1); + }; + + useEffect(() => { + const d = data?.map((item, i) => { + return [ + page === 1 ? i + 1 : i + perPage * (page - 1) + 1, + `${item?.cityGuild?.user?.fullname} (${item?.cityGuild?.user?.mobile})`, + formatJustDate(item?.createDate), + item?.fromAccount, + item?.toAccount, + item?.type === "online" ? "آنلاین" : "توسط بانک", + item?.amount?.toLocaleString(), + , + , + ]; + }); + + setTableData(d); + }, [data]); + + useEffect(() => { + fetchApiData(1); + }, [dispatch, selectedDate1, selectedDate2, perPage]); + + const handleSubmit = async (event) => { + event.preventDefault(); + dispatch(LOADING_START()); + + try { + const response = await axios.get( + `sub-sector-transactions/?role=${getRoleFromUrl()}&search=filter&value=${textValue}&date1=${selectedDate1}&date2=${selectedDate2}&page=${1}&page_size=${perPage}&type=vet` + ); + setData(response.data.results); + setTotalRows(response.data.count); + dispatch(LOADING_END()); + } catch (error) { + console.error("Error fetching data:", error); + } + }; + + return ( + + + + + ( + + )} + value={selectedDate1} + onChange={(e) => { + setSelectedDate1(moment(e).format("YYYY-MM-DD")); + }} + /> + ( + + )} + value={selectedDate2} + onChange={(e) => { + setSelectedDate2(moment(e).format("YYYY-MM-DD")); + }} + /> + + + +
    + + + +
    + + + + + +
    + + +
    + ); +}; diff --git a/src/features/province/components/province-sub-sector-steward-shares-overview/ProvinceSubSectorStewardSharesOverview.js b/src/features/province/components/province-sub-sector-steward-shares-overview/ProvinceSubSectorStewardSharesOverview.js new file mode 100644 index 0000000..67e4cdb --- /dev/null +++ b/src/features/province/components/province-sub-sector-steward-shares-overview/ProvinceSubSectorStewardSharesOverview.js @@ -0,0 +1,51 @@ +import React, { useEffect, useState } from "react"; +import { Grid } from "../../../../components/grid/Grid"; +import ResponsiveTable from "../../../../components/responsive-table/ResponsiveTable"; +import { useDispatch } from "react-redux"; +import { provinceSubSectorStewardSharesStewardsService } from "../../services/province-sub-sectors-services"; + +export const ProvinceSubSectorStewardSharesOverview = ({ getParams }) => { + const dispatch = useDispatch(); + + const [tableData, setTableData] = useState([]); + + useEffect(() => { + dispatch(provinceSubSectorStewardSharesStewardsService(getParams())).then( + (r) => { + const d = r.payload.data?.map((item, i) => { + return [ + i + 1, + `${item?.user?.fullname} (${item?.user?.mobile})`, + item?.user?.city, + Math.round(item?.wageInfo?.buyWeight), + Math.round(item?.wageInfo?.sellWeight), + Math.round(item?.wageInfo?.totalWage), + Math.round(item?.wageInfo?.guildDeposit), + Math.round(item?.wageInfo?.remainWage), + ]; + }); + setTableData(d); + } + ); + }, [dispatch, getParams]); + + return ( + + + + ); +}; diff --git a/src/features/province/components/province-sub-sector-vet-farm-shares-deposits/ProvinceSubSectorVetFarmSharesDeposits.js b/src/features/province/components/province-sub-sector-vet-farm-shares-deposits/ProvinceSubSectorVetFarmSharesDeposits.js new file mode 100644 index 0000000..e67f799 --- /dev/null +++ b/src/features/province/components/province-sub-sector-vet-farm-shares-deposits/ProvinceSubSectorVetFarmSharesDeposits.js @@ -0,0 +1,229 @@ +import React, { useContext, useEffect, useState } from "react"; +import { Button, TextField, Tooltip } from "@mui/material"; +import { DatePicker } from "@mui/x-date-pickers"; +import moment from "moment"; +import { useDispatch, useSelector } from "react-redux"; +import axios from "axios"; +import { AppContext } from "../../../../contexts/AppContext"; +import { + DRAWER, + LOADING_END, + LOADING_START, +} from "../../../../lib/redux/slices/appSlice"; +import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl"; +import { Grid } from "../../../../components/grid/Grid"; +import ResponsiveTable from "../../../../components/responsive-table/ResponsiveTable"; +import { ProvinceSubSectorCitySharesDepositsSubmit } from "../province-sub-sector-city-shares-deposits-submit/ProvinceSubSectorCitySharesDepositsSubmit"; +import { formatJustDate } from "../../../../utils/formatTime"; +import ShowImage from "../../../../components/show-image/ShowImage"; +import { ProvinceSubSectorCitySharesDepositsDepositsOperations } from "../province-sub-sector-city-shares-deposits-deposits-operations/ProvinceSubSectorCitySharesDepositsDepositsOperations"; +import { RiFileExcel2Fill } from "react-icons/ri"; +import { RiSearchLine } from "react-icons/ri"; + +export const ProvinceSubSectorVetFarmSharesDeposits = () => { + const [, , selectedDate1, setSelectedDate1, selectedDate2, setSelectedDate2] = + useContext(AppContext); + const dispatch = useDispatch(); + const userKey = useSelector((state) => state.userSlice.userProfile.key); + + useEffect(() => { + const currentDate = moment(new Date()).format("YYYY-MM-DD"); + setSelectedDate1(currentDate); + setSelectedDate2(currentDate); + }, []); + + const handleTextChange = (event) => { + setTextValue(event.target.value); + }; + + const [data, setData] = useState([]); + const [totalRows, setTotalRows] = useState(0); + const [perPage, setPerPage] = useState(10); + const [textValue, setTextValue] = useState(""); + const [page, setPage] = useState(1); + const [tableData, setTableData] = useState([]); + + const fetchApiData = async (page) => { + let response; + dispatch(LOADING_START()); + response = await axios.get( + `sub-sector-transactions/?search=filter&value=${textValue}&role=${getRoleFromUrl()}&date1=${selectedDate1}&date2=${selectedDate2}&page=${page}&page_size=${perPage}&type=vet` + ); + dispatch(LOADING_END()); + setData(response.data.results); + setTotalRows(response.data.count); + }; + + const handlePageChange = (page) => { + fetchApiData(page); + setPage(page); + }; + + const handlePerRowsChange = (perRows) => { + setPerPage(perRows); + setPage(1); + }; + + const updateTable = () => { + fetchApiData(page !== 0 ? page : 1); + }; + + useEffect(() => { + const d = data?.map((item, i) => { + return [ + page === 1 ? i + 1 : i + perPage * (page - 1) + 1, + `${item?.vet?.user?.fullname} (${item?.vet?.user?.mobile})`, + formatJustDate(item?.createDate), + item?.fromAccount, + item?.toAccount, + item?.type === "online" ? "آنلاین" : "توسط بانک", + item?.amount?.toLocaleString(), + , + , + ]; + }); + + setTableData(d); + }, [data]); + + useEffect(() => { + fetchApiData(1); + }, [dispatch, selectedDate1, selectedDate2, perPage]); + + const handleSubmit = async (event) => { + event.preventDefault(); + dispatch(LOADING_START()); + + try { + const response = await axios.get( + `sub-sector-transactions/?role=${getRoleFromUrl()}&search=filter&value=${textValue}&date1=${selectedDate1}&date2=${selectedDate2}&page=${1}&page_size=${perPage}&type=vet` + ); + setData(response.data.results); + setTotalRows(response.data.count); + dispatch(LOADING_END()); + } catch (error) { + console.error("Error fetching data:", error); + } + }; + + return ( + + + + + ( + + )} + value={selectedDate1} + onChange={(e) => { + setSelectedDate1(moment(e).format("YYYY-MM-DD")); + }} + /> + ( + + )} + value={selectedDate2} + onChange={(e) => { + setSelectedDate2(moment(e).format("YYYY-MM-DD")); + }} + /> + + + +
    + + + +
    + + + + + +
    + + +
    + ); +}; diff --git a/src/features/province/components/province-sub-sector-vet-farm-shares-overview/ProvinceSubSectorVetFarmSharesOverview.js b/src/features/province/components/province-sub-sector-vet-farm-shares-overview/ProvinceSubSectorVetFarmSharesOverview.js new file mode 100644 index 0000000..a995ab9 --- /dev/null +++ b/src/features/province/components/province-sub-sector-vet-farm-shares-overview/ProvinceSubSectorVetFarmSharesOverview.js @@ -0,0 +1,65 @@ +import React, { useEffect, useState } from "react"; +import { Grid } from "../../../../components/grid/Grid"; +import ResponsiveTable from "../../../../components/responsive-table/ResponsiveTable"; +import { useDispatch } from "react-redux"; +import { provinceSubSectorVetFarmSharesVetFarmsService } from "../../services/province-sub-sectors-services"; + +export const ProvinceSubSectorVetFarmSharesOverview = ({ getParams }) => { + const dispatch = useDispatch(); + + const [tableData, setTableData] = useState([]); + + useEffect(() => { + dispatch(provinceSubSectorVetFarmSharesVetFarmsService(getParams())).then( + (r) => { + const d = r.payload.data?.map((item, i) => { + return [ + i + 1, + `${item?.user?.fullname} (${item?.user?.mobile})`, + item?.user?.city, + Math.round(item?.wageInfo?.totalQuantity), + Math.round(item?.wageInfo?.totalWeight), + Math.round( + item?.wageInfo?.totalPureInternalProvinceCarcassesAmount + )?.toLocaleString(), + Math.round( + item?.wageInfo?.totalPureExternalProvinceCarcassesAmount + )?.toLocaleString(), + Math.round( + item?.wageInfo?.outProvincePoultryRequestAmount + )?.toLocaleString(), + Math.round(item?.wageInfo?.totalWage)?.toLocaleString(), + Math.round(item?.wageInfo?.numberOfDeposit)?.toLocaleString(), + Math.round(item?.wageInfo?.vetDepositAmount)?.toLocaleString(), + Math.round(item?.wageInfo?.totalRemainWage)?.toLocaleString(), + ]; + }); + setTableData(d); + } + ); + }, [dispatch, getParams]); + + return ( + + + + ); +}; diff --git a/src/features/province/components/province-sub-sector-vet-farm-shares/ProvinceSubSectorVetFarmShares.js b/src/features/province/components/province-sub-sector-vet-farm-shares/ProvinceSubSectorVetFarmShares.js new file mode 100644 index 0000000..ec5d3ec --- /dev/null +++ b/src/features/province/components/province-sub-sector-vet-farm-shares/ProvinceSubSectorVetFarmShares.js @@ -0,0 +1,180 @@ +import React, { useContext, useEffect, useState } from "react"; +import { Grid } from "../../../../components/grid/Grid"; +import { SPACING } from "../../../../data/spacing"; +import { Checkbox, Tab, Tabs, TextField } from "@mui/material"; +import { ProvinceSubSectorVetFarmSharesOverview } from "../province-sub-sector-vet-farm-shares-overview/ProvinceSubSectorVetFarmSharesOverview"; +import { provinceSubSectorVetFarmSharesOverviewDashboard } from "../../services/province-sub-sectors-services"; +import { useDispatch } from "react-redux"; +import ResponsiveTable from "../../../../components/responsive-table/ResponsiveTable"; +import { ProvinceSubSectorVetFarmSharesDeposits } from "../province-sub-sector-vet-farm-shares-deposits/ProvinceSubSectorVetFarmSharesDeposits"; +import { DatePicker } from "@mui/x-date-pickers"; +import moment from "moment"; +import ToggleOffOutlinedIcon from "@mui/icons-material/ToggleOffOutlined"; +import ToggleOnIcon from "@mui/icons-material/ToggleOn"; +import { AppContext } from "../../../../contexts/AppContext"; + +export const ProvinceSubSectorVetFarmShares = () => { + const [, , selectedDate1, setSelectedDate1, selectedDate2, setSelectedDate2] = + useContext(AppContext); + const [selectedTab, setSelectedTab] = useState(0); + const [dashboardData, setDashboardData] = useState([]); + const [withDate, setWithDate] = useState(false); + const dispatch = useDispatch(); + useEffect(() => { + const currentDate = moment(new Date()).format("YYYY-MM-DD"); + setSelectedDate1(currentDate); + setSelectedDate2(currentDate); + }, []); + const handleTabChange = (event, newValue) => { + setSelectedTab(newValue); + }; + + const getParams = () => { + return { + date1: withDate ? selectedDate1 : null, + date2: withDate ? selectedDate2 : null, + }; + }; + + useEffect(() => { + dispatch(provinceSubSectorVetFarmSharesOverviewDashboard(getParams())).then( + (r) => { + setDashboardData(r.payload.data); + } + ); + }, [dispatch, selectedTab, selectedDate1, selectedDate2, withDate]); + + return ( + + + } + checkedIcon={} + checked={withDate} + onChange={() => setWithDate(!withDate)} + color="primary" + size="large" + /> + + ( + + )} + value={selectedDate1} + onChange={(e) => { + setSelectedDate1(moment(e).format("YYYY-MM-DD")); + }} + /> + + + ( + + )} + value={selectedDate2} + onChange={(e) => { + setSelectedDate2(moment(e).format("YYYY-MM-DD")); + }} + /> + + + + + + + + + + + + + + {selectedTab === 0 && ( + + )} + {selectedTab === 1 && } + + ); +}; diff --git a/src/features/province/components/province-sub-sector-wage-deposits/ProvinceSubSectorWageDeposits.js b/src/features/province/components/province-sub-sector-wage-deposits/ProvinceSubSectorWageDeposits.js new file mode 100644 index 0000000..77d9ae6 --- /dev/null +++ b/src/features/province/components/province-sub-sector-wage-deposits/ProvinceSubSectorWageDeposits.js @@ -0,0 +1,175 @@ +import { Checkbox, Tab, Tabs, TextField } from "@mui/material"; +import React, { useContext, useEffect, useState } from "react"; +import ResponsiveTable from "../../../../components/responsive-table/ResponsiveTable"; +import { Grid } from "../../../../components/grid/Grid"; +import { SPACING } from "../../../../data/spacing"; +import { useDispatch } from "react-redux"; +import { provinceSubSectorStewardSharesOverviewDashboard } from "../../services/province-sub-sectors-services"; +import { ProvinceSubSectorStewardSharesOverview } from "../province-sub-sector-steward-shares-overview/ProvinceSubSectorStewardSharesOverview"; +import { ProvinceSubSectorStewardSharesDeposits } from "../province-sub-sector-steward-shares-deposits/ProvinceSubSectorStewardSharesDeposits"; +import { AppContext } from "../../../../contexts/AppContext"; +import moment from "moment"; +import { DatePicker } from "@mui/x-date-pickers"; +import ToggleOffOutlinedIcon from "@mui/icons-material/ToggleOffOutlined"; +import ToggleOnIcon from "@mui/icons-material/ToggleOn"; +export const ProvinceSubSectorWageDeposits = () => { + const [, , selectedDate1, setSelectedDate1, selectedDate2, setSelectedDate2] = + useContext(AppContext); + const [selectedTab, setSelectedTab] = useState(0); + const [dashboardData, setDashboardData] = useState([]); + const [withDate, setWithDate] = useState(false); + const dispatch = useDispatch(); + useEffect(() => { + const currentDate = moment(new Date()).format("YYYY-MM-DD"); + setSelectedDate1(currentDate); + setSelectedDate2(currentDate); + }, []); + const handleTabChange = (event, newValue) => { + setSelectedTab(newValue); + }; + + const getParams = () => { + return { + date1: withDate ? selectedDate1 : null, + date2: withDate ? selectedDate2 : null, + }; + }; + + useEffect(() => { + dispatch(provinceSubSectorStewardSharesOverviewDashboard(getParams())).then( + (r) => { + setDashboardData(r.payload.data); + } + ); + }, [dispatch, selectedTab, selectedDate1, selectedDate2, withDate]); + + return ( + + + + } + checkedIcon={} + checked={withDate} + onChange={() => setWithDate(!withDate)} + color="primary" + size="large" + /> + + ( + + )} + value={selectedDate1} + onChange={(e) => { + setSelectedDate1(moment(e).format("YYYY-MM-DD")); + }} + /> + + + ( + + )} + value={selectedDate2} + onChange={(e) => { + setSelectedDate2(moment(e).format("YYYY-MM-DD")); + }} + /> + + + + + + + + + + + + + {selectedTab === 0 && ( + + )} + {selectedTab === 1 && } + + ); +}; diff --git a/src/features/province/components/province-sub-sector-wage-operations/ProvinceSubSectorWageOperations.js b/src/features/province/components/province-sub-sector-wage-operations/ProvinceSubSectorWageOperations.js new file mode 100644 index 0000000..be41afa --- /dev/null +++ b/src/features/province/components/province-sub-sector-wage-operations/ProvinceSubSectorWageOperations.js @@ -0,0 +1,109 @@ +import { useLocation } from "react-router-dom"; +import { Grid } from "../../../../components/grid/Grid"; +import { SPACING } from "../../../../data/spacing"; +import { NavLink } from "../../../../components/nav-link/NavLink"; +import LinkItem from "../../../../components/link-item/LinkItem"; +import { VscTag } from "react-icons/vsc"; +import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl"; +import { + ROUTE_ADMINX_SUB_SECTORS_STEWARD_SHARES, + ROUTE_ADMINX_SUB_SECTORS_CITY_SHARES, + ROUTE_ADMINX_SUB_SECTORS_VET_FARM_SHARES, + ROUTE_PROVINCE_FINANCIAL_SUB_SECTORS_STEWARD_SHARES, + ROUTE_PROVINCE_FINANCIAL_SUB_SECTORS_CITY_SHARES, + ROUTE_PROVINCE_FINANCIAL_SUB_SECTORS_VET_FARM_SHARES, + ROUTE_PROVINCE_SUB_SECTORS_STEWARD_SHARES, + ROUTE_PROVINCE_SUB_SECTORS_CITY_SHARES, + ROUTE_PROVINCE_SUB_SECTORS_VET_FARM_SHARES, + ROUTE_SUPER_ADMIN_SUB_SECTORS_STEWARD_SHARES, + ROUTE_SUPER_ADMIN_SUB_SECTORS_CITY_SHARES, + ROUTE_SUPER_ADMIN_SUB_SECTORS_VET_FARM_SHARES, +} from "../../../../routes/routes"; + +export const ProvinceSubSectorWageOperations = () => { + const { pathname } = useLocation(); + + return ( + + + + + } + title="سهم تعاونی" + description="سهم تعاونی" + /> + + + + } + title="سهم دامپزشک فارم" + description="سهم دامپزشک فارم" + /> + + + + } + title="سهم صنف" + description="سهم صنف" + /> + + + + + ); +}; diff --git a/src/features/province/components/province-submit-bar-difference/ProvinceSubmitBarDifference.js b/src/features/province/components/province-submit-bar-difference/ProvinceSubmitBarDifference.js new file mode 100644 index 0000000..cba3c24 --- /dev/null +++ b/src/features/province/components/province-submit-bar-difference/ProvinceSubmitBarDifference.js @@ -0,0 +1,497 @@ +import React, { useContext, useEffect, useState } from "react"; +import { Grid } from "../../../../components/grid/Grid"; +import { SPACING } from "../../../../data/spacing"; +import { + Autocomplete, + Button, + Paper, + Stack, + TextField, + Typography, +} from "@mui/material"; + +import { Yup } from "../../../../lib/yup/yup"; +import { useFormik } from "formik"; +import { useDispatch, useSelector } from "react-redux"; +import { slaughterGetPoultriesService } from "../../../slaughter-house/services/salughter-get-poultries"; +import { avicultureGetHatchingData } from "../../../aviculture/services/aviculture-get-hatching-data"; +import { slaughterGetKillerKillhousesService } from "../../../slaughter-house/services/slaughter-get-killers-killhouses"; +import { slaughterGetKillhousesService } from "../../../slaughter-house/services/slaughter-get-killhouses"; +import { + provinceEditBarDifferenceService, + provinceGetBarDifferenceInfoService, + provinceSubmitBarDifferenceService, +} from "../../services/province-bar-differences-services"; +import { AppContext } from "../../../../contexts/AppContext"; +import { DRAWER } from "../../../../lib/redux/slices/appSlice"; +import { ImageUpload } from "../../../../components/image-upload/ImageUpload"; +import { fixBase64 } from "../../../../utils/toBase64"; +import { resizeImage } from "../../../../utils/resizeImage"; +import { checkPathStartsWith } from "../../../../utils/checkPathStartsWith"; + +export const ProvinceSubmitBarDifference = ({ updateTable, isEdit, item }) => { + const [poultryData, setPoultryData] = useState(""); + const [openNotif] = useContext(AppContext); + const [selectedPolutry, setSelectedPolutry] = useState(""); + const [profileImages, setProfileImages] = useState([]); + const [diffInfo, setDiffInfo] = useState(null); + const selectedSubUser = useSelector( + (state) => state.userSlice.selectedSubUser + ); + const dispatch = useDispatch(); + const { slaughterGetPoultries, slaughterGetKillhouses } = useSelector( + (state) => state.slaughterSlice + ); + + useEffect(() => { + if (!isEdit) { + dispatch( + slaughterGetPoultriesService({ + role_key: checkPathStartsWith("slaughter") + ? selectedSubUser?.key || "" + : "", + }) + ); + dispatch( + slaughterGetKillerKillhousesService({ + role_key: checkPathStartsWith("slaughter") + ? selectedSubUser?.key || "" + : "", + }) + ); + dispatch( + slaughterGetKillhousesService({ + role_key: checkPathStartsWith("slaughter") + ? selectedSubUser?.key || "" + : "", + }) + ); + } + }, [selectedSubUser?.key]); + + const initialValues = { + killhouse: null, + killerPlace: null, + poultry: null, + hatching_key: null, + quantity: parseInt(item?.quantity) || null, + difference_image: null, + register_message: item?.registerMessage || null, + }; + + const validationSchema = Yup.object().shape({ + killhouse: Yup.string("") + .typeError("این فیلد الزامی است") + .required("این فیلد الزامی است"), + poultry: Yup.string("") + .typeError("این فیلد الزامی است") + .required("این فیلد الزامی است"), + poultryPrice: Yup.number().typeError("لطفا فیلد را به درستی وارد کنید!"), + hatching_key: Yup.string().required("این فیلد الزامی است"), + quantity: Yup.number() + .required("این فیلد الزامی است") + .typeError("لطفا فیلد را به درستی وارد کنید!"), + }); + + const formik = useFormik({ + initialValues, + validationSchema, + }); + + useEffect(() => { + if (formik.values.poultry) { + dispatch( + avicultureGetHatchingData({ + key: formik.values.poultry, + }) + ).then((r) => { + setPoultryData(r.payload.data); + }); + } + }, [formik.values.poultry, selectedSubUser?.key]); + + useEffect(() => { + formik.validateForm(); + }, [formik.values.quantity, dispatch]); + + const factorPaymentHandler = (imageList) => { + if (imageList.length === 0) { + formik.setFieldValue("difference_image", []); + setProfileImages([]); + } else { + const resizedImagesPromises = imageList.map( + (image) => + new Promise((resolve) => { + const file = image.file; + resizeImage(file, (resizedDataUrl) => { + resolve(fixBase64(resizedDataUrl)); + }); + }) + ); + + Promise.all(resizedImagesPromises).then((resizedImages) => { + formik.setFieldValue("difference_image", resizedImages); + setProfileImages(imageList); + }); + } + }; + + useEffect(() => { + if (formik.values.hatching_key && formik.values.killhouse) { + dispatch( + provinceGetBarDifferenceInfoService({ + hatching_key: formik.values.hatching_key, + kill_house_key: formik.values.killhouse, + role_key: checkPathStartsWith("slaughter") + ? selectedSubUser?.key || "" + : "", + }) + ).then((r) => { + setDiffInfo(r.payload.data); + }); + } + }, [ + formik.values.hatching_key, + formik.values.killhouse, + selectedSubUser?.key, + ]); + + return ( + + {!isEdit && ( + <> + {slaughterGetPoultries?.length ? ( + { + return { + label: `${item.unitName} (${item.user?.fullname})`, + value: item.key, + item, + }; + })} + getOptionLabel={(option) => option.label} + onChange={(_, value) => { + formik.setFieldValue("poultry", value.item.key); + }} + onBlur={formik.handleBlur} + renderInput={(params) => ( + + )} + /> + ) : ( + + موردی یافت نشد! + + )} + + {poultryData && ( + + { + return { + label: `${item?.poultry.unitName}`, + value: item.key, + item, + }; + })} + onChange={(event, value) => { + setSelectedPolutry(value.item); + formik.setFieldValue("hatching_key", value.value); + }} + renderInput={(params) => ( + + )} + /> + + )} + + {selectedPolutry && ( + <> + + + نام و نام خانوادگی: + + {selectedPolutry?.poultry?.userprofile?.fullName} + + + + تلفن: + + {selectedPolutry?.poultry?.userprofile?.mobile} + + + + آدرس: + + {`شهر ${selectedPolutry.poultry?.address?.city?.name} ${ + selectedPolutry?.poultry?.address?.address + ? "-" + selectedPolutry?.poultry?.address?.address + : "" + }`} + + + + سن جوجه: + {selectedPolutry?.chickenAge} روز + + + مانده در سالن: + + {selectedPolutry?.leftOver?.toLocaleString()} قطعه + + + + مانده فروش آزاد: + + {selectedPolutry?.freeGovernmentalInfo?.leftTotalFreeCommitmentQuantity?.toLocaleString()}{" "} + قطعه + + + + نژاد: + {selectedPolutry?.chickenBreed} + + + {slaughterGetKillhouses?.length && ( + { + const buyerNamePrefix = item?.killer + ? "کشتارکن" + : "کشتارگاه"; + return { + label: buyerNamePrefix + " " + item.name, + value: item.key, + killer: item.killer, + item: item, + // disabled: item.allowDirectBuying, + }; + })} + // getOptionDisabled={(option) => !option.disabled} + getOptionLabel={(option) => option.label} + onChange={(_, value) => { + formik.setFieldValue("killhouse", value.value); + }} + onBlur={formik.handleBlur} + renderInput={(params) => ( + + )} + /> + )} + {diffInfo && ( + + + + حجم کم شده از سالن مرغدار:{" "} + + {diffInfo.totalQuantity?.toLocaleString()} قطعه + + + + وزن تقریبی کشتار:{" "} + + {diffInfo.totalWeight?.toLocaleString()} کیلوگرم + + + + حجم سفارشات دریافتی توسط کشتارگاه: + + {diffInfo.firstTotalQuantity?.toLocaleString()} قطعه + + + + اختلاف کشتار(حجم): + + {diffInfo.differenceQuantity?.toLocaleString()} قطعه + + + + + )} + + )} + + )} + + {(isEdit || selectedPolutry) && ( + <> + + + + + + + + )} + + ); +}; diff --git a/src/features/province/components/province-submit-message/ProvinceSubmitMessage.js b/src/features/province/components/province-submit-message/ProvinceSubmitMessage.js new file mode 100644 index 0000000..8c3b2fb --- /dev/null +++ b/src/features/province/components/province-submit-message/ProvinceSubmitMessage.js @@ -0,0 +1,356 @@ +import { Box, Button, Divider, InputLabel, TextField } from "@mui/material"; +import { useFormik } from "formik"; +import * as React from "react"; +import { useTheme } from "@mui/material/styles"; +import OutlinedInput from "@mui/material/OutlinedInput"; +import MenuItem from "@mui/material/MenuItem"; +import FormControl from "@mui/material/FormControl"; +import Select from "@mui/material/Select"; +import Chip from "@mui/material/Chip"; + +import { useDispatch, useSelector } from "react-redux"; +import { provinceSendMessage } from "../../services/province-send-message"; +import { useContext } from "react"; +import { Yup } from "../../../../lib/yup/yup"; +import { fixBase64 } from "../../../../utils/toBase64"; +import { Grid } from "../../../../components/grid/Grid"; +import { SPACING } from "../../../../data/spacing"; +import { ImageUpload } from "../../../../components/image-upload/ImageUpload"; +import { + LOADING_END, + LOADING_START, +} from "../../../../lib/redux/slices/appSlice"; +import { AppContext } from "../../../../contexts/AppContext"; +import { useEffect } from "react"; +import { AutocompleteSelect } from "../../../../components/autocomplete-select/AutocompleteSelect"; +import { getEnRoleFromFa } from "../../../../utils/getEnRoleFromFa"; +// import { useState } from "react"; + +const ITEM_HEIGHT = 48; +const ITEM_PADDING_TOP = 8; +const MenuProps = { + PaperProps: { + style: { + maxHeight: ITEM_HEIGHT * 4.5 + ITEM_PADDING_TOP, + width: 250, + }, + }, +}; + +const names = ["شهرستان", "دامپزشک", "راننده", "مرغدار", "کشتارگاه", "مالی"]; + +function getStyles(name, personName, theme) { + return { + fontWeight: + personName.indexOf(name) === -1 + ? theme.typography.fontWeightRegular + : theme.typography.fontWeightMedium, + }; +} + +const ProvinceSubmitMessage = () => { + const [usersList, setUsersList] = React.useState([]); + const { provinceUsers } = useSelector((state) => state.provinceSlice); + + useEffect(() => { + setUsersList( + provinceUsers.map((user) => { + const userName = user.profile.fullname + ? user.profile.fullname + : `${user.profile.firstName} ${user.profile.lastName}`; + return { + id: user.profile.key, + title: `${userName}`, + }; + }) + ); + }, []); + + const formik = useFormik({ + initialValues: { + description: "", + linkText: "", + heading: "", + link: "", + usersList: [], + }, + validationSchema: Yup.object({ + description: Yup.string() + .required("لطفا پیغام خود را بنویسید!") + .typeError("لطفا فیلد را پر کنید!"), + heading: Yup.string() + .required("لطفا عنوان پیغام خود را بنویسید!") + .typeError("لطفا فیلد را پر کنید!"), + link: Yup.string().typeError("لطفا فیلد را پر کنید!"), + linkText: Yup.string().typeError("لطفا فیلد را پر کنید!"), + }), + }); + + useEffect(() => { + formik.validateForm(); + }, []); + + const theme = useTheme(); + const [personName, setPersonName] = React.useState([]); + // const [setPersonNameKey] = useState(""); + + const dispatch = useDispatch(); + const [openNotif] = useContext(AppContext); + + const [profileImages, setProfileImages] = React.useState([]); + const [imagesData, setImagesData] = React.useState([]); + + const imagesHandler = (imageList, addUpdateIndex) => { + setImagesData(imageList.map((img) => fixBase64(img.data_url))); + setProfileImages(imageList); + }; + + const handleChange = (event) => { + const { + target: { value }, + } = event; + setPersonName(typeof value === "string" ? value.split(",") : value); + + // const roles = [ + // "", + // "Poultry", + // "VetFarm", + // "Driver", + // "KillHouse", + // "ProvinceFinancial", + // ]; + }; + + return ( + <> + + + + + + + + + + + ارسال پیام بر اساس نقش + + + + + + + + { + const ids = item.map((item) => item.id); + formik.setFieldValue("usersList", ids); + }} + /> + + {/* + { + formik.setFieldValue("usersList", value.id); + }} + renderInput={(params) => ( + + )} + /> + */} + + + + + + + + + + + + + + + + + + + + + + + + + ); +}; + +export default ProvinceSubmitMessage; diff --git a/src/features/province/components/province-submit-price/ProvineSubmitPrice.js b/src/features/province/components/province-submit-price/ProvineSubmitPrice.js new file mode 100644 index 0000000..de982f0 --- /dev/null +++ b/src/features/province/components/province-submit-price/ProvineSubmitPrice.js @@ -0,0 +1,138 @@ +import React, { useContext } from "react"; +import { Grid } from "../../../../components/grid/Grid"; +import { SPACING } from "../../../../data/spacing"; +import { Button, TextField } from "@mui/material"; +import { Yup } from "../../../../lib/yup/yup"; +import { useFormik } from "formik"; +import { useDispatch } from "react-redux"; +import { AppContext } from "../../../../contexts/AppContext"; +import { DRAWER } from "../../../../lib/redux/slices/appSlice"; +import { provincePriceEditService } from "../../services/province-price-edit"; + +export const ProvineSubmitPrice = ({ updateTable, item }) => { + const [openNotif] = useContext(AppContext); + const dispatch = useDispatch(); + + const initialValues = { + kill_house_price: item?.killHousePrice || 0, + wholesaler_price: item?.wholesalerPrice || 0, + retailer_price: item?.retailerPrice || 0, + }; + + const validationSchema = Yup.object().shape({ + kill_house_price: Yup.number() + .required("این فیلد الزامی است") + .min(0, "مقدار نمی‌تواند منفی باشد"), + wholesaler_price: Yup.number() + .required("این فیلد الزامی است") + .min(0, "مقدار نمی‌تواند منفی باشد"), + retailer_price: Yup.number() + .required("این فیلد الزامی است") + .min(0, "مقدار نمی‌تواند منفی باشد"), + }); + + const formik = useFormik({ + initialValues, + validationSchema, + enableReinitialize: true, + }); + + const handleSubmit = () => { + dispatch( + provincePriceEditService({ + id: item?.id, + kill_house_price: Number(formik.values.kill_house_price), + wholesaler_price: Number(formik.values.wholesaler_price), + retailer_price: Number(formik.values.retailer_price), + }) + ).then((r) => { + if (r.payload?.error) { + openNotif({ + vertical: "top", + horizontal: "center", + msg: r.payload.error, + severity: "error", + }); + } else { + updateTable(); + openNotif({ + vertical: "top", + horizontal: "center", + msg: "قیمت‌ها با موفقیت ویرایش شدند", + severity: "success", + }); + dispatch( + DRAWER({ + right: false, + bottom: false, + content: null, + }) + ); + } + }); + }; + + return ( + + + + + + + + + + ); +}; diff --git a/src/features/province/components/province-submit-pricing/ProvinceSubmitPricing.js b/src/features/province/components/province-submit-pricing/ProvinceSubmitPricing.js new file mode 100644 index 0000000..27833d8 --- /dev/null +++ b/src/features/province/components/province-submit-pricing/ProvinceSubmitPricing.js @@ -0,0 +1,304 @@ +import { Button, InputAdornment, TextField } from "@mui/material"; +import { DatePicker } from "@mui/x-date-pickers"; +import { SPACING } from "../../../../data/spacing"; +import { useFormik } from "formik"; +import moment from "moment"; +import { Yup } from "../../../../lib/yup/yup"; +import { useDispatch } from "react-redux"; + +import { provinceGetPricing } from "../../services/province-get-pricing"; +import { provinceNewPricing } from "../../services/province-new-pricing"; +import { useEffect } from "react"; +import { + DRAWER, + LOADING_END, + LOADING_START, +} from "../../../../lib/redux/slices/appSlice"; +import { Grid } from "../../../../components/grid/Grid"; +import { useContext } from "react"; +import { AppContext } from "../../../../contexts/AppContext"; +import { NumberInput } from "../../../../components/number-format-custom/NumberFormatCustom"; + +export const ProvinceSubmitPricing = () => { + const [openNotif] = useContext(AppContext); + // const ProvincePrices = []; + const dispatch = useDispatch(); + + const formik = useFormik({ + initialValues: { + date: moment(Date()).format("YYYY-MM-DD hh:mm:ss"), + price: "", + // slaughtedprice: "", + // priceforseller: "", + floorprice: "", + ceilingprice: "", + }, + validationSchema: Yup.object({ + price: Yup.number() + .required("این فیلد اجباری است!") + .typeError("لطفا عدد وارد کنید!"), + // slaughtedprice: Yup.number() + // .required("این فیلد اجباری است!") + // .typeError("لطفا عدد وارد کنید!"), + // priceforseller: Yup.number() + // .required("این فیلد اجباری است!") + // .typeError("لطفا عدد وارد کنید!"), + // floorprice: Yup.number() + // .required("این فیلد اجباری است!") + // .typeError("لطفا عدد وارد کنید!"), + // ceilingprice: Yup.number() + // .required("این فیلد اجباری است!") + // .typeError("لطفا عدد وارد کنید!"), + }), + }); + + useEffect(() => { + formik.validateForm(); + }, []); + + return ( + + + } + value={formik.values.date} + error={formik.touched.date ? Boolean(formik.errors.date) : null} + onChange={(e) => { + formik.setFieldValue( + "date", + moment(e).format("YYYY-MM-DD hh:mm:ss") + ); + }} + onBlur={formik.handleBlur} + helperText={ + formik.touched.date && Boolean(formik.errors.date) + ? formik.errors.date + : null + } + /> + + + ریال + ), + }} + value={formik.values.price} + error={formik.touched.price ? Boolean(formik.errors.price) : null} + onChange={formik.handleChange} + onBlur={formik.handleBlur} + helperText={ + formik.touched.price && Boolean(formik.errors.price) + ? formik.errors.price + : null + } + /> + + + {/* + ریال + ), + }} + value={formik.values.slaughtedprice} + error={ + formik.touched.slaughtedprice + ? Boolean(formik.errors.slaughtedprice) + : null + } + onChange={formik.handleChange} + onBlur={formik.handleBlur} + helperText={ + formik.touched.slaughtedprice && + Boolean(formik.errors.slaughtedprice) + ? formik.errors.slaughtedprice + : null + } + /> + + + ریال + ), + }} + value={formik.values.priceforseller} + error={ + formik.touched.priceforseller + ? Boolean(formik.errors.priceforseller) + : null + } + onChange={formik.handleChange} + onBlur={formik.handleBlur} + helperText={ + formik.touched.priceforseller && + Boolean(formik.errors.priceforseller) + ? formik.errors.priceforseller + : null + } + /> + */} + + + ریال + ), + }} + value={formik.values.floorprice} + error={ + formik.touched.floorprice ? Boolean(formik.errors.floorprice) : null + } + onChange={formik.handleChange} + onBlur={formik.handleBlur} + helperText={ + formik.touched.floorprice && Boolean(formik.errors.floorprice) + ? formik.errors.floorprice + : null + } + /> + + + ریال + ), + }} + value={formik.values.ceilingprice} + error={ + formik.touched.ceilingprice + ? Boolean(formik.errors.ceilingprice) + : null + } + onChange={formik.handleChange} + onBlur={formik.handleBlur} + helperText={ + formik.touched.ceilingprice && Boolean(formik.errors.ceilingprice) + ? formik.errors.ceilingprice + : null + } + /> + + + + + + + ); +}; diff --git a/src/features/province/components/province-submit-product-price/ProvinceSubmitProductPrice.js b/src/features/province/components/province-submit-product-price/ProvinceSubmitProductPrice.js new file mode 100644 index 0000000..00f8bb6 --- /dev/null +++ b/src/features/province/components/province-submit-product-price/ProvinceSubmitProductPrice.js @@ -0,0 +1,89 @@ +import React, { useContext, useEffect } from "react"; +import { Grid } from "../../../../components/grid/Grid"; +import { useFormik } from "formik"; +import { Yup } from "../../../../lib/yup/yup"; +import { Button, TextField } from "@mui/material"; +import { useDispatch } from "react-redux"; +import { provinceSubmitProductPrice } from "../../services/province-submit-product-price"; +import { AppContext } from "../../../../contexts/AppContext"; +import { provinceGetProducts } from "../../services/province-get-producrs"; + +export const ProvinceSubmitProductPrice = ({ item }) => { + const [openNotif] = useContext(AppContext); + + const dispatch = useDispatch(); + const formik = useFormik({ + initialValues: { + price: "", + }, + validationSchema: Yup.object({ + price: Yup.string() + .required("این فیلد اجباری است!") + .typeError("لطفا فیلد را به درستی وارد کنید!"), + }), + }); + + useEffect(() => { + formik.validateForm(); + }, []); + + return ( + + + + + + + + + ); +}; diff --git a/src/features/province/components/province-submit-user/ProvinceSubmitUser.js b/src/features/province/components/province-submit-user/ProvinceSubmitUser.js new file mode 100644 index 0000000..d8d40f7 --- /dev/null +++ b/src/features/province/components/province-submit-user/ProvinceSubmitUser.js @@ -0,0 +1,2486 @@ +import { + Autocomplete, + Button, + Chip, + Divider, + FormControl, + FormHelperText, + IconButton, + InputLabel, + MenuItem, + Select, + TextField, + Typography, +} from "@mui/material"; + +import React, { useEffect } from "react"; +import { useFormik } from "formik"; + +import DeleteIcon from "@mui/icons-material/Delete"; +import AddIcon from "@mui/icons-material/Add"; + +import { AppContext } from "../../../../contexts/AppContext"; +import { Yup } from "../../../../lib/yup/yup"; +import { Grid } from "../../../../components/grid/Grid"; +import { SPACING } from "../../../../data/spacing"; +import { + DRAWER, + LOADING_END, + LOADING_START, +} from "../../../../lib/redux/slices/appSlice"; +import { cityGetProvinces } from "../../../city/services/CityGetProvinces"; +import { cityGetCity } from "../../../city/services/city-get-city"; +import { useDispatch } from "react-redux"; +import { useState } from "react"; +import { DatePicker } from "@mui/x-date-pickers"; +import moment from "moment"; +import SearchIcon from "@mui/icons-material/Search"; +import { provinceCheckUserExistence } from "../../services/province-check-user-existence"; +import { useContext } from "react"; +import { provinceRegisterUser } from "../../services/province-register-user"; +import { provinceGetUserProfiles } from "../../services/province-get-user-profiles"; +import { NumberInput } from "../../../../components/number-format-custom/NumberFormatCustom"; +import { provinceGetKillHouses } from "../../services/province-get-kill-houses"; +import { UserInfo } from "./components/userInfo"; +import { CarPelak } from "../../../../components/car-pelak/CarPelak"; + +export const ProvinceSubmitUser = (id) => { + const [openNotif] = useContext(AppContext); + + const [provinceData, setProvinceData] = useState([]); + const [cityData, setCityData] = useState([]); + const [provinceKey, setProvinceKey] = useState(); + const [cityKey, setCityKey] = useState(); + + const [killHouseProvinceKey, setKillHouseProvinceKey] = useState(); + const [killHouseVetProvinceKey, setKillHouseVetProvinceKey] = useState(); + const [killHouseCityKey, setKillHouseCityKey] = useState(); + const [killHouseVetCityKey, setKillHouseVetCityKey] = useState(); + + const [poultryProvinceKey, setPoultryProvincekey] = useState(); + const [poultryCityKey, setPoultryCityKey] = useState(); + + const [OperatorProvinceKey, setOperatorProvinceKey] = useState(); + const [OperatorCityKey, setOperatorCityKey] = useState(); + + const [userChecked, setUserChecked] = useState(false); + + const [isExistProvince, setIsExistProvince] = useState(true); + + const [userData, setUserData] = useState(); + + const dispatch = useDispatch(); + + const formik = useFormik({ + initialValues: { + mobile: "", + fname: "", + lname: "", + nationalcode: "", + password: "", + birthday: moment(Date()).format("YYYY-MM-DD hh:mm:ss"), + }, + validationSchema: Yup.object({ + mobile: Yup.number() + .required("این فیلد اجباری است!") + .typeError("لطفا فیلد را به صورت عددی وارد کنید!") + .test("len", "شماره تلفن باید با 0 شروع شود", (val, context) => { + return context.originalValue && context.originalValue.startsWith("0"); + }) + .test("len", "شماره تماس 11 رقم باید باشد", (val, context) => { + if (context.originalValue) { + return context.originalValue.length === 11; + } + }), + fname: Yup.string() + .required("این فیلد اجباری است!") + .typeError("لطفا فیلد را پر کنید!"), + lname: Yup.string() + .required("این فیلد اجباری است!") + .typeError("لطفا فیلد را پر کنید!"), + nationalcode: Yup.number() + .required("این فیلد اجباری است!") + .test("len", "کد ملی میبایست ده رقم باشد.", (val, context) => { + if (context.originalValue) { + return context.originalValue.length === 10; + } + }), + password: Yup.string() + .required("این فیلد اجباری است!") + .typeError("لطفا مقادیر را به درستی وارد کنید!"), + }), + }); + + const formikKillHouse = useFormik({ + initialValues: { + KillHousePostal: "", + KillHouseCapacity: "", + KillHousePhone: "", + KillHouseAddress: "", + }, + validationSchema: Yup.object({ + KillHousePostal: Yup.number().typeError( + "لطفا فیلد را به درستی وارد کنید!" + ), + KillHouseCapacity: Yup.number().typeError( + "لطفا فیلد را به صورت عددی وارد کنید!" + ), + KillHousePhone: Yup.number() + .typeError("لطفا فیلد را به صورت عددی وارد کنید!") + .test("len", "شماره تلفن باید با 0 شروع شود", (val, context) => { + return context.originalValue && context.originalValue.startsWith("0"); + }) + .test("len", "شماره تماس 11 رقم باید باشد", (val, context) => { + if (context.originalValue) { + return context.originalValue.length === 11; + } + }), + KillHouseAddress: Yup.string().typeError( + "لطفا فیلد را به درستی وارد کنید!" + ), + }), + }); + + const formikKillHouseVet = useFormik({ + initialValues: { + KillHouseVetPostal: "", + KillHouseVetAddress: "", + }, + validationSchema: Yup.object({ + KillHouseVetPostal: Yup.number().typeError( + "لطفا فیلد را به درستی وارد کنید!" + ), + KillHouseVetAddress: Yup.string().typeError( + "لطفا فیلد را به درستی وارد کنید!" + ), + }), + }); + + const formikCityProvince = useFormik({ + initialValues: { + cityProvinceAddress: "", + cityProvincePostalCode: "", + }, + validationSchema: Yup.object({ + cityProvinceAddress: Yup.string() + .required("این فیلد اجباری است!") + .typeError("لطفا فیلد را به درستی وارد کنید!"), + cityProvincePostalCode: Yup.number() + .required("این فیلد اجباری است!") + .typeError("لطفا فیلد را به درستی وارد کنید!"), + }), + }); + + const formikUserBankInfo = useFormik({ + initialValues: { + bankName: "", + cardNumber: "", + accountNumber: "", + shabaNumber: "", + accountHolder: "", + }, + validationSchema: Yup.object({ + cardNumber: Yup.number().typeError("لطفا شماره کارتتان را وارد کنید!"), + accountNumber: Yup.number().typeError("لطفا شماره حسابتان را وارد کنید!"), + shabaNumber: Yup.number().typeError("لطفا شماره شبا را وارد کنید!"), + accountHolder: Yup.string().typeError("لطفا نام صاحب حساب را وارد کنید!"), + }), + }); + + const formikDriver = useFormik({ + initialValues: { + type_car: "ایسوزو", + type_weight: "سنگین", + capocity: "", + health_code: "", + }, + validationSchema: Yup.object({ + type_weight: Yup.string().typeError("لطفا فیلد را به درستی وارد کنید!"), + capocity: Yup.string().typeError("لطفا فیلد را به درستی وارد کنید!"), + name: Yup.string().typeError("لطفا فیلد را به درستی وارد کنید!"), + health_code: Yup.number() + .typeError("لطفا فیلد را به درستی وارد کنید!") + .required("این فیلد اجباری است!"), + }), + }); + + useEffect(() => { + formik.validateForm(); + formik2.validateForm(); + formikKillHouse.validateForm(); + formikCityProvince.validateForm(); + formikUserBankInfo.validateForm(); + formikDriver.validateForm(); + formikKillHouseVet.validateForm(); + }, []); + + const formik2 = useFormik({ + initialValues: { + userInfoCheck: "", + }, + validationSchema: Yup.object({ + userInfoCheck: Yup.number() + .required("این فیلد اجباری است!") + .typeError("لطفا فیلد را به درستی وارد کنید!"), + }), + }); + + const [user, setUser] = React.useState(); + + const handleChange = (event) => { + setUser(event.target.value); + }; + + useEffect(() => { + dispatch(LOADING_START()); + dispatch(cityGetProvinces())?.then((r) => { + dispatch(LOADING_END()); + setProvinceData(r.payload.data); + }); + }, []); + + useEffect(() => { + dispatch(LOADING_END()); + if (provinceKey) { + dispatch(LOADING_START()); + dispatch(cityGetCity(provinceKey)).then((r) => { + setCityData(r.payload.data); + setIsExistProvince(false); + dispatch(LOADING_END()); + }); + } else if (killHouseProvinceKey) { + dispatch(LOADING_START()); + dispatch(cityGetCity(killHouseProvinceKey)).then((r) => { + setCityData(r.payload.data); + setIsExistProvince(false); + dispatch(LOADING_END()); + }); + } else if (killHouseVetProvinceKey) { + dispatch(LOADING_START()); + dispatch(cityGetCity(killHouseVetProvinceKey)).then((r) => { + setCityData(r.payload.data); + setIsExistProvince(false); + dispatch(LOADING_END()); + }); + } else if (OperatorProvinceKey) { + dispatch(LOADING_START()); + dispatch(cityGetCity(OperatorProvinceKey)).then((r) => { + setCityData(r.payload.data); + setIsExistProvince(false); + dispatch(LOADING_END()); + }); + } else if (poultryProvinceKey) { + dispatch(LOADING_START()); + dispatch(cityGetCity(poultryProvinceKey)).then((r) => { + setCityData(r.payload.data); + setIsExistProvince(false); + dispatch(LOADING_END()); + }); + dispatch(LOADING_END()); + } + }, [ + provinceKey, + killHouseProvinceKey, + OperatorProvinceKey, + poultryProvinceKey, + killHouseVetProvinceKey, + ]); + + const [userExist, setUserExist] = useState(false); + + const [driverPelak, setDriverPelak] = useState([]); + + const carPelakHandleChange = (pelak1, pelak2, pelak3, pelak4) => { + setDriverPelak([pelak1, pelak2, pelak3, pelak4]); + }; + + useEffect(() => { + if (userData) { + setUserExist(true); + } else if (formik.isValid && cityKey && provinceKey) { + setUserExist(true); + } + }, [userData]); + + const isFormValid = (user) => { + if (userData) + switch (user) { + case "Poultry": + return !(userExist && poultryCityKey); + case "KillHouse": + return !(userExist && killHouseCityKey); + case "Driver": + return !(userExist && formikDriver.isValid); + case "ProvinceOperator": + return !(userExist && formikCityProvince.isValid); + case "CityOperator": + return !(userExist && formikCityProvince.isValid); + case "VetFarm": + return !(userExist && formikCityProvince.isValid); + case "ProvinceInspector": + return !(userExist && formikCityProvince.isValid); + case "ProvinceFinancial": + return !(userExist && formikCityProvince.isValid); + case "KillHouseVet": + return !( + userExist && + killHouseVetProvinceKey && + killHouseVetCityKey && + formikKillHouseVet.isValid + ); + default: + return !(userExist && user); + } + else { + return !(formik.isValid && cityKey && provinceKey); + } + }; + + const [arrKillHouse, setArrKillHouse] = useState([ + { + id: 0, + killHouseAddress: "", + postal: "", + shift_work_from: "", + shift_work_to: "", + province: "", + city: "", + name: "", + capacity: "", + killing_race: "", + phone: "", + bankName: "", + cardNumber: "", + accountNumber: "", + shabaNumber: "", + accountHolder: "", + }, + ]); + + const addInputkillHouse = () => { + setArrKillHouse((prevState) => { + return [ + ...prevState, + { + id: prevState.length, + killHouseAddress: "", + postal: "", + shift_work_from: "", + shift_work_to: "", + province: "", + city: "", + name: "", + capacity: "", + killing_race: "", + phone: "", + bankName: "", + cardNumber: "", + accountNumber: "", + shabaNumber: "", + accountHolder: "", + }, + ]; + }); + }; + + const removeInputKillHouse = (e) => { + let number = arrKillHouse.length - 1; + + if (number !== 0) { + let filteredArrayPrice = arrKillHouse.filter((object, i) => i < number); + + setArrKillHouse(filteredArrayPrice); + } + }; + + const handleChangeArrayKillHouse = (e, value, i) => { + let val, itemName, itemIndex; + if (value) { + val = value; + [itemName, , itemIndex] = e.target.id.split("-"); + } else { + val = e.target.value; + [itemName, itemIndex] = e.target.name.split("-"); + } + if (itemName === "shift_work_from") { + setArrKillHouse((prevState) => { + const newState = prevState; + newState[itemIndex].shift_work_from = val; + return newState; + }); + } else if (itemName === "shift_work_to") { + setArrKillHouse((prevState) => { + const newState = prevState; + newState[itemIndex].shift_work_to = val; + return newState; + }); + } else if (itemName === "killHouseAddress") { + setArrKillHouse((prevState) => { + const newState = prevState; + newState[itemIndex].killHouseAddress = val; + return newState; + }); + } else if (itemName === "postal") { + setArrKillHouse((prevState) => { + const newState = prevState; + newState[itemIndex].postal = val; + return newState; + }); + } else if (itemName === "capacity") { + setArrKillHouse((prevState) => { + const newState = prevState; + newState[itemIndex].capacity = Number(val); + return newState; + }); + } else if (itemName === "name") { + setArrKillHouse((prevState) => { + const newState = prevState; + newState[itemIndex].name = val; + return newState; + }); + } else if (itemName === "killing_race") { + setArrKillHouse((prevState) => { + const newState = prevState; + newState[itemIndex].killing_race = val; + return newState; + }); + } else if (itemName === "phone") { + setArrKillHouse((prevState) => { + const newState = prevState; + newState[itemIndex].phone = Number(val); + return newState; + }); + } else if (itemName === "province") { + dispatch(LOADING_START()); + dispatch(cityGetCity(val)).then((r) => { + setCityData(r.payload.data); + setIsExistProvince(false); + dispatch(LOADING_END()); + }); + setArrKillHouse((prevState) => { + const newState = prevState; + newState[i].province = val; + return newState; + }); + } else if (itemName === "city") { + setArrKillHouse((prevState) => { + const newState = prevState; + newState[i].city = val; + return newState; + }); + } else if (itemName === "bankName") { + setArrKillHouse((prevState) => { + const newState = prevState; + newState[itemIndex].bankName = e.target.value; + return newState; + }); + } else if (itemName === "cardNumber") { + setArrKillHouse((prevState) => { + const newState = prevState; + newState[itemIndex].cardNumber = Number(e.target.value); + return newState; + }); + } else if (itemName === "accountNumber") { + setArrKillHouse((prevState) => { + const newState = prevState; + newState[itemIndex].accountNumber = Number(e.target.value); + return newState; + }); + } else if (itemName === "shabaNumber") { + setArrKillHouse((prevState) => { + const newState = prevState; + newState[itemIndex].shabaNumber = Number(e.target.value); + return newState; + }); + } else if (itemName === "accountHolder") { + setArrKillHouse((prevState) => { + const newState = prevState; + newState[itemIndex].accountHolder = e.target.value; + return newState; + }); + } + }; + + const [arr, setArr] = useState([ + { + id: 0, + uniqueID: "", + poultryAddress: "", + halls: "", + systemCode: "", + epidemiologicalCode: "", + unitName: "", + capacity: "", + licenseNumber: "", + postal: "", + bankName: "", + cardNumber: "", + accountNumber: "", + shabaNumber: "", + accountHolder: "", + province: "", + city: "", + }, + ]); + + const addInput = () => { + setArr((prevState) => { + return [ + ...prevState, + { + id: prevState.length, + uniqueID: "", + poultryAddress: "", + halls: "", + systemCode: "", + epidemiologicalCode: "", + unitName: "", + capacity: "", + licenseNumber: "", + postal: "", + bankName: "", + cardNumber: "", + accountNumber: "", + shabaNumber: "", + accountHolder: "", + province: "", + city: "", + }, + ]; + }); + }; + + const removeInput = (e) => { + let number = arr.length - 1; + + if (number !== 0) { + let filteredArrayPrice = arr.filter((object, i) => i < number); + // let filteredArrayTime = arrPrices.filter((object, i) => i < number); + + setArr(filteredArrayPrice); + // setArrPrices(filteredArrayTime); + } + }; + + const handleChangeArray = (e) => { + const [itemName, itemIndex] = e.target.name.split("-"); + if (itemName === "uniqueID") { + setArr((prevState) => { + const newState = prevState; + newState[itemIndex].uniqueID = e.target.value; + return newState; + }); + } else if (itemName === "poultryAddress") { + setArr((prevState) => { + const newState = prevState; + newState[itemIndex].poultryAddress = e.target.value; + return newState; + }); + } else if (itemName === "halls") { + setArr((prevState) => { + const newState = prevState; + newState[itemIndex].halls = Number(e.target.value); + return newState; + }); + } else if (itemName === "systemCode") { + setArr((prevState) => { + const newState = prevState; + newState[itemIndex].systemCode = Number(e.target.value); + return newState; + }); + } else if (itemName === "epidemiologicalCode") { + setArr((prevState) => { + const newState = prevState; + newState[itemIndex].epidemiologicalCode = Number(e.target.value); + return newState; + }); + } else if (itemName === "ownerName") { + setArr((prevState) => { + const newState = prevState; + newState[itemIndex].ownerName = e.target.value; + return newState; + }); + } else if (itemName === "unitName") { + setArr((prevState) => { + const newState = prevState; + newState[itemIndex].unitName = e.target.value; + return newState; + }); + } else if (itemName === "capacity") { + setArr((prevState) => { + const newState = prevState; + newState[itemIndex].capacity = Number(e.target.value); + return newState; + }); + } else if (itemName === "licenseNumber") { + setArr((prevState) => { + const newState = prevState; + newState[itemIndex].licenseNumber = Number(e.target.value); + return newState; + }); + } else if (itemName === "postal") { + setArr((prevState) => { + const newState = prevState; + newState[itemIndex].postal = Number(e.target.value); + return newState; + }); + } else if (itemName === "bankName") { + setArr((prevState) => { + const newState = prevState; + newState[itemIndex].bankName = e.target.value; + return newState; + }); + } else if (itemName === "cardNumber") { + setArr((prevState) => { + const newState = prevState; + newState[itemIndex].cardNumber = Number(e.target.value); + return newState; + }); + } else if (itemName === "accountNumber") { + setArr((prevState) => { + const newState = prevState; + newState[itemIndex].accountNumber = Number(e.target.value); + return newState; + }); + } else if (itemName === "shabaNumber") { + setArr((prevState) => { + const newState = prevState; + newState[itemIndex].shabaNumber = Number(e.target.value); + return newState; + }); + } else if (itemName === "accountHolder") { + setArr((prevState) => { + const newState = prevState; + newState[itemIndex].accountHolder = e.target.value; + return newState; + }); + } else if (itemName === "province") { + setPoultryProvincekey(e.target.value); + setArr((prevState) => { + const newState = prevState; + newState[itemIndex].province = e.target.value; + return newState; + }); + } else if (itemName === "city") { + setPoultryCityKey(e.target.value); + setArr((prevState) => { + const newState = prevState; + newState[itemIndex].city = e.target.value; + return newState; + }); + } + }; + + const [killHouseData, setKillHouseData] = useState(); + const [killHouseKey, setKillHouseKey] = useState(); + useEffect(() => { + if (user === "KillHouseVet") { + dispatch(LOADING_START()); + dispatch(provinceGetKillHouses()).then((r) => { + setKillHouseData(r.payload.data); + dispatch(LOADING_END()); + }); + } + }, [user]); + + return ( + + + {!userChecked && ( + <> + بررسی کاربر + + + + { + dispatch(LOADING_START()); + dispatch( + provinceCheckUserExistence({ + type: "check_user", + value: formik2.values.userInfoCheck, + }) + ).then((r) => { + dispatch(LOADING_END()); + if (r.error) { + if (r.error.message.includes("409")) { + openNotif({ + vertical: "top", + horizontal: "center", + msg: "کاربر پیدا نشد، یک کاربر جدید بسازید!", + severity: "error", + }); + } + } else { + if (r.payload.data) { + setUserData(r.payload.data.profile); + } else { + openNotif({ + vertical: "top", + horizontal: "center", + msg: "مشکلی پیش آمده است!", + severity: "error", + }); + + dispatch( + DRAWER({ + right: false, + bottom: false, + content: null, + }) + ); + } + } + }); + setUserChecked(true); + }} + > + + + + شماره موبایل با صفر شروع می‌شود! + + )} + + {userChecked && ( + <> + {userData ? ( + + ) : ( + <> + + + + + + + + + + + } + value={formik.values.birthday} + error={ + formik.touched.birthday + ? Boolean(formik.errors.birthday) + : null + } + onChange={(e) => { + formik.setFieldValue( + "birthday", + moment(e).format("YYYY-MM-DD hh:mm:ss") + ); + }} + onBlur={formik.handleBlur} + helperText={ + formik.touched.birthday && Boolean(formik.errors.birthday) + ? formik.errors.birthday + : null + } + /> + + + ({ + id: i.key, + label: i.name, + }))} + onChange={(e, value) => { + setProvinceKey(value.id); + }} + renderInput={(params) => ( + + )} + /> + + + + ({ + id: i.key, + label: i.name, + }))} + onChange={(e, value) => { + setCityKey(value.id); + }} + renderInput={(params) => ( + + )} + /> + + + + + + + + + + + )} + + {userData && ( + + + + {userData ? "افزودن نقش" : "نوع کاربر"} + + + + + )} + + {/* start of poultry ============================================================================= */} + + {arr.map((item, i) => { + return ( + <> + {user === "Poultry" && ( + <> + + + + + + + + + + + + استان * + + + + + + + + + شهر * + + + + + + + + + + + + + + + + + + + + + + + + + + {/* + + */} + + + + + + + + + + + + + + + + + + + + بانک + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + )} + + ); + })} + + {/* end of poultry ============================================================================= */} + + {user === "Driver" && ( + <> + + + + + + + مدل خودرو + + + + + + + + + مشخصات پلاک + + + + + )} + {user === "KillHouse" && ( + <> + + + + + + ({ + id: i.key, + label: i.name, + }))} + onChange={(e, value) => { + setKillHouseProvinceKey(value.id); + }} + renderInput={(params) => ( + + )} + /> + + + + ({ + id: i.key, + label: i.name, + }))} + onChange={(e, value) => { + setKillHouseCityKey(value.id); + }} + renderInput={(params) => ( + + )} + /> + + + + + + + + + + + {arrKillHouse?.map((item, i) => { + return ( + <> + + + + + + + + + + ({ + id: i.key, + label: i.name, + }))} + onChange={(e, value) => { + handleChangeArrayKillHouse(e, value.id, i); + }} + name={"province-" + i} + // onChange={handleChangeArrayKillHouse} + renderInput={(params) => ( + + )} + /> + + + ({ + id: i.key, + label: i.name, + }))} + name={"city-" + i} + onChange={(e, value) => { + handleChangeArrayKillHouse(e, value.id, i); + }} + renderInput={(params) => ( + + )} + /> + + + + + + + + + + + + + + + + + + + + + + + + + بانک + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ); + })} + + )} + + {user === "KillHouseVet" && ( + <> + + + + + + ({ + id: i.key, + label: i.name, + }))} + onChange={(e, value) => { + setKillHouseKey(value.id); + }} + renderInput={(params) => ( + + )} + /> + + + + ({ + id: i.key, + label: i.name, + }))} + onChange={(e, value) => { + setKillHouseVetProvinceKey(value.id); + }} + renderInput={(params) => ( + + )} + /> + + + + ({ + id: i.key, + label: i.name, + }))} + onChange={(e, value) => { + setKillHouseVetCityKey(value.id); + }} + renderInput={(params) => ( + + )} + /> + + + + + + + + + + + )} + + {(user === "CityOperator" || + user === "ProvinceOperator" || + user === "VetFarm" || + user === "ProvinceInspector" || + user === "ProvinceFinancial") && ( + <> + + + + + + ({ + id: i.key, + label: i.name, + }))} + onChange={(e, value) => { + setOperatorProvinceKey(value.id); + }} + renderInput={(params) => ( + + )} + /> + + + + ({ + id: i.key, + label: i.name, + }))} + onChange={(e, value) => { + setOperatorCityKey(value.id); + }} + renderInput={(params) => ( + + )} + /> + + + + + + + + + + + )} + + {(user === "CityOperator" || + user === "KillHouseVet" || + user === "VetFarm" || + user === "ProvinceOperator" || + user === "Driver" || + user === "ProvinceFinancial") && ( + <> + + + + + + بانک + + + + + + + + + + + + + + + + + + + )} + + + + + + )} + + + ); +}; diff --git a/src/features/province/components/province-submit-user/components/userInfo.js b/src/features/province/components/province-submit-user/components/userInfo.js new file mode 100644 index 0000000..3065c85 --- /dev/null +++ b/src/features/province/components/province-submit-user/components/userInfo.js @@ -0,0 +1,176 @@ +import { Typography } from "@mui/material"; +import React from "react"; +import { Grid } from "../../../../../components/grid/Grid"; +import { SPACING } from "../../../../../data/spacing"; +import CheckIcon from "@mui/icons-material/Check"; +import { PropTypes } from "prop-types"; +import { formatJustDate } from "../../../../../utils/formatTime"; + +export const UserInfo = ({ userData }) => { + return ( + <> + + + prop.palette.grey["A700"]} + > + نام کامل: + + + {userData.fullname} + {" "} + + + + prop.palette.grey["A700"]} + > + موبایل: + + + {userData.mobile} + + + + + prop.palette.grey["A700"]} + > + استان: + + + {userData.province} + {" "} + + + + prop.palette.grey["A700"]} + > + شهر: + + + {userData.city} + + + + + prop.palette.grey["A700"]} + > + تاریخ تولد: + + + {formatJustDate(userData?.birthday)} + + + {userData?.role.length > 0 && ( + + prop.palette.grey["A700"]} + > + {userData?.role?.length > 1 ? "نقش ها:" : "نقش:"} + + + + {userData?.role?.map((item, i) => { + var name = ""; + switch (item) { + case "ProvinceOperator": + name = "اپراتور تخصیص استان"; + break; + case "CityOperator": + name = "اپراتور شهرستان"; + break; + case "KillHouseVet": + name = "دامپزشک کشتارگاه"; + break; + case "Poultry": + name = "مرغدار"; + break; + case "KillHouse": + name = "کشتارگاه"; + break; + case "VetFarm": + name = "دامپزشک"; + break; + case "Vet": + name = "دامپزشک"; + break; + case "ProvinceInspector": + name = "بازرس استان"; + break; + case "ProvinceFinancial": + name = "اپراتور مالی"; + break; + case "Driver": + name = "راننده"; + break; + case "Admin": + name = "راننده"; + break; + + default: + break; + } + return [ + + + {name} + , + ]; + })} + + + )} + + {userData?.image?.length > 5 && ( + <> + + prop.palette.grey["A700"]} + > + پروفایل: + + + + img + + + + + )} + + + ); +}; + +UserInfo.propTypes = { + userData: PropTypes.any, +}; diff --git a/src/features/province/components/province-table-process/ProvinceTableProcess.js b/src/features/province/components/province-table-process/ProvinceTableProcess.js new file mode 100644 index 0000000..a64abbd --- /dev/null +++ b/src/features/province/components/province-table-process/ProvinceTableProcess.js @@ -0,0 +1,314 @@ +import { useDispatch } from "react-redux"; +import { + LOADING_END, + LOADING_START, +} from "../../../../lib/redux/slices/appSlice"; +import axios from "axios"; +import { useContext, useEffect, useState } from "react"; +import { AppContext } from "../../../../contexts/AppContext"; +import moment from "moment"; +import { Grid } from "../../../../components/grid/Grid"; +import { RiFileExcel2Fill } from "react-icons/ri"; +import { + Button, + Pagination, + TextField, + Tooltip, + Typography, +} from "@mui/material"; +import { DatePicker } from "@mui/x-date-pickers"; +import { SPACING } from "../../../../data/spacing"; +import { formatJustDate } from "../../../../utils/formatTime"; + +export const ProvinceTableProcess = () => { + const dispatch = useDispatch(); + const [textValue, setTextValue] = useState(""); + const [totalRows, setTotalRows] = useState(0); + const [perPage, setPerPage] = useState(10); + const [data, setData] = useState([]); + const [page, setPage] = useState(0); + + const [, , selectedDate1, setSelectedDate1, selectedDate2, setSelectedDate2] = + useContext(AppContext); + const [openNotif] = useContext(AppContext); + + useEffect(() => { + const currentDate = moment(new Date()).format("YYYY-MM-DD"); + setSelectedDate1(currentDate); + setSelectedDate2(currentDate); + }, []); + + const handleTextChange = (event) => { + setTextValue(event.target.value); + }; + + const width = + window.innerWidth || + document.documentElement.clientWidth || + document.body.clientWidth; + + const fetchApiData = async (page) => { + dispatch(LOADING_START()); + let response = await axios.get( + `poultry_requests_for_total_information/?date1=${selectedDate1}&date2=${selectedDate2}&search=filter&value=${ + textValue ? textValue : "" + }&page=${page}&page_size=${perPage}` + ); + setData(response.data.results); + setTotalRows(response.data.count); + dispatch(LOADING_END()); + }; + + const handleChangePage = (event, newPage) => { + setPage(newPage); + fetchApiData(newPage + 1); + }; + + const handleSubmit = async (event) => { + event.preventDefault(); + fetchApiData(1); + }; + + useEffect(() => { + setPerPage(10); + fetchApiData(1); + }, [selectedDate1, selectedDate2]); + + return ( + + + روند پرونده ها + + } + value={selectedDate1} + onChange={(e) => { + setSelectedDate1(moment(e).format("YYYY-MM-DD")); + }} + /> + + + } + value={selectedDate2} + onChange={(e) => { + setSelectedDate2(moment(e).format("YYYY-MM-DD")); + }} + /> + + + + + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + {data?.map((item, i) => { + const rowSpan = + item?.killHouseRequests?.killHouseRequestsSerializer?.length + 1; + let stateReq = ""; + if (item.stateProcess === "accepted") { + stateReq = "تایید شده"; + } else if (item.stateProcess === "pending") { + stateReq = "در انتظار تایید"; + } else if (item.stateProcess === "rejected") { + stateReq = "رد شده"; + } + return ( + <> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + {item?.killHouseRequests?.killHouseRequestsSerializer?.map( + (buyer, i) => { + return ( + + + + + + + + + + + + + + + + + + + + + ); + } + )} + + ); + })} +
    کدسفارشنام واحدنام و نام خانوادگی مرغدارموبایلآدرستاریخ جوجه ریزیتعداد کل جوجه ریزیسن مرغتعداد درخواست کشتاروزن درخواست کشتارنوع فروشقیمت مرغ زندهتعداد تخصیصی به خریدارمانده قابل تخصیصحجم باقی مانده در سالننژادتاریخ درخواست کشتاردامپزشک فارمتلفن دامپزشک فارموضعیت درخواستخریدارتعداد تخصیصی قطعهوزن تخصیصیتاریخ تخصیصنوع تخصیصآدرسمحل کشتاروضعیت تخصیص به خریدارتعداد بار ایجاد شدهحجم تخصیصی به باروزن تخصیصی به بارمانده قطعه قابل تخصیصمانده وزن قابل تخصیصماشینرانندهتلفنکدبهداشتی حمل و نقلکدرهگیری سامانه قرنطینهتعداد ثبت شده در قرنطینهحجم باروزن باروضعیت بارتعداد تخلیهوزن تخلیهتاریخ تخلیه کشتارگاهدامپزشک کشتارگاهتلفن دامپزشک کشتارگاهاطلاعات تکمیلی قطعهاطلاعات تکمیلی وزنکاربر کشتارگاهتلفن کاربر کشتارگاه
    {item.orderCode}{item.poultry.unitName}{item.poultry.user.fullname}{item.poultry.user.mobile} + {`${item.poultry.address.province.name} - ${item.poultry.address.city.name} - ${item.poultry.address.address}`} + تاریخ جوجه ریزی + {item?.hatching?.quantity?.toLocaleString()} + {item.hatching.age}{item?.quantity?.toLocaleString()} + {item.quantity * item.IndexWeight} کیلوگرم + + {item.freeSaleInProvince ? "آزاد" : "دولتی"} + قیمت مرغ زنده + {item?.provinceKillRequests?.provinceKillRequestsTotalInfo?.allocatedQuantity?.toLocaleString()} + + {item?.provinceKillRequests?.provinceKillRequestsTotalInfo?.poultryRequestRemainQuantity?.toLocaleString()} + {item.hatching.leftOver}{item.chickenBreed}{formatJustDate(item.sendDate)}دامپزشک فارمتلفن دامپزشک فارم{stateReq}خریدارتعداد تخصیصی قطعهوزن تخصیصیتاریخ تخصیصنوع تخصیصآدرسمحل کشتاروضعیت تخصیص به خریدارتعداد بار ایجاد شدهحجم تخصیصی به باروزن تخصیصی به بارمانده قطعه قابل تخصیصمانده وزن قابل تخصیص
    {buyer?.addCar?.driver?.typeCar}{buyer?.addCar?.driver?.driverName}{"تلفن"}{"کدبهداشتی حمل و نقل"}{"کدرهگیری سامانه قرنطینه"}{"تعداد ثبت شده در قرنطینه"}{"حجم بار"}{"وزن بار"}{"وضعیت بار"}{"تعداد تخلیه"}{"وزن تخلیه"}{"تاریخ تخلیه کشتارگاه"}{"دامپزشک کشتارگاه"}{"تلفن دامپزشک کشتارگاه"}{"اطلاعات تکمیلی قطعه"}{"اطلاعات تکمیلی وزن"}{"کاربر کشتارگاه"}{"تلفن کاربر کشتارگاه"}
    +
    + + { + handleChangePage(event, newPage - 1); + }} + /> + +
    + ); +}; diff --git a/src/features/province/components/province-trade-panel-enter-market-code/ProvinceTradePanelEnterMarketCode.js b/src/features/province/components/province-trade-panel-enter-market-code/ProvinceTradePanelEnterMarketCode.js new file mode 100644 index 0000000..c3826fe --- /dev/null +++ b/src/features/province/components/province-trade-panel-enter-market-code/ProvinceTradePanelEnterMarketCode.js @@ -0,0 +1,81 @@ +import React, { useContext } from "react"; +import { useFormik } from "formik"; +import * as yup from "yup"; +import { Grid } from "../../../../components/grid/Grid"; +import { Button, TextField } from "@mui/material"; +import { useDispatch } from "react-redux"; +import { provinceTradePanelEnterMarketCodeService } from "../../services/province-trade-panel-enter-market-code-service"; +import { AppContext } from "../../../../contexts/AppContext"; +import { CLOSE_MODAL } from "../../../../lib/redux/slices/appSlice"; + +const validationSchema = yup.object({ + marketCode: yup + .string() + .required("کد احراز الزامی است") + .matches(/^[0-9]+$/, "کد احراز باید فقط شامل اعداد باشد"), +}); + +export const ProvinceTradePanelEnterMarketCode = ({ item, updateAll }) => { + const dispatch = useDispatch(); + + const [openNotif] = useContext(AppContext); + const formik = useFormik({ + initialValues: { + marketCode: item?.inputMarketCode || "", + }, + validationSchema: validationSchema, + onSubmit: (values) => { + dispatch( + provinceTradePanelEnterMarketCodeService({ + key: item?.key, + input_market_code: values.marketCode, + }) + ).then((r) => { + if (r.payload.error) { + openNotif({ + vertical: "top", + horizontal: "center", + msg: r.payload.error, + severity: "error", + }); + } else { + openNotif({ + vertical: "top", + horizontal: "center", + msg: "عملیات با موفقیت انجام شد.", + severity: "success", + }); + dispatch(CLOSE_MODAL()); + updateAll(); + } + }); + }, + }); + + return ( + + + + + + ); +}; diff --git a/src/features/province/components/province-trade-panel-market-old-request-details/ProvinceTradePanelMarketOldRequestDetails.js b/src/features/province/components/province-trade-panel-market-old-request-details/ProvinceTradePanelMarketOldRequestDetails.js new file mode 100644 index 0000000..3a5ba6f --- /dev/null +++ b/src/features/province/components/province-trade-panel-market-old-request-details/ProvinceTradePanelMarketOldRequestDetails.js @@ -0,0 +1,144 @@ +import { useEffect, useState } from "react"; +import ResponsiveTable from "../../../../components/responsive-table/ResponsiveTable"; +import { Grid } from "../../../../components/grid/Grid"; +import { formatJustDate, formatTime } from "../../../../utils/formatTime"; +import { useDispatch } from "react-redux"; +import { + LOADING_END, + LOADING_START, +} from "../../../../lib/redux/slices/appSlice"; +import axios from "axios"; +import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl"; +import PdfKillRequest from "../province-settlement-pdf-kill-request/ProvinceSettlementPdfKillRequest"; + +export const ProvinceTradePanelMarketOldRequestDetails = ({ req_key }) => { + const dispatch = useDispatch(); + + const [data, setData] = useState([]); + const [tableData, setTableData] = useState([]); + const [totalRows, setTotalRows] = useState(0); + const [perPage, setPerPage] = useState(10); + const [page, setPage] = useState(1); + + const handlePageChange = (page) => { + fetchApiData(page); + setPage(page); + }; + + const handlePerRowsChange = (perRows) => { + setPerPage(perRows); + setPage(1); + }; + + const fetchApiData = async (pageNumber = page) => { + try { + dispatch(LOADING_START()); + const response = await axios.get( + `/market-requests/?role=${getRoleFromUrl()}&search=filter&value=&page=${pageNumber}&page_size=${perPage}&poultry_request_key=${req_key}` + ); + dispatch(LOADING_END()); + setData(response.data.results); + setTotalRows(response.data.count); + } catch (error) { + dispatch(LOADING_END()); + } + }; + + const handleUpdate = () => { + fetchApiData(1); + }; + + useEffect(() => { + const d = data?.map((item, i) => { + return [ + page === 1 ? i + 1 : i + perPage * (page - 1) + 1, + `${item?.poultry?.unitName}`, + `${item?.poultry?.fullname} (${item?.poultry?.mobile})`, + item?.poultry?.city, + `${item?.killHouse?.killer === true ? "کشتارکن" : "کشتارگاه"} ${ + item?.killHouse?.name + }`, + `${item?.killHouse?.fullname} (${item?.killHouse?.mobile})`, + item?.killHouse?.city, + item?.chickenBreed, + item?.poultryRequest?.killingAge?.toLocaleString(), + item?.killCapacity?.toLocaleString(), + formatJustDate(item?.reciveDate), + formatTime(item?.createDate), + item?.IndexWeight, + Math.round( + item?.IndexWeight * item?.killCapacity || 0 + ).toLocaleString(), + item?.amount ? item?.amount.toLocaleString() : "0", + item?.paymentDeadlineDate + ? formatJustDate(item?.paymentDeadlineDate) + : "-", + `${ + item?.marketCodeStatus === true && + item?.marketFinalAccept === true && + !item?.inputMarketCode && + item?.marketState === "pending" + ? "در انتظار ورود کد احراز" + : item?.marketFinalAccept === false + ? "در انتظار تایید خریدار" + : item?.marketState === "pending" + ? "در انتظار تایید استان" + : item?.marketState === "accepted" + ? "تایید شده" + : item?.marketState === "rejected" + ? "رد شده" + : item?.marketState === "deleted" + ? "حذف شده" + : "" + }`, + item?.marketState === "accepted" ? ( + + ) : ( + "-" + ), + ]; + }); + + setTableData(d); + }, [data]); + + useEffect(() => { + handleUpdate(); + }, [perPage]); + + return ( + + + + ); +}; diff --git a/src/features/province/components/province-trade-panel-market-old-request/ProvinceTradePanelMarketOldRequest.js b/src/features/province/components/province-trade-panel-market-old-request/ProvinceTradePanelMarketOldRequest.js new file mode 100644 index 0000000..391b4e0 --- /dev/null +++ b/src/features/province/components/province-trade-panel-market-old-request/ProvinceTradePanelMarketOldRequest.js @@ -0,0 +1,528 @@ +import { useContext, useEffect, useState } from "react"; +import ResponsiveTable from "../../../../components/responsive-table/ResponsiveTable"; +import { Grid } from "../../../../components/grid/Grid"; +import { formatJustDate, formatTime } from "../../../../utils/formatTime"; +import { useDispatch } from "react-redux"; +import { + LOADING_END, + LOADING_START, +} from "../../../../lib/redux/slices/appSlice"; +import axios from "axios"; +import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl"; +import PdfKillRequest from "../province-settlement-pdf-kill-request/ProvinceSettlementPdfKillRequest"; +import { + Button, + FormControl, + InputLabel, + MenuItem, + Select, + TextField, +} from "@mui/material"; +import { + provinceTradePanelMarketRequestAdminOverview, + provinceTradePanelMarketRequestOverview, +} from "../../services/province-trade-panel-market-request-overview"; +import { SPACING } from "../../../../data/spacing"; +import { DatePicker } from "@mui/x-date-pickers"; +import moment from "moment"; +import { AppContext } from "../../../../contexts/AppContext"; +import { RiSearchLine } from "react-icons/ri"; +import { ProvinceTradePanelOldRequests } from "../province-trade-panel-old-requests/ProvinceTradePanelOldRequests"; + +export const ProvinceTradePanelMarketOldRequest = () => { + const [, , selectedDate1, setSelectedDate1, selectedDate2, setSelectedDate2] = + useContext(AppContext); + + const [overViewSelectedDate1, setOverviewSelectedDate1] = useState( + moment(new Date()).format("YYYY-MM-DD") + ); + const [overViewSelectedDate2, setOverviewSelectedDate2] = useState( + moment(new Date()).format("YYYY-MM-DD") + ); + + useEffect(() => { + const currentDate = moment(new Date()).format("YYYY-MM-DD"); + setSelectedDate1(currentDate); + setSelectedDate2(currentDate); + }, []); + + const dispatch = useDispatch(); + const [data, setData] = useState([]); + const [filter, setFilter] = useState("pending"); + const [tableData, setTableData] = useState([]); + const [overViewData, setOverViewData] = useState([]); + const [overViewDataList, setOverViewDataList] = useState([]); + const [overViewDataDashboard, setOverViewDataDashboard] = useState([]); + const [totalRows, setTotalRows] = useState(0); + const [perPage, setPerPage] = useState(10); + const [page, setPage] = useState(1); + + const handlePageChange = (page) => { + fetchApiData(page); + setPage(page); + }; + + const handlePerRowsChange = (perRows) => { + setPerPage(perRows); + setPage(1); + }; + + const [textValue, setTextValue] = useState(""); + + const handleTextChange = (event) => { + setTextValue(event.target.value); + }; + const [textValueOverview, setTextValueOverView] = useState(""); + + const handleTextChangeOverView = (event) => { + setTextValueOverView(event.target.value); + }; + + const getOverviewData = (event) => { + if (event) { + event.preventDefault(); + } + dispatch( + provinceTradePanelMarketRequestAdminOverview({ + date1: overViewSelectedDate1, + date2: overViewSelectedDate2, + search: "filter", + value: textValueOverview, + }) + ).then((r) => { + setOverViewDataDashboard(r.payload.data); + }); + dispatch( + provinceTradePanelMarketRequestOverview({ + date1: overViewSelectedDate1, + date2: overViewSelectedDate2, + search: "filter", + value: textValueOverview, + }) + ).then((r) => { + setOverViewData(r.payload.data); + }); + }; + + const fetchApiData = async (pageNumber = page, event) => { + if (event) { + event.preventDefault(); + } + try { + dispatch(LOADING_START()); + const response = await axios.get( + `/market-requests/?role=${getRoleFromUrl()}&search=filter&value=&page=${pageNumber}&page_size=${perPage}&type=${filter}&date1=${selectedDate1}&date2=${selectedDate2}&search=filter&value=${ + textValue ? textValue : "" + }` + ); + + dispatch(LOADING_END()); + setData(response.data.results); + setTotalRows(response.data.count); + } catch (error) { + dispatch(LOADING_END()); + } + }; + + const handleUpdate = () => { + fetchApiData(1); + getOverviewData(); + }; + + // Helper function to parse marketStateMessage JSON string + const parseMarketStateMessage = (messageString) => { + if (!messageString || typeof messageString !== "string") { + return null; + } + + try { + // Remove outer quotes if present and replace single quotes with double quotes for valid JSON + let jsonString = messageString.trim(); + // Remove outer single or double quotes + if ( + (jsonString.startsWith("'") && jsonString.endsWith("'")) || + (jsonString.startsWith('"') && jsonString.endsWith('"')) + ) { + jsonString = jsonString.slice(1, -1); + } + // Replace single quotes with double quotes + jsonString = jsonString.replace(/'/g, '"'); + const parsed = JSON.parse(jsonString); + return { + fullname: parsed?.fullname || "", + mobile: parsed?.mobile || "", + date: parsed?.date || "", + }; + } catch (error) { + console.error("Error parsing marketStateMessage:", error); + return null; + } + }; + + useEffect(() => { + const d = data?.map((item, i) => { + // Parse marketStateMessage if it exists + const marketStateInfo = parseMarketStateMessage(item?.marketStateMessage); + const statusText = `${ + item?.marketState === "deleted" + ? "حذف شده" + : item?.marketCodeStatus === true && + item?.marketFinalAccept === true && + !item?.inputMarketCode && + item?.marketState === "pending" + ? "در انتظار ورود کد احراز" + : item?.marketFinalAccept === false + ? "در انتظار تایید خریدار" + : item?.marketState === "pending" + ? "در انتظار تایید استان" + : item?.marketState === "accepted" + ? "تایید شده" + : item?.marketState === "rejected" + ? "رد شده" + : item?.marketState === "deleted" + ? "حذف شده" + : "" + }`; + + // Build status display with marketStateMessage info if available + // Only show marketStateMessage info when market_state === "deleted" + const isDeleted = item?.marketState === "deleted"; + const hasMarketStateMessage = + item?.marketStateMessage && + item.marketStateMessage !== null && + item.marketStateMessage !== ""; + + const statusDisplay = + isDeleted && marketStateInfo + ? `${statusText}${statusText ? " " : ""}( ${ + marketStateInfo.fullname + } ${marketStateInfo.mobile}) - ${formatTime(marketStateInfo.date)}` + : isDeleted && !hasMarketStateMessage + ? `${statusText}${statusText ? " " : ""}(سیستمی)` + : statusText; + + return [ + page === 1 ? i + 1 : i + perPage * (page - 1) + 1, + `${item?.poultry?.unitName || ""}`, + `${item?.poultry?.fullname || ""} (${item?.poultry?.mobile || ""})`, + item?.poultry?.city || "", + ...(getRoleFromUrl() !== "KillHouse" + ? [ + `${item?.killHouse?.killer === true ? "کشتارکن" : "کشتارگاه"} ${ + item?.killHouse?.name || "" + }`, + `${item?.killHouse?.fullname || ""} (${ + item?.killHouse?.mobile || "" + })`, + item?.killHouse?.city || "", + ] + : []), + item?.chickenBreed || "", + item?.poultryRequest?.killingAge?.toLocaleString() || "0", + item?.killCapacity?.toLocaleString() || "0", + formatJustDate(item?.reciveDate) || "-", + item?.createDate ? formatTime(item.createDate) : "-", + item?.IndexWeight || 0, + Math.round( + item?.IndexWeight * item?.killCapacity || 0 + ).toLocaleString(), + item?.amount ? item.amount.toLocaleString() : "0", + item?.paymentDeadlineDate + ? formatJustDate(item.paymentDeadlineDate) + : "-", + statusDisplay, + item?.marketState === "accepted" ? ( + + ) : ( + "-" + ), + ]; + }); + + setTableData(d); + }, [data, page, perPage]); + + useEffect(() => { + handleUpdate(); + }, [perPage, filter, selectedDate1, selectedDate2]); + + useEffect(() => { + getOverviewData(); + }, [overViewSelectedDate1, overViewSelectedDate2]); + + useEffect(() => { + if (overViewData) { + const d = overViewData?.map((item, i) => { + return [ + i + 1, + item?.name, + item?.info?.killHouseTodayShare?.toLocaleString() || "0", + item?.info?.killHouseMarketKillRequestsQuantity?.toLocaleString() || + "0", + item?.info?.killHouseMarketKillRequestsQuantityFirst?.toLocaleString() || + "0", + item?.info?.killHouseMarketKillRequestsQuantityFinal?.toLocaleString() || + "0", + item?.info?.killHouseMarketKillRequestsQuantityWeight?.toLocaleString() || + "0", + item?.info?.killHouseMarketKillRequestsQuantityFirstWeight?.toLocaleString() || + "0", + item?.info?.killHouseMarketKillRequestsQuantityFinalWeight?.toLocaleString() || + "0", + item?.info?.totalKillHouseMarketKillRequestsQuantityAgreementLightWeight?.toLocaleString() || + "0", + item?.info?.totalKillHouseMarketKillRequestsQuantityLightWeight?.toLocaleString() || + "0", + item?.info?.totalKillHouseMarketKillRequestsQuantityHeavyWeight?.toLocaleString() || + "0", + item?.info?.killHouseTodayLeftShare?.toLocaleString() || "0", + item?.info?.marketLightShare?.toLocaleString() || "0", + ]; + }); + + setOverViewDataList(d); + } + }, [overViewData]); + + return ( + + + + + فیلتر نتایج + + + + + ( + + )} + value={selectedDate1} + onChange={(e) => { + setSelectedDate1(moment(e).format("YYYY-MM-DD")); + }} + /> + + + ( + + )} + value={selectedDate2} + onChange={(e) => { + setSelectedDate2(moment(e).format("YYYY-MM-DD")); + }} + /> + +
    { + fetchApiData(1, e); + }} + > + + + +
    + + + + + + ( + + )} + value={overViewSelectedDate1} + onChange={(e) => { + setOverviewSelectedDate1(moment(e).format("YYYY-MM-DD")); + }} + /> + + + ( + + )} + value={overViewSelectedDate2} + onChange={(e) => { + setOverviewSelectedDate2(moment(e).format("YYYY-MM-DD")); + }} + /> + + +
    { + getOverviewData(e); + }} + > + + + +
    + + + + + + + + +
    + ); +}; diff --git a/src/features/province/components/province-trade-panel-market-request/ProvinceTradePanelMarketRequest.js b/src/features/province/components/province-trade-panel-market-request/ProvinceTradePanelMarketRequest.js new file mode 100644 index 0000000..6477e3d --- /dev/null +++ b/src/features/province/components/province-trade-panel-market-request/ProvinceTradePanelMarketRequest.js @@ -0,0 +1,681 @@ +import { useContext, useEffect, useRef, useState } from "react"; +import { ProvinceDirectBuyOperation } from "../province-direct-buy-operation/ProvinceDirectBuyOperation"; +import ResponsiveTable from "../../../../components/responsive-table/ResponsiveTable"; +import { Grid } from "../../../../components/grid/Grid"; +import { + formatJustDate, + formatTime, + formatTimeFull, +} from "../../../../utils/formatTime"; +import { useDispatch, useSelector } from "react-redux"; +import { + LOADING_END, + LOADING_START, +} from "../../../../lib/redux/slices/appSlice"; +import axios from "axios"; +import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl"; +import PdfKillRequest from "../province-settlement-pdf-kill-request/ProvinceSettlementPdfKillRequest"; +import { + Button, + FormControl, + InputLabel, + MenuItem, + Select, + Typography, +} from "@mui/material"; +import { + provinceTradePanelMarketRequestAdminOverview, + provinceTradePanelMarketRequestOverview, +} from "../../services/province-trade-panel-market-request-overview"; +import { AppContext } from "../../../../contexts/AppContext"; +import { RiFileExcel2Fill } from "react-icons/ri"; +import { checkPathStartsWith } from "../../../../utils/checkPathStartsWith"; + +export const ProvinceTradePanelMarketRequest = ({ + updateTable, + setUpdateRef, +}) => { + const dispatch = useDispatch(); + const userKey = useSelector((state) => state.userSlice.userProfile.key); + const [openNotif] = useContext(AppContext); + const [data, setData] = useState([]); + const [filter, setFilter] = useState("pending"); + const [tableData, setTableData] = useState([]); + const [overViewData, setOverViewData] = useState([]); + const [overViewDataList, setOverViewDataList] = useState([]); + const [overViewDataDashboard, setOverViewDataDashboard] = useState([]); + const [totalRows, setTotalRows] = useState(0); + const [perPage, setPerPage] = useState(10); + const [page, setPage] = useState(1); + const isFetching = useRef(false); + const hasFetchedDashboardApi = useRef(false); + const isFetchingDashboardApi = useRef(false); + const hasFetchedOverviewApi = useRef(false); + const isFetchingOverviewApi = useRef(false); + const lastOverviewRequestPayload = useRef(null); + const lastMarketRequestsPayload = useRef(null); + const isFetchingMarketRequests = useRef(false); + const selectedSubUser = useSelector( + (state) => state.userSlice.selectedSubUser + ); + + const handlePageChange = (pageNum) => { + lastMarketRequestsPayload.current = null; + fetchApiData(pageNum); + setPage(pageNum); + }; + + const handlePerRowsChange = (perRows) => { + setPerPage(perRows); + setPage(1); + }; + + const fetchDashboardOverview = async (forceFetch = false) => { + if (!forceFetch && hasFetchedDashboardApi.current) { + return; + } + + if (isFetchingDashboardApi.current) { + return; + } + + isFetchingDashboardApi.current = true; + hasFetchedDashboardApi.current = true; + + try { + const r = await dispatch( + provinceTradePanelMarketRequestAdminOverview({ + role_key: checkPathStartsWith("slaughter") + ? selectedSubUser?.key || "" + : "", + }) + ); + if (r?.payload?.data) { + setOverViewDataDashboard(r.payload.data); + } + } catch (error) { + console.error("Error fetching dashboard overview:", error); + hasFetchedDashboardApi.current = false; + } finally { + isFetchingDashboardApi.current = false; + } + }; + + const fetchMarketOverview = async (forceFetch = false) => { + const role = getRoleFromUrl(); + const payloadKey = JSON.stringify({ role }); + + if (!forceFetch && lastOverviewRequestPayload.current === payloadKey) { + return; + } + + if (isFetchingOverviewApi.current) { + return; + } + + isFetchingOverviewApi.current = true; + lastOverviewRequestPayload.current = payloadKey; + hasFetchedOverviewApi.current = true; + + try { + const r = await dispatch( + provinceTradePanelMarketRequestOverview({ + role_key: checkPathStartsWith("slaughter") + ? selectedSubUser?.key || "" + : "", + }) + ); + if (r?.payload?.data) { + setOverViewData(r.payload.data); + } + } catch (error) { + console.error("Error fetching market overview:", error); + lastOverviewRequestPayload.current = null; + hasFetchedOverviewApi.current = false; + } finally { + isFetchingOverviewApi.current = false; + } + }; + + const fetchMarketRequestsData = async ( + pageNumber = page, + forceFetch = false + ) => { + const payload = { + role: getRoleFromUrl(), + search: "filter", + value: "", + page: pageNumber, + page_size: perPage, + type: filter, + }; + + const payloadKey = JSON.stringify(payload); + + if (!forceFetch && lastMarketRequestsPayload.current === payloadKey) { + return null; + } + + if (isFetchingMarketRequests.current) { + return null; + } + + isFetchingMarketRequests.current = true; + lastMarketRequestsPayload.current = payloadKey; + + try { + const response = await axios.get( + `/market-requests/?role=${payload.role}&search=${ + payload.search + }&value=${payload.value}&page=${payload.page}&page_size=${ + payload.page_size + }&type=${payload.type}${ + checkPathStartsWith("slaughter") + ? `&role_key=${selectedSubUser?.key || ""}` + : "" + }` + ); + + setData(response.data.results); + setTotalRows(response.data.count); + return response; + } catch (error) { + console.error("Error fetching market requests:", error); + lastMarketRequestsPayload.current = null; + throw error; + } finally { + isFetchingMarketRequests.current = false; + } + }; + + const fetchApiData = async ( + pageNumber = page, + forceDashboardFetch = false, + forceOverviewFetch = false, + forceMarketRequestsFetch = false + ) => { + try { + dispatch(LOADING_START()); + + await fetchMarketRequestsData(pageNumber, forceMarketRequestsFetch); + + fetchDashboardOverview(forceDashboardFetch); + + fetchMarketOverview(forceOverviewFetch); + + dispatch(LOADING_END()); + } catch (error) { + dispatch(LOADING_END()); + console.error("Error fetching data:", error); + } + }; + + const parseMarketStateMessage = (messageString) => { + if (!messageString || typeof messageString !== "string") { + return null; + } + + try { + let jsonString = messageString.trim(); + if ( + (jsonString.startsWith("'") && jsonString.endsWith("'")) || + (jsonString.startsWith('"') && jsonString.endsWith('"')) + ) { + jsonString = jsonString.slice(1, -1); + } + jsonString = jsonString.replace(/'/g, '"'); + const parsed = JSON.parse(jsonString); + return { + fullname: parsed?.fullname || "", + mobile: parsed?.mobile || "", + date: parsed?.date || "", + }; + } catch (error) { + console.error("Error parsing marketStateMessage:", error); + return null; + } + }; + + const handleUpdate = async ( + forceDashboardFetch = true, + forceOverviewFetch = true, + forceMarketRequestsFetch = true + ) => { + if (isFetching.current) return; + try { + isFetching.current = true; + // Reset flags to force fresh data fetch + hasFetchedDashboardApi.current = false; + hasFetchedOverviewApi.current = false; + lastMarketRequestsPayload.current = null; + lastOverviewRequestPayload.current = null; + + await fetchApiData( + 1, + forceDashboardFetch, + forceOverviewFetch, + forceMarketRequestsFetch + ); + + // Also call parent updateTable to update main trade panel table + if (updateTable && typeof updateTable === "function") { + updateTable(); + } + } finally { + isFetching.current = false; + } + }; + + useEffect(() => { + fetchDashboardOverview(true); + fetchMarketOverview(true); + // eslint-disable-next-line react-hooks/exhaustive-deps + }, []); + + useEffect(() => { + const d = data?.map((item, i) => { + const marketStateInfo = parseMarketStateMessage(item?.marketStateMessage); + const statusText = `${ + item?.marketState === "deleted" + ? "حذف شده" + : item?.marketCodeStatus === true && + item?.marketFinalAccept === true && + !item?.inputMarketCode && + item?.marketState === "pending" + ? "در انتظار ورود کد احراز" + : item?.marketFinalAccept === false + ? "در انتظار تایید خریدار" + : item?.marketState === "pending" + ? "در انتظار تایید استان" + : item?.marketState === "accepted" + ? "تایید شده" + : item?.marketState === "rejected" + ? "رد شده" + : item?.marketState === "deleted" + ? "حذف شده" + : "" + }`; + + const isDeleted = item?.marketState === "deleted"; + const hasMarketStateMessage = + item?.marketStateMessage && + item.marketStateMessage !== null && + item.marketStateMessage !== ""; + + const statusDisplay = + isDeleted && marketStateInfo + ? `${statusText}${statusText ? " " : ""}( ${ + marketStateInfo.fullname + } ${marketStateInfo.mobile}) - ${formatTime(marketStateInfo.date)}` + : isDeleted && !hasMarketStateMessage + ? `${statusText}${statusText ? " " : ""}(سیستمی)` + : statusText; + + return [ + page === 1 ? i + 1 : i + perPage * (page - 1) + 1, + `${item?.poultry?.unitName || ""}`, + `${item?.poultry?.fullname || ""} (${item?.poultry?.mobile || ""})`, + item?.poultry?.city || "", + ...(getRoleFromUrl() !== "KillHouse" + ? [ + `${item?.killHouse?.killer === true ? "کشتارکن" : "کشتارگاه"} ${ + item?.killHouse?.name || "" + }`, + `${item?.killHouse?.fullname || ""} (${ + item?.killHouse?.mobile || "" + })`, + item?.killHouse?.city || "", + ] + : []), + item?.chickenBreed || "", + item?.poultryRequest?.killingAge?.toLocaleString() || "0", + item?.killCapacity?.toLocaleString() || "0", + formatJustDate(item?.reciveDate) || "-", + item?.createDate ? formatTimeFull(item.createDate) : "-", + item?.IndexWeight || 0, + Math.round( + item?.IndexWeight * item?.killCapacity || 0 + ).toLocaleString(), + item?.amount ? item.amount.toLocaleString() : "0", + item?.paymentDeadlineDate + ? formatJustDate(item.paymentDeadlineDate) + : "-", + statusDisplay, + item?.marketState === "accepted" ? ( + + ) : ( + "-" + ), + + , + ]; + }); + + setTableData(d); + }, [data, page, perPage]); + + useEffect(() => { + lastMarketRequestsPayload.current = null; + handleUpdate(false, false, true); + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [perPage, filter, updateTable]); + + useEffect(() => { + // Expose handleUpdate function to parent component + if (setUpdateRef && typeof setUpdateRef === "function") { + setUpdateRef(() => handleUpdate); + } + }, [setUpdateRef, handleUpdate]); + + useEffect(() => { + if (overViewData) { + let d; + if (getRoleFromUrl() === "KillHouse") { + d = [ + { + title: "سهمیه روز شما", + data: overViewData?.info?.killHouseTodayShare?.toLocaleString(), + }, + + { + title: "حجم خرید موقت", + data: overViewData?.info?.killHouseMarketKillRequestsQuantityFirst?.toLocaleString(), + }, + { + title: "حجم خرید نهایی", + data: overViewData?.info?.killHouseMarketKillRequestsQuantityFinal?.toLocaleString(), + }, + { + title: "مانده سهمیه", + data: overViewData?.info?.killHouseTodayLeftShare?.toLocaleString(), + }, + { + title: "الزام به خرید سبک", + data: overViewData?.info?.marketLightShare?.toLocaleString(), + }, + { + title: " حجم خرید سبک توافقی", + data: overViewData?.info?.totalKillHouseMarketKillRequestsQuantityAgreementLightWeight?.toLocaleString(), + }, + { + title: "حجم خرید سبک ", + data: overViewData?.info?.totalKillHouseMarketKillRequestsQuantityLightWeight?.toLocaleString(), + }, + + { + title: "حجم خرید سنگین ", + data: overViewData?.info?.totalKillHouseMarketKillRequestsQuantityHeavyWeight?.toLocaleString(), + }, + { + title: "حجم کل سفارشات", + data: overViewData?.info?.totalPoultryRequestsQuantity?.toLocaleString(), + }, + { + title: "کل حجم خریداری شده", + data: overViewData?.info?.killHouseMarketKillRequestsQuantity?.toLocaleString(), + }, + ]; + } else { + d = overViewData?.map((item, i) => { + return [ + i + 1, + item?.name, + item?.info?.killHouseTodayShare?.toLocaleString() || "0", + item?.info?.killHouseMarketKillRequestsQuantity?.toLocaleString() || + "0", + item?.info?.killHouseMarketKillRequestsQuantityFirst?.toLocaleString() || + "0", + item?.info?.killHouseMarketKillRequestsQuantityFinal?.toLocaleString() || + "0", + item?.info?.killHouseMarketKillRequestsQuantityWeight?.toLocaleString() || + "0", + item?.info?.killHouseMarketKillRequestsQuantityFirstWeight?.toLocaleString() || + "0", + item?.info?.killHouseMarketKillRequestsQuantityFinalWeight?.toLocaleString() || + "0", + item?.info?.totalKillHouseMarketKillRequestsQuantityAgreementLightWeight?.toLocaleString() || + "0", + item?.info?.totalKillHouseMarketKillRequestsQuantityLightWeight?.toLocaleString() || + "0", + item?.info?.totalKillHouseMarketKillRequestsQuantityHeavyWeight?.toLocaleString() || + "0", + item?.info?.killHouseTodayLeftShare?.toLocaleString() || "0", + item?.info?.marketLightShare?.toLocaleString() || "0", + ]; + }); + } + + setOverViewDataList(d); + } + }, [overViewData]); + + return ( + + {getRoleFromUrl() === "KillHouse" && ( + + {overViewDataList?.map((itemData, i) => ( + = 5 && i <= 9 + ? "#e0e7ff87" + : "primary.light", + + border: "1px solid", + borderColor: "divider", + transition: "transform 200ms ease, box-shadow 200ms ease", + transform: "translateY(0)", + boxShadow: "0 4px 12px rgba(0,0,0,0.06)", + "&:hover": { + boxShadow: "0 10px 28px rgba(0,0,0,0.12)", + transform: "translateY(-2px)", + }, + }} + > + + {itemData?.title} + + + {itemData?.data?.toLocaleString()} قطعه + + + ))} + + )} + + + + + + + + فیلتر نتایج + + + + + + } + title={ + getRoleFromUrl() === "KillHouse" + ? "خریدهای ثبت شده" + : "سفارشات دریافتی" + } + customWidth="100%" + data={tableData} + columns={[ + "ردیف", + "فارم", + "مرغدار", + "شهر", + ...(getRoleFromUrl() !== "KillHouse" + ? ["ماهیت خریدار", "خریدار", "آدرس خریدار"] + : []), + "نژاد", + "سن (روز)", + "تعداد قطعه", + "تاریخ کشتار", + "تاریخ ثبت سفارش", + "میانگین وزنی (کیلوگرم)", + "وزن تقریبی (کیلوگرم)", + "مبلغ هر کیلو (ریال)", + "حداکثر مهلت تسویه", + "وضعیت", + "توافق نامه", + "عملیات", + ]} + handlePageChange={handlePageChange} + totalRows={totalRows} + page={page} + perPage={perPage} + handlePerRowsChange={handlePerRowsChange} + customColors={[{ rest: true, color: "green" }]} + /> + + {getRoleFromUrl() !== "KillHouse" && ( + + + + + + )} + + ); +}; diff --git a/src/features/province/components/province-trade-panel-old-requests/ProvinceTradePanelOldRequests.js b/src/features/province/components/province-trade-panel-old-requests/ProvinceTradePanelOldRequests.js new file mode 100644 index 0000000..1a196c8 --- /dev/null +++ b/src/features/province/components/province-trade-panel-old-requests/ProvinceTradePanelOldRequests.js @@ -0,0 +1,156 @@ +import axios from "axios"; +import { useContext, useEffect, useState } from "react"; +import { useDispatch } from "react-redux"; +import { + DRAWER, + LOADING_END, + LOADING_START, +} from "../../../../lib/redux/slices/appSlice"; +import { formatJustDate } from "../../../../utils/formatTime"; +import { TradepanelDetails } from "../trade-panel-details/TradepanelDetails"; +import { Grid } from "../../../../components/grid/Grid"; +import ResponsiveTable from "../../../../components/responsive-table/ResponsiveTable"; +import { DatePicker } from "@mui/x-date-pickers"; +import { IconButton, TextField } from "@mui/material"; +import moment from "moment"; +import { AppContext } from "../../../../contexts/AppContext"; +import RemoveRedEyeIcon from "@mui/icons-material/RemoveRedEye"; +import { ProvinceTradePanelMarketOldRequestDetails } from "../province-trade-panel-market-old-request-details/ProvinceTradePanelMarketOldRequestDetails"; + +export const ProvinceTradePanelOldRequests = () => { + const [, , selectedDate1, setSelectedDate1, selectedDate2, setSelectedDate2] = + useContext(AppContext); + const dispatch = useDispatch(); + const [data, setData] = useState([]); + const [totalRows, setTotalRows] = useState(0); + const [perPage, setPerPage] = useState(20); + const [page, setPage] = useState(1); + const [tableData, setTableData] = useState([]); + + const fetchApiData = async (pageNumber = page) => { + dispatch(LOADING_START()); + try { + const response = await axios.get( + `direct-buying-poultry-requests?page=${pageNumber}&page_size=${perPage}&date1=${selectedDate1}&date2=${selectedDate2}` + ); + + dispatch(LOADING_END()); + setData(response.data.results); + setTotalRows(response.data.count); + } catch (error) { + dispatch(LOADING_END()); + } + }; + + useEffect(() => { + fetchApiData(1); + }, [perPage, selectedDate1, selectedDate2]); + + const handlePerRowsChange = (perRows) => { + setPerPage(perRows); + setPage(1); + }; + + const handlePageChange = (page) => { + fetchApiData(page); + setPage(page); + }; + + useEffect(() => { + const d = data?.map((item, i) => { + return [ + page === 1 ? i + 1 : i + perPage * (page - 1) + 1, + , + `${item?.poultry?.fullname} (${item?.poultry?.mobile})`, + item?.poultry?.city, + item?.chickenBreed, + item?.age?.age, + item?.IndexWeight, + formatJustDate(item?.sendDate), + item?.quantity, + item?.remainQuantity ? item?.remainQuantity.toLocaleString() : "0", + item?.totalAllocated ? item?.totalAllocated?.toLocaleString() : "0", + item?.amount ? item?.amount.toLocaleString() : "0", + { + dispatch( + DRAWER({ + top: true, + title: "جزئیات خرید", + content: ( + + ), + }) + ); + }} + > + + , + ]; + }); + + setTableData(d); + }, [data]); + + return ( + + + + ( + + )} + value={selectedDate1} + onChange={(e) => { + setSelectedDate1(moment(e).format("YYYY-MM-DD")); + }} + /> + + + ( + + )} + value={selectedDate2} + onChange={(e) => { + setSelectedDate2(moment(e).format("YYYY-MM-DD")); + }} + /> + + + + + ); +}; diff --git a/src/features/province/components/province-trade-panel/ProvinceTradePanel.js b/src/features/province/components/province-trade-panel/ProvinceTradePanel.js new file mode 100644 index 0000000..cde2996 --- /dev/null +++ b/src/features/province/components/province-trade-panel/ProvinceTradePanel.js @@ -0,0 +1,176 @@ +import { useEffect, useState, useMemo, useRef } from "react"; +import { Grid } from "../../../../components/grid/Grid"; +import { SPACING } from "../../../../data/spacing"; +import { ProvinceTradePanelMarketRequest } from "../province-trade-panel-market-request/ProvinceTradePanelMarketRequest"; +import { ProvinceTradePanelMarketOldRequest } from "../province-trade-panel-market-old-request/ProvinceTradePanelMarketOldRequest"; +import { TradePanelTabs } from "./TradePanelTabs"; +import { TradeTimeRangeInfo } from "./TradeTimeRangeInfo"; +import { TradePanelChart } from "./TradePanelChart"; +import { TradePanelSearchBar } from "./TradePanelSearchBar"; +import { TradePanelTable } from "./TradePanelTable"; +import { useTradePanelData } from "./useTradePanelData"; +import { useTradePanelFilters } from "./useTradePanelFilters"; + +export const ProvinceTradePanel = () => { + const [perPage, setPerPage] = useState(20); + const [textValue, setTextValue] = useState(""); + const [page, setPage] = useState(1); + const [value, setValue] = useState(0); + const marketRequestUpdateRef = useRef(null); + + const { + range, + chartsData, + data, + totalRows, + cities, + roleKey, + userKey, + fetchApiData, + initializeData, + } = useTradePanelData(); + + const { + filters, + updateFilter, + handleCityChange, + handleBreedChange, + handlePriceFilterSubmit, + handleAgeFilterSubmit, + getExcelUrlParams, + } = useTradePanelFilters(); + + const excelUrlParams = useMemo(() => { + if (!userKey) return ""; + return getExcelUrlParams(userKey, roleKey, textValue, page, perPage); + }, [getExcelUrlParams, userKey, roleKey, textValue, page, perPage]); + + useEffect(() => { + initializeData(textValue, filters, perPage); + }, []); + + useEffect(() => { + if (page === 1 && textValue === "") { + return; + } + fetchApiData(page, textValue, filters, perPage); + }, [ + page, + textValue, + filters.selectedBreeds, + filters.selectedCities, + filters.showRemaining, + filters.minPrice, + filters.maxPrice, + filters.minAge, + filters.maxAge, + perPage, + fetchApiData, + ]); + + const handleTextChange = (event) => { + setTextValue(event.target.value); + }; + + const handleChange = (event, newValue) => { + setValue(newValue); + }; + + const handlePerRowsChange = (perRows) => { + setPerPage(perRows); + setPage(1); + }; + + const handlePageChange = (pageNum) => { + setPage(pageNum); + fetchApiData(pageNum, textValue, filters, perPage); + }; + + const updateTable = () => { + fetchApiData(1, textValue, filters, perPage); + }; + + const updateAllTables = () => { + // Update "لیست اعلام کشتار های مرغداران" (tab 0) + updateTable(); + // Update "خریدهای ثبت شده" (tab 1) - call all services for ProvinceTradePanelMarketRequest + if ( + marketRequestUpdateRef.current && + typeof marketRequestUpdateRef.current === "function" + ) { + // Force all fetches: dashboard, overview, and market requests + marketRequestUpdateRef.current(true, true, true); + } + }; + + const handleSubmit = async (event) => { + event.preventDefault(); + setPage(1); + fetchApiData(1, textValue, filters, perPage); + }; + + const handlePriceFilterSubmitWithPageReset = () => { + handlePriceFilterSubmit(); + setPage(1); + }; + + const handleAgeFilterSubmitWithPageReset = () => { + handleAgeFilterSubmit(); + setPage(1); + }; + + return ( + <> + + + + {value === 0 && ( + + + + + + )} + + + { + marketRequestUpdateRef.current = updateFn; + }} + /> + + {value === 2 && ( + + + + )} + + + ); +}; + +export default ProvinceTradePanel; diff --git a/src/features/province/components/province-trade-panel/TradePanelChart.js b/src/features/province/components/province-trade-panel/TradePanelChart.js new file mode 100644 index 0000000..8a15bd3 --- /dev/null +++ b/src/features/province/components/province-trade-panel/TradePanelChart.js @@ -0,0 +1,72 @@ +import { useMemo } from "react"; +import { Grid } from "../../../../components/grid/Grid"; +import { AdvancedChart } from "../../../../components/advanced-chart/AdvancedChart"; +import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl"; +import { ProvinceTradePanelMarketRequest } from "../province-trade-panel-market-request/ProvinceTradePanelMarketRequest"; + +export const TradePanelChart = ({ chartsData, updateTable }) => { + const chartOptions = useMemo(() => { + if (!chartsData || !Array.isArray(chartsData) || !chartsData[0]) { + return []; + } + + const firstItem = chartsData[0]; + if (!firstItem?.category || !Array.isArray(firstItem.category)) { + return [ + { + name: "تعداد کل", + data: chartsData.map((item) => item?.totalQuantity || 0), + }, + ]; + } + + const formatCategoryName = (category) => + `بین ${category?.minValue || 0} تا ${category?.maxValue || 0}`; + + return [ + { + name: "تعداد کل", + data: chartsData.map((item) => item?.totalQuantity || 0), + }, + ...firstItem.category.map((cat, index) => ({ + name: formatCategoryName(cat), + data: chartsData.map((item) => { + if (!item?.category || !Array.isArray(item.category)) return 0; + return item.category[index]?.quantity || 0; + }), + })), + ]; + }, [chartsData]); + + const chartSeparator = + chartsData && Array.isArray(chartsData) + ? chartsData.map((item) => item?.city || "") + : []; + + const isKillHouse = getRoleFromUrl() === "KillHouse"; + + return ( + + + + + {isKillHouse && ( + + + + )} + + ); +}; diff --git a/src/features/province/components/province-trade-panel/TradePanelSearchBar.js b/src/features/province/components/province-trade-panel/TradePanelSearchBar.js new file mode 100644 index 0000000..b726878 --- /dev/null +++ b/src/features/province/components/province-trade-panel/TradePanelSearchBar.js @@ -0,0 +1,45 @@ +import { Button, TextField, Tooltip } from "@mui/material"; +import axios from "axios"; +import { RiFileExcel2Fill, RiSearchLine } from "react-icons/ri"; +import { Grid } from "../../../../components/grid/Grid"; +import { SPACING } from "../../../../data/spacing"; + +export const TradePanelSearchBar = ({ + textValue, + onTextChange, + onSubmit, + excelUrlParams, +}) => { + return ( + +
    + + + + + + + + + + + +
    +
    + ); +}; diff --git a/src/features/province/components/province-trade-panel/TradePanelTable.js b/src/features/province/components/province-trade-panel/TradePanelTable.js new file mode 100644 index 0000000..c14401b --- /dev/null +++ b/src/features/province/components/province-trade-panel/TradePanelTable.js @@ -0,0 +1,117 @@ +import { useEffect, useState } from "react"; +import { Grid } from "../../../../components/grid/Grid"; +import ResponsiveTable from "../../../../components/responsive-table/ResponsiveTable"; +import { formatJustDate } from "../../../../utils/formatTime"; +import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl"; +import { TradepanelDetails } from "../trade-panel-details/TradepanelDetails"; +import { TradePanelPurchaseOperation } from "../trade-panel-purchase-operation/TradePanelPurchaseOperation"; +import { TradePanelFilters } from "../trade-panel-filter/TradePanelFilter"; +import { CHICKEN_BREEDS } from "./constants"; + +export const TradePanelTable = ({ + data, + page, + perPage, + totalRows, + filters, + cities, + onFilterUpdate, + onCityChange, + onBreedChange, + onPriceFilterSubmit, + onAgeFilterSubmit, + onPageChange, + onPerRowsChange, + updateTable, +}) => { + const [tableData, setTableData] = useState([]); + + useEffect(() => { + if (!data || !Array.isArray(data)) { + setTableData([]); + return; + } + + const formatNumber = (num) => { + if (num === null || num === undefined) return "0"; + return num.toLocaleString(); + }; + + const rowNumber = (index) => { + const currentPage = page || 1; + const currentPerPage = perPage || 20; + return currentPage === 1 + ? index + 1 + : index + currentPerPage * (currentPage - 1) + 1; + }; + + const tableRows = data.map((item, i) => [ + rowNumber(i), + , + `${item?.poultry?.fullname || ""} (${item?.poultry?.mobile || ""})`, + item?.poultry?.city || "-", + item?.chickenBreed || "-", + item?.age?.age || "-", + item?.IndexWeight || "-", + item?.sendDate ? formatJustDate(item.sendDate) : "-", + item?.quantity || "-", + formatNumber(item?.remainQuantity), + formatNumber(item?.totalAllocated), + formatNumber(item?.amount), + , + ]); + + setTableData(tableRows); + }, [data, page, perPage, updateTable]); + + const columns = [ + "ردیف", + "جزئیات", + "نام و نام خانوادگی (تلفن)", + "استان / شهر", + "نژاد", + "سن جوجه", + "میانگین وزنی (کیلوگرم) ", + "تاریخ کشتار", + "تعداد قطعه", + "مانده قابل خرید", + "فروش رفته ", + "مبلغ هر کیلو (ریال)", + ...(getRoleFromUrl() === "KillHouse" ? ["خرید"] : []), + ]; + + return ( + + + + + + + + + + ); +}; diff --git a/src/features/province/components/province-trade-panel/TradePanelTabs.js b/src/features/province/components/province-trade-panel/TradePanelTabs.js new file mode 100644 index 0000000..032af1b --- /dev/null +++ b/src/features/province/components/province-trade-panel/TradePanelTabs.js @@ -0,0 +1,25 @@ +import { Tab, Tabs } from "@mui/material"; +import { Grid } from "../../../../components/grid/Grid"; +import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl"; + +export const TradePanelTabs = ({ value, onChange }) => { + if (getRoleFromUrl() === "KillHouse") { + return null; + } + + return ( + + + + + + + + ); +}; diff --git a/src/features/province/components/province-trade-panel/TradeTimeRangeInfo.js b/src/features/province/components/province-trade-panel/TradeTimeRangeInfo.js new file mode 100644 index 0000000..0b8853e --- /dev/null +++ b/src/features/province/components/province-trade-panel/TradeTimeRangeInfo.js @@ -0,0 +1,20 @@ +import { Typography } from "@mui/material"; +import InfoIcon from "@mui/icons-material/Info"; +import { Grid } from "../../../../components/grid/Grid"; + +export const TradeTimeRangeInfo = ({ range }) => { + if (!range?.allow) { + return null; + } + + return ( + + + + زمان فعالیت پنل معاملات: از ساعت{" "} + {range?.start_time ? range.start_time.slice(0, 5) : "-"} الی ساعت{" "} + {range?.end_time ? range.end_time.slice(0, 5) : "-"} + + + ); +}; diff --git a/src/features/province/components/province-trade-panel/constants.js b/src/features/province/components/province-trade-panel/constants.js new file mode 100644 index 0000000..fa1293d --- /dev/null +++ b/src/features/province/components/province-trade-panel/constants.js @@ -0,0 +1,15 @@ +export const CHICKEN_BREEDS = ["آرین", "راس", "کاب", "*ترکیبی"]; + +export const INITIAL_FILTERS = { + showRemaining: false, + selectedCities: [], + selectedBreeds: [], + minPrice: "", + maxPrice: "", + tempMinPrice: "", + tempMaxPrice: "", + minAge: "", + maxAge: "", + tempMinAge: "", + tempMaxAge: "", +}; diff --git a/src/features/province/components/province-trade-panel/useTradePanelData.js b/src/features/province/components/province-trade-panel/useTradePanelData.js new file mode 100644 index 0000000..441d7a8 --- /dev/null +++ b/src/features/province/components/province-trade-panel/useTradePanelData.js @@ -0,0 +1,169 @@ +import { useEffect, useState, useCallback, useRef, useMemo } from "react"; +import { useDispatch, useSelector } from "react-redux"; +import axios from "axios"; +import { checkPathStartsWith } from "../../../../utils/checkPathStartsWith"; +import { tradePanelChart } from "../../services/trade-panel-chat"; +import { provincePolicyGetTradeTimeRagnge } from "../../services/province-policy-edit-trade-time-range"; +import { provinceGetDirectBuyingPoultryRequests } from "../../services/province-get-direct-buying-poultry-requests"; + +export const useTradePanelData = () => { + const dispatch = useDispatch(); + const userKey = useSelector((state) => state.userSlice.userProfile.key); + const selectedSubUser = useSelector( + (state) => state.userSlice.selectedSubUser + ); + + const [range, setRange] = useState(); + const [chartsData, setChartsData] = useState([]); + const [data, setData] = useState([]); + const [totalRows, setTotalRows] = useState(0); + const [cities, setCities] = useState([]); + + const isInitialMount = useRef(true); + const lastRequestPayload = useRef(null); + const isFetching = useRef(false); + + const roleKey = useMemo( + () => (checkPathStartsWith("slaughter") ? selectedSubUser?.key || "" : ""), + [selectedSubUser?.key] + ); + + useEffect(() => { + const fetchCities = async () => { + try { + const response = await axios.get("/cities"); + setCities(response.data); + } catch (error) { + console.error("خطا در دریافت اطلاعات", error); + } + }; + fetchCities(); + }, []); + + const fetchTradeTimeRange = useCallback(async () => { + const r = await dispatch(provincePolicyGetTradeTimeRagnge()); + if (r?.payload?.data) { + const { startTime, endTime, allow } = r.payload.data; + setRange({ start_time: startTime, end_time: endTime, allow }); + } + }, [dispatch, roleKey]); + + const fetchChartData = useCallback(async () => { + const r = await dispatch( + tradePanelChart({ + role_key: checkPathStartsWith("slaughter") ? roleKey || "" : "", + }) + ); + if (r?.payload?.data) { + setChartsData(r.payload.data); + } + }, [dispatch, roleKey]); + + const fetchApiData = useCallback( + async (pageNumber, searchValue, filters, perPage, forceFetch = false) => { + const { + selectedBreeds = [], + selectedCities = [], + showRemaining = false, + minPrice = "", + maxPrice = "", + minAge = "", + maxAge = "", + } = filters || {}; + + const payload = { + selectedBreeds: [...(selectedBreeds || [])].sort().join(","), + selectedCities: [...(selectedCities || [])].sort().join(","), + showRemaining, + minPrice: minPrice || "", + maxPrice: maxPrice || "", + minAge: minAge || "", + maxAge: maxAge || "", + textValue: searchValue || "", + page: pageNumber || 1, + perPage: perPage || 20, + }; + + const payloadKey = JSON.stringify(payload); + + if (!forceFetch && lastRequestPayload.current === payloadKey) { + return; + } + + if (isFetching.current) { + return; + } + + isFetching.current = true; + lastRequestPayload.current = payloadKey; + + try { + const r = await dispatch( + provinceGetDirectBuyingPoultryRequests({ + selectedBreeds: selectedBreeds || [], + selectedCities: selectedCities || [], + showRemaining, + minPrice: minPrice || "", + maxPrice: maxPrice || "", + minAge: minAge || "", + maxAge: maxAge || "", + textValue: searchValue || "", + page: pageNumber || 1, + perPage: perPage || 20, + }) + ); + if (r?.payload?.error) { + console.error("Error fetching data:", r.payload.error); + setData([]); + setTotalRows(0); + } else if (r?.payload?.data) { + setData(r.payload.data.results || []); + setTotalRows(r.payload.data.count || 0); + } + } catch (error) { + console.error("Error in fetchApiData:", error); + setData([]); + setTotalRows(0); + } finally { + isFetching.current = false; + } + }, + [dispatch, roleKey] + ); + + const initializeData = useCallback( + async (textValue, filters, perPage) => { + if (isInitialMount.current) { + isInitialMount.current = false; + lastRequestPayload.current = null; + try { + await Promise.all([ + fetchTradeTimeRange(), + fetchChartData(), + fetchApiData(1, textValue, filters, perPage, true), + ]); + } catch (error) { + console.error("Error in initial fetch:", error); + } + } + }, + [fetchTradeTimeRange, fetchChartData, fetchApiData] + ); + + const resetPayload = useCallback(() => { + lastRequestPayload.current = null; + }, []); + + return { + range, + chartsData, + data, + totalRows, + cities, + roleKey, + userKey, + fetchApiData, + initializeData, + resetPayload, + }; +}; diff --git a/src/features/province/components/province-trade-panel/useTradePanelFilters.js b/src/features/province/components/province-trade-panel/useTradePanelFilters.js new file mode 100644 index 0000000..3b61be9 --- /dev/null +++ b/src/features/province/components/province-trade-panel/useTradePanelFilters.js @@ -0,0 +1,105 @@ +import { useState, useMemo } from "react"; +import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl"; +import { INITIAL_FILTERS } from "./constants"; + +export const useTradePanelFilters = () => { + const [filters, setFilters] = useState(INITIAL_FILTERS); + + const updateFilter = (key, value) => { + setFilters((prev) => ({ ...prev, [key]: value })); + }; + + const toggleArrayItem = (array, item) => + array.includes(item) ? array.filter((i) => i !== item) : [...array, item]; + + const handleCityChange = (city) => { + setFilters((prev) => ({ + ...prev, + selectedCities: toggleArrayItem(prev.selectedCities, city), + })); + }; + + const handleBreedChange = (breed) => { + setFilters((prev) => ({ + ...prev, + selectedBreeds: toggleArrayItem(prev.selectedBreeds, breed), + })); + }; + + const handlePriceFilterSubmit = () => { + setFilters((prev) => ({ + ...prev, + minPrice: prev.tempMinPrice, + maxPrice: prev.tempMaxPrice, + })); + }; + + const handleAgeFilterSubmit = () => { + setFilters((prev) => ({ + ...prev, + minAge: prev.tempMinAge, + maxAge: prev.tempMaxAge, + })); + }; + + const { + selectedCities, + selectedBreeds, + showRemaining, + minPrice, + maxPrice, + minAge, + maxAge, + } = filters; + + const getExcelUrlParams = useMemo(() => { + return (userKey, roleKey, textValue, page, perPage) => { + const params = new URLSearchParams({ + key: userKey || "", + breed: selectedBreeds?.join(",") || "", + remain: showRemaining, + min_age: minAge || "", + max_age: maxAge || "", + role: getRoleFromUrl() || "", + search: "filter", + value: textValue || "", + page: page?.toString() || "1", + page_size: perPage?.toString() || "20", + }); + + if (selectedCities?.length > 0) { + params.append("city", selectedCities.join(",")); + } + if (minPrice) params.append("min_amount", minPrice); + if (maxPrice) params.append("max_amount", maxPrice); + if (roleKey) params.append("role_key", roleKey); + + return params.toString(); + }; + }, [ + selectedBreeds, + selectedCities, + showRemaining, + minPrice, + maxPrice, + minAge, + maxAge, + ]); + + return { + filters, + updateFilter, + handleCityChange, + handleBreedChange, + handlePriceFilterSubmit, + handleAgeFilterSubmit, + selectedCities, + selectedBreeds, + showRemaining, + minPrice, + maxPrice, + minAge, + maxAge, + getExcelUrlParams, + }; +}; diff --git a/src/features/province/components/province-true-guilds-in-province/ProvinceTrueGuildsInProvince.js b/src/features/province/components/province-true-guilds-in-province/ProvinceTrueGuildsInProvince.js new file mode 100644 index 0000000..8e82397 --- /dev/null +++ b/src/features/province/components/province-true-guilds-in-province/ProvinceTrueGuildsInProvince.js @@ -0,0 +1,3 @@ +export const ProvinceTrueGuildsInProvince = () => { + return "ProvinceTrueGuildsInProvince"; +}; diff --git a/src/features/province/components/province-true-guilds-out-province/ProvinceTrueGuildsOutProvince.js b/src/features/province/components/province-true-guilds-out-province/ProvinceTrueGuildsOutProvince.js new file mode 100644 index 0000000..bf88486 --- /dev/null +++ b/src/features/province/components/province-true-guilds-out-province/ProvinceTrueGuildsOutProvince.js @@ -0,0 +1,144 @@ +import React, { useEffect, useState } from "react"; +import { Button, TextField } from "@mui/material"; +import ResponsiveTable from "../../../../components/responsive-table/ResponsiveTable"; +import { + LOADING_END, + LOADING_START, +} from "../../../../lib/redux/slices/appSlice"; +import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl"; +import { Grid } from "../../../../components/grid/Grid"; +import { useDispatch } from "react-redux"; +import { RiSearchLine } from "react-icons/ri"; +import { fetchOutProvinceRealBuyers } from "../../services/province-out-province-buyers"; + +export const ProvinceTrueGuildsOutProvince = () => { + const handleTextChange = (event) => { + setTextValue(event.target.value); + }; + + const dispatch = useDispatch(); + + const [data, setData] = useState([]); + const [totalRows, setTotalRows] = useState(0); + const [perPage, setPerPage] = useState(10); + const [textValue, setTextValue] = useState(""); + const [page, setPage] = useState(1); + const [tableData, setTableData] = useState([]); + + const fetchApiData = async (page) => { + dispatch(LOADING_START()); + try { + const response = await fetchOutProvinceRealBuyers({ + role: getRoleFromUrl(), + page: page, + pageSize: perPage, + searchValue: textValue, + }); + setData(response.data.results); + setTotalRows(response.data.count); + } catch (error) { + console.error("Error fetching data:", error); + } finally { + dispatch(LOADING_END()); + } + }; + + const handlePageChange = (page) => { + fetchApiData(page); + setPage(page); + }; + + const handlePerRowsChange = (perRows) => { + setPerPage(perRows); + setPage(1); + }; + + useEffect(() => { + const d = data?.map((item, i) => { + const killHouseName = item?.KillHouse?.name || "-"; + const killHouseOperator = + item?.KillHouse?.killHouseOperator?.user?.fullname || ""; + const killHouseInfo = killHouseOperator + ? `${killHouseName} (${killHouseOperator})` + : killHouseName; + + return [ + page === 1 ? i + 1 : i + perPage * (page - 1) + 1, + `${item?.fullname} (${item?.mobile})`, + item?.unitName || "-", + killHouseInfo, + item?.province || "-", + item?.city || "-", + item?.requestsInfo?.numberOfRequests?.toLocaleString() || "0", + item?.requestsInfo?.totalQuantity?.toLocaleString() || "0", + item?.requestsInfo?.totalWeight?.toLocaleString() || "0", + ]; + }); + + setTableData(d); + }, [data, page, perPage]); + + useEffect(() => { + fetchApiData(1); + }, [dispatch, perPage]); + + const handleSubmit = async (event) => { + event.preventDefault(); + fetchApiData(1); + setPage(1); + }; + + return ( + + + +
    + + + +
    +
    + + +
    + ); +}; diff --git a/src/features/province/components/province-unarchive-fee/ProvinceUnarchiveFee.js b/src/features/province/components/province-unarchive-fee/ProvinceUnarchiveFee.js new file mode 100644 index 0000000..025727f --- /dev/null +++ b/src/features/province/components/province-unarchive-fee/ProvinceUnarchiveFee.js @@ -0,0 +1,65 @@ +import { Button } from "@mui/material"; +import { Grid } from "../../../../components/grid/Grid"; +import { SPACING } from "../../../../data/spacing"; +import { useDispatch } from "react-redux"; +import { provinceUnarchiveFeeService } from "../../services/province-unarchive-fee"; +import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl"; +import { CLOSE_MODAL } from "../../../../lib/redux/slices/appSlice"; +import { AppContext } from "../../../../contexts/AppContext"; +import { useContext } from "react"; + +export const ProvinceUnarchiveFee = ({ + provinceKillRequestKey, + updateTable, +}) => { + const dispatch = useDispatch(); + const [openNotif] = useContext(AppContext); + + return ( + + + + + + + ); +}; diff --git a/src/features/province/components/province-unpaid-fees/ProvinceUnpaidFees.js b/src/features/province/components/province-unpaid-fees/ProvinceUnpaidFees.js new file mode 100644 index 0000000..ef58b06 --- /dev/null +++ b/src/features/province/components/province-unpaid-fees/ProvinceUnpaidFees.js @@ -0,0 +1,318 @@ +import { + Button, + Checkbox, + FormControlLabel, + TextField, + Tooltip, + Typography, +} from "@mui/material"; +import axios from "axios"; +import { useContext, useEffect, useState } from "react"; +import { RiFileExcel2Fill, RiSearchLine } from "react-icons/ri"; +import { useSelector } from "react-redux"; +import { useNavigate } from "react-router-dom"; +import { Grid } from "../../../../components/grid/Grid"; +import { PageTable } from "../../../../components/page-table/PageTable"; +import { SPACING } from "../../../../data/spacing"; +import { + ROUTE_ADMINX_PAYING_FEES_REQUESTS, + ROUTE_PROVINCE_PAYING_FEES_REQUESTS, + ROUTE_SUPER_ADMIN_PAYING_FEES_REQUESTS, +} from "../../../../routes/routes"; +import moment from "moment"; +import { DatePicker } from "@mui/x-date-pickers"; +import { AppContext } from "../../../../contexts/AppContext"; +import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl"; + +export const ProvinceUnpaidFees = () => { + const authToken = useSelector((state) => state.userSlice.authToken); + const navigate = useNavigate(); + const [data, setData] = useState([]); + const [loading, setLoading] = useState(false); + const [totalRows, setTotalRows] = useState(0); + const [perPage, setPerPage] = useState(10); + const [withDate, setWithDate] = useState(false); + const [textValue, setTextValue] = useState(""); + + const handleTextChange = (event) => { + setTextValue(event.target.value); + }; + + const [, , selectedDate1, setSelectedDate1, selectedDate2, setSelectedDate2] = + useContext(AppContext); + + useEffect(() => { + const currentDate = moment(new Date()).format("YYYY-MM-DD"); + setSelectedDate1(currentDate); + setSelectedDate2(currentDate); + }, []); + + const fetchApiData = async (page, textValue) => { + setLoading(true); + const response = await axios.get( + `kill_house_total_wage/?search=filter&value=${textValue}&type=unpaid&page=${page}&role=${getRoleFromUrl()}&page_size=${perPage}${ + withDate ? `&date1=${selectedDate1}&date2=${selectedDate2}` : `` + }` + ); + setData(response.data.results); + setTotalRows(response.data.count); + setLoading(false); + }; + + const handlePageChange = (page) => { + fetchApiData(page, textValue); + }; + + const handlePerRowsChange = async (newPerPage, page) => { + setLoading(true); + const response = await axios.get( + `kill_house_total_wage/?search=filter&value=${textValue}&type=unpaid&page=${page}&role=${getRoleFromUrl()}&page_size=${newPerPage}${ + withDate ? `&date1=${selectedDate1}&date2=${selectedDate2}` : `` + }` + ); + + setData(response.data.results); + setTotalRows(response.data.count); + setPerPage(newPerPage); + + setLoading(false); + }; + + useEffect(() => { + fetchApiData(1); + }, []); + + const handleSubmit = async (event) => { + event.preventDefault(); + setLoading(true); + + try { + const response = await axios.get( + `kill_house_total_wage/?search=filter&value=${textValue}&type=unpaid${ + withDate ? `&date1=${selectedDate1}&date2=${selectedDate2}` : `` + }` + ); + setData(response.data.results); + setTotalRows(response.data.count); + } catch (error) { + console.error("Error fetching data:", error); + } finally { + setLoading(false); + } + }; + + useEffect(() => { + fetchApiData(1); + }, [selectedDate1, selectedDate2, withDate]); + + const columns = [ + { + name: "خریدار", + selector: (item) => { + const type = item?.info?.killer ? "کشتارکن" : "کشتارگاه"; + return `${type} ${item?.info?.killHouseName} - ${item?.info?.killHouseFullname} (${item?.info?.killHouseMobile})`; + }, + sortable: true, + wrap: true, + allowOverflow: true, + center: true, + // width: "90px", + }, + { + name: "شهر", + selector: (item) => `${item?.info?.killHouseCity}`, + sortable: true, + wrap: true, + allowOverflow: true, + center: true, + // width: "80px", + }, + { + name: "تعداد پرونده", + selector: (item) => item?.info?.totalCount?.toLocaleString(), + sortable: true, + wrap: true, + allowOverflow: true, + center: true, + // width: "90px", + }, + { + name: "حجم", + selector: (item) => item.info?.totalQuantity?.toLocaleString(), + sortable: true, + wrap: true, + allowOverflow: true, + center: true, + // width: "90px", + }, + { + name: "وزن سفارشات (کیلوگرم)", + selector: (item) => item.info?.totalWeight?.toLocaleString(), + sortable: true, + wrap: true, + allowOverflow: true, + center: true, + // width: "90px", + }, + { + name: "مبلغ تعرفه (﷼)", + selector: (item) => item?.info?.totalWage?.toLocaleString(), + sortable: true, + wrap: true, + allowOverflow: true, + center: true, + // width: "90px", + }, + { + name: "جزییات سفارش", + selector: (item) => { + return ( + + ); + }, + sortable: true, + wrap: true, + allowOverflow: true, + center: true, + // width: "90px", + }, + ]; + + return ( + + + + تعرفه های پرداخت نشده + + + setWithDate(!withDate)} + color="primary" + /> + } + /> + + + ( + + )} + value={selectedDate1} + onChange={(e) => { + setSelectedDate1(moment(e).format("YYYY-MM-DD")); + }} + /> + + + ( + + )} + value={selectedDate2} + onChange={(e) => { + setSelectedDate2(moment(e).format("YYYY-MM-DD")); + }} + /> + + +
    + + + + + + + + +
    +
    + } + columns={columns} + data={data} + progressPending={loading} + pagination + paginationServer + paginationTotalRows={totalRows} + onChangeRowsPerPage={handlePerRowsChange} + onChangePage={handlePageChange} + /> + + ); +}; diff --git a/src/features/province/components/province-update-killer-identity/ProvinceUpdateKillerIdentity.js b/src/features/province/components/province-update-killer-identity/ProvinceUpdateKillerIdentity.js new file mode 100644 index 0000000..dc96ac0 --- /dev/null +++ b/src/features/province/components/province-update-killer-identity/ProvinceUpdateKillerIdentity.js @@ -0,0 +1,64 @@ +import { MenuItem, Select } from "@mui/material"; +import { useContext, useState } from "react"; +import { useDispatch } from "react-redux"; +import { AppContext } from "../../../../contexts/AppContext"; +import { slaughterGetKillerKillhousesService } from "../../../slaughter-house/services/slaughter-get-killers-killhouses"; +import { provinceGetSlaughterhousesQuotaService } from "../../services/province-get-slaughterhouses-quota"; +import { provinceUpdateKillerIdentityService } from "../../services/province-update-killer-identity"; + +export const ProvinceUpdateKillerIdentity = ({ + slaughterKey, + disableSelect, + killerType, +}) => { + const dispatch = useDispatch(); + const [openNotif] = useContext(AppContext); + const [selectedOption, setSelectedOption] = useState(killerType); + const handleOptionChange = (event) => { + dispatch( + provinceUpdateKillerIdentityService({ + kill_house_key: slaughterKey, + type: event.target.value, + }) + ).then((r) => { + if (r.payload.error) { + openNotif({ + vertical: "top", + horizontal: "center", + msg: r.payload.error, + severity: "error", + }); + } else { + setSelectedOption(event.target.value); + dispatch(provinceGetSlaughterhousesQuotaService()); + dispatch(slaughterGetKillerKillhousesService()); + openNotif({ + vertical: "top", + horizontal: "center", + msg: "عملیات با موفقیت انجام شد.", + severity: "success", + }); + } + }); + }; + + return ( + <> + {disableSelect ? ( + "-" + ) : ( + + )} + + ); +}; diff --git a/src/features/province/components/province-update-slaughter-identity/ProvinceUpdateSlaughterIdentity.js b/src/features/province/components/province-update-slaughter-identity/ProvinceUpdateSlaughterIdentity.js new file mode 100644 index 0000000..e6db1c6 --- /dev/null +++ b/src/features/province/components/province-update-slaughter-identity/ProvinceUpdateSlaughterIdentity.js @@ -0,0 +1,57 @@ +import { MenuItem, Select } from "@mui/material"; +import { useContext, useState } from "react"; +import { useDispatch } from "react-redux"; +import { AppContext } from "../../../../contexts/AppContext"; +import { slaughterGetKillerKillhousesService } from "../../../slaughter-house/services/slaughter-get-killers-killhouses"; +import { provinceGetSlaughterhousesQuotaService } from "../../services/province-get-slaughterhouses-quota"; +import { provinceUpdateSlaughterIdentityService } from "../../services/province-update-slaughter-identity"; + +export const ProvinceUpdateSlaughterIdentity = ({ + killhouseType, + slaughterKey, +}) => { + const dispatch = useDispatch(); + const [openNotif] = useContext(AppContext); + const [selectedOption, setSelectedOption] = useState(killhouseType); + + const handleOptionChange = (event) => { + dispatch( + provinceUpdateSlaughterIdentityService({ + percentage_key: slaughterKey, + identity: event.target.value, + }) + ).then((r) => { + if (r.payload.error) { + openNotif({ + vertical: "top", + horizontal: "center", + msg: r.payload.error, + severity: "error", + }); + } else { + setSelectedOption(event.target.value); + dispatch(provinceGetSlaughterhousesQuotaService()); + dispatch(slaughterGetKillerKillhousesService()); + openNotif({ + vertical: "top", + horizontal: "center", + msg: "عملیات با موفقیت انجام شد.", + severity: "success", + }); + } + }); + }; + + return ( + + ); +}; diff --git a/src/features/province/components/province-view-buyer-fees/ProvinceViewBuyerFees.js b/src/features/province/components/province-view-buyer-fees/ProvinceViewBuyerFees.js new file mode 100644 index 0000000..2489de0 --- /dev/null +++ b/src/features/province/components/province-view-buyer-fees/ProvinceViewBuyerFees.js @@ -0,0 +1,5 @@ +import { Typography } from "@mui/material"; + +export const ProvinceViewBuyerFees = () => { + return ProvinceViewBuyerFees; +}; diff --git a/src/features/province/components/province-wage-payment-create-transaction/ProvinceWagePaymentCreateTransaction.js b/src/features/province/components/province-wage-payment-create-transaction/ProvinceWagePaymentCreateTransaction.js new file mode 100644 index 0000000..c14e68d --- /dev/null +++ b/src/features/province/components/province-wage-payment-create-transaction/ProvinceWagePaymentCreateTransaction.js @@ -0,0 +1,457 @@ +import React, { useContext, useEffect, useState } from "react"; +import { + Grid, + TextField, + Autocomplete, + Button, + FormHelperText, + Select, + InputLabel, + FormControl, + MenuItem, +} from "@mui/material"; +import { useFormik } from "formik"; +import { Yup } from "../../../../lib/yup/yup"; +import { useDispatch } from "react-redux"; +import { provinceGetBuyersService } from "../../services/province-get-buyers"; +import { AppContext } from "../../../../contexts/AppContext"; +import { + provinceWagePaymentCreateTransactionService, + provinceWagePaymentEditTransactionService, +} from "../../services/province-wage-payment-create-transaction-service"; +import { DRAWER } from "../../../../lib/redux/slices/appSlice"; +import { ImageUpload } from "../../../../components/image-upload/ImageUpload"; +import { fixBase64 } from "../../../../utils/toBase64"; +import { DatePicker } from "@mui/x-date-pickers"; +import moment from "moment"; +import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl"; + +export const ProvinceWagePaymentCreateTransaction = ({ + fetchApiData, + item, + isEdit, +}) => { + const [killHouses, setKillHouses] = useState([]); + const dispatch = useDispatch(); + + const [openNotif] = useContext(AppContext); + const [profileImages, setProfileImages] = useState([]); + + const [, , selectedDate1, setSelectedDate1] = useContext(AppContext); + + useEffect(() => { + if (item?.date) { + setSelectedDate1(moment(item?.date).format("YYYY-MM-DD HH:MM")); + } + }, []); + + const validationSchema = Yup.object({ + kill_house_key: Yup.string().required("کشتارگاه را انتخاب کنید!"), + description: Yup.string(), + amount: Yup.number().required("مبلغ را وارد کنید!"), + image: Yup.string(), + transaction_type: Yup.string().required("نوع تراکنش را وارد کنید!"), + refId: Yup.string().required("شناسه ارجاع را وارد کنید!"), + orderId: Yup.string().required("شناسه سفارش را وارد کنید!"), + cardHolderPan: Yup.string().required("کارت بانکی را وارد کنید!"), + union_share: Yup.number().required("سهم اتحادیه را وارد کنید!"), + company_share: Yup.number().required("سهم شرکت را وارد کنید!"), + guilds_share: Yup.number().required("سهم اصناف را وارد کنید!"), + other_share: Yup.number().required("سایر سهم ها را وارد کنید!"), + }); + + const formik = useFormik({ + initialValues: { + kill_house_key: isEdit ? "test" : "", + description: item?.description ? item?.description : "", + amount: item?.amount ? item?.amount : "", + transaction_type: item?.transactionType ? item?.transactionType : "", + refId: item?.refId ? item?.refId : "", + orderId: item?.orderId ? item?.orderId : "", + cardHolderPan: item?.cardHolderPan ? item?.cardHolderPan : "", + union_share: item?.unionShare ? item?.unionShare : 0, + company_share: item?.companyShare ? item?.companyShare : 0, + guilds_share: item?.guildsShare ? item?.guildsShare : 0, + other_share: item?.otherShare ? item?.otherShare : 0, + image: "", + }, + validationSchema, + }); + + useEffect(() => { + if (!isEdit) { + dispatch( + provinceGetBuyersService({ dispenser: true, role: getRoleFromUrl() }) + ).then((r) => { + setKillHouses(r.payload.data); + }); + } + }, []); + + useEffect(() => { + formik.validateForm(); + }, []); + + const factorPaymentHandler = (imageList, addUpdateIndex) => { + if (imageList[0]) { + formik.setFieldValue("image", fixBase64(imageList[0]?.data_url)); + } + setProfileImages(imageList); + }; + + return ( + + + } + value={selectedDate1} + onChange={(e) => { + setSelectedDate1(moment(e).format("YYYY-MM-DD HH:MM:SS")); + }} + /> + + + {!isEdit && ( + + option.name} + onChange={(event, newValue) => { + formik.setFieldValue("kill_house_key", newValue.key); + }} + onBlur={formik.handleBlur} + renderInput={(params) => ( + + )} + /> + + )} + + + + نوع تراکنش + + + {formik.touched.transaction_type && + Boolean(formik.errors.transaction_type) + ? formik.errors.transaction_type + : null} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + {item?.image && !profileImages.length && ( + سند + )} + + + + + + + ); +}; diff --git a/src/features/province/components/province-wage-payment-transactions-operations/ProvinceWagePaymentTransactionsOperations.js b/src/features/province/components/province-wage-payment-transactions-operations/ProvinceWagePaymentTransactionsOperations.js new file mode 100644 index 0000000..98a35db --- /dev/null +++ b/src/features/province/components/province-wage-payment-transactions-operations/ProvinceWagePaymentTransactionsOperations.js @@ -0,0 +1,157 @@ +import { Button, IconButton, Popover, Tooltip } from "@mui/material"; +import { useContext, useState } from "react"; +import TuneIcon from "@mui/icons-material/Tune"; +import { Grid } from "../../../../components/grid/Grid"; +import EditIcon from "@mui/icons-material/Edit"; +import DeleteIcon from "@mui/icons-material/Delete"; +import { + CLOSE_MODAL, + DRAWER, + OPEN_MODAL, +} from "../../../../lib/redux/slices/appSlice"; +import { ProvinceWagePaymentCreateTransaction } from "../province-wage-payment-create-transaction/ProvinceWagePaymentCreateTransaction"; +import { useDispatch } from "react-redux"; +import { AppContext } from "../../../../contexts/AppContext"; +import { provinceWagePaymentDeleteTransactionService } from "../../services/province-wage-payment-create-transaction-service"; + +export const ProvinceWagePaymentTransactionsOperations = ({ + item, + fetchApiData, +}) => { + const dispatch = useDispatch(); + const [anchorEl, setAnchorEl] = useState(null); + const handleClick = (event) => { + setAnchorEl(event.currentTarget); + }; + + const handleClose = () => { + setAnchorEl(null); + }; + + const [openNotif] = useContext(AppContext); + + const open = Boolean(anchorEl); + const id = open ? "popover" : undefined; + + // const dispatch = useDispatch(); + + return ( +
    + + + + +
    + + + { + handleClose(); + dispatch( + DRAWER({ + title: "ویرایش تراکنش", + right: !(window.innerWidth <= 600), + bottom: window.innerWidth <= 600, + content: ( + + ), + }) + ); + }} + > + + + + + { + handleClose(); + dispatch( + OPEN_MODAL({ + title: "آیا مطمئن هستید؟", + content: ( + + + + + ), + }) + ); + }} + > + + + + +
    +
    +
    + ); +}; diff --git a/src/features/province/components/province-wage-payment-transactions-upload-doc/ProvinceWagePaymentTransactionsUploadDoc.js b/src/features/province/components/province-wage-payment-transactions-upload-doc/ProvinceWagePaymentTransactionsUploadDoc.js new file mode 100644 index 0000000..779cb62 --- /dev/null +++ b/src/features/province/components/province-wage-payment-transactions-upload-doc/ProvinceWagePaymentTransactionsUploadDoc.js @@ -0,0 +1,74 @@ +import { useContext, useEffect, useState } from "react"; +import { useDispatch } from "react-redux"; +import { AppContext } from "../../../../contexts/AppContext"; +import { provinceKillhousesPaidFeesChangePaymentTypeService } from "../../services/province-killhouses-paid-fee-change-payment-type-service"; +import { SPACING } from "../../../../data/spacing"; +import { resizeImage } from "../../../../utils/resizeImage"; +import { fixBase64 } from "../../../../utils/toBase64"; +import { ImageUpload } from "../../../../components/image-upload/ImageUpload"; +import { Grid } from "../../../../components/grid/Grid"; + +export const ProvinceWagePaymentTransactionsUploadDoc = ({ + item, + updateTable, +}) => { + const dispatch = useDispatch(); + const [openNotif] = useContext(AppContext); + const [profileImages, setProfileImages] = useState([]); + const [profileImg, setProfileImg] = useState(); + + const factorPaymentHandler = (imageList, addUpdateIndex) => { + if (imageList[0]) { + const file = imageList[0]?.file; + resizeImage(file, (resizedDataUrl) => { + const optimizedBase64 = fixBase64(resizedDataUrl); + setProfileImg(optimizedBase64); + }); + } + setProfileImages(imageList); + }; + + useEffect(() => { + if (profileImg) { + dispatch( + provinceKillhousesPaidFeesChangePaymentTypeService({ + image: profileImg, + transaction_key: item?.key, + }) + ).then((r) => { + setProfileImg(null); + setProfileImages([]); + if (r.payload.error) { + openNotif({ + vertical: "top", + horizontal: "center", + msg: r.payload.error, + severity: "error", + }); + } else { + openNotif({ + vertical: "top", + horizontal: "center", + msg: "عملیات با موفقیت انجام شد.", + severity: "success", + }); + updateTable(1); + } + }); + } + }, [profileImg, profileImages]); + + return ( + + + + + + ); +}; diff --git a/src/features/province/components/province-wage-payment-transactions/ProvinceWagePaymentTransactions.js b/src/features/province/components/province-wage-payment-transactions/ProvinceWagePaymentTransactions.js new file mode 100644 index 0000000..cf85828 --- /dev/null +++ b/src/features/province/components/province-wage-payment-transactions/ProvinceWagePaymentTransactions.js @@ -0,0 +1,418 @@ +import { + Button, + Checkbox, + FormControlLabel, + IconButton, + TextField, + Tooltip, +} from "@mui/material"; +import axios from "axios"; +import { useContext, useEffect, useState } from "react"; +// import { RiFileExcel2Fill } from "react-icons/ri"; +// import { useSelector } from "react-redux"; +import { Grid } from "../../../../components/grid/Grid"; +import { SPACING } from "../../../../data/spacing"; +import moment from "moment"; +import { DatePicker } from "@mui/x-date-pickers"; +import { AppContext } from "../../../../contexts/AppContext"; +import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl"; +import { formatJustDate } from "../../../../utils/formatTime"; +import { RiFileExcel2Fill } from "react-icons/ri"; +import { useDispatch, useSelector } from "react-redux"; +import { ProvinceKillHousePaidFeeEditDescription } from "../province-killhouse-paid-fee-edit-description/ProvinceKillHousePaidFeeEditDescription"; +import EditIcon from "@mui/icons-material/Edit"; +import { + DRAWER, + LOADING_END, + LOADING_START, + OPEN_MODAL, +} from "../../../../lib/redux/slices/appSlice"; +import ProvinceKillhousePaidFeeChangePaymentType from "../province-killhouse-paid-fee-change-payment-type/ProvinceKillhousePaidFeeChangePaymentType"; +import ShowImage from "../../../../components/show-image/ShowImage"; +import { ProvinceWagePaymentTransactionsUploadDoc } from "../province-wage-payment-transactions-upload-doc/ProvinceWagePaymentTransactionsUploadDoc"; +import { ProvinceWagePaymentCreateTransaction } from "../province-wage-payment-create-transaction/ProvinceWagePaymentCreateTransaction"; +import { ProvinceWagePaymentTransactionsOperations } from "../province-wage-payment-transactions-operations/ProvinceWagePaymentTransactionsOperations"; +import ResponsiveTable from "../../../../components/responsive-table/ResponsiveTable"; +import { RiSearchLine } from "react-icons/ri"; + +export const ProvinceWagePaymentTransactions = ({ province }) => { + // const authToken = useSelector((state) => state.userSlice.authToken); + const [data, setData] = useState([]); + const [totalRows, setTotalRows] = useState(0); + const [perPage, setPerPage] = useState(10); + const [page, setPage] = useState(1); + const [withDate, setWithDate] = useState(false); + const dispatch = useDispatch(); + const [textValue, setTextValue] = useState(""); + const userKey = useSelector((state) => state.userSlice.userProfile.key); + const [tableData, setTableData] = useState([]); + + const handleTextChange = (event) => { + setTextValue(event.target.value); + }; + + const [, , selectedDate1, setSelectedDate1, selectedDate2, setSelectedDate2] = + useContext(AppContext); + + useEffect(() => { + const currentDate = moment(new Date()).format("YYYY-MM-DD"); + setSelectedDate1(currentDate); + setSelectedDate2(currentDate); + }, []); + + const fetchApiData = async (page) => { + const response = await axios.get( + `${ + province ? province + "parent-company-" : "" + }total-internal-transactions/?search=filter&value=${textValue}&page=${page}&role=${getRoleFromUrl()}&page_size=${perPage}${ + withDate ? `&date1=${selectedDate1}&date2=${selectedDate2}` : `` + }` + ); + setData(response.data.results); + setTotalRows(response.data.count); + }; + + const handlePageChange = (page) => { + fetchApiData(page); + setPage(page); + }; + + const handlePerRowsChange = (perRows) => { + setPerPage(perRows); + setPage(1); + }; + + useEffect(() => { + fetchApiData(1); + }, [dispatch, selectedDate1, selectedDate2, perPage, withDate]); + + const handleSubmit = async (event) => { + event.preventDefault(); + dispatch(LOADING_START()); + try { + const response = await axios.get( + `${ + province ? province + "parent-company-" : "" + }total-internal-transactions/?search=filter&value=${textValue}&role=${getRoleFromUrl()}&page=${page}&page_size=${perPage}${ + withDate ? `&date1=${selectedDate1}&date2=${selectedDate2}` : `` + }` + ); + setData(response.data.results); + setTotalRows(response.data.count); + dispatch(LOADING_END()); + } catch (error) { + console.error("Error fetching data:", error); + } + }; + + useEffect(() => { + fetchApiData(1); + }, [selectedDate1, selectedDate2, withDate, province]); + + const getOthersShare = (item) => { + if ( + getRoleFromUrl() === "AdminX" || + getRoleFromUrl() === "SuperAdmin" || + getRoleFromUrl() === "ProvinceOperator" + ) { + return [ + item?.guildsShare?.toLocaleString(), + item?.companyShare?.toLocaleString(), + item?.otherShare?.toLocaleString(), + ]; + } else { + return []; + } + }; + + const getRoleColumns = () => { + if ( + getRoleFromUrl() === "AdminX" || + getRoleFromUrl() === "SuperAdmin" || + getRoleFromUrl() === "ProvinceOperator" + ) { + return ["سهم صنف (﷼)", "سهم شرکت (﷼)", "سهم دامپزشک (﷼)"]; + } else { + return []; + } + }; + + useEffect(() => { + const d = data?.map((item, i) => { + return [ + page === 1 ? i + 1 : i + perPage * (page - 1) + 1, + `${ + item?.payerType === "kill_house" + ? `کشتارگاه / کشتارکن ${item?.killHouse?.name}` + : item?.payerType === "chain_company" + ? `شرکت زنجیره ${item?.chainCompany?.name}` + : `خریدار (${ + item?.outProvincePoultryRequestBuyer?.unitName + ? item?.outProvincePoultryRequestBuyer?.unitName + : "-" + })` + }`, + formatJustDate(item?.date), + getRoleFromUrl() === "SuperAdmin" ? ( + + {item?.transactionType === "wage-gateway-auto" + ? "آنلاین" + : item?.transactionType === "correspondence" + ? "مکاتبات" + : "دستی"} + { + dispatch( + OPEN_MODAL({ + title: "ویرایش نوع پرداخت", + content: ( + + ), + }) + ); + }} + > + + + + ) : item?.transactionType === "wage-gateway-auto" ? ( + "آنلاین" + ) : item?.transactionType === "correspondence" ? ( + "مکاتبات" + ) : ( + "دستی" + ), + item?.refId, + item?.orderId, + `${item?.payerInfo?.fullname} (${item?.payerInfo?.mobile})`, + item?.cardHolderPan, + item?.transactionAmount.toLocaleString(), + item?.unionShare?.toLocaleString(), + ...getOthersShare(item), + item?.image && + (getRoleFromUrl() === "AdminX" || getRoleFromUrl() === "SuperAdmin") ? ( + + + + + ) : getRoleFromUrl() === "ParentCompany" ? ( + + ) : ( + + ), + getRoleFromUrl() === "SuperAdmin" || getRoleFromUrl() === "AdminX" ? ( + + {item?.description ? item?.description : "-"}{" "} + { + dispatch( + OPEN_MODAL({ + title: "ویرایش توضیحات", + content: ( + + ), + }) + ); + }} + > + + + + ) : item?.description ? ( + item?.description + ) : ( + "-" + ), + , + ]; + }); + + setTableData(d); + }, [data]); + + return ( + + + + {getRoleFromUrl() === "AdminX" && ( + + )} + + + setWithDate(!withDate)} + color="primary" + /> + } + /> + + + ( + + )} + value={selectedDate1} + onChange={(e) => { + setSelectedDate1(moment(e).format("YYYY-MM-DD")); + }} + /> + + + ( + + )} + value={selectedDate2} + onChange={(e) => { + setSelectedDate2(moment(e).format("YYYY-MM-DD")); + }} + /> + + +
    + + + + + + + + + + +
    +
    + + +
    + ); +}; diff --git a/src/features/province/components/province_policy_upload_image_slaughter_out_province/ProvincePolicyUploadImageSlaughterOutProvince.js b/src/features/province/components/province_policy_upload_image_slaughter_out_province/ProvincePolicyUploadImageSlaughterOutProvince.js new file mode 100644 index 0000000..bffc936 --- /dev/null +++ b/src/features/province/components/province_policy_upload_image_slaughter_out_province/ProvincePolicyUploadImageSlaughterOutProvince.js @@ -0,0 +1,117 @@ +import { useContext, useEffect, useState } from "react"; +import { useDispatch } from "react-redux"; +import { AppContext } from "../../../../contexts/AppContext"; +import { + provincePolicyGEditUploadImageService, + provincePolicyGetUploadImageService, +} from "../../services/province-policy-upload-image"; +import { Grid } from "../../../../components/grid/Grid"; +import { FormControlLabel, Radio, Typography } from "@mui/material"; + +export const ProvincePolicyUploadImageSlaughterOutProvince = () => { + const [submitStatus, SetSubmitStatus] = useState(false); + const dispatch = useDispatch(); + const [openNotif] = useContext(AppContext); + + const fetchData = () => { + dispatch(provincePolicyGetUploadImageService()).then((r) => { + SetSubmitStatus(r.payload.data.killHouseFreeSale); + }); + }; + + useEffect(() => { + fetchData(); + }, []); + + return ( + + + سند توزیع خارج استان کشتارگاه + + + { + SetSubmitStatus(true); + dispatch( + provincePolicyGEditUploadImageService({ + kill_house_free_sale: true, + }) + ).then((r) => { + if (r.payload.error) { + openNotif({ + vertical: "top", + horizontal: "center", + msg: r.payload.error, + severity: "error", + }); + } else { + fetchData(); + openNotif({ + vertical: "top", + horizontal: "center", + msg: "عملیات با موفقیت انجام شد.", + severity: "success", + }); + } + }); + }} + /> + } + label="اجباری" + /> + { + SetSubmitStatus(false); + dispatch( + provincePolicyGEditUploadImageService({ + kill_house_free_sale: false, + }) + ).then((r) => { + if (r.payload.error) { + openNotif({ + vertical: "top", + horizontal: "center", + msg: r.payload.error, + severity: "error", + }); + } else { + fetchData(); + openNotif({ + vertical: "top", + horizontal: "center", + msg: "عملیات با موفقیت انجام شد.", + severity: "success", + }); + } + }); + }} + /> + } + label="اختیاری" + /> + + + ); +}; diff --git a/src/features/province/components/success-transaction-recipt/SuccessTransactionRecipt.js b/src/features/province/components/success-transaction-recipt/SuccessTransactionRecipt.js new file mode 100644 index 0000000..9c8106c --- /dev/null +++ b/src/features/province/components/success-transaction-recipt/SuccessTransactionRecipt.js @@ -0,0 +1,158 @@ +import React, { forwardRef } from "react"; +import { PropTypes } from "prop-types"; +import logo from "../../../../assets/images/logo.png"; +import { formatJustDate, formatJustTime } from "../../../../utils/formatTime"; + +const styles = { + page: { + width: "214mm", + height: "302mm", + display: "flex", + margin: "0 auto", + justifyContent: "center", // Center horizontally + alignItems: "center", // Center vertically + position: "relative", + direction: "rtl", + fontFamily: "titr", + fontWeight: "bold", + }, + pageData: { + display: "flex", + flexDirection: "column", + padding: "20px", + border: "2px solid #666", // Border color + borderRadius: "10px", + width: "50%", + position: "relative", + backgroundColor: "#fff", // Background color + boxShadow: "0px 0px 20px rgba(0, 0, 0, 0.1)", // Box shadow + }, + title: { + textAlign: "center", + marginBottom: "10px", + fontSize: "24px", + fontWeight: "bold", + color: "#333", // Text color + }, + logo: { + width: "100px", + height: "auto", + margin: "0 auto", // Center horizontally + display: "block", + }, + hr: { + border: "none", + borderTop: "1px solid #ccc", // Line color + margin: "5px 0", // Adjust margin as needed + }, + row: { + display: "flex", + flexDirection: "row", + marginBottom: "10px", + justifyContent: "space-between", + }, + label: { + flex: "0 0 40%", + textAlign: "right", + marginRight: "10px", + fontWeight: "bold", + color: "#555", // Text color + }, + value: { + textAlign: "right", + color: "#333", // Text color + fontFamily: "titr", + }, +}; + +const SuccessTransactionRecipt = forwardRef(({ item, isPayment }, ref) => { + return ( +
    +
    + {item && ( +
    + Logo +

    رسید پرداخت

    +
    +
    +
    تاریخ و زمان:
    +
    + {`${formatJustDate(item.date)} ساعت ${formatJustTime( + item.date + )}`} +
    +
    +
    +
    +
    پرداخت کننده:
    +
    + {isPayment ? item?.payerInfo?.fullname : item.payer} +
    +
    + {!isPayment && ( + <> +
    +
    +
    تعداد سفارشات:
    +
    + {item.information?.totalRequestNumber} +
    +
    +
    +
    +
    تعداد کل (قطعه):
    +
    + {item.information?.totalQuantity} +
    +
    +
    +
    +
    وزن کل (کیلوگرم):
    +
    + {item.information?.totalWeight} +
    +
    + + )} + +
    +
    +
    شماره درخواست:
    +
    {item.orderId}
    +
    +
    +
    +
    شماره پیگیری:
    +
    {item.refId}
    +
    +
    +
    +
    کدسفارش:
    +
    {item.orderId}
    +
    +
    +
    +
    شماره کارت:
    +
    {item.cardHolderPan}
    +
    +
    +
    +
    مبلغ:
    +
    + {item.amount?.toLocaleString()} ریال +
    +
    +
    + )} +
    +
    + ); +}); + +SuccessTransactionRecipt.displayName = "SuccessTransactionRecipt"; + +export default SuccessTransactionRecipt; + +SuccessTransactionRecipt.propTypes = { + item: PropTypes.object, +}; diff --git a/src/features/province/components/success-transactions/SuccessTransactions.js b/src/features/province/components/success-transactions/SuccessTransactions.js new file mode 100644 index 0000000..906b79c --- /dev/null +++ b/src/features/province/components/success-transactions/SuccessTransactions.js @@ -0,0 +1,388 @@ +import { + Button, + IconButton, + Pagination, + TextField, + Tooltip, + Typography, +} from "@mui/material"; +import axios from "axios"; +import { useContext, useEffect, useRef, useState } from "react"; +import { RiFileExcel2Fill, RiSearchLine } from "react-icons/ri"; +import { useDispatch, useSelector } from "react-redux"; +import { Grid } from "../../../../components/grid/Grid"; +import { PageTable } from "../../../../components/page-table/PageTable"; +import { SPACING } from "../../../../data/spacing"; +import { DatePicker } from "@mui/x-date-pickers"; +import moment from "moment/moment"; +import { AppContext } from "../../../../contexts/AppContext"; +import { format } from "date-fns-jalali"; +import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl"; +import { + LOADING_END, + LOADING_START, +} from "../../../../lib/redux/slices/appSlice"; +import BoxList from "../../../../components/box-list/BoxList"; +import PrintIcon from "@mui/icons-material/Print"; +import { useReactToPrint } from "react-to-print"; +import SuccessTransactionRecipt from "../success-transaction-recipt/SuccessTransactionRecipt"; + +export const SuccessTransactions = () => { + const authToken = useSelector((state) => state.userSlice.authToken); + const [, , selectedDate1, setSelectedDate1, selectedDate2, setSelectedDate2] = + useContext(AppContext); + + const userInfo = useSelector((state) => state.userSlice); + + useEffect(() => { + const currentDate = moment(new Date()).format("YYYY-MM-DD"); + setSelectedDate1(currentDate); + setSelectedDate2(currentDate); + }, []); + const [dataTableM, setDataTableM] = useState([]); + const dispatch = useDispatch(); + const [data, setData] = useState([]); + const [loading, setLoading] = useState(false); + const [totalRows, setTotalRows] = useState(0); + const [perPage, setPerPage] = useState(10); + + const [textValue, setTextValue] = useState(""); + + const handleTextChange = (event) => { + setTextValue(event.target.value); + }; + + const fetchApiData = async (page, textValue) => { + setLoading(true); + const response = await axios.get( + `transactions/?search=filter&value=${textValue}&page=${page}&page_size=${perPage}&date1=${selectedDate1}&date2=${selectedDate2}&state=completed&role=${getRoleFromUrl()}` + ); + setData(response.data.results); + setTotalRows(response.data.count); + setLoading(false); + dispatch(LOADING_END()); + }; + + const [page, setPage] = useState(0); + const handleChangePageM = (event, newPage) => { + dispatch(LOADING_START()); + setPage(newPage); + fetchApiData(newPage + 1, textValue); + }; + + const handlePageChange = (page) => { + fetchApiData(page, textValue); + }; + + const handlePerRowsChange = async (newPerPage, page) => { + setLoading(true); + const response = await axios.get( + `transactions/?search=filter&value=${textValue}&page=${page}&page_size=${newPerPage}&date1=${selectedDate1}&date2=${selectedDate2}&state=completed&role=${getRoleFromUrl()}` + ); + + setData(response.data.results); + setTotalRows(response.data.count); + setPerPage(newPerPage); + + setLoading(false); + }; + + useEffect(() => { + fetchApiData(1); + }, [selectedDate1, selectedDate2, perPage]); + + const handleSubmit = async (event) => { + event.preventDefault(); + setLoading(true); + try { + const response = await axios.get( + `transactions/?search=filter&value=${textValue}&date1=${selectedDate1}&date2=${selectedDate2}&state=completed&role=${getRoleFromUrl()}` + ); + setData(response.data.results); + setTotalRows(response.data.count); + } catch (error) { + console.error("Error fetching data:", error); + } finally { + setLoading(false); + } + }; + + const [reciptData, setReciptData] = useState(); + + const componentRef = useRef(); + const printPDF = useReactToPrint({ + content: () => componentRef.current, + documentTitle: `گزارش پرونده `, + }); + + const setPdfOptions = (item) => { + setReciptData(item); + if (reciptData) { + printPDF(); + } + }; + + const columns = [ + { + name: "تاریخ و زمان", + selector: (item) => { + return format(new Date(item.createDate), "yyyy/MM/dd hh:mm:ss"); + }, + sortable: true, + wrap: true, + allowOverflow: true, + center: true, + // width: "90px", + }, + { + name: "پرداخت کننده", + selector: (item) => { + return item.payer; + }, + sortable: true, + wrap: true, + allowOverflow: true, + center: true, + // width: "90px", + }, + { + name: "تعداد سفارشات", + selector: (item) => { + return item.information?.totalRequestNumber; + }, + sortable: true, + wrap: true, + allowOverflow: true, + center: true, + // width: "90px", + }, + { + name: "تعداد کل (قطعه)", + selector: (item) => { + return item.information?.totalQuantity; + }, + sortable: true, + wrap: true, + allowOverflow: true, + center: true, + // width: "90px", + }, + { + name: "وزن کل (کیلوگرم)", + selector: (item) => { + return item.information?.totalWeight; + }, + sortable: true, + wrap: true, + allowOverflow: true, + center: true, + // width: "90px", + }, + { + name: "شماره درخواست", + selector: (item) => { + return item.orderId; + }, + sortable: true, + wrap: true, + allowOverflow: true, + center: true, + // width: "90px", + }, + { + name: "شماره پیگیری", + selector: (item) => { + return item.saleReferenceId; + }, + sortable: true, + wrap: true, + allowOverflow: true, + center: true, + // width: "90px", + }, + { + name: "کدسفارش", + selector: (item) => { + return item.orderId; + }, + sortable: true, + wrap: true, + allowOverflow: true, + center: true, + // width: "90px", + }, + { + name: "شماره کارت", + selector: (item) => { + return item.cardHolderPan; + }, + sortable: true, + wrap: true, + allowOverflow: true, + center: true, + // width: "90px", + }, + { + name: "قیمت", + selector: (item) => { + return item?.amount?.toLocaleString() + " ﷼"; + }, + sortable: true, + wrap: true, + allowOverflow: true, + center: true, + // width: "90px", + }, + { + name: "چاپ رسید", + selector: (item) => { + return ( + <> + { + setPdfOptions(item); + }} + > + + + + ); + }, + sortable: true, + wrap: true, + allowOverflow: true, + center: true, + // width: "90px", + }, + ]; + + const tableTitle = ( + + + تراکنش های موفق + + + ( + + )} + value={selectedDate1} + onChange={(e) => { + setSelectedDate1(moment(e).format("YYYY-MM-DD")); + }} + /> + + + ( + + )} + value={selectedDate2} + onChange={(e) => { + setSelectedDate2(moment(e).format("YYYY-MM-DD")); + }} + /> + + +
    + + + + + + + + +
    +
    + ); + + const columnNames = columns.map((column) => column.name); + const isMobile = window.innerWidth <= 600; + + useEffect(() => { + const d = data?.map((item, i) => { + return [ + format(new Date(item.createDate), "yyyy/MM/dd hh:mm:ss"), + item.information?.totalRequestNumber, + item.information?.totalQuantity, + item.information?.totalQuantity, + item.payerInfo, + item.refId, + item.trackingCode, + item.cardHolderPan, + item.orderId, + ]; + }); + + setDataTableM(d); + }, [data]); + + return ( + +
    + +
    + {isMobile ? ( + <> + {tableTitle} + + { + handleChangePageM(event, newPage - 1); + }} + /> + + ) : ( + + )} +
    + ); +}; diff --git a/src/features/province/components/total-cargo-information/TotalCargoInformation.js b/src/features/province/components/total-cargo-information/TotalCargoInformation.js new file mode 100644 index 0000000..cd9ccd9 --- /dev/null +++ b/src/features/province/components/total-cargo-information/TotalCargoInformation.js @@ -0,0 +1,560 @@ +import React, { useContext, useEffect, useState } from "react"; +import axios from "axios"; +import { useDispatch } from "react-redux"; +import { + LOADING_START, + LOADING_END, +} from "../../../../lib/redux/slices/appSlice"; +import { showSnackbar } from "../../../../utils/showSnackbar"; +import { AppContext } from "../../../../contexts/AppContext"; +import ResponsiveTable from "../../../../components/responsive-table/ResponsiveTable"; +import { + Autocomplete, + Checkbox, + CircularProgress, + Grid, + TextField, + IconButton, +} from "@mui/material"; +import ToggleOffOutlinedIcon from "@mui/icons-material/ToggleOffOutlined"; +import ToggleOnIcon from "@mui/icons-material/ToggleOn"; +import SearchIcon from "@mui/icons-material/Search"; +import { DatePicker } from "@mui/x-date-pickers"; +import moment from "moment"; +import { formatJustDate } from "../../../../utils/formatTime"; +import { CheckCleanceCode } from "../../../../components/check-clearance-code/ChechClearanceCode"; + +export const TotalCargoInformation = () => { + const [cargoInformation, setCargoInformation] = useState(null); + const [dashboardInformation, setDashboardInformation] = useState(null); + const [tableData, setTableData] = useState([]); + const [totalRows, setTotalRows] = useState(0); + const [page, setPage] = useState(1); + const [perPage, setPerPage] = useState(20); + const [isLoading, setIsLoading] = useState(false); + const [error, setError] = useState(null); + const [withDate, setWithDate] = useState(true); + const [provinceOptions, setProvinceOptions] = useState([]); + const [selectedProvince, setSelectedProvince] = useState(""); + const [isProvinceLoading, setIsProvinceLoading] = useState(false); + const [productOptions, setProductOptions] = useState([]); + const [selectedProduct, setSelectedProduct] = useState(""); + const [isProductLoading, setIsProductLoading] = useState(false); + const [searchValue, setSearchValue] = useState(""); + const [searchInput, setSearchInput] = useState(""); + + const dispatch = useDispatch(); + const [, , selectedDate1, setSelectedDate1, selectedDate2, setSelectedDate2] = + useContext(AppContext); + + const columns = [ + "ردیف", + "کد رهگیری", + "محصول", + "اقلام", + "مقدار", + "واحد", + "تاریخ", + "مقصد", + "شناسه مقصد", + "استان مقصد", + "شهرستان مقصد", + "مبدا", + "شناسه مبدا", + "استان مبدا", + "شهرستان مبدا", + "نوع حمل", + "مقصد قبلی", + "تغییر مقصد", + "کد رهگیری خودرو", + "تاریخ تخلیه", + "تخلیه", + ]; + + const dashboardColumns = [ + "محصول", + "تعداد بار", + "حجم بار (کیلوگرم)", + "تعداد بار داخل استان", + "حجم بار داخل استان (کیلوگرم)", + "درصد داخل استان", + "تعداد بار خارج استان", + "حجم بار خارج استان (کیلوگرم)", + "درصد خارج استان", + "آخرین بروزرسانی", + ]; + + const formatDateTimeFromIso = (value) => { + if (!value) return "-"; + const dateObj = new Date(value); + if (Number.isNaN(dateObj.getTime())) return "-"; + const date = dateObj.toLocaleDateString("fa-IR"); + const time = dateObj.toLocaleTimeString("fa-IR", { + hour: "2-digit", + minute: "2-digit", + hour12: false, + }); + return `${date} ${time}`; + }; + + const formatNumber = (value) => { + if (value === null || value === undefined) { + return "-"; + } + if (typeof value === "number") { + return value.toLocaleString("fa-IR"); + } + return value; + }; + + const formatPercent = (value) => { + if (value === null || value === undefined) { + return "-"; + } + const numericValue = Number(value); + if (Number.isNaN(numericValue)) { + return "-"; + } + return `${numericValue.toFixed(1)}%`; + }; + + const safeValue = (value) => { + if (value === null || value === undefined || value === "") { + return "-"; + } + return value; + }; + + useEffect(() => { + setPage(1); + }, [ + selectedDate1, + selectedDate2, + withDate, + selectedProvince, + selectedProduct, + searchValue, + ]); + + useEffect(() => { + let isMounted = true; + + const fetchProvinces = async () => { + try { + setIsProvinceLoading(true); + const { data } = await axios.get("iran_province/"); + if (!isMounted) { + return; + } + const names = + data?.map?.((item) => item?.name).filter((name) => !!name) ?? []; + setProvinceOptions(names); + } catch (err) { + console.error("Failed to fetch provinces:", err); + } finally { + if (isMounted) { + setIsProvinceLoading(false); + } + } + }; + + fetchProvinces(); + + return () => { + isMounted = false; + }; + }, []); + + useEffect(() => { + let isMounted = true; + + const fetchProducts = async () => { + try { + setIsProductLoading(true); + const { data } = await axios.get( + "https://rsibackend.rasadyar.com/app/all-products-transport-products" + ); + if (!isMounted) { + return; + } + const products = Array.isArray(data?.products) ? data.products : []; + setProductOptions(products); + } catch (err) { + console.error("Failed to fetch product types:", err); + } finally { + if (isMounted) { + setIsProductLoading(false); + } + } + }; + + fetchProducts(); + + return () => { + isMounted = false; + }; + }, []); + + useEffect(() => { + let isMounted = true; + + const fetchCargoInformation = async () => { + try { + setError(null); + setIsLoading(true); + dispatch(LOADING_START()); + const cargoParams = new URLSearchParams(); + cargoParams.append("product_type", selectedProduct || ""); + if (withDate && selectedDate1) { + cargoParams.append("date1", selectedDate1); + } + if (withDate && selectedDate2) { + cargoParams.append("date2", selectedDate2); + } + if (selectedProvince) { + cargoParams.append("destination_province", selectedProvince); + } + if (searchValue) { + cargoParams.append("search", searchValue); + } + cargoParams.append("page", page.toString()); + cargoParams.append("page_size", perPage.toString()); + + const dashboardParams = new URLSearchParams(); + dashboardParams.append("product_type", selectedProduct || ""); + if (withDate && selectedDate1) { + dashboardParams.append("date1", selectedDate1); + } + if (withDate && selectedDate2) { + dashboardParams.append("date2", selectedDate2); + } + if (selectedProvince) { + dashboardParams.append("destination_province", selectedProvince); + } + if (searchValue) { + dashboardParams.append("search", searchValue); + } + + const [cargoResponse, dashboardResponse] = await Promise.all([ + axios.get( + `https://rsibackend.rasadyar.com/app/all-products-transport/?${cargoParams.toString()}` + ), + axios.get( + `https://rsibackend.rasadyar.com/app/all-products-transport-dashboard/?${dashboardParams.toString()}` + ), + ]); + if (!isMounted) { + return; + } + const cargoData = cargoResponse.data ?? { results: [] }; + const results = cargoData?.results ?? []; + const mappedTableData = results.map((item, index) => [ + safeValue(formatNumber(index + 1 + (page - 1) * perPage)), + , + safeValue(item?.product), + safeValue(item?.items), + safeValue(formatNumber(item?.quantity)), + safeValue(item?.unit), + safeValue(formatJustDate(item?.date)), + safeValue(item?.destination), + safeValue(item?.jihadiDestination), + safeValue(item?.destinationProvince), + safeValue(item?.destinationCity), + safeValue(item?.origin), + safeValue(item?.jihadiOrigin), + safeValue(item?.originProvince), + safeValue(item?.originCity), + safeValue( + item?.originProvince === item?.destinationProvince + ? "داخل استان" + : "خارج استان" + ), + safeValue(item?.destinationPrev), + safeValue(item?.destinationChanged), + safeValue(item?.carTrackingCode), + safeValue(formatJustDate(item?.unloadingDate)), + safeValue(item?.unloading), + ]); + + setCargoInformation(cargoData); + setTableData(mappedTableData); + setTotalRows(cargoData?.count ?? 0); + setDashboardInformation(dashboardResponse.data); + } catch (err) { + console.error("Failed to fetch total cargo information:", err); + if (!isMounted) { + return; + } + setError(err); + showSnackbar( + "در دریافت اطلاعات بار کل کشور خطایی رخ داد، لطفا مجددا تلاش کنید.", + "error" + ); + } finally { + if (isMounted) { + setIsLoading(false); + } + dispatch(LOADING_END()); + } + }; + + fetchCargoInformation(); + return () => { + isMounted = false; + }; + }, [ + dispatch, + page, + perPage, + selectedDate1, + selectedDate2, + selectedProvince, + selectedProduct, + withDate, + searchValue, + ]); + + const handlePageChange = (newPage) => { + setPage(newPage); + }; + + const handlePerRowsChange = (newPerPage) => { + setPerPage(newPerPage); + setPage(1); + }; + + const handleSubmit = async (event) => { + event.preventDefault(); + const normalizedSearch = searchInput.trim(); + setSearchValue(normalizedSearch); + setSearchInput(normalizedSearch); + setPage(1); + }; + + if (error) { + return
    خطا در دریافت اطلاعات بار کل کشور
    ; + } + + if (isLoading && (!cargoInformation || !dashboardInformation)) { + return
    در حال بارگذاری اطلاعات ...
    ; + } + + return ( + + + + + } + checkedIcon={} + checked={withDate} + onChange={() => setWithDate(!withDate)} + color="primary" + size="large" + /> + + ( + + )} + value={selectedDate1} + onChange={(e) => { + if (!e) return; + setSelectedDate1(moment(e).format("YYYY-MM-DD")); + }} + /> + + + ( + + )} + value={selectedDate2} + onChange={(e) => { + if (!e) return; + setSelectedDate2(moment(e).format("YYYY-MM-DD")); + }} + /> + + + + { + setSelectedProvince(value || ""); + }} + noOptionsText="استانی یافت نشد" + renderInput={(params) => ( + + {isProvinceLoading ? ( + + ) : null} + {params.InputProps.endAdornment} + + ), + }} + /> + )} + clearOnEscape + /> + + { + setSelectedProduct(value || ""); + }} + noOptionsText="محصولی یافت نشد" + renderInput={(params) => ( + + {isProductLoading ? ( + + ) : null} + {params.InputProps.endAdornment} + + ), + }} + /> + )} + clearOnEscape + /> + + + setSearchInput(event.target.value)} + label="جستجو" + size="small" + variant="outlined" + sx={{ flexGrow: 1 }} + /> + + + + + + + + {dashboardInformation && ( + + + + )} + + + + ); +}; diff --git a/src/features/province/components/trade-panel-details/TradepanelDetails.js b/src/features/province/components/trade-panel-details/TradepanelDetails.js new file mode 100644 index 0000000..dae95c9 --- /dev/null +++ b/src/features/province/components/trade-panel-details/TradepanelDetails.js @@ -0,0 +1,86 @@ +import { IconButton, Tooltip, Box, Typography } from "@mui/material"; +import { Grid } from "../../../../components/grid/Grid"; +import VisibilityIcon from "@mui/icons-material/Visibility"; +import { useDispatch, useSelector } from "react-redux"; +import { OPEN_MODAL } from "../../../../lib/redux/slices/appSlice"; +import { tradePanelGetDetails } from "../../services/trade-panel-get-details"; +import { checkPathStartsWith } from "../../../../utils/checkPathStartsWith"; + +export const TradepanelDetails = ({ item, details_key }) => { + const dispatch = useDispatch(); + const selectedSubUser = useSelector( + (state) => state.userSlice.selectedSubUser + ); + + const handleOpenModal = async () => { + try { + const response = await dispatch( + tradePanelGetDetails({ + hatching_key: details_key, + role_key: checkPathStartsWith("province") + ? selectedSubUser?.key || "" + : "", + }) + ); + + if (response.payload?.data) { + dispatch( + OPEN_MODAL({ + title: "جزئیات کشتار", + content: ( + + + کمترین سن کشتار:{" "} + {response.payload.data.minAge} روز + + + بیشترین سن کشتار:{" "} + {response.payload.data.maxAge} روز + + + سن فعلی: {response.payload.data.nowAge} روز + + + میانگین وزن در کشتارهای گذشته:{" "} + {response.payload.data.avgWeight} کیلوگرم + + + میانگین افت:{" "} + {response.payload.data.avgWeightLosse}% + + + عملکرد در تحویل بار به کشتار:{" "} + {response.payload.data.receiveBarsPercent}% + + + ), + }) + ); + } else { + dispatch( + OPEN_MODAL({ + title: "خطا", + content: دیتایی دریافت نشد!, + }) + ); + } + } catch (error) { + dispatch( + OPEN_MODAL({ + title: "خطا", + content: مشکل در دریافت دیتا از سرور, + }) + ); + } + }; + + return ( + + + + + + + + ); +}; diff --git a/src/features/province/components/trade-panel-filter/TradePanelFilter.js b/src/features/province/components/trade-panel-filter/TradePanelFilter.js new file mode 100644 index 0000000..84ba848 --- /dev/null +++ b/src/features/province/components/trade-panel-filter/TradePanelFilter.js @@ -0,0 +1,256 @@ +import { + Accordion, + AccordionSummary, + AccordionDetails, + Typography, + FormControlLabel, + Switch, + Checkbox, + TextField, + Button, + Box, + InputAdornment, +} from "@mui/material"; +import ExpandMoreIcon from "@mui/icons-material/ExpandMore"; + +export const TradePanelFilters = ({ + filters, + updateFilter, + handleCityChange, + handleBreedChange, + handlePriceFilterSubmit, + handleAgeFilterSubmit, + cities, + chickenBreeds, +}) => { + const { + showRemaining, + selectedCities, + selectedBreeds, + tempMinPrice, + tempMaxPrice, + tempMinAge, + tempMaxAge, + } = filters; + + return ( + + + updateFilter("showRemaining", e.target.checked)} + sx={{ + width: 42, + height: 26, + padding: 0, + "& .MuiSwitch-switchBase": { + padding: 0, + margin: "2px", + transitionDuration: "300ms", + "&.Mui-checked": { + transform: "translateX(16px)", + color: "#fff", + "& + .MuiSwitch-track": { + backgroundColor: "#244CCC", + opacity: 1, + border: 0, + }, + "& .MuiSwitch-thumb": { + color: "#ffffff", + }, + }, + "&.Mui-disabled + .MuiSwitch-track": { + opacity: 0.5, + }, + }, + "& .MuiSwitch-thumb": { + boxShadow: "0 2px 4px rgba(0,0,0,0.2)", + width: 22, + height: 22, + color: "#ffffff", + backgroundColor: "#ffffff", + }, + "& .MuiSwitch-track": { + borderRadius: 26 / 2, + backgroundColor: "#e9e9ea", + opacity: 1, + transition: "background-color 300ms", + }, + }} + /> + } + label={ + + مانده فروش + + } + /> + + + + }> + + نژاد مرغ + + + + + {chickenBreeds.map((breed) => ( + handleBreedChange(breed)} + /> + } + label={{breed}} + /> + ))} + + + + + + }> + فیلتر شهرها + + + + {cities.map((city) => ( + handleCityChange(city.name)} + /> + } + label={city.name} + /> + ))} + + + + + + }> + + محدوده قیمت + + + + { + e.preventDefault(); + handlePriceFilterSubmit(); + }} + > + updateFilter("tempMinPrice", e.target.value)} + InputProps={{ + endAdornment: ( + ریال + ), + }} + /> + updateFilter("tempMaxPrice", e.target.value)} + InputProps={{ + endAdornment: ( + ریال + ), + }} + /> + + + + + + + }> + + محدوده سن + + + + { + e.preventDefault(); + handleAgeFilterSubmit(); + }} + > + updateFilter("tempMinAge", e.target.value)} + InputProps={{ + endAdornment: ( + روز + ), + }} + /> + updateFilter("tempMaxAge", e.target.value)} + InputProps={{ + endAdornment: ( + روز + ), + }} + /> + + + + + + ); +}; diff --git a/src/features/province/components/trade-panel-purchase-modal/TradePanelPurchaseModal.js b/src/features/province/components/trade-panel-purchase-modal/TradePanelPurchaseModal.js new file mode 100644 index 0000000..2efe7dc --- /dev/null +++ b/src/features/province/components/trade-panel-purchase-modal/TradePanelPurchaseModal.js @@ -0,0 +1,195 @@ +import { useContext, useEffect, useState } from "react"; +import { Button, TextField } from "@mui/material"; +import { Grid } from "../../../../components/grid/Grid"; +import { useDispatch, useSelector } from "react-redux"; +import { AppContext } from "../../../../contexts/AppContext"; +import { useFormik } from "formik"; +import { CLOSE_MODAL } from "../../../../lib/redux/slices/appSlice"; +import * as Yup from "yup"; +import { provinceEditMarketRequestService } from "../../services/trade-panel-edit-market-request"; +import { ProvinceMarketRequestService } from "../../services/trade-panel-market-request"; +import { paymentGetDeadLines } from "../../services/payment-get-deadlines"; +import { useProvinceName } from "../../../../utils/getProvinceName"; +import { checkPathStartsWith } from "../../../../utils/checkPathStartsWith"; + +function TradePanelPurchaseModal({ item, updateTable, isEdit = false }) { + const [paymentDeadlineDays, setPaymentDeadlineDays] = useState(null); + const [fullyRendered, setFullyRendered] = useState(false); + const selectedSubUser = useSelector( + (state) => state.userSlice.selectedSubUser + ); + const dispatch = useDispatch(); + const [openNotif] = useContext(AppContext); + + const validationSchema = Yup.object({ + killCapacity: Yup.number() + .required("این فیلد اجباری است!") + .typeError("لطفا عدد وارد کنید!") + + .max( + isEdit ? Infinity : item?.remainQuantity, + `مقدار وارد شده بیشتر از مانده قابل خرید است` + ), + + paymentDeadlineDays: Yup.number().when([], { + is: () => paymentDeadlineDays !== null, + then: Yup.number() + .required("این فیلد الزامی است") + .min(1, "حداقل مقدار باید 1 باشد") + .max( + paymentDeadlineDays, + `حداکثر مقدار باید ${paymentDeadlineDays} باشد` + ), + otherwise: Yup.number() + .required("این فیلد اجباری است!") + .typeError("لطفا عدد وارد کنید!"), + }), + }); + + useEffect(() => { + dispatch( + paymentGetDeadLines({ + role_key: checkPathStartsWith("province") + ? selectedSubUser?.key || "" + : "", + }) + ).then((r) => { + setFullyRendered(true); + const isEnabled = r?.payload?.data?.paymentDeadline; + + const days = r?.payload?.data?.paymentDeadlineDays; + + if (isEnabled === true && days > 0) { + setPaymentDeadlineDays(days); + } + }); + }, [selectedSubUser?.key]); + + const provinceName = useProvinceName(); + + useEffect(() => { + formik.validateForm(); + }, [paymentDeadlineDays, fullyRendered]); + + const formik = useFormik({ + initialValues: { + killCapacity: item?.killCapacity || "", + paymentDeadlineDays: item?.paymentDeadlineDays || "", + }, + + validationSchema, + onSubmit: (values) => { + const payload = { + recive_time: "12 - 14", + kill_capacity: parseInt(values.killCapacity), + payment_deadline_days: parseInt(values.paymentDeadlineDays), + ...(isEdit ? { key: item.key } : { poultry_request_key: item.key }), + }; + + const service = isEdit + ? provinceEditMarketRequestService + : ProvinceMarketRequestService; + + const remainTime = + provinceName === "test" || provinceName === "hamedan" ? 30 : 5; + + dispatch(service(payload)) + .then((r) => { + // Check if there's an error (error message string from service) + const errorMessage = r?.payload?.error || r?.error; + + if (errorMessage) { + // Error occurred (e.g., "باقی مانده اعلام نیاز مرغدار کمتر از درخواست شماست!") + dispatch(CLOSE_MODAL()); + openNotif({ + vertical: "top", + horizontal: "center", + msg: errorMessage, + severity: "error", + }); + } else { + openNotif({ + vertical: "top", + horizontal: "center", + msg: `عملیات با موفقیت انجام شد. برای نهایی کردن خرید ${remainTime} دقیقه فرصت دارد در غیر اینصورت خرید شما حذف می شود.`, + severity: "success", + }); + dispatch(CLOSE_MODAL()); + // Call updateTable after successful submit to refresh all tables + if (updateTable && typeof updateTable === "function") { + updateTable(); + } + } + }) + .catch((error) => { + // Handle unexpected errors + const errorMessage = + error?.response?.data?.result || + error?.message || + "مشکلی پیش آمده است!"; + + dispatch(CLOSE_MODAL()); + openNotif({ + vertical: "top", + horizontal: "center", + msg: errorMessage, + severity: "error", + }); + }); + }, + }); + + return ( + + + + + + + ); +} + +export default TradePanelPurchaseModal; diff --git a/src/features/province/components/trade-panel-purchase-operation/TradePanelPurchaseOperation.js b/src/features/province/components/trade-panel-purchase-operation/TradePanelPurchaseOperation.js new file mode 100644 index 0000000..955214d --- /dev/null +++ b/src/features/province/components/trade-panel-purchase-operation/TradePanelPurchaseOperation.js @@ -0,0 +1,36 @@ +import { IconButton } from "@mui/material"; +import { useDispatch } from "react-redux"; +import { Grid } from "../../../../components/grid/Grid"; +import LocalShippingIcon from "@mui/icons-material/LocalShipping"; +import { SPACING } from "../../../../data/spacing"; +import { OPEN_MODAL } from "../../../../lib/redux/slices/appSlice"; +import TradePanelPurchaseModal from "../trade-panel-purchase-modal/TradePanelPurchaseModal"; + +export const TradePanelPurchaseOperation = ({ item, updateTable }) => { + const dispatch = useDispatch(); + + return ( + + { + dispatch( + OPEN_MODAL({ + title: "ثبت خرید", + content: ( + + ), + }) + ); + }} + > + + + + ); +}; diff --git a/src/features/province/components/transactions/Transactions.js b/src/features/province/components/transactions/Transactions.js new file mode 100644 index 0000000..30f1570 --- /dev/null +++ b/src/features/province/components/transactions/Transactions.js @@ -0,0 +1,318 @@ +import { Grid } from "../../../../components/grid/Grid"; + +import React, { useContext, useEffect, useState } from "react"; +import { + Button, + Checkbox, + IconButton, + TextField, + Tooltip, +} from "@mui/material"; +import { DatePicker } from "@mui/x-date-pickers"; +import moment from "moment"; +import { useDispatch } from "react-redux"; +import axios from "axios"; +import { RiFileExcel2Fill, RiSearchLine } from "react-icons/ri"; +import { AppContext } from "../../../../contexts/AppContext"; +import ResponsiveTable from "../../../../components/responsive-table/ResponsiveTable"; +import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl"; +import { + LOADING_END, + LOADING_START, +} from "../../../../lib/redux/slices/appSlice"; +import { useNavigate } from "react-router-dom"; +import { + ROUTE_ADMINX_TRANSACTIONS, + ROUTE_CITY_REQUEST_TRANSACTIONS, + ROUTE_PROVINCE_FINANCIAL_TRANSACTIONS, + ROUTE_PROVINCE_TRANSACTIONS, + ROUTE_SUPER_ADMIN_TRANSACTIONS, +} from "../../../../routes/routes"; +import ToggleOffOutlinedIcon from "@mui/icons-material/ToggleOffOutlined"; +import ToggleOnIcon from "@mui/icons-material/ToggleOn"; +import ReceiptLongIcon from "@mui/icons-material/ReceiptLong"; +export const Transactions = () => { + const [, , selectedDate1, setSelectedDate1, selectedDate2, setSelectedDate2] = + useContext(AppContext); + const [withDate, setWithDate] = useState(true); + const [openNotif] = useContext(AppContext); + + const dispatch = useDispatch(); + useEffect(() => { + const currentDate = moment(new Date()).format("YYYY-MM-DD"); + setSelectedDate1(currentDate); + setSelectedDate2(currentDate); + }, []); + + const handleTextChange = (event) => { + setTextValue(event.target.value); + }; + const navigate = useNavigate(); + + const [data, setData] = useState([]); + const [totalRows, setTotalRows] = useState(0); + const [perPage, setPerPage] = useState(10); + const [textValue, setTextValue] = useState(""); + const [page, setPage] = useState(1); + const [tableData, setTableData] = useState([]); + const [menuState, setMenuState] = useState({ anchorEl: null, item: null }); + + const fetchApiData = async (page) => { + dispatch(LOADING_START()); + const response = await axios.get( + `pos-machine-transactions/?search=filter&value=${textValue}&role=${getRoleFromUrl()}${ + withDate ? `&date1=${selectedDate1}&date2=${selectedDate2}` : `` + }&page=${page}&page_size=${perPage}` + ); + dispatch(LOADING_END()); + setData(response.data.results); + setTotalRows(response.data.count); + }; + + const handlePageChange = (page) => { + fetchApiData(page); + setPage(page); + }; + + const handlePerRowsChange = (perRows) => { + setPerPage(perRows); + setPage(1); + }; + + // const updateTable = () => { + // fetchApiData(page !== 0 ? page : 1); + // }; + + useEffect(() => { + const d = data?.map((item, i) => { + return [ + page === 1 ? i + 1 : i + perPage * (page - 1) + 1, + item?.guildsName || "-", + `${item?.user?.fullname} (${item?.user?.mobile})`, + item?.user?.city?.name || "-", + item?.guildsName || "-", + item?.licenseNumber || "-", + item?.transaction?.totalCarcassesWeight?.toLocaleString(), + item?.transaction?.realAllocatedWeight?.toLocaleString(), + item?.transaction?.totalRemainWeight?.toLocaleString(), + item?.transaction?.lenTransaction?.toLocaleString(), + item?.transaction?.totalPrice?.toLocaleString(), + <> + { + handleMenuClose(); + navigateToTransactions(item); + }} + > + + + , + // "ردیف", + // "صنف", + // "کاربر", + // "شهر", + // "ورودی به انبار (کیلوگرم)", + // "فروش رفته (کیلوگرم)", + // "مانده انبار (کیلوگرم)", + // "تعداد تراکنش ها", + // "مبلغ تراکنش ها", + // "عملیات", + ]; + }); + + setTableData(d); + }, [data, menuState]); + + useEffect(() => { + fetchApiData(1); + }, [dispatch, selectedDate1, selectedDate2, perPage, withDate]); + + const handleSubmit = async (event) => { + event.preventDefault(); + dispatch(LOADING_START()); + + try { + const response = await axios.get( + `pos-machine-transactions/?role=${getRoleFromUrl()}&search=filter&value=${textValue}${ + withDate ? `&date1=${selectedDate1}&date2=${selectedDate2}` : `` + }&page=${1}&page_size=${perPage}` + ); + setData(response.data.results); + setTotalRows(response.data.count); + dispatch(LOADING_END()); + } catch (error) { + console.error("Error fetching data:", error); + } + }; + + const handleMenuClose = () => { + setMenuState({ anchorEl: null, item: null }); + }; + + const navigateToTransactions = (item) => { + const filterDateParam = withDate ? "on" : "off"; + navigate( + `${ + getRoleFromUrl() === "AdminX" + ? ROUTE_ADMINX_TRANSACTIONS + : getRoleFromUrl() === "SuperAdmin" + ? ROUTE_SUPER_ADMIN_TRANSACTIONS + : getRoleFromUrl() === "ProvinceFinancial" + ? ROUTE_PROVINCE_FINANCIAL_TRANSACTIONS + : getRoleFromUrl() === "CityPoultry" + ? ROUTE_CITY_REQUEST_TRANSACTIONS + : ROUTE_PROVINCE_TRANSACTIONS + }/${item?.key}/${item?.guildsName}?filterDate=${filterDateParam}` + ); + }; + + return ( + + + + } + checkedIcon={} + checked={withDate} + onChange={() => setWithDate(!withDate)} + color="primary" + size="large" + /> + + ( + + )} + value={selectedDate1} + onChange={(e) => { + setSelectedDate1(moment(e).format("YYYY-MM-DD")); + }} + /> + + + ( + + )} + value={selectedDate2} + onChange={(e) => { + setSelectedDate2(moment(e).format("YYYY-MM-DD")); + }} + /> + + + +
    + + + +
    + + {/* */} + + {/* */} + +
    + + +
    + ); +}; diff --git a/src/features/province/components/view-guild-details/ViewGuildDetails.js b/src/features/province/components/view-guild-details/ViewGuildDetails.js new file mode 100644 index 0000000..79d2fe6 --- /dev/null +++ b/src/features/province/components/view-guild-details/ViewGuildDetails.js @@ -0,0 +1,629 @@ +import React from "react"; +import { Typography, Box } from "@mui/material"; +import { Grid } from "../../../../components/grid/Grid"; +import { SPACING } from "../../../../data/spacing"; +import PersonIcon from "@mui/icons-material/Person"; +import BusinessIcon from "@mui/icons-material/Business"; +import DateRangeIcon from "@mui/icons-material/DateRange"; +import ConfirmationNumberIcon from "@mui/icons-material/ConfirmationNumber"; +import AccountBalanceIcon from "@mui/icons-material/AccountBalance"; +import LocalPostOfficeIcon from "@mui/icons-material/LocalPostOffice"; +import PhoneIcon from "@mui/icons-material/Phone"; +import PublicIcon from "@mui/icons-material/Public"; +import CorporateFareIcon from "@mui/icons-material/CorporateFare"; +import BadgeIcon from "@mui/icons-material/Badge"; +import CheckCircleIcon from "@mui/icons-material/CheckCircle"; +import LocationCityIcon from "@mui/icons-material/LocationCity"; +import FaceIcon from "@mui/icons-material/Face"; +import FavoriteIcon from "@mui/icons-material/Favorite"; +import CakeIcon from "@mui/icons-material/Cake"; +import HomeIcon from "@mui/icons-material/Home"; +import { formatJustDate } from "../../../../utils/formatTime"; +export const ViewGuildDetails = ({ guild }) => { + // Helper function to safely render values + const renderValue = (value) => { + if (!value) return "-"; + if (typeof value === "object") { + // If it's an object, try to extract a meaningful string + return value.name || value.title || value.label || JSON.stringify(value); + } + return value; + }; + + // Extract nested values + const provinceName = guild?.address?.province?.name || "-"; + const cityName = guild?.address?.city?.name || "-"; + const postalCode = guild?.address?.postalCode || "-"; + const guildCategory = guild?.guildAreaActivity?.title || "-"; + const unionName = guild?.unionName || "-"; + return ( + + + {/* Two Column Layout: Person Data | Guild Data */} + + + + + اطلاعات شخصی + + + + + + + + + + کد ملی + + + {renderValue(guild?.user?.nationalId)} + + + + + + + + + + نام + + + {renderValue(guild?.user?.firstName)} + + + + + + + + + + + نام خانوادگی + + + {renderValue(guild?.user?.lastName)} + + + + + + + + + + شماره شناسنامه + + + {renderValue(guild?.user?.nationalCode)} + + + + + + + + + + در قید حیات + + + {guild?.user?.isAlive ? "بلی" : "خیر"} + + + + + + + + + + + + + تاریخ تولد + + + {renderValue(guild?.user?.birthday)} + + + + + + + + + + + نام پدر + + + {renderValue(guild?.user?.fatherName)} + + + + + + + + + + + جنسیت + + + {guild?.user?.gender === "True" + ? "مرد" + : guild?.user?.gender === "False" + ? "زن" + : "-"} + + + + + + + + + + شماره همراه + + + {renderValue(guild?.user?.mobile)} + + + + + + + + + + + شهر + + + {renderValue(guild?.user?.city)} + + + + + + + + + + + + + + اطلاعات صنفی + + + + + + + + + + نام واحد + + + {renderValue(guild?.guildsName)} + + + + + + + + + + + رسته واحد صنفی + + {guildCategory} + + + + + + + + + استان + + {provinceName} + + + + + + + + + شهرستان + + {cityName} + + + + + + + + + + تاریخ انقضا مجوز + + + {formatJustDate(guild?.licenseExpireDate)} + + + + + + + + + + شماره مجوز + + + {renderValue(guild?.licenseNumber)} + + + + + + + + + + نام اتحادیه + + {unionName} + + + + + + + + + + + کد پستی + + {postalCode} + + + + + + + + + + شماره تلفن + + + {renderValue(guild?.phone)} + + + + + + + + + + + آیا اتباع است؟ + + + {guild?.isForeignNational ? "بلی" : "خیر"} + + + + + + + + + + + نام شرکت + + + {renderValue(guild?.companyName)} + + + + + + + + + + + شناسه ملی شرکت + + + {renderValue(guild?.companyIdentifier)} + + + + + + + + + + + وضعیت مجوز + + + {renderValue(guild?.licenseStatus)} + + + + + + + + + + آدرس + + + {renderValue(guild?.address?.address)} + + + + + + + + + + + ); +}; diff --git a/src/features/province/hooks/useProvinceNewRequests.js b/src/features/province/hooks/useProvinceNewRequests.js new file mode 100644 index 0000000..3a42f1f --- /dev/null +++ b/src/features/province/hooks/useProvinceNewRequests.js @@ -0,0 +1,23 @@ +import { useState, useEffect } from "react"; +import { useDispatch, useSelector } from "react-redux"; +import { getProvinceNewRequests } from "../services/get-province-new-requests"; + +const useProvinceRequests = () => { + const [data, setData] = useState(null); + const dispatch = useDispatch(); + const defaultValue = useSelector( + (state) => state.provinceSlice.provinceNewRequests + ); + + useEffect(() => { + dispatch(getProvinceNewRequests()); + }, []); + + useEffect(() => { + setData(defaultValue); + }, [defaultValue]); + + return data ? data : []; +}; + +export default useProvinceRequests; diff --git a/src/features/province/services/ProvinceGetFieldOfWorks.js b/src/features/province/services/ProvinceGetFieldOfWorks.js new file mode 100644 index 0000000..a8397a1 --- /dev/null +++ b/src/features/province/services/ProvinceGetFieldOfWorks.js @@ -0,0 +1,10 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; + +export const provinceGetFieldOfWorks = createAsyncThunk( + "PROVINCE_GET_FIELD_OF_WORKS", + async () => { + const { data, status } = await axios.get("area-activity/"); + return { data, status }; + } +); diff --git a/src/features/province/services/activate-returned-cargo.js b/src/features/province/services/activate-returned-cargo.js new file mode 100644 index 0000000..ffa396a --- /dev/null +++ b/src/features/province/services/activate-returned-cargo.js @@ -0,0 +1,25 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const activateReturnedCargo = createAsyncThunk( + "ACTIVATE_RETURNED_CARGO", + async (d, { dispatch }) => { + try { + dispatch(LOADING_START()); + const { data, status } = await axios.put( + "return-kill-house-requests/0/", + { + key: d.key, + trash: false, + return_trash: false, + } + ); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e.response?.data?.result || e.message }; + } + } +); diff --git a/src/features/province/services/activate-returned-request.js b/src/features/province/services/activate-returned-request.js new file mode 100644 index 0000000..b9a7d2d --- /dev/null +++ b/src/features/province/services/activate-returned-request.js @@ -0,0 +1,25 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const activateReturnedRequest = createAsyncThunk( + "ACTIVATE_RETURNED_REQUEST", + async (d, { dispatch }) => { + try { + dispatch(LOADING_START()); + const { data, status } = await axios.put( + "return-province-kill-requests/", + { + key: d.key, + trash: false, + return_trash: false, + } + ); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e.response?.data?.result || e.message }; + } + } +); diff --git a/src/features/province/services/admin-free-buy-edit-payment.js b/src/features/province/services/admin-free-buy-edit-payment.js new file mode 100644 index 0000000..f3408d7 --- /dev/null +++ b/src/features/province/services/admin-free-buy-edit-payment.js @@ -0,0 +1,18 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const adminFreeBuyEditPayment = createAsyncThunk( + "ADMIN_FREE_BUY_EDIT_PAYMENT", + async (d, { dispatch }) => { + try { + dispatch(LOADING_START()); + const { data, status } = await axios.put("direct-buying-requests/0/", d); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e.response.data.result }; + } + } +); diff --git a/src/features/province/services/admin-settlement-direct-buying-payment.js b/src/features/province/services/admin-settlement-direct-buying-payment.js new file mode 100644 index 0000000..df9ac6f --- /dev/null +++ b/src/features/province/services/admin-settlement-direct-buying-payment.js @@ -0,0 +1,18 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const adminSettlementDirectBuying = createAsyncThunk( + "ADMIN_SETTLEMENT_DIRECT_BUYING", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + try { + const { data, status } = await axios.post("direct-buying-payment/", d); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e.response.data.result }; + } + } +); diff --git a/src/features/province/services/chanin-bar-management-get-dashboard.js b/src/features/province/services/chanin-bar-management-get-dashboard.js new file mode 100644 index 0000000..7aa3b69 --- /dev/null +++ b/src/features/province/services/chanin-bar-management-get-dashboard.js @@ -0,0 +1,28 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { getRoleFromUrl } from "../../../utils/getRoleFromUrl"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const chainBarManagementGetDashboard = createAsyncThunk( + "CHAIN_BAR_MANAGEMNT_DASHBOARD", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + const { data, status } = await axios.get( + `${ + d.province ? d.province + "parent-company-" : "" + }dashboard-chain-allocation`, + { + params: { + date1: d.selectedDate1, + date2: d.selectedDate2, + role: getRoleFromUrl(), + filter: "search", + value: d.text ? d.text : "", + state: d.state ? d.state : null, + }, + } + ); + dispatch(LOADING_END()); + return { data, status }; + } +); diff --git a/src/features/province/services/check-killhouse-request-guild.js b/src/features/province/services/check-killhouse-request-guild.js new file mode 100644 index 0000000..ae13434 --- /dev/null +++ b/src/features/province/services/check-killhouse-request-guild.js @@ -0,0 +1,18 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const checkKillhouseRequestGuildService = createAsyncThunk( + "CHECK_KILLHOUSE_REQUEST_GUILD_SERVICE", + async (d, { dispatch }) => { + try { + dispatch(LOADING_START()); + const { data, status } = await axios.post("check_guilds/", d); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e.response.data.result }; + } + } +); diff --git a/src/features/province/services/deactivate-guild.js b/src/features/province/services/deactivate-guild.js new file mode 100644 index 0000000..f9cc702 --- /dev/null +++ b/src/features/province/services/deactivate-guild.js @@ -0,0 +1,20 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const deactivateGuildService = createAsyncThunk( + "DEACTIVATE_GUILD_SERVICE", + async (key, { dispatch }) => { + try { + dispatch(LOADING_START()); + const { data, status } = await axios.get( + `deactivate_guild/?key=${key}&guild=true` + ); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e.response?.data?.result || e.message }; + } + } +); diff --git a/src/features/province/services/delete-debtor-killhouses.js b/src/features/province/services/delete-debtor-killhouses.js new file mode 100644 index 0000000..a4346cb --- /dev/null +++ b/src/features/province/services/delete-debtor-killhouses.js @@ -0,0 +1,12 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; + +export const deleteDebtorKillhouses = createAsyncThunk( + "DELETE_DEBTORS", + async () => { + const { data, status } = await axios.delete( + "delete-debtors-kill-requests/0" + ); + return { data, status }; + } +); diff --git a/src/features/province/services/direct-buying-verification.js b/src/features/province/services/direct-buying-verification.js new file mode 100644 index 0000000..9166e36 --- /dev/null +++ b/src/features/province/services/direct-buying-verification.js @@ -0,0 +1,10 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; + +export const directBuyingVerification = createAsyncThunk( + "DIRECT_BUYING_VERIFICATION", + async () => { + const { data, status } = await axios.get("direct-buying-verification/"); + return { data, status }; + } +); diff --git a/src/features/province/services/direct-edit-buying-verification.js b/src/features/province/services/direct-edit-buying-verification.js new file mode 100644 index 0000000..0c22c93 --- /dev/null +++ b/src/features/province/services/direct-edit-buying-verification.js @@ -0,0 +1,21 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const directEditBuyingVerification = createAsyncThunk( + "DIRECT_EDIT_BUYING_VERIFICATION", + async (d, { dispatch }) => { + try { + dispatch(LOADING_START()); + const { data, status } = await axios.put( + "direct-buying-verification/0/", + d + ); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e.response.data.result }; + } + } +); diff --git a/src/features/province/services/free-buying-delete-payment.js b/src/features/province/services/free-buying-delete-payment.js new file mode 100644 index 0000000..917a6e7 --- /dev/null +++ b/src/features/province/services/free-buying-delete-payment.js @@ -0,0 +1,20 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const freeBuyDeletePaymentService = createAsyncThunk( + "FREE_BUYING_DELETE_PAYMENT", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + try { + const { data, status } = await axios.delete(`direct-buying-payment/0/`, { + params: d, + }); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e.response.data.result }; + } + } +); diff --git a/src/features/province/services/free-buying-payment.js b/src/features/province/services/free-buying-payment.js new file mode 100644 index 0000000..e927311 --- /dev/null +++ b/src/features/province/services/free-buying-payment.js @@ -0,0 +1,23 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const freeBuyingPayment = createAsyncThunk( + "FREE_BUYING_PAYMENT", + async (d, { dispatch }) => { + try { + dispatch(LOADING_START()); + const { data, status } = await axios.get(`direct-buying-payment`, { + params: { + province_kill_request_key: d.province_kill_request_key, + role_key: d.role_key || "", + }, + }); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e.response?.data?.result || "خطایی رخ داده است" }; + } + } +); diff --git a/src/features/province/services/get-approved-price-state.js b/src/features/province/services/get-approved-price-state.js new file mode 100644 index 0000000..409462f --- /dev/null +++ b/src/features/province/services/get-approved-price-state.js @@ -0,0 +1,27 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const getApprovedPriceState = createAsyncThunk( + "GET_APPROVED_PRICE_STATE", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + const { data, status } = await axios.get("approved-price", { + params: d, + }); + dispatch(LOADING_END()); + return { data, status }; + } +); + +export const getKillhouseApprovedPriceState = createAsyncThunk( + "GET_KILLHOUSE_APPROVED_PRICE_STATE", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + const { data, status } = await axios.get("broadcast-price", { + params: d, + }); + dispatch(LOADING_END()); + return { data, status }; + } +); diff --git a/src/features/province/services/get-cases-overview.js b/src/features/province/services/get-cases-overview.js new file mode 100644 index 0000000..127c236 --- /dev/null +++ b/src/features/province/services/get-cases-overview.js @@ -0,0 +1,21 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const provinceGetCasesOverview = createAsyncThunk( + "GET_PROVINCE_OVERVIEW_CASES", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + const { data, status } = await axios.get( + "general-statistics-dashboard-for-cases/", + { + params: { + date1: d.date1, + date2: d.date2, + }, + } + ); + dispatch(LOADING_END()); + return { data, status }; + } +); diff --git a/src/features/province/services/get-cities.js b/src/features/province/services/get-cities.js new file mode 100644 index 0000000..27e4015 --- /dev/null +++ b/src/features/province/services/get-cities.js @@ -0,0 +1,13 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const getCitiesService = createAsyncThunk( + "GET_CITIES_SERVICE", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + const { data, status } = await axios.get("city_operator/"); + dispatch(LOADING_END()); + return { data, status }; + } +); diff --git a/src/features/province/services/get-dahsnoard-province-kill-request.js b/src/features/province/services/get-dahsnoard-province-kill-request.js new file mode 100644 index 0000000..1045978 --- /dev/null +++ b/src/features/province/services/get-dahsnoard-province-kill-request.js @@ -0,0 +1,53 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; +import { getRoleFromUrl } from "../../../utils/getRoleFromUrl"; +import axios from "axios"; +export const provinceGetDashboardKillRequestService = createAsyncThunk( + "KILL_REQUEST_PROVINCE", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + + const params = { + date1: d.selectedDate1, + date2: d.selectedDate2, + role: getRoleFromUrl(), + role_key: d.role_key || "", + filter: "search", + value: d.textValue, + }; + + if (d.hasDocumentState) { + params.allocated_car_state = true; + } + + const { data, status } = await axios.get( + `dahsnoard_province_kill_request`, + { params } + ); + dispatch(LOADING_END()); + return { data, status }; + } +); + +export const provinceGetDashboardDeletedKillRequestService = createAsyncThunk( + "DELETED_KILL_REQUEST_PROVINCE", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + const { data, status } = await axios.get( + `dahsnoard_province_kill_request`, + { + params: { + date1: d.selectedDate1, + date2: d.selectedDate2, + role: getRoleFromUrl(), + role_key: d.role_key || "", + deleted_object: true, + filter: "search", + value: d.textValue, + }, + } + ); + dispatch(LOADING_END()); + return { data, status }; + } +); diff --git a/src/features/province/services/get-direct-buy-permission.js b/src/features/province/services/get-direct-buy-permission.js new file mode 100644 index 0000000..422f3da --- /dev/null +++ b/src/features/province/services/get-direct-buy-permission.js @@ -0,0 +1,13 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const getDirectBuyPermissionService = createAsyncThunk( + "GET_DIRECT_BUY_PERMISSION_SERVICE", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + const { data, status } = await axios.get("allow_direct_buying_total/"); + dispatch(LOADING_END()); + return { data, status }; + } +); diff --git a/src/features/province/services/get-guilds-settings.js b/src/features/province/services/get-guilds-settings.js new file mode 100644 index 0000000..b9e09c7 --- /dev/null +++ b/src/features/province/services/get-guilds-settings.js @@ -0,0 +1,13 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; + +export const getGuildsSettingsService = createAsyncThunk( + "GET_GUILDS_SETTINGS_SERVICE", + async (d) => { + const { data, status } = await axios.get( + "kill_house_choose_steward_guilds/", + { params: { kill_house_key: d.kill_house_key } } + ); + return { data, status }; + } +); diff --git a/src/features/province/services/get-killhouse-guilds-permission.js b/src/features/province/services/get-killhouse-guilds-permission.js new file mode 100644 index 0000000..ce5bdf9 --- /dev/null +++ b/src/features/province/services/get-killhouse-guilds-permission.js @@ -0,0 +1,13 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const getKillhouseGuildsPermissionService = createAsyncThunk( + "GET_KILLHOUSE_GUILDS_PERMISSION_SERVICE", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + const { data, status } = await axios.get("allow_register_guilds_total/"); + dispatch(LOADING_END()); + return { data, status }; + } +); diff --git a/src/features/province/services/get-losses-permission.js b/src/features/province/services/get-losses-permission.js new file mode 100644 index 0000000..67672d5 --- /dev/null +++ b/src/features/province/services/get-losses-permission.js @@ -0,0 +1,13 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const getLossesPermissionService = createAsyncThunk( + "GET_LOSSES_PERMISSION_SERVICE", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + const { data, status } = await axios.get("losses_permission/"); + dispatch(LOADING_END()); + return { data, status }; + } +); diff --git a/src/features/province/services/get-manage-poultries.js b/src/features/province/services/get-manage-poultries.js new file mode 100644 index 0000000..0db805b --- /dev/null +++ b/src/features/province/services/get-manage-poultries.js @@ -0,0 +1,15 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const getManagePoultriesService = createAsyncThunk( + "GET_MANAGE_POULTRIES_SERVICE", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + const { data, status } = await axios.get("total_poultry", { + params: { page: d.page, page_size: d.pageSize }, + }); + dispatch(LOADING_END()); + return { data, status }; + } +); diff --git a/src/features/province/services/get-min-max-age-state.js b/src/features/province/services/get-min-max-age-state.js new file mode 100644 index 0000000..90bf50e --- /dev/null +++ b/src/features/province/services/get-min-max-age-state.js @@ -0,0 +1,13 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const getMinMaxSlaughterAgeState = createAsyncThunk( + "GET_MIN_MAX_AGE_STATE", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + const { data, status } = await axios.get("chicken-age-range/"); + dispatch(LOADING_END()); + return { data, status }; + } +); diff --git a/src/features/province/services/get-policy-province-fee.js b/src/features/province/services/get-policy-province-fee.js new file mode 100644 index 0000000..9f7a637 --- /dev/null +++ b/src/features/province/services/get-policy-province-fee.js @@ -0,0 +1,13 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const getPolicyProvinceFeeService = createAsyncThunk( + "GET_POLICY_PROVINCE_FEE_SERVICE", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + const { data, status } = await axios.get("share/"); + dispatch(LOADING_END()); + return { data, status }; + } +); diff --git a/src/features/province/services/get-poultry-transport-by-code.js b/src/features/province/services/get-poultry-transport-by-code.js new file mode 100644 index 0000000..1c59740 --- /dev/null +++ b/src/features/province/services/get-poultry-transport-by-code.js @@ -0,0 +1,34 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const getPoultryTransportByCodeService = createAsyncThunk( + "GET_POULTRY_TRANSPORT_BY_CODE_SERVICE", + async (params, { dispatch }) => { + try { + dispatch(LOADING_START()); + const { data, status } = await axios.get( + "https://rsibackend.rasadyar.com/app/get-all-products-transport-by-code/", + { + params: { + code: params.code, + type: params.type, + page: params.page || 1, + page_size: params.page_size || 10, + date1: params.date1 || "", + date2: params.date2 || "", + search: params.search || "", + province: params.province || "", + product: params.product || "", + from: params.from || "", + }, + } + ); + dispatch(LOADING_END()); + return { data, status }; + } catch (error) { + dispatch(LOADING_END()); + return { error: error.response?.data || error.message }; + } + } +); diff --git a/src/features/province/services/get-poultry-transport-dashboard-by-code.js b/src/features/province/services/get-poultry-transport-dashboard-by-code.js new file mode 100644 index 0000000..a6edeff --- /dev/null +++ b/src/features/province/services/get-poultry-transport-dashboard-by-code.js @@ -0,0 +1,32 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const getPoultryTransportDashboardByCodeService = createAsyncThunk( + "GET_POULTRY_TRANSPORT_DASHBOARD_BY_CODE_SERVICE", + async (params, { dispatch }) => { + try { + dispatch(LOADING_START()); + const { data, status } = await axios.get( + "https://rsibackend.rasadyar.com/app/get-all-products-transport-dashboard-by-code/", + { + params: { + code: params.code, + type: params.type, + date1: params.date1 || "", + date2: params.date2 || "", + search: params.search || "", + product: params.product || "", + province: params.province || "", + from: params.from || "", + }, + } + ); + dispatch(LOADING_END()); + return { data, status }; + } catch (error) { + dispatch(LOADING_END()); + return { error: error.response?.data || error.message }; + } + } +); diff --git a/src/features/province/services/get-poultry-transport-products-by-code.js b/src/features/province/services/get-poultry-transport-products-by-code.js new file mode 100644 index 0000000..0c0f574 --- /dev/null +++ b/src/features/province/services/get-poultry-transport-products-by-code.js @@ -0,0 +1,26 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; + +export const getPoultryTransportProductsByCodeService = createAsyncThunk( + "GET_POULTRY_TRANSPORT_PRODUCTS_BY_CODE_SERVICE", + async (params) => { + try { + const { data, status } = await axios.get( + "https://rsibackend.rasadyar.com/app/get-all-products-transport-products-by-code/", + { + params: { + code: params.code, + type: params.type, + date1: params.date1 || "", + date2: params.date2 || "", + search: params.search || "", + from: params.from || "", + }, + } + ); + return { data, status }; + } catch (error) { + return { error: error.response?.data || error.message }; + } + } +); diff --git a/src/features/province/services/get-province-buyer-steward-allocation.js b/src/features/province/services/get-province-buyer-steward-allocation.js new file mode 100644 index 0000000..fd43cd5 --- /dev/null +++ b/src/features/province/services/get-province-buyer-steward-allocation.js @@ -0,0 +1,20 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; +import { getRoleFromUrl } from "../../../utils/getRoleFromUrl"; + +export const getProvinceBuyerStewardAllocationService = createAsyncThunk( + "GET_PROVINCE_BUYER_STEWARD_ALLOCATION_SERVICE", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + const { data, status } = await axios.get("automatic-steward-allocation/", { + params: { + kill_house_key: d.killHouseKey, + date: d.date, + role: getRoleFromUrl(), + }, + }); + dispatch(LOADING_END()); + return { data, status }; + } +); diff --git a/src/features/province/services/get-province-buyers-allocations.js b/src/features/province/services/get-province-buyers-allocations.js new file mode 100644 index 0000000..03d7f9d --- /dev/null +++ b/src/features/province/services/get-province-buyers-allocations.js @@ -0,0 +1,21 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const getProvinceBuyersAllocationsService = createAsyncThunk( + "GET_PROVINCE_BUYERS_ALLOCATIONS_SERVICE", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + const { data, status } = await axios.get( + `kill_house_ware_house_total_report_daily_broad_cast_in_detail`, + { + params: { + date1: d.selectedDate1, + date2: d.selectedDate2, + }, + } + ); + dispatch(LOADING_END()); + return { data, status }; + } +); diff --git a/src/features/province/services/get-province-fee-total-overview.js b/src/features/province/services/get-province-fee-total-overview.js new file mode 100644 index 0000000..e583456 --- /dev/null +++ b/src/features/province/services/get-province-fee-total-overview.js @@ -0,0 +1,15 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const getProvinceFeeTotalOverviewService = createAsyncThunk( + "GET_PROVINCE_FEE_TOTAL_OVERVIEW_SERVICE", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + const { data, status } = await axios.get( + "reporting_province_kill_request_wage/" + ); + dispatch(LOADING_END()); + return { data, status }; + } +); diff --git a/src/features/province/services/get-province-new-requests.js b/src/features/province/services/get-province-new-requests.js new file mode 100644 index 0000000..5372ca2 --- /dev/null +++ b/src/features/province/services/get-province-new-requests.js @@ -0,0 +1,15 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const getProvinceNewRequests = createAsyncThunk( + "GET_PROVINCE_NEW_REQUESTS", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + const { data, status } = await axios.get("city_operator_check_request", { + params: { state: "new", date1: d.selectedDate1, date2: d.selectedDate2 }, + }); + dispatch(LOADING_END()); + return { data, status }; + } +); diff --git a/src/features/province/services/get-province-steward.allocation.js b/src/features/province/services/get-province-steward.allocation.js new file mode 100644 index 0000000..7239242 --- /dev/null +++ b/src/features/province/services/get-province-steward.allocation.js @@ -0,0 +1,21 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const getProvinceStewardAllocationsService = createAsyncThunk( + "GET_PROVINCE_STEWARD_ALLOCATIONS_SERVICE", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + const { data, status } = await axios.get( + `steward_ware_house_total_report_daily_broad_cast_in_detail`, + { + params: { + date1: d.selectedDate1, + date2: d.selectedDate2, + }, + } + ); + dispatch(LOADING_END()); + return { data, status }; + } +); diff --git a/src/features/province/services/getDashboardOfManagePoultries.js b/src/features/province/services/getDashboardOfManagePoultries.js new file mode 100644 index 0000000..825d884 --- /dev/null +++ b/src/features/province/services/getDashboardOfManagePoultries.js @@ -0,0 +1,23 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; +import axios from "axios"; +import { getRoleFromUrl } from "../../../utils/getRoleFromUrl"; + +export const provinceGetDashboardPoultriesService = createAsyncThunk( + "POULTRIES_DASHBOARD", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + const { data, status } = await axios.get( + `total_poultry_hatching_dashboard`, + { + params: { + search: "filter", + value: d.textValue, + role: getRoleFromUrl(), + }, + } + ); + dispatch(LOADING_END()); + return { data, status }; + } +); diff --git a/src/features/province/services/getDocumentStates.js b/src/features/province/services/getDocumentStates.js new file mode 100644 index 0000000..cef9110 --- /dev/null +++ b/src/features/province/services/getDocumentStates.js @@ -0,0 +1,30 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const getDocumentStates = createAsyncThunk( + "GET_DOCUMENT_STATES", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + const { data, status } = await axios.get("bar-documents-status/", { + params: d, + }); + dispatch(LOADING_END()); + return { data, status }; + } +); + +export const submitDocumentStates = createAsyncThunk( + "PROVINCE_SUBMIT_DOCUMENT_STATES", + async (d, { dispatch }) => { + try { + dispatch(LOADING_START()); + const { data, status } = await axios.put("bar-documents-status/0/", d); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e.response.data.result }; + } + } +); diff --git a/src/features/province/services/getStewardTransactions.js b/src/features/province/services/getStewardTransactions.js new file mode 100644 index 0000000..34d33e6 --- /dev/null +++ b/src/features/province/services/getStewardTransactions.js @@ -0,0 +1,21 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; + +export const getStewardTransactions = createAsyncThunk( + "AVICULTURE_REQUESTS_SERVICE", + async (d) => { + const { data, status } = await axios.get( + "https://amait.mrkiani.ir/api/report/transactions/", + { + params: { + shop: d.key, + datefrom: d.datefrom, + dateto: d.dateto, + page: d.page, + mode: d.mode, + }, + } + ); + return { data, status }; + } +); diff --git a/src/features/province/services/killhouse-free-buy-edit-payment.js b/src/features/province/services/killhouse-free-buy-edit-payment.js new file mode 100644 index 0000000..dc5d090 --- /dev/null +++ b/src/features/province/services/killhouse-free-buy-edit-payment.js @@ -0,0 +1,18 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const killhouseFreeBuyEditPayment = createAsyncThunk( + "KILLHOUSE_FREE_BUY_EDIT_PAYMENT", + async (d, { dispatch }) => { + try { + dispatch(LOADING_START()); + const { data, status } = await axios.put("direct-buying-requests/0/", d); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e.response.data.result }; + } + } +); diff --git a/src/features/province/services/main-get-guilds-for-update-or-create.js b/src/features/province/services/main-get-guilds-for-update-or-create.js new file mode 100644 index 0000000..46de9a7 --- /dev/null +++ b/src/features/province/services/main-get-guilds-for-update-or-create.js @@ -0,0 +1,41 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; +import { getRoleFromUrl } from "../../../utils/getRoleFromUrl"; + +export const mainGetGuildsForUpdateOrCreateService = createAsyncThunk( + "MAIN_GET_GUILDS_FOR_UPDATE_OR_CREATE_SERVICE", + async (payload, { dispatch }) => { + dispatch(LOADING_START()); + try { + const { data, status } = await axios.get( + "main_get_guilds_for_update_or_create/", + { + params: { + national_code: payload.national_code, + update: payload.update || false, + role: getRoleFromUrl(), + }, + } + ); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + + if (e.response?.status === 403) { + const errorMessage = + e.response?.data?.result || + e.response?.data?.message || + "دسترسی غیرمجاز"; + return { error: errorMessage, status: 403 }; + } + + const errorMessage = + e.response?.data?.result || + e.response?.data?.message || + "خطا در دریافت اطلاعات"; + return { error: errorMessage }; + } + } +); diff --git a/src/features/province/services/manage-process-buy-req-operation.js b/src/features/province/services/manage-process-buy-req-operation.js new file mode 100644 index 0000000..655cca4 --- /dev/null +++ b/src/features/province/services/manage-process-buy-req-operation.js @@ -0,0 +1,18 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const manageProcessBuyReqOperationService = createAsyncThunk( + "MANAGE_PROCESS_BUY_REQ_OPERATION_SERVICE", + async (d, { dispatch }) => { + try { + dispatch(LOADING_START()); + const { data, status } = await axios.put("kill_house_purchase/0/", d); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e.response.data.result }; + } + } +); diff --git a/src/features/province/services/manage-process-buy-req.js b/src/features/province/services/manage-process-buy-req.js new file mode 100644 index 0000000..70e8bd8 --- /dev/null +++ b/src/features/province/services/manage-process-buy-req.js @@ -0,0 +1,13 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const manageProcessBuyReqService = createAsyncThunk( + "MANAGE_PROCESS_BUY_REQ_SERVICE", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + const { data, status } = await axios.get("kill_house_purchase_info/"); + dispatch(LOADING_END()); + return { data, status }; + } +); diff --git a/src/features/province/services/payment-edit-deadlines.js b/src/features/province/services/payment-edit-deadlines.js new file mode 100644 index 0000000..0e55bf9 --- /dev/null +++ b/src/features/province/services/payment-edit-deadlines.js @@ -0,0 +1,21 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const paymentEditDeadLines = createAsyncThunk( + "PAYMENT_EDIT_DEADLINES", + async (d, { dispatch }) => { + try { + dispatch(LOADING_START()); + const { data, status } = await axios.put( + "direct-buying-verification/0/", + d + ); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e.response.data.result }; + } + } +); diff --git a/src/features/province/services/payment-get-deadlines.js b/src/features/province/services/payment-get-deadlines.js new file mode 100644 index 0000000..e363313 --- /dev/null +++ b/src/features/province/services/payment-get-deadlines.js @@ -0,0 +1,12 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; + +export const paymentGetDeadLines = createAsyncThunk( + "PAYMENT_GET_DEADLINES", + async (d) => { + const { data, status } = await axios.get("direct-buying-verification/", { + params: d, + }); + return { data, status }; + } +); diff --git a/src/features/province/services/policy-change-killhouse-direct-buy.js b/src/features/province/services/policy-change-killhouse-direct-buy.js new file mode 100644 index 0000000..519717d --- /dev/null +++ b/src/features/province/services/policy-change-killhouse-direct-buy.js @@ -0,0 +1,18 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const policyChangeKillhouseDirectBuyService = createAsyncThunk( + "POLICY_CHANGE_KILLHOUSE_DIRECT_BUY_SERVICE", + async (d, { dispatch }) => { + try { + dispatch(LOADING_START()); + const { data, status } = await axios.put("allow_direct_buying/0/", d); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e.response.data.result }; + } + } +); diff --git a/src/features/province/services/policy-change-killhouse-guilds.js b/src/features/province/services/policy-change-killhouse-guilds.js new file mode 100644 index 0000000..048b56a --- /dev/null +++ b/src/features/province/services/policy-change-killhouse-guilds.js @@ -0,0 +1,18 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const policyChangeKillhouseGuildsService = createAsyncThunk( + "POLICY_CHANGE_KILLHOUSE_GUILDS_SERVICE", + async (d, { dispatch }) => { + try { + dispatch(LOADING_START()); + const { data, status } = await axios.put("allow_register_guilds/0/", d); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e.response.data.result }; + } + } +); diff --git a/src/features/province/services/policy-change-poultry-choose-slaughter.js b/src/features/province/services/policy-change-poultry-choose-slaughter.js new file mode 100644 index 0000000..2b64574 --- /dev/null +++ b/src/features/province/services/policy-change-poultry-choose-slaughter.js @@ -0,0 +1,21 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const policyChangePoultryChooseSlaughterService = createAsyncThunk( + "POLICY_CHANGE_POULTRY_CHOOSE_SLAUGHTER_SERVICE", + async (d, { dispatch }) => { + try { + dispatch(LOADING_START()); + const { data, status } = await axios.put( + "province_allow_poultry_choose_kill_house/0/", + d + ); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e.response.data.result }; + } + } +); diff --git a/src/features/province/services/policy-change-poultry-free-sales.js b/src/features/province/services/policy-change-poultry-free-sales.js new file mode 100644 index 0000000..23d8c34 --- /dev/null +++ b/src/features/province/services/policy-change-poultry-free-sales.js @@ -0,0 +1,21 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const policyChangePoultryFreeSalesService = createAsyncThunk( + "POLICY_CHANGE_POULTRY_CHOOSE_SLAUGHTER_SERVICE", + async (d, { dispatch }) => { + try { + dispatch(LOADING_START()); + const { data, status } = await axios.put( + "province_allow_poultry_sell_free/0/", + d + ); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e.response.data.result }; + } + } +); diff --git a/src/features/province/services/policy-change-province-fee.js b/src/features/province/services/policy-change-province-fee.js new file mode 100644 index 0000000..d451f0f --- /dev/null +++ b/src/features/province/services/policy-change-province-fee.js @@ -0,0 +1,18 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const policyChangeProvinceFeeService = createAsyncThunk( + "POLICY_CHANGE_PROVINCE_FEE_SERVICE", + async (d, { dispatch }) => { + try { + dispatch(LOADING_START()); + const { data, status } = await axios.put("share/0/", d); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e.response.data.result }; + } + } +); diff --git a/src/features/province/services/post-direct-buy-permission.js b/src/features/province/services/post-direct-buy-permission.js new file mode 100644 index 0000000..da7e73c --- /dev/null +++ b/src/features/province/services/post-direct-buy-permission.js @@ -0,0 +1,13 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const postDirectBuyPermissionService = createAsyncThunk( + "POST_DIRECT_BUY_PERMISSION_SERVICE", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + const { data, status } = await axios.post("allow_direct_buying_total/", d); + dispatch(LOADING_END()); + return { data, status }; + } +); diff --git a/src/features/province/services/post-killhouse-guild-permission.js b/src/features/province/services/post-killhouse-guild-permission.js new file mode 100644 index 0000000..a8ddb92 --- /dev/null +++ b/src/features/province/services/post-killhouse-guild-permission.js @@ -0,0 +1,16 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const postKillhouseGuildPermissionService = createAsyncThunk( + "POST_KILLHOUSE_GUILD_PERMISSION_SERVICE", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + const { data, status } = await axios.post( + "allow_register_guilds_total/", + d + ); + dispatch(LOADING_END()); + return { data, status }; + } +); diff --git a/src/features/province/services/province-add-auto-allocation.js b/src/features/province/services/province-add-auto-allocation.js new file mode 100644 index 0000000..1863fad --- /dev/null +++ b/src/features/province/services/province-add-auto-allocation.js @@ -0,0 +1,18 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const provinceAddAutoAllocationService = createAsyncThunk( + "PROVINCE_ADD_AUTO_ALLOCATION_SERVICE", + async (d, { dispatch }) => { + try { + dispatch(LOADING_START()); + const { data, status } = await axios.put("automatic_allocation/0/", d); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e.response.data.result }; + } + } +); diff --git a/src/features/province/services/province-add-car-to-killhouse.js b/src/features/province/services/province-add-car-to-killhouse.js new file mode 100644 index 0000000..e5298d2 --- /dev/null +++ b/src/features/province/services/province-add-car-to-killhouse.js @@ -0,0 +1,22 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; +import { getRoleFromUrl } from "../../../utils/getRoleFromUrl"; + +export const provinceAddCarToKillhouseService = createAsyncThunk( + "PROVINCE_ADD_CAR_TO_KILLHOUSE_SERVICE", + async (d, { dispatch }) => { + try { + dispatch(LOADING_START()); + const { data, status } = await axios.post("kill_house_add_car/", { + ...d, + role: getRoleFromUrl(), + }); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e.response.data.result }; + } + } +); diff --git a/src/features/province/services/province-age-message.js b/src/features/province/services/province-age-message.js new file mode 100644 index 0000000..7c64671 --- /dev/null +++ b/src/features/province/services/province-age-message.js @@ -0,0 +1,63 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const provinceGetAgeMessagesService = createAsyncThunk( + "GET_AGE_MESSAGES", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + const { data, status } = await axios.get("age-notification-poultry/"); + dispatch(LOADING_END()); + return { data, status }; + } +); + +export const provinceEditAgeMessagesService = createAsyncThunk( + "EDIT_AGE_MESSAGES", + async (d, { dispatch }) => { + try { + dispatch(LOADING_START()); + const { data, status } = await axios.put( + "age-notification-poultry/0/", + d + ); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e.response.data.result }; + } + } +); + +export const provinceSubmitAgeMessagesService = createAsyncThunk( + "SUBMIT_AGE_MESSAGES", + async (d, { dispatch }) => { + try { + dispatch(LOADING_START()); + const { data, status } = await axios.post("age-notification-poultry/", d); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e.response.data.result }; + } + } +); + +export const provinceDeleteAgeMessagesService = createAsyncThunk( + "DELETE_AGE_MESSAGES", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + try { + const { data, status } = await axios.delete( + "age-notification-poultry/0/?notif_key=" + d + ); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e.response.data.result }; + } + } +); diff --git a/src/features/province/services/province-allocated-delete.js b/src/features/province/services/province-allocated-delete.js new file mode 100644 index 0000000..11fb059 --- /dev/null +++ b/src/features/province/services/province-allocated-delete.js @@ -0,0 +1,28 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; +import { getRoleFromUrl } from "../../../utils/getRoleFromUrl"; + +export const provinceAllocatedDeleteService = createAsyncThunk( + "PROVINCE_ALLOCATED_DELETE_SERVICE", + async (d, { dispatch }) => { + try { + dispatch(LOADING_START()); + const { data, status } = await axios.delete( + "province_kill_request/0/?delete_allocation", + { + params: { + province_kill_request_key: d.province_kill_request_key, + message: "به دلیل انقضای کد سفارش", + role: getRoleFromUrl(), + }, + } + ); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e.response.data.result }; + } + } +); diff --git a/src/features/province/services/province-allocated-return-quantity.js b/src/features/province/services/province-allocated-return-quantity.js new file mode 100644 index 0000000..2a9964d --- /dev/null +++ b/src/features/province/services/province-allocated-return-quantity.js @@ -0,0 +1,25 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const provinceAllocatedReturnQuantityService = createAsyncThunk( + "PROVINCE_ALLOCATED_RETURN_QUANTITY_SERVICE", + async (d, { dispatch }) => { + try { + dispatch(LOADING_START()); + const { data, status } = await axios.delete( + "province_kill_request/0/?return_allocation_quantity", + { + params: { + province_kill_request_key: d.province_kill_request_key, + }, + } + ); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e.response.data.result }; + } + } +); diff --git a/src/features/province/services/province-approve-free-sale.js b/src/features/province/services/province-approve-free-sale.js new file mode 100644 index 0000000..c58a42b --- /dev/null +++ b/src/features/province/services/province-approve-free-sale.js @@ -0,0 +1,21 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const provinceApproveFreeSaleService = createAsyncThunk( + "PROVINCE_APPROVE_FREE_SALE_SERVICE", + async (d, { dispatch }) => { + try { + dispatch(LOADING_START()); + const { data, status } = await axios.post( + "final-approval-out-province-poultry-request/", + d + ); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e.response.data.result }; + } + } +); diff --git a/src/features/province/services/province-archive-fee-operation.js b/src/features/province/services/province-archive-fee-operation.js new file mode 100644 index 0000000..68f8191 --- /dev/null +++ b/src/features/province/services/province-archive-fee-operation.js @@ -0,0 +1,18 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const provinceArchiveFeeOperationService = createAsyncThunk( + "PROVINCE_ARCHIVE_FEE_OPERATION_SERVICE", + async (d, { dispatch }) => { + try { + dispatch(LOADING_START()); + const { data, status } = await axios.put("province_kill_request/0/", d); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e.response.data.result }; + } + } +); diff --git a/src/features/province/services/province-automatic-direct-buying-permission.js b/src/features/province/services/province-automatic-direct-buying-permission.js new file mode 100644 index 0000000..d960692 --- /dev/null +++ b/src/features/province/services/province-automatic-direct-buying-permission.js @@ -0,0 +1,28 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const getAutomaticDirectBuyingPermissionState = createAsyncThunk( + "GET_AUTO_DIRECT_BUYING", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + const { data, status } = await axios.get( + "automatic-direct-buying-permission/" + ); + dispatch(LOADING_END()); + return { data, status }; + } +); + +export const provinceAutomaticDirectBuyingPermission = createAsyncThunk( + "PROVINCE_AUTO_DIRECT_BUYING", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + const { data, status } = await axios.put( + "automatic-direct-buying-permission/0/", + d + ); + dispatch(LOADING_END()); + return { data, status }; + } +); diff --git a/src/features/province/services/province-automatic-steward-allocation.js b/src/features/province/services/province-automatic-steward-allocation.js new file mode 100644 index 0000000..da3b959 --- /dev/null +++ b/src/features/province/services/province-automatic-steward-allocation.js @@ -0,0 +1,21 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const provinceAutomaticStewardAllocationService = createAsyncThunk( + "PROVINCE_AUTOMATIC_STEWARD_ALLOCATION_SERVICE", + async (d, { dispatch }) => { + try { + dispatch(LOADING_START()); + const { data, status } = await axios.put( + "automatic-steward-allocation/0/", + d + ); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e.response.data.result }; + } + } +); diff --git a/src/features/province/services/province-bar-dashbored.js b/src/features/province/services/province-bar-dashbored.js new file mode 100644 index 0000000..3bf847a --- /dev/null +++ b/src/features/province/services/province-bar-dashbored.js @@ -0,0 +1,26 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; +import axios from "axios"; +import { getRoleFromUrl } from "../../../utils/getRoleFromUrl"; + +export const ProvinceBarDashboardService = createAsyncThunk( + "PROVINCE_BAR_DASHBOARD_SERVICE", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + const { data, status } = await axios.get( + "dashboard_bar_difference_request/", + { + params: { + role: getRoleFromUrl(), + date1: d.selectedDate1, + date2: d.selectedDate2, + filter: "search", + value: d.textValue, + state: d.state, + }, + } + ); + dispatch(LOADING_END()); + return { data, status }; + } +); diff --git a/src/features/province/services/province-bar-differences-services.js b/src/features/province/services/province-bar-differences-services.js new file mode 100644 index 0000000..1ed1575 --- /dev/null +++ b/src/features/province/services/province-bar-differences-services.js @@ -0,0 +1,60 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const provinceSubmitBarDifferenceService = createAsyncThunk( + "PROVINCE_CREATE_BAR_DIFFERENCE_SERVICE", + async (d, { dispatch }) => { + try { + dispatch(LOADING_START()); + const { data, status } = await axios.post("bar-difference-request/", d); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e.response.data.result }; + } + } +); + +export const provinceEditBarDifferenceService = createAsyncThunk( + "PROVINCE_EDIT_BAR_DIFFERENCE_SERVICE", + async (d, { dispatch }) => { + try { + dispatch(LOADING_START()); + const { data, status } = await axios.put("bar-difference-request/0/", d); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e.response.data.result }; + } + } +); + +export const provinceDeleteBarDifferenceService = createAsyncThunk( + "PROVINCE_DELETE_BAR_DIFFERENCE_SERVICE", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + try { + const { data, status } = await axios.delete( + `bar-difference-request/0/?bar_key=${d}` + ); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e.response.data.result }; + } + } +); + +export const provinceGetBarDifferenceInfoService = createAsyncThunk( + "PROVINCE_GET_BAR_DIFFERENCE_INFO_SERVICE", + async (d) => { + const { data, status } = await axios.get("get_hatching_kill_ingo/", { + params: d, + }); + return { data, status }; + } +); diff --git a/src/features/province/services/province-buyer-real-carcasses.js b/src/features/province/services/province-buyer-real-carcasses.js new file mode 100644 index 0000000..6739b4b --- /dev/null +++ b/src/features/province/services/province-buyer-real-carcasses.js @@ -0,0 +1,21 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const provinceBuyerRealCarcassesService = createAsyncThunk( + "PROVINCE_BUYER_REAL_CARCASSES_SERVICE", + async (d, { dispatch }) => { + try { + dispatch(LOADING_START()); + const { data, status } = await axios.put( + "automatic-steward-allocation/0/", + d + ); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e.response.data.result }; + } + } +); diff --git a/src/features/province/services/province-cars-dashboard.js b/src/features/province/services/province-cars-dashboard.js new file mode 100644 index 0000000..07c456d --- /dev/null +++ b/src/features/province/services/province-cars-dashboard.js @@ -0,0 +1,22 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; +import { getRoleFromUrl } from "../../../utils/getRoleFromUrl"; + +export const provinceCarsDashboardService = createAsyncThunk( + "CARS_DASHBOARD", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + const { data, status } = await axios.get( + `kill_house_driver_total_dashboard`, + { + params: { + role: getRoleFromUrl(), + ...data, + }, + } + ); + dispatch(LOADING_END()); + return { data, status }; + } +); diff --git a/src/features/province/services/province-cases-get-table-details.js b/src/features/province/services/province-cases-get-table-details.js new file mode 100644 index 0000000..e08d606 --- /dev/null +++ b/src/features/province/services/province-cases-get-table-details.js @@ -0,0 +1,19 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; +import { getRoleFromUrl } from "../../../utils/getRoleFromUrl"; +export const provinceCasesGetTableDetails = createAsyncThunk( + "PROVINCE_CASES_GET_TABLE_DETAILS", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + const { data, status } = await axios.get("detail_of_killing", { + params: { + date1: d.selectedDate1, + date2: d.selectedDate2, + role: getRoleFromUrl(), + }, + }); + dispatch(LOADING_END()); + return { data, status }; + } +); diff --git a/src/features/province/services/province-chains-delete-allocation.js b/src/features/province/services/province-chains-delete-allocation.js new file mode 100644 index 0000000..6e1d22c --- /dev/null +++ b/src/features/province/services/province-chains-delete-allocation.js @@ -0,0 +1,23 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; +import { getRoleFromUrl } from "../../../utils/getRoleFromUrl"; + +export const provinceChainsDeleteAllocation = createAsyncThunk( + "PROVINCE_DELETE_CHAIN_ALLOCATION_SERVICE", + async (d, { dispatch }) => { + try { + dispatch(LOADING_START()); + const { data, status } = await axios.delete( + "chain-allocation/0/?chain_allcation_key=" + + d + + `&role=${getRoleFromUrl()}` + ); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e.response.data.result }; + } + } +); diff --git a/src/features/province/services/province-chains-delete-chain.js b/src/features/province/services/province-chains-delete-chain.js new file mode 100644 index 0000000..6146852 --- /dev/null +++ b/src/features/province/services/province-chains-delete-chain.js @@ -0,0 +1,21 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const provinceChainsDeleteChain = createAsyncThunk( + "PROVINCE_CHAINS_DELETE_CHAIN", + async (d, { dispatch }) => { + try { + dispatch(LOADING_START()); + const { data, status } = await axios.put( + "poultry-choose-chain-company/0/", + d + ); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e.response.data.result }; + } + } +); diff --git a/src/features/province/services/province-chains-edit-allocation.js b/src/features/province/services/province-chains-edit-allocation.js new file mode 100644 index 0000000..7fd4bcb --- /dev/null +++ b/src/features/province/services/province-chains-edit-allocation.js @@ -0,0 +1,20 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; +import { provinceGetGuildsService } from "./province-get-guilds"; + +export const provinceChainsEditAllocation = createAsyncThunk( + "PROVINCE_EDIT_CHAIN_ALLOCATION", + async (d, { dispatch }) => { + try { + dispatch(LOADING_START()); + const { data, status } = await axios.put("chain-allocation/0/", d); + dispatch(provinceGetGuildsService()); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e.response.data.result }; + } + } +); diff --git a/src/features/province/services/province-chains-edit-bar.js b/src/features/province/services/province-chains-edit-bar.js new file mode 100644 index 0000000..ef17c3a --- /dev/null +++ b/src/features/province/services/province-chains-edit-bar.js @@ -0,0 +1,18 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const provinceChainsEditBar = createAsyncThunk( + "PROVINCE_CHAINS_EDIT_BAR", + async (d, { dispatch }) => { + try { + dispatch(LOADING_START()); + const { data, status } = await axios.put("chain-allocation/0/", d); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e.response.data.result }; + } + } +); diff --git a/src/features/province/services/province-chains-edit-company.js b/src/features/province/services/province-chains-edit-company.js new file mode 100644 index 0000000..cf8cf8b --- /dev/null +++ b/src/features/province/services/province-chains-edit-company.js @@ -0,0 +1,18 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const provinceChainsEditCompany = createAsyncThunk( + "PROVINCE_CHAINS_EDIT_COMPANY", + async (d, { dispatch }) => { + try { + dispatch(LOADING_START()); + const { data, status } = await axios.put("chain-company/0/", d); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e.response.data.result }; + } + } +); diff --git a/src/features/province/services/province-chains-get-companies.js b/src/features/province/services/province-chains-get-companies.js new file mode 100644 index 0000000..f5ab342 --- /dev/null +++ b/src/features/province/services/province-chains-get-companies.js @@ -0,0 +1,13 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const provinceChainsGetCompanies = createAsyncThunk( + "PROVINCE_CHAINS_GET_COMPANIES", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + const { data, status } = await axios.get("chain-company/"); + dispatch(LOADING_END()); + return { data, status }; + } +); diff --git a/src/features/province/services/province-chains-replace-active-chain.js b/src/features/province/services/province-chains-replace-active-chain.js new file mode 100644 index 0000000..1f31198 --- /dev/null +++ b/src/features/province/services/province-chains-replace-active-chain.js @@ -0,0 +1,21 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const provinceChainsReplaceActiveChain = createAsyncThunk( + "PROVINCE_CHAINS_REPLACE_ACTIVE_CHAIN", + async (d, { dispatch }) => { + try { + dispatch(LOADING_START()); + const { data, status } = await axios.put( + "poultry-choose-chain-company/0/", + d + ); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e.response.data.result }; + } + } +); diff --git a/src/features/province/services/province-chains-submit-active-chain.js b/src/features/province/services/province-chains-submit-active-chain.js new file mode 100644 index 0000000..80c7be7 --- /dev/null +++ b/src/features/province/services/province-chains-submit-active-chain.js @@ -0,0 +1,21 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const provinceChainsSubmitActiveChain = createAsyncThunk( + "PROVINCE_CHAINS_SUBMIT_ACTIVE_CHAIN", + async (d, { dispatch }) => { + try { + dispatch(LOADING_START()); + const { data, status } = await axios.post( + "poultry-choose-chain-company/", + d + ); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e.response.data.result }; + } + } +); diff --git a/src/features/province/services/province-chains-submit-company.js b/src/features/province/services/province-chains-submit-company.js new file mode 100644 index 0000000..6ebf4b3 --- /dev/null +++ b/src/features/province/services/province-chains-submit-company.js @@ -0,0 +1,18 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const provinceChainsSubmitCompany = createAsyncThunk( + "PROVINCE_CHAINS_SUBMIT_COMPANY", + async (d, { dispatch }) => { + try { + dispatch(LOADING_START()); + const { data, status } = await axios.post("chain-company/", d); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e.response.data.result }; + } + } +); diff --git a/src/features/province/services/province-chains-submut-allocation.js b/src/features/province/services/province-chains-submut-allocation.js new file mode 100644 index 0000000..95b4fca --- /dev/null +++ b/src/features/province/services/province-chains-submut-allocation.js @@ -0,0 +1,24 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; +import { provinceGetGuildsService } from "./province-get-guilds"; +import { getRoleFromUrl } from "../../../utils/getRoleFromUrl"; + +export const provinceChainsSubmitAllocation = createAsyncThunk( + "PROVINCE_CREATE_ALLOCATION", + async (d, { dispatch }) => { + try { + dispatch(LOADING_START()); + const { data, status } = await axios.post("chain-allocation/", { + ...d, + role: getRoleFromUrl(), + }); + dispatch(provinceGetGuildsService()); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e.response.data.result }; + } + } +); diff --git a/src/features/province/services/province-change-active-guild.js b/src/features/province/services/province-change-active-guild.js new file mode 100644 index 0000000..d741f00 --- /dev/null +++ b/src/features/province/services/province-change-active-guild.js @@ -0,0 +1,20 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; +import { provinceGetGuildsService } from "./province-get-guilds"; + +export const provinceChangeActiveGuildService = createAsyncThunk( + "PROVINCE_CHANGE_ACTIVE_GUILD_SERVICE", + async (d, { dispatch }) => { + try { + dispatch(LOADING_START()); + const { data, status } = await axios.put("provinceCreateGuildService", d); + dispatch(provinceGetGuildsService()); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e.response.data.result }; + } + } +); diff --git a/src/features/province/services/province-change-active-steward.js b/src/features/province/services/province-change-active-steward.js new file mode 100644 index 0000000..b8ed0c5 --- /dev/null +++ b/src/features/province/services/province-change-active-steward.js @@ -0,0 +1,20 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; +import { provinceGetStewardsService } from "./province-get-stewards"; + +export const provinceChangeActiveStewardService = createAsyncThunk( + "PROVINCE_CHANGE_ACTIVE_STEWARD_SERVICE", + async (d, { dispatch }) => { + try { + dispatch(LOADING_START()); + const { data, status } = await axios.put("steward/0/", d); + dispatch(provinceGetStewardsService()); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e.response.data.result }; + } + } +); diff --git a/src/features/province/services/province-change-slaughter-car-permission.js b/src/features/province/services/province-change-slaughter-car-permission.js new file mode 100644 index 0000000..7088797 --- /dev/null +++ b/src/features/province/services/province-change-slaughter-car-permission.js @@ -0,0 +1,21 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const provinceChangeSlaughterCarPermissionService = createAsyncThunk( + "PROVINCE_CHANGE_SLAUGHTER_CAR_PERMISSION_SERVICE", + async (d, { dispatch }) => { + try { + dispatch(LOADING_START()); + const { data, status } = await axios.post( + "province_allow_kill_house_register_car/", + d + ); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e.response.data.result }; + } + } +); diff --git a/src/features/province/services/province-change-user-status.js b/src/features/province/services/province-change-user-status.js new file mode 100644 index 0000000..0cb59d1 --- /dev/null +++ b/src/features/province/services/province-change-user-status.js @@ -0,0 +1,10 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; + +export const provinceChaneUserStatus = createAsyncThunk( + "PROVINCE_CHANGE_USER_STATUS", + async (d) => { + const { data, status } = await axios.post("system_user_profile/0/", d); + return { data, status }; + } +); diff --git a/src/features/province/services/province-check-chain-allocation.js b/src/features/province/services/province-check-chain-allocation.js new file mode 100644 index 0000000..0de23c6 --- /dev/null +++ b/src/features/province/services/province-check-chain-allocation.js @@ -0,0 +1,18 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const provinceCheckChainAllocationService = createAsyncThunk( + "PROVINCE_CHECK_CHAIN_ALLOCATION_SERVICE", + async (d, { dispatch }) => { + try { + dispatch(LOADING_START()); + const { data, status } = await axios.put("chain-allocation/0/", d); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e.response.data.result }; + } + } +); diff --git a/src/features/province/services/province-check-free-sale.js b/src/features/province/services/province-check-free-sale.js new file mode 100644 index 0000000..784b782 --- /dev/null +++ b/src/features/province/services/province-check-free-sale.js @@ -0,0 +1,21 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const provinceCheckFreeSaleService = createAsyncThunk( + "PROVINCE_CHECK_FREE_SALE_SERVICE", + async (d, { dispatch }) => { + try { + dispatch(LOADING_START()); + const { data, status } = await axios.post( + "province_check_operator_out_request/", + d + ); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e.response.data.result }; + } + } +); diff --git a/src/features/province/services/province-check-operator-out-request.js b/src/features/province/services/province-check-operator-out-request.js new file mode 100644 index 0000000..a4a26bb --- /dev/null +++ b/src/features/province/services/province-check-operator-out-request.js @@ -0,0 +1,21 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const provinceCheckOperatorOutRequestService = createAsyncThunk( + "PROVINCE_CHECK_OPERATOR_OUT_REQUEST_SERVICE", + async (d, { dispatch }) => { + try { + dispatch(LOADING_START()); + const { data, status } = await axios.delete( + `province_check_operator_out_request/0/?poultry_request_key=${d}`, + d + ); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e.response.data.result }; + } + } +); diff --git a/src/features/province/services/province-check-user-existence.js b/src/features/province/services/province-check-user-existence.js new file mode 100644 index 0000000..48332f3 --- /dev/null +++ b/src/features/province/services/province-check-user-existence.js @@ -0,0 +1,10 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; + +export const provinceCheckUserExistence = createAsyncThunk( + "PROVINCE_CHECK_USER_EXISTENCE", + async (d) => { + const { data, status } = await axios.post("system_user_profile/", d); + return { data, status }; + } +); diff --git a/src/features/province/services/province-chicken-distribution-and-sales-dashboard.js b/src/features/province/services/province-chicken-distribution-and-sales-dashboard.js new file mode 100644 index 0000000..809fdc1 --- /dev/null +++ b/src/features/province/services/province-chicken-distribution-and-sales-dashboard.js @@ -0,0 +1,35 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const ProvinceChickenDistributionsAndSalesDashboardService = + createAsyncThunk( + "PROVINCE_NATIONAL_GET_DISTRIBUTION_SERVICE", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + const { data, status } = await axios.get( + "https://rsibackend.rasadyar.com/app/transport-carcass-dashboard", + { + params: d, + } + ); + dispatch(LOADING_END()); + return { data, status }; + } + ); + +export const ProvinceStewardChickenDistributionsAndSalesDashboardService = + createAsyncThunk( + "PROVINCE_NATIONAL_GET_STEWARD_DISTRIBUTION_SERVICE", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + const { data, status } = await axios.get( + "https://rsibackend.rasadyar.com/app/guilds-transport-carcass-dashboard", + { + params: d, + } + ); + dispatch(LOADING_END()); + return { data, status }; + } + ); diff --git a/src/features/province/services/province-close-allocation.js b/src/features/province/services/province-close-allocation.js new file mode 100644 index 0000000..a8ce89e --- /dev/null +++ b/src/features/province/services/province-close-allocation.js @@ -0,0 +1,18 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const provinceCloseAllocationService = createAsyncThunk( + "PROVINCE_CLOSE_ALLOCATION_SERVICE", + async (d, { dispatch }) => { + try { + dispatch(LOADING_START()); + const { data, status } = await axios.put("Poultry_Request/0/", d); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e.response.data.result }; + } + } +); diff --git a/src/features/province/services/province-cold-houses.js b/src/features/province/services/province-cold-houses.js new file mode 100644 index 0000000..4de0356 --- /dev/null +++ b/src/features/province/services/province-cold-houses.js @@ -0,0 +1,58 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const provinceGetColdHousesDashboard = createAsyncThunk( + "GET_PROVINCE_COLD_HOUSES_DASHBOARD", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + const { data, status } = await axios.get("cold-house-total-dashboard"); + dispatch(LOADING_END()); + return { data, status }; + } +); + +export const provinceGetAllStewardsService = createAsyncThunk( + "PROVINCE_GET_ALL_STEWARDS_SERVICE", + async (d, { dispatch }) => { + try { + dispatch(LOADING_START()); + const { data, status } = await axios.get("stewards-for-cold-house/", {}); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e.response.data.result }; + } + } +); + +export const provinceCreateColdHouseService = createAsyncThunk( + "PROVINCE_CREATE_COLD_HOUSE_SERVICE", + async (d, { dispatch }) => { + try { + dispatch(LOADING_START()); + const { data, status } = await axios.post("cold-house/", d); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e.response.data.result }; + } + } +); + +export const provinceEditColdHouseService = createAsyncThunk( + "PROVINCE_EDIT_COLD_HOUSE_SERVICE", + async (d, { dispatch }) => { + try { + dispatch(LOADING_START()); + const { data, status } = await axios.put("cold-house/0/", d); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e.response.data.result }; + } + } +); diff --git a/src/features/province/services/province-create-auto-allocation.js b/src/features/province/services/province-create-auto-allocation.js new file mode 100644 index 0000000..76abb23 --- /dev/null +++ b/src/features/province/services/province-create-auto-allocation.js @@ -0,0 +1,18 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const provinceCreateAutoAllocationService = createAsyncThunk( + "PROVINCE_CREATE_AUTO_ALLOCATION_SERVICE", + async (d, { dispatch }) => { + try { + dispatch(LOADING_START()); + const { data, status } = await axios.post("automatic_allocation/", d); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e.response.data.result }; + } + } +); diff --git a/src/features/province/services/province-create-guild.js b/src/features/province/services/province-create-guild.js new file mode 100644 index 0000000..2295df1 --- /dev/null +++ b/src/features/province/services/province-create-guild.js @@ -0,0 +1,24 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; +import { provinceGetGuildsService } from "./province-get-guilds"; +import { getRoleFromUrl } from "../../../utils/getRoleFromUrl"; + +export const provinceCreateGuildService = createAsyncThunk( + "PROVINCE_CREATE_GUILD_SERVICE", + async (d, { dispatch }) => { + try { + dispatch(LOADING_START()); + const { data, status } = await axios.post( + "update_guild_by_national_id/?role=" + getRoleFromUrl(), + d + ); + dispatch(provinceGetGuildsService()); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e.response.data.result }; + } + } +); diff --git a/src/features/province/services/province-create-killhouse.js b/src/features/province/services/province-create-killhouse.js new file mode 100644 index 0000000..4bf9af2 --- /dev/null +++ b/src/features/province/services/province-create-killhouse.js @@ -0,0 +1,20 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; +import { provinceGetGuildsService } from "./province-get-guilds"; + +export const provinceCreateKillhouseService = createAsyncThunk( + "PROVINCE_CREATE_KILLHOUSE_SERVICE", + async (d, { dispatch }) => { + try { + dispatch(LOADING_START()); + const { data, status } = await axios.post("kill_house/", d); + dispatch(provinceGetGuildsService()); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e.response.data.result }; + } + } +); diff --git a/src/features/province/services/province-create-legal-guild.js b/src/features/province/services/province-create-legal-guild.js new file mode 100644 index 0000000..c98161f --- /dev/null +++ b/src/features/province/services/province-create-legal-guild.js @@ -0,0 +1,21 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const provinceCreateLegalGuildService = createAsyncThunk( + "PROVINCE_CREATE_LEGAL_GUILD_SERVICE", + async (d, { dispatch }) => { + try { + dispatch(LOADING_START()); + const { data, status } = await axios.post("register_legal_guild/", d); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { + error: + e.response?.data?.result || e.response?.data || "خطا در ثبت اطلاعات", + }; + } + } +); diff --git a/src/features/province/services/province-create-steward.js b/src/features/province/services/province-create-steward.js new file mode 100644 index 0000000..a51fedd --- /dev/null +++ b/src/features/province/services/province-create-steward.js @@ -0,0 +1,18 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const provinceCreateStewardService = createAsyncThunk( + "PROVINCE_CREATE_STEWARD_SERVICE", + async (d, { dispatch }) => { + try { + dispatch(LOADING_START()); + const { data, status } = await axios.post("steward/", d); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e.response.data.result }; + } + } +); diff --git a/src/features/province/services/province-dashboard-bar-diffrence-get-request.js b/src/features/province/services/province-dashboard-bar-diffrence-get-request.js new file mode 100644 index 0000000..4775054 --- /dev/null +++ b/src/features/province/services/province-dashboard-bar-diffrence-get-request.js @@ -0,0 +1,27 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; +import axios from "axios"; +import { getRoleFromUrl } from "../../../utils/getRoleFromUrl"; + +export const provinceGetDashboardBarDiffrenceRequest = createAsyncThunk( + "GET_PROVINCE_BAR_DIFFRENCE_REQUEST", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + const { data, status } = await axios.get( + "dashboard_bar_difference_request/", + { + params: { + role: getRoleFromUrl(), + role_key: d.role_key || "", + state: d.state, + filter: "search", + value: d.value, + date1: d.date1, + date2: d.date2, + }, + } + ); + dispatch(LOADING_END()); + return { data, status }; + } +); diff --git a/src/features/province/services/province-dashboard-submit-news.js b/src/features/province/services/province-dashboard-submit-news.js new file mode 100644 index 0000000..86f51ff --- /dev/null +++ b/src/features/province/services/province-dashboard-submit-news.js @@ -0,0 +1,18 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const provinceSubmitDashboardNewsService = createAsyncThunk( + "PROVINCE_SUBMIT_DASHBOARD_NEWS_SERVICE", + async (d, { dispatch }) => { + try { + dispatch(LOADING_START()); + const { data, status } = await axios.post("dashboard_notification/", d); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e.response.data.result }; + } + } +); diff --git a/src/features/province/services/province-deispenser-sale-out-get-dashboard.js b/src/features/province/services/province-deispenser-sale-out-get-dashboard.js new file mode 100644 index 0000000..7082d45 --- /dev/null +++ b/src/features/province/services/province-deispenser-sale-out-get-dashboard.js @@ -0,0 +1,31 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; +import axios from "axios"; +import { getRoleFromUrl } from "../../../utils/getRoleFromUrl"; + +export const provinceDispenserWithOutGetDashboard = createAsyncThunk( + "PROVINCE_DISPENSER_SALE_WITHOUT_DASHBOARD", + async (payload, { dispatch, rejectWithValue }) => { + try { + dispatch(LOADING_START()); + const { data, status } = await axios.get( + "steward_free_sale_bar_dashboard/", + { + params: { + date1: payload.selectedDate1, + date2: payload.selectedDate2, + role: getRoleFromUrl(), + steward_key: payload.steward_key || "all", + }, + } + ); + dispatch(LOADING_END()); + return { data, status }; + } catch (error) { + dispatch(LOADING_END()); + return rejectWithValue( + error?.response?.data || { message: "ارتباط با سرور برقرار نشد." } + ); + } + } +); diff --git a/src/features/province/services/province-delete-auto-allocation.js b/src/features/province/services/province-delete-auto-allocation.js new file mode 100644 index 0000000..c59f612 --- /dev/null +++ b/src/features/province/services/province-delete-auto-allocation.js @@ -0,0 +1,18 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const provinceDeleteAutoAllocationService = createAsyncThunk( + "PROVINCE_DELETE_AUTO_ALLOCATION_SERVICE", + async (d, { dispatch }) => { + try { + dispatch(LOADING_START()); + const { data, status } = await axios.put("automatic_allocation/0/", d); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e.response.data.result }; + } + } +); diff --git a/src/features/province/services/province-delete-trade-panel.js b/src/features/province/services/province-delete-trade-panel.js new file mode 100644 index 0000000..2fe117b --- /dev/null +++ b/src/features/province/services/province-delete-trade-panel.js @@ -0,0 +1,20 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const provinceDeleteTradePanelService = createAsyncThunk( + "SLAUGHTER_DELETE_FREE_BUY_SERVICE", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + try { + const { data, status } = await axios.delete( + `market-requests/0/?key=${d}` + ); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e.response.data.result }; + } + } +); diff --git a/src/features/province/services/province-dispenser-edit-sale-out.js b/src/features/province/services/province-dispenser-edit-sale-out.js new file mode 100644 index 0000000..37db399 --- /dev/null +++ b/src/features/province/services/province-dispenser-edit-sale-out.js @@ -0,0 +1,21 @@ +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; +import { createAsyncThunk } from "@reduxjs/toolkit"; + +export const provinceDispenserEditService = createAsyncThunk( + "PROVINCE_EDIT_DISPENSER_SERVICE", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + try { + const { data, status } = await axios.put( + "kill_house_free_sale_bar/0/", + d + ); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e.response.data.result }; + } + } +); diff --git a/src/features/province/services/province-dispenser-get-kill-house.js b/src/features/province/services/province-dispenser-get-kill-house.js new file mode 100644 index 0000000..d27fd91 --- /dev/null +++ b/src/features/province/services/province-dispenser-get-kill-house.js @@ -0,0 +1,15 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; +import axios from "axios"; + +export const provinceDispenserGetKillHouseService = createAsyncThunk( + "PROVINCE-DISPENSER-KILL-HOUSE-SERVICE", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + const { data, status } = await axios.get( + "kill_house/?total-exclude-exclusive-killers=true" + ); + dispatch(LOADING_END()); + return { data, status }; + } +); diff --git a/src/features/province/services/province-dispenser-get-steward.js b/src/features/province/services/province-dispenser-get-steward.js new file mode 100644 index 0000000..7dca7db --- /dev/null +++ b/src/features/province/services/province-dispenser-get-steward.js @@ -0,0 +1,13 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; +import axios from "axios"; + +export const provinceDispenserGetStewardService = createAsyncThunk( + "PROVINCE-DISPENSER-STEWARD-SERVICE", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + const { data, status } = await axios.get("get_all_guilds/"); + dispatch(LOADING_END()); + return { data, status }; + } +); diff --git a/src/features/province/services/province-dispenser-sale-out-dashboard.js b/src/features/province/services/province-dispenser-sale-out-dashboard.js new file mode 100644 index 0000000..761e0f4 --- /dev/null +++ b/src/features/province/services/province-dispenser-sale-out-dashboard.js @@ -0,0 +1,24 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; +import axios from "axios"; +import { getRoleFromUrl } from "../../../utils/getRoleFromUrl"; + +export const provinceDispenserWithOutGetDashboard = createAsyncThunk( + "PROVINCE_DISPENSER_SALE_WITHOUT_DASHBOARD", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + const { data, status } = await axios.get( + `dashboard_kill_house_free_sale_bar`, + { + params: { + date1: d.selectedDate1, + date2: d.selectedDate2, + role: getRoleFromUrl(), + kill_house_key: d.kill_house_key || "all", + }, + } + ); + dispatch(LOADING_END()); + return { data, status }; + } +); diff --git a/src/features/province/services/province-dispenser-segmentation-dashboard.js b/src/features/province/services/province-dispenser-segmentation-dashboard.js new file mode 100644 index 0000000..cc6fc08 --- /dev/null +++ b/src/features/province/services/province-dispenser-segmentation-dashboard.js @@ -0,0 +1,21 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; +import axios from "axios"; +import { getRoleFromUrl } from "../../../utils/getRoleFromUrl"; + +export const provinceDispenserSegmentationDashboard = createAsyncThunk( + "PROVINCE_DISPENSER_SEGMENTATION_DASHBOARD", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + const { data, status } = await axios.get(`segmentation-dashboard`, { + params: { + date1: d.selectedDate1, + date2: d.selectedDate2, + role: getRoleFromUrl(), + steward_key: d.steward_key || "all", + }, + }); + dispatch(LOADING_END()); + return { data, status }; + } +); diff --git a/src/features/province/services/province-dispenser-slaughter-get-steward-service.js b/src/features/province/services/province-dispenser-slaughter-get-steward-service.js new file mode 100644 index 0000000..7385161 --- /dev/null +++ b/src/features/province/services/province-dispenser-slaughter-get-steward-service.js @@ -0,0 +1,21 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; +import axios from "axios"; +import { getRoleFromUrl } from "../../../utils/getRoleFromUrl"; + +export const provinceGetDispenserSlaughterToStewardDashboardService = + createAsyncThunk( + "PROVINCE_GET_DISPENSER_KILLHOUSES_DASHBOARD_SERVICE", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + const { data, status } = await axios.get(`total-steward-dashboard`, { + params: { + role: getRoleFromUrl(), + date1: d.selectedDate1 ? d.selectedDate1 : null, + date2: d.selectedDate2 ? d.selectedDate2 : null, + }, + }); + dispatch(LOADING_END()); + return { data, status }; + } + ); diff --git a/src/features/province/services/province-dispenser-steward-edit-sale-out.js b/src/features/province/services/province-dispenser-steward-edit-sale-out.js new file mode 100644 index 0000000..1b8af06 --- /dev/null +++ b/src/features/province/services/province-dispenser-steward-edit-sale-out.js @@ -0,0 +1,18 @@ +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; +import { createAsyncThunk } from "@reduxjs/toolkit"; + +export const provinceDispenserStewardEditSaleOutService = createAsyncThunk( + "PROVINCE_EDIT_DISPENSER__STEWARD_SALE_OUT_SERVICE", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + try { + const { data, status } = await axios.put("steward_free_sale_bar/0/", d); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e.response.data.result }; + } + } +); diff --git a/src/features/province/services/province-dispenser-with-in-sale-dashboard.js b/src/features/province/services/province-dispenser-with-in-sale-dashboard.js new file mode 100644 index 0000000..b4d8c85 --- /dev/null +++ b/src/features/province/services/province-dispenser-with-in-sale-dashboard.js @@ -0,0 +1,24 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; +import axios from "axios"; +import { getRoleFromUrl } from "../../../utils/getRoleFromUrl"; + +export const provinceDispenserWithInGetDashboard = createAsyncThunk( + "PROVINCE_DISPENSER_SALE_WITHIN_DASHBOARD", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + const { data, status } = await axios.get( + `in-province-allocation-dashboard/?type=Steward`, + { + params: { + date1: d.selectedDate1, + date2: d.selectedDate2, + role: getRoleFromUrl(), + steward_key: d.steward_key || "all", + }, + } + ); + dispatch(LOADING_END()); + return { data, status }; + } +); diff --git a/src/features/province/services/province-dispenser-with-in-sale-inventory-dashboard.js b/src/features/province/services/province-dispenser-with-in-sale-inventory-dashboard.js new file mode 100644 index 0000000..5a16313 --- /dev/null +++ b/src/features/province/services/province-dispenser-with-in-sale-inventory-dashboard.js @@ -0,0 +1,26 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; +import axios from "axios"; +import { getRoleFromUrl } from "../../../utils/getRoleFromUrl"; + +export const provinceDispenserWithInGetDashboard = createAsyncThunk( + "PROVINCE_DISPENSER_SALE_WITHIN_DASHBOARD", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + const { data, status } = await axios.get( + `in-province-allocation-dashboard/?type=KillHouse`, + { + params: { + date1: d.selectedDate1, + date2: d.selectedDate2, + role: getRoleFromUrl(), + kill_house_key: d.kill_house_key || "all", + trash: d.trash, + return_trash: d.return_trash, + }, + } + ); + dispatch(LOADING_END()); + return { data, status }; + } +); diff --git a/src/features/province/services/province-dispensers-services.js b/src/features/province/services/province-dispensers-services.js new file mode 100644 index 0000000..eebaea8 --- /dev/null +++ b/src/features/province/services/province-dispensers-services.js @@ -0,0 +1,49 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; +import { getRoleFromUrl } from "../../../utils/getRoleFromUrl"; + +export const provinceDispensersGetAllStewards = createAsyncThunk( + "GET_STEWARDS_GUILDS_SERVICE", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + const { data, status } = await axios.get("real-guilds/", { + params: { + role: getRoleFromUrl(), + ...d, + }, + }); + dispatch(LOADING_END()); + return { data, status }; + } +); + +export const provinceDispensersAddSteward = createAsyncThunk( + "ADD_STEWARDS_GUILDS_SERVICE", + async (d, { dispatch }) => { + try { + dispatch(LOADING_START()); + const { data, status } = await axios.put("real-guilds/0/", d); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e.response.data.result }; + } + } +); + +export const provinceDispensersCreateSteward = createAsyncThunk( + "CREATE_STEWARDS_GUILDS_SERVICE", + async (d, { dispatch }) => { + try { + dispatch(LOADING_START()); + const { data, status } = await axios.post("real-guilds/", d); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e.response.data.result }; + } + } +); diff --git a/src/features/province/services/province-edit-approved-price.js b/src/features/province/services/province-edit-approved-price.js new file mode 100644 index 0000000..9423c0e --- /dev/null +++ b/src/features/province/services/province-edit-approved-price.js @@ -0,0 +1,28 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const provinceEditApprovedPrice = createAsyncThunk( + "PROVINCE_EDIT_APPROVED_PRICE", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + const { data, status } = await axios.put("approved-price/0/", d); + dispatch(LOADING_END()); + return { data, status }; + } +); + +export const provinceEditKillhouseApprovedPrice = createAsyncThunk( + "PROVINCE_EDIT_KILL_APPROVED_PRICE", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + try { + const { data, status } = await axios.put("broadcast-price/0/", d); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e.response.data.result }; + } + } +); diff --git a/src/features/province/services/province-edit-auto-allocation.js b/src/features/province/services/province-edit-auto-allocation.js new file mode 100644 index 0000000..ac92dbf --- /dev/null +++ b/src/features/province/services/province-edit-auto-allocation.js @@ -0,0 +1,18 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const provinceEditAutoAllocationService = createAsyncThunk( + "PROVINCE_EDIT_AUTO_ALLOCATION_SERVICE", + async (d, { dispatch }) => { + try { + dispatch(LOADING_START()); + const { data, status } = await axios.put("automatic_allocation/0/", d); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e.response.data.result }; + } + } +); diff --git a/src/features/province/services/province-edit-car.js b/src/features/province/services/province-edit-car.js new file mode 100644 index 0000000..6d712d9 --- /dev/null +++ b/src/features/province/services/province-edit-car.js @@ -0,0 +1,18 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const provinceEditCarService = createAsyncThunk( + "PROVINCE_EDIT_CAR_SERVICE", + async (d, { dispatch }) => { + try { + dispatch(LOADING_START()); + const { data, status } = await axios.put("kill_house_driver/0/", d); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e.response.data.result }; + } + } +); diff --git a/src/features/province/services/province-edit-evacuation-permit.js b/src/features/province/services/province-edit-evacuation-permit.js new file mode 100644 index 0000000..9975851 --- /dev/null +++ b/src/features/province/services/province-edit-evacuation-permit.js @@ -0,0 +1,18 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const provinceEditEvacuationPermit = createAsyncThunk( + "PROVINCE_EDIT_EVACUATION_PERMIT", + async (d, { dispatch }) => { + try { + dispatch(LOADING_START()); + const { data, status } = await axios.put("evacuation_permit/0/", d); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e.response.data.result }; + } + } +); diff --git a/src/features/province/services/province-edit-free-sale.js b/src/features/province/services/province-edit-free-sale.js new file mode 100644 index 0000000..300bd61 --- /dev/null +++ b/src/features/province/services/province-edit-free-sale.js @@ -0,0 +1,21 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const provinceEditFreeSaleService = createAsyncThunk( + "PROVINCE_EDIT_FREE_SALE_SERVICE", + async (d, { dispatch }) => { + try { + dispatch(LOADING_START()); + const { data, status } = await axios.put( + "province_check_operator_out_request/0/", + d + ); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e.response.data.result }; + } + } +); diff --git a/src/features/province/services/province-edit-kill-capacity.js b/src/features/province/services/province-edit-kill-capacity.js new file mode 100644 index 0000000..3ce243e --- /dev/null +++ b/src/features/province/services/province-edit-kill-capacity.js @@ -0,0 +1,18 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const provinceEditKillCapacityService = createAsyncThunk( + "PROVINCE_EDIT_KILL_CAPACITY_SERVICE", + async (d, { dispatch }) => { + try { + dispatch(LOADING_START()); + const { data, status } = await axios.put("kill_request/0/", d); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e.response.data.result }; + } + } +); diff --git a/src/features/province/services/province-edit-min-max-age.js b/src/features/province/services/province-edit-min-max-age.js new file mode 100644 index 0000000..20cbcda --- /dev/null +++ b/src/features/province/services/province-edit-min-max-age.js @@ -0,0 +1,13 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const provinceEditMinMaxAge = createAsyncThunk( + "PROVINCE_EDIT_MIN_MAX_AGE", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + const { data, status } = await axios.put("chicken-age-range/0/", d); + dispatch(LOADING_END()); + return { data, status }; + } +); diff --git a/src/features/province/services/province-edit-poultry-city.js b/src/features/province/services/province-edit-poultry-city.js new file mode 100644 index 0000000..10c3922 --- /dev/null +++ b/src/features/province/services/province-edit-poultry-city.js @@ -0,0 +1,18 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const provinceEditPoultryCityService = createAsyncThunk( + "PROVINCE_EDIT_POULTRY_CITY_SERVICE", + async (d, { dispatch }) => { + try { + dispatch(LOADING_START()); + const { data, status } = await axios.put("Poultry/0/", d); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e.response.data.result }; + } + } +); diff --git a/src/features/province/services/province-edit-poultry-request-service.js b/src/features/province/services/province-edit-poultry-request-service.js new file mode 100644 index 0000000..d3e440b --- /dev/null +++ b/src/features/province/services/province-edit-poultry-request-service.js @@ -0,0 +1,18 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const provinceEditPoultryRequestService = createAsyncThunk( + "PROVINCE_EDIT_POULTRY_REQUEST_SERVICE", + async (d, { dispatch }) => { + try { + dispatch(LOADING_START()); + const { data, status } = await axios.put("Poultry_Request/0/", d); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e.response.data.result }; + } + } +); diff --git a/src/features/province/services/province-edit-send-date.js b/src/features/province/services/province-edit-send-date.js new file mode 100644 index 0000000..9a6a1be --- /dev/null +++ b/src/features/province/services/province-edit-send-date.js @@ -0,0 +1,18 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const provinceEditSendDate = createAsyncThunk( + "PROVINCE_EDIT_SEND_DATE", + async (d, { dispatch }) => { + try { + dispatch(LOADING_START()); + const { data, status } = await axios.put("Poultry_Request/0/", d); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e.response.data.result }; + } + } +); diff --git a/src/features/province/services/province-edit-steward.js b/src/features/province/services/province-edit-steward.js new file mode 100644 index 0000000..71820ee --- /dev/null +++ b/src/features/province/services/province-edit-steward.js @@ -0,0 +1,20 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; +import { provinceGetStewardsService } from "./province-get-stewards"; + +export const provinceEditStewardService = createAsyncThunk( + "PROVINCE_EDIT_STEWARD_SERVICE", + async (d, { dispatch }) => { + try { + dispatch(LOADING_START()); + const { data, status } = await axios.put("steward/0/", d); + dispatch(provinceGetStewardsService()); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e.response.data.result }; + } + } +); diff --git a/src/features/province/services/province-edit-trade-panel.js b/src/features/province/services/province-edit-trade-panel.js new file mode 100644 index 0000000..6df3d6e --- /dev/null +++ b/src/features/province/services/province-edit-trade-panel.js @@ -0,0 +1,18 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const provinceEditTradePanelService = createAsyncThunk( + "PROVINCE_EDIT_TRADE_PANEL_SERVICE", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + try { + const { data, status } = await axios.put("market-requests/0/", d); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e.response.data.result }; + } + } +); diff --git a/src/features/province/services/province-edit-unpaid-fee.js b/src/features/province/services/province-edit-unpaid-fee.js new file mode 100644 index 0000000..cc6f8ee --- /dev/null +++ b/src/features/province/services/province-edit-unpaid-fee.js @@ -0,0 +1,18 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const provinceEditUnpaidFeeService = createAsyncThunk( + "PROVINCE_EDIT_UNPAID_FEE_SERVICE", + async (d, { dispatch }) => { + try { + dispatch(LOADING_START()); + const { data, status } = await axios.put("province_kill_request/0/", d); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e.response.data.result }; + } + } +); diff --git a/src/features/province/services/province-free-sale-edit-request.js b/src/features/province/services/province-free-sale-edit-request.js new file mode 100644 index 0000000..d4049f4 --- /dev/null +++ b/src/features/province/services/province-free-sale-edit-request.js @@ -0,0 +1,18 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const provinceFreeSaleEditRequestService = createAsyncThunk( + "PROVINCE_FREE_SALE_EDIT_REQUEST", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + try { + const { data, status } = await axios.put("Poultry_Request/0/", d); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e.response.data.result }; + } + } +); diff --git a/src/features/province/services/province-free-sales-edit-buyer.js b/src/features/province/services/province-free-sales-edit-buyer.js new file mode 100644 index 0000000..fb39c8c --- /dev/null +++ b/src/features/province/services/province-free-sales-edit-buyer.js @@ -0,0 +1,21 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const provinceFreeSalesEditBuyer = createAsyncThunk( + "PROVINCE_FREE_SALES_EDIT_BUYER", + async (d, { dispatch }) => { + try { + dispatch(LOADING_START()); + const { data, status } = await axios.put( + "out-province-poultry-request-buyers/0/", + d + ); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e.response.data.result }; + } + } +); diff --git a/src/features/province/services/province-free-sales-get-buyers.js b/src/features/province/services/province-free-sales-get-buyers.js new file mode 100644 index 0000000..86da3b4 --- /dev/null +++ b/src/features/province/services/province-free-sales-get-buyers.js @@ -0,0 +1,15 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const provinceFreeSaleBuyers = createAsyncThunk( + "PROVINCE_FREE_SALES_GET_BUYERS", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + const { data, status } = await axios.get( + "out-province-poultry-request-buyers/" + ); + dispatch(LOADING_END()); + return { data, status }; + } +); diff --git a/src/features/province/services/province-free-sales-get-transaction-dashboard.js b/src/features/province/services/province-free-sales-get-transaction-dashboard.js new file mode 100644 index 0000000..33c04c8 --- /dev/null +++ b/src/features/province/services/province-free-sales-get-transaction-dashboard.js @@ -0,0 +1,26 @@ +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; +import { getRoleFromUrl } from "../../../utils/getRoleFromUrl"; +import { createAsyncThunk } from "@reduxjs/toolkit"; + +export const provinceFreeSalesGetDashboardTransactionsService = + createAsyncThunk( + "PROVINCE_FREE_SALES_TRANSACTIONS_DASH", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + const { data, status } = await axios.get( + `total-dashboard-poultry-requests-transactions`, + { + params: { + date1: d.selectedDate1, + date2: d.selectedDate2, + role: getRoleFromUrl(), + filter: "search", + value: d.textValue, + }, + } + ); + dispatch(LOADING_END()); + return { data, status }; + } + ); diff --git a/src/features/province/services/province-free-sales-send-sms-again.js b/src/features/province/services/province-free-sales-send-sms-again.js new file mode 100644 index 0000000..db5dec1 --- /dev/null +++ b/src/features/province/services/province-free-sales-send-sms-again.js @@ -0,0 +1,20 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const provinceFreeSalsesSendSmsService = createAsyncThunk( + "PROVINCE_SEND_SMS_AGAIN_SERVICE", + async (d, { dispatch }) => { + try { + dispatch(LOADING_START()); + const { data, status } = await axios.get( + "send_again_sms_for_final_approval_out_province/?key=" + d + ); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e.response.data.result }; + } + } +); diff --git a/src/features/province/services/province-free-sales-submit-buyer.js b/src/features/province/services/province-free-sales-submit-buyer.js new file mode 100644 index 0000000..48f0ea4 --- /dev/null +++ b/src/features/province/services/province-free-sales-submit-buyer.js @@ -0,0 +1,21 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const provinceFreeSalesSubmitBuyer = createAsyncThunk( + "PROVINCE_CREATE_FREE_SALE_BUYER", + async (d, { dispatch }) => { + try { + dispatch(LOADING_START()); + const { data, status } = await axios.post( + "out-province-poultry-request-buyers/", + d + ); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e.response.data.result }; + } + } +); diff --git a/src/features/province/services/province-get-active-requests.js b/src/features/province/services/province-get-active-requests.js new file mode 100644 index 0000000..950df9b --- /dev/null +++ b/src/features/province/services/province-get-active-requests.js @@ -0,0 +1,12 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; + +export const provinceGetActiveRequestsService = createAsyncThunk( + "PROVINCE_GET_ACTIVE_REQUESTS_SERVICE", + async () => { + const { data, status } = await axios.get("city_operator_check_request", { + params: { state: "all" }, + }); + return { data, status }; + } +); diff --git a/src/features/province/services/province-get-all-requests.js b/src/features/province/services/province-get-all-requests.js new file mode 100644 index 0000000..d674a4e --- /dev/null +++ b/src/features/province/services/province-get-all-requests.js @@ -0,0 +1,17 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import moment from "moment/moment"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const provinceGetAllRequests = createAsyncThunk( + "PROVINCE_GET_ACTIVE_REQUESTS", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + d = d || moment(new Date()).format("YYYY-MM-DD"); + const { data, status } = await axios.get("city_operator_check_request", { + params: { state: "waiting", date: d }, + }); + dispatch(LOADING_END()); + return { data, status }; + } +); diff --git a/src/features/province/services/province-get-allocated-requests.js b/src/features/province/services/province-get-allocated-requests.js new file mode 100644 index 0000000..db30b0a --- /dev/null +++ b/src/features/province/services/province-get-allocated-requests.js @@ -0,0 +1,47 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; +import { getRoleFromUrl } from "../../../utils/getRoleFromUrl"; +export const provinceGetAllocatedRequestsService = createAsyncThunk( + "PROVINCE_GET_ALLOCATED_REQUESTS_SERVICE", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + + const params = { + role: getRoleFromUrl(), + role_key: d.role_key || "", + date1: d.selectedDate1, + date2: d.selectedDate2, + filter: "search", + value: d.textValue, + }; + + if (d.hasDocumentState) { + params.allocated_car_state = true; + } else { + params.allocations = true; + } + + const { data, status } = await axios.get(`province_kill_request/`, { + params, + }); + + dispatch(LOADING_END()); + return { data, status }; + } +); + +export const provinceUpdateAllocatedRequestService = createAsyncThunk( + "PROVINCE_UPDATE_ALLOCATED_REQUEST_SERVICE", + async (d, { dispatch }) => { + try { + dispatch(LOADING_START()); + const { data, status } = await axios.put("province_kill_request/0/", d); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e.response.data.result }; + } + } +); diff --git a/src/features/province/services/province-get-allocation-letter-report.js b/src/features/province/services/province-get-allocation-letter-report.js new file mode 100644 index 0000000..4eb4ea3 --- /dev/null +++ b/src/features/province/services/province-get-allocation-letter-report.js @@ -0,0 +1,12 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; + +export const provinceGetAllocationLetterReport = createAsyncThunk( + "PROVINCE_GET_ALLOCATION_LETTER", + async (d, { dispatch }) => { + const { data, status } = await axios.get( + "province_request_letter/?date=" + d + ); + return { data, status }; + } +); diff --git a/src/features/province/services/province-get-allocation-letter.js b/src/features/province/services/province-get-allocation-letter.js new file mode 100644 index 0000000..cb1c188 --- /dev/null +++ b/src/features/province/services/province-get-allocation-letter.js @@ -0,0 +1,15 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const provinceGetAllocationLetter = createAsyncThunk( + "PROVINCE_GET_ALLOCATION_LETTER", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + const { data, status } = await axios.get( + "poultry_request_letter/?date=" + d + ); + dispatch(LOADING_END()); + return { data, status }; + } +); diff --git a/src/features/province/services/province-get-archive-auto-allocations.js b/src/features/province/services/province-get-archive-auto-allocations.js new file mode 100644 index 0000000..3b0331d --- /dev/null +++ b/src/features/province/services/province-get-archive-auto-allocations.js @@ -0,0 +1,24 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const provinceGetArchiveAutoAllocationsService = createAsyncThunk( + "PROVINCE_GET_ARCHIVE_AUTO_ALLOCATIONS_SERVICE", + async (d, { dispatch }) => { + try { + dispatch(LOADING_START()); + const { data, status } = await axios.get("automatic_allocation/", { + params: { + state: "final_registration", + date1: d.selectedDate1, + date2: d.selectedDate2, + }, + }); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e.response.data.result }; + } + } +); diff --git a/src/features/province/services/province-get-auto-allocations.js b/src/features/province/services/province-get-auto-allocations.js new file mode 100644 index 0000000..6f3851a --- /dev/null +++ b/src/features/province/services/province-get-auto-allocations.js @@ -0,0 +1,22 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const provinceGetAutoAllocationsService = createAsyncThunk( + "PROVINCE_GET_AUTO_ALLOCATIONS_SERVICE", + async (d, { dispatch }) => { + try { + dispatch(LOADING_START()); + const { data, status } = await axios.get("automatic_allocation/", { + params: { + state: "temporary", + }, + }); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e.response.data.result }; + } + } +); diff --git a/src/features/province/services/province-get-buyers.js b/src/features/province/services/province-get-buyers.js new file mode 100644 index 0000000..dec83ac --- /dev/null +++ b/src/features/province/services/province-get-buyers.js @@ -0,0 +1,18 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const provinceGetBuyersService = createAsyncThunk( + "PROVINCE_GET_BUYERS_SERVICE", + async (d, { dispatch }) => { + try { + dispatch(LOADING_START()); + const { data, status } = await axios.get("kill_house/", { params: d }); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e.response.data.result }; + } + } +); diff --git a/src/features/province/services/province-get-cars.js b/src/features/province/services/province-get-cars.js new file mode 100644 index 0000000..40bc2b8 --- /dev/null +++ b/src/features/province/services/province-get-cars.js @@ -0,0 +1,16 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { getRoleFromUrl } from "../../../utils/getRoleFromUrl"; + +export const provinceGetCars = createAsyncThunk( + "PROVINCE_GET_CARS", + async () => { + const { data, status } = await axios.get("kill_house_driver/", { + params: { + role: getRoleFromUrl(), + ...data, + }, + }); + return { data, status }; + } +); diff --git a/src/features/province/services/province-get-case-status.js b/src/features/province/services/province-get-case-status.js new file mode 100644 index 0000000..b149bd3 --- /dev/null +++ b/src/features/province/services/province-get-case-status.js @@ -0,0 +1,16 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; +import { getRoleFromUrl } from "../../../utils/getRoleFromUrl"; + +export const provinceGetCaseStatusService = createAsyncThunk( + "PROVINCE_GET_CASE_STATUS_SERVICE", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + const { data, status } = await axios.get("case_status/", { + params: { date: d, role: getRoleFromUrl() }, + }); + dispatch(LOADING_END()); + return { data, status }; + } +); diff --git a/src/features/province/services/province-get-cities.js b/src/features/province/services/province-get-cities.js new file mode 100644 index 0000000..0f85220 --- /dev/null +++ b/src/features/province/services/province-get-cities.js @@ -0,0 +1,10 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; + +export const provinceGetCitiesService = createAsyncThunk( + "PROVINCE_GET_CITIES_SERVICE", + async () => { + const { data, status } = await axios.get("province_cities/"); + return { data, status }; + } +); diff --git a/src/features/province/services/province-get-deleted-allocated-requests.js b/src/features/province/services/province-get-deleted-allocated-requests.js new file mode 100644 index 0000000..134204f --- /dev/null +++ b/src/features/province/services/province-get-deleted-allocated-requests.js @@ -0,0 +1,26 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; +import { getRoleFromUrl } from "../../../utils/getRoleFromUrl"; + +export const provinceGetDeletedAllocatedRequestsService = createAsyncThunk( + "PROVINCE_GET_DELETED_ALLOCATED_REQUESTS_SERVICE", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + const { data, status } = await axios.get( + `province_kill_request/?allocations&deleted_object`, + { + params: { + role: getRoleFromUrl(), + role_key: d.role_key || "", + date1: d.selectedDate1, + date2: d.selectedDate2, + filter: "search", + value: d.textValue, + }, + } + ); + dispatch(LOADING_END()); + return { data, status }; + } +); diff --git a/src/features/province/services/province-get-direct-buying-poultry-requests.js b/src/features/province/services/province-get-direct-buying-poultry-requests.js new file mode 100644 index 0000000..08abf7c --- /dev/null +++ b/src/features/province/services/province-get-direct-buying-poultry-requests.js @@ -0,0 +1,43 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; +import { getRoleFromUrl } from "../../../utils/getRoleFromUrl"; + +export const provinceGetDirectBuyingPoultryRequests = createAsyncThunk( + "PROVINCE_GET_DIRECT_BUYING_POULTRY_REQUESTS", + async (params, { dispatch }) => { + dispatch(LOADING_START()); + try { + const { + selectedBreeds = [], + selectedCities = [], + showRemaining = false, + minPrice = "", + maxPrice = "", + minAge = "", + maxAge = "", + textValue = "", + page = 1, + perPage = 20, + } = params || {}; + + const cityParams = + selectedCities.length > 0 ? `&city=${selectedCities.join(",")}` : ""; + const minPriceParam = minPrice ? `&min_amount=${minPrice}` : ""; + const maxPriceParam = maxPrice ? `&max_amount=${maxPrice}` : ""; + + const { data, status } = await axios.get( + `direct-buying-poultry-requests?breed=${selectedBreeds.join( + "," + )}${cityParams}&remain=${showRemaining}${minPriceParam}${maxPriceParam}&weight=&min_age=${minAge}&max_age=${maxAge}&role=${getRoleFromUrl()}&search=filter&value=${ + textValue || "" + }&page=${page}&page_size=${perPage}` + ); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e.response?.data?.result || e.message }; + } + } +); diff --git a/src/features/province/services/province-get-dispenser-killhouse-dashboard-service.js b/src/features/province/services/province-get-dispenser-killhouse-dashboard-service.js new file mode 100644 index 0000000..fc74ed6 --- /dev/null +++ b/src/features/province/services/province-get-dispenser-killhouse-dashboard-service.js @@ -0,0 +1,42 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; +import axios from "axios"; +import { getRoleFromUrl } from "../../../utils/getRoleFromUrl"; + +export const provinceGetDispenserKillhousesService = createAsyncThunk( + "PROVINCE_GET_DISPENSER_KILLHOUSES_SERVICE", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + const { data, status } = await axios.get( + `kill-house-warehouse-dashboard-for-province`, + { + params: { + role: getRoleFromUrl(), + date1: d.selectedDate1 ? d.selectedDate1 : null, + date2: d.selectedDate2 ? d.selectedDate2 : null, + }, + } + ); + dispatch(LOADING_END()); + return { data, status }; + } +); + +export const provinceGetDispenserKillhousesDashboardService = createAsyncThunk( + "PROVINCE_GET_DISPENSER_KILLHOUSES_DASHBOARD_SERVICE", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + const { data, status } = await axios.get( + `in-province-allocation-dashboard/`, + { + params: { + role: getRoleFromUrl(), + date1: d.selectedDate1 ? d.selectedDate1 : null, + date2: d.selectedDate2 ? d.selectedDate2 : null, + }, + } + ); + dispatch(LOADING_END()); + return { data, status }; + } +); diff --git a/src/features/province/services/province-get-dispenser-killhouses.js b/src/features/province/services/province-get-dispenser-killhouses.js new file mode 100644 index 0000000..07ee1ec --- /dev/null +++ b/src/features/province/services/province-get-dispenser-killhouses.js @@ -0,0 +1,42 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; +import { getRoleFromUrl } from "../../../utils/getRoleFromUrl"; + +export const provinceGetDispenserKillhousesService = createAsyncThunk( + "PROVINCE_GET_DISPENSER_KILLHOUSES_SERVICE", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + const { data, status } = await axios.get( + `kill-house-warehouse-dashboard-for-province`, + { + params: { + role: getRoleFromUrl(), + date1: d.selectedDate1 ? d.selectedDate1 : null, + date2: d.selectedDate2 ? d.selectedDate2 : null, + }, + } + ); + dispatch(LOADING_END()); + return { data, status }; + } +); + +export const provinceGetDispenserKillhousesDashboardService = createAsyncThunk( + "PROVINCE_GET_DISPENSER_KILLHOUSES_DASHBOARD_SERVICE", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + const { data, status } = await axios.get( + `total-kill-house-warehouse-dashboard-for-province`, + { + params: { + role: getRoleFromUrl(), + date1: d.selectedDate1 ? d.selectedDate1 : null, + date2: d.selectedDate2 ? d.selectedDate2 : null, + }, + } + ); + dispatch(LOADING_END()); + return { data, status }; + } +); diff --git a/src/features/province/services/province-get-driver-by-health-code.js b/src/features/province/services/province-get-driver-by-health-code.js new file mode 100644 index 0000000..25fc0c1 --- /dev/null +++ b/src/features/province/services/province-get-driver-by-health-code.js @@ -0,0 +1,12 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; + +export const provinceGetDriverByHealthCode = createAsyncThunk( + "PROVINCE_GET_DRIVER_BY_HEALTH_CODE", + async (id) => { + const { data, status } = await axios.get( + "kill_house_driver/?health_code=" + id + ); + return { data, status }; + } +); diff --git a/src/features/province/services/province-get-evacuation-permit.js b/src/features/province/services/province-get-evacuation-permit.js new file mode 100644 index 0000000..c1777b1 --- /dev/null +++ b/src/features/province/services/province-get-evacuation-permit.js @@ -0,0 +1,10 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; + +export const provinceGetEvacuationPermit = createAsyncThunk( + "PROVINCE_GET_EVACUATION_PERMIT", + async () => { + const { data, status } = await axios.get("evacuation_permit/"); + return { data, status }; + } +); diff --git a/src/features/province/services/province-get-files-state.js b/src/features/province/services/province-get-files-state.js new file mode 100644 index 0000000..50e0516 --- /dev/null +++ b/src/features/province/services/province-get-files-state.js @@ -0,0 +1,20 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; +import { getRoleFromUrl } from "../../../utils/getRoleFromUrl"; + +export const provinceGetFilesStateService = createAsyncThunk( + "PROVINCE_GET_FILES_STATE_SERVICE", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + const { data, status } = await axios.get("general_case_status", { + params: { + date1: d.date1, + date2: d.date2, + role: getRoleFromUrl(), + }, + }); + dispatch(LOADING_END()); + return { data, status }; + } +); diff --git a/src/features/province/services/province-get-free-sales-dashboard.js b/src/features/province/services/province-get-free-sales-dashboard.js new file mode 100644 index 0000000..123c0f2 --- /dev/null +++ b/src/features/province/services/province-get-free-sales-dashboard.js @@ -0,0 +1,25 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; +import { getRoleFromUrl } from "../../../utils/getRoleFromUrl"; + +export const provinceGetFreeSalesDashboardService = createAsyncThunk( + "GET_PROVINCE_FEE_SALES_DASHBOARD", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + const { data, status } = await axios.get( + "out-province-poultry-requests-dashboard", + { + params: { + date1: d.selectedDate1, + date2: d.selectedDate2, + search: "filter", + value: d.textValue, + role: getRoleFromUrl(), + }, + } + ); + dispatch(LOADING_END()); + return { data, status }; + } +); diff --git a/src/features/province/services/province-get-free-sales-requests.js b/src/features/province/services/province-get-free-sales-requests.js new file mode 100644 index 0000000..67b3a39 --- /dev/null +++ b/src/features/province/services/province-get-free-sales-requests.js @@ -0,0 +1,23 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import moment from "moment/moment"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; +import { getRoleFromUrl } from "../../../utils/getRoleFromUrl"; + +export const provinceGetFreeSalesRequestsService = createAsyncThunk( + "PROVINCE_GET_FREE_SALES_REQUESTS_SERVICE", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + d = d || moment(new Date()).format("YYYY-MM-DD"); + const { data, status } = await axios.get("out-province-poultry-requests", { + params: { + role: getRoleFromUrl(), + date1: d.selectedDate1, + date2: d.selectedDate2, + out: "", + }, + }); + dispatch(LOADING_END()); + return { data, status }; + } +); diff --git a/src/features/province/services/province-get-guilds-for-update-or-create.js b/src/features/province/services/province-get-guilds-for-update-or-create.js new file mode 100644 index 0000000..034cf5c --- /dev/null +++ b/src/features/province/services/province-get-guilds-for-update-or-create.js @@ -0,0 +1,41 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; +import { getRoleFromUrl } from "../../../utils/getRoleFromUrl"; + +export const provinceGetGuildsForUpdateOrCreateService = createAsyncThunk( + "PROVINCE_GET_GUILDS_FOR_UPDATE_OR_CREATE_SERVICE", + async (payload, { dispatch }) => { + dispatch(LOADING_START()); + try { + const { data, status } = await axios.get( + "get_guilds_for_update_or_create/", + { + params: { + national_code: payload.national_code, + update: payload.update || false, + role: getRoleFromUrl(), + }, + } + ); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + + if (e.response?.status === 403) { + const errorMessage = + e.response?.data?.result || + e.response?.data?.message || + "دسترسی غیرمجاز"; + return { error: errorMessage, status: 403 }; + } + + const errorMessage = + e.response?.data?.result || + e.response?.data?.message || + "خطا در دریافت اطلاعات"; + return { error: errorMessage }; + } + } +); diff --git a/src/features/province/services/province-get-guilds-numbers-names.js b/src/features/province/services/province-get-guilds-numbers-names.js new file mode 100644 index 0000000..de0d75c --- /dev/null +++ b/src/features/province/services/province-get-guilds-numbers-names.js @@ -0,0 +1,17 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import moment from "moment/moment"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const provinceGetGuildsNumbersNamesService = createAsyncThunk( + "PROVINCE_GET_GUILDS_NUMBERS_NAMES_SERVICE", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + d = d || moment(new Date()).format("YYYY-MM-DD"); + const { data, status } = await axios.get("guilds/", { + params: { type: "kill_house_percentage", percentage_key: d.key }, + }); + dispatch(LOADING_END()); + return { data, status }; + } +); diff --git a/src/features/province/services/province-get-guilds.js b/src/features/province/services/province-get-guilds.js new file mode 100644 index 0000000..ac17b47 --- /dev/null +++ b/src/features/province/services/province-get-guilds.js @@ -0,0 +1,21 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; +import { getRoleFromUrl } from "../../../utils/getRoleFromUrl"; + +export const provinceGetGuildsService = createAsyncThunk( + "PROVINCE_GET_GUILD_SERVICE", + async (d, { dispatch }) => { + try { + dispatch(LOADING_START()); + const { data, status } = await axios.get("guilds/", { + params: { role: getRoleFromUrl() }, + }); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e.response.data.result }; + } + } +); diff --git a/src/features/province/services/province-get-kill-houses.js b/src/features/province/services/province-get-kill-houses.js new file mode 100644 index 0000000..f5cf3ac --- /dev/null +++ b/src/features/province/services/province-get-kill-houses.js @@ -0,0 +1,12 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; + +export const provinceGetKillHouses = createAsyncThunk( + "PROVINCE_GET_KILLHOUSES", + async () => { + const { data, status } = await axios.get( + "kill_house/?role=ProvinceInspector" + ); + return { data, status }; + } +); diff --git a/src/features/province/services/province-get-killhouses-for-allocation.js b/src/features/province/services/province-get-killhouses-for-allocation.js new file mode 100644 index 0000000..7be8333 --- /dev/null +++ b/src/features/province/services/province-get-killhouses-for-allocation.js @@ -0,0 +1,10 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; + +export const provinceGetKillHousesForAllocation = createAsyncThunk( + "PROVINCE_GET_KILLHOUSES_FOR_ALLOCATION", + async () => { + const { data, status } = await axios.get("/kill_house/?kill_house=true"); + return { data, status }; + } +); diff --git a/src/features/province/services/province-get-killhouses-guilds.js b/src/features/province/services/province-get-killhouses-guilds.js new file mode 100644 index 0000000..d6387aa --- /dev/null +++ b/src/features/province/services/province-get-killhouses-guilds.js @@ -0,0 +1,18 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const provinceGetKillhousesGuildsService = createAsyncThunk( + "PROVINCE_GET_KILLHOUSES_GUILDS_SERVICE", + async (d, { dispatch }) => { + try { + dispatch(LOADING_START()); + const { data, status } = await axios.get("allow_register_guilds/"); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e.response.data.result }; + } + } +); diff --git a/src/features/province/services/province-get-killhouses.js b/src/features/province/services/province-get-killhouses.js new file mode 100644 index 0000000..cb99b96 --- /dev/null +++ b/src/features/province/services/province-get-killhouses.js @@ -0,0 +1,18 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const provinceGetKillhousesService = createAsyncThunk( + "PROVINCE_GET_KILLHOUSES_SERVICE", + async (d, { dispatch }) => { + try { + dispatch(LOADING_START()); + const { data, status } = await axios.get("allow_direct_buying/"); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e.response.data.result }; + } + } +); diff --git a/src/features/province/services/province-get-legal-person-unit-info.js b/src/features/province/services/province-get-legal-person-unit-info.js new file mode 100644 index 0000000..22cbb41 --- /dev/null +++ b/src/features/province/services/province-get-legal-person-unit-info.js @@ -0,0 +1,21 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const provinceGetLegalPersonUnitInfoService = createAsyncThunk( + "PROVINCE_GET_LEGAL_PERSON_UNIT_INFO_SERVICE", + async (nationalCode, { dispatch }) => { + try { + dispatch(LOADING_START()); + const { data, status } = await axios.get( + `get_legal_person_unit_info/?national_code=${nationalCode}` + ); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e.response?.data?.result || e.response?.data || "خطا در دریافت اطلاعات" }; + } + } +); + diff --git a/src/features/province/services/province-get-limitation.js b/src/features/province/services/province-get-limitation.js new file mode 100644 index 0000000..fa7e43c --- /dev/null +++ b/src/features/province/services/province-get-limitation.js @@ -0,0 +1,18 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const provinceGetLimitation = createAsyncThunk( + "PROVINCE_GET_LIMITATION", + async (d, { dispatch }) => { + try { + dispatch(LOADING_START()); + const { data, status } = await axios.get("operation-limitation/"); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e.response.data.result }; + } + } +); diff --git a/src/features/province/services/province-get-manage-users-roles.js b/src/features/province/services/province-get-manage-users-roles.js new file mode 100644 index 0000000..796bdf7 --- /dev/null +++ b/src/features/province/services/province-get-manage-users-roles.js @@ -0,0 +1,15 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const provinceGetManageUsersRolesService = createAsyncThunk( + "PROVINCE_GET_MANAGE_USERS_ROLES_SERVICE", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + const { data, status } = await axios.get("system_user_profile/", { + params: { all_users: true, userprofile_key: d.userProfileKey }, + }); + dispatch(LOADING_END()); + return { data, status }; + } +); diff --git a/src/features/province/services/province-get-manage-users.js b/src/features/province/services/province-get-manage-users.js new file mode 100644 index 0000000..015871f --- /dev/null +++ b/src/features/province/services/province-get-manage-users.js @@ -0,0 +1,15 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const provinceGetManageUsersService = createAsyncThunk( + "PROVINCE_GET_MANAGE_USERS_SERVICE", + async (_, { dispatch }) => { + dispatch(LOADING_START()); + const { data, status } = await axios.get("system_user_profile/", { + params: { users_base_info: true }, + }); + dispatch(LOADING_END()); + return { data, status }; + } +); diff --git a/src/features/province/services/province-get-mobile-messages.js b/src/features/province/services/province-get-mobile-messages.js new file mode 100644 index 0000000..da13951 --- /dev/null +++ b/src/features/province/services/province-get-mobile-messages.js @@ -0,0 +1,58 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const provinceUpdateMobileMessagesActiveService = createAsyncThunk( + "PROVINCE_UPDATE_MOBILE_MESSAGES_ACTIVE_SERVICE", + async (d, { dispatch }) => { + try { + dispatch(LOADING_START()); + const { data, status } = await axios.put("moving-text-with-role/0/", d); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e.response.data.result }; + } + } +); + +export const provinceUpdateMobileMessagesActiveTextService = createAsyncThunk( + "PROVINCE_UPDATE_MOBILE_MESSAGES_ACTIVE_TEXT_SERVICE", + async (d, { dispatch }) => { + try { + dispatch(LOADING_START()); + const { data, status } = await axios.put("moving-text/0/", d); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e.response.data.result }; + } + } +); + +export const provinceSubmitNewMovingText = createAsyncThunk( + "PROVINCE_UPDATE_SUBMIT_MOVING_TEXT", + async (d, { dispatch }) => { + try { + dispatch(LOADING_START()); + const { data, status } = await axios.post("moving-text/", d); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e.response.data.result }; + } + } +); + +export const provinceDeleteMovingTextService = createAsyncThunk( + "PROVINCE_DELETE_MOVING_TEXT", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + const { data, status } = await axios.delete("moving-text/" + d + "/"); + dispatch(LOADING_END()); + return { data, status }; + } +); diff --git a/src/features/province/services/province-get-national-documents.js b/src/features/province/services/province-get-national-documents.js new file mode 100644 index 0000000..d87fca1 --- /dev/null +++ b/src/features/province/services/province-get-national-documents.js @@ -0,0 +1,53 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; +import { showSnackbar } from "../../../utils/showSnackbar"; + +export const provinceGetNationalDocumentsService = createAsyncThunk( + "PROVINCE_GET_NATIONAL_DOCUMENTS_SERVICE", + async (payload, { dispatch }) => { + dispatch(LOADING_START()); + try { + const { data, status } = await axios.get( + `https://pay.rasadyar.com/national-documents?info=${payload.info}&type=${payload.type}`, + { + timeout: 30000, + } + ); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + + if (e.code === "ECONNABORTED" || e.message.includes("timeout")) { + showSnackbar( + "زمان درخواست به پایان رسید. لطفا دوباره تلاش کنید.", + "error" + ); + return { + error: "زمان درخواست به پایان رسید. لطفا دوباره تلاش کنید.", + }; + } + + if (e.response?.status === 500) { + showSnackbar("خطای سرور رخ داده است. لطفا بعدا تلاش کنید.", "error"); + return { error: "خطای سرور رخ داده است. لطفا بعدا تلاش کنید." }; + } + + if (!e.response) { + showSnackbar( + "خطا در برقراری ارتباط با سرور. لطفا اتصال اینترنت خود را بررسی کنید.", + "error" + ); + return { + error: + "خطا در برقراری ارتباط با سرور. لطفا اتصال اینترنت خود را بررسی کنید.", + }; + } + + const errorMessage = e.response?.data?.result || "خطا در دریافت اطلاعات"; + showSnackbar(errorMessage, "error"); + return { error: errorMessage }; + } + } +); diff --git a/src/features/province/services/province-get-only-kill-houses.js b/src/features/province/services/province-get-only-kill-houses.js new file mode 100644 index 0000000..3446248 --- /dev/null +++ b/src/features/province/services/province-get-only-kill-houses.js @@ -0,0 +1,10 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; + +export const provinceGetOnlyKillHousesService = createAsyncThunk( + "PROVINCE_GET_ONLY_KILLHOUSES_SERVICE", + async (d) => { + const { data, status } = await axios.get(`kill_house/?${d}`); + return { data, status }; + } +); diff --git a/src/features/province/services/province-get-payment-by-weight-overview.js b/src/features/province/services/province-get-payment-by-weight-overview.js new file mode 100644 index 0000000..fc49f77 --- /dev/null +++ b/src/features/province/services/province-get-payment-by-weight-overview.js @@ -0,0 +1,28 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; +import { getRoleFromUrl } from "../../../utils/getRoleFromUrl"; + +export const provinceGetPaymentByWeightOverview = createAsyncThunk( + "PROVINCE_GET_PAYMENT_BY_WEIGHT_OVERVIREW", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + const { data, status } = await axios.get(`total-wage-information/`, { + params: { ...d }, + }); + dispatch(LOADING_END()); + return { data, status }; + } +); + +export const parentConpanyGetPaymentByWeightOverview = createAsyncThunk( + "PARENT_COMPANY_GET_PAYMENT_BY_WEIGHT_OVERVIREW", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + const { data, status } = await axios.get( + d + `parent-company-total-wage-information/?role=${getRoleFromUrl()}` + ); + dispatch(LOADING_END()); + return { data, status }; + } +); diff --git a/src/features/province/services/province-get-policy-aviculture-commit.js b/src/features/province/services/province-get-policy-aviculture-commit.js new file mode 100644 index 0000000..6796c99 --- /dev/null +++ b/src/features/province/services/province-get-policy-aviculture-commit.js @@ -0,0 +1,13 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const provinceGetPolicyAvicultureCommitService = createAsyncThunk( + "PROVINCE_GET_POLICY_AVICULTURE_COMMIT_SERVICE", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + const { data, status } = await axios.get("free_sale_within_province/"); + dispatch(LOADING_END()); + return { data, status }; + } +); diff --git a/src/features/province/services/province-get-policy-poultry-choose-kill-house.js b/src/features/province/services/province-get-policy-poultry-choose-kill-house.js new file mode 100644 index 0000000..da499eb --- /dev/null +++ b/src/features/province/services/province-get-policy-poultry-choose-kill-house.js @@ -0,0 +1,20 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const provinceGetPolicyPoultryChooseKillHouseService = createAsyncThunk( + "PROVINCE_GET_POLICY_POULTRY_CHOOSE_KILL_HOUSE_SERVICE", + async (d, { dispatch }) => { + try { + dispatch(LOADING_START()); + const { data, status } = await axios.get( + "province_allow_poultry_choose_kill_house_total/" + ); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e.response.data.result }; + } + } +); diff --git a/src/features/province/services/province-get-poultries.js b/src/features/province/services/province-get-poultries.js new file mode 100644 index 0000000..1f8461e --- /dev/null +++ b/src/features/province/services/province-get-poultries.js @@ -0,0 +1,18 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const provinceGetPoultriesService = createAsyncThunk( + "PROVINCE_GET_POULTRIES_SERVICE", + async (d, { dispatch }) => { + try { + dispatch(LOADING_START()); + const { data, status } = await axios.get("Poultry/?all"); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e.response.data.result }; + } + } +); diff --git a/src/features/province/services/province-get-poultry-active-limited.js b/src/features/province/services/province-get-poultry-active-limited.js new file mode 100644 index 0000000..1d9f2ad --- /dev/null +++ b/src/features/province/services/province-get-poultry-active-limited.js @@ -0,0 +1,18 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; +import axios from "axios"; + +export const getPoultryActiveLimitedService = createAsyncThunk( + "GET_POULTRY_ACTIVE_LIMITED_SERVICE", + async (d, { dispatch }) => { + try { + dispatch(LOADING_START()); + const { data, status } = await axios.put("/Poultry/0/", d); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e.response.data.result }; + } + } +); diff --git a/src/features/province/services/province-get-pricing.js b/src/features/province/services/province-get-pricing.js new file mode 100644 index 0000000..0e7e8ee --- /dev/null +++ b/src/features/province/services/province-get-pricing.js @@ -0,0 +1,10 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; + +export const provinceGetPricing = createAsyncThunk( + "PROVINCE_GET_PRICING", + async () => { + const { data, status } = await axios.get("chicken-commission-prices/"); + return { data, status }; + } +); diff --git a/src/features/province/services/province-get-producrs.js b/src/features/province/services/province-get-producrs.js new file mode 100644 index 0000000..537c0ad --- /dev/null +++ b/src/features/province/services/province-get-producrs.js @@ -0,0 +1,10 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; + +export const provinceGetProducts = createAsyncThunk( + "PROVINCE_GET_PRODUCTS", + async () => { + const { data, status } = await axios.get("additional-products/"); + return { data, status }; + } +); diff --git a/src/features/province/services/province-get-profile.js b/src/features/province/services/province-get-profile.js new file mode 100644 index 0000000..48984da --- /dev/null +++ b/src/features/province/services/province-get-profile.js @@ -0,0 +1,10 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; + +export const provinceGetProfile = createAsyncThunk( + "PROVINCE_GET_PROFILE", + async () => { + const { data, status } = await axios.get("province_operator/0/?profile"); + return { data, status }; + } +); diff --git a/src/features/province/services/province-get-province-and-city.js b/src/features/province/services/province-get-province-and-city.js new file mode 100644 index 0000000..1d089c8 --- /dev/null +++ b/src/features/province/services/province-get-province-and-city.js @@ -0,0 +1,33 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const provinceGetProvincesService = createAsyncThunk( + "PROVINCE_GET_PROVINCES_SERVICE", + async (d, { dispatch }) => { + try { + dispatch(LOADING_START()); + const { data, status } = await axios.get("iran_province/"); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e.response.data.result }; + } + } +); + +export const provinceGetCitiesService = createAsyncThunk( + "PROVINCE_GET_CITIES_SERVICE", + async (d, { dispatch }) => { + try { + dispatch(LOADING_START()); + const { data, status } = await axios.get("iran_city/?province_id=" + d); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e.response.data.result }; + } + } +); diff --git a/src/features/province/services/province-get-quarantine-letter.js b/src/features/province/services/province-get-quarantine-letter.js new file mode 100644 index 0000000..5273448 --- /dev/null +++ b/src/features/province/services/province-get-quarantine-letter.js @@ -0,0 +1,15 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const provinceGetQuarantineLetter = createAsyncThunk( + "PROVINCE_GET_VETERINARY_LETTER", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + const { data, status } = await axios.get( + "poultry_request_letter/?order_code=" + d + ); + dispatch(LOADING_END()); + return { data, status }; + } +); diff --git a/src/features/province/services/province-get-register-code-state.js b/src/features/province/services/province-get-register-code-state.js new file mode 100644 index 0000000..dc7cfb5 --- /dev/null +++ b/src/features/province/services/province-get-register-code-state.js @@ -0,0 +1,31 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const provinceGetRegisterCodeStateService = createAsyncThunk( + "PROVINCE_GET_REGISTER_CODE_SERVICE", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + const { data, status } = await axios.get("allow_register_code_for_guilds"); + dispatch(LOADING_END()); + return { data, status }; + } +); + +export const provinceResendRegisterCodeStateService = createAsyncThunk( + "PROVINCE_RESEND_REGISTER_CODE_SERVICE", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + try { + const { data, status } = await axios.post( + "send_again_sms_for_register_code_guild/", + d + ); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e.response.data.result }; + } + } +); diff --git a/src/features/province/services/province-get-rejected-requests.js b/src/features/province/services/province-get-rejected-requests.js new file mode 100644 index 0000000..d84ae58 --- /dev/null +++ b/src/features/province/services/province-get-rejected-requests.js @@ -0,0 +1,10 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; + +export const provinceGetRejectedRequests = createAsyncThunk( + "PROVINCE_GET_REJECTED_REQUESTS", + async () => { + const { data, status } = await axios.get("rejected_requests"); + return { data, status }; + } +); diff --git a/src/features/province/services/province-get-report-process.js b/src/features/province/services/province-get-report-process.js new file mode 100644 index 0000000..cfd40b0 --- /dev/null +++ b/src/features/province/services/province-get-report-process.js @@ -0,0 +1,20 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const provinceGetProcessData = createAsyncThunk( + "PROVINCE_GET_REPORT_PROCESS", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + try { + const { data, status } = await axios.get( + `general_poultry_request_letter_report/?date=${d.selectedDate1}&type=${d.value}` + ); + dispatch(LOADING_END()); + return { data, status }; + } catch (error) { + dispatch(LOADING_END()); + throw error; + } + } +); diff --git a/src/features/province/services/province-get-sell-for-freezing-status.js b/src/features/province/services/province-get-sell-for-freezing-status.js new file mode 100644 index 0000000..db8deb7 --- /dev/null +++ b/src/features/province/services/province-get-sell-for-freezing-status.js @@ -0,0 +1,18 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const provinceGetSellForFreezingStatus = createAsyncThunk( + "PROVINCE_GET_SELL_FOR_FREEZING_STATUS", + async (d, { dispatch }) => { + try { + dispatch(LOADING_START()); + const { data, status } = await axios.get("sell-for-freezing/"); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e.response.data.result }; + } + } +); diff --git a/src/features/province/services/province-get-slaughter-letter.js b/src/features/province/services/province-get-slaughter-letter.js new file mode 100644 index 0000000..6aece86 --- /dev/null +++ b/src/features/province/services/province-get-slaughter-letter.js @@ -0,0 +1,15 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const provinceGetSlaughterLetter = createAsyncThunk( + "PROVINCE_GET_SLAUGHTER_LETTER", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + const { data, status } = await axios.get( + "poultry_request_letter_order_code/?date=" + d + ); + dispatch(LOADING_END()); + return { data, status }; + } +); diff --git a/src/features/province/services/province-get-slaughter-surverillance-service.js b/src/features/province/services/province-get-slaughter-surverillance-service.js new file mode 100644 index 0000000..d2b1017 --- /dev/null +++ b/src/features/province/services/province-get-slaughter-surverillance-service.js @@ -0,0 +1,20 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; +export const provinceGetSlaughterSurveillanceService = createAsyncThunk( + "PROVINCE_GET_SLAUGHTER_SERVEILLANCE", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + const { data, status } = await axios.get( + "comprehensive_report_of_slaughterhouse", + { + params: { + date1: d.selectedDate1, + date2: d.selectedDate2, + }, + } + ); + dispatch(LOADING_END()); + return { data, status }; + } +); diff --git a/src/features/province/services/province-get-slaughterhouses-quota.js b/src/features/province/services/province-get-slaughterhouses-quota.js new file mode 100644 index 0000000..0c46b80 --- /dev/null +++ b/src/features/province/services/province-get-slaughterhouses-quota.js @@ -0,0 +1,20 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const provinceGetSlaughterhousesQuotaService = createAsyncThunk( + "PROVINCE_GET_SLAUGHTERHOUSES_QUOTA_SERVICE", + async (d, { dispatch }) => { + try { + dispatch(LOADING_START()); + const { data, status } = await axios.get("kill_house_percent/", { + params: d, + }); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e.response.data.result }; + } + } +); diff --git a/src/features/province/services/province-get-sms-license.js b/src/features/province/services/province-get-sms-license.js new file mode 100644 index 0000000..fa2e578 --- /dev/null +++ b/src/features/province/services/province-get-sms-license.js @@ -0,0 +1,18 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const provinceGetSmsLincenseService = createAsyncThunk( + "PROVINCE_GET_SMS_LINCENSE_SERVICE", + async (d, { dispatch }) => { + try { + dispatch(LOADING_START()); + const { data, status } = await axios.get("sms_license/"); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e.response.data }; + } + } +); diff --git a/src/features/province/services/province-get-stewards.js b/src/features/province/services/province-get-stewards.js new file mode 100644 index 0000000..9c73ef1 --- /dev/null +++ b/src/features/province/services/province-get-stewards.js @@ -0,0 +1,24 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; +import { getRoleFromUrl } from "../../../utils/getRoleFromUrl"; + +export const provinceGetStewardsService = createAsyncThunk( + "PROVINCE_GET_STEWARDS_SERVICE", + async (d, { dispatch }) => { + try { + dispatch(LOADING_START()); + const { data, status } = await axios.get("steward/", { + params: { + ...d, + role: getRoleFromUrl(), + }, + }); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e.response.data.result }; + } + } +); diff --git a/src/features/province/services/province-get-total-guilds.js b/src/features/province/services/province-get-total-guilds.js new file mode 100644 index 0000000..41d9b0c --- /dev/null +++ b/src/features/province/services/province-get-total-guilds.js @@ -0,0 +1,48 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; +import { getRoleFromUrl } from "../../../utils/getRoleFromUrl"; + +export const provinceGetTotalGuildsService = createAsyncThunk( + "PROVINCE_GET_TOTAL_GUILDS_SERVICE", + async ( + { + search = "filter", + value = "", + page = 1, + page_size = 10, + steward = false, + active_state = "active", + is_real_person = true, + role_key = "", + }, + { dispatch } + ) => { + try { + dispatch(LOADING_START()); + const { data, status } = await axios.get("total_guilds/", { + params: { + search, + value, + role: getRoleFromUrl(), + page, + page_size, + steward, + active_state, + is_real_person, + role_key: role_key, + }, + }); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { + error: + e.response?.data?.result || + e.response?.data || + "خطا در دریافت اطلاعات", + }; + } + } +); diff --git a/src/features/province/services/province-get-total-killhouse-remain-weight.js b/src/features/province/services/province-get-total-killhouse-remain-weight.js new file mode 100644 index 0000000..ef9d04f --- /dev/null +++ b/src/features/province/services/province-get-total-killhouse-remain-weight.js @@ -0,0 +1,89 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const provinceGetTotalKillhouseRemainWeight = createAsyncThunk( + "PROVINCE_GET_TOTAL_KILLHOUSE_REMAIN_WEIGHT", + async (params, { dispatch }) => { + try { + dispatch(LOADING_START()); + + const pathname = + typeof window !== "undefined" ? window.location.pathname : ""; + const isStewardPage = + pathname?.split("/").filter(Boolean).pop() === "steward"; + + const endpoint = isStewardPage + ? "total-steward-remain-weight/" + : "total-kill-house-remain-weight/"; + + const requestParams = { + search: params?.search ?? "filter", + value: params?.value ?? "", + page: params?.page ?? 1, + page_size: params?.page_size ?? (isStewardPage ? 40 : 10), + quota: params?.quota ?? false, + }; + + if (params?.date1) { + requestParams.date1 = params.date1; + } + + if (params?.date2) { + requestParams.date2 = params.date2; + } + + if (isStewardPage) { + requestParams.owner_type = params?.owner_type ?? "steward"; + } else { + requestParams.role = params?.role ?? "SuperAdmin"; + } + + const { data, status } = await axios.get(endpoint, { + params: requestParams, + }); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e.response?.data?.result || "خطا در دریافت اطلاعات" }; + } + } +); + +export const provinceGetTotalKillhouseArchiveDashboard = createAsyncThunk( + "PROVINCE_GET_TOTAL_KILLHOUSE_ARCHIVE_DASHBOARD", + async (params, { dispatch }) => { + try { + dispatch(LOADING_START()); + const isSteward = params?.owner_type === "steward"; + const endpoint = isSteward + ? "total-guild-steward-archive-dashboard/" + : "total-kill-house-archive-dashboard/"; + + const requestParams = { + search: params?.search ?? "filter", + value: params?.value ?? "", + date1: params?.date1, + date2: params?.date2, + page: params?.page ?? 1, + page_size: params?.page_size ?? 10, + }; + + if (isSteward) { + requestParams.owner_type = params.owner_type ?? "steward"; + } else { + requestParams.role = params?.role ?? "SuperAdmin"; + } + + const { data, status } = await axios.get(endpoint, { + params: requestParams, + }); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e.response?.data?.result || "خطا در دریافت اطلاعات" }; + } + } +); diff --git a/src/features/province/services/province-get-total-report-agent-share.js b/src/features/province/services/province-get-total-report-agent-share.js new file mode 100644 index 0000000..b04792e --- /dev/null +++ b/src/features/province/services/province-get-total-report-agent-share.js @@ -0,0 +1,21 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const provinceGetTotalReportAgentShareService = createAsyncThunk( + "PROVINCE_GET_TOTAL_REPORT_AGENT_SHARE_SERVICE", + async (d, { dispatch }) => { + try { + dispatch(LOADING_START()); + const { data, status } = await axios.get( + "kill_house_total_report_province_kill_requests/", + { params: d } + ); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e.response.data.result }; + } + } +); diff --git a/src/features/province/services/province-get-user-by-key.js b/src/features/province/services/province-get-user-by-key.js new file mode 100644 index 0000000..5e5a2d3 --- /dev/null +++ b/src/features/province/services/province-get-user-by-key.js @@ -0,0 +1,12 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; + +export const provinceGetUserByKey = createAsyncThunk( + "PROVINCE_CHECK_USER_EXISTENCE", + async (d) => { + const { data, status } = await axios.get( + "system_user_profile/0/?userprofile_key=" + d + ); + return { data, status }; + } +); diff --git a/src/features/province/services/province-get-user-profiles.js b/src/features/province/services/province-get-user-profiles.js new file mode 100644 index 0000000..8e06c7c --- /dev/null +++ b/src/features/province/services/province-get-user-profiles.js @@ -0,0 +1,10 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; + +export const provinceGetUserProfiles = createAsyncThunk( + "PROVINCE_GET_USER_PROFILES", + async () => { + const { data, status } = await axios.get("system_user_profile/?users_info"); + return { data, status }; + } +); diff --git a/src/features/province/services/province-get-users-by-roles.js b/src/features/province/services/province-get-users-by-roles.js new file mode 100644 index 0000000..908af8d --- /dev/null +++ b/src/features/province/services/province-get-users-by-roles.js @@ -0,0 +1,20 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const provinceGetUsersByRolesService = createAsyncThunk( + "PROVINCE_GET_USERS_BY_ROLES_SERVICE", + async (d, { dispatch }) => { + try { + dispatch(LOADING_START()); + const { data, status } = await axios.get("diageram", { + params: d, + }); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e.response.data }; + } + } +); diff --git a/src/features/province/services/province-get-users.js b/src/features/province/services/province-get-users.js new file mode 100644 index 0000000..7016bc6 --- /dev/null +++ b/src/features/province/services/province-get-users.js @@ -0,0 +1,10 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; + +export const provinceGetUsers = createAsyncThunk( + "PROVINCE_GET_USERS", + async () => { + const { data, status } = await axios.get("rejected_requests"); + return { data, status }; + } +); diff --git a/src/features/province/services/province-get-wages-of-killhouses.js b/src/features/province/services/province-get-wages-of-killhouses.js new file mode 100644 index 0000000..066faec --- /dev/null +++ b/src/features/province/services/province-get-wages-of-killhouses.js @@ -0,0 +1,29 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const provinceGetWagesOfKillhousesService = createAsyncThunk( + "PROVINCE_GET_VETERINARY_LETTER", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + const { data, status } = await axios.get("kill-house-new-wage/", { + params: { + ...d, + }, + }); + dispatch(LOADING_END()); + return { data, status }; + } +); + +export const parentCompanyGetWagesOfKillhousesService = createAsyncThunk( + "PARENT_COMPANY_GET_VETERINARY_LETTER", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + const { data, status } = await axios.get( + d + "parent-company-kill-house-new-wage/" + ); + dispatch(LOADING_END()); + return { data, status }; + } +); diff --git a/src/features/province/services/province-hatching-archive-percent.js b/src/features/province/services/province-hatching-archive-percent.js new file mode 100644 index 0000000..384d35e --- /dev/null +++ b/src/features/province/services/province-hatching-archive-percent.js @@ -0,0 +1,34 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const provinceGetHatchingArchivePercent = createAsyncThunk( + "PROVINCE_GET_HATCHING_ARCHIVE_PERCENT", + async (d, { dispatch }) => { + try { + dispatch(LOADING_START()); + const { data, status } = await axios.get("/hatching-archive-percent/"); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e.response.data.result }; + } + } +); + +export const provinceEditHatchingArchivePercent = createAsyncThunk( + "PROVINCE_EDIT_HATCHING_ARCHIVE_PERCENT", + async (d, { dispatch }) => { + try { + dispatch(LOADING_START()); + const { data, status } = await axios.put("/hatching-archive-percent/0/", d); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e.response.data.result }; + } + } +); + diff --git a/src/features/province/services/province-killhouses-paid-fee-change-payment-type-service.js b/src/features/province/services/province-killhouses-paid-fee-change-payment-type-service.js new file mode 100644 index 0000000..9410741 --- /dev/null +++ b/src/features/province/services/province-killhouses-paid-fee-change-payment-type-service.js @@ -0,0 +1,16 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const provinceKillhousesPaidFeesChangePaymentTypeService = + createAsyncThunk("PROVINCE_EDIT_CAR_SERVICE", async (d, { dispatch }) => { + try { + dispatch(LOADING_START()); + const { data, status } = await axios.put("internal-transactions/0/", d); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e.response.data.result }; + } + }); diff --git a/src/features/province/services/province-make-kill-request-for-poultry.js b/src/features/province/services/province-make-kill-request-for-poultry.js new file mode 100644 index 0000000..a0384fb --- /dev/null +++ b/src/features/province/services/province-make-kill-request-for-poultry.js @@ -0,0 +1,18 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const provinceMakeKillRequestForPoultryService = createAsyncThunk( + "PROVINCE_MAKE_KILL_REQUEST_FOR_POULTRY_SERVICE", + async (d, { dispatch }) => { + try { + dispatch(LOADING_START()); + const { data, status } = await axios.post("make_kill_request/"); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e.response.data }; + } + } +); diff --git a/src/features/province/services/province-manage-guilds-trades-edit-percents.js b/src/features/province/services/province-manage-guilds-trades-edit-percents.js new file mode 100644 index 0000000..f5cc94e --- /dev/null +++ b/src/features/province/services/province-manage-guilds-trades-edit-percents.js @@ -0,0 +1,49 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const provinceManageGuildTradesEditPercents = createAsyncThunk( + "PROVINCE_MANAGE_GUILD_TRADES_EDIT_PERCENTS", + async (d, { dispatch }) => { + try { + dispatch(LOADING_START()); + const { data, status } = await axios.put("guilds-for-configs/0/", d); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e.response.data.result }; + } + } +); +export const provinceManageGuildTradesEditAllPercents = createAsyncThunk( + "PROVINCE_MANAGE_GUILD_TRADES_EDIT_ALL_PERCENTS", + async (d, { dispatch }) => { + try { + dispatch(LOADING_START()); + const { data, status } = await axios.put("guilds-configs/0/", d); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e.response.data.result }; + } + } +); + +export const provinceManageGuildTradesGetPercents = createAsyncThunk( + "PROVINCE_MANAGE_GUILD_TRADES_GET_PERCENTS", + async (d, { dispatch }) => { + try { + dispatch(LOADING_START()); + const { data, status } = await axios.get("guilds-configs", { + params: d, + }); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e.response.data }; + } + } +); diff --git a/src/features/province/services/province-manage-slaughter-request-dashboard.js b/src/features/province/services/province-manage-slaughter-request-dashboard.js new file mode 100644 index 0000000..35f82fe --- /dev/null +++ b/src/features/province/services/province-manage-slaughter-request-dashboard.js @@ -0,0 +1,22 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { getRoleFromUrl } from "../../../utils/getRoleFromUrl"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const provinceManageSlaughterRequestDashboard = createAsyncThunk( + "PROVINCE_SLAUGHTER_REQUEST_DASHBOARD", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + const { data, status } = await axios.get(`dashboard_kill_request`, { + params: { + date1: d.selectedDate1, + date2: d.selectedDate2, + role: getRoleFromUrl(), + // search: "filter", + // value: d.text ? d.text : "", + }, + }); + dispatch(LOADING_END()); + return { data, status }; + } +); diff --git a/src/features/province/services/province-manage-trades-edit-percents.js b/src/features/province/services/province-manage-trades-edit-percents.js new file mode 100644 index 0000000..78d63cf --- /dev/null +++ b/src/features/province/services/province-manage-trades-edit-percents.js @@ -0,0 +1,18 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const provinceManageTradesEditPercents = createAsyncThunk( + "PROVINCE_MANAGE_TRADES_EDIT_PERCENTS", + async (d, { dispatch }) => { + try { + dispatch(LOADING_START()); + const { data, status } = await axios.put("market-kill-houses/0/", d); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e.response.data.result }; + } + } +); diff --git a/src/features/province/services/province-management-send-sms.js b/src/features/province/services/province-management-send-sms.js new file mode 100644 index 0000000..0b2161b --- /dev/null +++ b/src/features/province/services/province-management-send-sms.js @@ -0,0 +1,22 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const managementSendSms = createAsyncThunk( + "MANAGEMENT_SEND_SMS", + async (d, { dispatch }) => { + try { + dispatch(LOADING_START()); + const { id, ...rest } = d; + const { data, status } = await axios.put( + `management-send-sms/${id}/`, + rest + ); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e.response?.data?.result || "خطا در ارسال پیامک" }; + } + } +); diff --git a/src/features/province/services/province-market-request-final-accept.js b/src/features/province/services/province-market-request-final-accept.js new file mode 100644 index 0000000..425f6b6 --- /dev/null +++ b/src/features/province/services/province-market-request-final-accept.js @@ -0,0 +1,18 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const ProvinceMarketRequestFinalAcceptService = createAsyncThunk( + "PROVINCE_MARKET_REQUEST_FINAL_ACCEPT_SERVICE", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + try { + const { data, status } = await axios.put("market-requests/0/", d); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e.response.data.result }; + } + } +); diff --git a/src/features/province/services/province-national-info-farm-management-info-dashboard-service.js b/src/features/province/services/province-national-info-farm-management-info-dashboard-service.js new file mode 100644 index 0000000..896f28c --- /dev/null +++ b/src/features/province/services/province-national-info-farm-management-info-dashboard-service.js @@ -0,0 +1,24 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; +import { getRoleFromUrl } from "../../../utils/getRoleFromUrl"; + +export const provinceNationalFarmManagementInfoDashboardService = + createAsyncThunk( + "PROVINCE_NATIONAL_GET_FARM_INFO_DASHBOARD_SERVICE", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + const { data, status } = await axios.get( + "https://rsibackend.rasadyar.com/app/poultry-dashboard/", + { + params: { + role: getRoleFromUrl(), + search: d.search, + province: d.province, + }, + } + ); + dispatch(LOADING_END()); + return { data, status }; + } + ); diff --git a/src/features/province/services/province-national-transport-managemant-info-dashboard-service.js b/src/features/province/services/province-national-transport-managemant-info-dashboard-service.js new file mode 100644 index 0000000..94394e3 --- /dev/null +++ b/src/features/province/services/province-national-transport-managemant-info-dashboard-service.js @@ -0,0 +1,28 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; +import { getRoleFromUrl } from "../../../utils/getRoleFromUrl"; + +export const provinceNationalTransportManagementInfoDashboardService = + createAsyncThunk( + "PROVINCE_NATIONAL_GET_TRANSPORT_INFO_DASHBOARD_SERVICE", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + const { data, status } = await axios.get( + "https://rsibackend.rasadyar.com/app/transporting-dashboard", + { + params: { + role: getRoleFromUrl(), + search: d.search, + value: d.search, + province: d.province, + PartIdCode: d.PartIdCode, + date1: d.date1, + date2: d.date2, + }, + } + ); + dispatch(LOADING_END()); + return { data, status }; + } + ); diff --git a/src/features/province/services/province-need-request-form.js b/src/features/province/services/province-need-request-form.js new file mode 100644 index 0000000..32ece2b --- /dev/null +++ b/src/features/province/services/province-need-request-form.js @@ -0,0 +1,21 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const provinceNeedRequestFormService = createAsyncThunk( + "PROVINCE_NEED_REQUEST_FORM_SERVICE", + async (d, { dispatch }) => { + try { + dispatch(LOADING_START()); + const { data, status } = await axios.post( + "province_check_kill_request/", + d + ); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e.response.data }; + } + } +); diff --git a/src/features/province/services/province-new-pricing.js b/src/features/province/services/province-new-pricing.js new file mode 100644 index 0000000..654928b --- /dev/null +++ b/src/features/province/services/province-new-pricing.js @@ -0,0 +1,10 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; + +export const provinceNewPricing = createAsyncThunk( + "PROVINCE_NEW_PRICING", + async (d) => { + const { data, status } = await axios.post("pricing/", d); + return { data, status }; + } +); diff --git a/src/features/province/services/province-out-province-buyers.js b/src/features/province/services/province-out-province-buyers.js new file mode 100644 index 0000000..0a101c2 --- /dev/null +++ b/src/features/province/services/province-out-province-buyers.js @@ -0,0 +1,44 @@ +import axios from "axios"; + +/** + * Fetch out-province carcass buyers (real persons - حقیقی) + * @param {Object} params - Query parameters + * @param {string} params.role - User role + * @param {number} params.page - Page number + * @param {number} params.pageSize - Items per page + * @param {string} params.searchValue - Search value + * @returns {Promise} Axios promise with buyers data + */ +export const fetchOutProvinceRealBuyers = async ({ + role, + page, + pageSize, + searchValue = "", +}) => { + const response = await axios.get( + `out-province-carcasses-buyer/?search=filter&value=${searchValue}&role=${role}&page=${page}&page_size=${pageSize}&state=buyer-list&type=real` + ); + return response; +}; + +/** + * Fetch out-province carcass buyers (legal entities - حقوقی) + * @param {Object} params - Query parameters + * @param {string} params.role - User role + * @param {number} params.page - Page number + * @param {number} params.pageSize - Items per page + * @param {string} params.searchValue - Search value + * @returns {Promise} Axios promise with buyers data + */ +export const fetchOutProvinceLegalBuyers = async ({ + role, + page, + pageSize, + searchValue = "", +}) => { + const response = await axios.get( + `out-province-carcasses-buyer/?search=filter&value=${searchValue}&role=${role}&page=${page}&page_size=${pageSize}&state=buyer-list&type=legal` + ); + return response; +}; + diff --git a/src/features/province/services/province-paid-fees-edit-description.js b/src/features/province/services/province-paid-fees-edit-description.js new file mode 100644 index 0000000..7d97bf3 --- /dev/null +++ b/src/features/province/services/province-paid-fees-edit-description.js @@ -0,0 +1,13 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const provincePaidFeesEditDescription = createAsyncThunk( + "PROVINCE_PAID_FEES_EDIT_DESCRIPTION", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + const { data, status } = await axios.put("internal-transactions/0/", d); + dispatch(LOADING_END()); + return { data, status }; + } +); diff --git a/src/features/province/services/province-payment-by-weight-dashboard.js b/src/features/province/services/province-payment-by-weight-dashboard.js new file mode 100644 index 0000000..de46d56 --- /dev/null +++ b/src/features/province/services/province-payment-by-weight-dashboard.js @@ -0,0 +1,26 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_START } from "../../../lib/redux/slices/appSlice"; +import { getRoleFromUrl } from "../../../utils/getRoleFromUrl"; + +export const provincePaymentByWeightGetDashboard = createAsyncThunk( + "PROVINCE_GET_PAYMENT_DASHBOARD", + async (d, { dispatch }) => { + try { + dispatch(LOADING_START()); + const { data, status } = await axios.get( + "dashboard_detail_general_killhouse_wage", + { + params: { + date1: d.withDate ? d.selectedDate1 : "null", + date2: d.withDate ? d.selectedDate2 : "null", + role: getRoleFromUrl(), + }, + } + ); + return { data, status }; + } catch (e) { + return { error: e.response.data }; + } + } +); diff --git a/src/features/province/services/province-payment-by-weight-killhouse.js b/src/features/province/services/province-payment-by-weight-killhouse.js new file mode 100644 index 0000000..724c694 --- /dev/null +++ b/src/features/province/services/province-payment-by-weight-killhouse.js @@ -0,0 +1,30 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; +import { getRoleFromUrl } from "../../../utils/getRoleFromUrl"; + +export const provincePaymentByWeightGetKillHousesService = createAsyncThunk( + "PROVINCE_PAYMENT_GET_KILLHOUSES", + async (d, { dispatch }) => { + try { + dispatch(LOADING_START()); + const { data, status } = await axios.get( + "detail_general_killhouse_wage/", + { + params: { + date1: d.withDate ? d.selectedDate1 : "null", + date2: d.withDate ? d.selectedDate2 : "null", + search: "filter", + value: d.textValue, + role: getRoleFromUrl(), + }, + } + ); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e.response.data }; + } + } +); diff --git a/src/features/province/services/province-payment-get-killers-of-killhouses-info.js b/src/features/province/services/province-payment-get-killers-of-killhouses-info.js new file mode 100644 index 0000000..142263c --- /dev/null +++ b/src/features/province/services/province-payment-get-killers-of-killhouses-info.js @@ -0,0 +1,25 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const provincePaymentGetKillersOfKillhousesInfo = createAsyncThunk( + "PROVINCE_GET_KILLERS_OF_KILLHOUSES_INFO", + async (d, { dispatch }) => { + try { + dispatch(LOADING_START()); + const { data, status } = await axios.get( + "total-wage-exclusive-killer-information/", + { + params: { + ...d, + }, + } + ); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e.response.data }; + } + } +); diff --git a/src/features/province/services/province-payment-refId.js b/src/features/province/services/province-payment-refId.js new file mode 100644 index 0000000..45905ad --- /dev/null +++ b/src/features/province/services/province-payment-refId.js @@ -0,0 +1,21 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; + +export const provincePaymentRefIdService = createAsyncThunk( + "PROVINCE_PAYMENT_REF_ID", + async (d, { dispatch }) => { + const { data, status } = await axios.post("wage-payment-total/", d); + return { data, status }; + } +); + +export const provincePaymentRefIdWagesService = createAsyncThunk( + "PROVINCE_PAYMENT_REF_ID_WAGES", + async (d, { dispatch }) => { + const { data, status } = await axios.post( + `https://${d.backend}backend.rasadyar.com/wage-payment-with-link/`, + d.data + ); + return { data, status }; + } +); diff --git a/src/features/province/services/province-policy-auto-accept-slaughter.js b/src/features/province/services/province-policy-auto-accept-slaughter.js new file mode 100644 index 0000000..b8969bc --- /dev/null +++ b/src/features/province/services/province-policy-auto-accept-slaughter.js @@ -0,0 +1,16 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const provincePolicyAutoAcceptSlaughterService = createAsyncThunk( + "PROVINCE_POLICY_AUTO_ACCEPT_SLAUGHTER_SERVICE", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + const { data, status } = await axios.put( + "auto_accept_province_kill_requests/0/", + d + ); + dispatch(LOADING_END()); + return { data, status }; + } +); diff --git a/src/features/province/services/province-policy-auto-allocate-car.js b/src/features/province/services/province-policy-auto-allocate-car.js new file mode 100644 index 0000000..b300b45 --- /dev/null +++ b/src/features/province/services/province-policy-auto-allocate-car.js @@ -0,0 +1,16 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const provincePolicyAutoAllocateCarService = createAsyncThunk( + "PROVINCE_POLICY_AUTO_ALLOCATE_CAR_SERVICE", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + const { data, status } = await axios.put( + "auto_make_kill_house_requests/0/", + d + ); + dispatch(LOADING_END()); + return { data, status }; + } +); diff --git a/src/features/province/services/province-policy-create-wage.js b/src/features/province/services/province-policy-create-wage.js new file mode 100644 index 0000000..d267611 --- /dev/null +++ b/src/features/province/services/province-policy-create-wage.js @@ -0,0 +1,18 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const provincePolicyCreateWage = createAsyncThunk( + "PROVINCE_POLICY_CREATE_WAGE", + async (d, { dispatch }) => { + try { + dispatch(LOADING_START()); + const { data, status } = await axios.post("share-type/", d); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e.response.data.result }; + } + } +); diff --git a/src/features/province/services/province-policy-delete-wage.js b/src/features/province/services/province-policy-delete-wage.js new file mode 100644 index 0000000..5efd8b9 --- /dev/null +++ b/src/features/province/services/province-policy-delete-wage.js @@ -0,0 +1,20 @@ +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; +import { createAsyncThunk } from "@reduxjs/toolkit"; + +export const provincePolicyDeleteWage = createAsyncThunk( + "PROVINCE_POLICY_DELETE_WAGE", + async (d, { dispatch }) => { + try { + dispatch(LOADING_START()); + const { data, status } = await axios.delete( + "total-wage-type/" + d.id + "/" + ); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e.response.data.result }; + } + } +); diff --git a/src/features/province/services/province-policy-direct-purchase-bar-limitation.js b/src/features/province/services/province-policy-direct-purchase-bar-limitation.js new file mode 100644 index 0000000..d5d09b9 --- /dev/null +++ b/src/features/province/services/province-policy-direct-purchase-bar-limitation.js @@ -0,0 +1,38 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const provincePolicyGetDirectPurchaseBarLimitation = createAsyncThunk( + "PROVINCE_POLICY_GET_DIRECT_PURCHASE_BAR_LIMITATION", + async (d, { dispatch }) => { + try { + dispatch(LOADING_START()); + const { data, status } = await axios.get( + "limitation_for_direct_purchase_and_bar_information/" + ); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e.response?.data?.result || "خطا در دریافت اطلاعات" }; + } + } +); + +export const provincePolicyEditDirectPurchaseBarLimitation = createAsyncThunk( + "PROVINCE_POLICY_EDIT_DIRECT_PURCHASE_BAR_LIMITATION", + async ({ id, data: requestData }, { dispatch }) => { + try { + dispatch(LOADING_START()); + const { data, status } = await axios.put( + `limitation_for_direct_purchase_and_bar_information/${id}/`, + requestData + ); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e.response?.data?.result || "خطا در ویرایش اطلاعات" }; + } + } +); diff --git a/src/features/province/services/province-policy-drop-limit.js b/src/features/province/services/province-policy-drop-limit.js new file mode 100644 index 0000000..3f05494 --- /dev/null +++ b/src/features/province/services/province-policy-drop-limit.js @@ -0,0 +1,13 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; +import axios from "axios"; + +export const provincePolicyGetDropLimitService = createAsyncThunk( + "PROVINCE_POLICY_GET_DROP_LIMIT_SERVICE", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + const { data, status } = await axios.get("drop-limit/", d); + dispatch(LOADING_END()); + return { data, status }; + } +); diff --git a/src/features/province/services/province-policy-edit-drop-limited.js b/src/features/province/services/province-policy-edit-drop-limited.js new file mode 100644 index 0000000..e7ac396 --- /dev/null +++ b/src/features/province/services/province-policy-edit-drop-limited.js @@ -0,0 +1,13 @@ +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; +import { createAsyncThunk } from "@reduxjs/toolkit"; + +export const provinceEditDropLimitedService = createAsyncThunk( + "PROVINCE_EDIT_DROP_LIMITED_SERVICE", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + const { data, status } = await axios.put("/drop-limit/0/", d); + dispatch(LOADING_END()); + return { data, status }; + } +); diff --git a/src/features/province/services/province-policy-edit-export-allow-state.js b/src/features/province/services/province-policy-edit-export-allow-state.js new file mode 100644 index 0000000..d2311ee --- /dev/null +++ b/src/features/province/services/province-policy-edit-export-allow-state.js @@ -0,0 +1,18 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const provincePolicyEditExportAllowState = createAsyncThunk( + "PROVINCE_EDIT_EXPORT_STATE", + async (d, { dispatch }) => { + try { + dispatch(LOADING_START()); + const { data, status } = await axios.put("poultry-export/0/", d); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e.response.data.result }; + } + } +); diff --git a/src/features/province/services/province-policy-edit-fine-permission.js b/src/features/province/services/province-policy-edit-fine-permission.js new file mode 100644 index 0000000..7b62a19 --- /dev/null +++ b/src/features/province/services/province-policy-edit-fine-permission.js @@ -0,0 +1,17 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; +export const provincePolicyEditFinePermission = createAsyncThunk( + "PROVINCE_POLICY_EDIT_WEIGHT_FINE_PERMISSION", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + try { + const { data, status } = await axios.put(`fine-permission/0/`, d); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e.response.data.result }; + } + } +); diff --git a/src/features/province/services/province-policy-edit-free-sale-allow-state.js b/src/features/province/services/province-policy-edit-free-sale-allow-state.js new file mode 100644 index 0000000..68f45bc --- /dev/null +++ b/src/features/province/services/province-policy-edit-free-sale-allow-state.js @@ -0,0 +1,21 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const provincePolicyEditFreeSaleAllowState = createAsyncThunk( + "PROVINCE_EDIT_FREE_SALE_STATE", + async (d, { dispatch }) => { + try { + dispatch(LOADING_START()); + const { data, status } = await axios.put( + "poultry-out-province-request/0/", + d + ); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e.response.data.result }; + } + } +); diff --git a/src/features/province/services/province-policy-edit-payment-fractions.js b/src/features/province/services/province-policy-edit-payment-fractions.js new file mode 100644 index 0000000..b889795 --- /dev/null +++ b/src/features/province/services/province-policy-edit-payment-fractions.js @@ -0,0 +1,16 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const provincePolicyEditPaymentFractions = createAsyncThunk( + "PROVINCE_POLICY_EDIT_PAYMENT_FRACTIONS", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + const { data, status } = await axios.put( + "payment-gateway-percentage/0/", + d + ); + dispatch(LOADING_END()); + return { data, status }; + } +); diff --git a/src/features/province/services/province-policy-edit-share-type.js b/src/features/province/services/province-policy-edit-share-type.js new file mode 100644 index 0000000..e611127 --- /dev/null +++ b/src/features/province/services/province-policy-edit-share-type.js @@ -0,0 +1,20 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const provincePolicyEditShareType = createAsyncThunk( + "PROVINCE_POLICY_EDIT_SHARE_TYPE", + async (d, { dispatch }) => { + try { + dispatch(LOADING_START()); + const { data, status } = await axios.put("share-type/" + d.id + "/", { + name: d.name, + }); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e.response.data.result }; + } + } +); diff --git a/src/features/province/services/province-policy-edit-time-range.js b/src/features/province/services/province-policy-edit-time-range.js new file mode 100644 index 0000000..cc98b9d --- /dev/null +++ b/src/features/province/services/province-policy-edit-time-range.js @@ -0,0 +1,13 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const provincePolicyEditTimeRange = createAsyncThunk( + "PROVINCE_POLICY_EDIT_TIME_RANGE", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + const { data, status } = await axios.put("time-range/0/", d); + dispatch(LOADING_END()); + return { data, status }; + } +); diff --git a/src/features/province/services/province-policy-edit-trade-time-range.js b/src/features/province/services/province-policy-edit-trade-time-range.js new file mode 100644 index 0000000..4d088fe --- /dev/null +++ b/src/features/province/services/province-policy-edit-trade-time-range.js @@ -0,0 +1,28 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; +import { getRoleFromUrl } from "../../../utils/getRoleFromUrl"; + +export const provincePolicyEditTradeTimeRange = createAsyncThunk( + "PROVINCE_POLICY_EDIT_TRADE_TIME_RANGE", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + const { data, status } = await axios.put("show-market-requests/0/", d); + dispatch(LOADING_END()); + return { data, status }; + } +); + +export const provincePolicyGetTradeTimeRagnge = createAsyncThunk( + "PROVINCE_POLICY_GET_TRADE_TIME_RANGE", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + const { data, status } = await axios.get("show-market-requests", { + params: { + role: getRoleFromUrl(), + }, + }); + dispatch(LOADING_END()); + return { data, status }; + } +); diff --git a/src/features/province/services/province-policy-edit-wage.js b/src/features/province/services/province-policy-edit-wage.js new file mode 100644 index 0000000..6f02771 --- /dev/null +++ b/src/features/province/services/province-policy-edit-wage.js @@ -0,0 +1,18 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const provincePolicyEditWage = createAsyncThunk( + "PROVINCE_POLICY_EDIT_WAGE", + async (d, { dispatch }) => { + try { + dispatch(LOADING_START()); + const { data, status } = await axios.put("wage-type/0/", d); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e.response.data.result }; + } + } +); diff --git a/src/features/province/services/province-policy-free-sale.js b/src/features/province/services/province-policy-free-sale.js new file mode 100644 index 0000000..60ca874 --- /dev/null +++ b/src/features/province/services/province-policy-free-sale.js @@ -0,0 +1,16 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const provincePolicyFreeSaleService = createAsyncThunk( + "PROVINCE_POLICY_FREE_SALE_SERVICE", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + const { data, status } = await axios.post( + "province_allow_poultry_sell_free_total/", + d + ); + dispatch(LOADING_END()); + return { data, status }; + } +); diff --git a/src/features/province/services/province-policy-get-accounts.js b/src/features/province/services/province-policy-get-accounts.js new file mode 100644 index 0000000..64b4b8b --- /dev/null +++ b/src/features/province/services/province-policy-get-accounts.js @@ -0,0 +1,80 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const provincePolicyGetAccountsSevice = createAsyncThunk( + "PROVINCE_POLICY_GET_ACCOUNTS_SERVICE", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + const { data, status } = await axios.get("zarinpal-accounts/"); + dispatch(LOADING_END()); + return { data, status }; + } +); + +export const provincePolicyEditAccountsSevice = createAsyncThunk( + "PROVINCE_POLICY_EDIT_ACCOUNTS_SERVICE", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + const { data, status } = await axios.put("zarinpal-accounts/0/", d); + dispatch(LOADING_END()); + return { data, status }; + } +); + +export const provincePolicyGetBeneficiaryAccountsSevice = createAsyncThunk( + "PROVINCE_POLICY_GET_BENEFICIARY_ACCOUNTS_SERVICE", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + const { data, status } = await axios.get("beneficiary-accounts/"); + dispatch(LOADING_END()); + return { data, status }; + } +); + +export const provincePolicySubmitBeneficiaryAccountsSevice = createAsyncThunk( + "PROVINCE_POLICY_SUBMIT_BENEFICIARY_ACCOUNTS_SERVICE", + async (d, { dispatch }) => { + try { + dispatch(LOADING_START()); + const { data, status } = await axios.post("beneficiary-accounts/", d); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e.response.data.result }; + } + } +); + +export const provincePolicyEditBeneficiaryAccountsSevice = createAsyncThunk( + "PROVINCE_POLICY_EDIT_BENEFICIARY_ACCOUNTS_SERVICE", + async (d, { dispatch }) => { + try { + dispatch(LOADING_START()); + const { data, status } = await axios.put("beneficiary-accounts/0/", d); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e.response.data.result }; + } + } +); + +export const provincePolicyDeleteBeneficiaryAccountsSevice = createAsyncThunk( + "PROVINCE_POLICY_DELETE_BENEFICIARY_ACCOUNTS_SERVICE", + async (id, { dispatch }) => { + dispatch(LOADING_START()); + try { + const { data, status } = await axios.delete( + "beneficiary-accounts/0/?account_key=" + id + ); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e.response.data.result }; + } + } +); diff --git a/src/features/province/services/province-policy-get-aggregate-bar-info-allow-state.js b/src/features/province/services/province-policy-get-aggregate-bar-info-allow-state.js new file mode 100644 index 0000000..0aa3cc3 --- /dev/null +++ b/src/features/province/services/province-policy-get-aggregate-bar-info-allow-state.js @@ -0,0 +1,33 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const provincePolicyGetAggregateBarInfoAllowStatus = createAsyncThunk( + "PROVINCE_GET_AGGREGATE_STATUS", + async (d, { dispatch }) => { + try { + dispatch(LOADING_START()); + const { data, status } = await axios.get("aggregate-permission/"); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e.response.data.result }; + } + } +); + +export const provincePolicyEditAggregateBarInfoAllowStatus = createAsyncThunk( + "PROVINCE_EDIT_AGGREGATE_STATUS", + async (d, { dispatch }) => { + try { + dispatch(LOADING_START()); + const { data, status } = await axios.put("aggregate-permission/0/", d); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e.response.data.result }; + } + } +); diff --git a/src/features/province/services/province-policy-get-auto-accept-slaughter.js b/src/features/province/services/province-policy-get-auto-accept-slaughter.js new file mode 100644 index 0000000..d354e2f --- /dev/null +++ b/src/features/province/services/province-policy-get-auto-accept-slaughter.js @@ -0,0 +1,16 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const provincePolicyGetAutoAcceptSlaughterService = createAsyncThunk( + "PROVINCE_POLICY_GET_AUTO_ACCEPT_SLAUGHTER_SERVICE", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + const { data, status } = await axios.get( + "auto_accept_province_kill_requests/", + d + ); + dispatch(LOADING_END()); + return { data, status }; + } +); diff --git a/src/features/province/services/province-policy-get-auto-allocate-car.js b/src/features/province/services/province-policy-get-auto-allocate-car.js new file mode 100644 index 0000000..6377a1b --- /dev/null +++ b/src/features/province/services/province-policy-get-auto-allocate-car.js @@ -0,0 +1,16 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const provincePolicyGetAutoAllocateCarService = createAsyncThunk( + "PROVINCE_POLICY_GET_AUTO_ALLOCATE_CAR_SERVICE", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + const { data, status } = await axios.get( + "auto_make_kill_house_requests/", + d + ); + dispatch(LOADING_END()); + return { data, status }; + } +); diff --git a/src/features/province/services/province-policy-get-export-allow-state.js b/src/features/province/services/province-policy-get-export-allow-state.js new file mode 100644 index 0000000..002640c --- /dev/null +++ b/src/features/province/services/province-policy-get-export-allow-state.js @@ -0,0 +1,18 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const provincePolicyGetExportAllowStatus = createAsyncThunk( + "PROVINCE_GET_EXPORT_STATUS", + async (d, { dispatch }) => { + try { + dispatch(LOADING_START()); + const { data, status } = await axios.get("poultry-export/"); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e.response.data.result }; + } + } +); diff --git a/src/features/province/services/province-policy-get-fine-permission.js b/src/features/province/services/province-policy-get-fine-permission.js new file mode 100644 index 0000000..dea224d --- /dev/null +++ b/src/features/province/services/province-policy-get-fine-permission.js @@ -0,0 +1,13 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const provincePolicyGetFinePermission = createAsyncThunk( + "PROVINCE_POLICY_GET_FINE_PERMISSION", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + const { data, status } = await axios.get("fine-permission/"); + dispatch(LOADING_END()); + return { data, status }; + } +); diff --git a/src/features/province/services/province-policy-get-free-sale-state.js b/src/features/province/services/province-policy-get-free-sale-state.js new file mode 100644 index 0000000..0d76654 --- /dev/null +++ b/src/features/province/services/province-policy-get-free-sale-state.js @@ -0,0 +1,18 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const provincePolicyGetFreeSaleStatus = createAsyncThunk( + "PROVINCE_GET_FREE_SALE_STATUS", + async (d, { dispatch }) => { + try { + dispatch(LOADING_START()); + const { data, status } = await axios.get("poultry-out-province-request/"); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e.response.data.result }; + } + } +); diff --git a/src/features/province/services/province-policy-get-free-sale.js b/src/features/province/services/province-policy-get-free-sale.js new file mode 100644 index 0000000..127342a --- /dev/null +++ b/src/features/province/services/province-policy-get-free-sale.js @@ -0,0 +1,16 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const provincePolicyGetFreeSaleService = createAsyncThunk( + "PROVINCE_POLICY_GET_FREE_SALE_SERVICE", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + const { data, status } = await axios.get( + "province_allow_poultry_sell_free_total/", + d + ); + dispatch(LOADING_END()); + return { data, status }; + } +); diff --git a/src/features/province/services/province-policy-get-maximum-bar-quantity.js b/src/features/province/services/province-policy-get-maximum-bar-quantity.js new file mode 100644 index 0000000..6f1c751 --- /dev/null +++ b/src/features/province/services/province-policy-get-maximum-bar-quantity.js @@ -0,0 +1,33 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const provincePolicyGetMaximumBarQuantityStatus = createAsyncThunk( + "PROVINCE_GET_MAX_BAR_STATUS", + async (d, { dispatch }) => { + try { + dispatch(LOADING_START()); + const { data, status } = await axios.get("bar-limitation/"); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e.response.data.result }; + } + } +); + +export const provincePolicyEditMaximumBarQuantityStatus = createAsyncThunk( + "PROVINCE_EDIT_MAX_BAR_STATUS", + async (d, { dispatch }) => { + try { + dispatch(LOADING_START()); + const { data, status } = await axios.put("bar-limitation/0/", d); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e.response.data.result }; + } + } +); diff --git a/src/features/province/services/province-policy-get-payment-fractions.js b/src/features/province/services/province-policy-get-payment-fractions.js new file mode 100644 index 0000000..d40d473 --- /dev/null +++ b/src/features/province/services/province-policy-get-payment-fractions.js @@ -0,0 +1,13 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const provincePolicyGetPaymentFractions = createAsyncThunk( + "PROVINCE_POLICY_GET_PAYMENT_FRACTIONS", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + const { data, status } = await axios.get("payment-gateway-percentage/"); + dispatch(LOADING_END()); + return { data, status }; + } +); diff --git a/src/features/province/services/province-policy-get-slaughter-buying-price-status.js b/src/features/province/services/province-policy-get-slaughter-buying-price-status.js new file mode 100644 index 0000000..ce2e777 --- /dev/null +++ b/src/features/province/services/province-policy-get-slaughter-buying-price-status.js @@ -0,0 +1,43 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const provincePolicyGetSLaughterSubmitBuyingPriceStatus = + createAsyncThunk( + "PROVINCE_GET_SLAUGHTER_BUYING_PRICE_STATUS", + async (d, { dispatch }) => { + try { + dispatch(LOADING_START()); + const { data, status } = await axios.get( + "kill-house-price-permission/", + { + params: d, + } + ); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e.response.data.result }; + } + } + ); + +export const provincePolicyEditSlaughterSubmitBuyingPriceStatus = + createAsyncThunk( + "PROVINCE_EDIT_SLAUGHTER_BUYING_PRICE_STATUS", + async (d, { dispatch }) => { + try { + dispatch(LOADING_START()); + const { data, status } = await axios.put( + "kill-house-price-permission/0/", + d + ); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e.response.data.result }; + } + } + ); diff --git a/src/features/province/services/province-policy-get-ticket-permissions.js b/src/features/province/services/province-policy-get-ticket-permissions.js new file mode 100644 index 0000000..dff1d04 --- /dev/null +++ b/src/features/province/services/province-policy-get-ticket-permissions.js @@ -0,0 +1,13 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const provincePolicyGetTicketPermissions = createAsyncThunk( + "PROVINCE_POLICY_GET_TICKETS", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + const { data, status } = await axios.get("ticket-permission/"); + dispatch(LOADING_END()); + return { data, status }; + } +); diff --git a/src/features/province/services/province-policy-get-time-range.js b/src/features/province/services/province-policy-get-time-range.js new file mode 100644 index 0000000..f8e2e5d --- /dev/null +++ b/src/features/province/services/province-policy-get-time-range.js @@ -0,0 +1,13 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const provincePolicyGetTimeRagnge = createAsyncThunk( + "GET_MIN_MAX_AGE_STATE", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + const { data, status } = await axios.get("time-range/"); + dispatch(LOADING_END()); + return { data, status }; + } +); diff --git a/src/features/province/services/province-policy-get-wage-fractions.js b/src/features/province/services/province-policy-get-wage-fractions.js new file mode 100644 index 0000000..eaa503e --- /dev/null +++ b/src/features/province/services/province-policy-get-wage-fractions.js @@ -0,0 +1,13 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const provincePolicyGetWageFractions = createAsyncThunk( + "PROVINCE_POLICY_GET_WAGE_FRACTIONS", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + const { data, status } = await axios.get("wage-type/"); + dispatch(LOADING_END()); + return { data, status }; + } +); diff --git a/src/features/province/services/province-policy-get-wages.js b/src/features/province/services/province-policy-get-wages.js new file mode 100644 index 0000000..765acc5 --- /dev/null +++ b/src/features/province/services/province-policy-get-wages.js @@ -0,0 +1,13 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const provincePolicyGetShareType = createAsyncThunk( + "PROVINCE_POLICY_GET_SHARE_TYPE", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + const { data, status } = await axios.get("share-type/"); + dispatch(LOADING_END()); + return { data, status }; + } +); diff --git a/src/features/province/services/province-policy-get-weight-category.js b/src/features/province/services/province-policy-get-weight-category.js new file mode 100644 index 0000000..c6c3996 --- /dev/null +++ b/src/features/province/services/province-policy-get-weight-category.js @@ -0,0 +1,60 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const provincePolicyGetWeightCategory = createAsyncThunk( + "PROVINCE_POLICY_GET_WEIGHT_CATEGORY", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + const { data, status } = await axios.get("index-weight-category/"); + dispatch(LOADING_END()); + return { data, status }; + } +); + +export const provincePolicySubmitWeightCategory = createAsyncThunk( + "PROVINCE_POLICY_SUBMIT_WEIGHT_CATEGORY", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + try { + const { data, status } = await axios.post("index-weight-category/", d); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e.response.data.result }; + } + } +); + +export const provincePolicyEditWeightCategory = createAsyncThunk( + "PROVINCE_POLICY_EDIT_WEIGHT_CATEGORY", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + try { + const { data, status } = await axios.put(`index-weight-category/0/`, d); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e.response.data.result }; + } + } +); + +export const provincePolicyDeleteWeightCategory = createAsyncThunk( + "PROVINCE_DELETE_WEIGHT_CATEGORY", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + try { + const { data, status } = await axios.delete( + `index-weight-category/${d}/` + ); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e.response.data.result }; + } + } +); diff --git a/src/features/province/services/province-policy-get-weight-range.js b/src/features/province/services/province-policy-get-weight-range.js new file mode 100644 index 0000000..73a5ad3 --- /dev/null +++ b/src/features/province/services/province-policy-get-weight-range.js @@ -0,0 +1,68 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const provincePolicyGetWeightRange = createAsyncThunk( + "PROVINCE_POLICY_GET_WEIGHT_RANGE", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + const { data, status } = await axios.get("management_hatching_age_range/", { + params: d, + }); + dispatch(LOADING_END()); + return { data, status }; + } +); + +export const provincePolicySubmitWeightRange = createAsyncThunk( + "PROVINCE_POLICY_SUBMIT_WEIGHT_RANGE", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + try { + const { data, status } = await axios.post( + "management_hatching_age_range/", + d + ); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e.response.data.result }; + } + } +); + +export const provincePolicyEditWeightRange = createAsyncThunk( + "PROVINCE_POLICY_EDIT_WEIGHT_RANGE", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + try { + const { data, status } = await axios.put( + `management_hatching_age_range/${d.id}/`, + d + ); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e.response.data.result }; + } + } +); + +export const provincePolicyDeleteWeightRange = createAsyncThunk( + "PROVINCE_DELETE_WEIGHT_RANGE", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + try { + const { data, status } = await axios.delete( + `management_hatching_age_range/${d}/` + ); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e.response.data.result }; + } + } +); diff --git a/src/features/province/services/province-policy-market-daily-limitation.js b/src/features/province/services/province-policy-market-daily-limitation.js new file mode 100644 index 0000000..83afd7d --- /dev/null +++ b/src/features/province/services/province-policy-market-daily-limitation.js @@ -0,0 +1,34 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const provincePolicyGetMarketDailyLimitation = createAsyncThunk( + "PROVINCE_GET_MARKET_DAILY_LIMITATION", + async (d, { dispatch }) => { + try { + dispatch(LOADING_START()); + const { data, status } = await axios.get("market-daily-limitation/"); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e.response.data.result }; + } + } +); + +export const provincePolicyEditMarketDailyLimitation = createAsyncThunk( + "PROVINCE_EDIT_MARKET_DAILY_LIMITATION", + async (d, { dispatch }) => { + try { + dispatch(LOADING_START()); + const { data, status } = await axios.put("market-daily-limitation/0/", d); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e.response.data.result }; + } + } +); + diff --git a/src/features/province/services/province-policy-poultry-choose-kill-house.js b/src/features/province/services/province-policy-poultry-choose-kill-house.js new file mode 100644 index 0000000..fb47fbb --- /dev/null +++ b/src/features/province/services/province-policy-poultry-choose-kill-house.js @@ -0,0 +1,16 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const provincePolicyPoultryChooseKillHouseService = createAsyncThunk( + "PROVINCE_POLICY_POULTRY_CHOOSE_KILL_HOUSE_SERVICE", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + const { data, status } = await axios.post( + "province_allow_poultry_choose_kill_house_total/", + d + ); + dispatch(LOADING_END()); + return { data, status }; + } +); diff --git a/src/features/province/services/province-policy-submit-document-state.js b/src/features/province/services/province-policy-submit-document-state.js new file mode 100644 index 0000000..9c8211b --- /dev/null +++ b/src/features/province/services/province-policy-submit-document-state.js @@ -0,0 +1,50 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const provincePolicySubmitDocumentState = createAsyncThunk( + "PROVINCE_POLICY_SUBMIT_DOCUMENT_STATE", + async (d, { dispatch }) => { + try { + dispatch(LOADING_START()); + const { data, status } = await axios.post("bar-documents-status/", d); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e.response.data.result }; + } + } +); + +export const provincePolicyEditDocumentState = createAsyncThunk( + "PROVINCE_POLICY_SUBMIT_DOCUMENT_STATE", + async (d, { dispatch }) => { + try { + dispatch(LOADING_START()); + const { data, status } = await axios.put("bar-documents-status/0/", d); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e.response.data.result }; + } + } +); + +export const provincePolicyDeleteDocumentState = createAsyncThunk( + "PROVINCE_POLICY_DELETE_DOCUMENT_STATE", + async (d, { dispatch }) => { + try { + dispatch(LOADING_START()); + const { data, status } = await axios.delete( + "bar-documents-status/" + d + "/" + ); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e.response.data.result }; + } + } +); diff --git a/src/features/province/services/province-policy-submit-ticket-permission.js b/src/features/province/services/province-policy-submit-ticket-permission.js new file mode 100644 index 0000000..f489b5c --- /dev/null +++ b/src/features/province/services/province-policy-submit-ticket-permission.js @@ -0,0 +1,18 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const provincePolicySubmitTicketPermission = createAsyncThunk( + "PROVINCE_POLICY_SUBMIT_TICKET_PERMISSION", + async (d, { dispatch }) => { + try { + dispatch(LOADING_START()); + const { data, status } = await axios.post("ticket-permission/", d); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e.response.data.result }; + } + } +); diff --git a/src/features/province/services/province-policy-update-limitation.js b/src/features/province/services/province-policy-update-limitation.js new file mode 100644 index 0000000..f2ba338 --- /dev/null +++ b/src/features/province/services/province-policy-update-limitation.js @@ -0,0 +1,18 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const provincePolicyUpdateLimitations = createAsyncThunk( + "PROVINCE_POLICY_UPDATE_LIMITATIONS", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + try { + const { data, status } = await axios.put("operation-limitation/0/", d); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e.response.data.result }; + } + } +); diff --git a/src/features/province/services/province-policy-upload-image.js b/src/features/province/services/province-policy-upload-image.js new file mode 100644 index 0000000..48724c2 --- /dev/null +++ b/src/features/province/services/province-policy-upload-image.js @@ -0,0 +1,34 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; +import axios from "axios"; + +export const provincePolicyGetUploadImageService = createAsyncThunk( + "PROVINCE_GET_UPLOAD_IMAGE", + async (d, { dispatch }) => { + try { + dispatch(LOADING_START()); + const { data, status } = await axios.get("/upload-image-limit/", { + params: d, + }); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e.response.data.result }; + } + } +); +export const provincePolicyGEditUploadImageService = createAsyncThunk( + "PROVINCE_GET_UPLOAD_IMAGE", + async (d, { dispatch }) => { + try { + dispatch(LOADING_START()); + const { data, status } = await axios.put("/upload-image-limit/0/", d); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e.response.data.result }; + } + } +); diff --git a/src/features/province/services/province-policy-validate-poultry-wth-sms-service.js b/src/features/province/services/province-policy-validate-poultry-wth-sms-service.js new file mode 100644 index 0000000..0ebda5f --- /dev/null +++ b/src/features/province/services/province-policy-validate-poultry-wth-sms-service.js @@ -0,0 +1,37 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const provincePolicyValidatePoultryWithSmsStatusService = + createAsyncThunk( + "PROVINCE_GET_SMS_POULTRY_VALIDATE_STATUS", + async (d, { dispatch }) => { + try { + dispatch(LOADING_START()); + const { data, status } = await axios.get("price-confirmation", { + params: d, + }); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e.response.data.result }; + } + } + ); + +export const provincePolicyEditValidatePoultryWithSmsStatusService = + createAsyncThunk( + "PROVINCE_EDIT_SMS_POULTRY_VALIDATE_STATUS", + async (d, { dispatch }) => { + try { + dispatch(LOADING_START()); + const { data, status } = await axios.put("price-confirmation/0/", d); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e.response.data.result }; + } + } + ); diff --git a/src/features/province/services/province-policy-wage-setup-get-killhouses.js b/src/features/province/services/province-policy-wage-setup-get-killhouses.js new file mode 100644 index 0000000..cd62124 --- /dev/null +++ b/src/features/province/services/province-policy-wage-setup-get-killhouses.js @@ -0,0 +1,15 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const provincePolicyWageSetupGetKillhouses = createAsyncThunk( + "PROVINCE_POLICY_WAGES_SETUP_GET_KILLHOUSES", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + const { data, status } = await axios.get( + "kill_house/?gate-way-kill-houses=true/" + ); + dispatch(LOADING_END()); + return { data, status }; + } +); diff --git a/src/features/province/services/province-policy-wages-edit-killhouse.js b/src/features/province/services/province-policy-wages-edit-killhouse.js new file mode 100644 index 0000000..1da0689 --- /dev/null +++ b/src/features/province/services/province-policy-wages-edit-killhouse.js @@ -0,0 +1,18 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const provincePolicyWagesEditKillhouse = createAsyncThunk( + "PROVINCE_POLICY_EDIT_KILLHOUSE", + async (d, { dispatch }) => { + try { + dispatch(LOADING_START()); + const { data, status } = await axios.put("kill_house/0/", d); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e.response.data.result }; + } + } +); diff --git a/src/features/province/services/province-poultry-request-enter-confirmation-code.js b/src/features/province/services/province-poultry-request-enter-confirmation-code.js new file mode 100644 index 0000000..91e7950 --- /dev/null +++ b/src/features/province/services/province-poultry-request-enter-confirmation-code.js @@ -0,0 +1,19 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const provincePoultryRequestEnterConfirmationCodeService = + createAsyncThunk( + "PROVINCE_EDIT_CONFIRMATION_CODE", + async (d, { dispatch }) => { + try { + dispatch(LOADING_START()); + const { data, status } = await axios.put("Poultry_Request/0/", d); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e.response.data.result }; + } + } + ); diff --git a/src/features/province/services/province-poultry-science-experts-add-poultry-service.js b/src/features/province/services/province-poultry-science-experts-add-poultry-service.js new file mode 100644 index 0000000..d2bdc51 --- /dev/null +++ b/src/features/province/services/province-poultry-science-experts-add-poultry-service.js @@ -0,0 +1,30 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const provincePoultryScienceExpertsAllPoultryService = createAsyncThunk( + "PROVINCE_POULTRY_SCIENCE_EXPERTS", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + const { data, status } = await axios.get( + "get-all-poultry-for-poultry-science/" + ); + dispatch(LOADING_END()); + return { data, status }; + } +); + +export const provincePoultryScienceExpertsEditPoultryService = createAsyncThunk( + "PROVINCE_POLICY_UPDATE_LIMITATIONS_EDIT", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + try { + const { data, status } = await axios.put("poultry_science/0/", d); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e.response.data.result }; + } + } +); diff --git a/src/features/province/services/province-price-edit.js b/src/features/province/services/province-price-edit.js new file mode 100644 index 0000000..279158d --- /dev/null +++ b/src/features/province/services/province-price-edit.js @@ -0,0 +1,27 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; +import axios from "axios"; + +export const provincePriceEditService = createAsyncThunk( + "PROVINCE_PRICE_EDIT_SERVICE", + async (d, { dispatch }) => { + try { + dispatch(LOADING_START()); + + const { data, status } = await axios.put( + `chicken-commission-prices/${d.id}/`, + { + kill_house_price: d.kill_house_price, + wholesaler_price: d.wholesaler_price, + retailer_price: d.retailer_price, + } + ); + + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e?.response?.data?.result || "خطایی رخ داده است" }; + } + } +); diff --git a/src/features/province/services/province-purge-needed-request.js b/src/features/province/services/province-purge-needed-request.js new file mode 100644 index 0000000..f684db5 --- /dev/null +++ b/src/features/province/services/province-purge-needed-request.js @@ -0,0 +1,20 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const provincePurgeNeededRequestService = createAsyncThunk( + "PROVINCE_PURGE_NEEDED_REQUEST_SERVICE", + async (_, { dispatch }) => { + try { + dispatch(LOADING_START()); + const { data, status } = await axios.put("kill_request/0/", { + previous_requests: true, + }); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e.response.data.result }; + } + } +); diff --git a/src/features/province/services/province-register-car.js b/src/features/province/services/province-register-car.js new file mode 100644 index 0000000..9fe84b7 --- /dev/null +++ b/src/features/province/services/province-register-car.js @@ -0,0 +1,18 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const provinceRegisterCarService = createAsyncThunk( + "PROVINCE_REGISTER_CAR_SERVICE", + async (d, { dispatch }) => { + try { + dispatch(LOADING_START()); + const { data, status } = await axios.post("kill_house_driver/", d); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e.response.data.result }; + } + } +); diff --git a/src/features/province/services/province-register-user.js b/src/features/province/services/province-register-user.js new file mode 100644 index 0000000..3085b80 --- /dev/null +++ b/src/features/province/services/province-register-user.js @@ -0,0 +1,14 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; + +export const provinceRegisterUser = createAsyncThunk( + "PROVINCE_REGISTER_USER", + async (d) => { + try { + const { data, status } = await axios.post("system_user_profile/", d); + return { data, status }; + } catch (e) { + return { error: e.response.data.result }; + } + } +); diff --git a/src/features/province/services/province-remove-car-from-killhouse.js b/src/features/province/services/province-remove-car-from-killhouse.js new file mode 100644 index 0000000..65d93c9 --- /dev/null +++ b/src/features/province/services/province-remove-car-from-killhouse.js @@ -0,0 +1,20 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const provinceRemoveCarFromKillhouseService = createAsyncThunk( + "PROVINCE_REMOVE_CAR_FROM_KILLHOUSE_SERVICE", + async (d, { dispatch }) => { + try { + dispatch(LOADING_START()); + const { data, status } = await axios.delete("kill_house_add_car/0/", { + params: d, + }); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e.response.data.result }; + } + } +); diff --git a/src/features/province/services/province-remove-car.js b/src/features/province/services/province-remove-car.js new file mode 100644 index 0000000..20a60f2 --- /dev/null +++ b/src/features/province/services/province-remove-car.js @@ -0,0 +1,12 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; + +export const provinceRemoveCar = createAsyncThunk( + "PROVINCE_REMOVE_CAR", + async (id) => { + const { data, status } = await axios.delete( + "kill_house_driver/0/?key=" + id + ); + return { data, status }; + } +); diff --git a/src/features/province/services/province-selected-slaughter-in-request.js b/src/features/province/services/province-selected-slaughter-in-request.js new file mode 100644 index 0000000..d5e2f02 --- /dev/null +++ b/src/features/province/services/province-selected-slaughter-in-request.js @@ -0,0 +1,21 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const provinceSelectedSlaughterInRequestService = createAsyncThunk( + "PROVINCE_SELECTED_SLAUGHTER_IN_REQUEST_SERVICE", + async (d, { dispatch }) => { + try { + dispatch(LOADING_START()); + const { data, status } = await axios.put( + "kill_request_for_poultry/0/", + d + ); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e.response.data.result }; + } + } +); diff --git a/src/features/province/services/province-send-message.js b/src/features/province/services/province-send-message.js new file mode 100644 index 0000000..1e6da28 --- /dev/null +++ b/src/features/province/services/province-send-message.js @@ -0,0 +1,10 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; + +export const provinceSendMessage = createAsyncThunk( + "PROVINCE_SEND_MESSAGE", + async (d) => { + const { data, status } = await axios.post("user_message/", d); + return { data, status }; + } +); diff --git a/src/features/province/services/province-send-report-get-times.js b/src/features/province/services/province-send-report-get-times.js new file mode 100644 index 0000000..1f527da --- /dev/null +++ b/src/features/province/services/province-send-report-get-times.js @@ -0,0 +1,78 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const provinceSendReportGetTimes = createAsyncThunk( + "PROVINCE_SEND_REPORT_GET_TIMES", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + const { data, status } = await axios.get("report-submission/"); + dispatch(LOADING_END()); + return { data, status }; + } +); + +export const provinceSendReportGetPositions = createAsyncThunk( + "PROVINCE_SEND_REPORT_GET_POSITIONS", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + const { data, status } = await axios.get("user-position/"); + dispatch(LOADING_END()); + return { data, status }; + } +); + +export const provinceSendReportUpdateSendTime = createAsyncThunk( + "PROVINCE_UPDATE_SEND_TIME", + async (d, { dispatch }) => { + try { + dispatch(LOADING_START()); + const { data, status } = await axios.put("report-submission/0/", d); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e.response.data.result }; + } + } +); + +export const provinceSendReportUpdateReportStatus = createAsyncThunk( + "PROVINCE_UPDATE_REPORT_STATUS", + async (d, { dispatch }) => { + try { + dispatch(LOADING_START()); + const { data, status } = await axios.put("user-reports/0/", d); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e.response.data.result }; + } + } +); + +export const provinceSendReportSubmitReport = createAsyncThunk( + "PROVINCE_UPDATE_SUBMIT_REPORT", + async (d, { dispatch }) => { + try { + dispatch(LOADING_START()); + const { data, status } = await axios.post("user-reports/", d); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e.response.data.result }; + } + } +); + +export const provinceSendReportGetReports = createAsyncThunk( + "PROVINCE_SEND_REPORT_GET_REPORTS", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + const { data, status } = await axios.get("reports/"); + dispatch(LOADING_END()); + return { data, status }; + } +); diff --git a/src/features/province/services/province-send-report-new-user.js b/src/features/province/services/province-send-report-new-user.js new file mode 100644 index 0000000..0036708 --- /dev/null +++ b/src/features/province/services/province-send-report-new-user.js @@ -0,0 +1,48 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const provinceSendReportNewUser = createAsyncThunk( + "PROVINCE_SEND_REPORT_NEW_USER", + async (d, { dispatch }) => { + try { + dispatch(LOADING_START()); + const { data, status } = await axios.post("reports-users/", d); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e.response.data.result }; + } + } +); + +export const provinceSendReportEditUser = createAsyncThunk( + "PROVINCE_SEND_REPORT_EDIT_USER", + async (d, { dispatch }) => { + try { + dispatch(LOADING_START()); + const { data, status } = await axios.put("reports-users/0/", d); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e.response.data.result }; + } + } +); + +export const provinceSendReportDeleteUser = createAsyncThunk( + "PROVINCE_DELETE_USER_REPORT", + async (d, { dispatch }) => { + try { + dispatch(LOADING_START()); + const { data, status } = await axios.delete("reports-users/" + d + "/"); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e.response.data.result }; + } + } +); diff --git a/src/features/province/services/province-send-sms.js b/src/features/province/services/province-send-sms.js new file mode 100644 index 0000000..abef76d --- /dev/null +++ b/src/features/province/services/province-send-sms.js @@ -0,0 +1,18 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const provinceSendSmsService = createAsyncThunk( + "PROVINCE_SEND_SMS_SERVICE", + async (d, { dispatch }) => { + try { + dispatch(LOADING_START()); + const { data, status } = await axios.post("sms/", d); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e.response.data }; + } + } +); diff --git a/src/features/province/services/province-set-sell-for-freezing-access.js b/src/features/province/services/province-set-sell-for-freezing-access.js new file mode 100644 index 0000000..3fae7b7 --- /dev/null +++ b/src/features/province/services/province-set-sell-for-freezing-access.js @@ -0,0 +1,10 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; + +export const provinceSetSellForFreezing = createAsyncThunk( + "PROVINCE_SET_SELL_FOR_FREEZING_ACCESSS", + async (d) => { + const { data, status } = await axios.put(`sell-for-freezing/0/`, d); + return { data, status }; + } +); diff --git a/src/features/province/services/province-set-slaughterhouses-quota.js b/src/features/province/services/province-set-slaughterhouses-quota.js new file mode 100644 index 0000000..f73433d --- /dev/null +++ b/src/features/province/services/province-set-slaughterhouses-quota.js @@ -0,0 +1,18 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const provinceSetSlaughterhousesQuotaService = createAsyncThunk( + "PROVINCE_SET_SLAUGHTERHOUSES_QUOTA_SERVICE", + async (d, { dispatch }) => { + try { + dispatch(LOADING_START()); + const { data, status } = await axios.put("kill_house_percent/0/", d); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e.response.data.result }; + } + } +); diff --git a/src/features/province/services/province-sms-license.js b/src/features/province/services/province-sms-license.js new file mode 100644 index 0000000..a2e5b1f --- /dev/null +++ b/src/features/province/services/province-sms-license.js @@ -0,0 +1,18 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const provinceSmsLincenseService = createAsyncThunk( + "PROVINCE_SMS_LINCENSE_SERVICE", + async (d, { dispatch }) => { + try { + dispatch(LOADING_START()); + const { data, status } = await axios.post("sms_license/", d); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e.response.data }; + } + } +); diff --git a/src/features/province/services/province-sms-set-announcement.js b/src/features/province/services/province-sms-set-announcement.js new file mode 100644 index 0000000..430145b --- /dev/null +++ b/src/features/province/services/province-sms-set-announcement.js @@ -0,0 +1,13 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const provinceSmsSetAnnouncement = createAsyncThunk( + "PROVINCE_SMS_ANNOUNCEMENT", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + const { data, status } = await axios.put("announcements/0/", d); + dispatch(LOADING_END()); + return { data, status }; + } +); diff --git a/src/features/province/services/province-sub-sectors-services.js b/src/features/province/services/province-sub-sectors-services.js new file mode 100644 index 0000000..ec4b62b --- /dev/null +++ b/src/features/province/services/province-sub-sectors-services.js @@ -0,0 +1,191 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const provinceSubSectorCitySharesWageDetailsDashboard = createAsyncThunk( + "SUB_SECTOR_CITY_SHARES_DASHBOARD", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + const { data, status } = await axios.get( + "/union-subsector-wage-dashboard", + { + params: { ...d }, + } + ); + dispatch(LOADING_END()); + return { data, status }; + } +); +export const provinceSubSectorCitySharesDepositssDashboard = createAsyncThunk( + "SUB_SECTOR_DEPOSITS_DASHBOARD", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + const { data, status } = await axios.get( + "/union-subsector-transaction-dashboard" + ); + dispatch(LOADING_END()); + return { data, status }; + } +); + +export const provinceSubSectorCitySharesWageDetailsService = createAsyncThunk( + "SUB_SECTOR_CITY_SHARES", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + const { data, status } = await axios.get("/city-operator-for-sub-sector", { + params: { ...d }, + }); + dispatch(LOADING_END()); + return { data, status }; + } +); + +export const provinceSubSectorCitySharesGeyCitisService = createAsyncThunk( + "SUB_SECTOR_CITY_SHARES", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + const { data, status } = await axios.get( + "/city-operator-for-sub-sector/?operators=true" + ); + dispatch(LOADING_END()); + return { data, status }; + } +); + +export const provinceSubSectorCitySharesWageDetailsSubmitDepositService = + createAsyncThunk("CREATE_TRANSACTION", async (d, { dispatch }) => { + try { + dispatch(LOADING_START()); + const { data, status } = await axios.post("sub-sector-transactions/", d); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e.response.data.result }; + } + }); + +export const provinceSubSectorCitySharesWageDetailsEditDepositService = + createAsyncThunk("CREATE_TRANSACTION", async (d, { dispatch }) => { + try { + dispatch(LOADING_START()); + const { data, status } = await axios.put("sub-sector-transactions/0/", d); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e.response.data.result }; + } + }); + +export const provinceSubSectorCitySharesWageDetailsDeleteDepositService = + createAsyncThunk("DELETE_TRANSACTION", async (d, { dispatch }) => { + dispatch(LOADING_START()); + const { data, status } = await axios.delete("sub-sector-transactions/0/", { + params: { + transaction_key: d, + }, + }); + dispatch(LOADING_END()); + return { data, status }; + }); + +export const provinceSubSectorCitySharesService = createAsyncThunk( + "SUB_SECTOR_SHARES", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + const { data, status } = await axios.get( + "/sub-sector-wage-type-percentage/?type=" + d + ); + dispatch(LOADING_END()); + return { data, status }; + } +); + +export const provinceSubSectorCitySharesSharesService = createAsyncThunk( + "EDIT_SHARE", + async (d, { dispatch }) => { + try { + dispatch(LOADING_START()); + const { data, status } = await axios.put( + "sub-sector-wage-type-percentage/0/", + d + ); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e.response.data.result }; + } + } +); + +// vetFarm + +export const provinceSubSectorVetFarmSharesOverviewDashboard = createAsyncThunk( + "SUB_SECTOR_VETFARM_SHARES_DASHBOARD", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + const { data, status } = await axios.get("/vet_dashboard_wage", { + params: { ...d }, + }); + dispatch(LOADING_END()); + return { data, status }; + } +); + +export const provinceSubSectorVetFarmSharesVetFarmsService = createAsyncThunk( + "SUB_SECTOR_VETFARM_SHARES", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + const { data, status } = await axios.get("/vet_for_sub_sector", { + params: { ...d }, + }); + dispatch(LOADING_END()); + return { data, status }; + } +); + +export const provinceSubSectorVetFarmSharesGeyVetFarmsService = + createAsyncThunk("SUB_SECTOR_VET_FARMS_SHARES", async (d, { dispatch }) => { + dispatch(LOADING_START()); + const { data, status } = await axios.get("/vet_for_sub_sector_transaction"); + dispatch(LOADING_END()); + return { data, status }; + }); + +// guild +export const provinceSubSectorStewardSharesGeyVetFarmsService = + createAsyncThunk( + "SUB_SECTOR_STEWARD_FARMS_SHARES", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + const { data, status } = await axios.get( + "/city-guild-for-sub-sector-transactions" + ); + dispatch(LOADING_END()); + return { data, status }; + } + ); + +export const provinceSubSectorStewardSharesOverviewDashboard = createAsyncThunk( + "SUB_SECTOR_STEWARD_SHARES_DASHBOARD", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + const { data, status } = await axios.get("/city-guild-wage-dashboard", { + params: { ...d }, + }); + dispatch(LOADING_END()); + return { data, status }; + } +); + +export const provinceSubSectorStewardSharesStewardsService = createAsyncThunk( + "SUB_SECTOR_STEWARD_SHARES", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + const { data, status } = await axios.get("/city-guild-for-sub-sector"); + dispatch(LOADING_END()); + return { data, status }; + } +); diff --git a/src/features/province/services/province-submit-car.js b/src/features/province/services/province-submit-car.js new file mode 100644 index 0000000..7dddf9a --- /dev/null +++ b/src/features/province/services/province-submit-car.js @@ -0,0 +1,10 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; + +export const provinceSubmitCar = createAsyncThunk( + "PROVINCE_SUBMIT_CAR", + async (d) => { + const { data, status } = await axios.post("kill_house_driver/", d); + return { data, status }; + } +); diff --git a/src/features/province/services/province-submit-final-auto-allocations.js b/src/features/province/services/province-submit-final-auto-allocations.js new file mode 100644 index 0000000..acd42e1 --- /dev/null +++ b/src/features/province/services/province-submit-final-auto-allocations.js @@ -0,0 +1,18 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const provinceSubmitFinalAutoAllocationsService = createAsyncThunk( + "PROVINCE_SUBMIT_FINAL_AUTO_ALLOCATIONS_SERVICE", + async (d, { dispatch }) => { + try { + dispatch(LOADING_START()); + const { data, status } = await axios.put("automatic_allocation/0/", d); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e.response.data.result }; + } + } +); diff --git a/src/features/province/services/province-submit-maximum-load.js b/src/features/province/services/province-submit-maximum-load.js new file mode 100644 index 0000000..e69de29 diff --git a/src/features/province/services/province-submit-product-price.js b/src/features/province/services/province-submit-product-price.js new file mode 100644 index 0000000..dba4268 --- /dev/null +++ b/src/features/province/services/province-submit-product-price.js @@ -0,0 +1,18 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const provinceSubmitProductPrice = createAsyncThunk( + "PROVINCE_SUBMUIT_PRODUCT_PRICE", + async (d, { dispatch }) => { + try { + dispatch(LOADING_START()); + const { data, status } = await axios.put("additional-products/0/", d); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e.response.data.result }; + } + } +); diff --git a/src/features/province/services/province-trade-panel-enter-market-code-service.js b/src/features/province/services/province-trade-panel-enter-market-code-service.js new file mode 100644 index 0000000..e73eba5 --- /dev/null +++ b/src/features/province/services/province-trade-panel-enter-market-code-service.js @@ -0,0 +1,18 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const provinceTradePanelEnterMarketCodeService = createAsyncThunk( + "PROVINCE_TRADE_PANEL_ENTER_MARKET_CODE_SERVICE", + async (d, { dispatch }) => { + try { + dispatch(LOADING_START()); + const { data, status } = await axios.put("market-requests/0/", d); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e.response.data.result }; + } + } +); diff --git a/src/features/province/services/province-trade-panel-market-request-overview.js b/src/features/province/services/province-trade-panel-market-request-overview.js new file mode 100644 index 0000000..c445cb3 --- /dev/null +++ b/src/features/province/services/province-trade-panel-market-request-overview.js @@ -0,0 +1,34 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { getRoleFromUrl } from "../../../utils/getRoleFromUrl"; + +export const provinceTradePanelMarketRequestOverview = createAsyncThunk( + "PROVINCE_GET_TRADE_PANEL_MARKET_REQUEST", + async (d) => { + try { + const { data, status } = await axios.get(`kill-house-market-info`, { + params: { ...d, role: getRoleFromUrl() || "" }, + }); + return { data, status }; + } catch (e) { + return { error: e.response.data.result }; + } + } +); + +export const provinceTradePanelMarketRequestAdminOverview = createAsyncThunk( + "PROVINCE_GET_TRADE_PANEL_ADMIN_MARKET_REQUEST", + async (d) => { + try { + const { data, status } = await axios.get( + `kill-house-market-info-dashboard`, + { + params: { ...d, role: getRoleFromUrl() || "" }, + } + ); + return { data, status }; + } catch (e) { + return { error: e.response.data.result }; + } + } +); diff --git a/src/features/province/services/province-unarchive-fee.js b/src/features/province/services/province-unarchive-fee.js new file mode 100644 index 0000000..8936204 --- /dev/null +++ b/src/features/province/services/province-unarchive-fee.js @@ -0,0 +1,18 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const provinceUnarchiveFeeService = createAsyncThunk( + "PROVINCE_UNARCHIVE_FEE_SERVICE", + async (d, { dispatch }) => { + try { + dispatch(LOADING_START()); + const { data, status } = await axios.put("province_kill_request/0/", d); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e.response.data.result }; + } + } +); diff --git a/src/features/province/services/province-update-allocate-stewards.js b/src/features/province/services/province-update-allocate-stewards.js new file mode 100644 index 0000000..7f5a52f --- /dev/null +++ b/src/features/province/services/province-update-allocate-stewards.js @@ -0,0 +1,21 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const provinceUpdateAllocateStewardsService = createAsyncThunk( + "PROVINCE_UPDATE_ALLOCATE_STEWARDS_SERVICE", + async (d, { dispatch }) => { + try { + dispatch(LOADING_START()); + const { data, status } = await axios.post( + "first-automatic-steward-allocation/", + d + ); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e.response.data.result }; + } + } +); diff --git a/src/features/province/services/province-update-killer-identity.js b/src/features/province/services/province-update-killer-identity.js new file mode 100644 index 0000000..45efd2f --- /dev/null +++ b/src/features/province/services/province-update-killer-identity.js @@ -0,0 +1,18 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const provinceUpdateKillerIdentityService = createAsyncThunk( + "PROVINCE_UPDATE_Killer_IDENTITY_SERVICE", + async (d, { dispatch }) => { + try { + dispatch(LOADING_START()); + const { data, status } = await axios.put("/kill_house/0/", d); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e.response.data.result }; + } + } +); diff --git a/src/features/province/services/province-update-killhouse-archive-percent.js b/src/features/province/services/province-update-killhouse-archive-percent.js new file mode 100644 index 0000000..a424471 --- /dev/null +++ b/src/features/province/services/province-update-killhouse-archive-percent.js @@ -0,0 +1,19 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const provinceUpdateKillhouseArchivePercentService = createAsyncThunk( + "PROVINCE_UPDATE_KILLHOUSE_ARCHIVE_PERCENT_SERVICE", + async (d, { dispatch }) => { + try { + dispatch(LOADING_START()); + const { data, status } = await axios.put("kill_house/0/", d); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e.response.data.result }; + } + } +); + diff --git a/src/features/province/services/province-update-policy-aviculture-commit.js b/src/features/province/services/province-update-policy-aviculture-commit.js new file mode 100644 index 0000000..d2fa005 --- /dev/null +++ b/src/features/province/services/province-update-policy-aviculture-commit.js @@ -0,0 +1,21 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const provinceUpdatePolicyAvicultureCommitService = createAsyncThunk( + "PROVINCE_UPDATE_POLICY_AVICULTURE_COMMIT_SERVICE", + async (d, { dispatch }) => { + try { + dispatch(LOADING_START()); + const { data, status } = await axios.put( + "free_sale_within_province/0/", + d + ); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e.response.data.result }; + } + } +); diff --git a/src/features/province/services/province-update-slaughter-identity.js b/src/features/province/services/province-update-slaughter-identity.js new file mode 100644 index 0000000..20aba71 --- /dev/null +++ b/src/features/province/services/province-update-slaughter-identity.js @@ -0,0 +1,18 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const provinceUpdateSlaughterIdentityService = createAsyncThunk( + "PROVINCE_UPDATE_SLAUGHTER_IDENTITY_SERVICE", + async (d, { dispatch }) => { + try { + dispatch(LOADING_START()); + const { data, status } = await axios.put("kill_house_percent/0/", d); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e.response.data.result }; + } + } +); diff --git a/src/features/province/services/province-update-slaughter-killplace.js b/src/features/province/services/province-update-slaughter-killplace.js new file mode 100644 index 0000000..5eab69b --- /dev/null +++ b/src/features/province/services/province-update-slaughter-killplace.js @@ -0,0 +1,18 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const provinceUpdateSlaughterKillplaceService = createAsyncThunk( + "PROVINCE_UPDATE_SLAUGHTER_KILLPLACE_SERVICE", + async (d, { dispatch }) => { + try { + dispatch(LOADING_START()); + const { data, status } = await axios.put("kill_house_percent/0/", d); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e.response.data.result }; + } + } +); diff --git a/src/features/province/services/province-upload-hatching-excel.js b/src/features/province/services/province-upload-hatching-excel.js new file mode 100644 index 0000000..2921ef6 --- /dev/null +++ b/src/features/province/services/province-upload-hatching-excel.js @@ -0,0 +1,18 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const provinceUploadHatchingExcelService = createAsyncThunk( + "PROVINCE_UPLOAD_HATCHING_EXCEL_SERVICE", + async (d, { dispatch }) => { + try { + dispatch(LOADING_START()); + const { data, status } = await axios.post("hatching_excel/", d); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e.response.data.result }; + } + } +); diff --git a/src/features/province/services/province-wage-payment-create-transaction-service.js b/src/features/province/services/province-wage-payment-create-transaction-service.js new file mode 100644 index 0000000..a7cb292 --- /dev/null +++ b/src/features/province/services/province-wage-payment-create-transaction-service.js @@ -0,0 +1,50 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const provinceWagePaymentCreateTransactionService = createAsyncThunk( + "CREATE_TRANSACTION", + async (d, { dispatch }) => { + try { + dispatch(LOADING_START()); + const { data, status } = await axios.post("internal-transactions/", d); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e.response.data.result }; + } + } +); + +export const provinceWagePaymentEditTransactionService = createAsyncThunk( + "EDIT_TRANSACTION", + async (d, { dispatch }) => { + try { + dispatch(LOADING_START()); + const { data, status } = await axios.put("internal-transactions/0/", d); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e.response.data.result }; + } + } +); + +export const provinceWagePaymentDeleteTransactionService = createAsyncThunk( + "DELETE_TRANSACTION", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + try { + const { data, status } = await axios.delete( + "internal-transactions/0/?transaction_key=" + d + ); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e.response.data.result }; + } + } +); diff --git a/src/features/province/services/province-warehouse-archive.js b/src/features/province/services/province-warehouse-archive.js new file mode 100644 index 0000000..11d77fd --- /dev/null +++ b/src/features/province/services/province-warehouse-archive.js @@ -0,0 +1,61 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const provinceWarehouseArchive = createAsyncThunk( + "PROVINCE_WAREHOUSE_ARCHIVE", + async (d) => { + const { data, status } = await axios.post("ware-house-archive/", d); + return { data, status }; + } +); + +export const provinceGetWarehouseArchive = createAsyncThunk( + "PROVINCE_GET_WAREHOUSE_ARCHIVE", + async (params, { dispatch }) => { + try { + dispatch(LOADING_START()); + const requestParams = { + date1: params?.date1, + date2: params?.date2, + search: params?.search ?? "filter", + value: params?.value ?? "", + page: params?.page ?? 1, + page_size: params?.page_size ?? 10, + }; + + if (params?.archive_type) { + requestParams.archive_type = params.archive_type; + } + + if (params?.owner_type) { + requestParams.owner_type = params.owner_type; + } + + const { data, status } = await axios.get("ware-house-archive/", { + params: requestParams, + }); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e.response?.data?.result || "خطا در دریافت اطلاعات" }; + } + } +); + +export const provinceDeleteWarehouseArchive = createAsyncThunk( + "PROVINCE_DELETE_WAREHOUSE_ARCHIVE", + async ({ key }, { dispatch }) => { + try { + dispatch(LOADING_START()); + const endpoint = "ware-house-archive/0/"; + const { data, status } = await axios.delete(`${endpoint}?key=${key}`); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e.response?.data?.result || "خطا در حذف بایگانی" }; + } + } +); diff --git a/src/features/province/services/provinceGetContradictionsData.js b/src/features/province/services/provinceGetContradictionsData.js new file mode 100644 index 0000000..fbfff81 --- /dev/null +++ b/src/features/province/services/provinceGetContradictionsData.js @@ -0,0 +1,23 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; +import { getRoleFromUrl } from "../../../utils/getRoleFromUrl"; + +export const provinceGetContradictionsData = createAsyncThunk( + "PROVINCE_GET_CONTRADICTIONS_DATA", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + try { + const { data, status } = await axios.get( + `/killing_info_discrepancy_report/?date1=${d.selectedDate1}&date2=${ + d.selectedDate2 + }&role=${getRoleFromUrl()}` + ); + dispatch(LOADING_END()); + return { data, status }; + } catch (error) { + dispatch(LOADING_END()); + throw error; + } + } +); diff --git a/src/features/province/services/provinceGetStewards.js b/src/features/province/services/provinceGetStewards.js new file mode 100644 index 0000000..5e1b1a6 --- /dev/null +++ b/src/features/province/services/provinceGetStewards.js @@ -0,0 +1,23 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; + +export const getStewards = createAsyncThunk( + "MAIN_GET_STEWARDS", + async (province) => { + const axiosInstance = axios.create(); + axiosInstance.defaults.headers.common = {}; + + const apiUrl = `https://amait.mrkiani.ir/api/report/pos/${ + province === "markazi" ? "markazi" : "hamadan" + }`; + + try { + const response = await axiosInstance.get(apiUrl); + const { data, status } = response; + return { data, status }; + } catch (error) { + console.error("Error fetching data:", error); + throw error; + } + } +); diff --git a/src/features/province/services/provinceGetTypeActivity.js b/src/features/province/services/provinceGetTypeActivity.js new file mode 100644 index 0000000..28107bf --- /dev/null +++ b/src/features/province/services/provinceGetTypeActivity.js @@ -0,0 +1,10 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; + +export const provinceGetTypeActivity = createAsyncThunk( + "PROVINCE_GET_TYPE_ACTIVITY", + async () => { + const { data, status } = await axios.get("type-activity/"); + return { data, status }; + } +); diff --git a/src/features/province/services/provinceOutRequestCancelRequest.js b/src/features/province/services/provinceOutRequestCancelRequest.js new file mode 100644 index 0000000..d904107 --- /dev/null +++ b/src/features/province/services/provinceOutRequestCancelRequest.js @@ -0,0 +1,21 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const provinceOutRequestCancelRequest = createAsyncThunk( + "PROVINCE_OUT_REQUEST_CANCEL_REQUEST", + async (d, { dispatch }) => { + try { + dispatch(LOADING_START()); + const { data, status } = await axios.put( + "cancel-out-poultry_request/0/", + d + ); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e.response.data.result }; + } + } +); diff --git a/src/features/province/services/trade-panel-chat.js b/src/features/province/services/trade-panel-chat.js new file mode 100644 index 0000000..7c8a5e9 --- /dev/null +++ b/src/features/province/services/trade-panel-chat.js @@ -0,0 +1,23 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { getRoleFromUrl } from "../../../utils/getRoleFromUrl"; + +export const tradePanelChart = createAsyncThunk( + "TRADE_PANEL_CHART", + async (d) => { + try { + const { data, status } = await axios.get( + `/direct-buying-poultry-requests-chart`, + { + params: { + role: getRoleFromUrl(), + role_key: d?.role_key || "", + }, + } + ); + return { data, status }; + } catch (e) { + return { error: e.response.data }; + } + } +); diff --git a/src/features/province/services/trade-panel-edit-market-request.js b/src/features/province/services/trade-panel-edit-market-request.js new file mode 100644 index 0000000..db20454 --- /dev/null +++ b/src/features/province/services/trade-panel-edit-market-request.js @@ -0,0 +1,18 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const provinceEditMarketRequestService = createAsyncThunk( + "PROVINCE_EDIT_MARKET_REQUEST_SERVICE", + async (d, { dispatch }) => { + try { + dispatch(LOADING_START()); + const { data, status } = await axios.put("market-requests/0/", d); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e.response.data.result }; + } + } +); diff --git a/src/features/province/services/trade-panel-get-details.js b/src/features/province/services/trade-panel-get-details.js new file mode 100644 index 0000000..68356ca --- /dev/null +++ b/src/features/province/services/trade-panel-get-details.js @@ -0,0 +1,21 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const tradePanelGetDetails = createAsyncThunk( + "TRADE_PANEL_GET_DEATILS", + async (params, { dispatch }) => { + try { + dispatch(LOADING_START()); + const { data, status } = await axios.get( + "direct-buying-poultry-hatching/", + { params } + ); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e.response?.data?.result || e.message }; + } + } +); diff --git a/src/features/province/services/trade-panel-market-request.js b/src/features/province/services/trade-panel-market-request.js new file mode 100644 index 0000000..34db6fe --- /dev/null +++ b/src/features/province/services/trade-panel-market-request.js @@ -0,0 +1,18 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const ProvinceMarketRequestService = createAsyncThunk( + "PROVINCE_MARKET_REQUEST_SERVICE", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + try { + const { data, status } = await axios.post("market-requests/", d); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e.response.data.result }; + } + } +); diff --git a/src/features/province/services/update-car-state.js b/src/features/province/services/update-car-state.js new file mode 100644 index 0000000..b84945d --- /dev/null +++ b/src/features/province/services/update-car-state.js @@ -0,0 +1,18 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const updateCarStateService = createAsyncThunk( + "UPDATE_CAR_STATE_SERVICE", + async (d, { dispatch }) => { + try { + dispatch(LOADING_START()); + const { data, status } = await axios.put("kill_house_driver/0/", d); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e.response.data.result }; + } + } +); diff --git a/src/features/province/services/update-guild-by-national-id-new.js b/src/features/province/services/update-guild-by-national-id-new.js new file mode 100644 index 0000000..749662e --- /dev/null +++ b/src/features/province/services/update-guild-by-national-id-new.js @@ -0,0 +1,24 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; +import { provinceGetGuildsService } from "./province-get-guilds"; +import { getRoleFromUrl } from "../../../utils/getRoleFromUrl"; + +export const updateGuildByNationalIdNewService = createAsyncThunk( + "UPDATE_GUILD_BY_NATIONAL_ID_NEW_SERVICE", + async (d, { dispatch }) => { + try { + dispatch(LOADING_START()); + const { data, status } = await axios.post( + "update_guild_by_national_id_new/?role=" + getRoleFromUrl(), + d + ); + dispatch(provinceGetGuildsService()); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e.response.data.result }; + } + } +); diff --git a/src/features/province/services/update-guilds-settings.js b/src/features/province/services/update-guilds-settings.js new file mode 100644 index 0000000..b9f5291 --- /dev/null +++ b/src/features/province/services/update-guilds-settings.js @@ -0,0 +1,13 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; + +export const updateGuildsSettingsService = createAsyncThunk( + "UPDATE_GUILDS_SETTINGS_SERVICE", + async (d) => { + const { data, status } = await axios.put( + "kill_house_choose_steward_guilds/0/", + d + ); + return { data, status }; + } +); diff --git a/src/features/province/services/update-kill-poultry-request.js b/src/features/province/services/update-kill-poultry-request.js new file mode 100644 index 0000000..133b138 --- /dev/null +++ b/src/features/province/services/update-kill-poultry-request.js @@ -0,0 +1,14 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; + +export const updateKillPoultryRequest = createAsyncThunk( + "UPDATE_KILL_POULTRY_REQUEST", + async (d) => { + try { + const { data, status } = await axios.put("Poultry_Request/0/", d); + return { data, status }; + } catch (e) { + return { error: e.response.data.result }; + } + } +); diff --git a/src/features/province/services/update-losses-permission.js b/src/features/province/services/update-losses-permission.js new file mode 100644 index 0000000..bada1f9 --- /dev/null +++ b/src/features/province/services/update-losses-permission.js @@ -0,0 +1,13 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const updateLossesPermissionService = createAsyncThunk( + "UPDATE_LOSSES_PERMISSION_SERVICE", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + const { data, status } = await axios.put("losses_permission/0/", d); + dispatch(LOADING_END()); + return { data, status }; + } +); diff --git a/src/features/psp-company/components/psp-active-session/PspActiveSession.js b/src/features/psp-company/components/psp-active-session/PspActiveSession.js new file mode 100644 index 0000000..f4fc01c --- /dev/null +++ b/src/features/psp-company/components/psp-active-session/PspActiveSession.js @@ -0,0 +1,202 @@ +import { useEffect, useState } from "react"; +import { useDispatch } from "react-redux"; +import { + LOADING_END, + LOADING_START, +} from "../../../../lib/redux/slices/appSlice"; +import axios from "axios"; +import { Grid } from "../../../../components/grid/Grid"; +import { SPACING } from "../../../../data/spacing"; +import { Button, TextField, Autocomplete } from "@mui/material"; +import { RiSearchLine } from "react-icons/ri"; +import ResponsiveTable from "../../../../components/responsive-table/ResponsiveTable"; +import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl"; +import { formatJustDate, formatTime } from "../../../../utils/formatTime"; + +export const PspActiveSession = () => { + const [data, setData] = useState([]); + const [totalRows, setTotalRows] = useState(0); + const [perPage, setPerPage] = useState(10); + const [textValue, setTextValue] = useState(""); + const [page, setPage] = useState(1); + const [tableData, setTableData] = useState([]); + const [companies, setCompanies] = useState([]); + const [selectedCompany, setSelectedCompany] = useState(""); + const dispatch = useDispatch(); + + const fetchCompanies = async () => { + try { + dispatch(LOADING_START()); + const response = await axios.get( + `/get_all_pos_company/?role=${getRoleFromUrl()}` + ); + setCompanies(response.data); + dispatch(LOADING_END()); + } catch (error) { + console.error("Error fetching companies:", error); + dispatch(LOADING_END()); + } + }; + + const fetchApiData = async (page) => { + let response; + dispatch(LOADING_START()); + + let url = `report-pos-device_session/?search=filter&value=${textValue}&role=${getRoleFromUrl()}&page=${page}&page_size=${perPage}`; + if (selectedCompany) { + url += `&company=${selectedCompany}`; + } + response = await axios.get(url); + + dispatch(LOADING_END()); + setData(response.data.results); + setTotalRows(response.data.count); + }; + + const handlePageChange = (page) => { + fetchApiData(page); + setPage(page); + }; + + const handlePerRowsChange = (perRows) => { + setPerPage(perRows); + setPage(1); + }; + + const handleTextChange = (event) => { + setTextValue(event.target.value); + }; + // const clearFilters = () => { + // setSelectedCompany(""); + // setTextValue(""); + // setPage(1); + // fetchApiData(1); + // }; + + useEffect(() => { + const d = data?.map((item, i) => { + return [ + page === 1 ? i + 1 : i + perPage * (page - 1) + 1, + item?.pos?.posCompany, + `${item?.pos?.userInfo?.type} (${item?.pos?.userInfo?.name})`, + `${item?.pos?.userInfo?.fullname} (${item?.pos?.userInfo?.mobile})`, + item?.pos?.userInfo?.nationalCode, + item?.pos?.posId, + item?.password, + item?.name, + formatJustDate(item?.sessionCreateDate), + formatTime(item?.sessionLastSeenDate), + item?.active ? "فعال" : "غیرفعال", + ]; + }); + + setTableData(d); + }, [data]); + + useEffect(() => { + fetchCompanies(); + fetchApiData(1); + }, [dispatch]); + + useEffect(() => { + fetchApiData(page); + }, [selectedCompany, perPage]); + + const handleSubmit = async (event) => { + event.preventDefault(); + fetchApiData(1); + }; + + const tableTitle = ( + + + {getRoleFromUrl() !== "PosCompany" && ( + { + return { + data: i, + label: `${i?.name}`, + }; + }) + : [] + } + onChange={(event, value) => { + setSelectedCompany(value?.data?.key); + }} + renderInput={(params) => ( + + )} + /> + )} + + + + + + + + + ); + + return ( + + {tableTitle} + + + ); +}; diff --git a/src/features/psp-company/components/psp-create-pos/PspCreatePos.js b/src/features/psp-company/components/psp-create-pos/PspCreatePos.js new file mode 100644 index 0000000..e260265 --- /dev/null +++ b/src/features/psp-company/components/psp-create-pos/PspCreatePos.js @@ -0,0 +1,149 @@ +import React, { useContext, useEffect } from "react"; +import { Grid } from "../../../../components/grid/Grid"; +import { Yup } from "../../../../lib/yup/yup"; +import { useFormik } from "formik"; +import { Button, TextField } from "@mui/material"; +import { SPACING } from "../../../../data/spacing"; +import { useDispatch } from "react-redux"; +import { pspSubmitPos } from "../../services/psp-submit-pos"; +import { DRAWER, LOADING_START } from "../../../../lib/redux/slices/appSlice"; +import { AppContext } from "../../../../contexts/AppContext"; + +export const PspCreatePos = ({ item, updateTable }) => { + const [openNotif] = useContext(AppContext); + const dispatch = useDispatch(); + const formik = useFormik({ + initialValues: { + reciver: "", + terminal: "", + serial: "", + password: "", + }, + validationSchema: Yup.object({ + reciver: Yup.number() + .required("این فیلد اجباری است!") + .typeError("لطفا عدد وارد کنید!"), + terminal: Yup.number() + .required("این فیلد اجباری است!") + .typeError("لطفا وزن را وارد کنید!"), + password: Yup.string() + .matches(/^\d{4}$/, "پسورد باید یک عدد 4 رقمی باشد") + .typeError("لطفا یک عدد 4 رقمی وارد کنید."), + serial: Yup.string(), + }), + }); + + useEffect(() => { + formik.validateForm(); + }, []); + + return ( + + + + + + { + const value = e.target.value.replace(/\D/g, "").slice(0, 4); + formik.setFieldValue("password", value); + }} + onBlur={formik.handleBlur} + helperText={ + formik.touched.password && Boolean(formik.errors.password) + ? formik.errors.password + : null + } + error={formik.touched.password && Boolean(formik.errors.password)} + inputProps={{ + maxLength: 4, + }} + /> + + + + ); +}; diff --git a/src/features/psp-company/components/psp-devices-v2/PspDevicesV2.js b/src/features/psp-company/components/psp-devices-v2/PspDevicesV2.js new file mode 100644 index 0000000..86ec829 --- /dev/null +++ b/src/features/psp-company/components/psp-devices-v2/PspDevicesV2.js @@ -0,0 +1,777 @@ +import { useContext, useEffect, useState } from "react"; +import { useDispatch } from "react-redux"; +import { + LOADING_END, + LOADING_START, + CLOSE_MODAL, + OPEN_MODAL, + DRAWER, +} from "../../../../lib/redux/slices/appSlice"; +import axios from "axios"; +import { Grid } from "../../../../components/grid/Grid"; +import { SPACING } from "../../../../data/spacing"; +import { + Autocomplete, + Button, + CircularProgress, + IconButton, + List, + ListItem, + ListItemIcon, + ListItemButton, + ListItemText, + Popover, + Switch, + TextField, + Typography, + Box, +} from "@mui/material"; +import { RiSearchLine } from "react-icons/ri"; +import ResponsiveTable from "../../../../components/responsive-table/ResponsiveTable"; +import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl"; +import { formatJustDate } from "../../../../utils/formatTime"; +import TuneIcon from "@mui/icons-material/Tune"; +import PersonAddAlt1RoundedIcon from "@mui/icons-material/PersonAddAlt1Rounded"; +import SwapHorizRoundedIcon from "@mui/icons-material/SwapHorizRounded"; +import AddRoundedIcon from "@mui/icons-material/AddRounded"; +import { AppContext } from "../../../../contexts/AppContext"; +import { BackButton } from "../../../../components/back-button/BackButton"; + +const PspDevicesV2 = () => { + const [data, setData] = useState([]); + const [totalRows, setTotalRows] = useState(0); + const [perPage, setPerPage] = useState(10); + const [textValue, setTextValue] = useState(""); + const [page, setPage] = useState(1); + const [tableData, setTableData] = useState([]); + const [companies, setCompanies] = useState([]); + const [selectedCompany, setSelectedCompany] = useState(""); + const dispatch = useDispatch(); + + const fetchCompanies = async () => { + try { + dispatch(LOADING_START()); + const response = await axios.get( + `/get_all_pos_company/?role=${getRoleFromUrl()}` + ); + setCompanies(response.data); + dispatch(LOADING_END()); + } catch (error) { + console.error("Error fetching companies:", error); + dispatch(LOADING_END()); + } + }; + + const fetchApiData = async (page) => { + try { + dispatch(LOADING_START()); + let url = `/user-pos-machine/?search=filter&value=${textValue}&role=${getRoleFromUrl()}&page=${page}&page_size=${perPage}`; + if (selectedCompany) { + url += `&company=${selectedCompany}`; + } + const response = await axios.get(url); + + setData(response.data?.results || []); + setTotalRows(response.data?.count || 0); + } catch (error) { + console.error("Error fetching devices:", error); + } finally { + dispatch(LOADING_END()); + } + }; + + const handlePageChange = (page) => { + fetchApiData(page); + setPage(page); + }; + + const handlePerRowsChange = (perRows) => { + setPerPage(perRows); + setPage(1); + }; + + const handleTextChange = (event) => { + setTextValue(event.target.value); + }; + // const clearFilters = () => { + // setSelectedCompany(""); + // setTextValue(""); + // setPage(1); + // fetchApiData(1); + // }; + + useEffect(() => { + const d = data?.map((item, i) => { + const owner = item?.owner || {}; + const posCompany = item?.pos_company || {}; + const hasOwner = !!item?.owner; + return [ + page === 1 ? i + 1 : i + perPage * (page - 1) + 1, + posCompany?.name || "-", + item?.serial ?? "-", + item?.receiverNumber ?? "-", + item?.terminalNumber ?? "-", + item?.password ?? "-", + item?.posUniqueId || item?.posId || "-", + owner?.fullname ? `${owner?.fullname} (${owner?.mobile ?? "-"})` : "-", + owner?.nationalId || owner?.nationalCode || "-", + item?.createDate ? formatJustDate(item?.createDate) : "-", + item?.active ? "فعال" : "غیرفعال", + { + fetchApiData(page); + }} + />, + ]; + }); + + setTableData(d); + }, [data, page, perPage]); + + useEffect(() => { + fetchCompanies(); + }, [dispatch]); + + useEffect(() => { + fetchApiData(page); + }, [selectedCompany, perPage]); + + const handleSubmit = async (event) => { + event.preventDefault(); + fetchApiData(1); + }; + + const handleDeviceCreated = () => { + setPage(1); + fetchApiData(1); + }; + + const handleOpenCreateDevice = () => { + const isMobile = window.innerWidth <= 600; + dispatch( + DRAWER({ + title: "ایجاد دستگاه", + right: !isMobile, + bottom: isMobile, + content: , + }) + ); + }; + + const tableTitle = ( + + + + {getRoleFromUrl() !== "PosCompany" && ( + { + return { + data: i, + label: `${i?.name || ""}`, + }; + }) + : [] + } + onChange={(event, value) => { + setSelectedCompany(value?.data?.key); + }} + renderInput={(params) => ( + + )} + /> + )} + + + + + + + + + + + + + + ); + + return ( + + + + {tableTitle} + + + + ); +}; + +const DeviceOperations = ({ device, hasOwner, onOwnerAssigned }) => { + const [anchorEl, setAnchorEl] = useState(null); + const [updatingStatus] = useState(false); + const [localActive, setLocalActive] = useState(!!device?.active); + const dispatch = useDispatch(); + const [openNotif] = useContext(AppContext); + + useEffect(() => { + setLocalActive(!!device?.active); + }, [device?.active]); + + const handleOpen = (event) => { + setAnchorEl(event.currentTarget); + }; + + const handleClose = () => { + setAnchorEl(null); + }; + + const handleAddOwner = () => { + handleClose(); + dispatch( + OPEN_MODAL({ + title: hasOwner ? "تغییر مالک" : "افزودن مالک", + width: "auto", + content: ( + + ), + }) + ); + }; + + const open = Boolean(anchorEl); + const id = open ? "device-operations-popover" : undefined; + const actionLabel = hasOwner ? "تغییر مالک" : "افزودن مالک"; + const ActionIcon = hasOwner ? SwapHorizRoundedIcon : PersonAddAlt1RoundedIcon; + const actionColor = hasOwner ? "warning.main" : "success.main"; + const deviceKey = device?.key || device?.id; + + const handleToggleActive = async (event) => { + event.stopPropagation(); + event.preventDefault(); + + if (!deviceKey) { + openNotif({ + vertical: "top", + horizontal: "center", + severity: "error", + msg: "شناسه دستگاه یافت نشد.", + }); + return; + } + }; + + return ( + <> + + + + + + + + + + + + + + + + + + + ); +}; + +const AssignOwnerModal = ({ device, onSuccess }) => { + const dispatch = useDispatch(); + const [openNotif] = useContext(AppContext); + const [options, setOptions] = useState([]); + const [selectedOption, setSelectedOption] = useState(null); + const [loading, setLoading] = useState(false); + const [submitting, setSubmitting] = useState(false); + const [fetchError, setFetchError] = useState(""); + + useEffect(() => { + let isMounted = true; + + const fetchOwners = async () => { + setLoading(true); + setFetchError(""); + setSelectedOption(null); + try { + const response = await axios.get("/users_for_pos/"); + + if (isMounted) { + const rawOptions = Array.isArray(response?.data?.results) + ? response?.data?.results + : Array.isArray(response?.data) + ? response?.data + : []; + + // Normalize the data + const normalizedOptions = rawOptions.map((item) => { + const fullname = item?.fullname || "-"; + const mobile = item?.mobile || ""; + const mobileLabel = mobile ? ` (${mobile})` : ""; + const label = `${fullname}${mobileLabel}`; + + return { + ...item, + label: label || "-", + }; + }); + + setOptions(normalizedOptions); + setSelectedOption( + normalizedOptions.find( + (option) => option?.mobile === device?.owner?.mobile + ) + ); + } + } catch (error) { + if (isMounted) { + setFetchError("دریافت لیست کاربران با خطا مواجه شد."); + console.error("Error fetching users:", error); + } + } finally { + if (isMounted) { + setLoading(false); + } + } + }; + + fetchOwners(); + + return () => { + isMounted = false; + }; + }, [device]); + + const handleCloseModal = () => { + dispatch(CLOSE_MODAL()); + }; + + const handleSubmit = async () => { + if (!selectedOption) { + return; + } + + if (!device?.key && !device?.id) { + openNotif({ + vertical: "top", + horizontal: "center", + severity: "error", + msg: "شناسه دستگاه یافت نشد. لطفاً دوباره تلاش کنید.", + }); + return; + } + + setSubmitting(true); + try { + const payload = { + key: device?.key || device?.id, + recipient_type: "owner", + recipient_key: selectedOption?.key || selectedOption?.id, + }; + + await axios.put("/user-pos-machine/0/", payload); + + openNotif({ + vertical: "top", + horizontal: "center", + severity: "success", + msg: "مالک با موفقیت ثبت شد.", + }); + + if (onSuccess) { + onSuccess(); + } + handleCloseModal(); + } catch (error) { + openNotif({ + vertical: "top", + horizontal: "center", + severity: "error", + msg: + error?.response?.data?.result || + error?.response?.data?.detail || + "ثبت مالک با خطا مواجه شد.", + }); + } finally { + setSubmitting(false); + } + }; + + return ( + + + دستگاه انتخاب شده:{" "} + {device?.serial || + device?.posUniqueId || + device?.posId || + device?.pos_unique_id || + device?.pos_id || + "-"} + + {loading ? ( + + + + ) : ( + option?.group || ""} + loading={loading} + loadingText="در حال دریافت..." + noOptionsText="موردی یافت نشد." + onChange={(event, value) => setSelectedOption(value)} + isOptionEqualToValue={(option, value) => option?.key === value?.key} + getOptionLabel={(option) => option?.label || ""} + renderOption={(props, option) => { + if (!option) return null; + return ( +
  • + + + {option?.label || "-"} + + {option?.city && ( + + {option.city} + + )} + +
  • + ); + }} + renderInput={(params) => ( + + {loading ? ( + + ) : null} + {params.InputProps.endAdornment} + + ), + }} + /> + )} + /> + )} + {fetchError && ( + + {fetchError} + + )} + + + + +
    + ); +}; + +const CreateDeviceDrawer = ({ onSuccess }) => { + const dispatch = useDispatch(); + const [openNotif] = useContext(AppContext); + const [values, setValues] = useState({ + receiver_number: "", + terminal_number: "", + password: "", + serial: "", + }); + const [errors, setErrors] = useState({}); + const [submitting, setSubmitting] = useState(false); + + const closeDrawer = () => { + dispatch(DRAWER({ right: false, bottom: false, content: null })); + }; + + const handleChange = (event) => { + const { name, value } = event.target; + setValues((prev) => ({ ...prev, [name]: value })); + if (errors[name]) { + setErrors((prev) => ({ ...prev, [name]: "" })); + } + }; + + const validate = () => { + const newErrors = {}; + if (!values.receiver_number?.trim()) { + newErrors.receiver_number = "وارد کردن شماره پذیرنده الزامی است."; + } + if (!values.terminal_number?.trim()) { + newErrors.terminal_number = "وارد کردن شماره ترمینال الزامی است."; + } + if (!values.password?.trim()) { + newErrors.password = "وارد کردن رمز عبور الزامی است."; + } + if (!values.serial?.trim()) { + newErrors.serial = "وارد کردن سریال دستگاه الزامی است."; + } + + setErrors(newErrors); + return Object.keys(newErrors).length === 0; + }; + + const handleSubmit = async (event) => { + event.preventDefault(); + if (!validate()) { + return; + } + + setSubmitting(true); + try { + await axios.post("/new-pos-machine/", { + receiver_number: values.receiver_number.trim(), + terminal_number: values.terminal_number.trim(), + password: values.password.trim(), + serial: values.serial.trim(), + }); + + openNotif({ + vertical: "top", + horizontal: "center", + severity: "success", + msg: "دستگاه با موفقیت ایجاد شد.", + }); + + if (onSuccess) { + onSuccess(); + } + closeDrawer(); + } catch (error) { + openNotif({ + vertical: "top", + horizontal: "center", + severity: "error", + msg: + error?.response?.data?.result || + error?.response?.data?.detail || + "ایجاد دستگاه با خطا مواجه شد.", + }); + } finally { + setSubmitting(false); + } + }; + + return ( + + + + + + + + + + + ); +}; + +export default PspDevicesV2; diff --git a/src/features/psp-company/components/psp-devices/PspDevices.js b/src/features/psp-company/components/psp-devices/PspDevices.js new file mode 100644 index 0000000..b6f10b9 --- /dev/null +++ b/src/features/psp-company/components/psp-devices/PspDevices.js @@ -0,0 +1,855 @@ +import { useContext, useEffect, useState } from "react"; +import { useDispatch } from "react-redux"; +import { + LOADING_END, + LOADING_START, + CLOSE_MODAL, + OPEN_MODAL, + DRAWER, +} from "../../../../lib/redux/slices/appSlice"; +import axios from "axios"; +import { Grid } from "../../../../components/grid/Grid"; +import { LabelField } from "../../../../components/label-field/LabelField"; +import { SPACING } from "../../../../data/spacing"; +import { + Autocomplete, + Button, + CircularProgress, + IconButton, + List, + ListItem, + ListItemIcon, + ListItemButton, + ListItemText, + Popover, + Switch, + TextField, + Typography, + FormControl, + RadioGroup, + FormControlLabel, + Radio, +} from "@mui/material"; +import { RiSearchLine } from "react-icons/ri"; +import ResponsiveTable from "../../../../components/responsive-table/ResponsiveTable"; +import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl"; +import { formatJustDate } from "../../../../utils/formatTime"; +import TuneIcon from "@mui/icons-material/Tune"; +import PersonAddAlt1RoundedIcon from "@mui/icons-material/PersonAddAlt1Rounded"; +import SwapHorizRoundedIcon from "@mui/icons-material/SwapHorizRounded"; +import AddRoundedIcon from "@mui/icons-material/AddRounded"; +import { AppContext } from "../../../../contexts/AppContext"; +import { + fetchPspGuilds, + fetchPspKillHouses, + updatePosMachineOwner, +} from "../../services/psp-device-services"; + +export const PspDevices = () => { + const [data, setData] = useState([]); + const [totalRows, setTotalRows] = useState(0); + const [perPage, setPerPage] = useState(10); + const [textValue, setTextValue] = useState(""); + const [page, setPage] = useState(1); + const [tableData, setTableData] = useState([]); + const [companies, setCompanies] = useState([]); + const [selectedCompany, setSelectedCompany] = useState(""); + const dispatch = useDispatch(); + + const fetchCompanies = async () => { + try { + dispatch(LOADING_START()); + const response = await axios.get( + `/get_all_pos_company/?role=${getRoleFromUrl()}` + ); + setCompanies(response.data); + dispatch(LOADING_END()); + } catch (error) { + console.error("Error fetching companies:", error); + dispatch(LOADING_END()); + } + }; + + const fetchApiData = async (page) => { + try { + dispatch(LOADING_START()); + let url = `/new-pos-machine/?search=filter&value=${textValue}&role=${getRoleFromUrl()}&page=${page}&page_size=${perPage}`; + if (selectedCompany) { + url += `&company=${selectedCompany}`; + } + const response = await axios.get(url); + + setData(response.data?.results || []); + setTotalRows(response.data?.count || 0); + } catch (error) { + console.error("Error fetching devices:", error); + } finally { + dispatch(LOADING_END()); + } + }; + + const handlePageChange = (page) => { + fetchApiData(page); + setPage(page); + }; + + const handlePerRowsChange = (perRows) => { + setPerPage(perRows); + setPage(1); + }; + + const handleTextChange = (event) => { + setTextValue(event.target.value); + }; + // const clearFilters = () => { + // setSelectedCompany(""); + // setTextValue(""); + // setPage(1); + // fetchApiData(1); + // }; + + useEffect(() => { + const d = data?.map((item, i) => { + const owner = item?.owner || {}; + const hasOwner = !!item?.owner; + return [ + page === 1 ? i + 1 : i + perPage * (page - 1) + 1, + item?.companyName || "-", + item?.serial ?? "-", + item?.receiverNumber ?? "-", + item?.terminalNumber ?? "-", + item?.password ?? "-", + item?.posId ?? "-", + owner?.unitName ? `${owner?.unitName}` : "-", + owner?.fullname ? `${owner?.fullname} (${owner?.mobile ?? "-"})` : "-", + owner?.licenseNumber ?? "-", + item?.createDate ? formatJustDate(item?.createDate) : "-", + item?.active ? "فعال" : "غیرفعال", + { + fetchApiData(page); + }} + />, + ]; + }); + + setTableData(d); + }, [data, page, perPage]); + + useEffect(() => { + fetchCompanies(); + fetchApiData(1); + }, [dispatch]); + + useEffect(() => { + fetchApiData(page); + }, [selectedCompany, perPage]); + + const handleSubmit = async (event) => { + event.preventDefault(); + fetchApiData(1); + }; + + const handleDeviceCreated = () => { + setPage(1); + fetchApiData(1); + }; + + const handleOpenCreateDevice = () => { + const isMobile = window.innerWidth <= 600; + dispatch( + DRAWER({ + title: "ایجاد دستگاه", + right: !isMobile, + bottom: isMobile, + content: , + }) + ); + }; + + const tableTitle = ( + + + + {getRoleFromUrl() !== "PosCompany" && ( + { + return { + data: i, + label: `${i?.name || ""}`, + }; + }) + : [] + } + onChange={(event, value) => { + setSelectedCompany(value?.data?.key); + }} + renderInput={(params) => ( + + )} + /> + )} + + + + + + + + + + + + + + ); + + return ( + + {tableTitle} + + + ); +}; + +const DeviceOperations = ({ device, hasOwner, onOwnerAssigned }) => { + const [anchorEl, setAnchorEl] = useState(null); + const [updatingStatus] = useState(false); + const [localActive, setLocalActive] = useState(!!device?.active); + const dispatch = useDispatch(); + const [openNotif] = useContext(AppContext); + + useEffect(() => { + setLocalActive(!!device?.active); + }, [device?.active]); + + const handleOpen = (event) => { + setAnchorEl(event.currentTarget); + }; + + const handleClose = () => { + setAnchorEl(null); + }; + + const handleAddOwner = () => { + handleClose(); + dispatch( + OPEN_MODAL({ + title: hasOwner ? "تغییر مالک" : "افزودن مالک", + width: "auto", + content: ( + + ), + }) + ); + }; + + const open = Boolean(anchorEl); + const id = open ? "device-operations-popover" : undefined; + const actionLabel = hasOwner ? "تغییر مالک" : "افزودن مالک"; + const ActionIcon = hasOwner ? SwapHorizRoundedIcon : PersonAddAlt1RoundedIcon; + const actionColor = hasOwner ? "warning.main" : "success.main"; + const deviceKey = device?.key || device?.id; + + const handleToggleActive = async (event) => { + event.stopPropagation(); + event.preventDefault(); + + if (!deviceKey) { + openNotif({ + vertical: "top", + horizontal: "center", + severity: "error", + msg: "شناسه دستگاه یافت نشد.", + }); + return; + } + }; + + return ( + <> + + + + + + + + + + + + + + + + + + + ); +}; + +const AssignOwnerModal = ({ device, onSuccess }) => { + const dispatch = useDispatch(); + const [openNotif] = useContext(AppContext); + const [options, setOptions] = useState([]); + const [selectedOption, setSelectedOption] = useState(null); + const [loading, setLoading] = useState(false); + const [submitting, setSubmitting] = useState(false); + const [fetchError, setFetchError] = useState(""); + const [ownerType, setOwnerType] = useState("guild"); + + useEffect(() => { + let isMounted = true; + + const fetchOwners = async () => { + setLoading(true); + setFetchError(""); + setSelectedOption(null); + try { + let response; + if (ownerType === "kill_house") { + response = await fetchPspKillHouses(); + } else { + response = await fetchPspGuilds(getRoleFromUrl()); + } + + if (isMounted) { + const rawOptions = Array.isArray(response?.data?.results) + ? response?.data?.results + : Array.isArray(response?.data) + ? response?.data + : []; + + let normalizedOptions; + if (ownerType === "kill_house") { + // Normalize kill house data + normalizedOptions = rawOptions.map((item) => { + const typeLabel = item?.killer ? "کشتارکن" : "کشتارگاه"; + const primaryLabel = item?.unitName || item?.fullname || "-"; + const mobileLabel = item?.mobile ? ` (${item.mobile})` : ""; + return { + ...item, + label: `${primaryLabel}${mobileLabel}`, + meta: typeLabel, + group: "", + }; + }); + } else { + // Normalize guild data + normalizedOptions = rawOptions.map((item) => { + const typeLabel = item?.steward ? "مباشر" : "صنف"; + const primaryLabel = + item?.guildsName || item?.user?.fullname || "-"; + const mobileLabel = item?.user?.mobile + ? ` (${item.user.mobile})` + : ""; + return { + ...item, + label: `${primaryLabel}${mobileLabel}`, + meta: typeLabel, + group: "", + }; + }); + } + + setOptions(normalizedOptions); + setSelectedOption( + normalizedOptions.find( + (option) => + option?.user?.mobile === device?.owner?.mobile || + option?.mobile === device?.owner?.mobile + ) + ); + } + } catch (error) { + if (isMounted) { + setFetchError("دریافت لیست مالک‌ها با خطا مواجه شد."); + } + } finally { + if (isMounted) { + setLoading(false); + } + } + }; + + fetchOwners(); + + return () => { + isMounted = false; + }; + }, [ownerType]); + + const handleCloseModal = () => { + dispatch(CLOSE_MODAL()); + }; + + const handleSubmit = async () => { + if (!selectedOption) { + return; + } + + if (!device?.key && !device?.id) { + openNotif({ + vertical: "top", + horizontal: "center", + severity: "error", + msg: "شناسه دستگاه یافت نشد. لطفاً دوباره تلاش کنید.", + }); + return; + } + + setSubmitting(true); + try { + let owner_type; + if (ownerType === "kill_house") { + owner_type = "kill_house"; + } else { + owner_type = selectedOption?.steward ? "Steward" : "Guilds"; + } + + const payload = { + key: device?.key || device?.id, + owner_type: owner_type, + owner_key: selectedOption?.key, + }; + + await updatePosMachineOwner(payload); + + openNotif({ + vertical: "top", + horizontal: "center", + severity: "success", + msg: "مالک با موفقیت ثبت شد.", + }); + + if (onSuccess) { + onSuccess(); + } + handleCloseModal(); + } catch (error) { + openNotif({ + vertical: "top", + horizontal: "center", + severity: "error", + msg: + error?.response?.data?.result || + error?.response?.data?.detail || + "ثبت مالک با خطا مواجه شد.", + }); + } finally { + setSubmitting(false); + } + }; + + return ( + + + دستگاه انتخاب شده: {device?.serial || device?.posId || "-"} + + + + setOwnerType(e.target.value)} + > + } + label="صنف / مباشر" + /> + } + label="کشتارگاه / کشتارکن" + /> + + + + {loading ? ( + + + + ) : ( + option?.group || ""} + loading={loading} + loadingText="در حال دریافت..." + noOptionsText="موردی یافت نشد." + onChange={(event, value) => setSelectedOption(value)} + isOptionEqualToValue={(option, value) => option?.key === value?.key} + getOptionLabel={(option) => option?.label || ""} + renderOption={(props, option) => { + if (!option) return null; + return ( +
  • + + {ownerType === "kill_house" ? ( + <> + + {`${option?.unitName || option?.fullname || ""}${ + option?.mobile ? ` (${option.mobile})` : "" + }`} + + + {`${option?.meta || ""}${ + option?.city ? ` | ${option.city}` : "" + }`.replace(/^ \| /, "")} + + + ) : ( + <> + + {`${option?.guildsName || ""}${ + option?.user?.mobile ? ` (${option.user.mobile})` : "" + }`} + + + {`${option?.typeActivity || ""}${ + option?.areaActivity + ? ` | ${option.areaActivity}` + : "" + }${option?.user?.city ? ` | ${option.user.city}` : ""}${ + option?.licenseNumber + ? ` | شناسه : ${option.licenseNumber}` + : "" + }`.replace(/^ \| /, "")} + + + )} + +
  • + ); + }} + renderInput={(params) => ( + + {loading ? ( + + ) : null} + {params.InputProps.endAdornment} + + ), + }} + /> + )} + /> + )} + {fetchError && ( + + {fetchError} + + )} + + + + +
    + ); +}; + +const CreateDeviceDrawer = ({ onSuccess }) => { + const dispatch = useDispatch(); + const [openNotif] = useContext(AppContext); + const [values, setValues] = useState({ + receiver_number: "", + terminal_number: "", + password: "", + serial: "", + }); + const [errors, setErrors] = useState({}); + const [submitting, setSubmitting] = useState(false); + + const closeDrawer = () => { + dispatch(DRAWER({ right: false, bottom: false, content: null })); + }; + + const handleChange = (event) => { + const { name, value } = event.target; + setValues((prev) => ({ ...prev, [name]: value })); + if (errors[name]) { + setErrors((prev) => ({ ...prev, [name]: "" })); + } + }; + + const validate = () => { + const newErrors = {}; + if (!values.receiver_number?.trim()) { + newErrors.receiver_number = "وارد کردن شماره پذیرنده الزامی است."; + } + if (!values.terminal_number?.trim()) { + newErrors.terminal_number = "وارد کردن شماره ترمینال الزامی است."; + } + if (!values.password?.trim()) { + newErrors.password = "وارد کردن رمز عبور الزامی است."; + } + if (!values.serial?.trim()) { + newErrors.serial = "وارد کردن سریال دستگاه الزامی است."; + } + + setErrors(newErrors); + return Object.keys(newErrors).length === 0; + }; + + const handleSubmit = async (event) => { + event.preventDefault(); + if (!validate()) { + return; + } + + setSubmitting(true); + try { + await axios.post("/new-pos-machine/", { + receiver_number: values.receiver_number.trim(), + terminal_number: values.terminal_number.trim(), + password: values.password.trim(), + serial: values.serial.trim(), + }); + + openNotif({ + vertical: "top", + horizontal: "center", + severity: "success", + msg: "دستگاه با موفقیت ایجاد شد.", + }); + + if (onSuccess) { + onSuccess(); + } + closeDrawer(); + } catch (error) { + openNotif({ + vertical: "top", + horizontal: "center", + severity: "error", + msg: + error?.response?.data?.result || + error?.response?.data?.detail || + "ایجاد دستگاه با خطا مواجه شد.", + }); + } finally { + setSubmitting(false); + } + }; + + return ( + + + + + + + + + + + ); +}; diff --git a/src/features/psp-company/components/psp-manage-guilds-operation/PspManageGuildsOperation.js b/src/features/psp-company/components/psp-manage-guilds-operation/PspManageGuildsOperation.js new file mode 100644 index 0000000..3031df4 --- /dev/null +++ b/src/features/psp-company/components/psp-manage-guilds-operation/PspManageGuildsOperation.js @@ -0,0 +1,201 @@ +import { IconButton, Popover, Tooltip, Box } from "@mui/material"; +import { Grid } from "../../../../components/grid/Grid"; +import { useState } from "react"; +import TuneIcon from "@mui/icons-material/Tune"; +import { PspSubmitGuildCondition } from "../psp-submit-guild-condition/PspSubmitGuildCondition"; +import { useDispatch } from "react-redux"; +import EditIcon from "@mui/icons-material/Edit"; +import { PspPosList } from "../psp-pos-list/PspPosList"; +import { PspCreatePos } from "../psp-create-pos/PspCreatePos"; +import { DRAWER, OPEN_MODAL } from "../../../../lib/redux/slices/appSlice"; +import AddIcon from "@mui/icons-material/Add"; +import RemoveRedEyeIcon from "@mui/icons-material/RemoveRedEye"; +export const PspManageGuildsOperation = ({ + item, + // selectedAge1, + // selectedAge2, + updateTable, + // readOnly, +}) => { + const [anchorEl, setAnchorEl] = useState(null); + const dispatch = useDispatch(); + + const handleClick = (event) => { + setAnchorEl(event.currentTarget); + }; + + const handleClose = () => { + setAnchorEl(null); + }; + + const open = Boolean(anchorEl); + const id = open ? "popover" : undefined; + + return ( +
    + + + + + + + {/* مشاهده دستگاه‌های POS */} + {item?.numberOfPos > 0 && ( + + + { + handleClose(); + dispatch( + DRAWER({ + title: "جزئیات کارتخوان", + top: !(window.innerWidth <= 600), + bottom: window.innerWidth <= 600, + content: ( + + ), + }) + ); + }} + > + + + + + )} + + {/* ثبت دستگاه POS */} + + + { + handleClose(); + dispatch( + DRAWER({ + title: "ایجاد دستگاه", + right: !(window.innerWidth <= 600), + bottom: window.innerWidth <= 600, + content: ( + + ), + }) + ); + }} + > + + + + + + {/* توضیحات وضعیت */} + {/* + + { + handleClose(); + dispatch( + OPEN_MODAL({ + title: "مشاهده توضیحات", + content: ( + + توضیحات: {item.descriptionCondition} + + ), + }) + ); + }} + > + + {item.condition} + + + + */} + + {/* ثبت/ویرایش وضعیت صنف */} + + + { + handleClose(); + dispatch( + OPEN_MODAL({ + title: "ثبت توضیحات", + content: ( + + ), + }) + ); + }} + > + + + + + + + +
    + ); +}; diff --git a/src/features/psp-company/components/psp-manage-guilds/PspManageGuilds.js b/src/features/psp-company/components/psp-manage-guilds/PspManageGuilds.js new file mode 100644 index 0000000..5cd28e0 --- /dev/null +++ b/src/features/psp-company/components/psp-manage-guilds/PspManageGuilds.js @@ -0,0 +1,351 @@ +import React, { useEffect, useState } from "react"; +import { Button, TextField, Tooltip } from "@mui/material"; +import { OPEN_MODAL } from "../../../../lib/redux/slices/appSlice"; +import { useDispatch, useSelector } from "react-redux"; +import axios from "axios"; +import { RiFileExcel2Fill, RiSearchLine } from "react-icons/ri"; +import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl"; +import { + LOADING_END, + LOADING_START, +} from "../../../../lib/redux/slices/appSlice"; +import { Grid } from "../../../../components/grid/Grid"; +import ResponsiveTable from "../../../../components/responsive-table/ResponsiveTable"; +import { SPACING } from "../../../../data/spacing"; +import { CreateGuilds } from "../../../province/components/create-guilds/CreateGuilds"; +import { PspManageGuildsOperation } from "../psp-manage-guilds-operation/PspManageGuildsOperation"; +// import { PspPosList } from "../psp-pos-list/PspPosList"; +// import { PspCreatePos } from "../psp-create-pos/PspCreatePos"; +// import { PspSubmitGuildCondition } from "../psp-submit-guild-condition/PspSubmitGuildCondition"; +// import { PspSessions } from "../psp-sessions/PspSessions"; + +export const PspManageGuilds = () => { + const [data, setData] = useState([]); + const [totalRows, setTotalRows] = useState(0); + const [perPage, setPerPage] = useState(10); + const [textValue, setTextValue] = useState(""); + const [page, setPage] = useState(1); + const [tableData, setTableData] = useState([]); + const dispatch = useDispatch(); + + const userInfo = useSelector((state) => state.userSlice); + + const fetchApiData = async (page) => { + let response; + dispatch(LOADING_START()); + response = await axios.get( + `total_guilds_for_companies/?search=filter&value=${textValue}&role=${getRoleFromUrl()}&page=${page}&page_size=${perPage}` + ); + + dispatch(LOADING_END()); + setData(response.data.results); + setTotalRows(response.data.count); + }; + + const handlePageChange = (page) => { + fetchApiData(page); + setPage(page); + }; + + const handlePerRowsChange = (perRows) => { + setPerPage(perRows); + setPage(1); + }; + + const updateTable = () => { + fetchApiData(page !== 0 ? page : 1); + }; + + const handleTextChange = (event) => { + setTextValue(event.target.value); + }; + useEffect(() => { + const d = data?.map((item, i) => { + return [ + page === 1 ? i + 1 : i + perPage * (page - 1) + 1, + item.guildsId, + item?.guildsName, + `${item?.user?.fullname} (${item?.user?.mobile})`, + item?.user?.nationalId, + item?.typeActivity, + item?.areaActivity, + `${item?.user?.province}/${item?.user?.city}/${ + item?.user?.address ? item?.user?.address : "" + }`, + item?.steward ? "می باشد" : "نمی باشد", + item?.provinceAcceptState === "accepted" + ? "تایید شده" + : item?.provinceAcceptState === "rejected" + ? "رد شده" + : "در انتظار تایید", + + `${item?.condition || "توضیحاتی وجود ندارد"} (${ + item?.descriptionCondition + })`, + + // , + , + // + // + // {/* {item?.numberOfPos ? ( + // + // ) : ( + // "" + // )} */} + + // + // + // + // + // + // { + // dispatch( + // OPEN_MODAL({ + // title: "مشاهده توضیحات", + // content: ( + // + // توضیحات: {item.descriptionCondition} + // + // ), + // }) + // ); + // }} + // > + // {item.condition} + // + // + + // + // + // + // , + ]; + }); + + setTableData(d); + }, [data]); + + useEffect(() => { + fetchApiData(1); + }, [dispatch, perPage]); + + const handleSubmit = async (event) => { + event.preventDefault(); + dispatch(LOADING_START()); + + try { + const response = await axios.get( + `total_guilds_for_companies/?role=${getRoleFromUrl()}&search=filter&value=${textValue}` + ); + + setData(response.data.results); + setTotalRows(response.data.count); + dispatch(LOADING_END()); + } catch (error) { + console.error("Error fetching data:", error); + } + }; + + const tableTitle = ( + + +
    + + + + + + + + + +
    + + + + + + +
    +
    + ); + + return ( + + {tableTitle} + + + ); +}; diff --git a/src/features/psp-company/components/psp-operations/PspOperations.js b/src/features/psp-company/components/psp-operations/PspOperations.js new file mode 100644 index 0000000..68e2102 --- /dev/null +++ b/src/features/psp-company/components/psp-operations/PspOperations.js @@ -0,0 +1,108 @@ +import { Grid } from "../../../../components/grid/Grid"; +import { SPACING } from "../../../../data/spacing"; +import { NavLink } from "../../../../components/nav-link/NavLink"; +import { useLocation } from "react-router-dom"; +import { + ROUTE_ADMINX_COMPANY_ROUTE_ACTIVE_SESSION, + ROUTE_ADMINX_COMPANY_ROUTE_DEVICES, + ROUTE_PSP_COMPANY_ROUTE_ACTIVE_SESSION, + ROUTE_PSP_COMPANY_ROUTE_DEVICES, + ROUTE_PSP_COMPANY_ROUTE_DEVICES_V2, + ROUTE_SUPER_ADMIN_COMPANY_ROUTE_ACTIVE_SESSION, + ROUTE_SUPER_ADMIN_COMPANY_ROUTE_DEVICES, + // ROUTE_PSP_COMPANY_ROUTE_GUILDS, +} from "../../../../routes/routes"; +import LinkItem from "../../../../components/link-item/LinkItem"; +// import { MdCorporateFare } from "react-icons/md"; +import { FaFax, FaMobileAlt } from "react-icons/fa"; +import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl"; +export const PspOperations = () => { + const { pathname } = useLocation(); + + return ( + + + } + title="دستگاه‌ها دوم" + /> + + + } + title="دستگاه ها" + /> + + {/* + } + title="اصناف" + /> + */} + + } + title="نشست های فعال" + /> + + + ); +}; diff --git a/src/features/psp-company/components/psp-pos-list/PspPosList.js b/src/features/psp-company/components/psp-pos-list/PspPosList.js new file mode 100644 index 0000000..690a09c --- /dev/null +++ b/src/features/psp-company/components/psp-pos-list/PspPosList.js @@ -0,0 +1,359 @@ +import React, { useContext, useState } from "react"; +import { + Switch, + Tooltip, + Typography, + Box, + Button, + Paper, + useTheme, + IconButton, +} from "@mui/material"; +import { useDispatch } from "react-redux"; +import { pspChangePosActiveState } from "../../services/psp-change-pos-active-state"; +import { AppContext } from "../../../../contexts/AppContext"; +import { + CLOSE_MODAL, + DRAWER, + OPEN_MODAL, +} from "../../../../lib/redux/slices/appSlice"; +import ArrowBackIcon from "@mui/icons-material/ArrowBack"; +import { motion, AnimatePresence } from "framer-motion"; +import { AdvancedTable } from "../../../../components/advanced-table/AdvancedTable"; +import { formatJustDate } from "../../../../utils/formatTime"; +import { Grid } from "../../../../components/grid/Grid"; +import { SimpleTable } from "../../../../components/simple-table/SimpleTable"; +import InfoIcon from "@mui/icons-material/Info"; +import CardMembershipIcon from "@mui/icons-material/CardMembership"; +import DeleteIcon from "@mui/icons-material/Delete"; +import { pspRemoveSession } from "../../services/psp-remove-session"; + +export const PspPosList = ({ item, updateTable }) => { + const dispatch = useDispatch(); + const [openNotif] = useContext(AppContext); + const [showDetail, setShowDetail] = useState(false); + const [posInfo, setPosInfo] = useState(null); + + const handleDeleteSession = (sessionKey) => { + dispatch( + OPEN_MODAL({ + title: "آیا مطمئن هستید؟", + content: ( + + + + + + + + + ), + }) + ); + }; + const theme = useTheme(); + + const tableData = item?.guildPos.map((pos, index) => [ + index + 1, + pos.receiverNumber || "-", + pos.terminalNumber || "-", + pos.serial || "-", + pos.posId || "-", + pos.password || "-", + pos.posCompany || "-", + pos?.posSessions?.length > 0 + ? formatJustDate(pos.posSessions[0]?.sessionCreateDate) + : "-", + pos?.posSessions?.length > 0 + ? formatJustDate(pos.posSessions[0]?.sessionLastSeenDate) + : "-", + + {pos?.posStatus ? "در حال استفاده" : "خاموش"} + + , + , + + { + dispatch( + pspChangePosActiveState({ + pos_key: pos.key, + active: !pos.active, + }) + ).then((r) => { + updateTable(); + dispatch(DRAWER({ top: false, bottom: false, content: null })); + if (r.error) { + openNotif({ + vertical: "top", + horizontal: "center", + msg: "مشکلی پیش آمده است!", + severity: "error", + }); + } else { + openNotif({ + vertical: "top", + horizontal: "center", + msg: "عملیات با موفقیت انجام شد.", + severity: "success", + }); + } + }); + }} + /> + , + ]); + + // neshast + const sessionsData = posInfo?.posSessions + ?.sort((a, b) => { + const dateA = new Date( + a.sessionLastSeenDate || a.sessionCreateDate + ).getTime(); + const dateB = new Date( + b.sessionLastSeenDate || b.sessionCreateDate + ).getTime(); + return dateB - dateA; + }) + ?.map((session, i) => { + const oneWeekAgo = new Date(); + oneWeekAgo.setDate(oneWeekAgo.getDate() - 7); + + const sessionDate = new Date( + session.sessionLastSeenDate || session.sessionCreateDate + ); + + const isLessThanOneWeek = sessionDate > oneWeekAgo; + + return [ + i + 1, + session.name || "-", + session.serial || "-", + + {formatJustDate(session.sessionCreateDate || "-")} + , + + {formatJustDate(session.sessionLastSeenDate || "-")} + , + + + { + handleDeleteSession(session.key); + }} + > + + + + , + ]; + }); + + return ( + + + {!showDetail ? ( + + + + + + اطلاعات دستگاه‌های POS + + + ({item?.guildPos?.length || 0} دستگاه ثبت شده) + + + + } + columns={[ + "ردیف", + "شماره پذیرنده", + "شماره ترمینال", + "سریال دستگاه", + "کلید اتصال", + "کلمه عبور امنیتی", + "نام دستگاه", + "اولین ورود", + "آخرین بازدید", + "وضعیت", + "نشست‌ها", + "فعال/غیرفعال", + ]} + data={tableData || []} + sx={{ + "& .MuiTableCell-root": { + py: 1.5, + }, + "& .MuiTableHead-root": { + backgroundColor: theme.palette.grey[100], + }, + }} + /> + + + ) : ( + + + + + + + + نشست‌های فعال دستگاه + {" "} + {posInfo?.receiverNumber} + + + + + + + + + + + + )} + + + ); +}; diff --git a/src/features/psp-company/components/psp-sessions/PspSessions.js b/src/features/psp-company/components/psp-sessions/PspSessions.js new file mode 100644 index 0000000..0fc9d58 --- /dev/null +++ b/src/features/psp-company/components/psp-sessions/PspSessions.js @@ -0,0 +1,145 @@ +import React, { useContext } from "react"; +import { + Grid, + Card, + CardContent, + Button, + Typography, + Divider, + Box, +} from "@mui/material"; +import { useDispatch } from "react-redux"; +import { AppContext } from "../../../../contexts/AppContext"; +import { pspRemoveSession } from "../../services/psp-remove-session"; +import { DRAWER } from "../../../../lib/redux/slices/appSlice"; +import { formatJustDate } from "../../../../utils/formatTime"; + +export const PspSessions = ({ item, updateTable }) => { + const dispatch = useDispatch(); + const [openNotif] = useContext(AppContext); + + return ( + + {item?.guildPos?.map((item, i) => ( + + + + + شناسه: {item?.posId} + + + شماره ترمینال: {item?.terminalNumber} + + {!!item?.posSessions?.length && ( + <> + + + نشست های فعال: + + + )} + {item?.posSessions?.map((option, index) => ( + + + {index + 1} - نام: + + {option?.name} + + + + + سریال دستگاه : + + {option?.serial || "-"} + + + + تاریخ اولین ورود : + + {formatJustDate(option?.sessionCreateDate) || "-"} + + + + زمان آخرین بازدید : + + {formatJustDate(option?.sessionLastSeenDate) || "-"} + + + + کلمه عبور : + + {option?.password} + + + + + ))} + + + + ))} + + ); +}; diff --git a/src/features/psp-company/components/psp-submit-guild-condition/PspSubmitGuildCondition.js b/src/features/psp-company/components/psp-submit-guild-condition/PspSubmitGuildCondition.js new file mode 100644 index 0000000..d6ea087 --- /dev/null +++ b/src/features/psp-company/components/psp-submit-guild-condition/PspSubmitGuildCondition.js @@ -0,0 +1,139 @@ +import React, { useContext, useEffect } from "react"; +import { Grid } from "../../../../components/grid/Grid"; +import { + Button, + FormControl, + FormHelperText, + InputLabel, + MenuItem, + Select, + TextField, +} from "@mui/material"; +import { useFormik } from "formik"; +import { Yup } from "../../../../lib/yup/yup"; +import { useDispatch } from "react-redux"; +import { pspSubmitGuildGuildCondition } from "../../services/psp-submit-guild-condition"; +import { AppContext } from "../../../../contexts/AppContext"; +import { CLOSE_MODAL } from "../../../../lib/redux/slices/appSlice"; + +export const PspSubmitGuildCondition = ({ item, updateTable }) => { + const [openNotif] = useContext(AppContext); + + const dispatch = useDispatch(); + const formik = useFormik({ + initialValues: { + condition: item.condition ? item.condition : "مرجوع شده", + description: item.descriptionCondition ? item.descriptionCondition : "", + }, + validationSchema: Yup.object({ + description: Yup.string() + .required("این فیلد اجباری است!") + .typeError("لطفا توضیحات را وارد کنید."), + }), + }); + + useEffect(() => { + formik.validateForm(); + }, []); + + return ( + + + + وضعیت + + + {formik.touched.condition && Boolean(formik.errors.condition) + ? formik.errors.condition + : null} + + + + + + + + + + + ); +}; diff --git a/src/features/psp-company/services/psp-change-pos-active-state.js b/src/features/psp-company/services/psp-change-pos-active-state.js new file mode 100644 index 0000000..b0ffad3 --- /dev/null +++ b/src/features/psp-company/services/psp-change-pos-active-state.js @@ -0,0 +1,18 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const pspChangePosActiveState = createAsyncThunk( + "PSP_CHANGE_POS_ACTIVE_STATE", + async (d, { dispatch }) => { + try { + dispatch(LOADING_START()); + const { data, status } = await axios.put("/pos-machine/0/", d); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e.response.data.result }; + } + } +); diff --git a/src/features/psp-company/services/psp-device-services.js b/src/features/psp-company/services/psp-device-services.js new file mode 100644 index 0000000..4b1eb79 --- /dev/null +++ b/src/features/psp-company/services/psp-device-services.js @@ -0,0 +1,32 @@ +import axios from "axios"; + +/** + * Fetch guilds/owners list for PSP POS devices + * @param {string} role - The role from URL + * @returns {Promise} Axios promise with guilds data + */ +export const fetchPspGuilds = async (role) => { + const response = await axios.get( + `/guilds/?role=${role}&page_size=1000&psp_pos=true` + ); + return response; +}; + +/** + * Fetch kill houses list for PSP POS devices + * @returns {Promise} Axios promise with kill houses data + */ +export const fetchPspKillHouses = async () => { + const response = await axios.get(`/kill_house/?psp=true`); + return response; +}; + +/** + * Update POS machine owner + * @param {Object} payload - The payload containing device key, owner type, and owner key + * @returns {Promise} Axios promise with update response + */ +export const updatePosMachineOwner = async (payload) => { + const response = await axios.put(`/new-pos-machine/0/`, payload); + return response; +}; diff --git a/src/features/psp-company/services/psp-remove-session.js b/src/features/psp-company/services/psp-remove-session.js new file mode 100644 index 0000000..c5967b4 --- /dev/null +++ b/src/features/psp-company/services/psp-remove-session.js @@ -0,0 +1,15 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const pspRemoveSession = createAsyncThunk( + "PSP_REMOVE_SESSION", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + const { data, status } = await axios.delete( + "pos_register_session_inspection/0/?session_key=" + d + ); + dispatch(LOADING_END()); + return { data, status }; + } +); diff --git a/src/features/psp-company/services/psp-submit-guild-condition.js b/src/features/psp-company/services/psp-submit-guild-condition.js new file mode 100644 index 0000000..0258d53 --- /dev/null +++ b/src/features/psp-company/services/psp-submit-guild-condition.js @@ -0,0 +1,21 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const pspSubmitGuildGuildCondition = createAsyncThunk( + "PSP_SUBMIT_GUILD_CONDITION", + async (d, { dispatch }) => { + try { + dispatch(LOADING_START()); + const { data, status } = await axios.put( + "total_guilds_for_companies/0/", + d + ); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e.response.data.result }; + } + } +); diff --git a/src/features/psp-company/services/psp-submit-pos.js b/src/features/psp-company/services/psp-submit-pos.js new file mode 100644 index 0000000..b13dd91 --- /dev/null +++ b/src/features/psp-company/services/psp-submit-pos.js @@ -0,0 +1,14 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const pspSubmitPos = createAsyncThunk( + "PSP_SUBMIT_POS", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + const { data, status } = await axios.post("pos-machine/", d); + dispatch(LOADING_END()); + + return { data, status }; + } +); diff --git a/src/features/senf/components/SenfEnterToWarehouse.js b/src/features/senf/components/SenfEnterToWarehouse.js new file mode 100644 index 0000000..9da4581 --- /dev/null +++ b/src/features/senf/components/SenfEnterToWarehouse.js @@ -0,0 +1,5 @@ +import { SlaughterStockWrapper } from "../../slaughter-house/components/slaughter-stock-wrapper/SlaughterStockWrapper"; + +export const SenfEnterToWarehouse = () => { + return ; +}; diff --git a/src/features/senf/components/SenfInventoryOperation.js b/src/features/senf/components/SenfInventoryOperation.js new file mode 100644 index 0000000..4a5ee26 --- /dev/null +++ b/src/features/senf/components/SenfInventoryOperation.js @@ -0,0 +1,54 @@ +import { VscNewFolder } from "react-icons/vsc"; +import { useLocation } from "react-router-dom"; +import { Grid } from "../../../components/grid/Grid"; +import LinkItem from "../../../components/link-item/LinkItem"; +import { NavLink } from "../../../components/nav-link/NavLink"; +import { SPACING } from "../../../data/spacing"; +import { + ROUTE_SENF_INVENTORY_SEGMENTATION, + ROUTE_SENF_INVENTORY_STOCK, +} from "../../../routes/routes"; +import ContentCutIcon from "@mui/icons-material/ContentCut"; + +export const SenfInventoryOperation = () => { + const { pathname } = useLocation(); + + return ( + + + } + title="ورود به انبار" + /> + + {/* + } + title="ورود به انبار" + /> + */} + + } + title="قطعه بندی" + /> + + + ); +}; diff --git a/src/features/senf/components/SenfSegmentaion.js b/src/features/senf/components/SenfSegmentaion.js new file mode 100644 index 0000000..d00e8ef --- /dev/null +++ b/src/features/senf/components/SenfSegmentaion.js @@ -0,0 +1,320 @@ +import { useContext, useEffect, useState } from "react"; +import { useDispatch, useSelector } from "react-redux"; +import moment from "moment"; +import { Button, TextField, Typography } from "@mui/material"; +import { DatePicker } from "@mui/x-date-pickers"; +import { RiSearchLine } from "react-icons/ri"; +import axios from "axios"; +import { AppContext } from "../../../contexts/AppContext"; +import { + DRAWER, + LOADING_END, + LOADING_START, +} from "../../../lib/redux/slices/appSlice"; +import { formatJustDate, formatTime } from "../../../utils/formatTime"; +import { StewardSegmentOperation } from "../../guild/components/StewardSegmentOperation"; +import { getRoleFromUrl } from "../../../utils/getRoleFromUrl"; +import { Grid } from "../../../components/grid/Grid"; +import { SPACING } from "../../../data/spacing"; +import ResponsiveTable from "../../../components/responsive-table/ResponsiveTable"; +import { checkPathStartsWith } from "../../../utils/checkPathStartsWith"; +import { stawardGetSegmentDashboardService } from "../../guild/services/steward-get-dashboard-service"; +import { stewardGetOutSellService } from "../../guild/services/steward-get-sell-out-service"; +import { StewardSegmentSubmitOperation } from "../../guild/components/StewardSegmentSubmitOperation"; + +export const SenfSegmentaion = () => { + const [data, setData] = useState([]); + const [products, setProducts] = useState([]); + const [tableData, setTableData] = useState([]); + const [totalRows, setTotalRows] = useState(0); + const [perPage, setPerPage] = useState(10); + const [textValue, setTextValue] = useState(""); + const [page, setPage] = useState(1); + const [dashboardData, setDashboardData] = useState([]); + const selectedSubUser = useSelector( + (state) => state.userSlice.selectedSubUser + ); + const [, , selectedDate1, setSelectedDate1, selectedDate2, setSelectedDate2] = + useContext(AppContext); + const dispatch = useDispatch(); + + // const userKey = useSelector((state) => state.userSlice.userProfile.key); + + const getDashboardData = () => { + dispatch( + stawardGetSegmentDashboardService({ + value: textValue, + date1: selectedDate1, + date2: selectedDate2, + role: getRoleFromUrl(), + role_key: + checkPathStartsWith("slaughter") || checkPathStartsWith("senf") + ? selectedSubUser?.key + : "", + }) + ).then((r) => { + setDashboardData(r.payload.data); + }); + }; + + useEffect(() => { + const currentDate = moment(new Date()).format("YYYY-MM-DD"); + setSelectedDate1(currentDate); + setSelectedDate2(currentDate); + }, []); + + const fetchApiData = async (page) => { + dispatch(LOADING_START()); + const response = await axios.get( + `app-segmentation/?search=filter&value=${textValue}&date1=${selectedDate1}&date2=${selectedDate2}&page=${page}&page_size=${perPage}&role=${getRoleFromUrl()}${ + checkPathStartsWith("slaughter") || checkPathStartsWith("senf") + ? `&role_key=${selectedSubUser?.key}` + : "" + }` + ); + + getDashboardData(); + dispatch(LOADING_END()); + setData(response.data.results); + setTotalRows(response.data.count); + }; + + const handlePageChange = (page) => { + fetchApiData(page); + setPage(page); + }; + const updateTable = () => { + fetchApiData(page); + }; + + const handlePerRowsChange = (perRows) => { + setPerPage(perRows); + setPage(1); + }; + + const handleTextChange = (event) => { + setTextValue(event.target.value); + }; + + useEffect(() => { + fetchApiData(1); + dispatch( + stewardGetOutSellService({ + role_key: + checkPathStartsWith("slaughter") || checkPathStartsWith("senf") + ? selectedSubUser?.key || "" + : "", + }) + ).then((r) => { + setProducts(r.payload.data); + }); + }, []); + + useEffect(() => { + const d = data?.map((item, i) => { + return [ + page === 1 ? i + 1 : i + perPage * (page - 1) + 1, + item?.productionDate ? formatTime(item?.productionDate) : "-", + item?.distributionType === "web" + ? "سایت" + : item?.distributionType === "app" + ? "موبایل" + : item?.distributionType === "pos" + ? "پوز" + : item?.distributionType || "-", + `${item?.buyer?.fullname}(${item?.buyer?.mobile})`, + item?.toGuild + ? `به قطعه بند - ${item?.toGuild?.user?.fullname}(${item?.toGuild?.user?.mobile})` + : "قطعه بندی توسط کشتارگاه", + item?.date ? formatJustDate(item?.date) : "-", + item?.weight, + item?.quota === "governmental" + ? "دولتی" + : item?.quota === "free" + ? "آزاد" + : "-", + item?.saleType === "governmental" + ? "دولتی" + : item?.saleType === "free" + ? "آزاد" + : "-", + , + ]; + }); + + setTableData(d); + }, [data]); + + useEffect(() => { + fetchApiData(1); + }, [selectedDate1, selectedDate2, perPage, selectedSubUser?.key]); + + const handleSubmit = async (event) => { + event.preventDefault(); + dispatch(LOADING_START()); + try { + const response = await axios.get( + `app-segmentation/?search=filter&value=${textValue}&date1=${selectedDate1}&date2=${selectedDate2}&page=${page}&role=${getRoleFromUrl()}${ + checkPathStartsWith("slaughter") || checkPathStartsWith("senf") + ? `&role_key=${selectedSubUser?.key}` + : "" + }` + ); + setData(response.data.results); + setTotalRows(response.data.count); + getDashboardData(); + dispatch(LOADING_END()); + } catch (error) { + console.error("Error fetching data:", error); + } + }; + + return ( + + + ثبت قطعه بندی + + + + + +
    + + + + + + + ( + + )} + value={selectedDate1} + onChange={(e) => + setSelectedDate1(moment(e).format("YYYY-MM-DD")) + } + /> + + + ( + + )} + value={selectedDate2} + onChange={(e) => + setSelectedDate2(moment(e).format("YYYY-MM-DD")) + } + /> + + {/* + + */} + +
    + + +
    +
    + ); +}; diff --git a/src/features/senf/components/SenfStock.js b/src/features/senf/components/SenfStock.js new file mode 100644 index 0000000..cefa26c --- /dev/null +++ b/src/features/senf/components/SenfStock.js @@ -0,0 +1,339 @@ +import { Button, TextField, Typography, Tabs, Tab } from "@mui/material"; +import { DatePicker } from "@mui/x-date-pickers"; +import moment from "moment/moment"; +import { useContext, useEffect, useState } from "react"; +import { useDispatch, useSelector } from "react-redux"; +import { Grid } from "../../../components/grid/Grid"; +import { AppContext } from "../../../contexts/AppContext"; +import { SPACING } from "../../../data/spacing"; +import { + LOADING_END, + LOADING_START, + OPEN_MODAL, +} from "../../../lib/redux/slices/appSlice"; +import { GuildReceiveBarOperation } from "../../guild/components/GuildReceiveBarOperation"; +import { senfGetAllocationDashboardService } from "../../guild/services/senf-get-allocation-dashboard"; +import { senfGetInventoryAllocatedService } from "../../guild/services/senf-get-inventory-allocated"; +import { guildSalesInfoDashboardService } from "../../guild/services/guild-sales-info-dashboard"; +import { getFaUserRole } from "../../../utils/getFaUserRole"; +import { formatJustDate } from "../../../utils/formatTime"; +import { checkPathStartsWith } from "../../../utils/checkPathStartsWith"; +import ResponsiveTable from "../../../components/responsive-table/ResponsiveTable"; +import { RiSearchLine } from "react-icons/ri"; + +export const SenfStock = () => { + const dispatch = useDispatch(); + const [dataTable, setDataTable] = useState([]); + const [statusTab, setStatusTab] = useState("pending"); + const [text, setText] = useState(""); + const [, , selectedDate1, setSelectedDate1, selectedDate2, setSelectedDate2] = + useContext(AppContext); + const { + senfGetInventoryStock, + senfGetInventoryAllocated, + guildSalesInfoDashboard, + } = useSelector((state) => state.generalSlice); + const selectedSubUser = useSelector( + (state) => state.userSlice.selectedSubUser + ); + useEffect(() => { + dispatch( + senfGetAllocationDashboardService({ + date1: selectedDate1, + date2: selectedDate2, + role_key: checkPathStartsWith("senf") ? selectedSubUser?.key : "", + search: text, + }) + ); + dispatch( + senfGetInventoryAllocatedService({ + date1: selectedDate1, + date2: selectedDate2, + role_key: checkPathStartsWith("senf") ? selectedSubUser?.key : "", + type: statusTab, + search: text, + }) + ); + dispatch( + guildSalesInfoDashboardService({ + role_key: checkPathStartsWith("senf") ? selectedSubUser?.key : "", + }) + ); + }, [selectedDate1, selectedDate2, selectedSubUser?.key, statusTab, dispatch]); + + useEffect(() => { + const items = senfGetInventoryAllocated?.results || []; + + if (items.length > 0) { + const d = items.map((item, i) => { + let state = ""; + if (item?.receiverState === "accepted") { + state = "تحویل گرفته شده"; + } else if (item?.receiverState === "rejected") { + state = "رد شده"; + } else { + state = "در انتظار تحویل"; + } + + const sellerRoleFa = getFaUserRole(item?.seller_type); + const sellerName = + item?.stewards?.user?.fullname || + item?.stewards?.name || + item?.killHouse?.name || + item?.toKillHouse?.name || + "-"; + const sellerMobile = + item?.stewards?.user?.mobile || + item?.killHouse?.user?.mobile || + item?.toKillHouse?.user?.mobile || + "-"; + + return [ + i + 1, + `${sellerRoleFa} ${sellerName} (${sellerMobile})`, + formatJustDate(item.date), + (item?.weightOfCarcasses || 0).toLocaleString() + " کیلوگرم", + + {item?.receiverRealNumberOfCarcasses && ( + <> + + {item?.receiverRealNumberOfCarcasses?.toLocaleString() + + " قطعه"} + + + {item?.receiverRealWeightOfCarcasses?.toLocaleString() + + " کیلوگرم"} + + + )} + {/* {item?.receiverState === "pending" && ( + + + + )} */} + , + + {item.receiverState === "pending" ? ( + + ) : ( + state + )} + , + ]; + }); + + setDataTable(d); + } else { + setDataTable([]); + } + }, [senfGetInventoryAllocated, dispatch]); + + const handleSubmit = async (event) => { + event.preventDefault(); + dispatch(LOADING_START()); + try { + dispatch( + senfGetAllocationDashboardService({ + date1: selectedDate1, + date2: selectedDate2, + role_key: checkPathStartsWith("senf") ? selectedSubUser?.key : "", + search: text, + }) + ); + dispatch( + senfGetInventoryAllocatedService({ + date1: selectedDate1, + date2: selectedDate2, + role_key: checkPathStartsWith("senf") ? selectedSubUser?.key : "", + type: statusTab, + search: text, + }) + ); + } catch (error) { + console.error("Error fetching data:", error); + } finally { + dispatch(LOADING_END()); + } + }; + + return ( + + + + + ( + + )} + value={selectedDate1} + onChange={(e) => { + setSelectedDate1(moment(e).format("YYYY-MM-DD")); + }} + /> + ( + + )} + value={selectedDate2} + onChange={(e) => { + setSelectedDate2(moment(e).format("YYYY-MM-DD")); + }} + /> +
    + setText(e.target.value)} + /> + + +
    +
    + + {/* Tabs for filtering by receiver state */} + + setStatusTab(value)} + sx={{ borderBottom: 1, borderColor: "divider", mb: 1 }} + > + + + + + + row.slice(0, -1)) + : dataTable + } + /> +
    + ); +}; diff --git a/src/features/slaughter-house-vet/components/slaughter-house-vet-bars-operation/SlaughterHouseVetBarsOperation.js b/src/features/slaughter-house-vet/components/slaughter-house-vet-bars-operation/SlaughterHouseVetBarsOperation.js new file mode 100644 index 0000000..f879a0d --- /dev/null +++ b/src/features/slaughter-house-vet/components/slaughter-house-vet-bars-operation/SlaughterHouseVetBarsOperation.js @@ -0,0 +1,101 @@ +import React, { useContext } from "react"; +import { Grid, TextField, Button } from "@mui/material"; +import { useDispatch } from "react-redux"; +import { useFormik } from "formik"; +import * as Yup from "yup"; +import { CLOSE_MODAL } from "../../../../lib/redux/slices/appSlice"; +import { SPACING } from "../../../../data/spacing"; +import { slaughterEditFreeSaleService } from "../../../slaughter-house/services/slaughter-edit-free-sale"; +import { AppContext } from "../../../../contexts/AppContext"; + +const validationSchema = Yup.object({ + weight: Yup.number().positive("عدد مثبت وارد کنید"), + amount: Yup.number().positive("عدد مثبت وارد کنید"), +}); + +export const SlaughterHouseVetBarsOperation = ({ item, updateTable }) => { + const dispatch = useDispatch(); + const [openNotif] = useContext(AppContext); + + const formik = useFormik({ + initialValues: { + weight: "", + amount: "", + }, + validationSchema: validationSchema, + }); + + const submitData = (state) => { + dispatch( + slaughterEditFreeSaleService({ + key: item?.key, + kill_house_vet_state: state, + kill_house_vet_quantity: parseInt(formik.values.amount), + kill_house_vet_weight: parseInt(formik.values.weight), + }) + ).then((r) => { + dispatch(CLOSE_MODAL()); + updateTable(1); + if (r.payload.error) { + openNotif({ + vertical: "top", + horizontal: "center", + msg: r.payload.error, + severity: "error", + }); + } else { + openNotif({ + vertical: "top", + horizontal: "center", + msg: "عملیات با موفقیت انجام شد.", + severity: "success", + }); + } + }); + }; + + return ( + + + + + + + + ); +}; diff --git a/src/features/slaughter-house-vet/components/slaughter-house-vet-new-requests/SlaughterHouseVetNewRequests.js b/src/features/slaughter-house-vet/components/slaughter-house-vet-new-requests/SlaughterHouseVetNewRequests.js new file mode 100644 index 0000000..33c4b78 --- /dev/null +++ b/src/features/slaughter-house-vet/components/slaughter-house-vet-new-requests/SlaughterHouseVetNewRequests.js @@ -0,0 +1,541 @@ +import { + Box, + IconButton, + TextField, + ToggleButton, + ToggleButtonGroup, + Typography, + Paper, + Divider, +} from "@mui/material"; +import { useContext, useEffect, useState } from "react"; +import SettingsIcon from "@mui/icons-material/Settings"; +import PlagiarismIcon from "@mui/icons-material/Plagiarism"; +import { useNavigate } from "react-router-dom"; +import { ROUTE_SLAUGHTER_HOUSE_VET_FILE } from "../../../../routes/routes"; +import { Grid } from "../../../../components/grid/Grid"; +import { SPACING } from "../../../../data/spacing"; + +import { useDispatch, useSelector } from "react-redux"; +import { slaughterHouseVetNewRequests } from "../../services/slaughter-house-vet-new-requests"; +import { DRAWER } from "../../../../lib/redux/slices/appSlice"; +import EditIcon from "@mui/icons-material/Edit"; +import SlaughterHouseVetCheckRequest from "../../../file/components/slaughter-house-vet-check-request/SlaughterHouseVetCheckRequest"; +import { format } from "date-fns-jalali"; +import moment from "moment/moment"; +import { DatePicker } from "@mui/x-date-pickers"; +import { AppContext } from "../../../../contexts/AppContext"; +import { formatTime } from "../../../../utils/formatTime"; +import ResponsiveTable from "../../../../components/responsive-table/ResponsiveTable"; + +export const SlaughterHouseVetNewRequests = () => { + const navigate = useNavigate(); + const dispatch = useDispatch(); + const [dataTable, setDataTable] = useState([]); + const [dataTableMobile, setDataTableMobile] = useState([]); + const [dataTableArchive, setDataTableArchive] = useState([]); + const [dataTableArchiveMobile, setDataTableArchiveMobile] = useState([]); + const [, , selectedDate1, setSelectedDate1, selectedDate2, setSelectedDate2] = + useContext(AppContext); + + useEffect(() => { + const currentDate = moment(new Date()).format("YYYY-MM-DD"); + setSelectedDate1(currentDate); + setSelectedDate2(currentDate); + }, []); + + const { newRequests } = useSelector((state) => state.slaughterHouseVetSlice); + + useEffect(() => { + dispatch(slaughterHouseVetNewRequests({ selectedDate1, selectedDate2 })); + }, [selectedDate1, selectedDate2]); + + useEffect(() => { + const d = newRequests + ?.filter((item) => item.vetState === "pending") + .map((item, i) => { + return [ + i + 1, + item.barcod, + item.clearanceCode ? item.clearanceCode : "ندارد", + item.killHouseName, + format(new Date(item?.sendDate), "yyyy/MM/dd"), + formatTime(item?.createDate), + `${item.poultryName} (${item.poultryMobile})`, + item.killPlace, + item.poultryCity, + item.age, + `${item.driverName} (${item.driverMobile})`, + item.typeCar, + item.pelak, + + item.chickenBreed, + item?.quantity?.toLocaleString(), + item.indexWeight, + (item.indexWeight * item?.quantity).toLocaleString(), + { + dispatch( + DRAWER({ + title: "انجام عملیات تخلیه", + + top: !(window.innerWidth <= 600), + bottom: window.innerWidth <= 600, + content: , + }) + ); + }} + > + + , + ]; + }); + + setDataTable(d); + + const c = newRequests + ?.filter((item) => item.vetState === "accepted") + ?.map((item, i) => { + return [ + i + 1, + item.barcod, + item.clearanceCode ? item.clearanceCode : "ندارد", + item.killHouseName, + format(new Date(item?.sendDate), "yyyy/MM/dd"), + item.poultryName, + item.poultryMobile, + item.poultryCity, + item?.age, + item?.quantity?.toLocaleString() + " قطعه", + item.driverName, + item.typeCar, + item.pelak, + + item.chickenBreed, + item.indexWeight, + + navigate(ROUTE_SLAUGHTER_HOUSE_VET_FILE + item.poultryRequestId) + } + > + + , + ]; + }); + + setDataTableArchive(c); + + const datam = newRequests + ?.filter((item) => item.vetState === "pending") + .map((item, i) => { + return ( + + + + کد بار: {item.barcod} + + + + کدرهگیری: {item.clearanceCode ? item.clearanceCode : "ندارد"} + + + {} + + + تاریخ کشتار: {format(new Date(item?.sendDate), "yyyy/MM/dd")} + + + + مرغدار: +
    + {`${item.poultryName} (${item.poultryMobile})`} +
    + + + سن مرغ: {item.age} + + + + تعداد: {item?.quantity?.toLocaleString()} + + + { + dispatch( + DRAWER({ + title: "انجام عملیات تخصیص", + top: !(window.innerWidth <= 600), + bottom: window.innerWidth <= 600, + content: , + }) + ); + }} + > + + +
    +
    + ); + }); + + setDataTableMobile(datam); + + const archivem = newRequests + ?.filter((item) => item.vetState === "accepted") + .map((item, i) => { + return ( + + + + کد بار: {item.barcod} + + + + کدرهگیری: {item.clearanceCode ? item.clearanceCode : "ندارد"} + + + + خریدار: {item.killHouseName} + + + + تاریخ کشتار: {format(new Date(item?.sendDate), "yyyy/MM/dd")} + + + + مرغدار: +
    + {`${item.poultryName} (${item.poultryMobile})`} +
    + + + سن مرغ: {item.age} + + + + تعداد: {item?.quantity?.toLocaleString()} + + + + navigate( + ROUTE_SLAUGHTER_HOUSE_VET_FILE + item.poultryRequestId + ) + } + > + + +
    +
    + ); + }); + + setDataTableArchiveMobile(archivem); + }, [newRequests]); + + const [view, setView] = useState("active"); + + const handleChange = (event, newAlignment) => { + if (newAlignment) { + setView(newAlignment); + } + }; + + const isMobile = window.innerWidth <= 600; + + return ( + + + + + + بارها + بایگانی + + + + {view === "active" && ( + + {isMobile ? ( + + + + بارهای جدید + + + ( + + )} + value={selectedDate1} + onChange={(e) => { + setSelectedDate1(moment(e).format("YYYY-MM-DD")); + }} + /> + + + ( + + )} + value={selectedDate2} + onChange={(e) => { + setSelectedDate2(moment(e).format("YYYY-MM-DD")); + }} + /> + + + {dataTableMobile} + + ) : ( + + + بارهای جدید + + + ( + + )} + value={selectedDate1} + onChange={(e) => { + setSelectedDate1(moment(e).format("YYYY-MM-DD")); + }} + /> + + + ( + + )} + value={selectedDate2} + onChange={(e) => { + setSelectedDate2(moment(e).format("YYYY-MM-DD")); + }} + /> + + + } + columns={[ + "ردیف", + "کد بار", + "کدرهگیری سامانه قرنطینه", + "خریدار", + "تاریخ کشتار", + "تاریخ ثبت خودرو", + "مرغدار", + "محل کشتار", + "شهر", + "سن مرغ", + "راننده", + "ماشین", + "پلاک", + + "نژاد", + "تعداد (قطعه)", + "میانگین وزن", + "وزن تقریبی بار (کیلوگرم)", + "عملیات", + ]} + data={dataTable} + paginated + /> + )} + + )} + {view === "archive" && ( + + {isMobile ? ( + + + + بایگانی + + + ( + + )} + value={selectedDate1} + onChange={(e) => { + setSelectedDate1(moment(e).format("YYYY-MM-DD")); + }} + /> + + + ( + + )} + value={selectedDate2} + onChange={(e) => { + setSelectedDate2(moment(e).format("YYYY-MM-DD")); + }} + /> + + + {dataTableArchiveMobile} + + ) : ( + + + بایگانی + + + ( + + )} + value={selectedDate1} + onChange={(e) => { + setSelectedDate1(moment(e).format("YYYY-MM-DD")); + }} + /> + + + ( + + )} + value={selectedDate2} + onChange={(e) => { + setSelectedDate2(moment(e).format("YYYY-MM-DD")); + }} + /> + + + } + columns={[ + "ردیف", + "کد بار", + "کدرهگیری سامانه قرنطینه", + "خریدار", + "تاریخ درخواست", + "مرغدار", + "تلفن مرغدار", + "شهر", + "سن مرغ", + "تعداد", + "راننده", + "ماشین", + "پلاک", + + "نژاد", + "میانگین وزن", + "مشاهده", + ]} + data={dataTableArchive} + paginated + /> + )} + + )} + + + + ); +}; diff --git a/src/features/slaughter-house-vet/components/slaughter-house-vet-operations/SlaughterHouseVetOperations.js b/src/features/slaughter-house-vet/components/slaughter-house-vet-operations/SlaughterHouseVetOperations.js new file mode 100644 index 0000000..b6b65a5 --- /dev/null +++ b/src/features/slaughter-house-vet/components/slaughter-house-vet-operations/SlaughterHouseVetOperations.js @@ -0,0 +1,121 @@ +import { Grid } from "../../../../components/grid/Grid"; +import { SPACING } from "../../../../data/spacing"; +import { NavLink } from "../../../../components/nav-link/NavLink"; +import { useLocation } from "react-router-dom"; +import { + // ROUTE_SLAUGHTER_HOUSE_VET_COMPLAINTS, + ROUTE_SLAUGHTER_HOUSE_VET_ENTER_BAR_INFO, + ROUTE_SLAUGHTER_HOUSE_VET_FREE_BUY_ROUTE, + // ROUTE_SLAUGHTER_HOUSE_VET_ACTIVE_REQUESTS, + // ROUTE_SLAUGHTER_HOUSE_VET_ARCHIVED_REQUESTS, + ROUTE_SLAUGHTER_HOUSE_VET_NEW_REQUESTS, + // ROUTE_SLAUGHTER_HOUSE_VET_REJECTED_REQUESTS, +} from "../../../../routes/routes"; +import LinkItem from "../../../../components/link-item/LinkItem"; +import { VscFolderActive, VscNewFolder } from "react-icons/vsc"; + +export const SlaughterHouseVetOperations = () => { + const { pathname } = useLocation(); + + return ( + + + + + } + title="بارهای خارج استان" + description="درخواست های در انتظار عملیات وارد کردن اطلاعات بارهای دریافتی" + /> + + + } + title="بارهای جدید" + /> + + + } + title="وارد کردن اطلاعات بار" + /> + + + {/* + } + title="افت نامتعارف" + /> + */} + {/* + + */} + {/* + + + + + */} + + + + ); +}; diff --git a/src/features/slaughter-house-vet/components/slaughter-house-vet-profile/SlaughterHouseVetProfile.js b/src/features/slaughter-house-vet/components/slaughter-house-vet-profile/SlaughterHouseVetProfile.js new file mode 100644 index 0000000..1713f84 --- /dev/null +++ b/src/features/slaughter-house-vet/components/slaughter-house-vet-profile/SlaughterHouseVetProfile.js @@ -0,0 +1,73 @@ +import { Box } from "@mui/system"; +import { useEffect } from "react"; +import { useDispatch, useSelector } from "react-redux"; +import { Grid } from "../../../../components/grid/Grid"; +import { SimpleTable } from "../../../../components/simple-table/SimpleTable"; +import { SPACING } from "../../../../data/spacing"; +import { + LOADING_END, + LOADING_START, +} from "../../../../lib/redux/slices/appSlice"; +import { ChangeCardInfo } from "../../../authentication/components/change-card-info/ChangeCardInfo"; +import { slaughterHouseVetGetProfile } from "../../services/slaughter-house-vet-get-profile"; +// import { ChangeCardInfo } from "../../../authentication/components/change-card-info/ChangeCardInfo"; + +export const SlaughterHouseVetProfile = () => { + const dispatch = useDispatch(); + const { profile } = useSelector((state) => state.slaughterHouseVetSlice); + + useEffect(() => { + dispatch(LOADING_START()); + dispatch(slaughterHouseVetGetProfile()).then((r) => { + dispatch(LOADING_END()); + }); + }, []); + + return ( + + + + + <> + + + + + + + + + + + + ); +}; diff --git a/src/features/slaughter-house-vet/services/slaughter-house-vet-get-complaints.js b/src/features/slaughter-house-vet/services/slaughter-house-vet-get-complaints.js new file mode 100644 index 0000000..de4c99a --- /dev/null +++ b/src/features/slaughter-house-vet/services/slaughter-house-vet-get-complaints.js @@ -0,0 +1,12 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; + +export const slaughterHouseVetGetComplaints = createAsyncThunk( + "SLAUGHTER_VET_GET_COMLATIONS", + async (id) => { + const { data, status } = await axios.get( + "kill_house_assignment_information/?role=KillHouseVet" + ); + return { data, status }; + } +); diff --git a/src/features/slaughter-house-vet/services/slaughter-house-vet-get-profile.js b/src/features/slaughter-house-vet/services/slaughter-house-vet-get-profile.js new file mode 100644 index 0000000..2022432 --- /dev/null +++ b/src/features/slaughter-house-vet/services/slaughter-house-vet-get-profile.js @@ -0,0 +1,10 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; + +export const slaughterHouseVetGetProfile = createAsyncThunk( + "SLAUGHTER_HOUSE_VET_GET_PROFILE", + async () => { + const { data, status } = await axios.get("vet/0/?profile"); + return { data, status }; + } +); diff --git a/src/features/slaughter-house-vet/services/slaughter-house-vet-new-requests.js b/src/features/slaughter-house-vet/services/slaughter-house-vet-new-requests.js new file mode 100644 index 0000000..5d291d8 --- /dev/null +++ b/src/features/slaughter-house-vet/services/slaughter-house-vet-new-requests.js @@ -0,0 +1,22 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const slaughterHouseVetNewRequests = createAsyncThunk( + "SLAUGHTER_HOUSE_VET_NEW_REQUESTS", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + const { data, status } = await axios.get( + "kill_house_request/?operator=KillHouseVet", + { + params: { + date1: d.selectedDate1, + date2: d.selectedDate2, + role_key: d.role_key || "", + }, + } + ); + dispatch(LOADING_END()); + return { data, status }; + } +); diff --git a/src/features/slaughter-house/components/aggregate-upload-doc/aggregate-upload-doc.js b/src/features/slaughter-house/components/aggregate-upload-doc/aggregate-upload-doc.js new file mode 100644 index 0000000..78f0c71 --- /dev/null +++ b/src/features/slaughter-house/components/aggregate-upload-doc/aggregate-upload-doc.js @@ -0,0 +1,144 @@ +import { useContext, useEffect, useState } from "react"; +import { Grid } from "../../../../components/grid/Grid"; +import { ImageUpload } from "../../../../components/image-upload/ImageUpload"; +import { fixBase64 } from "../../../../utils/toBase64"; +import { Typography } from "@mui/material"; +import { SPACING } from "../../../../data/spacing"; +import { killHouseAssignmentInformationAggregateLoadService } from "../../services/killhouse-assignment-information-aggregate-load"; +import { useDispatch, useSelector } from "react-redux"; +import { AppContext } from "../../../../contexts/AppContext"; +import { CLOSE_MODAL, OPEN_MODAL } from "../../../../lib/redux/slices/appSlice"; +import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl"; +import { resizeImage } from "../../../../utils/resizeImage"; + +export const AggregateUploadDoc = ({ isSingular, item, updateTable }) => { + const dispatch = useDispatch(); + const [openNotif] = useContext(AppContext); + const [profileImages, setProfileImages] = useState([]); + const [profileImg, setProfileImg] = useState(); + const { slaughterGetAggregateLoadInformation } = useSelector( + (state) => state.slaughterSlice + ); + + const factorPaymentHandler = (imageList, addUpdateIndex) => { + if (imageList[0]) { + const file = imageList[0]?.file; + resizeImage(file, (resizedDataUrl) => { + const optimizedBase64 = fixBase64(resizedDataUrl); + setProfileImg(optimizedBase64); + }); + } + setProfileImages(imageList); + }; + + useEffect(() => { + if (profileImg) { + if (isSingular) { + dispatch( + killHouseAssignmentInformationAggregateLoadService({ + image: profileImg, + bar_key: item.key, + role: getRoleFromUrl(), + }) + ).then((r) => { + setProfileImg(null); + setProfileImages([]); + dispatch(CLOSE_MODAL()); + if (r.payload.error) { + openNotif({ + vertical: "top", + horizontal: "center", + msg: r.payload.error, + severity: "error", + }); + } else { + openNotif({ + vertical: "top", + horizontal: "center", + msg: "عملیات با موفقیت انجام شد.", + severity: "success", + }); + if ( + item?.assingmentInformation?.realQuantity && + item?.assingmentInformation?.carWeightWithLoadImage + ) { + dispatch( + OPEN_MODAL({ + title: "بار به تب مدیریت بارها منتقل شد.", + }) + ); + } + updateTable(1); + } + }); + } else { + dispatch( + killHouseAssignmentInformationAggregateLoadService({ + image: profileImg, + bar_keys: slaughterGetAggregateLoadInformation?.map( + (item) => item.key + ), + role: getRoleFromUrl(), + }) + ).then((r) => { + setProfileImg(null); + setProfileImages([]); + dispatch(CLOSE_MODAL()); + if (r.payload.error) { + openNotif({ + vertical: "top", + horizontal: "center", + msg: r.payload.error, + severity: "error", + }); + } else { + openNotif({ + vertical: "top", + horizontal: "center", + msg: "عملیات با موفقیت انجام شد.", + severity: "success", + }); + updateTable(1); + if ( + item?.assingmentInformation?.realQuantity && + item?.assingmentInformation?.carWeightWithLoadImage + ) { + dispatch( + OPEN_MODAL({ + title: "بار به تب مدیریت بارها منتقل شد.", + // content: "", + }) + ); + } + } + }); + } + } + }, [profileImg, profileImages]); + + return ( + + {!isSingular && ( + + نکته: + + این سند برای تمامی بارهایی که فاقد سند هستند ثبت خواهد شد. + + + )} + + + + + ); +}; diff --git a/src/features/slaughter-house/components/edit-verification-direct-buy/EditVerificationDirectBuy.js b/src/features/slaughter-house/components/edit-verification-direct-buy/EditVerificationDirectBuy.js new file mode 100644 index 0000000..2c109f9 --- /dev/null +++ b/src/features/slaughter-house/components/edit-verification-direct-buy/EditVerificationDirectBuy.js @@ -0,0 +1,125 @@ +import { useContext, useEffect, useState } from "react"; +import { verificationDirectBuyingCode } from "../../services/edit-verification-direct-buying-code"; +import EditIcon from "@mui/icons-material/Edit"; +import { AppContext } from "../../../../contexts/AppContext"; +import { useDispatch } from "react-redux"; +import { + Grid, + IconButton, + InputAdornment, + TextField, + Typography, +} from "@mui/material"; + +import { Yup } from "../../../../lib/yup/yup"; +import { useFormik } from "formik"; + +function EditVerificationDirectBuy({ + inputDirectBuyingCode, + kill_request_key, + updateTable, +}) { + const dispatch = useDispatch(); + const [openNotif] = useContext(AppContext); + const [isEditMode, setIsEditMode] = useState(false); + + const formik = useFormik({ + initialValues: { + input_direct_buying_code: inputDirectBuyingCode, + }, + validationSchema: Yup.object({ + input_direct_buying_code: Yup.string() + .required("این فیلد اجباری است!") + .typeError("لطفا فیلد را به درستی وارد کنید!") + .matches(/^[0-9]+$/, "فقط عدد وارد کنید"), + // .min(5, "کد باید حداقل ۵ کاراکتر باشد") + // .max(20, "کد نمی‌تواند بیشتر از ۲۰ کاراکتر باشد"), + }), + onSubmit: (values) => { + dispatch( + verificationDirectBuyingCode({ + kill_request_key: kill_request_key, + input_direct_buying_code: values.input_direct_buying_code, + role: "KillHouse", + }) + ).then((r) => { + if (r.payload.error) { + openNotif({ + vertical: "top", + horizontal: "center", + msg: r.payload.error, + severity: "error", + }); + } else { + openNotif({ + vertical: "top", + horizontal: "center", + msg: "عملیات با موفقیت انجام شد.", + severity: "success", + }); + updateTable(); + } + setIsEditMode(false); + }); + }, + }); + + useEffect(() => { + formik.setValues({ input_direct_buying_code: inputDirectBuyingCode }); + setIsEditMode(false); + }, [inputDirectBuyingCode]); + + return isEditMode ? ( + +
    + + + ثبت + + + ), + }} + /> + +
    + ) : ( + + {inputDirectBuyingCode} + { + setIsEditMode(!isEditMode); + }} + > + + + + ); +} + +export default EditVerificationDirectBuy; diff --git a/src/features/slaughter-house/components/enter-aggregate-load-information/EnterAggregateLoadInformation.js b/src/features/slaughter-house/components/enter-aggregate-load-information/EnterAggregateLoadInformation.js new file mode 100644 index 0000000..a9ff9e8 --- /dev/null +++ b/src/features/slaughter-house/components/enter-aggregate-load-information/EnterAggregateLoadInformation.js @@ -0,0 +1,732 @@ +import { + Button, + IconButton, + TextField, + Tooltip, + Typography, +} from "@mui/material"; +import axios from "axios"; +import { useContext, useEffect, useState, useMemo, useCallback } from "react"; +import moment from "moment"; +import { DatePicker } from "@mui/x-date-pickers"; +import { AppContext } from "../../../../contexts/AppContext"; +import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl"; +import { format } from "date-fns-jalali"; +import { Grid } from "../../../../components/grid/Grid"; +import { SPACING } from "../../../../data/spacing"; +import { AggregateUploadDoc } from "../aggregate-upload-doc/aggregate-upload-doc"; +import ShowImage from "../../../../components/show-image/ShowImage"; +import { useFormik } from "formik"; +import { salughterAggregateQuantityService } from "../../services/salughter-aggregate-quantity"; +import { useDispatch, useSelector } from "react-redux"; +import { + CLOSE_MODAL, + LOADING_END, + LOADING_START, + OPEN_MODAL, +} from "../../../../lib/redux/slices/appSlice"; +import { VetFarmEditTrafficCode } from "../../../vet-farm/components/vet-farm-edit-traffic-code/VetFarmEditTrafficCode"; +import { RiFileExcel2Fill } from "react-icons/ri"; +import ResponsiveTable from "../../../../components/responsive-table/ResponsiveTable"; +import { slaughterEnterLoadInformationGetDashboard } from "../../services/slaughter-enter-load-information-get-dashboard"; +import { RiSearchLine } from "react-icons/ri"; +import EditIcon from "@mui/icons-material/Edit"; +import AddCircleOutlineIcon from "@mui/icons-material/AddCircleOutline"; +import { provincePolicyGetWeightRange } from "../../../province/services/province-policy-get-weight-range"; +import { isValidIndexWeight } from "../../../../utils/isValidIndexWeight"; +import { checkPathStartsWith } from "../../../../utils/checkPathStartsWith"; + +// Constants +const ROLES = { + PROVINCE_OPERATOR: "ProvinceOperator", + SUPER_ADMIN: "SuperAdmin", + ADMIN_X: "AdminX", + SUPPORTER: "Supporter", + VET_SUPERVISOR: "VetSupervisor", + VET_FARM: "VetFarm", + CITY_VET: "CityVet", +}; + +const KILL_TYPES = { + FREEZING: "انجماد", + EXPORT: "صادرات", + NORMAL: "عادی", +}; + +const DEFAULT_PER_PAGE = 10; +const DEFAULT_PAGE = 1; + +// Helper functions +const formatDate = (date) => { + if (!date) return "-"; + return format(new Date(date), "yyyy/MM/dd"); +}; + +const formatCurrency = (value) => { + return value ? `${value.toLocaleString()} ﷼` : "-"; +}; + +const formatNumber = (value) => { + return value ? value.toLocaleString() : "-"; +}; + +const formatUserInfo = (name, mobile) => { + return name && mobile ? `${name} (${mobile})` : "-"; +}; + +const getKillType = (item) => { + if (item?.poultryRequest?.freezing) return KILL_TYPES.FREEZING; + if (item?.poultryRequest?.export) return KILL_TYPES.EXPORT; + return KILL_TYPES.NORMAL; +}; + +const buildApiUrl = (params) => { + const { textValue, role, date1, date2, page, perPage, roleKey } = params; + const baseUrl = "kill_house_request_aggregate_load/"; + const queryParams = new URLSearchParams({ + check: "", + search: "filter", + value: textValue || "", + role: role || "", + date1: date1 || "", + date2: date2 || "", + page: page || DEFAULT_PAGE, + page_size: perPage || DEFAULT_PER_PAGE, + }); + + if (roleKey) { + queryParams.append("role_key", roleKey); + } + + return `${baseUrl}?${queryParams.toString()}`; +}; + +const buildExcelUrl = (params) => { + const { baseURL, date1, date2, role, roleKey, userKey, textValue } = params; + const queryParams = new URLSearchParams({ + start: date1 || "", + end: date2 || "", + role: role || "", + state: "bar_pending", + key: userKey || "", + search: "filter", + value: textValue || "", + }); + + if (roleKey) { + queryParams.append("role_key", roleKey); + } + + return `${baseURL}bar_excel/?${queryParams.toString()}`; +}; + +const isTrafficCodeEditable = (role, item) => { + const adminRoles = [ + ROLES.PROVINCE_OPERATOR, + ROLES.SUPER_ADMIN, + ROLES.ADMIN_X, + ROLES.SUPPORTER, + ROLES.VET_SUPERVISOR, + ]; + + if (adminRoles.includes(role)) { + return true; + } + + const vetRoles = [ROLES.VET_FARM, ROLES.CITY_VET]; + return ( + item.trash !== true && + item.assignmentStateArchive === "pending" && + !item?.clearanceCode && + vetRoles.includes(role) + ); +}; + +export const EnterAggregateLoadInformation = () => { + const [, , selectedDate1, setSelectedDate1, selectedDate2, setSelectedDate2] = + useContext(AppContext); + + // Redux + const userKey = useSelector((state) => state.userSlice.userProfile.key); + const selectedSubUser = useSelector( + (state) => state.userSlice.selectedSubUser + ); + const dispatch = useDispatch(); + + // State + const [data, setData] = useState([]); + const [totalRows, setTotalRows] = useState(0); + const [perPage, setPerPage] = useState(DEFAULT_PER_PAGE); + const [textValue, setTextValue] = useState(""); + const [page, setPage] = useState(DEFAULT_PAGE); + const [tableData, setTableData] = useState([]); + const [dashboardData, setDashboardData] = useState([]); + + // Memoized values + const currentRole = useMemo(() => getRoleFromUrl(), []); + const roleKey = useMemo( + () => (checkPathStartsWith("slaughter") ? selectedSubUser?.key || "" : ""), + [selectedSubUser?.key] + ); + + // Initialize dates + useEffect(() => { + const currentDate = moment(new Date()).format("YYYY-MM-DD"); + setSelectedDate1(currentDate); + setSelectedDate2(currentDate); + }, [setSelectedDate1, setSelectedDate2]); + + // Fetch API data + const fetchApiData = useCallback( + async (pageNumber = page) => { + dispatch(LOADING_START()); + try { + const url = buildApiUrl({ + textValue, + role: currentRole, + date1: selectedDate1, + date2: selectedDate2, + page: pageNumber, + perPage, + roleKey, + }); + + const response = await axios.get(url); + setData(response.data.results); + setTotalRows(response.data.count); + } catch (error) { + console.error("Error fetching data:", error); + } finally { + dispatch(LOADING_END()); + } + }, + [ + textValue, + currentRole, + selectedDate1, + selectedDate2, + perPage, + roleKey, + page, + dispatch, + ] + ); + + // Fetch dashboard data + const fetchDashboardData = useCallback(() => { + dispatch( + slaughterEnterLoadInformationGetDashboard({ + selectedDate1, + selectedDate2, + text: textValue, + role_key: roleKey, + }) + ).then((r) => { + setDashboardData(r.payload.data); + }); + }, [selectedDate1, selectedDate2, textValue, roleKey, dispatch]); + + // Handlers + const handlePageChange = (newPage) => { + fetchApiData(newPage); + setPage(newPage); + }; + + const handlePerRowsChange = (newPerRows) => { + setPerPage(newPerRows); + setPage(DEFAULT_PAGE); + }; + + const handleSubmit = async (event) => { + event.preventDefault(); + await fetchApiData(DEFAULT_PAGE); + fetchDashboardData(); + setPage(DEFAULT_PAGE); + }; + + const handleTextChange = (event) => { + setTextValue(event.target.value); + }; + + const handleDateChange1 = (date) => { + if (date) { + setSelectedDate1(moment(date).format("YYYY-MM-DD")); + } + }; + + const handleDateChange2 = (date) => { + if (date) { + setSelectedDate2(moment(date).format("YYYY-MM-DD")); + } + }; + + const handleOpenModal = useCallback( + (item) => { + dispatch( + OPEN_MODAL({ + title: "ثبت اطلاعات بار", + content: , + }) + ); + }, + [dispatch, fetchApiData] + ); + + // Initial data fetch + useEffect(() => { + fetchApiData(DEFAULT_PAGE); + fetchDashboardData(); + // eslint-disable-next-line react-hooks/exhaustive-deps + }, []); + + // Refetch when filters change + useEffect(() => { + fetchApiData(DEFAULT_PAGE); + fetchDashboardData(); + setPage(DEFAULT_PAGE); + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [selectedDate1, selectedDate2, perPage, roleKey]); + + // Transform data to table format + useEffect(() => { + const transformedData = data?.map((item, i) => { + const rowNumber = + page === DEFAULT_PAGE ? i + 1 : i + perPage * (page - 1) + 1; + const hasAssignmentInfo = !!item?.assignmentInfo?.realQuantity; + + return [ + rowNumber, + hasAssignmentInfo ? ( + + {formatNumber(item?.assignmentInfo?.realQuantity)} قطعه + {formatNumber(item?.assignmentInfo?.netWeight)} کیلوگرم + + handleOpenModal(item)} + size="small" + > + + + + + ) : ( + + handleOpenModal(item)} + size="small" + > + + + + ), + item?.assingmentInformation?.carWeightWithLoadImage ? ( + + + + + ) : ( + + ), + , + , + + {item.barCode} + , + , + formatCurrency(item?.amount), + formatDate(item?.poultryRequest?.sendDate), + formatUserInfo( + item.killhouseUser?.name, + item.killhouseUser?.killHouseOperator?.user?.mobile + ), + item?.killer + ? formatUserInfo( + item.killer?.name, + item.killer?.killHouseOperator?.user?.mobile + ) + : "-", + formatUserInfo( + item.poultryRequest?.poultry?.unitName, + item.poultryRequest?.poultry?.user?.mobile + ), + item?.poultryRequest?.age || "-", + formatNumber(item.quantity), + formatNumber(item?.weightInfo?.weight), + formatCurrency(item?.poultryRequest?.amount), + formatCurrency(item?.weightInfo?.killHousePrice), + `${item.addCar?.driver?.typeCar || ""} ${ + item.addCar?.driver?.pelak || "" + }`.trim() || "-", + formatUserInfo( + item.addCar?.driver?.driverName, + item.addCar?.driver?.driverMobile + ), + formatNumber(item.vetAcceptedRealQuantity), + formatNumber(item.vetAcceptedRealWeight), + item?.poultryRequest?.orderCode || "-", + item?.finalBarState || "-", + getKillType(item), + ]; + }); + + setTableData(transformedData || []); + }, [data, page, perPage, currentRole, handleOpenModal, fetchApiData]); + + // Table columns + const dashboardColumns = [ + "تعداد بار", + "مجموع تعداد اولیه", + "مجموع وزن اولیه (کیلوگرم)", + "مجموع تعداد تحویلی دامپزشک", + "مجموع وزن تحویلی دامپزشک (کیلوگرم)", + ]; + + const tableColumns = [ + "ردیف", + "تعداد/وزن خالص", + "سند", + "بارنامه خالی", + "بارنامه پر", + "کدبار", + "کد بهداشتی حمل و نقل", + "قیمت مرغ زنده‌ی بار", + "تاریخ کشتار", + "خریدار", + "کشتارکن اختصاصی", + "مرغدار", + "سن مرغ", + "تعداد اولیه", + "وزن اولیه بار (کیلوگرم)", + "قیمت مرغدار", + "قیمت کشتارگاه", + "ماشین", + "راننده", + "تحویلی دامپزشک (قطعه)", + "وزن تحویلی دامپزشک (کیلوگرم)", + "کدسفارش کشتار", + "وضعیت بار", + "نوع کشتار", + ]; + + const dashboardRow = [ + formatNumber(dashboardData?.lenKillHouseRequest), + formatNumber(dashboardData?.firstQuantity), + formatNumber(dashboardData?.firstWeight), + formatNumber(dashboardData?.vetAcceptedRealQuantity), + formatNumber(dashboardData?.vetAcceptedRealWeight), + ]; + + const excelUrl = buildExcelUrl({ + baseURL: axios.defaults.baseURL, + date1: selectedDate1, + date2: selectedDate2, + role: currentRole, + roleKey, + userKey, + textValue, + }); + + return ( + + + + + ( + + )} + value={selectedDate1} + onChange={handleDateChange1} + /> + + + ( + + )} + value={selectedDate2} + onChange={handleDateChange2} + /> + +
    + + + + {!!data?.length && ( + + + + + + + + )} +
    +
    + + + + + +
    + ); +}; + +const Operation = ({ item, fetchApiData }) => { + const [openNotif] = useContext(AppContext); + const { weightRange } = useSelector((state) => state.provinceSlice); + const dispatch = useDispatch(); + const selectedSubUser = useSelector( + (state) => state.userSlice.selectedSubUser + ); + const currentRole = useMemo(() => getRoleFromUrl(), []); + + // Fetch weight range on mount + useEffect(() => { + dispatch( + provincePolicyGetWeightRange({ + role_key: checkPathStartsWith("slaughter") + ? selectedSubUser?.key || "" + : "", + }) + ); + }, [selectedSubUser?.key]); + + // Validation helpers + const validateNumeric = (value) => /^\d+$/.test(value); + + const checkVolumeLimits = (quantity) => { + const { maximumLoadVolumeReduction, maximumLoadVolumeIncrease } = + item?.killhouseUser || {}; + const acceptedQuantity = item?.acceptedRealQuantity || 0; + + if ( + maximumLoadVolumeReduction !== 0 && + quantity < acceptedQuantity * (1 - maximumLoadVolumeReduction / 100) + ) { + return { + isValid: false, + message: + "حجم وارد شده با مجوز حداکثر افزایش/کاهش ورود اطلاعات بار مطابقت ندارد!", + }; + } + + if ( + maximumLoadVolumeIncrease !== 0 && + quantity > acceptedQuantity * (1 + maximumLoadVolumeIncrease / 100) + ) { + return { + isValid: false, + message: + "حجم وارد شده با مجوز حداکثر افزایش/کاهش ورود اطلاعات بار مطابقت ندارد!", + }; + } + + return { isValid: true }; + }; + + const checkWeightValidation = (weight, quantity) => { + const adminRoles = [ROLES.SUPER_ADMIN, ROLES.ADMIN_X]; + if (adminRoles.includes(currentRole)) { + return { isValid: true }; + } + + const averageWeight = parseInt(weight) / parseInt(quantity); + if ( + !isValidIndexWeight(weightRange, item?.poultryRequest?.age, averageWeight) + ) { + return { + isValid: false, + message: + "میانگین وزنی با احراز سنی مطابقت ندارد. لطفا با اتحادیه تماس بگیرید.", + }; + } + + return { isValid: true }; + }; + + const formik = useFormik({ + initialValues: { + quantity: "", + weight: "", + }, + onSubmit: async (values) => { + // Validate volume limits + const volumeCheck = checkVolumeLimits(parseInt(values.quantity)); + if (!volumeCheck.isValid) { + openNotif({ + vertical: "top", + horizontal: "center", + msg: volumeCheck.message, + severity: "error", + }); + return; + } + + // Validate weight + const weightCheck = checkWeightValidation(values.weight, values.quantity); + if (!weightCheck.isValid) { + openNotif({ + vertical: "top", + horizontal: "center", + msg: weightCheck.message, + severity: "error", + }); + return; + } + + // Submit data + const result = await dispatch( + salughterAggregateQuantityService({ + kill_house_request_key: item.key, + role: currentRole, + net_weight: values.weight, + exploited_carcass: 0, + real_quantity: values.quantity, + }) + ); + + if (result.payload.error) { + openNotif({ + vertical: "top", + horizontal: "center", + msg: result.payload.error, + severity: "error", + }); + } else { + openNotif({ + vertical: "top", + horizontal: "center", + msg: "عملیات با موفقیت انجام شد.", + severity: "success", + }); + dispatch(CLOSE_MODAL()); + fetchApiData(DEFAULT_PAGE); + } + }, + validate: (values) => { + const errors = {}; + if (!validateNumeric(values.weight)) { + errors.weight = "لطفا عدد وارد کنید"; + } + if (!validateNumeric(values.quantity)) { + errors.quantity = "لطفا عدد وارد کنید"; + } + return errors; + }, + }); + + return ( +
    + + + + + + +
    + ); +}; diff --git a/src/features/slaughter-house/components/enter-auth-code-direct-buy/EnterAuthCodeDirectBuy.js b/src/features/slaughter-house/components/enter-auth-code-direct-buy/EnterAuthCodeDirectBuy.js new file mode 100644 index 0000000..62ed78d --- /dev/null +++ b/src/features/slaughter-house/components/enter-auth-code-direct-buy/EnterAuthCodeDirectBuy.js @@ -0,0 +1,79 @@ +import React, { useContext } from "react"; +import { useFormik } from "formik"; +import { Yup } from "../../../../lib/yup/yup"; +import { Button, TextField } from "@mui/material"; +import { useDispatch } from "react-redux"; +import { slaughterEditFreeBuyService } from "../../services/slaughter-edit-free-buy"; +import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl"; +import { AppContext } from "../../../../contexts/AppContext"; +import { CLOSE_MODAL } from "../../../../lib/redux/slices/appSlice"; +import { Grid } from "../../../../components/grid/Grid"; +import { SPACING } from "../../../../data/spacing"; + +export const EnterAuthCodeDirectBuy = ({ item, updateTable }) => { + const [openNotif] = useContext(AppContext); + const dispatch = useDispatch(); + const formik = useFormik({ + initialValues: { + textFieldValue: "", // Initial value for your text field + }, + validationSchema: Yup.object({ + textFieldValue: Yup.string().required("این فیلد الزامی است"), // Validation schema for the text field + }), + onSubmit: (values) => { + dispatch( + slaughterEditFreeBuyService({ + role: getRoleFromUrl(), + kill_request_key: item.key, + input_direct_buying_code: values.textFieldValue, + }) + ).then((r) => { + if (r?.payload?.error) { + openNotif({ + vertical: "top", + horizontal: "center", + msg: r?.payload?.error, + severity: "error", + }); + } else { + updateTable(); + openNotif({ + vertical: "top", + horizontal: "center", + msg: "عملیات با موفقیت انجام شد.", + severity: "success", + }); + dispatch(CLOSE_MODAL()); + } + }); + }, + }); + + return ( +
    + + + + + +
    + ); +}; diff --git a/src/features/slaughter-house/components/enter-load-information/EnterLoadInformation.js b/src/features/slaughter-house/components/enter-load-information/EnterLoadInformation.js new file mode 100644 index 0000000..ee26b87 --- /dev/null +++ b/src/features/slaughter-house/components/enter-load-information/EnterLoadInformation.js @@ -0,0 +1,445 @@ +import { useContext, useEffect, useState, useMemo, useCallback } from "react"; +import { AppContext } from "../../../../contexts/AppContext"; +import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl"; +import { slaughterGetPermissionToVetService } from "../../services/slaughter-get-premisson-to-vet"; +import { Box, Switch, TextField, Typography, Button } from "@mui/material"; +import moment from "moment"; +import { slaughterPermissionToVetService } from "../../services/slaughter-premisson-to-vet"; +import { SPACING } from "../../../../data/spacing"; +import { DatePicker } from "@mui/x-date-pickers"; +import { + LOADING_END, + LOADING_START, +} from "../../../../lib/redux/slices/appSlice"; +import { useDispatch, useSelector } from "react-redux"; +import { format } from "date-fns-jalali"; +import axios from "axios"; +import { VetFarmEditTrafficCode } from "../../../vet-farm/components/vet-farm-edit-traffic-code/VetFarmEditTrafficCode"; +import ResponsiveTable from "../../../../components/responsive-table/ResponsiveTable"; +import { slaughterEnterLoadInformationGetDashboard } from "../../services/slaughter-enter-load-information-get-dashboard"; +import { Grid } from "../../../../components/grid/Grid"; +import { RiSearchLine } from "react-icons/ri"; +import { SlaughterEnterInformationOperation } from "../slaughter-enter-information-operation/SlaughterEnterInformationOperation"; +import { checkPathStartsWith } from "../../../../utils/checkPathStartsWith"; + +// Constants +const ROLES = { + KILL_HOUSE: "KillHouse", + PROVINCE_OPERATOR: "ProvinceOperator", + SUPER_ADMIN: "SuperAdmin", + VET_SUPERVISOR: "VetSupervisor", + VET_FARM: "VetFarm", + CITY_VET: "CityVet", +}; + +const DEFAULT_PER_PAGE = 10; +const DEFAULT_PAGE = 1; + +// Helper functions +const formatDate = (date) => { + if (!date) return "-"; + return format(new Date(date), "yyyy/MM/dd"); +}; + +const formatCurrency = (value) => { + return value ? `${value.toLocaleString()} ﷼` : "-"; +}; + +const formatNumber = (value) => { + return value ? value.toLocaleString() : "-"; +}; + +const formatUserInfo = (name, mobile) => { + return name && mobile ? `${name} (${mobile})` : "-"; +}; + +const buildApiUrl = (params) => { + const { textValue, role, date1, date2, page, perPage, roleKey } = params; + const baseUrl = "kill_house_request_complete_information/"; + const queryParams = new URLSearchParams({ + search: "filter", + value: textValue || "", + role: role || "", + date1: date1 || "", + date2: date2 || "", + page: page || DEFAULT_PAGE, + page_size: perPage || DEFAULT_PER_PAGE, + }); + + if (roleKey) { + queryParams.append("role_key", roleKey); + } + + return `${baseUrl}?${queryParams.toString()}`; +}; + +const isTrafficCodeEditable = (role, item) => { + const adminRoles = [ + ROLES.PROVINCE_OPERATOR, + ROLES.SUPER_ADMIN, + ROLES.VET_SUPERVISOR, + ]; + + if (adminRoles.includes(role)) { + return true; + } + + const vetRoles = [ROLES.VET_FARM, ROLES.CITY_VET]; + return ( + item.trash !== true && + item.assignmentStateArchive === "pending" && + !item?.clearanceCode && + vetRoles.includes(role) + ); +}; + +export const EnterLoadInformation = () => { + const [, , selectedDate1, setSelectedDate1, selectedDate2, setSelectedDate2] = + useContext(AppContext); + + // State + const [checked, setChecked] = useState(false); + const [data, setData] = useState([]); + const [totalRows, setTotalRows] = useState(0); + const [perPage, setPerPage] = useState(DEFAULT_PER_PAGE); + const [textValue, setTextValue] = useState(""); + const [page, setPage] = useState(DEFAULT_PAGE); + const [tableData, setTableData] = useState([]); + const [dashboardData, setDashboardData] = useState([]); + + // Redux + const selectedSubUser = useSelector( + (state) => state.userSlice.selectedSubUser + ); + const dispatch = useDispatch(); + + // Memoized values + const currentRole = useMemo(() => getRoleFromUrl(), []); + const isKillHouse = useMemo( + () => currentRole === ROLES.KILL_HOUSE, + [currentRole] + ); + const roleKey = useMemo( + () => (checkPathStartsWith("slaughter") ? selectedSubUser?.key || "" : ""), + [selectedSubUser?.key] + ); + + // Initialize dates + useEffect(() => { + const currentDate = moment(new Date()).format("YYYY-MM-DD"); + setSelectedDate1(currentDate); + setSelectedDate2(currentDate); + }, [setSelectedDate1, setSelectedDate2]); + + // Fetch permission for KillHouse role + useEffect(() => { + if (isKillHouse) { + dispatch( + slaughterGetPermissionToVetService({ + role_key: roleKey, + }) + ).then((r) => { + setChecked(r.payload.data?.[0]?.allow || false); + }); + } + }, [isKillHouse, selectedSubUser?.key, dispatch]); + + // Fetch API data + const fetchApiData = useCallback( + async (pageNumber = page) => { + dispatch(LOADING_START()); + try { + const url = buildApiUrl({ + textValue, + role: currentRole, + date1: selectedDate1, + date2: selectedDate2, + page: pageNumber, + perPage, + roleKey, + }); + + const response = await axios.get(url); + setData(response.data.results); + setTotalRows(response.data.count); + } catch (error) { + console.error("Error fetching data:", error); + } finally { + dispatch(LOADING_END()); + } + }, + [ + textValue, + currentRole, + selectedDate1, + selectedDate2, + perPage, + roleKey, + page, + dispatch, + ] + ); + + // Fetch dashboard data + const fetchDashboardData = useCallback(() => { + dispatch( + slaughterEnterLoadInformationGetDashboard({ + selectedDate1, + selectedDate2, + text: textValue, + role_key: roleKey, + }) + ).then((r) => { + setDashboardData(r.payload.data); + }); + }, [selectedDate1, selectedDate2, textValue, roleKey, dispatch]); + + // Update table data + const updateTable = useCallback(() => { + fetchDashboardData(); + fetchApiData(DEFAULT_PAGE); + setPage(DEFAULT_PAGE); + }, [fetchDashboardData, fetchApiData]); + + // Transform data to table format + useEffect(() => { + const transformedData = data?.map((item, i) => [ + , + + {item.barCode} + , + , + formatDate(item?.poultryRequest?.sendDate), + formatUserInfo( + item.killhouseUser?.name, + item.killhouseUser?.killHouseOperator?.user?.mobile + ), + item?.killer + ? formatUserInfo( + item.killer?.name, + item.killer?.killHouseOperator?.user?.mobile + ) + : "-", + formatUserInfo( + item.poultryRequest?.poultry?.unitName, + item.poultryRequest?.poultry?.user?.mobile + ), + item?.poultryRequest?.age || "-", + formatNumber(item.quantity), + formatNumber(item?.weightInfo?.weight), + `${item.addCar?.driver?.typeCar || ""} ${ + item.addCar?.driver?.pelak || "" + }`.trim() || "-", + formatUserInfo( + item.addCar?.driver?.driverName, + item.addCar?.driver?.driverMobile + ), + formatCurrency(item?.poultryRequest?.amount), + formatCurrency(item?.weightInfo?.killHousePrice), + formatNumber(item.vetAcceptedRealQuantity), + formatNumber(item.vetAcceptedRealWeight), + item?.poultryRequest?.orderCode || "-", + item?.barDocumentStatus?.title || "-", + item?.finalBarState || "-", + item?.poultryRequest?.freezing ? "انجماد" : "عادی", + ]); + + setTableData(transformedData || []); + }, [data, currentRole, updateTable, fetchApiData]); + + // Initial data fetch + useEffect(() => { + fetchApiData(DEFAULT_PAGE); + fetchDashboardData(); + }, []); + + // Refetch when filters change + useEffect(() => { + fetchApiData(DEFAULT_PAGE); + fetchDashboardData(); + setPage(DEFAULT_PAGE); + }, [selectedDate1, selectedDate2, perPage, selectedSubUser?.keys]); + + // Handlers + const handlePageChange = (newPage) => { + fetchApiData(newPage); + setPage(newPage); + }; + + const handlePerRowsChange = (newPerRows) => { + setPerPage(newPerRows); + setPage(DEFAULT_PAGE); + }; + + const handleSubmit = async (event) => { + event.preventDefault(); + await fetchApiData(DEFAULT_PAGE); + fetchDashboardData(); + setPage(DEFAULT_PAGE); + }; + + const handleTextChange = (event) => { + setTextValue(event.target.value); + }; + + const handleDateChange1 = (date) => { + if (date) { + setSelectedDate1(moment(date).format("YYYY-MM-DD")); + } + }; + + const handleDateChange2 = (date) => { + if (date) { + setSelectedDate2(moment(date).format("YYYY-MM-DD")); + } + }; + + const handleSwitchChange = () => { + const newValue = !checked; + dispatch( + slaughterPermissionToVetService({ + allow: newValue, + }) + ); + setChecked(newValue); + }; + + // Table columns + const dashboardColumns = [ + "تعداد بار", + "مجموع تعداد اولیه", + "مجموع وزن اولیه (کیلوگرم)", + "مجموع تعداد تحویلی دامپزشک", + "مجموع وزن تحویلی دامپزشک (کیلوگرم)", + ]; + + const tableColumns = [ + "عملیات", + "کدبار", + "کدبهداشتی حمل و نقل", + "تاریخ کشتار", + "خریدار", + "کشتارکن اختصاصی", + "مرغدار", + "سن مرغ", + "تعداد اولیه", + "وزن اولیه بار(کیلوگرم)", + "ماشین", + "راننده", + "قیمت مرغدار", + "قیمت کشتارگاه", + "تحویلی دامپزشک (قطعه)", + "وزن تحویلی دامپزشک(کیلوگرم)", + "کد سفارش کشتار", + "وضعیت سند", + "وضعیت بار", + "نوع کشتار", + ]; + + const dashboardRow = [ + formatNumber(dashboardData?.lenKillHouseRequest), + formatNumber(dashboardData?.firstQuantity), + formatNumber(dashboardData?.firstWeight), + formatNumber(dashboardData?.vetAcceptedRealQuantity), + formatNumber(dashboardData?.vetAcceptedRealWeight), + ]; + + return ( + + {isKillHouse && ( + + + + + دسترسی دامپزشک برای وارد کردن اطلاعات بار + + + + + + + + )} + + + + } + value={selectedDate1} + onChange={handleDateChange1} + /> + + + } + value={selectedDate2} + onChange={handleDateChange2} + /> + +
    + + + +
    + + + + + + + + +
    + ); +}; diff --git a/src/features/slaughter-house/components/province-reject-free-buy/ProvinceRejectFreeBuy.js b/src/features/slaughter-house/components/province-reject-free-buy/ProvinceRejectFreeBuy.js new file mode 100644 index 0000000..2954d15 --- /dev/null +++ b/src/features/slaughter-house/components/province-reject-free-buy/ProvinceRejectFreeBuy.js @@ -0,0 +1,63 @@ +import { Button, TextField } from "@mui/material"; +import { useContext, useState } from "react"; +import { useDispatch } from "react-redux"; +import { Grid } from "../../../../components/grid/Grid"; +import { AppContext } from "../../../../contexts/AppContext"; +import { SPACING } from "../../../../data/spacing"; +import { CLOSE_MODAL } from "../../../../lib/redux/slices/appSlice"; +import { provinceRejectSlaughterFreeBuyService } from "../../services/province-reject-slaughter-free-buy"; + +export const ProviceRejectFreeBuy = ({ item, updateTable }) => { + const dispatch = useDispatch(); + const [openNotif] = useContext(AppContext); + const [text, setText] = useState(""); + + const handleTextChange = (event) => { + setText(event.target.value); + }; + + return ( + + + + + ); +}; diff --git a/src/features/slaughter-house/components/resp-guild-exclusive-item/RespGuildExclusiveItem.js b/src/features/slaughter-house/components/resp-guild-exclusive-item/RespGuildExclusiveItem.js new file mode 100644 index 0000000..8c9970b --- /dev/null +++ b/src/features/slaughter-house/components/resp-guild-exclusive-item/RespGuildExclusiveItem.js @@ -0,0 +1,35 @@ +import { Typography } from "@mui/material"; +import { Grid } from "../../../../components/grid/Grid"; + +export const RespGuildExclusiveItem = ({ data }) => { + return ( + + {data?.map((item, i) => { + return ( + + + + {`${i + 1}- ${item[6]} `} + + + {`با ماهیت ${item[3]} با کدملی ${item[7]} در شهرستان ${item[12]}`} + + + {item[16]} + + ); + })} + + ); +}; diff --git a/src/features/slaughter-house/components/resp-slaughter-guild-list-item/RespSlaughterGuildListItem.js b/src/features/slaughter-house/components/resp-slaughter-guild-list-item/RespSlaughterGuildListItem.js new file mode 100644 index 0000000..8ba3b71 --- /dev/null +++ b/src/features/slaughter-house/components/resp-slaughter-guild-list-item/RespSlaughterGuildListItem.js @@ -0,0 +1,35 @@ +import { Typography } from "@mui/material"; +import { Grid } from "../../../../components/grid/Grid"; + +export const RespSlaughterGuildListItem = ({ data }) => { + return ( + + {data?.map((item, i) => { + return ( + + + + {`${i + 1}- ${item[1]} ${item[3]}`} + + + {` تلفن ${item[5]} در شهرستان ${item[9]} با میانگین سهم ${item[10]}`} + + + {item[11]} + + ); + })} + + ); +}; diff --git a/src/features/slaughter-house/components/resp-slaughter-stock-bar-system/RespSlaughterStockBarSystem.js b/src/features/slaughter-house/components/resp-slaughter-stock-bar-system/RespSlaughterStockBarSystem.js new file mode 100644 index 0000000..2b88776 --- /dev/null +++ b/src/features/slaughter-house/components/resp-slaughter-stock-bar-system/RespSlaughterStockBarSystem.js @@ -0,0 +1,66 @@ +import { IconButton, Tooltip, Typography } from "@mui/material"; +import { Grid } from "../../../../components/grid/Grid"; +import { SPACING } from "../../../../data/spacing"; +import { OPEN_MODAL } from "../../../../lib/redux/slices/appSlice"; +import { SlaughterSubmitRealInventory } from "../slaughter-submit-real-inventory/SlaughterSubmitRealInventory"; +import { useDispatch } from "react-redux"; +import SettingsIcon from "@mui/icons-material/Settings"; + +export const RespSlaughterStockBarSystem = ({ + data, + inventorySelectedKillHouse, +}) => { + const dispatch = useDispatch(); + return ( + + {data?.map((item, i) => { + return ( + + + + {`${i + 1}- مرغدار ${item[1]} کشتارگاه ${item[2]} با کدسفارش ${ + item[3] + } در شهرستان ${item[4]} با تعداد تخصیصی ${item[12]}`} + + {item[17]} + + { + dispatch( + OPEN_MODAL({ + title: "ثبت موجودی واقعی", + content: ( + + ), + }) + ); + }} + > + + + + + + ); + })} + + ); +}; diff --git a/src/features/slaughter-house/components/slaughter-active-requests/SlaughterActiveRequests.js b/src/features/slaughter-house/components/slaughter-active-requests/SlaughterActiveRequests.js new file mode 100644 index 0000000..3554e92 --- /dev/null +++ b/src/features/slaughter-house/components/slaughter-active-requests/SlaughterActiveRequests.js @@ -0,0 +1,153 @@ +import { Card, Grid, IconButton, TextField, Typography } from "@mui/material"; +import { ROUTE_SLAUGHTER_FILE } from "../../../../routes/routes"; +import { AdvancedTable } from "../../../../components/advanced-table/AdvancedTable"; +import { SPACING } from "../../../../data/spacing"; +import { useFormik } from "formik"; +import moment from "moment"; +import { Yup } from "../../../../lib/yup/yup"; +import { useDispatch, useSelector } from "react-redux"; +import { slaughterGetActiveRequests } from "../../services/slaughter-get-active-requests"; +import { useContext, useEffect, useState } from "react"; +import { useNavigate } from "react-router-dom"; +import PlagiarismIcon from "@mui/icons-material/Plagiarism"; +import { format } from "date-fns-jalali"; +import { AppContext } from "../../../../contexts/AppContext"; +import { DatePicker } from "@mui/x-date-pickers"; + +export const SlaughterActiveRequests = () => { + const navigate = useNavigate(); + + const [dataTable, setDataTable] = useState([]); + const { slaughterActiveRequests } = useSelector( + (state) => state.slaughterSlice + ); + const [, , selectedDate1, setSelectedDate1, selectedDate2, setSelectedDate2] = + useContext(AppContext); + + useEffect(() => { + const currentDate = moment(new Date()).format("YYYY-MM-DD"); + setSelectedDate1(currentDate); + setSelectedDate2(currentDate); + }, []); + const dispatch = useDispatch(); + + useEffect(() => { + dispatch(slaughterGetActiveRequests({ selectedDate1, selectedDate2 })); + }, [selectedDate1, selectedDate2]); + + useEffect(() => { + const filteredData = slaughterActiveRequests?.filter( + (item, i) => item.provinceKillState !== "rejected" + ); + const key = "orderCode"; + const arrayUniqueByKey = [ + ...new Map(filteredData?.map((item) => [item[key], item])).values(), + ]; + const d = arrayUniqueByKey.map((item, i) => { + return [ + i + 1, + item.orderCode, + format(new Date(item?.sendDate), "yyyy/MM/dd"), + item.poultryName, + item.poultryMobile, + item.city, + item.province, + item.age, + item.mainQuantity + " قطعه", + navigate(ROUTE_SLAUGHTER_FILE + item.poultryReqId)} + > + + , + ]; + }); + + setDataTable(d); + }, [slaughterActiveRequests]); + + const [tableDataCol] = useState([ + "ردیف", + "کد سفارش", + "تاریخ درخواست", + "مرغدار", + "تلفن مرغدار", + "شهر", + "استان", + "سن مرغ", + "تعداد", + "مشاهده", + ]); + + const formik = useFormik({ + initialValues: { + capacity: "", + recieveTime: "", + recieveDate: moment(Date()).format("YYYY-MM-DD hh:mm:ss"), + }, + validationSchema: Yup.object({ + capacity: Yup.number() + .required("این فیلد اجباری است!") + .typeError("لطفا عدد وارد کنید!"), + recieveTime: Yup.string() + .required("این فیلد اجباری است!") + .typeError("لطفا وزن را وارد کنید!"), + }), + }); + + useEffect(() => { + formik.validateForm(); + }, []); + + return ( + + + + + درخواست های فعال + + + ( + + )} + value={selectedDate1} + onChange={(e) => { + setSelectedDate1(moment(e).format("YYYY-MM-DD")); + }} + /> + + + ( + + )} + value={selectedDate2} + onChange={(e) => { + setSelectedDate2(moment(e).format("YYYY-MM-DD")); + }} + /> + + + } + columns={tableDataCol} + data={dataTable} + /> + + + ); +}; diff --git a/src/features/slaughter-house/components/slaughter-add-daily-list/SlaughterAddDailyList.js b/src/features/slaughter-house/components/slaughter-add-daily-list/SlaughterAddDailyList.js new file mode 100644 index 0000000..1f53acc --- /dev/null +++ b/src/features/slaughter-house/components/slaughter-add-daily-list/SlaughterAddDailyList.js @@ -0,0 +1,120 @@ +import { useContext, useEffect, useState } from "react"; +import { AppContext } from "../../../../contexts/AppContext"; +import { useDispatch, useSelector } from "react-redux"; +import { Autocomplete, Button, Chip, TextField } from "@mui/material"; +import { Grid } from "../../../../components/grid/Grid"; +import { SPACING } from "../../../../data/spacing"; +import { + slaughterAddDailyListService, + slaughterGetGuildsService, +} from "../../services/slaughter-add-daily-list"; +import { DRAWER } from "../../../../lib/redux/slices/appSlice"; +import { checkPathStartsWith } from "../../../../utils/checkPathStartsWith"; + +export const SlaughterAddDailyList = ({ updateTable }) => { + const [openNotif] = useContext(AppContext); + const dispatch = useDispatch(); + const [guildsData, setGuildsData] = useState([]); + const [selectedItems, setSelectedItems] = useState([]); + const selectedSubUser = useSelector( + (state) => state.userSlice.selectedSubUser + ); + + useEffect(() => { + const fetchGuilds = async () => { + dispatch( + slaughterGetGuildsService({ + role_key: + checkPathStartsWith("slaughter") || checkPathStartsWith("steward") + ? selectedSubUser?.key || "" + : "", + }) + ).then((r) => { + setGuildsData(r.payload.data); + }); + }; + + fetchGuilds(); + }, [dispatch]); + + const handleSubmit = () => { + dispatch( + slaughterAddDailyListService({ + guild_key_list: selectedItems.map((item) => item.key), + }) + ).then((r) => { + if (r.payload.error) { + openNotif({ + vertical: "top", + horizontal: "center", + msg: "خطا در ثبت لیست", + severity: "error", + }); + } else { + openNotif({ + vertical: "top", + horizontal: "center", + msg: "لیست با موفقیت ثبت شد.", + severity: "success", + }); + dispatch(DRAWER({ right: false, bottom: false, content: null })); + updateTable(1); + } + }); + }; + const handleDelete = (key) => { + setSelectedItems((prev) => prev.filter((item) => item.key !== key)); + }; + + return ( + + null} + getOptionLabel={(option) => + `${option.steward ? "مباشر" : "صنف"} ${ + option.name || option.guildsName + } + ${option.user?.fullname || ""} + (${option.user?.mobile || ""})` + } + onChange={(event, values) => { + setSelectedItems(values); + }} + sx={{ width: "250px" }} + renderInput={(params) => ( + + )} + /> + + + {selectedItems.map((item) => ( + handleDelete(item.key)} + sx={{ width: "fit-content" }} + /> + ))} + + + + + ); +}; diff --git a/src/features/slaughter-house/components/slaughter-add-steward/SlaughterAddSteward.js b/src/features/slaughter-house/components/slaughter-add-steward/SlaughterAddSteward.js new file mode 100644 index 0000000..28b792d --- /dev/null +++ b/src/features/slaughter-house/components/slaughter-add-steward/SlaughterAddSteward.js @@ -0,0 +1,330 @@ +import { Autocomplete, Button, InputAdornment, TextField } from "@mui/material"; +import { useFormik } from "formik"; +import { useContext, useEffect, useState } from "react"; +import { useDispatch, useSelector } from "react-redux"; +import { Grid } from "../../../../components/grid/Grid"; +import { AppContext } from "../../../../contexts/AppContext"; +import { SPACING } from "../../../../data/spacing"; +import { CLOSE_MODAL } from "../../../../lib/redux/slices/appSlice"; +import { Yup } from "../../../../lib/yup/yup"; +import { slaughterGetUpdatedInventoryStock } from "../../services/salughter-get-updated-inventory-stock"; +import { slaughterManageInventoryAllocationsService } from "../../services/salughter-manage-inventory-allocations"; +import { slaughterAllocateStewardService } from "../../services/slaughter-allocate-steward"; +import { slaughterEditAllocateStewardService } from "../../services/slaughter-edit-allocate-steward"; +import { slaughterGetGuildsService } from "../../services/slaughter-get-guilds"; +import { slaughterGetKillhouseGuildsService } from "../../services/slaughter-get-killhouse-guilds"; +import { slaughterGetKillhouseStewardsService } from "../../services/slaughter-get-killhouse-stewards"; +import { slaughterGetStewardsService } from "../../services/slaughter-get-stewards"; +import { NumberInput } from "../../../../components/number-format-custom/NumberFormatCustom"; + +export const SlaughterAddSteward = ({ + stewardKey, + guildKey, + sellType, + isGuild, + weight, + quantity, + item, + totalAverageWeightOfCarcasses, +}) => { + const dispatch = useDispatch(); + const [openNotif] = useContext(AppContext); + const [, , selectedDate1] = useContext(AppContext); + const [price, setPrice] = useState(); + + const { + slaughterGetStewards, + inventorySelectedKillHouse, + slaughterGetGuilds, + } = useSelector((state) => state.slaughterSlice); + + useEffect(() => { + dispatch(slaughterGetStewardsService()); + dispatch(slaughterGetGuildsService()); + }, []); + + const getOptionLabel = (option) => option.label; + + const validationSchema = Yup.object({ + wholePrice: Yup.number().when("quantity", { + is: quantity, + then: Yup.number().required("لطفا این فیلد را پر کنید"), + otherwise: Yup.number(), + }), + slaughteSteward: Yup.string().required("لطفاً یک مورد را انتخاب کنید"), + numberOfPieces: Yup.number() + .required("حجم لاشه را وارد کنید") + .min(1, "حداقل یک قطعه"), + weight: Yup.number() + .required("وزن لاشه را وارد کنید") + .min(0.01, "حداقل 0.01 کیلوگرم"), + }); + + let defaultKey; + + if (isGuild) { + defaultKey = guildKey; + } else { + defaultKey = stewardKey; + } + + const formik = useFormik({ + initialValues: { + slaughteSteward: defaultKey, + numberOfPieces: quantity ? quantity : "", + weight: weight ? weight : "", + }, + validationSchema, + onSubmit: (values) => { + let req; + if (!isGuild) { + req = { + steward_key: values.slaughteSteward, + kill_house_key: inventorySelectedKillHouse, + number_of_carcasses: Number(values.numberOfPieces), + weight_of_carcasses: Number(values.weight), + sell_type: sellType, + date: selectedDate1, + amount: Number(price), + total_amount: Number(values.wholePrice), + }; + } else { + req = { + guild_key: values.slaughteSteward, + kill_house_key: inventorySelectedKillHouse, + number_of_carcasses: Number(values.numberOfPieces), + weight_of_carcasses: Number(values.weight), + sell_type: sellType, + date: selectedDate1, + amount: Number(price), + total_amount: Number(values.wholePrice), + }; + } + if (quantity) { + dispatch( + slaughterEditAllocateStewardService({ + steward_allocation_key: item.key, + number_of_carcasses: Number(values.numberOfPieces), + weight_of_carcasses: Number(values.weight), + }) + ).then((r) => { + if (r.payload.error) { + openNotif({ + vertical: "top", + horizontal: "center", + msg: r.payload.error, + severity: "error", + }); + } else { + dispatch( + slaughterGetKillhouseStewardsService({ + kill_house_key: inventorySelectedKillHouse, + date: selectedDate1, + }) + ); + dispatch( + slaughterGetUpdatedInventoryStock({ + kill_house_key: inventorySelectedKillHouse, + date: selectedDate1, + }) + ); + dispatch( + slaughterManageInventoryAllocationsService({ + kill_house_key: inventorySelectedKillHouse, + date: selectedDate1, + }) + ); + dispatch( + slaughterGetKillhouseGuildsService({ + kill_house_key: inventorySelectedKillHouse, + date: selectedDate1, + }) + ); + dispatch(CLOSE_MODAL()); + openNotif({ + vertical: "top", + horizontal: "center", + msg: "عملیات با موفقیت انجام شد.", + severity: "success", + }); + } + }); + } else { + dispatch(slaughterAllocateStewardService(req)).then((r) => { + if (r.payload.error) { + openNotif({ + vertical: "top", + horizontal: "center", + msg: r.payload.error, + severity: "error", + }); + } else { + dispatch( + slaughterGetKillhouseStewardsService({ + kill_house_key: inventorySelectedKillHouse, + date: selectedDate1, + }) + ); + dispatch( + slaughterGetUpdatedInventoryStock({ + kill_house_key: inventorySelectedKillHouse, + date: selectedDate1, + }) + ); + dispatch( + slaughterManageInventoryAllocationsService({ + kill_house_key: inventorySelectedKillHouse, + date: selectedDate1, + }) + ); + dispatch( + slaughterGetKillhouseGuildsService({ + kill_house_key: inventorySelectedKillHouse, + date: selectedDate1, + }) + ); + dispatch(CLOSE_MODAL()); + openNotif({ + vertical: "top", + horizontal: "center", + msg: "عملیات با موفقیت انجام شد.", + severity: "success", + }); + } + }); + } + }, + }); + + useEffect(() => { + const finalQuantity = formik.values.weight / totalAverageWeightOfCarcasses; + formik.setFieldValue("numberOfPieces", Number(finalQuantity).toFixed(0)); + }, [formik.values.weight]); + + useEffect(() => { + const calcPrice = formik.values.wholePrice / Number(formik.values.weight); + setPrice(Number(calcPrice.toFixed(0))); + }, [formik.values.wholePrice]); + + return ( +
    + + {!stewardKey && !guildKey && !isGuild && !quantity && ( + + formik.setFieldValue("slaughteSteward", value.value) + } + onBlur={formik.handleBlur("slaughteSteward")} + // value={formik.values.slaughteSteward} + renderInput={(params) => } + /> + )} + + {isGuild && !quantity && !stewardKey && !guildKey && ( + + formik.setFieldValue("slaughteSteward", value.value) + } + onBlur={formik.handleBlur("slaughteSteward")} + // value={formik.values.slaughteSteward} + renderInput={(params) => } + /> + )} + + کیلوگرم + ), + }} + {...formik.getFieldProps("weight")} + error={formik.touched.weight && formik.errors.weight} + helperText={formik.touched.weight && formik.errors.weight} + /> + + {!quantity && ( + <> + ریال + ), + }} + value={formik.values.wholePrice} + error={ + formik.touched.wholePrice + ? Boolean(formik.errors.wholePrice) + : null + } + onChange={formik.handleChange} + onBlur={formik.handleBlur} + helperText={ + formik.touched.wholePrice && Boolean(formik.errors.wholePrice) + ? formik.errors.wholePrice + : null + } + /> + + ریال + ), + readOnly: true, + }} + value={price} + /> + + )} + + قطعه, + }} + {...formik.getFieldProps("numberOfPieces")} + error={formik.touched.numberOfPieces && formik.errors.numberOfPieces} + helperText={ + formik.touched.numberOfPieces && formik.errors.numberOfPieces + } + /> + + +
    + ); +}; diff --git a/src/features/slaughter-house/components/slaughter-allocate-car-to-request-operation/SlaughterAllocatedCarToRequestOperation.js b/src/features/slaughter-house/components/slaughter-allocate-car-to-request-operation/SlaughterAllocatedCarToRequestOperation.js new file mode 100644 index 0000000..bfc1b0a --- /dev/null +++ b/src/features/slaughter-house/components/slaughter-allocate-car-to-request-operation/SlaughterAllocatedCarToRequestOperation.js @@ -0,0 +1,381 @@ +import { + Button, + IconButton, + List, + ListItemButton, + ListItemIcon, + ListItemText, + Popover, + Typography, +} from "@mui/material"; +import TuneIcon from "@mui/icons-material/Tune"; +import DeleteIcon from "@mui/icons-material/Delete"; +import EditIcon from "@mui/icons-material/Edit"; +import { Grid } from "../../../../components/grid/Grid"; +import { useContext, useState } from "react"; +import { useNavigate } from "react-router-dom"; +import { ROUTE_SLAUGHTER_FILE } from "../../../../routes/routes"; +import PlagiarismIcon from "@mui/icons-material/Plagiarism"; +import SettingsBackupRestoreIcon from "@mui/icons-material/SettingsBackupRestore"; +import AddCircleOutlineIcon from "@mui/icons-material/AddCircleOutline"; +import { slaughterDeleteAllocatedBackRequestService } from "../../services/slaughter-delete-allocated-back-kill-request"; +import { slaughterRemoveAllocateCarService } from "../../services/slaughter-remove-allocate-car"; +import { slaughterGetActiveRequests } from "../../services/slaughter-get-active-requests"; +import { slaughterGetAllocatedCarsService } from "../../services/slaughter-get-allocated-cars"; +import { AppContext } from "../../../../contexts/AppContext"; +import { useDispatch, useSelector } from "react-redux"; +import { + OPEN_MODAL, + CLOSE_MODAL, + DRAWER, +} from "../../../../lib/redux/slices/appSlice"; +import { SlaughterEditAllocatedCar } from "../slaughter-edit-allocated-car/SlaughterEditAllocatedCar"; +import { SlaughterSubmitChickenPrice } from "../slaughter-submit-chicken-price/SlaughterSubmitChickenPrice"; +import SlaughterAssignCar from "../../../file/components/slaughter-assign-car/SlaughterAssignCar"; +import { SPACING } from "../../../../data/spacing"; +import { checkPathStartsWith } from "../../../../utils/checkPathStartsWith"; + +export const SlaughterAllocatedCarToRequestOperation = ({ + item, + updateTable, + isAllocatedCar = false, + selectedDate1, + selectedDate2, + submitStatus, +}) => { + const [anchorEl, setAnchorEl] = useState(null); + const [openNotif, , contextDate1, , contextDate2] = useContext(AppContext); + const dispatch = useDispatch(); + const selectedSubUser = useSelector( + (state) => state.userSlice.selectedSubUser + ); + // Use prop dates if provided, otherwise use context dates + const date1 = selectedDate1 || contextDate1; + const date2 = selectedDate2 || contextDate2; + + const handleClick = (event) => { + setAnchorEl(event.currentTarget); + }; + + const handleClose = () => { + setAnchorEl(null); + }; + const navigate = useNavigate(); + + const open = Boolean(anchorEl); + const id = open ? "popover" : undefined; + + const confirmDeleteAllocatedCar = () => { + dispatch(slaughterRemoveAllocateCarService(item.killHouseRequestKey)).then( + (r) => { + if (r.payload?.error) { + openNotif({ + vertical: "top", + horizontal: "center", + msg: r.payload.error, + severity: "error", + }); + } else { + openNotif({ + vertical: "top", + horizontal: "center", + msg: "عملیات با موفقیت انجام شد.", + severity: "success", + }); + dispatch(CLOSE_MODAL()); + // Refresh both tables + dispatch( + slaughterGetActiveRequests({ + isCar: true, + selectedDate1: date1, + selectedDate2: date2, + role_key: checkPathStartsWith("slaughter") + ? selectedSubUser?.key || "" + : "", + }) + ); + dispatch( + slaughterGetAllocatedCarsService({ + selectedDate1: date1, + selectedDate2: date2, + role_key: checkPathStartsWith("slaughter") + ? selectedSubUser?.key || "" + : "", + }) + ); + if (updateTable) updateTable(); + } + } + ); + }; + + const handleDeleteAllocatedCar = () => { + handleClose(); + dispatch( + OPEN_MODAL({ + title: "تایید حذف", + content: ( + + + آیا از حذف تخصیص این خودرو اطمینان دارید؟ + + + + + + + ), + }) + ); + }; + + const handleEditAllocatedCar = () => { + dispatch( + OPEN_MODAL({ + title: "ویرایش خودرو و کد حمل", + content: ( + { + // Refresh both tables + dispatch( + slaughterGetActiveRequests({ + isCar: true, + selectedDate1: date1, + selectedDate2: date2, + role_key: checkPathStartsWith("slaughter") + ? selectedSubUser?.key || "" + : "", + }) + ); + dispatch( + slaughterGetAllocatedCarsService({ + selectedDate1: date1, + selectedDate2: date2, + role_key: checkPathStartsWith("slaughter") + ? selectedSubUser?.key || "" + : "", + }) + ); + if (updateTable) updateTable(); + }} + poultryRequestKey={item?.poultryReqKey} + killHouseKey={item?.killHouseKey} + killRequestKey={item?.killRequestKey} + /> + ), + }) + ); + handleClose(); + }; + + const handleViewFile = () => { + navigate(ROUTE_SLAUGHTER_FILE + item.poultryReqId); + }; + + const handleReturnAllocation = () => { + dispatch( + slaughterDeleteAllocatedBackRequestService({ + provinceKillRequestKey: item?.provinceKillRequestKey, + returnAllocationQuantity: true, + }) + ).then((r) => { + if (r.error) { + openNotif({ + vertical: "top", + horizontal: "center", + msg: r.error, + severity: "error", + }); + } else { + if (updateTable) { + updateTable(); + } + openNotif({ + vertical: "top", + horizontal: "center", + msg: "عملیات برگشت تخصیص با موفقیت انجام شد.", + severity: "success", + }); + } + }); + }; + + const handleRegisterCar = () => { + if (submitStatus === true && item?.killHousePrice === 0) { + dispatch( + OPEN_MODAL({ + title: "ثبت قیمت مرغ زنده", + content: ( + + ), + }) + ); + } else { + dispatch( + DRAWER({ + title: "انجام عملیات تخصیص", + top: !(window.innerWidth <= 600), + bottom: window.innerWidth <= 600, + content: ( + + ), + }) + ); + } + }; + + const options = []; + + if (!isAllocatedCar) { + const needsPrice = + submitStatus === true && (item?.killHousePrice || 0) === 0; + + options.push({ + key: "register", + label: "ثبت خودرو", + color: needsPrice ? "error.main" : "primary.main", + icon: AddCircleOutlineIcon, + action: handleRegisterCar, + }); + + options.push({ + key: "viewFile", + label: "مشاهده پرونده", + color: "primary.main", + icon: PlagiarismIcon, + action: handleViewFile, + }); + + const returnDisabled = item?.allocatedQuantity > 0; + options.push({ + key: "return", + label: "برگشت تخصیص", + color: returnDisabled ? "text.disabled" : "warning.main", + icon: SettingsBackupRestoreIcon, + action: handleReturnAllocation, + disabled: returnDisabled, + }); + } + + if (isAllocatedCar) { + options.push({ + key: "editAllocated", + label: "ویرایش خودرو و کد حمل", + color: "info.main", + icon: EditIcon, + action: handleEditAllocatedCar, + }); + + options.push({ + key: "deleteAllocated", + label: "حذف تخصیص خودرو", + color: "error.main", + icon: DeleteIcon, + action: handleDeleteAllocatedCar, + }); + } + + const handleOptionClick = (option) => { + if (option.disabled) { + return; + } + handleClose(); + option.action(); + }; + + return ( + + + + + + + {options.map((option) => { + const IconComponent = option.icon; + const itemColor = option.disabled ? "text.disabled" : option.color; + return ( + handleOptionClick(option)} + sx={{ + borderRadius: 1, + mb: 0.25, + py: 0.5, + "&:last-of-type": { + mb: 0, + }, + }} + > + + + + + + ); + })} + + + + ); +}; diff --git a/src/features/slaughter-house/components/slaughter-allocate-car-to-requests/SlaughterAllocateCarToRequests.js b/src/features/slaughter-house/components/slaughter-allocate-car-to-requests/SlaughterAllocateCarToRequests.js new file mode 100644 index 0000000..4ae1731 --- /dev/null +++ b/src/features/slaughter-house/components/slaughter-allocate-car-to-requests/SlaughterAllocateCarToRequests.js @@ -0,0 +1,346 @@ +import { Grid, IconButton, TextField, Tooltip } from "@mui/material"; +import { SPACING } from "../../../../data/spacing"; +import { useFormik } from "formik"; +import moment from "moment"; +import { Yup } from "../../../../lib/yup/yup"; +import { useDispatch, useSelector } from "react-redux"; +import { slaughterGetActiveRequests } from "../../services/slaughter-get-active-requests"; +import { useContext, useEffect, useState } from "react"; +import EditIcon from "@mui/icons-material/Edit"; +import { OPEN_MODAL } from "../../../../lib/redux/slices/appSlice"; +import { slaughterGetAllocatedCarsService } from "../../services/slaughter-get-allocated-cars"; +import { AppContext } from "../../../../contexts/AppContext"; +import { format } from "date-fns-jalali"; +import { DatePicker } from "@mui/x-date-pickers"; +import PictureAsPdfIcon from "@mui/icons-material/PictureAsPdf"; +import { useReactToPrint } from "react-to-print"; +import { useRef } from "react"; +import SlaughterSendKillerInvoice from "../slaughter-send-killer-invoice/SlaughterSendKillerInvoice"; +import { useSystemName } from "../../../../utils/getSystemName"; +import { formatJustDate, formatTime } from "../../../../utils/formatTime"; +import ResponsiveTable from "../../../../components/responsive-table/ResponsiveTable"; +import { provincePolicyGetSLaughterSubmitBuyingPriceStatus } from "../../../province/services/province-policy-get-slaughter-buying-price-status"; +import { SlaughterSubmitChickenPrice } from "../slaughter-submit-chicken-price/SlaughterSubmitChickenPrice"; +import { SlaughterAllocatedCarToRequestOperation } from "../slaughter-allocate-car-to-request-operation/SlaughterAllocatedCarToRequestOperation"; +import { checkPathStartsWith } from "../../../../utils/checkPathStartsWith"; + +export const SlaughterAllocateCarToRequests = () => { + const componentRef = useRef(); + const selectedSubUser = useSelector( + (state) => state.userSlice.selectedSubUser + ); + const [data, setData] = useState(); + const [dataTable, setDataTable] = useState([]); + const [allocatedDataTable, setAllocatedDataTable] = useState([]); + const { slaughterActiveRequests, slaughterGetAllocatedCars } = useSelector( + (state) => state.slaughterSlice + ); + + const systemName = useSystemName(); + const dispatch = useDispatch(); + const [, , selectedDate1, setSelectedDate1, selectedDate2, setSelectedDate2] = + useContext(AppContext); + + const [submitStatus, SetSubmitStatus] = useState(); + + const fetchData = () => { + dispatch( + slaughterGetActiveRequests({ + isCar: true, + selectedDate1, + selectedDate2, + role_key: checkPathStartsWith("slaughter") + ? selectedSubUser?.key || "" + : "", + }) + ); + dispatch( + slaughterGetAllocatedCarsService({ + selectedDate1, + selectedDate2, + role_key: checkPathStartsWith("slaughter") + ? selectedSubUser?.key || "" + : "", + }) + ); + dispatch( + provincePolicyGetSLaughterSubmitBuyingPriceStatus({ + role_key: checkPathStartsWith("slaughter") + ? selectedSubUser?.key || "" + : "", + }) + ).then((r) => { + SetSubmitStatus(r.payload.data.allow); + }); + }; + + useEffect(() => { + fetchData(); + }, [selectedDate1, selectedDate2, selectedSubUser?.key]); + + const printPDF = useReactToPrint({ + content: () => componentRef.current, + documentTitle: "حواله خرید", + }); + const updateTable = () => { + fetchData(); + }; + + const setPdfOptions = (item) => { + setData(item); + }; + + useEffect(() => { + const d = slaughterActiveRequests?.map((item, i) => { + return [ + i + 1, + item.orderCode, + item?.freezing ? "انجماد" : item?.export ? "صادرات" : "عادی", + item?.freeSaleInProvince ? "آزاد" : "دولتی", + item?.directBuying ? "خرید مستقیم" : "اتحادیه", + format(new Date(item?.sendDate), "yyyy/MM/dd"), + `${item.poultryName} (${item.poultryMobile})`, + `${item.killHouseName} (${item.killHouseMobile})`, + `${item.province}/${item.city}`, + item.age, + item.indexWeight, + item?.totalWeight.toLocaleString(), + item.mainQuantity.toLocaleString() + " قطعه", + item.amount.toLocaleString() + " ﷼", + item.allocatedQuantity.toLocaleString() + " قطعه", + item.remainQuantity.toLocaleString() + " قطعه", + item?.killHousePrice > 0 ? ( + + {item?.killHousePrice?.toLocaleString() + " ریال"} + {formatJustDate(item?.sendDate) === formatJustDate(new Date()) ? ( + { + dispatch( + OPEN_MODAL({ + title: "ویرایش قیمت مرغ زنده", + content: ( + + ), + }) + ); + }} + > + + + ) : null} + + ) : ( + 0 + ), + + , + // navigate(ROUTE_SLAUGHTER_FILE + item.poultryReqId)} + // > + // + // , + ]; + }); + + setDataTable(d); + }, [slaughterActiveRequests, submitStatus]); + + useEffect(() => { + const d = slaughterGetAllocatedCars + ?.filter((item) => item.vetState === "pending") + .map((item, i) => { + return [ + i + 1, + item?.orderCode, + item?.barcod, + item?.freezing ? "انجماد" : item?.export ? "صادرات" : "عادی", + item?.freeSaleInProvince ? "آزاد" : "دولتی", + formatJustDate(item?.sendDate), + formatTime(item?.killHouseCreateDate), + `${item?.poultryName} (${item.poultryMobile})`, + `${item?.killHouseName} (${item.killHouseMobile})`, + item?.killer + ? `${item?.killer?.killerName} (${item?.killer?.killerMobile})` + : "-", + item?.driverName, + item?.typeCar, + item?.pelak, + // item?.realCar + // ? `${item?.realCar?.realTypeCar} (${ + // item?.realCar?.realPelak ? item?.realCar?.realPelak : "نامشخص" + // }) - راننده: ${item?.realCar?.realDriverName}` + // : "-", + item?.acceptedRealQuantity.toLocaleString() + " قطعه", + item?.acceptedRealWeight.toLocaleString(), + item?.amount?.toLocaleString() + " ﷼", + item?.trafficCode, + item?.barAmount?.toLocaleString() + " ﷼", + + + + {systemName === "استان اردبیل" ? ( + + { + printPDF(); + setPdfOptions(item); + }} + size={"large"} + aria-label="pdf" + color="success" + > + + + + ) : null} + , + ]; + }); + + setAllocatedDataTable(d); + }, [slaughterGetAllocatedCars]); + + const [tableDataCol] = useState([ + "ردیف", + "کد سفارش", + "کشتار", + "فروش", + "درخواست", + "تاریخ کشتار", + "مرغدار", + "خریدار", + "استان/شهر", + "سن", + "میانگین وزن", + "وزن کل (کیلوگرم)", + "تعداد", + "قیمت مرغدار", + "تخصیص به خودرو", + "مانده قابل تخصیص", + "قیمت کشتارگاه", + "عملیات", + ]); + + const formik = useFormik({ + initialValues: { + capacity: "", + recieveTime: "", + recieveDate: moment(Date()).format("YYYY-MM-DD hh:mm:ss"), + }, + validationSchema: Yup.object({ + capacity: Yup.number() + .required("این فیلد اجباری است!") + .typeError("لطفا عدد وارد کنید!"), + recieveTime: Yup.string() + .required("این فیلد اجباری است!") + .typeError("لطفا وزن را وارد کنید!"), + }), + }); + + useEffect(() => { + formik.validateForm(); + }, []); + + return ( + + {data && ( +
    + +
    + )} + + + + ( + + )} + value={selectedDate1} + onChange={(e) => { + setSelectedDate1(moment(e).format("YYYY-MM-DD")); + }} + /> + + + ( + + )} + value={selectedDate2} + onChange={(e) => { + setSelectedDate2(moment(e).format("YYYY-MM-DD")); + }} + /> + + + + +
    + ); +}; diff --git a/src/features/slaughter-house/components/slaughter-allocate-for-freezing/SlaughterAllocateForFreezing.js b/src/features/slaughter-house/components/slaughter-allocate-for-freezing/SlaughterAllocateForFreezing.js new file mode 100644 index 0000000..e8c970f --- /dev/null +++ b/src/features/slaughter-house/components/slaughter-allocate-for-freezing/SlaughterAllocateForFreezing.js @@ -0,0 +1,595 @@ +import React, { useContext, useEffect, useState, useCallback } from "react"; +import { Grid } from "../../../../components/grid/Grid"; +import { + Autocomplete, + Button, + FormControl, + FormControlLabel, + Radio, + RadioGroup, + TextField, + Typography, +} from "@mui/material"; +import { useDispatch, useSelector } from "react-redux"; +import { slaughterGetProductsService } from "../../services/slaughter-inventory-gets"; +import { NumberInput } from "../../../../components/number-format-custom/NumberFormatCustom"; +import { useFormik } from "formik"; +import { Yup } from "../../../../lib/yup/yup"; +import { + slaughterAllocateStewardService, + slaughterEditAllocateStewardService, +} from "../../services/slaughter-allocate-steward"; +import { AppContext } from "../../../../contexts/AppContext"; +import { CLOSE_MODAL } from "../../../../lib/redux/slices/appSlice"; +import { liveStockGetInventoryData } from "../../../live-stock-support/services/live-stock-get-inventory-data"; +import { DatePicker } from "@mui/x-date-pickers"; +import moment from "moment"; +import { fetchSlaughterBroadcastAndProducts } from "../../services/handle-fetch-slaughter-products"; +import MonthlyDataCalendar from "../../../../components/date-picker/MonthlyDataCalendar"; +import PersianDate from "persian-date"; +import axios from "axios"; +import { checkPathStartsWith } from "../../../../utils/checkPathStartsWith"; +import { LabelField } from "../../../../components/label-field/LabelField"; + +export const SlaughterAllocateForFreezing = ({ + sellerType, + sellType, + updateTable, + fetchApiData, + editData, + remainWeight, + priceInfo, +}) => { + const dispatch = useDispatch(); + const [productData, setProductData] = useState([]); + const [productKey, setProductKey] = useState(null); + const [coldHouseData, setColdHouseData] = useState([]); + const [coldHouseKey, setColdHouseKey] = useState(null); + const [selectedInventory, setSelectedInventory] = useState("governmental"); + const [approvedStatus, setApprovedStatus] = useState( + priceInfo?.active === false ? false : true + ); + const selectedSubUser = useSelector( + (state) => state.userSlice.selectedSubUser + ); + const [openNotif] = useContext(AppContext); + + // Calendar states + const [selectedCalendarDate, setSelectedCalendarDate] = useState(null); + const [calendarDayData, setCalendarDayData] = useState({}); + const [productionDate, setProductionDate] = useState(null); + const [selectedDateAmount, setSelectedDateAmount] = useState(null); + const [calendarRawData, setCalendarRawData] = useState({ + governmental: [], + free: [], + }); + + const transformCalendarData = useCallback((dataArray) => { + if (!Array.isArray(dataArray)) return {}; + + const transformedData = {}; + dataArray.forEach((item) => { + if (item.day && item.amount !== undefined) { + const persianDate = new PersianDate(new Date(item.day)); + const persianDateStr = persianDate.format("YYYY/MM/DD"); + transformedData[persianDateStr] = { + value1: item.amount, + originalDay: item.day, + active: item.active === true, + }; + } + }); + return transformedData; + }, []); + + const updateCalendarData = useCallback( + (dataArray) => { + const transformed = transformCalendarData(dataArray); + setCalendarDayData(transformed); + }, + [transformCalendarData] + ); + + // Fetch calendar data from API + const fetchCalendarData = useCallback( + async (dateParam) => { + try { + const response = await axios.get("/kill-house-remain-weight/", { + params: { + date: dateParam, + role_key: checkPathStartsWith("slaughter") + ? selectedSubUser?.key || "" + : "", + }, + }); + if (response.data) { + setCalendarRawData({ + governmental: response.data.governmental || [], + free: response.data.free || [], + }); + const dataToShow = + selectedInventory === "governmental" + ? response.data.governmental + : response.data.free; + updateCalendarData(dataToShow); + } + } catch (error) { + console.error("Error fetching calendar data:", error); + } + }, + [selectedInventory, updateCalendarData, selectedSubUser] + ); + + const handleDateSelect = (dateInfo) => { + if (dateInfo && dateInfo.formattedDate) { + setSelectedCalendarDate(dateInfo.formattedDate); + + const data = calendarDayData[dateInfo.formattedDate]; + + if (data && data.originalDay) { + const selectedOriginalDay = data.originalDay; + if ( + selectedDate1 && + moment(selectedOriginalDay).isAfter(moment(selectedDate1), "day") + ) { + setCalendarDateError( + "تاریخ تولید نمی‌تواند بعد از تاریخ انتخابی باشد" + ); + return; + } + setCalendarDateError(null); + setProductionDate(selectedOriginalDay); + } + + if (data && data.value1 !== undefined) { + setSelectedDateAmount(data.value1); + } else { + setSelectedDateAmount(null); + } + } + }; + + const getValidationSchema = useCallback( + () => + Yup.object({ + weight: Yup.number() + .required("این فیلد اجباری است!") + .integer("عدد باید صحیح باشد!") + .min(1, "یک مقدار مثبت وارد کنید!") + .max( + remainWeight + (editData?.realWeightOfCarcasses || 0), + "وزن وارد شده بیش از موجودی انبار است!" + ) + .test( + "max-production-date-amount", + `وزن نمی‌تواند بیشتر از موجودی تاریخ تولید (${ + selectedDateAmount?.toLocaleString() || 0 + } کیلوگرم) باشد!`, + function (value) { + if (!selectedDateAmount || selectedDateAmount === null) + return true; + return value <= selectedDateAmount; + } + ), + }), + [remainWeight, editData, selectedDateAmount] + ); + + const validationSchema = getValidationSchema(); + const [selectedDate1, setSelectedDate1] = useState( + moment(new Date()).format("YYYY-MM-DD") + ); + const [dateRangeError, setDateRangeError] = useState(null); + const [calendarDateError, setCalendarDateError] = useState(null); + + const formik = useFormik({ + initialValues: { + weight: editData?.realWeightOfCarcasses || "", + }, + validationSchema, + }); + + const successSubmit = () => { + dispatch(CLOSE_MODAL()); + openNotif({ + vertical: "top", + horizontal: "center", + msg: "عملیات با موفقیت انجام شد.", + severity: "success", + }); + dispatch( + fetchSlaughterBroadcastAndProducts({ + role_key: checkPathStartsWith("slaughter") + ? selectedSubUser?.key || "" + : "", + }) + ); + fetchApiData(); + updateTable(); + }; + + const handleSellType = (event) => { + const newType = event.target.value; + setSelectedInventory(newType); + }; + + const handleApprovedPrice = (event) => { + const newType = event.target.value; + setApprovedStatus(newType); + }; + + useEffect(() => { + if (!editData) { + dispatch( + slaughterGetProductsService({ + role_key: checkPathStartsWith("slaughter") + ? selectedSubUser?.key || "" + : "", + }) + ).then((r) => { + setProductData(r.payload.data); + }); + + dispatch( + liveStockGetInventoryData({ + role_key: checkPathStartsWith("slaughter") + ? selectedSubUser?.key || "" + : "", + }) + ).then((r) => { + setColdHouseData(r.payload.data); + }); + } + fetchCalendarData(selectedDate1); + }, [ + dispatch, + editData, + fetchCalendarData, + selectedDate1, + selectedSubUser?.key, + ]); + + useEffect(() => { + fetchCalendarData(selectedDate1); + }, [selectedDate1, fetchCalendarData, selectedSubUser?.key]); + + useEffect(() => { + if ( + calendarRawData.governmental.length > 0 || + calendarRawData.free.length > 0 + ) { + const dataToShow = + selectedInventory === "governmental" + ? calendarRawData.governmental + : calendarRawData.free; + updateCalendarData(dataToShow); + setSelectedCalendarDate(null); + setProductionDate(null); + setSelectedDateAmount(null); + } + }, [selectedInventory, calendarRawData, updateCalendarData]); + + useEffect(() => { + formik.validateForm(); + }, [selectedDateAmount]); + + return ( + + {!editData && ( + ( + + )} + shouldDisableDate={(date) => { + const d = moment(date); + const today = moment(); + const yesterday = moment().subtract(1, "day"); + return !(d.isSame(today, "day") || d.isSame(yesterday, "day")); + }} + value={selectedDate1} + onChange={(e) => { + if (!e) { + setDateRangeError(null); + return; + } + const d = moment(e); + const today = moment(); + const yesterday = moment().subtract(1, "day"); + const isAllowed = + d.isSame(today, "day") || d.isSame(yesterday, "day"); + if (!isAllowed) { + setDateRangeError( + "تنها امکان انتخاب «امروز» یا «دیروز» وجود دارد." + ); + return; + } + setDateRangeError(null); + const formatted = moment(e).format("YYYY-MM-DD"); + setSelectedDate1(formatted); + fetchCalendarData(formatted); + }} + /> + )} + {!editData && ( + + { + return { + data: i, + label: `${i.name}`, + }; + }) + : [] + } + onChange={(event, value) => { + setProductKey(value.data); + }} + renderInput={(params) => ( + + )} + /> + + )} + + {!editData && ( + + { + return { + data: i, + label: `${i.name}`, + }; + }) + : [] + } + onChange={(event, value) => { + setColdHouseKey(value.data?.key); + }} + renderInput={(params) => ( + + )} + /> + + )} + + {!editData && priceInfo?.active && ( + + + } + label="قیمت دولتی" + /> + } + label="قیمت آزاد" + /> + + + )} + + {!editData && ( + + + + + } + label="دولتی" + /> + } + label="آزاد" + /> + + + + + )} + + {!editData && ( + + + {calendarDateError && ( + + {calendarDateError} + + )} + + )} + + selectedDateAmount + } + onChange={(e) => { + const value = e.target.value; + if (value === "" || value === null || value === undefined) { + formik.setFieldValue("weight", ""); + return; + } + const intValue = Math.floor(Number(value)); + if (intValue > 0) { + formik.setFieldValue("weight", intValue); + } else if (intValue === 0) { + formik.setFieldValue("weight", ""); + } + }} + onBlur={formik.handleBlur} + helperText={ + remainWeight < 1 + ? "موجودی انبار خالی است!" + : selectedDateAmount && formik.values.weight > selectedDateAmount + ? `وزن نمی‌تواند بیشتر از موجودی تاریخ تولید (${selectedDateAmount?.toLocaleString()} کیلوگرم) باشد!` + : formik.touched.weight && Boolean(formik.errors.weight) + ? formik.errors.weight + : null + } + /> + + + + ); +}; diff --git a/src/features/slaughter-house/components/slaughter-allocate-self-steward/SlaughterAllocateSelfSteward.js b/src/features/slaughter-house/components/slaughter-allocate-self-steward/SlaughterAllocateSelfSteward.js new file mode 100644 index 0000000..0df6245 --- /dev/null +++ b/src/features/slaughter-house/components/slaughter-allocate-self-steward/SlaughterAllocateSelfSteward.js @@ -0,0 +1,39 @@ +import { Button } from "@mui/material"; +import { useDispatch } from "react-redux"; +import { OPEN_MODAL } from "../../../../lib/redux/slices/appSlice"; +import { SlaughterAddSteward } from "../slaughter-add-steward/SlaughterAddSteward"; + +export const SlaughterAllocateSelfSteward = ({ + stewardKey, + guildKey, + isGuild, + finalSubmitDisabled, + slaughterUpdatedInventoryStock, +}) => { + const dispatch = useDispatch(); + return ( + + ); +}; diff --git a/src/features/slaughter-house/components/slaughter-allocate-to-coldhouse/SlaughterAllocateToColdHouse.js b/src/features/slaughter-house/components/slaughter-allocate-to-coldhouse/SlaughterAllocateToColdHouse.js new file mode 100644 index 0000000..3899d10 --- /dev/null +++ b/src/features/slaughter-house/components/slaughter-allocate-to-coldhouse/SlaughterAllocateToColdHouse.js @@ -0,0 +1,602 @@ +import React, { useContext, useEffect, useState } from "react"; +import { Grid } from "../../../../components/grid/Grid"; +import { + Autocomplete, + Button, + FormControl, + FormControlLabel, + InputAdornment, + Radio, + RadioGroup, + TextField, + Typography, +} from "@mui/material"; +import { useDispatch, useSelector } from "react-redux"; +import { slaughterGetProductsService } from "../../services/slaughter-inventory-gets"; +import { NumberInput } from "../../../../components/number-format-custom/NumberFormatCustom"; +import { useFormik } from "formik"; +import { Yup } from "../../../../lib/yup/yup"; +import { + slaughterAllocateStewardService, + slaughterEditAllocateStewardService, +} from "../../services/slaughter-allocate-steward"; +import { AppContext } from "../../../../contexts/AppContext"; +import { CLOSE_MODAL } from "../../../../lib/redux/slices/appSlice"; +import { + slaughterGetColdHousesForAllocateService, + slaughterGetGuildsForAllocateService, +} from "../../services/slaughter-get-guilds-for-allocate"; +import { DatePicker } from "@mui/x-date-pickers"; +import moment from "moment"; +import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl"; +import { ImageUpload } from "../../../../components/image-upload/ImageUpload"; +import { fixBase64 } from "../../../../utils/toBase64"; +import { provincePolicyGetUploadImageService } from "../../../province/services/province-policy-upload-image"; +import { fetchSlaughterBroadcastAndProducts } from "../../services/handle-fetch-slaughter-products"; +import { checkPathStartsWith } from "../../../../utils/checkPathStartsWith"; + +export const SlaughterAllocateToColdHouse = ({ + item, + key, + sellerType, + fetchData, + buyerType, + allocationType, + sellType, + updateTable, + fetchApiData, + editData, + priceInfo, + coldHouseKey, + coldHouseItemKey, + remainWeight, + killHouseAllocation, +}) => { + const dispatch = useDispatch(); + const [productData, setProductData] = useState([]); + const [guildsData, setGuildsData] = useState([]); + const [coldHouseData, setColdHouseData] = useState([]); + const [productKey, setProductKey] = useState(null); + const [openNotif] = useContext(AppContext); + const [sellGovernmental, setSellGovernmental] = useState( + priceInfo?.active ? "true" : "false" + ); + const [profileImages, setProfileImages] = useState( + editData?.image ? [{ data_url: editData.image }] : [] + ); + const [value, setValue] = useState("own"); + const [imageUploadLimit, setImageUploadLimit] = useState(1); + const [imageChanged, setImageChanged] = useState(false); + const selectedSubUser = useSelector( + (state) => state.userSlice.selectedSubUser + ); + + const handleChange = (event) => { + setValue(event.target.value); + setBuyerData({ + key: "", + item: "", + buyerType: "", + allocationType: "", + }); + }; + + const handleChangeSellGovernmental = (event) => { + setSellGovernmental(event.target.value); + if (event.target.value === "false") { + formik.setFieldValue("price", ""); + } + }; + + const [buyerData, setBuyerData] = useState({ + key, + item, + buyerType, + allocationType, + }); + + useEffect(() => { + if (getRoleFromUrl() === "Steward") { + setValue("free"); + } + }, []); + + useEffect(() => { + dispatch(provincePolicyGetUploadImageService()).then((r) => { + if (r.payload?.data) { + setImageUploadLimit(r.payload.data.killHouseAllocation); + } + }); + + if (!editData) { + dispatch( + slaughterGetProductsService({ + role_key: checkPathStartsWith("slaughter") + ? selectedSubUser?.key || "" + : "", + }) + ).then((r) => { + setProductData(r.payload.data); + }); + if (!item) { + if (value === "cold") { + dispatch( + slaughterGetColdHousesForAllocateService({ + role_key: checkPathStartsWith("slaughter") + ? selectedSubUser?.key || "" + : "", + }) + ).then((r) => { + setColdHouseData(r.payload.data); + }); + } + dispatch( + slaughterGetGuildsForAllocateService({ + free: value === "free" ? true : false, + role_key: checkPathStartsWith("slaughter") + ? selectedSubUser?.key || "" + : "", + }) + ).then((r) => { + setGuildsData(r.payload.data); + }); + } + } + }, [dispatch, value, selectedSubUser?.key]); + + const validationSchema = Yup.object({ + weight: Yup.number() + .required("این فیلد اجباری است!") + .min(1, "یک مقدار مثبت وارد کنید!") + .max( + editData + ? remainWeight + editData?.realWeightOfCarcasses + : remainWeight, + "وزن وارد شده بیش از موجودی انبار است!" + ), + price: Yup.number() + .required("این فیلد اجباری است!") + .min(1, "یک مقدار مثبت وارد کنید!"), + wholePrice: Yup.number() + .required("این فیلد اجباری است!") + .min(1, "یک مقدار مثبت وارد کنید!"), + ...(killHouseAllocation && { + image: Yup.string().when([], { + is: () => (!editData || imageChanged) && imageUploadLimit > 0, + then: Yup.string().required("عکس الزامی است"), + otherwise: Yup.string().notRequired(), + }), + }), + }); + + const factorPaymentHandler = (imageList) => { + if (imageList[0]) { + formik.setFieldValue("image", fixBase64(imageList[0]?.data_url)); + setImageChanged(true); + } else { + formik.setFieldValue("image", ""); + setImageChanged(true); + } + setProfileImages(imageList); + }; + + const formik = useFormik({ + initialValues: { + weight: editData?.realWeightOfCarcasses || "", + wholePrice: editData?.totalAmount || "", + price: editData?.amount || "", + image: editData?.image || "", + }, + validationSchema, + }); + + useEffect(() => { + formik.validateForm(); + }, []); + + useEffect(() => { + if (sellGovernmental === "false") { + if (formik.values.weight && formik.values.price) { + formik.setFieldValue( + "wholePrice", + formik.values.price * formik.values.weight + ); + } + } else { + if (priceInfo?.active && formik.values.weight) { + formik.setFieldValue( + "wholePrice", + priceInfo?.killHousePrice * formik.values.weight + ); + } + } + }, [formik.values.price, formik.values.weight, sellGovernmental]); + + useEffect(() => { + if (priceInfo?.active && sellGovernmental === "true") { + formik.setFieldValue("price", priceInfo?.killHousePrice); + } + }, [sellGovernmental]); + + const successSubmit = () => { + dispatch(CLOSE_MODAL()); + openNotif({ + vertical: "top", + horizontal: "center", + msg: "عملیات با موفقیت انجام شد.", + severity: "success", + }); + dispatch( + fetchSlaughterBroadcastAndProducts({ + role_key: checkPathStartsWith("slaughter") + ? selectedSubUser?.key || "" + : "", + }) + ); + + fetchApiData && fetchApiData(1); + updateTable && updateTable(); + fetchData && fetchData(1); + }; + + const [selectedDate1, setSelectedDate1] = useState( + moment(new Date()).format("YYYY-MM-DD") + ); + + return ( + + {!editData && ( + } + value={selectedDate1} + onChange={(e) => { + setSelectedDate1(moment(e).format("YYYY-MM-DD")); + }} + /> + )} + + {!editData && !coldHouseKey && ( + + { + return { + data: i, + label: `${i.name}`, + }; + }) + : [] + } + onChange={(event, value) => { + setProductKey(value.data); + }} + renderInput={(params) => ( + + )} + /> + + )} + + {!editData && ( + + + } + label="صنوف اختصاصی" + /> + } + label="صنوف آزاد" + /> + } + label="انتقال به سردخانه" + /> + + + )} + + {!item && !editData && value !== "cold" && ( + + { + return { + data: i, + label: `${i?.steward ? "مباشر" : "صنف"} ${ + i?.guildsName + } ${i?.user?.fullname} (${i?.user?.mobile})`, + }; + }) + : [] + } + onChange={(event, value) => { + setBuyerData({ + item: value?.data, + key: value?.data?.key, + allocationType: value?.data?.steward + ? "killhouse_steward" + : "killhouse_guild", + buyerType: value?.data?.steward ? "Steward" : "Guild", + }); + }} + renderInput={(params) => ( + + )} + /> + + )} + + {!item && !editData && value === "cold" && ( + + { + return { + data: i, + label: `سردخانه ${i?.name} (${ + i?.steward?.user?.mobile || + i?.killHouse?.killHouseOperator?.user?.mobile + })`, + }; + }) + : [] + } + onChange={(event, value) => { + setBuyerData({ + item: value?.data, + key: value?.data?.key, + allocationType: "ColdHouse", + buyerType: "ColdHouse", + }); + }} + renderInput={(params) => ( + + )} + /> + + )} + remainWeight + ? "error.main" + : undefined, + }, + }} + /> + + {priceInfo?.active && ( + + + } + label="قیمت مصوب" + /> + } + label="قیمت آزاد" + /> + + + )} + + ریال, + }} + value={formik.values.price} + error={formik.touched.price ? Boolean(formik.errors.price) : null} + onChange={formik.handleChange} + onBlur={formik.handleBlur} + helperText={ + formik.touched.price && Boolean(formik.errors.price) + ? formik.errors.price + : null + } + /> + + ریال, + }} + value={formik.values.wholePrice} + error={ + formik.touched.wholePrice ? Boolean(formik.errors.wholePrice) : null + } + onChange={formik.handleChange} + onBlur={formik.handleBlur} + helperText={ + formik.touched.wholePrice && Boolean(formik.errors.wholePrice) + ? formik.errors.wholePrice + : null + } + /> + {(killHouseAllocation || (editData && editData.image)) && ( + <> + + {formik.touched.image && Boolean(formik.errors.image) && ( + ثبت تصویر الزامی است + )} + + )} + + + ); +}; diff --git a/src/features/slaughter-house/components/slaughter-allocate-to-freezing/SlaughterAllocateToFreezing.js b/src/features/slaughter-house/components/slaughter-allocate-to-freezing/SlaughterAllocateToFreezing.js new file mode 100644 index 0000000..c556a17 --- /dev/null +++ b/src/features/slaughter-house/components/slaughter-allocate-to-freezing/SlaughterAllocateToFreezing.js @@ -0,0 +1,223 @@ +import { + Autocomplete, + Button, + FormControl, + InputLabel, + MenuItem, + Select, + TextField, +} from "@mui/material"; +import React, { useContext, useEffect, useState } from "react"; +import { Grid } from "../../../../components/grid/Grid"; +import { useDispatch } from "react-redux"; +import { slaughterGetColdHouses } from "../../services/slaughter-get-cold-houses"; +import { slaughterSubmitAllocateToFreezing } from "../../services/slaughter-submit-allocate-to-freezing"; +import { AppContext } from "../../../../contexts/AppContext"; +import { + CLOSE_MODAL, + LOADING_END, +} from "../../../../lib/redux/slices/appSlice"; +import { Yup } from "../../../../lib/yup/yup"; +import { useFormik } from "formik"; +import { slaughterUpdateAllocationForFreezing } from "../../services/slaughter-update-allocation-for-freezing"; +import { slaughterGetProductsService } from "../../services/slaughter-inventory-gets"; + +export const SlaughterAllocateToFreezing = ({ + fetchItems, + isEdit, + item, + updateTable, + handleUpdateFreezing, +}) => { + const [coldHouse, setColdHouse] = useState(""); + const [coldHouses, setColdHouses] = useState([]); + const [openNotif] = useContext(AppContext); + const [productKey, setProductKey] = useState(null); + const [productData, setProductData] = useState([]); + + const dispatch = useDispatch(); + + useEffect(() => { + if (!isEdit) { + dispatch(slaughterGetProductsService()).then((r) => { + setProductData(r.payload.data); + }); + dispatch(slaughterGetColdHouses()).then((r) => { + setColdHouses(r.payload.data); + }); + } + }, []); + + const handleChange = (event) => { + setColdHouse(event.target.value); + }; + + const formik = useFormik({ + initialValues: { + quantity: item?.quantity ? item?.quantity : "", + weight: item?.weight ? item?.weight : "", + }, + validationSchema: Yup.object({ + quantity: Yup.number() + .required("این فیلد اجباری است!") + .typeError("لطفا عدد وارد کنید!"), + weight: Yup.number() + .required("این فیلد اجباری است!") + .typeError("لطفا عدد وارد کنید!"), + }), + }); + + useEffect(() => { + formik.validateForm(); + }, []); + + return ( + + {!isEdit && ( + + { + return { + data: i, + label: `${i.name}`, + }; + }) + : [] + } + onChange={(event, value) => { + setProductKey(value.data); + }} + renderInput={(params) => ( + + )} + /> + + )} + {!isEdit && ( + <> + + + انتخاب سردخانه + + + + + )} + + + + + + ); +}; diff --git a/src/features/slaughter-house/components/slaughter-allocate-to-guild/SlaughterAllocateToGuild.js b/src/features/slaughter-house/components/slaughter-allocate-to-guild/SlaughterAllocateToGuild.js new file mode 100644 index 0000000..9e99f92 --- /dev/null +++ b/src/features/slaughter-house/components/slaughter-allocate-to-guild/SlaughterAllocateToGuild.js @@ -0,0 +1,1063 @@ +import React, { useContext, useEffect, useState, useCallback } from "react"; +import { Grid } from "../../../../components/grid/Grid"; +import { + Autocomplete, + Button, + Checkbox, + FormControl, + FormControlLabel, + InputAdornment, + Radio, + RadioGroup, + TextField, + Typography, +} from "@mui/material"; +import { useDispatch, useSelector } from "react-redux"; +import { slaughterGetProductsService } from "../../services/slaughter-inventory-gets"; +import { NumberInput } from "../../../../components/number-format-custom/NumberFormatCustom"; +import { useFormik } from "formik"; +import { Yup } from "../../../../lib/yup/yup"; +import { + slaughterAllocateStewardService, + slaughterEditAllocateStewardService, +} from "../../services/slaughter-allocate-steward"; +import { AppContext } from "../../../../contexts/AppContext"; +import { CLOSE_MODAL, DRAWER } from "../../../../lib/redux/slices/appSlice"; +import { + slaughterGetGuildsForAllocateService, + slaughterGetStewardsForAllocateService, +} from "../../services/slaughter-get-guilds-for-allocate"; +import { DatePicker } from "@mui/x-date-pickers"; +import moment from "moment"; +import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl"; +import { ImageUpload } from "../../../../components/image-upload/ImageUpload"; +import { fixBase64 } from "../../../../utils/toBase64"; +import { provincePolicyGetUploadImageService } from "../../../province/services/province-policy-upload-image"; +import { fetchSlaughterBroadcastAndProducts } from "../../services/handle-fetch-slaughter-products"; +import MonthlyDataCalendar from "../../../../components/date-picker/MonthlyDataCalendar"; +import PersianDate from "persian-date"; +import axios from "axios"; +import { LabelField } from "../../../../components/label-field/LabelField"; +import { SPACING } from "../../../../data/spacing"; +import { checkPathStartsWith } from "../../../../utils/checkPathStartsWith"; + +export const SlaughterAllocateToGuild = ({ + item, + key, + sellerType, + buyerType, + allocationType, + sellType, + updateTable, + fetchApiData, + editData, + priceInfo, + coldHouseKey, + coldHouseItemKey, + killHouseAllocation, + disableFreeOptions = false, +}) => { + const dispatch = useDispatch(); + const [productData, setProductData] = useState([]); + const [guildsData, setGuildsData] = useState([]); + const [stewardsData, setStewardsData] = useState([]); + const [selectedInventory, setSelectedInventory] = useState("governmental"); + const [approvedStatus, setApprovedStatus] = useState("true"); + const [productKey, setProductKey] = useState(null); + const [openNotif] = useContext(AppContext); + const [profileImages, setProfileImages] = useState( + editData?.image ? [{ data_url: editData.image }] : [] + ); + + const [buyerCategory, setBuyerCategory] = useState(""); // "stewards" or "guilds" + const [value, setValue] = useState(""); + const [imageUploadLimit, setImageUploadLimit] = useState(1); + const [imageChanged, setImageChanged] = useState(false); + const [changeMobile, setChangeMobile] = useState(false); + const [selectedCalendarDate, setSelectedCalendarDate] = useState(null); + const [calendarDayData, setCalendarDayData] = useState({}); + const [productionDate, setProductionDate] = useState(null); + const [selectedDateAmount, setSelectedDateAmount] = useState(null); + const [calendarRawData, setCalendarRawData] = useState({ + governmental: [], + free: [], + }); + const selectedSubUser = useSelector( + (state) => state.userSlice.selectedSubUser + ); + const [selectedDate1, setSelectedDate1] = useState( + moment(new Date()).format("YYYY-MM-DD") + ); + const [dateRangeError, setDateRangeError] = useState(null); + + const handleBuyerCategoryChange = (event) => { + const newCategory = event.target.value; + setBuyerCategory(newCategory); + setBuyerData({ + key: "", + item: "", + buyerType: "", + allocationType: "", + }); + setGuildsData([]); + setStewardsData([]); + }; + + const handleChange = (event) => { + setValue(event.target.value); + setBuyerData({ + key: "", + item: "", + buyerType: "", + allocationType: "", + }); + setGuildsData([]); + setStewardsData([]); + }; + + const handleSellType = (event) => { + const newType = event.target.value; + setSelectedInventory(newType); + }; + + const handleApprovedPrice = (event) => { + const newType = event.target.value; + setApprovedStatus(newType); + if (newType === "false") { + formik.setFieldValue("price", ""); + } + }; + + const handleDateSelect = (dateInfo) => { + if (dateInfo && dateInfo.formattedDate) { + setSelectedCalendarDate(dateInfo.formattedDate); + + const data = calendarDayData[dateInfo.formattedDate]; + + if (data && data.originalDay) { + setProductionDate(data.originalDay); + } + + if (data && (data.amount !== undefined || data.value1 !== undefined)) { + const rawAmount = data.amount !== undefined ? data.amount : data.value1; + const normalizedAmount = + typeof rawAmount === "string" + ? Number(rawAmount.replace(/,/g, "")) + : Number(rawAmount); + setSelectedDateAmount( + Number.isFinite(normalizedAmount) ? normalizedAmount : null + ); + } else { + setSelectedDateAmount(null); + } + } + }; + + const transformCalendarData = useCallback((dataArray) => { + if (!Array.isArray(dataArray)) return {}; + + const transformedData = {}; + dataArray.forEach((item) => { + if (item.day && item.amount !== undefined) { + const persianDate = new PersianDate(new Date(item.day)); + const persianDateStr = persianDate.format("YYYY/MM/DD"); + const rawAmount = item.amount; + const normalizedAmount = + typeof rawAmount === "string" + ? Number(rawAmount.replace(/,/g, "")) + : Number(rawAmount); + transformedData[persianDateStr] = { + value1: normalizedAmount, + originalDay: item.day, + active: item.active === true, // Store active status + }; + } + }); + return transformedData; + }, []); + + const updateCalendarData = useCallback( + (dataArray) => { + const transformed = transformCalendarData(dataArray); + setCalendarDayData(transformed); + }, + [transformCalendarData] + ); + + const fetchCalendarData = useCallback(async () => { + try { + const response = await axios.get("/kill-house-remain-weight/", { + params: { + date: selectedDate1, + role: getRoleFromUrl(), + role_key: + checkPathStartsWith("slaughter") || checkPathStartsWith("steward") + ? selectedSubUser?.key || "" + : "", + }, + }); + if (response.data) { + setCalendarRawData({ + governmental: response.data.governmental || [], + free: response.data.free || [], + }); + const dataToShow = + selectedInventory === "governmental" + ? response.data.governmental + : response.data.free; + updateCalendarData(dataToShow); + } + } catch (error) { + console.error("Error fetching calendar data:", error); + } + }, [selectedInventory, updateCalendarData, selectedDate1, selectedSubUser]); + + const [buyerData, setBuyerData] = useState({ + key, + item, + buyerType, + allocationType, + }); + + useEffect(() => { + if (getRoleFromUrl() === "Steward") { + setValue("free"); + } + fetchCalendarData(); + }, [selectedSubUser?.key]); + + useEffect(() => { + if ( + calendarRawData.governmental.length > 0 || + calendarRawData.free.length > 0 + ) { + const dataToShow = + selectedInventory === "governmental" + ? calendarRawData.governmental + : calendarRawData.free; + updateCalendarData(dataToShow); + setSelectedCalendarDate(null); + setProductionDate(null); + setSelectedDateAmount(null); + } + }, [selectedInventory, calendarRawData]); + + useEffect(() => { + dispatch( + provincePolicyGetUploadImageService({ + role_key: + checkPathStartsWith("slaughter") || checkPathStartsWith("steward") + ? selectedSubUser?.key || "" + : "", + }) + ).then((r) => { + if (r.payload?.data) { + setImageUploadLimit(r.payload.data.killHouseAllocation); + } + }); + + if (!editData) { + dispatch( + slaughterGetProductsService({ + role_key: + checkPathStartsWith("slaughter") || checkPathStartsWith("steward") + ? selectedSubUser?.key || "" + : "", + }) + ).then((r) => { + setProductData(r.payload.data); + }); + if (!item && buyerCategory && value) { + if (buyerCategory === "guilds") { + dispatch( + slaughterGetGuildsForAllocateService({ + free: value === "free" ? true : false, + role_key: + checkPathStartsWith("slaughter") || + checkPathStartsWith("steward") + ? selectedSubUser?.key || "" + : "", + }) + ).then((r) => { + setGuildsData(r.payload.data); + }); + } else if (buyerCategory === "stewards") { + dispatch( + slaughterGetStewardsForAllocateService({ + free: value === "free" ? true : false, + role_key: + checkPathStartsWith("slaughter") || + checkPathStartsWith("steward") + ? selectedSubUser?.key || "" + : "", + }) + ).then((r) => { + setStewardsData(r.payload.data); + }); + } + } + } + }, [buyerCategory, value, selectedSubUser?.key]); + + const validationSchema = Yup.object({ + mobile: Yup.string().when([], { + is: () => !editData, + then: (schema) => + schema + .required("شماره موبایل الزامی است") + .min(11, "شماره موبایل باید 11 رقم باشد") + .max(11, "شماره موبایل باید 11 رقم باشد") + .matches( + /^09\d{9}$/, + "شماره موبایل باید با 09 شروع شود و 11 رقم باشد" + ), + otherwise: (schema) => schema.notRequired(), + }), + weight: Yup.number() + .required("این فیلد اجباری است!") + .integer("عدد باید صحیح باشد!") + .min(1, "یک مقدار مثبت وارد کنید!") + .test( + "max-production-date-amount", + `وزن نمی‌تواند بیشتر از موجودی تاریخ تولید (${ + selectedDateAmount?.toLocaleString() || 0 + } کیلوگرم) باشد!`, + function (value) { + if (!selectedDateAmount || selectedDateAmount === null) return true; + return value <= selectedDateAmount; + } + ), + price: Yup.number() + .required("این فیلد اجباری است!") + .min(1, "یک مقدار مثبت وارد کنید!"), + wholePrice: Yup.number() + .required("این فیلد اجباری است!") + .min(1, "یک مقدار مثبت وارد کنید!"), + date: Yup.date().test( + "date-not-before-production", + "تاریخ نمی‌تواند قبل از تاریخ تولید باشد", + function (value) { + if (!productionDate || !value) return true; + return moment(value).isSameOrAfter(moment(productionDate), "day"); + } + ), + ...(killHouseAllocation && { + image: Yup.string().when([], { + is: () => (!editData || imageChanged) && imageUploadLimit > 0, + then: Yup.string().required("عکس الزامی است"), + otherwise: Yup.string().notRequired(), + }), + }), + }); + + const factorPaymentHandler = (imageList) => { + if (imageList[0]) { + formik.setFieldValue("image", fixBase64(imageList[0]?.data_url)); + setImageChanged(true); + } else { + formik.setFieldValue("image", ""); + setImageChanged(true); + } + setProfileImages(imageList); + }; + + const formik = useFormik({ + initialValues: { + mobile: "", + weight: editData?.realWeightOfCarcasses || "", + wholePrice: editData?.totalAmount || "", + price: editData?.amount || "", + image: editData?.image || "", + date: selectedDate1, + }, + validationSchema, + }); + + useEffect(() => { + formik.validateForm(); + }, [selectedDateAmount, productionDate]); + + useEffect(() => { + formik.setFieldValue("date", selectedDate1); + }, [selectedDate1]); + + useEffect(() => { + if (priceInfo?.active === false) { + setApprovedStatus("false"); + } + }, [priceInfo?.active]); + + useEffect(() => { + if (approvedStatus === "true" && priceInfo?.active) { + formik.setFieldValue("price", priceInfo?.killHousePrice); + } + }, [approvedStatus]); + + useEffect(() => { + if (approvedStatus === "true" && priceInfo?.active) { + if (formik.values.weight) { + formik.setFieldValue( + "wholePrice", + priceInfo?.killHousePrice * formik.values.weight + ); + } + } else { + if (formik.values.weight && formik.values.price) { + formik.setFieldValue( + "wholePrice", + formik.values.price * formik.values.weight + ); + } + } + }, [formik.values.price, formik.values.weight, approvedStatus]); + + const successSubmit = () => { + dispatch(CLOSE_MODAL()); + openNotif({ + vertical: "top", + horizontal: "center", + msg: "عملیات با موفقیت انجام شد.", + severity: "success", + }); + dispatch( + fetchSlaughterBroadcastAndProducts({ + role_key: + checkPathStartsWith("slaughter") || checkPathStartsWith("steward") + ? selectedSubUser?.key || "" + : "", + }) + ); + dispatch( + DRAWER({ + right: false, + bottom: false, + left: false, + content: null, + }) + ); + updateTable && updateTable(); + fetchApiData && fetchApiData(); + }; + + return ( + + {!editData && ( + ( + + )} + shouldDisableDate={(date) => { + const d = moment(date); + const today = moment(); + return !d.isSame(today, "day"); + }} + value={selectedDate1} + onChange={(e) => { + if (!e) { + setDateRangeError(null); + return; + } + const d = moment(e); + const today = moment(); + const yesterday = moment().subtract(1, "day"); + const isAllowed = + d.isSame(today, "day") || d.isSame(yesterday, "day"); + if (!isAllowed) { + setDateRangeError( + "تنها امکان انتخاب «امروز» یا «دیروز» وجود دارد." + ); + return; + } + setDateRangeError(null); + setSelectedDate1(moment(e).format("YYYY-MM-DD")); + }} + /> + )} + + {!editData && !coldHouseKey && ( + + { + return { + data: i, + label: `${i.name}`, + }; + }) + : [] + } + onChange={(event, value) => { + setProductKey(value.data); + }} + renderInput={(params) => ( + + )} + /> + + )} + + {!editData && ( + + + + } + label="مباشرین" + /> + } + label="اصناف" + /> + + + + )} + + {!editData && buyerCategory && ( + + + + } + label="اختصاصی" + /> + } + label="آزاد" + disabled={disableFreeOptions} + /> + + + + )} + + {!item && !editData && buyerCategory && value && ( + + {(() => { + const currentData = + buyerCategory === "guilds" ? guildsData : stewardsData; + const isEmpty = !currentData || currentData.length === 0; + + if (isEmpty) { + return ( + + {buyerCategory === "guilds" + ? "هیچ صنفی یافت نشد" + : "هیچ مباشری یافت نشد"} + + ); + } + + return ( + { + return { + data: i, + label: `${i?.steward ? "مباشر" : "صنف"} ${ + i?.guildsName + } ${i?.user?.fullname} (${i?.user?.mobile})`, + }; + }) + : stewardsData.map((i) => { + return { + data: i, + label: `${i?.name || ""} - ${ + i?.user?.fullname || "" + } (${i?.user?.mobile || ""})`, + }; + }) + } + onChange={(event, value) => { + if (buyerCategory === "guilds") { + setBuyerData({ + item: value?.data, + key: value?.data?.key, + allocationType: value?.data?.steward + ? "killhouse_steward" + : "killhouse_guild", + buyerType: value?.data?.steward ? "Steward" : "Guild", + }); + formik.setFieldValue("mobile", value?.data?.user?.mobile); + } else if (buyerCategory === "stewards") { + setBuyerData({ + item: value?.data, + key: value?.data?.key, + allocationType: "killhouse_steward", + buyerType: "Steward", + }); + formik.setFieldValue("mobile", value?.data?.user?.mobile); + } + formik.setFieldTouched("mobile", true, false); + formik.validateField("mobile"); + const reg = new RegExp(/^09\d{9}$/); + if ( + value?.data?.user?.mobile && + !reg.test(value?.data?.user?.mobile) + ) { + setChangeMobile(true); + } + }} + renderInput={(params) => ( + + )} + /> + ); + })()} + + )} + {!item && !editData && buyerData?.key && ( + + + setChangeMobile(!changeMobile)} + /> + {buyerCategory === "stewards" + ? "از این قسمت میتوانید تلفن مباشر را ویرایش کنید." + : buyerCategory === "guilds" + ? "از این قسمت میتوانید تلفن صنف را ویرایش کنید." + : "از این قسمت میتوانید تلفن مباشر/صنف را ویرایش کنید."} + + + {changeMobile && ( + + )} + + )} + + {!item && !editData && priceInfo?.active !== false && ( + + + + } + label="قیمت دولتی" + /> + } + label="قیمت آزاد" + disabled={disableFreeOptions} + /> + + + + )} + + {!item && !editData && ( + + + + } + label="دولتی" + /> + } + label="آزاد" + disabled={disableFreeOptions} + /> + + + + )} + + + {productionDate && + selectedDate1 && + moment(productionDate).isAfter(moment(selectedDate1), "day") && ( + + تاریخ تولید نمی‌تواند بعد از تاریخ انتخابی باشد + + )} + + + selectedDateAmount + } + onChange={(e) => { + const value = e.target.value; + if (value === "" || value === null || value === undefined) { + formik.setFieldValue("weight", ""); + return; + } + const intValue = Math.floor(Number(value)); + if (intValue > 0) { + formik.setFieldValue("weight", intValue); + } else if (intValue === 0) { + formik.setFieldValue("weight", ""); + } + }} + onBlur={formik.handleBlur} + helperText={ + !selectedDateAmount && !productionDate + ? "لطفاً ابتدا تاریخ تولید را انتخاب کنید!" + : formik.touched.weight && Boolean(formik.errors.weight) + ? formik.errors.weight + : null + } + disabled={!selectedDateAmount && !productionDate} + sx={{ + "& .MuiFormHelperText-root": { + color: + selectedDateAmount && formik.values.weight > selectedDateAmount + ? "error.main" + : undefined, + }, + }} + /> + + ریال, + }} + value={formik.values.price} + error={formik.touched.price ? Boolean(formik.errors.price) : null} + onChange={formik.handleChange} + onBlur={formik.handleBlur} + helperText={ + formik.touched.price && Boolean(formik.errors.price) + ? formik.errors.price + : null + } + disabled={approvedStatus === "true" && priceInfo?.active} + /> + + ریال, + }} + value={formik.values.wholePrice} + error={ + formik.touched.wholePrice ? Boolean(formik.errors.wholePrice) : null + } + onChange={formik.handleChange} + onBlur={formik.handleBlur} + helperText={ + formik.touched.wholePrice && Boolean(formik.errors.wholePrice) + ? formik.errors.wholePrice + : null + } + /> + {(killHouseAllocation || (editData && editData.image)) && ( + + + {formik.touched.image && Boolean(formik.errors.image) && ( + ثبت تصویر الزامی است + )} + + )} + + + + + + + + + + + ); +}; diff --git a/src/features/slaughter-house/components/slaughter-allocated-check-requests/SlaughterAllocatedCheckRequests.js b/src/features/slaughter-house/components/slaughter-allocated-check-requests/SlaughterAllocatedCheckRequests.js new file mode 100644 index 0000000..f9f5133 --- /dev/null +++ b/src/features/slaughter-house/components/slaughter-allocated-check-requests/SlaughterAllocatedCheckRequests.js @@ -0,0 +1,181 @@ +import { Grid, IconButton, TextField } from "@mui/material"; +import { ROUTE_SLAUGHTER_FILE } from "../../../../routes/routes"; +import { SPACING } from "../../../../data/spacing"; +import { useFormik } from "formik"; +import moment from "moment"; +import { Yup } from "../../../../lib/yup/yup"; +import { useDispatch, useSelector } from "react-redux"; +import { slaughterGetActiveRequests } from "../../services/slaughter-get-active-requests"; +import { useContext, useEffect, useState } from "react"; +import { useNavigate } from "react-router-dom"; +import PlagiarismIcon from "@mui/icons-material/Plagiarism"; +import EditIcon from "@mui/icons-material/Edit"; +import { DRAWER } from "../../../../lib/redux/slices/appSlice"; +import SlaughterCheckRequest from "../../../file/components/slaughter-check-request/SlaughterCheckRequest"; +import { format } from "date-fns-jalali"; +import { DatePicker } from "@mui/x-date-pickers"; +import { AppContext } from "../../../../contexts/AppContext"; +import ResponsiveTable from "../../../../components/responsive-table/ResponsiveTable"; +import { checkPathStartsWith } from "../../../../utils/checkPathStartsWith"; + +export const SlaughterAllocatedCheckRequests = () => { + const navigate = useNavigate(); + const [dataTable, setDataTable] = useState([]); + const { slaughterActiveRequests } = useSelector( + (state) => state.slaughterSlice + ); + const dispatch = useDispatch(); + const [, , selectedDate1, setSelectedDate1, selectedDate2, setSelectedDate2] = + useContext(AppContext); + const selectedSubUser = useSelector( + (state) => state.userSlice.selectedSubUser + ); + + useEffect(() => { + const currentDate = moment(new Date()).format("YYYY-MM-DD"); + setSelectedDate1(currentDate); + setSelectedDate2(currentDate); + }, []); + + useEffect(() => { + dispatch( + slaughterGetActiveRequests({ + selectedDate1, + selectedDate2, + role_key: checkPathStartsWith("slaughter") + ? selectedSubUser?.key || "" + : "", + }) + ); + }, [selectedDate1, selectedDate2, selectedSubUser?.key]); + + useEffect(() => { + const filteredData = slaughterActiveRequests?.filter( + (item) => item.provinceKillState === "pending" + ); + // const key = "orderCode"; + // const arrayUniqueByKey = [ + // ...new Map(filteredData?.map((item) => [item[key], item])).values(), + // ]; + const d = filteredData?.map((item, i) => { + return [ + i + 1, + item.orderCode, + item?.freezing ? "انجماد" : item?.export ? "صادرات" : "عادی", + item?.freeSaleInProvince === false ? "دولتی" : "آزاد", + format(new Date(item?.sendDate), "yyyy/MM/dd"), + `${item.poultryName} (${item.poultryMobile})`, + `${item.killHouseName} (${item.killHouseMobile})`, + item.city, + item.province, + item.age, + item.mainQuantity.toLocaleString() + " قطعه", + item.amount.toLocaleString() + " ﷼", + item.chickenBreed, + item.indexWeight + " کیلوگرم", + { + dispatch( + DRAWER({ + title: "انجام عملیات تخصیص", + // right: !(window.innerWidth <= 600), + top: !(window.innerWidth <= 600), + bottom: window.innerWidth <= 600, + content: , + }) + ); + }} + > + + , + navigate(ROUTE_SLAUGHTER_FILE + item.poultryReqId)} + > + + , + ]; + }); + + setDataTable(d); + }, [slaughterActiveRequests]); + + const [tableDataCol] = useState([ + "ردیف", + "کد سفارش", + "کشتار", + "فروش", + "تاریخ درخواست", + "مرغدار", + "خریدار", + "شهر", + "استان", + "سن مرغ", + "تعداد", + "قیمت مرغ زنده", + "نژاد", + "میانگین وزن", + "عملیات", + "مشاهده", + ]); + + const formik = useFormik({ + initialValues: { + capacity: "", + recieveTime: "", + recieveDate: moment(Date()).format("YYYY-MM-DD hh:mm:ss"), + }, + validationSchema: Yup.object({ + capacity: Yup.number() + .required("این فیلد اجباری است!") + .typeError("لطفا عدد وارد کنید!"), + recieveTime: Yup.string() + .required("این فیلد اجباری است!") + .typeError("لطفا وزن را وارد کنید!"), + }), + }); + + useEffect(() => { + formik.validateForm(); + }, []); + + return ( + + + ( + + )} + value={selectedDate1} + onChange={(e) => { + setSelectedDate1(moment(e).format("YYYY-MM-DD")); + }} + /> + ( + + )} + value={selectedDate2} + onChange={(e) => { + setSelectedDate2(moment(e).format("YYYY-MM-DD")); + }} + /> + + + + + ); +}; diff --git a/src/features/slaughter-house/components/slaughter-archived-fees/SlaughterArchivedFees.js b/src/features/slaughter-house/components/slaughter-archived-fees/SlaughterArchivedFees.js new file mode 100644 index 0000000..cb5027b --- /dev/null +++ b/src/features/slaughter-house/components/slaughter-archived-fees/SlaughterArchivedFees.js @@ -0,0 +1,540 @@ +import { + Button, + Checkbox, + FormControlLabel, + Pagination, + TextField, + Tooltip, + tooltipClasses, + Typography, +} from "@mui/material"; +import axios from "axios"; +import { useContext, useEffect, useState } from "react"; +import { useDispatch, useSelector } from "react-redux"; +import { Grid } from "../../../../components/grid/Grid"; +import { PageTable } from "../../../../components/page-table/PageTable"; +import { SPACING } from "../../../../data/spacing"; +import { + DRAWER, + LOADING_END, + LOADING_START, + OPEN_MODAL, +} from "../../../../lib/redux/slices/appSlice"; +import { formatJustDate } from "../../../../utils/formatTime"; +import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl"; +import KeyboardDoubleArrowUpIcon from "@mui/icons-material/KeyboardDoubleArrowUp"; +import KeyboardDoubleArrowDownIcon from "@mui/icons-material/KeyboardDoubleArrowDown"; +import styled from "styled-components"; +import { getFaUserRole } from "../../../../utils/getFaUserRole"; +import { SlaughterUnpaidFeesDetails } from "../slaughter-unpaid-fees-details/SlaughterUnpaidFeesDetails"; +import { ProvinceArchiveFeeDetails } from "../../../province/components/province-archive-fee-details/ProvinceArchiveFeeDetails"; +import { RiFileExcel2Fill, RiSearchLine } from "react-icons/ri"; +import BoxList from "../../../../components/box-list/BoxList"; +import moment from "moment"; +import { AppContext } from "../../../../contexts/AppContext"; +import { DatePicker } from "@mui/x-date-pickers"; + +export const SlaughterArchivedFees = () => { + const [, , selectedDate1, setSelectedDate1, selectedDate2, setSelectedDate2] = + useContext(AppContext); + const [withDate, setWithDate] = useState(false); + + useEffect(() => { + const currentDate = moment(new Date()).format("YYYY-MM-DD"); + setSelectedDate1(currentDate); + setSelectedDate2(currentDate); + }, []); + + const dispatch = useDispatch(); + const [data, setData] = useState([]); + const [loading, setLoading] = useState(false); + const [totalRows, setTotalRows] = useState(0); + const [perPage, setPerPage] = useState(10); + const userInfo = useSelector((state) => state.userSlice); + const [dataTableM, setDataTableM] = useState([]); + + const [textValue, setTextValue] = useState(""); + + const handleTextChange = (event) => { + setTextValue(event.target.value); + }; + + const fetchApiData = async (page, textValue) => { + setLoading(true); + const response = await axios.get( + `province_wage/?search=filter&value=${textValue}&page=${page}&page_size=${perPage}&type=archive&role=${getRoleFromUrl()}${ + withDate ? `&date1=${selectedDate1}&date2=${selectedDate2}` : `` + }` + ); + setData(response.data.results); + setTotalRows(response.data.count); + setLoading(false); + dispatch(LOADING_END()); + }; + + const [page, setPage] = useState(0); + const handleChangePageM = (event, newPage) => { + dispatch(LOADING_START()); + setPage(newPage); + fetchApiData(newPage + 1, textValue); + }; + + const handlePageChange = (page) => { + fetchApiData(page, textValue); + }; + + const handlePerRowsChange = async (newPerPage, page) => { + setLoading(true); + const response = await axios.get( + `province_wage/?search=filter&value=${textValue}&page=${page}&page_size=${newPerPage}&type=archive&role=${getRoleFromUrl()}${ + withDate ? `&date1=${selectedDate1}&date2=${selectedDate2}` : `` + }` + ); + + setData(response.data.results); + setTotalRows(response.data.count); + setPerPage(newPerPage); + + setLoading(false); + }; + + useEffect(() => { + fetchApiData(1); + }, []); + + useEffect(() => { + fetchApiData(1); + }, [selectedDate1, selectedDate2, withDate]); + + const handleSubmit = async (event) => { + event.preventDefault(); + setLoading(true); + + try { + const response = await axios.get( + `province_wage/?search=filter&value=${textValue}&type=archive&role=${getRoleFromUrl()}${ + withDate ? `&date1=${selectedDate1}&date2=${selectedDate2}` : `` + }` + ); + setData(response.data.results); + setTotalRows(response.data.count); + } catch (error) { + console.error("Error fetching data:", error); + } finally { + setLoading(false); + } + }; + + const updateTable = () => { + fetchApiData(1); + }; + + const columns = [ + { + name: "کدسفارش", + selector: (item) => item?.provinceRequest?.orderCode, + sortable: true, + wrap: true, + allowOverflow: true, + center: true, + // width: "90px", + }, + { + name: "مرغدار (تلفن)", + selector: (item) => + `${item?.provinceRequest?.poultryFullname} (${item?.provinceRequest?.poultryMobile})`, + sortable: true, + wrap: true, + allowOverflow: true, + center: true, + // width: "90px", + }, + { + name: "شهر", + selector: (item) => `${item?.provinceRequest?.poultryCity}`, + sortable: true, + wrap: true, + allowOverflow: true, + center: true, + // width: "80px", + }, + { + name: "تاریخ کشتار", + selector: (item) => formatJustDate(item?.provinceRequest?.sendDate), + sortable: true, + wrap: true, + allowOverflow: true, + center: true, + // width: "80px", + }, + { + name: "محل کشتار", + selector: (item) => item?.provinceRequest?.killPlace, + sortable: true, + wrap: true, + allowOverflow: true, + center: true, + }, + { + name: "نژاد", + selector: (item) => item?.provinceRequest?.breed, + sortable: true, + wrap: true, + allowOverflow: true, + center: true, + // width: "80px", + }, + { + name: "تعداد (قطعه)", + selector: (item) => + item?.provinceRequest?.provinceKillRequestQuantity?.toLocaleString(), + sortable: true, + wrap: true, + allowOverflow: true, + center: true, + // width: "80px", + }, + { + name: "وزن (کیلوگرم)", + selector: (item) => + item?.provinceRequest?.provinceKillRequestTotalWeight?.toLocaleString(), + sortable: true, + wrap: true, + allowOverflow: true, + center: true, + // width: "90px", + }, + { + name: "میانگین وزنی (کیلوگرم)", + selector: (item) => item?.provinceRequest?.indexWeight, + sortable: true, + wrap: true, + allowOverflow: true, + center: true, + // width: "90px", + }, + { + name: "تعرفه اتحادیه (ریال)", + selector: (item) => item?.provinceRequest?.wage?.toLocaleString(), + sortable: true, + wrap: true, + allowOverflow: true, + center: true, + // width: "90px", + }, + { + name: "مبلغ کل تعرفه (ریال)", + selector: (item) => ( + + ), + sortable: true, + wrap: true, + allowOverflow: true, + center: true, + // width: "90px", + }, + { + name: "جزییات سفارش", + selector: (item) => ( + + ), + sortable: true, + wrap: true, + allowOverflow: true, + center: true, + // width: "90px", + }, + { + name: "اطلاعات بایگانی", + selector: (item) => ( + + ), + sortable: true, + wrap: true, + allowOverflow: true, + center: true, + // width: "90px", + }, + ]; + + const tableTitle = ( + + + بایگانی + + + setWithDate(!withDate)} + color="primary" // Change the color to your preference + /> + } + /> + + + ( + + )} + value={selectedDate1} + onChange={(e) => { + setSelectedDate1(moment(e).format("YYYY-MM-DD")); + }} + /> + + + ( + + )} + value={selectedDate2} + onChange={(e) => { + setSelectedDate2(moment(e).format("YYYY-MM-DD")); + }} + /> + + +
    + + + + + + + + +
    +
    + ); + + const isMobile = window.innerWidth <= 600; + + useEffect(() => { + const d = data?.map((item, i) => { + return [ + item?.provinceRequest?.orderCode, + `${item?.provinceRequest?.poultryFullname} (${item?.provinceRequest?.poultryMobile})`, + `${item?.provinceRequest?.poultryCity}`, + , + , + , + ]; + }); + + setDataTableM(d); + }, [data]); + + return ( + + {isMobile ? ( + + {tableTitle} + + { + handleChangePageM(event, newPage - 1); + }} + /> + + ) : ( + + )} + + ); +}; + +const ProvinceUnpaidFeeView = ({ item, updateTable }) => { + const isBigger = + item?.provinceRequest.prevTotalAmount < item?.provinceRequest.totalAmount; + const isSmaller = + item?.provinceRequest.prevTotalAmount > item?.provinceRequest.totalAmount; + + const prevTotalAmount = ( + + {isBigger && "افزایش یافته"} + {isSmaller && "کاهش یافته"} + + مبلغ اولیه: {item?.provinceRequest?.prevTotalAmount?.toLocaleString()} ﷼ + + ویرایش کننده: {item?.totalAmountEditor?.fullname} + تاریخ ویرایش: {formatJustDate(item?.totalAmountEditor?.date)} + سمت: {getFaUserRole(item?.totalAmountEditor?.role)} + تلفن: {item?.totalAmountEditor?.mobile} + + ); + return ( + + {Boolean(item?.provinceRequest?.prevTotalAmount) && isBigger && ( + + + + + {item?.provinceRequest?.totalAmount?.toLocaleString()} + + + + )} + + {Boolean(item?.provinceRequest?.prevTotalAmount) && isSmaller && ( + + + + + {item?.provinceRequest?.totalAmount?.toLocaleString()} + + + + )} + + {!item?.provinceRequest?.prevTotalAmount && ( + + {item?.provinceRequest?.totalAmount?.toLocaleString()} + + )} + + ); +}; + +const HtmlTooltip = styled(({ className, ...props }) => ( + +))(({ theme }) => ({ + [`& .${tooltipClasses.tooltip}`]: { + backgroundColor: "#f5f5f9", + color: "rgba(0, 0, 0, 0.87)", + maxWidth: 220, + border: "1px solid #dadde9", + }, +})); diff --git a/src/features/slaughter-house/components/slaughter-archived-requests/SlaughterArchivedRequests.js b/src/features/slaughter-house/components/slaughter-archived-requests/SlaughterArchivedRequests.js new file mode 100644 index 0000000..fce0bee --- /dev/null +++ b/src/features/slaughter-house/components/slaughter-archived-requests/SlaughterArchivedRequests.js @@ -0,0 +1,133 @@ +import { Card, IconButton, TextField, Typography } from "@mui/material"; +import { useContext, useEffect, useState } from "react"; +import { AdvancedTable } from "../../../../components/advanced-table/AdvancedTable"; +import PlagiarismIcon from "@mui/icons-material/Plagiarism"; +import { useNavigate } from "react-router-dom"; +import { ROUTE_SLAUGHTER_FILE } from "../../../../routes/routes"; +import { formatJustDate } from "../../../../utils/formatTime"; +import { DatePicker } from "@mui/x-date-pickers"; +import { Grid } from "../../../../components/grid/Grid"; +import { SPACING } from "../../../../data/spacing"; +import moment from "moment/moment"; +import { AppContext } from "../../../../contexts/AppContext"; +import { useDispatch, useSelector } from "react-redux"; +import { + LOADING_END, + LOADING_START, +} from "../../../../lib/redux/slices/appSlice"; +import { avicultureGetRequests } from "../../../aviculture/services/aviculture-requests"; + +export const SlaughterArchivedRequests = () => { + const navigate = useNavigate(); + const dispatch = useDispatch(); + const [dataTable, setDataTable] = useState([]); + const { avicultureRequests } = useSelector((state) => state.avicultureSlice); + + const [, , selectedDate1, setSelectedDate1, selectedDate2, setSelectedDate2] = + useContext(AppContext); + + useEffect(() => { + const currentDate = moment(new Date()).format("YYYY-MM-DD"); + setSelectedDate1(currentDate); + setSelectedDate2(currentDate); + }, []); + + useEffect(() => { + dispatch(LOADING_START()); + dispatch(avicultureGetRequests({ selectedDate1, selectedDate2 })).then( + () => { + dispatch(LOADING_END()); + } + ); + }, [selectedDate1, selectedDate2]); + + useEffect(() => { + const filteredData = avicultureRequests?.filter( + (item, i) => item.inspector != null + ); + const d = filteredData?.map((item, i) => { + return [ + i + 1, + item.orderCode, + formatJustDate(item?.createDate), + formatJustDate(item?.sendDate), + item?.process?.poultry?.poultryName, + item?.process?.poultry?.poultryMobile, + item?.process?.poultry?.poultryCity, + item?.process?.poultry?.poultryProvince, + item?.process?.poultry?.age, + item?.process?.poultry?.poultryQuantity, + + navigate( + ROUTE_SLAUGHTER_FILE + item?.process?.poultry?.poultryRequestId + ) + } + > + + , + ]; + }); + + setDataTable(d); + }, [avicultureRequests]); + + const [tableDataCol] = useState([ + "ردیف", + "کد سفارش", + "تاریخ ثبت درخواست", + "تاریخ درخواست", + "مرغدار", + "تلفن مرغدار", + "شهر", + "استان", + "سن مرغ", + "تعداد", + "مشاهده", + ]); + return ( + + + + درخواست های بایگانی شده + + + ( + + )} + value={selectedDate1} + onChange={(e) => { + setSelectedDate1(moment(e).format("YYYY-MM-DD")); + }} + /> + + + ( + + )} + value={selectedDate2} + onChange={(e) => { + setSelectedDate2(moment(e).format("YYYY-MM-DD")); + }} + /> + + + } + expandable + columns={tableDataCol} + data={dataTable} + /> + + ); +}; diff --git a/src/features/slaughter-house/components/slaughter-balance-status-button/SlaughterBalanceStatusButton.js b/src/features/slaughter-house/components/slaughter-balance-status-button/SlaughterBalanceStatusButton.js new file mode 100644 index 0000000..f49e622 --- /dev/null +++ b/src/features/slaughter-house/components/slaughter-balance-status-button/SlaughterBalanceStatusButton.js @@ -0,0 +1,109 @@ +import { Box, Typography } from "@mui/material"; +import { useSelector } from "react-redux"; +import { useState, useEffect } from "react"; +import { slaughterGetKillHouseLockInfoService } from "../../services/slaughter-get-kill-house-lock-info"; +import lockDollarIcon from "../../../../assets/images/lock-dollar.svg"; +import lockAnbarIcon from "../../../../assets/images/lock-anbar.svg"; + +export const SlaughterBalanceStatusButton = () => { + const userRoles = useSelector((state) => state.userSlice.role); + const [lockInfo, setLockInfo] = useState(null); + + const hasOnlyKillHouseRole = userRoles && userRoles.includes("KillHouse"); + + useEffect(() => { + if (hasOnlyKillHouseRole) { + const fetchLockInfo = async () => { + try { + const data = await slaughterGetKillHouseLockInfoService(); + setLockInfo(data); + } catch (error) { + console.error("Error fetching lock info:", error); + setLockInfo(null); + } + }; + fetchLockInfo(); + } + }, [hasOnlyKillHouseRole, userRoles]); + + return ( + + {lockInfo?.wageLock && ( + + )} + {lockInfo?.wareHouseLock && ( + + )} + + {(lockInfo?.wage || 0).toLocaleString()} + + + ریال + + + ); +}; diff --git a/src/features/slaughter-house/components/slaughter-bars/SlaughterBars.js b/src/features/slaughter-house/components/slaughter-bars/SlaughterBars.js new file mode 100644 index 0000000..62f2d5a --- /dev/null +++ b/src/features/slaughter-house/components/slaughter-bars/SlaughterBars.js @@ -0,0 +1,878 @@ +import { + Button, + IconButton, + Pagination, + Tab, + Tabs, + TextField, + Tooltip, + Typography, +} from "@mui/material"; +import { format } from "date-fns-jalali"; +import { useContext, useEffect, useState } from "react"; +import { useDispatch, useSelector } from "react-redux"; +// import { AdvancedTable } from "../../../../components/advanced-table/AdvancedTable"; +import { Grid } from "../../../../components/grid/Grid"; +// import { vetFarmGetAllocatedService } from "../../services/vet-farm-get-allocated"; +import { DatePicker } from "@mui/x-date-pickers"; +import CancelIcon from "@mui/icons-material/Delete"; +import moment from "moment/moment"; +import { SPACING } from "../../../../data/spacing"; +import { AppContext } from "../../../../contexts/AppContext"; +import axios from "axios"; +import { RiFileExcel2Fill, RiSearchLine } from "react-icons/ri"; +import { + LOADING_END, + LOADING_START, + OPEN_MODAL, +} from "../../../../lib/redux/slices/appSlice"; +import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl"; +// import { getFaUserRole } from "../../../../utils/getFaUserRole"; +import { PageTable } from "../../../../components/page-table/PageTable"; +import { SimpleTable } from "../../../../components/simple-table/SimpleTable"; +import { VetFarmCancelBar } from "../../../vet-farm/components/vet-farm-cancel-bar/VetFarmCancelBar"; +import { VetFarmEditTrafficCode } from "../../../vet-farm/components/vet-farm-edit-traffic-code/VetFarmEditTrafficCode"; +import { VetFarmDeletedBars } from "../../../vet-farm/components/vet-farm-deleted-bars/VetFarmDeletedBars"; +import { ProvinceBarDifference } from "../../../province/components/province-bar-difference/ProvinceBarDifference"; +import { CheckCleanceCode } from "../../../../components/check-clearance-code/ChechClearanceCode"; +import ResponsiveTable from "../../../../components/responsive-table/ResponsiveTable"; +import { SlaughterBarDashboardService } from "../../services/slaughter-bar-dashbored"; +import { SlaughterEnterNoneReciept } from "../slaughter-enter-none-receipt/SlaughterEnterNoneReciept"; +import { checkPathStartsWith } from "../../../../utils/checkPathStartsWith"; + +export const SlaughterBars = () => { + const [, , selectedDate1, setSelectedDate1, selectedDate2, setSelectedDate2] = + useContext(AppContext); + + useEffect(() => { + const currentDate = moment(new Date()).format("YYYY-MM-DD"); + setSelectedDate1(currentDate); + setSelectedDate2(currentDate); + }, []); + const userKey = useSelector((state) => state.userSlice.userProfile.key); + + const [selectedTab, setSelectedTab] = useState(0); + + const handleTabChange = (event, newValue) => { + setSelectedTab(newValue); + }; + + const dispatch = useDispatch(); + + const [dataTableM, setDataTableM] = useState([]); + + const [data, setData] = useState([]); + const [loading, setLoading] = useState(false); + const [totalRows, setTotalRows] = useState(0); + const [perPage, setPerPage] = useState(10); + const [dashboardData, setDashboardData] = useState([]); + const selectedSubUser = useSelector( + (state) => state.userSlice.selectedSubUser + ); + + const fetchApiData = async (page) => { + setLoading(true); + const response = await axios.get( + `kill_house_request_bar_management/?check&search=filter&value=${textValue}&role=${getRoleFromUrl()}${ + checkPathStartsWith("slaughter") + ? `&role_key=${selectedSubUser?.key}` + : "" + }&date1=${selectedDate1}&date2=${selectedDate2}&page=${page}&page_size=${perPage}` + ); + + setData(response.data.results); + setTotalRows(response.data.count); + setLoading(false); + dispatch(LOADING_END()); + }; + + const [page, setPage] = useState(0); + const handleChangePageM = (event, newPage) => { + dispatch(LOADING_START()); + setPage(newPage); + fetchApiData(newPage + 1, textValue); + }; + + const handlePageChange = (page) => { + fetchApiData(page); + }; + + const handlePerRowsChange = async (newPerPage, page) => { + setLoading(true); + const response = await axios.get( + `kill_house_request_bar_management/?check&search=filter&value=${textValue}&role=${getRoleFromUrl()}${ + checkPathStartsWith("slaughter") + ? `&role_key=${selectedSubUser?.key}` + : "" + }&date1=${selectedDate1}&date2=${selectedDate2}&page=${page}&page_size=${newPerPage}` + ); + + setData(response.data.results); + setTotalRows(response.data.count); + setPerPage(newPerPage); + + setLoading(false); + }; + + useEffect(() => { + fetchApiData(1); + }, []); + + // const updateTable = () => { + // fetchApiData(1); + // }; + const btnDisabled = !( + getRoleFromUrl() === "ProvinceOperator" || getRoleFromUrl() === "CityVet" + ); + + const columns = [ + { + name: "کدبار", + selector: (item) => { + return item.barCode; + }, + sortable: false, + wrap: true, + allowOverflow: true, + center: true, + width: "100px", + }, + { + name: "خریدار", + selector: (item) => { + return `${item.killhouseUser?.name} (${item.killhouseUser?.killHouseOperator?.user?.mobile})`; + }, + sortable: false, + wrap: true, + allowOverflow: true, + center: true, + width: "80px", + }, + { + name: "کشتارکن اختصاصی", + selector: (item) => { + return item?.killer + ? `${item?.killer?.name} (${item?.killer?.killHouseOperator?.user?.mobile})` + : "-"; + }, + sortable: false, + wrap: true, + allowOverflow: true, + center: true, + width: "80px", + }, + { + name: "ماشین", + selector: (item) => { + return `${item.addCar.driver.typeCar} ${item.addCar.driver.pelak}`; + }, + sortable: false, + wrap: true, + allowOverflow: true, + center: true, + width: "100px", + }, + { + name: "راننده", + selector: (item) => { + return `${item.addCar.driver.driverName} (${item.addCar.driver.driverMobile})`; + }, + sortable: false, + wrap: true, + allowOverflow: true, + center: true, + width: "80px", + }, + { + name: "کد بهداشتی حمل و نقل", + selector: (item) => { + return item?.trafficCode; + }, + sortable: false, + wrap: true, + allowOverflow: true, + center: true, + // width: "80px", + }, + { + name: "قیمت مرغ زنده‌ی بار", + selector: (item) => { + return item?.amount?.toLocaleString() + " ﷼"; + }, + sortable: false, + wrap: true, + allowOverflow: true, + center: true, + // width: "80px", + }, + { + name: "نژاد", + selector: (item) => { + return item.poultryRequest.chickenBreed; + }, + sortable: false, + wrap: true, + allowOverflow: true, + center: true, + width: "50px", + }, + { + name: "تعداد اولیه", + selector: (item) => { + return item.quantity?.toLocaleString(); + }, + sortable: true, + wrap: true, + allowOverflow: true, + center: true, + width: "50px", + }, + { + name: "وزن اولیه بار (کیلوگرم)", + selector: (item) => { + return item?.weightInfo?.weight?.toLocaleString(); + }, + sortable: true, + wrap: true, + allowOverflow: true, + center: true, + width: "70px", + }, + { + name: "میانگین وزن اولیه (کیلوگرم)", + selector: (item) => { + return item?.weightInfo?.indexWeight?.toLocaleString(); + }, + sortable: true, + wrap: true, + allowOverflow: true, + center: true, + width: "70px", + }, + { + name: "قیمت مرغدار", + selector: (item) => { + return item?.poultryRequest?.amount?.toLocaleString() + " ﷼"; + }, + sortable: false, + wrap: true, + allowOverflow: true, + center: true, + width: "80px", + }, + { + name: "قیمت کشتارگاه", + selector: (item) => { + return item?.weightInfo?.killHousePrice?.toLocaleString() + " ﷼"; + }, + sortable: false, + wrap: true, + allowOverflow: true, + center: true, + width: "80px", + }, + { + name: "مرغدار", + selector: (item) => { + return `${item.poultryRequest?.poultry?.unitName} (${item.poultryRequest.poultry?.user?.mobile})`; + }, + sortable: false, + wrap: true, + allowOverflow: true, + center: true, + width: "80px", + }, + { + name: "دامپزشک فارم", + selector: (item) => { + return item?.vetFarm?.vet?.user?.fullname + ? item?.vetFarm?.vet?.user?.fullname + + `(${item?.vetFarm?.vet?.user?.mobile})` + : "فاقد دامپزشک"; + }, + sortable: false, + wrap: true, + allowOverflow: true, + center: true, + width: "100px", + }, + { + name: "کدرهگیری سامانه قرنطینه", + selector: (item) => { + return ( + <> + {getRoleFromUrl() === "VetFarm" || + getRoleFromUrl() === "ProvinceOperator" || + getRoleFromUrl() === "CityVet" || + getRoleFromUrl() === "VetSupervisor" ? ( + <> + {item?.registerar?.date + ? `${format( + new Date(item?.registerar?.date), + "yyyy/MM/dd" + )} ${item?.registerar?.name}` + : ""} + + ) : item?.clearanceCode ? ( + item?.clearanceCode && ( + + ) + ) : ( + "-" + )} + + ); + }, + sortable: false, + wrap: true, + allowOverflow: true, + center: true, + width: "200px", + }, + { + name: "محل کشتار", + selector: (item) => { + return `${item.killPlace}`; + }, + sortable: false, + wrap: true, + allowOverflow: true, + center: true, + width: "80px", + }, + { + name: "شهر", + selector: (item) => { + return item.poultryRequest.poultry.address.city.name; + }, + sortable: false, + wrap: true, + allowOverflow: true, + center: true, + width: "80px", + }, + { + name: "تاریخ کشتار", + selector: (item) => { + return item?.poultryRequest.sendDate + ? format(new Date(item?.poultryRequest.sendDate), "yyyy/MM/dd") + : "-"; + }, + sortable: false, + wrap: true, + allowOverflow: true, + center: true, + width: "80px", + }, + { + name: "کدسفارش کشتار", + selector: (item) => { + return item?.poultryRequest.orderCode; + }, + sortable: false, + wrap: true, + allowOverflow: true, + center: true, + width: "70px", + }, + { + name: "تعداد نهایی", + selector: (item) => { + return item.acceptedRealQuantity?.toLocaleString(); + }, + sortable: true, + wrap: true, + allowOverflow: true, + center: true, + width: "50px", + }, + { + name: "وزن نهایی بار (کیلوگرم)", + selector: (item) => { + return item?.acceptedRealWeight?.toLocaleString(); + }, + sortable: true, + wrap: true, + allowOverflow: true, + center: true, + width: "70px", + }, + { + name: "میانگین وزن نهایی (کیلوگرم)", + selector: (item) => { + return item?.weightInfo?.finalIndexWeight?.toLocaleString(); + }, + sortable: true, + wrap: true, + allowOverflow: true, + center: true, + width: "70px", + }, + { + name: "وضعیت", + selector: (item) => { + let state = ""; + if (item.vetState === "accepted") { + state = "تایید تخلیه"; + } else if (item.vetState === "pending") { + state = "در انتظار تخلیه"; + } + return state; + }, + sortable: false, + wrap: true, + allowOverflow: true, + center: true, + width: "90px", + }, + { + name: "عملیات", + selector: (item) => { + return ( + + + { + dispatch( + OPEN_MODAL({ + title: "لغو بار", + content: ( + + ), + }) + ); + }} + > + + + + + ); + }, + sortable: false, + wrap: true, + allowOverflow: true, + center: true, + width: "70px", + }, + ]; + + const handleDateChange1 = (date) => { + setSelectedDate1(date); + }; + + const handleDateChange2 = (date) => { + setSelectedDate2(date); + }; + + useEffect(() => { + fetchApiData(1); + }, [selectedDate1, selectedDate2, perPage, selectedSubUser?.key]); + + const [textValue, setTextValue] = useState(""); + + const handleTextChange = (event) => { + setTextValue(event.target.value); + }; + + useEffect(() => { + fetchApiData(1); + dispatch( + SlaughterBarDashboardService({ + selectedDate1, + selectedDate2, + textValue, + role_key: checkPathStartsWith("slaughter") + ? selectedSubUser?.key || "" + : "", + }) + ).then((r) => { + setDashboardData(r.payload.data); + }); + }, [dispatch, selectedDate1, selectedDate2, selectedSubUser?.key]); + + const handleSubmit = async (event) => { + event.preventDefault(); + setLoading(true); + + try { + const response = await axios.get( + `kill_house_request_bar_management/?check&role=${getRoleFromUrl()}${ + checkPathStartsWith("slaughter") + ? `&role_key=${selectedSubUser?.key}` + : "" + }&search=filter&value=${textValue}&date1=${selectedDate1}&date2=${selectedDate2}&page=${1}&page_size=${perPage}` + ); + setData(response.data.results); + setTotalRows(response.data.count); + dispatch( + SlaughterBarDashboardService({ + selectedDate1, + selectedDate2, + textValue, + role_key: checkPathStartsWith("slaughter") + ? selectedSubUser?.key || "" + : "", + }) + ).then((r) => { + setDashboardData(r.payload.data); + }); + } catch (error) { + console.error("Error fetching data:", error); + } finally { + setLoading(false); + } + }; + + const updateTable = () => { + fetchApiData(1); + }; + + const tableTitle = ( + + + مدیریت بارها + + } + value={selectedDate1} + onChange={(e) => { + handleDateChange1(moment(e).format("YYYY-MM-DD")); + }} + /> + + + } + value={selectedDate2} + onChange={(e) => { + handleDateChange2(moment(e).format("YYYY-MM-DD")); + }} + /> + +
    + + + + + + + + +
    +
    + ); + + const getItemState = (item) => { + let state = ""; + if (item.vetState === "accepted") { + state = "تایید تخلیه"; + } else if (item.vetState === "pending") { + state = "در انتظار تخلیه"; + } + return state; + }; + + const columnNames = columns.map((column) => column.name); + const isMobile = window.innerWidth <= 600; + + useEffect(() => { + const d = data?.map((item, i) => { + return [ + item.barCode, + `${item.killhouseUser?.name} (${item.killhouseUser?.killHouseOperator?.user?.mobile})`, + `${item.addCar.driver.typeCar} ${item.addCar.driver.pelak}`, + `${item.addCar.driver.driverName} (${item.addCar.driver.driverMobile})`, + , + item.poultryRequest.chickenBreed, + item.quantity?.toLocaleString(), + item?.weightInfo?.weight?.toLocaleString(), + item?.weightInfo?.indexWeight?.toLocaleString(), + `${item.poultryRequest?.poultry?.unitName} (${item.poultryRequest.poultry?.user?.mobile})`, + item?.vetFarm?.vet?.user?.fullname + ? item?.vetFarm?.vet?.user?.fullname + + `(${item?.vetFarm?.vet?.user?.mobile})` + : "فاقد دامپزشک", + <> + {getRoleFromUrl() === "VetFarm" || + getRoleFromUrl() === "ProvinceOperator" || + getRoleFromUrl() === "CityVet" || + getRoleFromUrl() === "VetSupervisor" ? ( + <> + {item?.registerar?.date + ? `${format(new Date(item?.registerar?.date), "yyyy/MM/dd")} ${ + item?.registerar?.name + }` + : ""} + + ) : item?.clearanceCode ? ( + item?.clearanceCode + ) : ( + "-" + )} + , + `${item.killPlace}`, + item.poultryRequest.poultry.address.city.name, + item?.poultryRequest.sendDate + ? format(new Date(item?.poultryRequest.sendDate), "yyyy/MM/dd") + : "-", + item?.poultryRequest.orderCode, + getItemState(item), + + + { + dispatch( + OPEN_MODAL({ + title: "لغو بار", + content: ( + + ), + }) + ); + }} + > + + + + , + ]; + }); + + setDataTableM(d); + }, [data]); + + const tabs = ( + + + + + + + ); + + return ( + + + {tabs} + + + {selectedTab === 0 && ( + + + + + {isMobile ? ( + + {tableTitle} + + { + handleChangePageM(event, newPage - 1); + }} + /> + + ) : ( + + )} + {/* + + مدیریت بارها + + + ( + + )} + value={selectedDate1} + onChange={(e) => { + setSelectedDate1(moment(e).format("YYYY-MM-DD")); + }} + /> + + + ( + + )} + value={selectedDate2} + onChange={(e) => { + setSelectedDate2(moment(e).format("YYYY-MM-DD")); + }} + /> + + {getRoleFromUrl() === "ProvinceOperator" && ( + + + + + + )} + + } + columns={[ + "ردیف", + "کدبار", + "دامپزشک فارم", + "ماشین", + "راننده", + // "کد بهداشتی", + "خریدار", + "محل کشتار", + "مرغدار", + "شهر", + "تاریخ کشتار", + "کدسفارش کشتار", + "نژاد", + "تعداد", + "کد بهداشتی حمل و نقل", + "کدرهگیری سامانه قرنطینه", + "وضعیت", + "عملیات", + ]} + data={dataTable} + /> */} + + )} + {selectedTab === 1 && ( + + + + )} + {selectedTab === 2 && ( + + + + )} + {selectedTab === 3 && ( + + + + )} + + ); +}; + +// const DisabledWrap = ({ children, checked }) => { +// return {children}; +// }; diff --git a/src/features/slaughter-house/components/slaughter-cold-house-bars-operations/SlaughterColdHouseBarsOperations.js b/src/features/slaughter-house/components/slaughter-cold-house-bars-operations/SlaughterColdHouseBarsOperations.js new file mode 100644 index 0000000..7b6d6dc --- /dev/null +++ b/src/features/slaughter-house/components/slaughter-cold-house-bars-operations/SlaughterColdHouseBarsOperations.js @@ -0,0 +1,136 @@ +import React, { useContext, useState } from "react"; +import { Button, IconButton, Popover } from "@mui/material"; +import TuneIcon from "@mui/icons-material/Tune"; +import { useDispatch } from "react-redux"; +import { AppContext } from "../../../../contexts/AppContext"; +import { Grid } from "../../../../components/grid/Grid"; +import { OPEN_MODAL } from "../../../../lib/redux/slices/appSlice"; +import { slaughterDeleteAllocatedService } from "../../services/salughter-delete-allocated"; +import { SlaughterAllocateToGuild } from "../slaughter-allocate-to-guild/SlaughterAllocateToGuild"; + +export const SlaughterColdHouseBarsOperations = ({ + fetchApiData, + item, + fetchData, + updateTable, + priceInfo, + remainWeight, +}) => { + const [anchorEl, setAnchorEl] = useState(null); + + const handleClick = (event) => { + setAnchorEl(event.currentTarget); + }; + + const handleClose = () => { + setAnchorEl(null); + }; + + const open = Boolean(anchorEl); + const id = open ? "popover" : undefined; + + const [openNotif] = useContext(AppContext); + + const dispatch = useDispatch(); + + return ( + + + + + +
    + + + + + +
    +
    +
    + ); +}; diff --git a/src/features/slaughter-house/components/slaughter-cold-house-bars/SlaughterColdHouseBars.js b/src/features/slaughter-house/components/slaughter-cold-house-bars/SlaughterColdHouseBars.js new file mode 100644 index 0000000..9559127 --- /dev/null +++ b/src/features/slaughter-house/components/slaughter-cold-house-bars/SlaughterColdHouseBars.js @@ -0,0 +1,414 @@ +import React, { useContext, useEffect, useState } from "react"; +import { + Button, + IconButton, + TextField, + Tooltip, + Typography, +} from "@mui/material"; +import { useDispatch, useSelector } from "react-redux"; +import axios from "axios"; +import { + CLOSE_MODAL, + LOADING_END, + LOADING_START, + OPEN_MODAL, +} from "../../../../lib/redux/slices/appSlice"; +import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl"; +import { Grid } from "../../../../components/grid/Grid"; +import ResponsiveTable from "../../../../components/responsive-table/ResponsiveTable"; +import { formatJustDate } from "../../../../utils/formatTime"; +import { RiFileExcel2Fill } from "react-icons/ri"; +import { AppContext } from "../../../../contexts/AppContext"; +import { RiSearchLine } from "react-icons/ri"; +import { SlaughterColdHouseBarsOperations } from "../slaughter-cold-house-bars-operations/SlaughterColdHouseBarsOperations"; +import { getKillhouseApprovedPriceState } from "../../../province/services/get-approved-price-state"; +import { slaughterInventoryFinalSubmitService } from "../../services/slaughter-inventory-final-submit"; +import { SPACING } from "../../../../data/spacing"; +import { SlaughterAllocateToColdHouse } from "../slaughter-allocate-to-coldhouse/SlaughterAllocateToColdHouse"; +import TuneIcon from "@mui/icons-material/Tune"; +import { checkPathStartsWith } from "../../../../utils/checkPathStartsWith"; +export const SlaughterColdHouseBars = ({ + selectedDate1, + selectedDate2, + title, + type, + withDate, + coldHouseKey, + getDashboardsData, + remainWeight, +}) => { + const dispatch = useDispatch(); + const userKey = useSelector((state) => state.userSlice.userProfile.key); + const [openNotif] = useContext(AppContext); + const handleTextChange = (event) => { + setTextValue(event.target.value); + }; + const selectedSubUser = useSelector( + (state) => state.userSlice.selectedSubUser + ); + const { priceInfo } = useSelector((state) => state.slaughterSlice); + + const [data, setData] = useState([]); + const [totalRows, setTotalRows] = useState(0); + const [perPage, setPerPage] = useState(10); + const [textValue, setTextValue] = useState(""); + const [page, setPage] = useState(1); + const [tableData, setTableData] = useState([]); + + const fetchApiData = async (page) => { + dispatch(LOADING_START()); + const response = await axios.get( + `steward-allocation/?search=filter&value=${textValue}&role=${getRoleFromUrl()}${ + checkPathStartsWith("slaughter") + ? `&role_key=${selectedSubUser?.key}` + : "" + }${ + withDate ? `&date1=${selectedDate1}&date2=${selectedDate2}` : `` + }&page=${page}&page_size=${perPage}&cold_house=true&type=${type}&cold_house_key=${coldHouseKey}` + ); + dispatch( + getKillhouseApprovedPriceState({ + role_key: checkPathStartsWith("slaughter") + ? selectedSubUser?.key || "" + : "", + }) + ); + + dispatch(LOADING_END()); + setData(response.data.results); + setTotalRows(response.data.count); + }; + + const handlePageChange = (page) => { + fetchApiData(page); + setPage(page); + }; + + const handlePerRowsChange = (perRows) => { + setPerPage(perRows); + setPage(1); + }; + + const updateTable = () => { + fetchApiData(page !== 0 ? page : 1); + }; + + const getLastItem = (item) => { + if (item?.systemRegistrationCode) { + return [ + + + , + ]; + } else { + return [ + , + ]; + } + }; + const getLastItemTitle = () => { + if (type === "output") { + return ["عملیات"]; + } else { + return []; + } + }; + const isOut = title === "بارهای خارج شده"; + + useEffect(() => { + const d = data?.map((item, i) => { + let registrationCodeStatus; + switch (item?.receiverState) { + case "pending": + registrationCodeStatus = "در انتظار تایید"; + break; + case "accepted": + registrationCodeStatus = "تایید شده"; + break; + + case "rejected": + registrationCodeStatus = "رد شده"; + break; + default: + registrationCodeStatus = "-"; + } + + console.log(item); + + return [ + page === 1 ? i + 1 : i + perPage * (page - 1) + 1, + formatJustDate(item?.date), + isOut + ? item?.toGuilds + ? "سردخانه به صنف" + : item?.otherColdHouse + ? "سردخانه به سردخانه" + : item?.toStewards + ? "سردخانه به مباشر" + : "-" + : `${item?.killHouse ? "کشتارگاه" : "سردخانه"} به سردخانه`, + isOut + ? item?.toGuilds + ? `${item?.toGuilds?.guildsName} ( ${item?.toGuilds?.user?.fullname} ${item?.toGuilds?.user?.mobile})` + : item?.otherColdHouse + ? item?.otherColdHouse?.steward + ? `${item?.otherColdHouse?.steward?.user?.fullname} (${item?.otherColdHouse?.steward?.user?.mobile})` + : `${item?.otherColdHouse?.killHouse?.name} (${item?.otherColdHouse?.killHouse?.killHouseOperator?.user?.fullname} ${item?.otherColdHouse?.killHouse?.killHouseOperator?.user?.mobile})` + : `${item?.toStewards?.name} (${item?.toStewards?.user?.fullname}${item?.toStewards?.user?.mobile})` + : item?.killHouse + ? `${item.toColdHouse?.name} (${item.toColdHouse?.killHouse?.killHouseOperator?.user?.mobile})` + : `${item?.otherColdHouse?.name} ${item?.otherColdHouse?.killHouse?.killHouseOperator?.user?.mobile}`, + item?.sellType === "exclusive" ? "اختصاصی" : "آزاد", + item?.amount?.toLocaleString() + " ریال", + item?.totalAmount?.toLocaleString() + " ریال", + // item?.realNumberOfCarcasses?.toLocaleString(), + item?.realWeightOfCarcasses?.toLocaleString(), + item?.loggedRegistrationCode?.toLocaleString(), + item?.systemRegistrationCode === true + ? "کد احراز ارسال شده" + : "در انتظار ارسال کد احراز", + + registrationCodeStatus, + // item?.receiverRealNumberOfCarcasses?.toLocaleString(), + // item?.receiverRealWeightOfCarcasses?.toLocaleString(), + ...getLastItem(item), + ]; + }); + + setTableData(d); + }, [data]); + + useEffect(() => { + fetchApiData(1); + }, [ + dispatch, + selectedDate1, + selectedDate2, + perPage, + withDate, + selectedSubUser?.key, + ]); + + const handleSubmit = async (event) => { + event.preventDefault(); + dispatch(LOADING_START()); + + try { + const response = await axios.get( + `steward-allocation/?role=${getRoleFromUrl()}${ + checkPathStartsWith("slaughter") + ? `&role_key=${selectedSubUser?.key}` + : "" + }&search=filter&value=${textValue}${ + withDate ? `&date1=${selectedDate1}&date2=${selectedDate2}` : `` + }&page=${1}&page_size=${perPage}&cold_house=true&type=${type}&cold_house_key=${coldHouseKey}` + ); + setData(response.data.results); + setTotalRows(response.data.count); + dispatch(LOADING_END()); + } catch (error) { + console.error("Error fetching data:", error); + } + }; + + return ( + + + + + {type === "output" && ( + + + + + ), + }) + ); + }} + > + تایید نهایی (یکجا) + + )} + + +
    + + + +
    + + {/* */} + + {/* */} + + + + + + ); +}; diff --git a/src/features/slaughter-house/components/slaughter-daily-list-operation/SlaughterDailyListOperation.js b/src/features/slaughter-house/components/slaughter-daily-list-operation/SlaughterDailyListOperation.js new file mode 100644 index 0000000..2c3e37f --- /dev/null +++ b/src/features/slaughter-house/components/slaughter-daily-list-operation/SlaughterDailyListOperation.js @@ -0,0 +1,118 @@ +// import { Button, IconButton, Popover, Tooltip } from "@mui/material"; +// import { useContext, useState } from "react"; +// import TuneIcon from "@mui/icons-material/Tune"; +// import { Grid } from "../../../../components/grid/Grid"; +// import DeleteIcon from "@mui/icons-material/Delete"; +// import { CLOSE_MODAL, OPEN_MODAL } from "../../../../lib/redux/slices/appSlice"; +// import { slaughterDeleteDailyListService } from "../../services/slaughter-add-daily-list"; +// import { useDispatch } from "react-redux"; +// import { AppContext } from "../../../../contexts/AppContext"; + +// export const SlaughterDailyListOperation = ({ item, updateTable }) => { +// const dispatch = useDispatch(); +// const [anchorEl, setAnchorEl] = useState(null); + +// const handleClick = (event) => { +// setAnchorEl(event.currentTarget); +// }; + +// const handleClose = () => { +// setAnchorEl(null); +// }; + +// const open = Boolean(anchorEl); +// const id = open ? "popover" : undefined; + +// const [openNotif] = useContext(AppContext); +// return ( +//
    +// +// +// +// +//
    +// +// +// { +// handleClose(); +// dispatch( +// OPEN_MODAL({ +// title: "آیا مطمئن هستید؟", +// content: ( +// +// +// +// +// +// +// +// +// ), +// }) +// ); +// }} +// > +// +// +// +// +//
    +//
    +//
    +// ); +// }; diff --git a/src/features/slaughter-house/components/slaughter-daily-list/SlaughterDailyList.js b/src/features/slaughter-house/components/slaughter-daily-list/SlaughterDailyList.js new file mode 100644 index 0000000..18d6131 --- /dev/null +++ b/src/features/slaughter-house/components/slaughter-daily-list/SlaughterDailyList.js @@ -0,0 +1,713 @@ +import React, { useContext, useEffect, useRef, useState } from "react"; +import { Grid } from "../../../../components/grid/Grid"; +import ResponsiveTable from "../../../../components/responsive-table/ResponsiveTable"; +import { useDispatch, useSelector } from "react-redux"; +import { slaughterGetProductsService } from "../../services/slaughter-inventory-gets"; +import InfoIcon from "@mui/icons-material/Info"; +import TextField from "@mui/material/TextField"; +import InputAdornment from "@mui/material/InputAdornment"; +import SearchIcon from "@mui/icons-material/Search"; +import { ImageUpload } from "../../../../components/image-upload/ImageUpload"; +import { + DRAWER, + LOADING_END, + LOADING_START, +} from "../../../../lib/redux/slices/appSlice"; +import axios from "axios"; +import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl"; +import { + Box, + Button, + Card, + CardContent, + IconButton, + Typography, +} from "@mui/material"; +import { SlaughterAddDailyList } from "../slaughter-add-daily-list/SlaughterAddDailyList"; +import { + slaughterDeleteDailyListService, + slaughterGetPriceService, + submitBatchAllocationsService, +} from "../../services/slaughter-add-daily-list"; +import { NumberInput } from "../../../../components/number-format-custom/NumberFormatCustom"; +import moment from "moment"; +import { AppContext } from "../../../../contexts/AppContext"; +import AddIcon from "@mui/icons-material/Add"; +import CheckCircleIcon from "@mui/icons-material/CheckCircle"; +import DeleteIcon from "@mui/icons-material/Delete"; +import { fixBase64 } from "../../../../utils/toBase64"; +import { provincePolicyGetUploadImageService } from "../../../province/services/province-policy-upload-image"; +import { checkPathStartsWith } from "../../../../utils/checkPathStartsWith"; + +export const SlaughterDailyList = () => { + const [productsTable, setProductsTable] = useState(); + const [slaughterProducts, setSlaughterProducts] = useState(); + const [prices, setPrices] = useState([]); + const [rendered, setrendered] = useState(false); + const [weights, setWeights] = useState([]); + const [data, setData] = useState([]); + const [tableData, setTableData] = useState([]); + const [searchTerm, setSearchTerm] = useState(""); + const [filteredData, setFilteredData] = useState([]); + const [rowImages, setRowImages] = useState([]); + const [uploadPolicy, setUploadPolicy] = useState({ + killHouseAllocation: true, + }); + const selectedSubUser = useSelector( + (state) => state.userSlice.selectedSubUser + ); + const [openNotif] = useContext(AppContext); + + const priceRefs = useRef([]); + const weightRefs = useRef([]); + const imageRefs = useRef([]); + + const dispatch = useDispatch(); + + const [priceState, setPriceState] = useState({ + active: false, + killHousePrice: 0, + stewardPrice: 0, + guildPrice: 0, + }); + + const getPriceByRole = () => { + const role = getRoleFromUrl(); + if (role === "KillHouse") return priceState.killHousePrice; + if (role === "Steward") return priceState.stewardPrice; + if (role === "Guilds") return priceState.guildPrice; + return 0; + }; + + useEffect(() => { + priceRefs.current = priceRefs.current.slice(0, data?.length || 0); + weightRefs.current = weightRefs.current.slice(0, data?.length || 0); + imageRefs.current = imageRefs.current.slice(0, data?.length || 0); + }, [data]); + + useEffect(() => { + if (searchTerm) { + const filtered = tableData.filter((item) => + item.some((cell) => + String(cell).toLowerCase().includes(searchTerm.toLowerCase()) + ) + ); + setFilteredData(filtered); + } else { + setFilteredData(tableData); + } + }, [searchTerm, tableData]); + + const handleKeyDown = (e, index, fieldType) => { + if (e.key === "Enter") { + e.preventDefault(); + + if (fieldType === "price") { + const updatedPrices = [...prices]; + updatedPrices[index] = Number(e.target.value.replace(/,/g, "")); + setPrices(updatedPrices); + + if (weightRefs.current[index]) { + weightRefs.current[index].focus(); + } + } else if (fieldType === "weight") { + const updatedWeights = [...weights]; + updatedWeights[index] = Number(e.target.value.replace(/,/g, "")); + setWeights(updatedWeights); + + if (uploadPolicy?.killHouseAllocation || rowImages[index]) { + if (imageRefs.current[index]) { + imageRefs.current[index].focus(); + } + } else { + moveToNextField(index); + } + } + } + }; + + const moveToNextField = (currentIndex) => { + if (priceState?.active) { + let nextIndex = currentIndex + 1; + while (nextIndex < data.length) { + if (weightRefs.current[nextIndex]) { + weightRefs.current[nextIndex].focus(); + break; + } + nextIndex++; + } + + if (nextIndex >= data.length && weightRefs.current[0]) { + weightRefs.current[0]?.focus(); + } + } else { + let nextIndex = currentIndex + 1; + while (nextIndex < data.length) { + if (priceRefs.current[nextIndex]) { + priceRefs.current[nextIndex].focus(); + break; + } + nextIndex++; + } + + if (nextIndex >= data.length && priceRefs.current[0]) { + priceRefs.current[0]?.focus(); + } + } + }; + + const fetchUploadPolicy = () => { + dispatch( + provincePolicyGetUploadImageService({ + role_key: checkPathStartsWith("slaughter") ? selectedSubUser?.key : "", + }) + ).then((r) => { + if (r.payload?.data) { + setUploadPolicy(r.payload.data); + } + }); + }; + + const fetchPriceStatus = async () => { + dispatch( + slaughterGetPriceService({ + role: getRoleFromUrl(), + role_key: selectedSubUser?.key, + }) + ).then((r) => { + setPriceState(r.payload.data); + }); + }; + + const fetchApiData = async () => { + dispatch(LOADING_START()); + try { + const response = await axios.get( + `commonly-used/?search=filter&value=&role=${getRoleFromUrl()}${ + checkPathStartsWith("slaughter") + ? `&role_key=${selectedSubUser?.key}` + : "" + }&page=1&page_size=10000` + ); + setrendered(true); + setData(response.data.results || []); + } catch (e) { + console.error(e); + } finally { + dispatch(LOADING_END()); + } + }; + + const handleRowImageChange = (images, index) => { + const newRowImages = [...rowImages]; + newRowImages[index] = images[0] + ? { + ...images[0], + base64: fixBase64(images[0]?.data_url), + } + : null; + setRowImages(newRowImages); + + if ( + (uploadPolicy?.killHouseAllocation && images[0]) || + !uploadPolicy?.killHouseAllocation + ) { + moveToNextField(index); + } + }; + + useEffect(() => { + const d = data?.map((item, i) => { + const getPrice = + parseInt(priceState?.active ? getPriceByRole() : prices[i]) * + parseInt(weights[i]); + return [ + i + 1, + item?.guild?.steward ? "مباشر" : "صنف", + `${item?.guild?.guildsName}/${item?.guild?.user?.fullname}/${item?.guild?.user?.city}/${item?.guild?.user?.mobile}`, + item?.exclusive ? "اختصاصی" : "آزاد", + handleKeyDown(e, i, "price")} + inputRef={(el) => (priceRefs.current[i] = el)} + variant="outlined" + style={{ width: 100 }} + />, + + { + handleKeyDown(e, i, "weight"); + }} + inputRef={(el) => (weightRefs.current[i] = el)} + variant="outlined" + style={{ width: 100 }} + />, + isNaN(getPrice) ? "وارد نشده! " : getPrice?.toLocaleString() + " ریال", +
    + handleRowImageChange(images, i)} + images={rowImages[i] ? [rowImages[i]] : []} + maxNumber={1} + title={"بارگزاری سند"} + required={uploadPolicy?.killHouseAllocation} + inputRef={(el) => (imageRefs.current[i] = el)} + /> + {uploadPolicy?.killHouseAllocation && !rowImages[i] && ( + + تصویر الزامی است + + )} +
    , + + + handleDeleteItem(item.key)} /> + , + ]; + }); + + setTableData(d); + setFilteredData(d); + }, [data, prices, weights, priceState, rowImages, uploadPolicy]); + + useEffect(() => { + fetchApiData(); + fetchPriceStatus(); + fetchUploadPolicy(); + dispatch(slaughterGetProductsService()).then((r) => { + setSlaughterProducts(r.payload.data); + }); + }, [selectedSubUser?.key]); + + useEffect(() => { + const d = slaughterProducts?.map((item) => { + return [item?.name, item?.totalRemainWeight?.toLocaleString()]; + }); + + setProductsTable(d); + }, [slaughterProducts]); + + const handleDeleteItem = (key) => { + dispatch(slaughterDeleteDailyListService(key)).then((r) => { + if (r.payload.error) { + openNotif({ + vertical: "top", + horizontal: "center", + msg: r.payload.error, + severity: "error", + }); + } else { + openNotif({ + vertical: "top", + horizontal: "center", + msg: "عملیات با موفقیت انجام شد.", + severity: "success", + }); + + fetchApiData(1); + } + }); + }; + + const handleSendAllocate = () => { + const filteredData = data + ?.map((item, i) => { + const price = priceState?.active ? getPriceByRole() : prices[i]; + const weight = weights[i]; + + if (!price || !weight) return null; + + if (uploadPolicy?.killHouseAllocation && !rowImages[i]) { + return null; + } + + let d = { + seller_type: "KillHouse", + buyer_type: item?.guild?.steward ? "Steward" : "Guild", + guild_key: !item?.guild?.steward ? item?.guild?.key : null, + steward_key: item?.guild?.steward ? item?.guild?.key : null, + product_key: slaughterProducts[0]?.key, + type: "manual", + allocation_type: item?.guild?.steward + ? "killhouse_steward" + : "killhouse_guild", + number_of_carcasses: 0, + weight_of_carcasses: weight, + sell_type: "free", + amount: price, + total_amount: price * weight, + approved_price_status: priceState?.active, + date: moment(new Date()).format("YYYY-MM-DD"), + }; + + if (rowImages[i]) { + d.image = rowImages[i]?.base64; + } + + return Object.fromEntries( + Object.entries(d).filter(([_, value]) => value !== null) + ); + }) + .filter(Boolean); + + if (filteredData.length === 0) { + openNotif({ + vertical: "top", + horizontal: "center", + msg: "لطفا حداقل یک رکورد معتبر با عکس وارد کنید", + severity: "error", + }); + return; + } + + dispatch(submitBatchAllocationsService(filteredData)).then((r) => { + if (r.payload.error) { + openNotif({ + vertical: "top", + horizontal: "center", + msg: r.payload.error, + severity: "error", + }); + } else { + openNotif({ + vertical: "top", + horizontal: "center", + msg: "عملیات با موفقیت انجام شد.", + severity: "success", + }); + setPrices([]); + setWeights([]); + setRowImages([]); + fetchApiData(1); + fetchPriceStatus(); + fetchUploadPolicy(); + dispatch(slaughterGetProductsService()).then((r) => { + setSlaughterProducts(r.payload.data); + }); + } + }); + }; + + return ( + + + + + + + + + + + + + + + + مجموع وزن وارد شده + + + {weights?.length + ? weights.reduce((a, b) => a + b, 0).toLocaleString() + : "۰"} + + + + + وزن باقیمانده + a + b, 0) > + slaughterProducts[0]?.totalRemainWeight + ? "error" + : "text.secondary" + : "text.secondary" + } + > + {slaughterProducts?.[0]?.totalRemainWeight !== undefined + ? weights?.length + ? ( + slaughterProducts[0]?.totalRemainWeight - + weights.reduce((a, b) => a + b, 0) + ).toLocaleString() + : slaughterProducts[0]?.totalRemainWeight.toLocaleString() + : "۰"} + + + + + + + + + + + + + + + + پس از وارد کردن هر مقدار، کلید Enter را فشار دهید! + + + + + + + صرفا تخصیصاتی که هر دو مقدار قیمت و وزن آنها را وارد کنید ثبت خواهند + شد. + + + + + setSearchTerm(e.target.value)} + InputProps={{ + startAdornment: ( + + + + ), + }} + sx={{ mb: 2 }} + /> + + + {filteredData?.length ? ( + + {filteredData?.map((item, i) => ( + + + {item[0]} + + + + + ماهیت: + + + {item[1]} + + + + + + خریدار: + + + {item[2]} + + + + + + نوع فروش: + + + {item[3]} + + + + + + قیمت هرکیلو: + + + {item[4]} + + + + + + وزن لاشه: + + + {item[5]} + + + + + + قیمت کل: + + + {item[6]} + + + + + {item[7]} + + + + {item[8]} + + + + {!priceState?.active && + (!prices[i] || !weights[i]) && + (prices[i] || weights[i]) && ( + + لطفا همه موارد را وارد کنید و کلید Enter را بزنید + + )} + + + ))} + + ) : ( + + {!rendered + ? searchTerm + ? "نتیجه‌ای یافت نشد" + : "در حال بارگزاری..." + : "موردی یافت نشد!"} + + )} + + ); +}; diff --git a/src/features/slaughter-house/components/slaughter-edit-allocated-car/SlaughterEditAllocatedCar.js b/src/features/slaughter-house/components/slaughter-edit-allocated-car/SlaughterEditAllocatedCar.js new file mode 100644 index 0000000..5d4478c --- /dev/null +++ b/src/features/slaughter-house/components/slaughter-edit-allocated-car/SlaughterEditAllocatedCar.js @@ -0,0 +1,239 @@ +import { useContext, useEffect } from "react"; +import { useDispatch } from "react-redux"; +import { useFormik } from "formik"; +import { Yup } from "../../../../lib/yup/yup"; +import { + Autocomplete, + Button, + TextField, + FormControl, + FormHelperText, +} from "@mui/material"; +import { Grid } from "../../../../components/grid/Grid"; +import { SPACING } from "../../../../data/spacing"; +import { AppContext } from "../../../../contexts/AppContext"; +import { CLOSE_MODAL } from "../../../../lib/redux/slices/appSlice"; +import { slaughterEditAllocatedCarService } from "../../services/slaughter-edit-allocated-car"; +import { useSlaughterHouseCars } from "../../../file/hooks/useSlaughterHouseCars"; +import { PropTypes } from "prop-types"; + +export const SlaughterEditAllocatedCar = ({ + item, + updateTable, + poultryRequestKey, + killHouseKey, + killRequestKey, +}) => { + const dispatch = useDispatch(); + const [openNotif] = useContext(AppContext); + + // Get available cars + const slaughterHouseCars = useSlaughterHouseCars( + poultryRequestKey, + killHouseKey, + killRequestKey + ); + + const formik = useFormik({ + initialValues: { + car: null, + trafficCode: item?.trafficCode || "", + amount: item?.barAmount || "", + }, + validationSchema: Yup.object({ + car: Yup.object().nullable(), + trafficCode: Yup.string(), + amount: Yup.number().positive("قیمت باید عدد مثبت باشد").nullable(), + }), + }); + + useEffect(() => { + formik.validateForm(); + }, []); + + // Set initial car if available + useEffect(() => { + if (slaughterHouseCars && item) { + const currentCar = slaughterHouseCars.find( + (car) => car.key === item.carKey + ); + if (currentCar) { + formik.setFieldValue("car", currentCar); + } + } + }, [slaughterHouseCars, item]); + + const handleSubmit = () => { + // Check if at least one field has a value + if ( + !formik.values.car && + !formik.values.trafficCode && + !formik.values.amount + ) { + openNotif({ + vertical: "top", + horizontal: "center", + msg: "لطفا حداقل یکی از فیلدها را پر کنید", + severity: "error", + }); + return; + } + + // Build request object + const requestData = { + key: item?.killHouseRequestKey, + }; + + // If user is updating car or traffic code, send all 3 parameters together + if (formik.values.car || formik.values.trafficCode) { + if (formik.values.car?.key && formik.values.car.key !== item?.carKey) { + requestData.car_key = formik.values.car.key; + } + + if ( + formik.values.trafficCode && + formik.values.trafficCode !== item?.trafficCode + ) { + requestData.traffic_code = formik.values.trafficCode; + } + + if (formik.values.amount && formik.values.amount !== item?.barAmount) { + requestData.amount = formik.values.amount; + } + } + // If user is updating only amount, send only amount + else if (formik.values.amount) { + requestData.amount = formik.values.amount; + } + + dispatch(slaughterEditAllocatedCarService(requestData)).then((r) => { + if (r.payload?.error) { + openNotif({ + vertical: "top", + horizontal: "center", + msg: r.payload.error, + severity: "error", + }); + } else { + openNotif({ + vertical: "top", + horizontal: "center", + msg: "ویرایش با موفقیت انجام شد", + severity: "success", + }); + dispatch(CLOSE_MODAL()); + if (updateTable) updateTable(); + } + }); + }; + + return ( + + + { + if (car) { + const carType = car.type === "exclusive" ? "اختصاصی" : "اجاره ای"; + return `${car.driverName} (${car.driverMobile}) ${car.typeCar} پلاک ${car.pelak} (${carType})`; + } + return ""; + }} + value={formik.values.car} + onChange={(e, car) => { + formik.setFieldValue("car", car); + if (car?.healthCode) { + formik.setFieldValue("trafficCode", car.healthCode); + } + }} + onBlur={formik.handleBlur} + renderInput={(params) => ( + + )} + /> + + {formik.touched.car && Boolean(formik.errors.car) + ? formik.errors.car + : null} + + + + + + + + + + + + + + ); +}; + +SlaughterEditAllocatedCar.propTypes = { + item: PropTypes.object.isRequired, + updateTable: PropTypes.func, + poultryRequestKey: PropTypes.string, + killHouseKey: PropTypes.string, + killRequestKey: PropTypes.string, +}; diff --git a/src/features/slaughter-house/components/slaughter-edit-stock/SlaughterEditStock.js b/src/features/slaughter-house/components/slaughter-edit-stock/SlaughterEditStock.js new file mode 100644 index 0000000..189e58c --- /dev/null +++ b/src/features/slaughter-house/components/slaughter-edit-stock/SlaughterEditStock.js @@ -0,0 +1,130 @@ +import { Button, TextField } from "@mui/material"; +import { useFormik } from "formik"; +import { useContext, useEffect } from "react"; +import { useDispatch, useSelector } from "react-redux"; +import { Grid } from "../../../../components/grid/Grid"; +import { AppContext } from "../../../../contexts/AppContext"; +import { SPACING } from "../../../../data/spacing"; +import { DRAWER } from "../../../../lib/redux/slices/appSlice"; +import { Yup } from "../../../../lib/yup/yup"; +import { slaughterGetInventoryStock } from "../../services/salughter-get-inventory-stock"; +import { slaughterEditStockService } from "../../services/slaughter-edit-stock"; + +const NumberValidationSchema = Yup.object().shape({ + firstNumber: Yup.number() + .required("حجم لاشه ها الزامی می باشد") + .min(0, "Number must be greater than or equal to 0"), + secondNumber: Yup.number() + .required("موجودی وزن لاشه ها الزامی می باشد") + .min(0, "Number must be greater than or equal to 0"), +}); + +export const SlaughterEditStock = ({ inventoryKey, aveWeightOfCarcasses }) => { + const dispatch = useDispatch(); + const [openNotif] = useContext(AppContext); + const [, , selectedDate1] = useContext(AppContext); + + const { inventorySelectedKillHouse } = useSelector( + (state) => state.slaughterSlice + ); + + const formik = useFormik({ + initialValues: { + firstNumber: "", + secondNumber: "", + }, + validationSchema: NumberValidationSchema, + onSubmit: (values) => { + dispatch( + slaughterEditStockService({ + key: inventoryKey, + updated_number_of_carcasses: Number(values.firstNumber), + updated_weight_of_carcasses: Number(values.secondNumber), + }) + ).then((r) => { + dispatch( + slaughterGetInventoryStock({ + date: selectedDate1, + kill_house_key: inventorySelectedKillHouse, + }) + ); + if (r.error) { + openNotif({ + vertical: "top", + horizontal: "center", + msg: r.error, + severity: "error", + }); + } else { + dispatch(DRAWER({ right: false, bottom: false, content: null })); + openNotif({ + vertical: "top", + horizontal: "center", + msg: "عملیات با موفقیت انجام شد.", + severity: "success", + }); + } + }); + }, + }); + + useEffect(() => { + let quantity; + if (aveWeightOfCarcasses) { + quantity = formik.values.secondNumber / aveWeightOfCarcasses; + } else { + quantity = formik.values.secondNumber / 2; + } + formik.setFieldValue("firstNumber", Number(quantity).toFixed()); + }, [formik.values.secondNumber]); + + return ( + +
    + + + + + + + +
    +
    + ); +}; diff --git a/src/features/slaughter-house/components/slaughter-enter-bar-info/SlaghterEnterBarInfo.js b/src/features/slaughter-house/components/slaughter-enter-bar-info/SlaghterEnterBarInfo.js new file mode 100644 index 0000000..da759c6 --- /dev/null +++ b/src/features/slaughter-house/components/slaughter-enter-bar-info/SlaghterEnterBarInfo.js @@ -0,0 +1,44 @@ +import { Box, Grid, Tab, Tabs } from "@mui/material"; +import { SPACING } from "../../../../data/spacing"; +import { useState } from "react"; +import { SlaughterManageBars } from "../slaughter-manage-bars/SlaughterManageBars"; +import { EnterAggregateLoadInformation } from "../enter-aggregate-load-information/EnterAggregateLoadInformation"; +import { EnterLoadInformation } from "../enter-load-information/EnterLoadInformation"; +import { SlaughterEnterNoneReciept } from "../slaughter-enter-none-receipt/SlaughterEnterNoneReciept"; + +export const SalughterEnterBarInfo = () => { + const [value, setValue] = useState(0); + + const handleChangeTab = (event, newValue) => { + setValue(newValue); + }; + + return ( + + + + + + + + + + {value === 0 && } + {value === 1 && } + {value === 2 && } + {value === 3 && } + + ); +}; diff --git a/src/features/slaughter-house/components/slaughter-enter-information-modal/SlaughterEnterInformationModal.js b/src/features/slaughter-house/components/slaughter-enter-information-modal/SlaughterEnterInformationModal.js new file mode 100644 index 0000000..ec0ed9a --- /dev/null +++ b/src/features/slaughter-house/components/slaughter-enter-information-modal/SlaughterEnterInformationModal.js @@ -0,0 +1,122 @@ +import { + Box, + Button, + Typography, + Stack, + Divider, + TextField, +} from "@mui/material"; +import { useFormik } from "formik"; +import * as Yup from "yup"; +import { SPACING } from "../../../../data/spacing"; +import { Grid } from "../../../../components/grid/Grid"; +import { format } from "date-fns-jalali"; + +export const SlaughterEnterInformationModal = ({ handleSubmit, item }) => { + const validationSchema = Yup.object({ + message: Yup.string().required("پیام الزامی است"), + }); + + const formik = useFormik({ + initialValues: { + message: "", + }, + validationSchema, + onSubmit: (values) => { + handleSubmit(values); + }, + }); + + return ( + + + + + + + کدبار: + {item?.barCode || "-"} + + + + تاریخ کشتار: + + {item?.poultryRequest.sendDate + ? format( + new Date(item?.poultryRequest.sendDate), + "yyyy/MM/dd" + ) + : "-"} + + + + + خریدار: + {`${item.killhouseUser?.name}(${item.killhouseUser?.killHouseOperator?.user?.mobile})`} + + + + + + + + مرغدار: + {`${item.poultryRequest?.poultry?.unitName}`} + + + + کد سفارش: + + {item?.poultryRequest.orderCode} + + + + + تعداد اولیه: + + {item.quantity?.toLocaleString()} (قطعه) + + + + وزن : + + {item?.weightInfo?.weight?.toLocaleString()} (کیلوگرم) + + + + + + + + + + + + + ); +}; diff --git a/src/features/slaughter-house/components/slaughter-enter-information-operation/SlaughterEnterInformationOperation.js b/src/features/slaughter-house/components/slaughter-enter-information-operation/SlaughterEnterInformationOperation.js new file mode 100644 index 0000000..fe5c336 --- /dev/null +++ b/src/features/slaughter-house/components/slaughter-enter-information-operation/SlaughterEnterInformationOperation.js @@ -0,0 +1,145 @@ +import { IconButton, Popover, Tooltip } from "@mui/material"; +import { useContext, useState } from "react"; +import { useDispatch } from "react-redux"; +import { + CLOSE_MODAL, + DRAWER, + OPEN_MODAL, +} from "../../../../lib/redux/slices/appSlice"; +import TuneIcon from "@mui/icons-material/Tune"; +import EditIcon from "@mui/icons-material/Edit"; +import { SlaughterEnterBarWeight } from "../../../file/components/slaughter-enter-bar-weight/SlaughterEnterBarWeight"; +import { Grid } from "../../../../components/grid/Grid"; +import ReceiptLongIcon from "@mui/icons-material/ReceiptLong"; +import { SlaughterEnterInformationModal } from "../slaughter-enter-information-modal/SlaughterEnterInformationModal"; +import { AppContext } from "../../../../contexts/AppContext"; +import { slaughterUpdateNoneRecieptService } from "../../services/slaughter-update-none-recipt"; +import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl"; + +export const SlaughterEnterInformationOperation = ({ item, updateTable }) => { + const dispatch = useDispatch(); + const [openNotif] = useContext(AppContext); + const [anchorEl, setAnchorEl] = useState(null); + + const handleClick = (event) => { + setAnchorEl(event.currentTarget); + }; + + const handleClose = () => { + setAnchorEl(null); + }; + + const open = Boolean(anchorEl); + const id = open ? "popover" : undefined; + + const handleSubmit = (values) => { + dispatch( + slaughterUpdateNoneRecieptService({ + non_receipt: true, + main_non_receipt: true, + non_receipt_message: values.message, + key: item.key, + role: getRoleFromUrl(), + }) + ).then((r) => { + dispatch(CLOSE_MODAL()); + if (r.payload.error) { + openNotif({ + vertical: "top", + horizontal: "center", + msg: r.payload.error, + severity: "error", + }); + } else { + handleClose(); + updateTable(); + openNotif({ + vertical: "top", + horizontal: "center", + msg: "عملیات عدم وصول با موفقیت انجام شد.", + severity: "success", + }); + } + }); + }; + + return ( + + + + + + + + { + handleClose(); + dispatch( + DRAWER({ + title: "انجام عملیات", + top: !(window.innerWidth <= 600), + bottom: window.innerWidth <= 600, + content: ( + + ), + }) + ); + }} + > + + + + + 0} + onClick={() => { + handleClose(); + dispatch( + OPEN_MODAL({ + title: "عدم وصول", + content: ( + + ), + }) + ); + }} + aria-label="delete" + color="primary" + > + + + + + + + ); +}; diff --git a/src/features/slaughter-house/components/slaughter-enter-none-receipt/SlaughterEnterNoneReciept.js b/src/features/slaughter-house/components/slaughter-enter-none-receipt/SlaughterEnterNoneReciept.js new file mode 100644 index 0000000..80f2ac3 --- /dev/null +++ b/src/features/slaughter-house/components/slaughter-enter-none-receipt/SlaughterEnterNoneReciept.js @@ -0,0 +1,473 @@ +import { useContext, useEffect, useState, useMemo, useCallback } from "react"; +import { useDispatch, useSelector } from "react-redux"; +import { + LOADING_END, + LOADING_START, +} from "../../../../lib/redux/slices/appSlice"; +import axios from "axios"; +import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl"; +import { Button, TextField, Tooltip } from "@mui/material"; +import { VetFarmEditTrafficCode } from "../../../vet-farm/components/vet-farm-edit-traffic-code/VetFarmEditTrafficCode"; +import { format } from "date-fns-jalali"; +import { SlaughterNoneRecieptOperation } from "../slaughter-none-reciept-operation/SlaughterNoneRecieptOperation"; +import { Grid } from "../../../../components/grid/Grid"; +import { SPACING } from "../../../../data/spacing"; +import moment from "moment"; +import { RiFileExcel2Fill, RiSearchLine } from "react-icons/ri"; +import ResponsiveTable from "../../../../components/responsive-table/ResponsiveTable"; +import { AppContext } from "../../../../contexts/AppContext"; +import { DatePicker } from "@mui/x-date-pickers"; +import ShowImage from "../../../../components/show-image/ShowImage"; +import { formatJustDate } from "../../../../utils/formatTime"; +import { checkPathStartsWith } from "../../../../utils/checkPathStartsWith"; + +// Constants +const ROLES = { + PROVINCE_OPERATOR: "ProvinceOperator", + SUPER_ADMIN: "SuperAdmin", + ADMIN_X: "AdminX", + SUPPORTER: "Supporter", + VET_SUPERVISOR: "VetSupervisor", + VET_FARM: "VetFarm", + CITY_VET: "CityVet", +}; + +const KILL_TYPES = { + FREEZING: "انجماد", + EXPORT: "صادرات", + NORMAL: "عادی", +}; + +const SALE_TYPES = { + FREE: "آزاد", + GOVERNMENT: "دولتی", +}; + +const NON_RECEIPT_STATES = { + ACCEPTED: "تایید شده", + REJECTED: "رد شده", + PENDING: "درانتظار تایید", +}; + +const DEFAULT_PER_PAGE = 10; +const DEFAULT_PAGE = 1; + +// Helper functions +const formatDate = (date) => { + if (!date) return "-"; + return format(new Date(date), "yyyy/MM/dd"); +}; + +const formatCurrency = (value) => { + return value ? `${value.toLocaleString()} ﷼` : "-"; +}; + +const formatNumber = (value) => { + return value ? value.toLocaleString() : "-"; +}; + +const formatUserInfo = (name, mobile) => { + return name && mobile ? `${name} (${mobile})` : "-"; +}; + +const getKillType = (item) => { + if (item?.poultryRequest?.freezing) return KILL_TYPES.FREEZING; + if (item?.poultryRequest?.export) return KILL_TYPES.EXPORT; + return KILL_TYPES.NORMAL; +}; + +const getSaleType = (item) => { + return item?.poultryRequest?.freeSaleInProvince + ? SALE_TYPES.FREE + : SALE_TYPES.GOVERNMENT; +}; + +const getNonReceiptState = (item) => { + if (item?.nonReceiptState === "accepted") return NON_RECEIPT_STATES.ACCEPTED; + if (item?.nonReceiptState === "rejected") return NON_RECEIPT_STATES.REJECTED; + return NON_RECEIPT_STATES.PENDING; +}; + +const formatCheckerInfo = (checker, mobile) => { + return checker && mobile ? `${checker}(${mobile})` : "-"; +}; + +const buildApiUrl = (params) => { + const { textValue, role, date1, date2, page, perPage, roleKey } = params; + const baseUrl = "non-receipt-request/"; + const queryParams = new URLSearchParams({ + search: "filter", + value: textValue || "", + role: role || "", + date1: date1 || "", + date2: date2 || "", + page: page || DEFAULT_PAGE, + page_size: perPage || DEFAULT_PER_PAGE, + }); + + if (roleKey) { + queryParams.append("role_key", roleKey); + } + + return `${baseUrl}?${queryParams.toString()}`; +}; + +const buildExcelUrl = (params) => { + const { baseURL, role, roleKey, userKey, textValue, date1, date2 } = params; + const queryParams = new URLSearchParams({ + role: role || "", + key: userKey || "", + search: "filter", + value: textValue || "", + date1: date1 || "", + date2: date2 || "", + }); + + if (roleKey) { + queryParams.append("role_key", roleKey); + } + + return `${baseURL}non_receipt_request_excel/?${queryParams.toString()}`; +}; + +const isTrafficCodeEditable = (role, item) => { + const adminRoles = [ + ROLES.PROVINCE_OPERATOR, + ROLES.SUPER_ADMIN, + ROLES.ADMIN_X, + ROLES.SUPPORTER, + ROLES.VET_SUPERVISOR, + ]; + + if (adminRoles.includes(role)) { + return true; + } + + const vetRoles = [ROLES.VET_FARM, ROLES.CITY_VET]; + return ( + item.trash !== true && + item.assignmentStateArchive === "pending" && + !item?.clearanceCode && + vetRoles.includes(role) + ); +}; + +export const SlaughterEnterNoneReciept = () => { + const [, , selectedDate1, setSelectedDate1, selectedDate2, setSelectedDate2] = + useContext(AppContext); + const [openNotif] = useContext(AppContext); + + // Redux + const userKey = useSelector((state) => state.userSlice.userProfile.key); + const selectedSubUser = useSelector( + (state) => state.userSlice.selectedSubUser + ); + const dispatch = useDispatch(); + + // State + const [data, setData] = useState([]); + const [totalRows, setTotalRows] = useState(0); + const [perPage, setPerPage] = useState(DEFAULT_PER_PAGE); + const [textValue, setTextValue] = useState(""); + const [page, setPage] = useState(DEFAULT_PAGE); + const [tableData, setTableData] = useState([]); + + // Memoized values + const currentRole = useMemo(() => getRoleFromUrl(), []); + const roleKey = useMemo( + () => (checkPathStartsWith("slaughter") ? selectedSubUser?.key || "" : ""), + [selectedSubUser?.key] + ); + + // Fetch API data + const fetchApiData = useCallback( + async (pageNumber = page) => { + dispatch(LOADING_START()); + try { + const url = buildApiUrl({ + textValue, + role: currentRole, + date1: selectedDate1, + date2: selectedDate2, + page: pageNumber || DEFAULT_PAGE, + perPage, + roleKey, + }); + + const response = await axios.get(url); + setData(response.data.results); + setTotalRows(response.data.count); + } catch (error) { + console.error("Error fetching data:", error); + } finally { + dispatch(LOADING_END()); + } + }, + [ + textValue, + currentRole, + selectedDate1, + selectedDate2, + perPage, + roleKey, + page, + dispatch, + ] + ); + + // Update table callback + const updateTable = useCallback(() => { + fetchApiData(DEFAULT_PAGE); + setPage(DEFAULT_PAGE); + }, [fetchApiData]); + + // Handlers + const handlePageChange = (newPage) => { + fetchApiData(newPage); + setPage(newPage); + }; + + const handlePerRowsChange = (newPerRows) => { + setPerPage(newPerRows); + setPage(DEFAULT_PAGE); + }; + + const handleSubmit = async (event) => { + event.preventDefault(); + await fetchApiData(DEFAULT_PAGE); + setPage(DEFAULT_PAGE); + }; + + const handleTextChange = (event) => { + setTextValue(event.target.value); + }; + + const handleDateChange1 = (date) => { + if (date) { + setSelectedDate1(moment(date).format("YYYY-MM-DD")); + } + }; + + const handleDateChange2 = (date) => { + if (date) { + setSelectedDate2(moment(date).format("YYYY-MM-DD")); + } + }; + + const handleExcelDownload = useCallback(() => { + openNotif({ + vertical: "top", + horizontal: "center", + msg: "فایل اکسل در حال دانلود می باشد، این علمیات ممکن است زمان بر باشد لطفا صبر کنید.", + severity: "success", + }); + + const excelUrl = buildExcelUrl({ + baseURL: axios.defaults.baseURL, + role: currentRole, + roleKey, + userKey, + textValue, + date1: selectedDate1, + date2: selectedDate2, + }); + + window.location.href = excelUrl; + }, [ + openNotif, + currentRole, + roleKey, + userKey, + textValue, + selectedDate1, + selectedDate2, + ]); + + // Initial data fetch and refetch when filters change + useEffect(() => { + fetchApiData(DEFAULT_PAGE); + setPage(DEFAULT_PAGE); + }, [selectedDate1, selectedDate2, perPage, roleKey, selectedSubUser?.key]); + + // Transform data to table format + useEffect(() => { + const transformedData = data?.map((item, i) => { + const rowNumber = + page === DEFAULT_PAGE ? i + 1 : i + perPage * (page - 1) + 1; + + return [ + rowNumber, + , + , + item?.barCode || "-", + , + formatCurrency(item?.amount), + formatDate(item?.poultryRequest?.sendDate), + formatUserInfo( + item.killhouseUser?.name, + item.killhouseUser?.killHouseOperator?.user?.mobile + ), + item?.killer + ? formatUserInfo( + item.killer?.name, + item.killer?.killHouseOperator?.user?.mobile + ) + : "-", + formatUserInfo( + item.poultryRequest?.poultry?.unitName, + item.poultryRequest?.poultry?.user?.mobile + ), + item?.poultryRequest?.age || "-", + formatNumber(item.quantity), + formatNumber(item?.weightInfo?.weight), + formatCurrency(item?.poultryRequest?.amount), + formatCurrency(item?.weightInfo?.killHousePrice), + `${item.addCar?.driver?.typeCar || ""} ${ + item.addCar?.driver?.pelak || "" + }`.trim() || "-", + formatUserInfo( + item.addCar?.driver?.driverName, + item.addCar?.driver?.driverMobile + ), + formatNumber(item.vetAcceptedRealQuantity), + formatNumber(item.vetAcceptedRealWeight), + item?.poultryRequest?.orderCode || "-", + getKillType(item), + getSaleType(item), + getNonReceiptState(item), + item?.nonReceiptMessage || "-", + formatJustDate(item?.nonReceiptCheckDate) || "-", + formatCheckerInfo( + item?.nonReceiptChecker, + item?.nonReceiptCheckerMobile + ), + item?.message || "-", + , + ]; + }); + + setTableData(transformedData || []); + }, [data, page, perPage, currentRole, fetchApiData, updateTable]); + + // Table columns + const tableColumns = [ + "ردیف", + "بارنامه خالی", + "بارنامه پر", + "کدبار", + "کد بهداشتی حمل و نقل", + "قیمت مرغ زنده‌ی بار", + "تاریخ کشتار", + "خریدار", + "کشتارکن اختصاصی", + "مرغدار", + "سن مرغ", + "تعداد اولیه", + "وزن اولیه بار (کیلوگرم)", + "قیمت مرغدار", + "قیمت کشتارگاه", + "ماشین", + "راننده", + "تحویلی دامپزشک (قطعه)", + "وزن تحویلی دامپزشک (کیلوگرم)", + "کدسفارش کشتار", + "نوع کشتار", + "نوع فروش", + "وضعیت عدم وصول", + "توضیحات کشتارگاه", + "تاریخ (تایید / رد)", + "بررسی کننده", + "توضیحات بررسی کننده", + "عملیات", + ]; + + return ( + + + + + ( + + )} + value={selectedDate1} + onChange={handleDateChange1} + /> + + + ( + + )} + value={selectedDate2} + onChange={handleDateChange2} + /> + +
    + + + + + + +
    +
    + + +
    + ); +}; diff --git a/src/features/slaughter-house/components/slaughter-export-options/SlaughterExportOptions.js b/src/features/slaughter-house/components/slaughter-export-options/SlaughterExportOptions.js new file mode 100644 index 0000000..0c1b6a0 --- /dev/null +++ b/src/features/slaughter-house/components/slaughter-export-options/SlaughterExportOptions.js @@ -0,0 +1,132 @@ +import React, { useContext, useState } from "react"; +import { Grid } from "../../../../components/grid/Grid"; +import { IconButton, Popover, Tooltip } from "@mui/material"; +import TuneIcon from "@mui/icons-material/Tune"; +import { DRAWER } from "../../../../lib/redux/slices/appSlice"; +import { SlaughterSubmitExport } from "../slaughter-submit-export/SlaughterSubmitExport"; +import EditIcon from "@mui/icons-material/Edit"; +import { useDispatch } from "react-redux"; +import { slaughterDeleteFreeBuyService } from "../../services/slaughter-delete-free-buy"; +import { AppContext } from "../../../../contexts/AppContext"; +import DeleteIcon from "@mui/icons-material/Delete"; + +export const SlaughterExportOptions = ({ item, updateTable }) => { + const dispatch = useDispatch(); + + const [anchorEl, setAnchorEl] = useState(null); + + const [openNotif] = useContext(AppContext); + const handleClick = (event) => { + setAnchorEl(event.currentTarget); + }; + + const handleClose = () => { + setAnchorEl(null); + }; + + const open = Boolean(anchorEl); + const id = open ? "popover" : undefined; + + return ( + + + + + +
    + + + { + handleClose(); + dispatch( + DRAWER({ + title: "ویرایش درخواست صادرات", + content: ( + + ), + right: !(window.innerWidth <= 600), + bottom: window.innerWidth <= 600, + }) + ); + }} + > + + + + + + { + dispatch(slaughterDeleteFreeBuyService(item.key)).then( + (r) => { + if (r.error) { + openNotif({ + vertical: "top", + horizontal: "center", + msg: r.error, + severity: "error", + }); + } else { + updateTable(); + openNotif({ + vertical: "top", + horizontal: "center", + msg: "عملیات با موفقیت انجام شد.", + severity: "success", + }); + } + } + ); + }} + > + + + + + {/* + + + + */} + +
    +
    +
    + ); +}; diff --git a/src/features/slaughter-house/components/slaughter-export/SlaughterExport.js b/src/features/slaughter-house/components/slaughter-export/SlaughterExport.js new file mode 100644 index 0000000..2634b4d --- /dev/null +++ b/src/features/slaughter-house/components/slaughter-export/SlaughterExport.js @@ -0,0 +1,383 @@ +import React, { useContext, useEffect, useState } from "react"; +import { AppContext } from "../../../../contexts/AppContext"; +import moment from "moment"; +import axios from "axios"; +import { + DRAWER, + LOADING_END, + LOADING_START, + OPEN_MODAL, +} from "../../../../lib/redux/slices/appSlice"; +import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl"; +import ResponsiveTable from "../../../../components/responsive-table/ResponsiveTable"; +import { Grid } from "../../../../components/grid/Grid"; +import { SPACING } from "../../../../data/spacing"; +import { useDispatch, useSelector } from "react-redux"; +import { Button, Tab, Tabs, TextField, Tooltip } from "@mui/material"; +import { DatePicker } from "@mui/x-date-pickers"; +import { slaughterGetExportAllowState } from "../../services/slaughter-get-export-allow-state"; +import { SlaughterSubmitExport } from "../slaughter-submit-export/SlaughterSubmitExport"; +import { formatJustDate, formatTime } from "../../../../utils/formatTime"; +import { SlaughterExportOptions } from "../slaughter-export-options/SlaughterExportOptions"; +import { EnterAuthCodeDirectBuy } from "../enter-auth-code-direct-buy/EnterAuthCodeDirectBuy"; +import { RiFileExcel2Fill } from "react-icons/ri"; +import { RiSearchLine } from "react-icons/ri"; +import { checkPathStartsWith } from "../../../../utils/checkPathStartsWith"; + +export const SlaughterExport = () => { + const dispatch = useDispatch(); + const [exportData, setExportData] = useState(); + const selectedSubUser = useSelector( + (state) => state.userSlice.selectedSubUser + ); + useEffect(() => { + dispatch( + slaughterGetExportAllowState({ + role_key: checkPathStartsWith("slaughter") + ? selectedSubUser?.key || "" + : "", + }) + ).then((r) => { + setExportData(r.payload.data); + }); + }, [selectedSubUser?.key]); + + const [activeTab, setActiveTab] = useState(0); + + const handleTabChange = (event, newValue) => { + setActiveTab(newValue); + }; + + const [, , selectedDate1, setSelectedDate1, selectedDate2, setSelectedDate2] = + useContext(AppContext); + + useEffect(() => { + const currentDate = moment(new Date()).format("YYYY-MM-DD"); + setSelectedDate1(currentDate); + setSelectedDate2(currentDate); + }, []); + + const handleTextChange = (event) => { + setTextValue(event.target.value); + }; + + const [data, setData] = useState([]); + const [totalRows, setTotalRows] = useState(0); + const [perPage, setPerPage] = useState(10); + const [textValue, setTextValue] = useState(""); + const [page, setPage] = useState(1); + const [tableData, setTableData] = useState([]); + const [tableDataArchive, setTableDataArchive] = useState([]); + + const fetchApiData = async (page) => { + dispatch(LOADING_START()); + const response = await axios.get( + `kill_request/?export=true&type=${ + activeTab === 0 ? "pending" : "archive" + }&search=filter&value=${textValue}&role=${getRoleFromUrl()}${ + checkPathStartsWith("slaughter") + ? `&role_key=${selectedSubUser?.key}` + : "" + }&date1=${selectedDate1}&date2=${selectedDate2}&page=${page}&page_size=${perPage}` + ); + dispatch(LOADING_END()); + setData(response.data.results); + setTotalRows(response.data.count); + }; + + const handlePageChange = (page) => { + fetchApiData(page); + setPage(page); + }; + + const handlePerRowsChange = (perRows) => { + setPerPage(perRows); + setPage(1); + }; + + const updateTable = () => { + fetchApiData(page !== 0 ? page : 1); + }; + + useEffect(() => { + fetchApiData(1); + }, [selectedSubUser?.key, selectedDate1, selectedDate2, perPage, activeTab]); + + const getItemState = (item) => { + let state = ""; + if (item.exportState === "pending") { + state = "در انتظار تایید"; + } else if (item.exportState === "rejected") { + state = "رد شده"; + } else if (item.exportState === "accepted") { + state = "تایید شده"; + } else if (item.exportState === "deleted") { + state = "حذف شده"; + } + return state; + }; + + useEffect(() => { + const d = data?.map((item, i) => { + return [ + page === 1 ? i + 1 : i + perPage * (page - 1) + 1, + formatJustDate(item?.createDate), + formatJustDate(item.reciveDate), + `${item.killHouse.name} (${item.killHouse.killHouseOperator.user.mobile})`, + item?.slaughterHouse + ? item?.slaughterHouse?.name + : item?.killHouse?.name, + item?.exportCountry, + `${item?.poultry?.userprofile?.fullName} (${item?.poultry?.userprofile?.mobile})`, + item.killCapacity, + item.IndexWeight, + (item.IndexWeight * item.killCapacity)?.toLocaleString(), + <> + {item?.inputDirectBuyingCode ? ( + item?.inputDirectBuyingCode + ) : ( + + )} + , + getItemState(item), + + activeTab === 0 ? ( + + ) : ( + "-" + ), + ]; + }); + + setTableData(d); + + const a = data?.map((item, i) => { + return [ + page === 1 ? i + 1 : i + perPage * (page - 1) + 1, + formatJustDate(item?.createDate), + formatJustDate(item.reciveDate), + `${item.killHouse.name} (${item.killHouse.killHouseOperator.user.mobile})`, + item?.slaughterHouse + ? item?.slaughterHouse?.name + : item?.killHouse?.name, + item?.exportCountry, + `${item?.poultry?.userprofile?.fullName} (${item?.poultry?.userprofile?.mobile})`, + item.killCapacity, + item.IndexWeight, + (item.IndexWeight * item.killCapacity)?.toLocaleString(), + getItemState(item), + item?.acceptRejectDate ? formatTime(item?.acceptRejectDate) : "-", + item?.directBuyingMessage, + ]; + }); + + setTableDataArchive(a); + }, [data]); + + const handleSubmit = async (event) => { + event.preventDefault(); + dispatch(LOADING_START()); + + try { + const response = await axios.get( + `kill_request/?export=true&type=${ + activeTab === 0 ? "pending" : "archive" + }&role=${getRoleFromUrl()}${ + checkPathStartsWith("slaughter") + ? `&role_key=${selectedSubUser?.key}` + : "" + }&search=filter&value=${textValue}&date1=${selectedDate1}&date2=${selectedDate2}&page=${1}&page_size=${perPage}` + ); + setData(response.data.results); + setTotalRows(response.data.count); + dispatch(LOADING_END()); + } catch (error) { + console.error("Error fetching data:", error); + } + }; + const userKey = useSelector((state) => state.userSlice.userProfile.key); + + return ( + + + + + + + + + +
    + + + + + ( + + )} + value={selectedDate1} + onChange={(e) => { + setSelectedDate1(moment(e).format("YYYY-MM-DD")); + }} + /> + + + ( + + )} + value={selectedDate2} + onChange={(e) => { + setSelectedDate2(moment(e).format("YYYY-MM-DD")); + }} + /> + + {activeTab === 1 && ( + + + + + + + + )} + +
    + + {activeTab === 0 ? ( + + ) : ( + + )} +
    +
    + ); +}; diff --git a/src/features/slaughter-house/components/slaughter-factors/SlaughterFactors.js b/src/features/slaughter-house/components/slaughter-factors/SlaughterFactors.js new file mode 100644 index 0000000..01cb164 --- /dev/null +++ b/src/features/slaughter-house/components/slaughter-factors/SlaughterFactors.js @@ -0,0 +1,285 @@ +import { useContext, useEffect, useState } from "react"; +import { useDispatch, useSelector } from "react-redux"; +import { AdvancedTable } from "../../../../components/advanced-table/AdvancedTable"; +import { slaughterFactorsService } from "../../services/slaughter-factors"; +import PaymentIcon from "@mui/icons-material/Payment"; +import { Button, IconButton, TextField, Typography } from "@mui/material"; +import { + CLOSE_MODAL, + DRAWER, + OPEN_MODAL, +} from "../../../../lib/redux/slices/appSlice"; +import { SlaughterPayFactor } from "../slaughter-pay-factor/SlaughterPayFactor"; +import { Grid } from "../../../../components/grid/Grid"; +import { slaughterDeleteFactorService } from "../../services/slaughter-delete-factor"; +import { AppContext } from "../../../../contexts/AppContext"; +import DeleteIcon from "@mui/icons-material/Delete"; +import { SPACING } from "../../../../data/spacing"; +import { formatJustDate } from "../../../../utils/formatTime"; +import { DatePicker } from "@mui/x-date-pickers"; +import moment from "moment/moment"; + +export const SlaughterFactorsComponent = () => { + const dispatch = useDispatch(); + const [openNotif] = useContext(AppContext); + const [, , selectedDate1, setSelectedDate1, selectedDate2, setSelectedDate2] = + useContext(AppContext); + + useEffect(() => { + const currentDate = moment(new Date()).format("YYYY-MM-DD"); + setSelectedDate1(currentDate); + setSelectedDate2(currentDate); + }, []); + const { slaughterFactors } = useSelector((state) => state.slaughterSlice); + const [dataTable, setDataTable] = useState([]); + const [archiveDataTable, setArchiveDataTable] = useState([]); + + useEffect(() => { + const d = slaughterFactors + ?.filter((item) => item.state === "pending") + .map((item) => { + let state; + switch (item.state) { + case "pending": + state = "در انتظار پرداخت"; + break; + case "paid": + state = "پرداخت شده"; + break; + case "unpaid": + state = "پرداخت نشده"; + break; + default: + state = "در انتظار پرداخت"; + } + return [ + item?.killRequest?.slaughterHouse?.name + ? item?.killRequest?.slaughterHouse?.name + : item?.killRequest?.killHouse?.name, + formatJustDate(item?.createDate), + item?.killRequest?.IndexWeight, + item.killRequest.oldChickenBreed + ? item.killRequest.oldChickenBreed + : item?.killRequest?.chickenBreed, + item.killRequest.chickenBreed, + item.killRequest.provinceQuantity + ? item.killRequest.provinceQuantity.toLocaleString() + : item.killRequest.killCapacity?.toLocaleString(), + item.killRequest.provinceQuantity + ? item.killRequest.killCapacity?.toLocaleString() + : 0, + item?.amount.toLocaleString() + " ﷼", + item?.minimumAmount.toLocaleString() + " ﷼", + state, + { + dispatch( + DRAWER({ + title: "پرداخت فاکتور", + right: !(window.innerWidth <= 600), + bottom: window.innerWidth <= 600, + content: , + }) + ); + }} + > + + , + { + dispatch( + OPEN_MODAL({ + title: "لغو سفارش", + content: ( + + + + در صورت لغو فاکتور درخواست اولیه شما هم لغو می گردد. + + + + + + + ), + }) + ); + }} + > + + , + ]; + }); + setDataTable(d); + + const c = slaughterFactors + ?.filter((item) => item.state === "paid" || item.state === "unpaid") + .map((item) => { + let state; + switch (item.state) { + case "pending": + state = "در انتظار پرداخت"; + break; + case "paid": + state = "پرداخت شده"; + break; + case "unpaid": + state = "پرداخت نشده"; + break; + default: + state = "در انتظار پرداخت"; + } + return [ + item?.killRequest?.slaughterHouse?.name + ? item?.killRequest?.slaughterHouse?.name + : item?.killRequest?.killHouse?.name, + formatJustDate(item?.createDate), + item?.killRequest?.IndexWeight, + item.killRequest.oldChickenBreed + ? item.killRequest.oldChickenBreed + : item?.killRequest?.chickenBreed, + item.killRequest.chickenBreed, + item.killRequest.provinceQuantity + ? item.killRequest.provinceQuantity.toLocaleString() + : item.killRequest.killCapacity?.toLocaleString(), + item.killRequest.provinceQuantity + ? item.killRequest.killCapacity?.toLocaleString() + : 0, + item?.amount.toLocaleString() + " ﷼", + item?.minimumAmount.toLocaleString() + " ﷼", + state, + ]; + }); + setArchiveDataTable(c); + }, [slaughterFactors]); + + useEffect(() => { + dispatch(slaughterFactorsService({ selectedDate1, selectedDate2 })); + }, [selectedDate1, selectedDate2]); + + return ( + + + + + فاکتور همراه با ثبت درخواست کشتار + + + ( + + )} + value={selectedDate1} + onChange={(e) => { + setSelectedDate1(moment(e).format("YYYY-MM-DD")); + }} + /> + + + ( + + )} + value={selectedDate2} + onChange={(e) => { + setSelectedDate2(moment(e).format("YYYY-MM-DD")); + }} + /> + + + } + columns={[ + "کاربر", + "تاریخ درخواست", + "وزن", + "نژاد درخواستی", + "نژاد تایید شده", + "تعداد درخواستی", + "تعداد تایید شده", + "مبلغ پیش فاکتور", + "حداقل پرداختی (70%)", + "وضعیت", + "پرداخت", + "لغو سفارش", + ]} + data={dataTable} + /> + + + + + + ); +}; diff --git a/src/features/slaughter-house/components/slaughter-final-factors/SlaughterFinalFactors.js b/src/features/slaughter-house/components/slaughter-final-factors/SlaughterFinalFactors.js new file mode 100644 index 0000000..bb55827 --- /dev/null +++ b/src/features/slaughter-house/components/slaughter-final-factors/SlaughterFinalFactors.js @@ -0,0 +1,130 @@ +import { useContext, useEffect, useState } from "react"; +import { useDispatch, useSelector } from "react-redux"; +import { AdvancedTable } from "../../../../components/advanced-table/AdvancedTable"; +import PaymentIcon from "@mui/icons-material/Payment"; +import { IconButton, TextField, Typography } from "@mui/material"; +import { DRAWER } from "../../../../lib/redux/slices/appSlice"; +import { SlaughterPayFactor } from "../slaughter-pay-factor/SlaughterPayFactor"; +import { slaughterFinalFactorsService } from "../../services/slaughter-final-factors"; +import { Grid } from "../../../../components/grid/Grid"; +import { DatePicker } from "@mui/x-date-pickers"; +import { AppContext } from "../../../../contexts/AppContext"; +import { SPACING } from "../../../../data/spacing"; +import moment from "moment/moment"; + +export const SlaughterFinalFactorsComponent = () => { + const dispatch = useDispatch(); + const { slaughterFinalFactors } = useSelector( + (state) => state.slaughterSlice + ); + const [, , selectedDate1, setSelectedDate1, selectedDate2, setSelectedDate2] = + useContext(AppContext); + + useEffect(() => { + const currentDate = moment(new Date()).format("YYYY-MM-DD"); + setSelectedDate1(currentDate); + setSelectedDate2(currentDate); + }, []); + const [dataFinalFactorsTable, setDataFinalFactorsTable] = useState([]); + + useEffect(() => { + const c = slaughterFinalFactors?.map((item) => { + let state; + switch (item.paidState) { + case "pending": + state = "در انتظار پرداخت"; + break; + case "paid": + state = "پرداخت شده"; + break; + default: + state = "در انتظار پرداخت"; + } + return [ + item?.factorBarCode, + state, + item?.factorFee.toLocaleString() + " ﷼", + item?.totalPrice.toLocaleString() + " ﷼", + item?.totalWeight, + { + dispatch( + DRAWER({ + title: "پرداخت فاکتور", + right: !(window.innerWidth <= 600), + bottom: window.innerWidth <= 600, + content: ( + + ), + }) + ); + }} + > + + , + ]; + }); + setDataFinalFactorsTable(c); + }, [slaughterFinalFactors]); + + useEffect(() => { + dispatch(slaughterFinalFactorsService({ selectedDate1, selectedDate2 })); + }, [selectedDate1, selectedDate2]); + + return ( + + + + + فاکتور نهایی + + + ( + + )} + value={selectedDate1} + onChange={(e) => { + setSelectedDate1(moment(e).format("YYYY-MM-DD")); + }} + /> + + + ( + + )} + value={selectedDate2} + onChange={(e) => { + setSelectedDate2(moment(e).format("YYYY-MM-DD")); + }} + /> + + + } + columns={[ + "کدبار", + "وضعیت", + "قیمت هرکیلو", + "قابل پرداخت", + "وزن", + "پرداخت", + ]} + data={dataFinalFactorsTable} + /> + + + ); +}; diff --git a/src/features/slaughter-house/components/slaughter-free-bars-alives-operations/SlaughterFreeBarsAlivesOperations.js b/src/features/slaughter-house/components/slaughter-free-bars-alives-operations/SlaughterFreeBarsAlivesOperations.js new file mode 100644 index 0000000..9eea470 --- /dev/null +++ b/src/features/slaughter-house/components/slaughter-free-bars-alives-operations/SlaughterFreeBarsAlivesOperations.js @@ -0,0 +1,144 @@ +import { Button, IconButton, Popover } from "@mui/material"; +import { useState } from "react"; +import { useDispatch } from "react-redux"; +import { Grid } from "../../../../components/grid/Grid"; +import { DRAWER, OPEN_MODAL } from "../../../../lib/redux/slices/appSlice"; +import { slaughterDeleteInventoryFreeBarService } from "../../services/slaughter-delete-inventory-free-bar"; +import { SlaughterSubmitFreeBar } from "../slaughter-submit-free-bar/SlaughterSubmitFreeBar"; +import { SlaughterSubmitRealInventoryFreeBar } from "../slaughter-submit-real-inventory-free-bar/SLaughterSubmitRealInverntoryFreeBar"; +import TuneIcon from "@mui/icons-material/Tune"; +import { fetchSlaughterBroadcastAndProducts } from "../../services/handle-fetch-slaughter-products"; + +export const SlaughterFreeBarsAlivesOperations = ({ + item, + updateTable, + barState, + type, +}) => { + const dispatch = useDispatch(); + + const [anchorEl, setAnchorEl] = useState(null); + + const handleClick = (event) => { + setAnchorEl(event.currentTarget); + }; + + const handleClose = () => { + setAnchorEl(null); + }; + + const open = Boolean(anchorEl); + const id = open ? "popover" : undefined; + + const ableToSeeDelete = () => { + if (type === "carcass" || item?.buyType !== "live") { + return true; + } else { + if (!barState && !item.weightOfCarcasses) { + return true; + } else { + return false; + } + } + }; + + const isAbleToSee = + item?.registerType === "automatic" + ? false + : item.weightOfCarcasses && !barState && item?.buyType === "live"; + + return ( +
    + + + + +
    + + {barState === "entered" && item?.registerType === "automatic" && ( + + )} + {(barState === "entered" + ? item?.registerType !== "automatic" + : true) && ( + + )} + + {ableToSeeDelete() && item?.registerType !== "automatic" && ( + + )} + +
    +
    +
    + ); +}; diff --git a/src/features/slaughter-house/components/slaughter-free-bars-operations/SlaughterFreeBarsOperations.js b/src/features/slaughter-house/components/slaughter-free-bars-operations/SlaughterFreeBarsOperations.js new file mode 100644 index 0000000..75b4f41 --- /dev/null +++ b/src/features/slaughter-house/components/slaughter-free-bars-operations/SlaughterFreeBarsOperations.js @@ -0,0 +1,178 @@ +import { + IconButton, + Popover, + List, + ListItem, + ListItemButton, + Typography, + ListItemIcon, +} from "@mui/material"; +import { useState } from "react"; +import { useDispatch } from "react-redux"; +import { DRAWER, OPEN_MODAL } from "../../../../lib/redux/slices/appSlice"; +import { slaughterDeleteInventoryFreeBarService } from "../../services/slaughter-delete-inventory-free-bar"; +import { SlaughterSubmitFreeBar } from "../slaughter-submit-free-bar/SlaughterSubmitFreeBar"; +import { SlaughterSubmitRealInventoryFreeBar } from "../slaughter-submit-real-inventory-free-bar/SLaughterSubmitRealInverntoryFreeBar"; +import TuneIcon from "@mui/icons-material/Tune"; +import { fetchSlaughterBroadcastAndProducts } from "../../services/handle-fetch-slaughter-products"; +import EditOutlinedIcon from "@mui/icons-material/EditOutlined"; +import Inventory2OutlinedIcon from "@mui/icons-material/Inventory2Outlined"; +import DeleteOutlineOutlinedIcon from "@mui/icons-material/DeleteOutlineOutlined"; + +export const SlaughterFreeBarsOperations = ({ + item, + updateTable, + barState, + type, +}) => { + const dispatch = useDispatch(); + + const [anchorEl, setAnchorEl] = useState(null); + + const handleClick = (event) => { + setAnchorEl(event.currentTarget); + }; + + const handleClose = () => { + setAnchorEl(null); + }; + + const open = Boolean(anchorEl); + const id = open ? "popover" : undefined; + + const ableToSeeUpdate = () => { + if (item?.buyType === "live") { + return !item.weightOfCarcasses && !barState; + } else { + return false; + } + }; + const ableToSeeDelete = () => { + if (type === "carcass" || item?.buyType !== "live") { + return true; + } else { + if (!barState && !item.weightOfCarcasses) { + return true; + } else { + return false; + } + } + }; + + const isAbleToSee = + item?.registerType === "automatic" + ? false + : item.weightOfCarcasses && !barState && item?.buyType === "live"; + + return ( +
    + + + + + + {(ableToSeeUpdate() || item?.registerType === "automatic") && ( + + { + handleClose(); + dispatch( + DRAWER({ + right: !(window.innerWidth <= 600), + bottom: window.innerWidth <= 600, + title: "ویرایش بار آزاد", + content: ( + + ), + }) + ); + }} + > + + + + ویرایش + + + )} + {barState && item?.registerType === "manual" && ( + + { + handleClose(); + dispatch( + OPEN_MODAL({ + title: "ثبت اطلاعات لاشه ورودی به انبار", + content: ( + + ), + }) + ); + }} + > + + + + + {barState === "entered" ? "ویرایش" : "ورود به انبار"} + + + + )} + + {ableToSeeDelete() && item?.registerType !== "automatic" && ( + + { + handleClose(); + dispatch( + slaughterDeleteInventoryFreeBarService(item.key) + ).then(() => { + updateTable(); + dispatch(fetchSlaughterBroadcastAndProducts()); + }); + }} + > + + + + + حذف + + + + )} + + +
    + ); +}; diff --git a/src/features/slaughter-house/components/slaughter-free-buy-archive/SlaughterFreeBuyArchive.js b/src/features/slaughter-house/components/slaughter-free-buy-archive/SlaughterFreeBuyArchive.js new file mode 100644 index 0000000..81ff971 --- /dev/null +++ b/src/features/slaughter-house/components/slaughter-free-buy-archive/SlaughterFreeBuyArchive.js @@ -0,0 +1,215 @@ +import { Tooltip } from "@mui/material"; +import { Button, TextField } from "@mui/material"; +import { DatePicker } from "@mui/x-date-pickers"; +import axios from "axios"; +import moment from "moment/moment"; +import { useContext, useEffect, useState } from "react"; +import { RiFileExcel2Fill } from "react-icons/ri"; +import { useDispatch, useSelector } from "react-redux"; +import { Grid } from "../../../../components/grid/Grid"; +import { AppContext } from "../../../../contexts/AppContext"; +import { SPACING } from "../../../../data/spacing"; +import { formatJustDate } from "../../../../utils/formatTime"; +import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl"; +import ResponsiveTable from "../../../../components/responsive-table/ResponsiveTable"; +import { RiSearchLine } from "react-icons/ri"; +import { slaughterGetFreeBuyRequests } from "../../services/slaughter-get-free-buy-requests"; + +export const SlaughterFreeBuyArchive = () => { + const userKey = useSelector((state) => state.userSlice.userProfile.key); + const dispatch = useDispatch(); + const [, , selectedDate1, setSelectedDate1, selectedDate2, setSelectedDate2] = + useContext(AppContext); + useEffect(() => { + const currentDate = moment(new Date()).format("YYYY-MM-DD"); + setSelectedDate1(currentDate); + setSelectedDate2(currentDate); + }, []); + const [data, setData] = useState([]); + const [totalRows, setTotalRows] = useState(0); + const [perPage, setPerPage] = useState(10); + const [textValue, setTextValue] = useState(""); + const [page, setPage] = useState(1); + const [tableData, setTableData] = useState([]); + + const handleTextChange = (event) => { + setTextValue(event.target.value); + }; + + const fetchApiData = async (page) => { + try { + const response = await dispatch( + slaughterGetFreeBuyRequests({ + date1: selectedDate1, + date2: selectedDate2, + value: textValue || "", + type: "archive", + page: page, + page_size: perPage, + }) + ); + if (response.payload?.data) { + setData(response.payload.data.results); + setTotalRows(response.payload.data.count); + } + } catch (error) { + console.error("Error fetching data:", error); + } + }; + + const handlePageChange = (page) => { + fetchApiData(page, textValue); + }; + + const handlePerRowsChange = (perRows) => { + setPerPage(perRows); + setPage(1); + }; + + const handleSubmit = async (event) => { + event.preventDefault(); + try { + const response = await dispatch( + slaughterGetFreeBuyRequests({ + date1: selectedDate1, + date2: selectedDate2, + value: textValue || "", + type: "archive", + }) + ); + if (response.payload?.data) { + setData(response.payload.data.results); + setTotalRows(response.payload.data.count); + } + } catch (error) { + console.error("Error fetching data:", error); + } + }; + + const getItemState = (item) => { + let state = ""; + if (item.directBuyingState === "pending") { + state = "در انتظار تایید"; + } else if (item.directBuyingState === "rejected") { + state = "رد شده"; + } else if (item.directBuyingState === "accepted") { + state = "تایید شده"; + } else if (item.directBuyingState === "deleted") { + state = "حذف شده"; + } + return state; + }; + + useEffect(() => { + fetchApiData(1); + }, [selectedDate1, selectedDate2, perPage, textValue, dispatch]); + + useEffect(() => { + const d = data?.map((item, i) => { + return [ + page === 1 ? i + 1 : i + perPage * (page - 1) + 1, + formatJustDate(item?.createDate), + formatJustDate(item.reciveDate), + `${item.killHouse.name} (${item.killHouse.killHouseOperator.user.mobile})`, + item?.slaughterHouse + ? item?.slaughterHouse?.name + : item?.killHouse?.name, + `${item?.poultry?.userprofile?.fullName} (${item?.poultry?.userprofile?.mobile})`, + `${item.chickenBreed ? item.chickenBreed : "-"}`, + item.killCapacity, + item.IndexWeight, + (item.IndexWeight * item.killCapacity)?.toLocaleString(), + item?.inputDirectBuyingCode, + getItemState(item), + ]; + }); + + setTableData(d); + }, [data]); + + return ( + + +
    + + + + + ( + + )} + value={selectedDate1} + onChange={(e) => { + setSelectedDate1(moment(e).format("YYYY-MM-DD")); + }} + /> + ( + + )} + value={selectedDate2} + onChange={(e) => { + setSelectedDate2(moment(e).format("YYYY-MM-DD")); + }} + /> + + + + + + + +
    +
    + +
    + ); +}; diff --git a/src/features/slaughter-house/components/slaughter-free-buy-bars/SlaughterFreeBuyBars.js b/src/features/slaughter-house/components/slaughter-free-buy-bars/SlaughterFreeBuyBars.js new file mode 100644 index 0000000..54d523b --- /dev/null +++ b/src/features/slaughter-house/components/slaughter-free-buy-bars/SlaughterFreeBuyBars.js @@ -0,0 +1,776 @@ +import React, { useContext, useEffect, useState } from "react"; +import moment from "moment"; +import axios from "axios"; +import { useDispatch, useSelector } from "react-redux"; +import { + Button, + IconButton, + Tab, + Tabs, + TextField, + Tooltip, + Typography, +} from "@mui/material"; +import { DatePicker } from "@mui/x-date-pickers"; +import { Grid } from "../../../../components/grid/Grid"; +import { SPACING } from "../../../../data/spacing"; +import ResponsiveTable from "../../../../components/responsive-table/ResponsiveTable"; +import { + CLOSE_MODAL, + DRAWER, + LOADING_END, + LOADING_START, + OPEN_MODAL, +} from "../../../../lib/redux/slices/appSlice"; +import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl"; +import { AppContext } from "../../../../contexts/AppContext"; +import { SlaughterFreeBarsOperations } from "../slaughter-free-bars-operations/SlaughterFreeBarsOperations"; +import { formatJustDate } from "../../../../utils/formatTime"; +import ShowImage from "../../../../components/show-image/ShowImage"; +import { SlaughterSubmitFreeBar } from "../slaughter-submit-free-bar/SlaughterSubmitFreeBar"; +import { SlaughterHouseVetBarsOperation } from "../../../slaughter-house-vet/components/slaughter-house-vet-bars-operation/SlaughterHouseVetBarsOperation"; +import { RiFileExcel2Fill } from "react-icons/ri"; +import { slaughterGetProfile } from "../../services/slaughter-get-profile"; +import { vetFarmGetOutProvinceDashboard } from "../../../vet-farm/services/vet-farm-get-out-province-dashboard"; +import { RiSearchLine } from "react-icons/ri"; +import { CheckCleanceCode } from "../../../../components/check-clearance-code/ChechClearanceCode"; +import { slaughterDeleteInventoryFreeBarService } from "../../services/slaughter-delete-inventory-free-bar"; +import { slaughterReturnEnteredFreeBarService } from "../../services/slaughter-return-entered-free-bar"; +import DeleteIcon from "@mui/icons-material/Delete"; +import UndoIcon from "@mui/icons-material/Undo"; +import { checkPathStartsWith } from "../../../../utils/checkPathStartsWith"; + +export const SlaughterFreeBuyBars = ({ isBarManagemen }) => { + const [activeTab, setActiveTab] = useState(0); + const [tableDataArchive, setTableDataArchive] = useState([]); + const [data, setData] = useState([]); + const [totalRows, setTotalRows] = useState(0); + const [perPage, setPerPage] = useState(10); + const [textValue, setTextValue] = useState(""); + const [page, setPage] = useState(1); + const [tableData, setTableData] = useState([]); + const [openNotif] = useContext(AppContext); + const dispatch = useDispatch(); + const selectedSubUser = useSelector( + (state) => state.userSlice.selectedSubUser + ); + const userKey = useSelector((state) => state.userSlice.userProfile.key); + + const [dashboardData, setDashboardData] = useState([]); + const handleTabChange = (event, newValue) => { + setActiveTab(newValue); + }; + + const [, , selectedDate1, setSelectedDate1, selectedDate2, setSelectedDate2] = + useContext(AppContext); + const getDashboardData = () => { + dispatch( + vetFarmGetOutProvinceDashboard({ + date1: selectedDate1, + date2: selectedDate2, + search: "filter", + role: getRoleFromUrl(), + role_key: checkPathStartsWith("slaughter") + ? selectedSubUser?.key || "" + : "", + value: textValue, + type: activeTab === 0 ? "live" : "carcass", + }) + ).then((r) => { + setDashboardData(r.payload.data); + }); + }; + + useEffect(() => { + const currentDate = moment(new Date()).format("YYYY-MM-DD"); + setSelectedDate1(currentDate); + setSelectedDate2(currentDate); + }, []); + + const handleTextChange = (event) => { + setTextValue(event.target.value); + }; + + const { inventorySelectedKillHouse } = useSelector( + (state) => state.slaughterSlice + ); + + useEffect(() => { + dispatch( + slaughterGetProfile({ + role_key: checkPathStartsWith("slaughter") + ? selectedSubUser?.key || "" + : "", + }) + ); + }, [selectedSubUser?.key]); + + const fetchApiData = async (page) => { + dispatch(LOADING_START()); + const response = await axios.get( + `kill_house_free_bar/?type=${ + activeTab === 0 ? "live" : "carcass" + }&search=filter&value=${textValue}&role=${getRoleFromUrl()}${ + checkPathStartsWith("slaughter") + ? `&role_key=${selectedSubUser?.key}` + : "" + }&date1=${selectedDate1}&date2=${selectedDate2}&page=${page}&page_size=${perPage}&date_type=buy` + ); + getDashboardData(); + dispatch(LOADING_END()); + setData(response.data.results); + setTotalRows(response.data.count); + }; + + const handlePageChange = (page) => { + fetchApiData(page); + setPage(page); + }; + + const handlePerRowsChange = (perRows) => { + setPerPage(perRows); + setPage(1); + }; + + const updateTable = () => { + setPage(1); + fetchApiData(1); + getDashboardData(); + }; + + useEffect(() => { + fetchApiData(1); + }, [selectedSubUser?.key]); + + useEffect(() => { + const d = data?.map((item, i) => { + return [ + page === 1 ? i + 1 : i + perPage * (page - 1) + 1, + item?.registerType === "automatic" ? "سیستمی" : "دستی", + item?.barCode || "-", + formatJustDate(item.createDate), + `${item?.killHouse?.name} (${item?.killHouse?.killHouseOperator?.user?.mobile})`, + item?.exclusiveKiller + ? `${item?.exclusiveKiller?.name} (${item?.exclusiveKiller?.killHouseOperator?.user?.mobile})` + : "-", + item.buyType === "live" ? "مرغ زنده" : "لاشه", + item.poultryName, + `${item.province}/${item.city}`, + , + item.car || "-", + item?.driverName || "-", + + item?.driverMobile || "-", + formatJustDate(item.date), + + item.numberOfCarcasses.toLocaleString(), + item.weightOfCarcasses.toLocaleString(), + , + <> + {getRoleFromUrl() === "KillHouse" ? ( + + ) : ( + + )} + , + ]; + }); + + setTableData(d); + + const getInformation = (item) => { + if (getRoleFromUrl() === "AdminX" || getRoleFromUrl() === "SuperAdmin") { + return [ + + + { + dispatch( + OPEN_MODAL({ + title: "بازگشت بار", + content: ( + + + آیا از بازگشت بار از انبار اطمینان دارید؟ + + + + + + + + + + + ), + }) + ); + }} + > + + + + , + ]; + } else { + return []; + } + }; + + const a = data?.map((item, i) => { + return [ + page === 1 ? i + 1 : i + perPage * (page - 1) + 1, + item?.registerType === "automatic" ? "سیستمی" : "دستی", + item?.barCode || "-", + formatJustDate(item.createDate), + formatJustDate(item.registerDate) || "-", + `${item?.killHouse?.name} (${item?.killHouse?.killHouseOperator?.user?.mobile})`, + item?.exclusiveKiller + ? `${item?.exclusiveKiller?.name} (${item?.exclusiveKiller?.killHouseOperator?.user?.mobile})` + : "-", + item.buyType === "live" ? "مرغ زنده" : "لاشه", + + item.poultryName, + `${item.province}/${item.city}`, + , + item.car || "-", + item?.driverName || "-", + item?.driverMobile || "-", + item.quantity.toLocaleString(), + item.liveWeight.toLocaleString(), + formatJustDate(item.date), + + item.numberOfCarcasses.toLocaleString(), + item.weightOfCarcasses.toLocaleString(), + item?.poultry?.age, + item.weightOfCarcasses ? "ورود به انبار" : "در انتظار ورود به انبار", + , + ...getInformation(item), + <> + {getRoleFromUrl() === "KillHouse" ? ( + + ) : ( + isBarManagemen && + getRoleFromUrl() === "AdminX" && ( + + { + dispatch( + OPEN_MODAL({ + title: "حذف بار", + content: ( + + + آیا از حذف بار اطمینان دارید؟ + + + + + + + + + + + ), + }) + ); + }} + > + + + + ) + )} + , + ]; + }); + + setTableDataArchive(a); + }, [data]); + + useEffect(() => { + fetchApiData(1); + }, [selectedDate1, selectedDate2, perPage, activeTab, selectedSubUser?.key]); + + const handleSubmit = async (event) => { + event.preventDefault(); + dispatch(LOADING_START()); + + try { + const response = await axios.get( + `kill_house_free_bar/?type=${ + activeTab === 0 ? "live" : "carcass" + }&role=${getRoleFromUrl()}${ + checkPathStartsWith("slaughter") + ? `&role_key=${selectedSubUser?.key}` + : "" + }&search=filter&value=${textValue}&date1=${selectedDate1}&date2=${selectedDate2}&page=${1}&page_size=${perPage}&date_type=buy` + ); + setData(response.data.results); + setTotalRows(response.data.count); + getDashboardData(); + dispatch(LOADING_END()); + } catch (error) { + console.error("Error fetching data:", error); + } + }; + + const getLastItem = () => { + let item = []; + if (isBarManagemen && getRoleFromUrl() === "AdminX") { + item = ["حذف"]; + } else if (isBarManagemen) { + item = []; + } else { + item = ["عملیات"]; + } + + return item; + }; + + const information = () => { + if (getRoleFromUrl() === "AdminX" || getRoleFromUrl() === "SuperAdmin") { + return ["بازگشت از انبار"]; + } else { + return []; + } + }; + const LiveBars = ( + + ); + + return ( + + + + + + + + +
    + + {getRoleFromUrl() === "KillHouse" && + !isBarManagemen && + inventorySelectedKillHouse && ( + + )} + + + + + ( + + )} + value={selectedDate1} + onChange={(e) => { + setSelectedDate1(moment(e).format("YYYY-MM-DD")); + }} + /> + + + ( + + )} + value={selectedDate2} + onChange={(e) => { + setSelectedDate2(moment(e).format("YYYY-MM-DD")); + }} + /> + + + + {/* */} + + +
    + + + {activeTab === 0 ? ( + + ) : ( + + + + )} + + + {activeTab === 0 ? ( + <>{LiveBars} + ) : ( + + )} +
    +
    + ); +}; diff --git a/src/features/slaughter-house/components/slaughter-free-buy-operations/SlaughterFreeBuyOperations.js b/src/features/slaughter-house/components/slaughter-free-buy-operations/SlaughterFreeBuyOperations.js new file mode 100644 index 0000000..543a9b5 --- /dev/null +++ b/src/features/slaughter-house/components/slaughter-free-buy-operations/SlaughterFreeBuyOperations.js @@ -0,0 +1,324 @@ +import { + Button, + IconButton, + Popover, + List, + ListItemButton, + ListItemIcon, + ListItemText, +} from "@mui/material"; +import { Grid } from "../../../../components/grid/Grid"; +import DeleteIcon from "@mui/icons-material/Delete"; +import EditIcon from "@mui/icons-material/Edit"; +import DoneOutlineIcon from "@mui/icons-material/DoneOutline"; +import DoNotDisturbIcon from "@mui/icons-material/DoNotDisturb"; +import { useDispatch } from "react-redux"; +import { + CLOSE_MODAL, + DRAWER, + OPEN_MODAL, +} from "../../../../lib/redux/slices/appSlice"; +import { SlaughterSubmitFreeBuy } from "../slaughter-submit-free-buy/SlaughterSubmitFreeBuy"; +import { slaughterDeleteFreeBuyService } from "../../services/slaughter-delete-free-buy"; +import { useContext, useState } from "react"; +import { AppContext } from "../../../../contexts/AppContext"; +import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl"; +import { ProviceRejectFreeBuy } from "../province-reject-free-buy/ProvinceRejectFreeBuy"; +import { ProvinceAcceptDirectBuy } from "../../../province/components/province-accept-direct-buy/ProvinceAcceptDirectBuy"; +import TuneIcon from "@mui/icons-material/Tune"; +import ThumbUpAltIcon from "@mui/icons-material/ThumbUpAlt"; +import SmsIcon from "@mui/icons-material/Sms"; +import { slaughterEditFreeBuyService } from "../../services/slaughter-edit-free-buy"; +import { slaughterResendDirectBuyingSmsService } from "../../services/slaughter-resend-direct-buying-sms"; + +export const SlaughterFreeBuyOperations = ({ + item, + updateTable, + poultryCodeMandatory, +}) => { + const dispatch = useDispatch(); + const [openNotif] = useContext(AppContext); + + const [anchorEl, setAnchorEl] = useState(null); + + const handleClick = (event) => { + setAnchorEl(event.currentTarget); + }; + + const handleClose = () => { + setAnchorEl(null); + }; + + const open = Boolean(anchorEl); + const id = open ? "popover" : undefined; + + const showOnlyDelete = poultryCodeMandatory && !item?.inputDirectBuyingCode; + + const handleApproveRequest = () => { + dispatch( + OPEN_MODAL({ + title: "تایید فروش مستقیم", + content: ( + + ), + }) + ); + }; + + const handleRejectRequest = () => { + dispatch( + OPEN_MODAL({ + title: "رد درخواست فروش آزاد", + content: , + }) + ); + }; + + const handleFinalAccept = () => { + dispatch( + OPEN_MODAL({ + title: "آیا مطمئن هستید؟", + content: ( + + + + + ), + }) + ); + }; + + const handleEdit = () => { + dispatch( + DRAWER({ + title: "ویرایش خرید مستقیم", + content: ( + + ), + right: !(window.innerWidth <= 600), + bottom: window.innerWidth <= 600, + }) + ); + }; + + const handleResendSms = () => { + dispatch( + slaughterResendDirectBuyingSmsService({ + key: item?.key, + }) + ).then((r) => { + if (r?.payload?.error) { + openNotif({ + vertical: "top", + horizontal: "center", + msg: r?.payload?.error, + severity: "error", + }); + } else { + openNotif({ + vertical: "top", + horizontal: "center", + msg: "پیامک با موفقیت ارسال شد.", + severity: "success", + }); + } + }); + }; + + const handleDelete = () => { + dispatch(slaughterDeleteFreeBuyService(item.key)).then((r) => { + if (r.error) { + openNotif({ + vertical: "top", + horizontal: "center", + msg: r.error, + severity: "error", + }); + } else { + updateTable(); + openNotif({ + vertical: "top", + horizontal: "center", + msg: "عملیات با موفقیت انجام شد.", + severity: "success", + }); + dispatch( + DRAWER({ + right: false, + bottom: false, + left: false, + content: null, + }) + ); + } + }); + }; + + const options = []; + + if ( + !showOnlyDelete && + (getRoleFromUrl() === "ProvinceOperator" || + getRoleFromUrl() === "SuperAdmin" || + getRoleFromUrl() === "AdminX") + ) { + options.push({ + key: "approve", + label: "تایید درخواست", + color: "success.main", + icon: , + action: handleApproveRequest, + }); + + options.push({ + key: "reject", + label: "رد درخواست", + color: "warning.main", + icon: , + action: handleRejectRequest, + }); + } + + if (getRoleFromUrl() === "KillHouse" && !item?.finalAccept) { + options.push({ + key: "finalAccept", + label: "تایید نهایی", + color: "primary.main", + icon: , + action: handleFinalAccept, + }); + + options.push({ + key: "edit", + label: "ویرایش", + color: "info.main", + icon: , + action: handleEdit, + }); + } + + if (showOnlyDelete && item?.finalAccept) { + options.push({ + key: "resendSms", + label: "ارسال مجدد پیامک", + color: "info.main", + icon: , + action: handleResendSms, + }); + } + + options.push({ + key: "delete", + label: "حذف", + color: "error.main", + icon: , + action: handleDelete, + }); + + return ( + + + + + + + {options.map((option) => ( + { + handleClose(); + option.action(); + }} + sx={{ + borderRadius: 1, + mb: 0.25, + py: 0.5, + color: option.color, + "&:last-of-type": { + mb: 0, + }, + }} + > + + {option.icon} + + + + ))} + + + + ); +}; diff --git a/src/features/slaughter-house/components/slaughter-free-buy/SlaughterFreeBuy.js b/src/features/slaughter-house/components/slaughter-free-buy/SlaughterFreeBuy.js new file mode 100644 index 0000000..605f3bb --- /dev/null +++ b/src/features/slaughter-house/components/slaughter-free-buy/SlaughterFreeBuy.js @@ -0,0 +1,410 @@ +import { useCallback } from "react"; +import { Button, TextField, Tooltip, Typography } from "@mui/material"; +import { DatePicker } from "@mui/x-date-pickers"; +import axios from "axios"; +import moment from "moment/moment"; +import { useContext, useEffect, useState } from "react"; +import { useDispatch, useSelector } from "react-redux"; +import { Grid } from "../../../../components/grid/Grid"; + +import { AppContext } from "../../../../contexts/AppContext"; + +import { SPACING } from "../../../../data/spacing"; +import { DRAWER } from "../../../../lib/redux/slices/appSlice"; +import { formatJustDate, formatTime } from "../../../../utils/formatTime"; +import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl"; +// import { EnterAuthCodeDirectBuy } from "../enter-auth-code-direct-buy/EnterAuthCodeDirectBuy"; +import { SlaughterFreeBuyOperations } from "../slaughter-free-buy-operations/SlaughterFreeBuyOperations"; +import { SlaughterSubmitFreeBuy } from "../slaughter-submit-free-buy/SlaughterSubmitFreeBuy"; +import { RiFileExcel2Fill, RiSearchLine } from "react-icons/ri"; +import ResponsiveTable from "../../../../components/responsive-table/ResponsiveTable"; +import { paymentGetDeadLines } from "../../services/payment-get-deadlines"; +import EditVerificationDirectBuy from "../edit-verification-direct-buy/EditVerificationDirectBuy"; +import SlaughterBuyPdfKillRequest from "../../../province/components/province-settlement-pdf-kill-request/ProvinceSettlementPdfKillRequest"; +import { slaughterGetFreeBuyDashboardService } from "../../services/slaughter-free-buy-dashboard"; +import { slaughterGetFreeBuyRequests } from "../../services/slaughter-get-free-buy-requests"; +import { checkPathStartsWith } from "../../../../utils/checkPathStartsWith"; + +export const SlaughterFreeBuy = () => { + const dispatch = useDispatch(); + const selectedSubUser = useSelector( + (state) => state.userSlice.selectedSubUser + ); + const [, , selectedDate1, setSelectedDate1, selectedDate2, setSelectedDate2] = + useContext(AppContext); + const [poultryCodeMandatory, setPoultryCodeMandatory] = useState(false); + const [dashboardData, setDashboardData] = useState([]); + const userKey = useSelector((state) => state.userSlice.userProfile.key); + + useEffect(() => { + const currentDate = moment(new Date()).format("YYYY-MM-DD"); + setSelectedDate1(currentDate); + setSelectedDate2(currentDate); + }, []); + + useEffect(() => { + dispatch( + paymentGetDeadLines({ + role_key: checkPathStartsWith("slaughter") + ? selectedSubUser?.key || "" + : "", + }) + ).then((response) => { + setPoultryCodeMandatory(response.payload.data?.poultryCodeMandatory); + }); + }, [selectedSubUser?.key]); + + const [data, setData] = useState([]); + const [totalRows, setTotalRows] = useState(0); + const [perPage, setPerPage] = useState(10); + const [textValue, setTextValue] = useState(""); + const [page, setPage] = useState(1); + const [tableData, setTableData] = useState([]); + + const handleTextChange = (event) => { + setTextValue(event.target.value); + }; + + const getDashboardData = () => { + dispatch( + slaughterGetFreeBuyDashboardService({ + direct_buying: true, + date1: selectedDate1, + date2: selectedDate2, + role: getRoleFromUrl(), + search: "filter", + value: textValue, + role_key: checkPathStartsWith("slaughter") + ? selectedSubUser?.key || "" + : "", + }) + ).then((r) => { + setDashboardData(r.payload.data); + }); + }; + + const fetchApiData = useCallback( + async (pageNumber = page) => { + try { + const response = await dispatch( + slaughterGetFreeBuyRequests({ + date1: selectedDate1, + date2: selectedDate2, + value: textValue || "", + page: pageNumber, + page_size: perPage, + role_key: checkPathStartsWith("slaughter") + ? selectedSubUser?.key || "" + : "", + }) + ); + if (response.payload?.data) { + getDashboardData(); + setData(response.payload.data.results); + setTotalRows(response.payload.data.count); + } + } catch (error) { + console.error("Error fetching data:", error); + } + }, + [ + selectedDate1, + selectedDate2, + perPage, + page, + textValue, + dispatch, + selectedSubUser?.key, + ] + ); + + const updateTable = useCallback(() => { + fetchApiData(1); + }, [fetchApiData]); + + useEffect(() => { + fetchApiData(1); + }, [fetchApiData]); + const handlePerRowsChange = (perRows) => { + setPerPage(perRows); + setPage(1); + }; + + const handlePageChange = (page) => { + fetchApiData(page, textValue); + }; + + const handleSubmit = async (event) => { + event.preventDefault(); + try { + const response = await dispatch( + slaughterGetFreeBuyRequests({ + date1: selectedDate1, + date2: selectedDate2, + value: textValue || "", + role_key: checkPathStartsWith("slaughter") + ? selectedSubUser?.key || "" + : "", + }) + ); + if (response.payload?.data) { + setData(response.payload.data.results); + setTotalRows(response.payload.data.count); + } + } catch (error) { + console.error("Error fetching data:", error); + } + }; + + const getItemState = (item) => { + let state = ""; + if (item.finalAccept === false) { + state = "در انتظار ارسال به استان"; + } else if (poultryCodeMandatory && !item?.inputDirectBuyingCode) { + state = "در انتظار ورود کد احراز"; + } else if (item?.directBuyingState === "rejected") { + state = "رد شده"; + } else if (item?.directBuyingState === "accepted") { + state = "تایید شده"; + } else if (item?.directBuyingState === "deleted") { + state = "حذف شده"; + } else { + state = "در انتظار تایید استان"; + } + return state; + }; + + useEffect(() => { + const d = data?.map((item, i) => { + return [ + page === 1 ? i + 1 : i + perPage * (page - 1) + 1, + item?.createDate ? formatTime(item?.createDate) : "-", + item?.reciveDate ? formatJustDate(item?.reciveDate) : "-", + `${item.killHouse.name} (${item.killHouse.killHouseOperator.user.mobile})`, + item?.freeDirectBuying ? "آزاد" : "دولتی", + item?.slaughterHouse + ? item?.slaughterHouse?.name + : item?.killHouse?.name, + `${item?.poultry?.userprofile?.fullName} (${item?.poultry?.userprofile?.mobile})`, + item.poultryHatching?.chickenAge || "-", + `${item.chickenBreed ? item.chickenBreed : "-"}`, + item.killCapacity?.toLocaleString(), + item.IndexWeight, + (item.IndexWeight * item.killCapacity)?.toLocaleString(), + item?.amount?.toLocaleString(), + + + {item?.directBuyingState === "pending" && + item?.finalAccept === true && + (getRoleFromUrl() === "KillHouse" || + getRoleFromUrl() === "AdminX" || + getRoleFromUrl() === "SuperAdmin" || + getRoleFromUrl() === "ProvinceOperator") && + poultryCodeMandatory ? ( + + ) : ( + + {item?.inputDirectBuyingCode || "-"} + + )} + , + item?.paymentDeadlineDate + ? formatJustDate(item?.paymentDeadlineDate) + : "-", + getItemState(item), + item?.directBuyingState === "pending" + ? "-" + : item?.automaticAccept + ? "سیستم" + : "اپراتور", + item?.inputDirectBuyingCode || + (!item?.freeDirectBuying && item?.directBuyingState === "accepted") ? ( + + ) : ( + "-" + ), + + , + ]; + }); + + setTableData(d); + }, [data]); + + return ( + + + + {/* {getRoleFromUrl() === "KillHouse" && ( */} + + {/* )} */} + + + +
    + + + + + ( + + )} + value={selectedDate1} + onChange={(e) => { + setSelectedDate1(moment(e).format("YYYY-MM-DD")); + }} + /> + ( + + )} + value={selectedDate2} + onChange={(e) => { + setSelectedDate2(moment(e).format("YYYY-MM-DD")); + }} + /> + + + + + + + + + + +
    +
    + + + + + + +
    +
    +
    + ); +}; diff --git a/src/features/slaughter-house/components/slaughter-freezing-allocations-operations/SlaughterFreezingAllocationsOperations.js b/src/features/slaughter-house/components/slaughter-freezing-allocations-operations/SlaughterFreezingAllocationsOperations.js new file mode 100644 index 0000000..a5fce89 --- /dev/null +++ b/src/features/slaughter-house/components/slaughter-freezing-allocations-operations/SlaughterFreezingAllocationsOperations.js @@ -0,0 +1,123 @@ +import { IconButton, Popover, Tooltip } from "@mui/material"; +import React, { useContext, useState } from "react"; +import { useDispatch } from "react-redux"; +import TuneIcon from "@mui/icons-material/Tune"; +import DeleteIcon from "@mui/icons-material/Delete"; +import EditIcon from "@mui/icons-material/Edit"; +import { Grid } from "../../../../components/grid/Grid"; +import { AppContext } from "../../../../contexts/AppContext"; +import { slaughterDeleteAllocationForFreezing } from "../../services/slaughter-delete-allocation-for-freezing"; +import { OPEN_MODAL } from "../../../../lib/redux/slices/appSlice"; +import { SlaughterAllocateToFreezing } from "../slaughter-allocate-to-freezing/SlaughterAllocateToFreezing"; + +export const SlaughterFreezingAllocationsOperations = ({ + item, + fetchApiData, + updateInventory, +}) => { + const dispatch = useDispatch(); + const [openNotif] = useContext(AppContext); + + const [anchorEl, setAnchorEl] = useState(null); + + const handleClick = (event) => { + setAnchorEl(event.currentTarget); + }; + + const handleClose = () => { + setAnchorEl(null); + }; + + const open = Boolean(anchorEl); + const id = open ? "popover" : undefined; + + return ( +
    + + + + +
    + + + { + handleClose(); + + dispatch( + slaughterDeleteAllocationForFreezing(item?.key) + ).then((r) => { + if (r.payload.error) { + openNotif({ + vertical: "top", + horizontal: "center", + msg: "مشکلی پیش آمده است", + severity: "error", + }); + } else { + fetchApiData(); + updateInventory(); + openNotif({ + vertical: "top", + horizontal: "center", + msg: "عملیات با موفقیت انجام شد.", + severity: "success", + }); + } + }); + }} + > + + + + + { + handleClose(); + + dispatch( + OPEN_MODAL({ + title: "ویرایش تخصیص به انجماد", + content: ( + + ), + }) + ); + }} + > + + + + +
    +
    +
    + ); +}; diff --git a/src/features/slaughter-house/components/slaughter-freezing-allocations/SlaughterFreezingAllocations.js b/src/features/slaughter-house/components/slaughter-freezing-allocations/SlaughterFreezingAllocations.js new file mode 100644 index 0000000..60f6e80 --- /dev/null +++ b/src/features/slaughter-house/components/slaughter-freezing-allocations/SlaughterFreezingAllocations.js @@ -0,0 +1,191 @@ +import React, { useEffect, useState } from "react"; +import { Button, TextField } from "@mui/material"; +import { DatePicker } from "@mui/x-date-pickers"; +import moment from "moment"; +import { useDispatch } from "react-redux"; +import axios from "axios"; +import { + LOADING_END, + LOADING_START, +} from "../../../../lib/redux/slices/appSlice"; +import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl"; +import { Grid } from "../../../../components/grid/Grid"; +import ResponsiveTable from "../../../../components/responsive-table/ResponsiveTable"; +import { formatJustDate } from "../../../../utils/formatTime"; +import { SlaughterFreezingAllocationsOperations } from "../slaughter-freezing-allocations-operations/SlaughterFreezingAllocationsOperations"; +import { RiSearchLine } from "react-icons/ri"; + +export const SlaughterFreezingAllocations = ({ + updateFreezing, + updateInventory, +}) => { + const [selectedDate1, setSelectedDate1] = useState( + moment(new Date()).format("YYYY-MM-DD") + ); + const [selectedDate2, setSelectedDate2] = useState( + moment(new Date()).format("YYYY-MM-DD") + ); + const dispatch = useDispatch(); + + const handleTextChange = (event) => { + setTextValue(event.target.value); + }; + + const [data, setData] = useState([]); + const [totalRows, setTotalRows] = useState(0); + const [perPage, setPerPage] = useState(10); + const [textValue, setTextValue] = useState(""); + const [page, setPage] = useState(1); + const [tableData, setTableData] = useState([]); + + const fetchApiData = async (page) => { + dispatch(LOADING_START()); + const response = await axios.get( + `cold-house-allocations/?search=filter&value=${textValue}&role=${getRoleFromUrl()}&date1=${selectedDate1}&date2=${selectedDate2}&page=${page}&page_size=${perPage}` + ); + dispatch(LOADING_END()); + setData(response.data.results); + setTotalRows(response.data.count); + }; + + const handlePageChange = (page) => { + fetchApiData(page); + setPage(page); + }; + + const handlePerRowsChange = (perRows) => { + setPerPage(perRows); + setPage(1); + }; + + const updateTable = () => { + fetchApiData(page !== 0 ? page : 1); + }; + + useEffect(() => { + const d = data?.map((item, i) => { + return [ + page === 1 ? i + 1 : i + perPage * (page - 1) + 1, + item?.state === "pending" + ? "در انتظار تایید" + : item?.state === "accepted" + ? "تایید شده" + : "رد شده", + formatJustDate(item?.date), + item?.coldHouse?.name, + item?.quantity?.toLocaleString(), + item?.weight?.toLocaleString(), + item?.realQuantity?.toLocaleString(), + item?.realWeight?.toLocaleString(), + , + ]; + }); + + setTableData(d); + }, [data]); + + useEffect(() => { + fetchApiData(1); + }, [dispatch, selectedDate1, selectedDate2, perPage, updateFreezing]); + + const handleSubmit = async (event) => { + event.preventDefault(); + dispatch(LOADING_START()); + + try { + const response = await axios.get( + `cold-house-allocations/?role=${getRoleFromUrl()}&search=filter&value=${textValue}&date1=${selectedDate1}&date2=${selectedDate2}&page=${1}&page_size=${perPage}` + ); + setData(response.data.results); + setTotalRows(response.data.count); + dispatch(LOADING_END()); + } catch (error) { + console.error("Error fetching data:", error); + } + }; + + return ( + + + + ( + + )} + value={selectedDate1} + onChange={(e) => { + setSelectedDate1(moment(e).format("YYYY-MM-DD")); + }} + /> + + + ( + + )} + value={selectedDate2} + onChange={(e) => { + setSelectedDate2(moment(e).format("YYYY-MM-DD")); + }} + /> + + +
    + + + +
    +
    + + +
    + ); +}; diff --git a/src/features/slaughter-house/components/slaughter-house-cold-house-bars-edit/SlaughterHouseColdHouseBarsEdit.js b/src/features/slaughter-house/components/slaughter-house-cold-house-bars-edit/SlaughterHouseColdHouseBarsEdit.js new file mode 100644 index 0000000..eb0599c --- /dev/null +++ b/src/features/slaughter-house/components/slaughter-house-cold-house-bars-edit/SlaughterHouseColdHouseBarsEdit.js @@ -0,0 +1,188 @@ +import React, { useContext, useEffect } from "react"; +import { Grid } from "../../../../components/grid/Grid"; +import { Button, InputAdornment } from "@mui/material"; +import { useDispatch } from "react-redux"; +import { NumberInput } from "../../../../components/number-format-custom/NumberFormatCustom"; +import { useFormik } from "formik"; +import { Yup } from "../../../../lib/yup/yup"; +import { + slaughterAllocateStewardService, + slaughterEditAllocateStewardService, +} from "../../services/slaughter-allocate-steward"; +import { AppContext } from "../../../../contexts/AppContext"; +import { CLOSE_MODAL } from "../../../../lib/redux/slices/appSlice"; +import { fetchSlaughterBroadcastAndProducts } from "../../services/handle-fetch-slaughter-products"; +export const SlaughterHouseColdHouseBarsEdit = ({ + sellerType, + fetchData, + sellType, + updateTable, + fetchApiData, + editData, + isColdHouse, + priceInfo, +}) => { + const dispatch = useDispatch(); + const [openNotif] = useContext(AppContext); + + const validationSchema = Yup.object({ + weight: Yup.number() + .required("این فیلد اجباری است!") + .min(1, "یک مقدار مثبت وارد کنید!"), + }); + + const formik = useFormik({ + initialValues: { + weight: editData?.realWeightOfCarcasses || "", + }, + validationSchema, + }); + + useEffect(() => { + formik.validateForm(); + }, []); + + const successSubmit = () => { + dispatch(CLOSE_MODAL()); + openNotif({ + vertical: "top", + horizontal: "center", + msg: "عملیات با موفقیت انجام شد.", + severity: "success", + }); + dispatch(fetchSlaughterBroadcastAndProducts()); + fetchApiData(); + updateTable(); + fetchData(); + }; + + return ( + + + + ریال, + }} + value={formik.values.price} + error={formik.touched.price ? Boolean(formik.errors.price) : null} + onChange={formik.handleChange} + onBlur={formik.handleBlur} + helperText={ + formik.touched.price && Boolean(formik.errors.price) + ? formik.errors.price + : null + } + /> + + ریال, + }} + value={formik.values.wholePrice} + error={ + formik.touched.wholePrice ? Boolean(formik.errors.wholePrice) : null + } + onChange={formik.handleChange} + onBlur={formik.handleBlur} + helperText={ + formik.touched.wholePrice && Boolean(formik.errors.wholePrice) + ? formik.errors.wholePrice + : null + } + /> + + + + ); +}; diff --git a/src/features/slaughter-house/components/slaughter-house-delegates/DelegatesLimitationForm.js b/src/features/slaughter-house/components/slaughter-house-delegates/DelegatesLimitationForm.js new file mode 100644 index 0000000..5aedfa3 --- /dev/null +++ b/src/features/slaughter-house/components/slaughter-house-delegates/DelegatesLimitationForm.js @@ -0,0 +1,131 @@ +import React, { useContext, useState } from "react"; +import { + Button, + TextField, + Typography, + Checkbox, + FormControlLabel, +} from "@mui/material"; +import { useDispatch } from "react-redux"; +import { Grid } from "../../../../components/grid/Grid"; +import { SPACING } from "../../../../data/spacing"; +import { CLOSE_MODAL } from "../../../../lib/redux/slices/appSlice"; +import { AppContext } from "../../../../contexts/AppContext"; +import { slaughterEditDelegatesService } from "../../services/slaughter-get-delegates-service"; + +export const DelegatesLimitationForm = ({ item, updateTable }) => { + const dispatch = useDispatch(); + const [openNotif] = useContext(AppContext); + + const [hasLimitation, setHasLimitation] = useState(item?.limitation || false); + const [governmentalValue, setGovernmentalValue] = useState( + item?.governmentalLimitationWeight || 0 + ); + const [freeValue, setFreeValue] = useState(item?.freeLimitationWeight || 0); + + const handleSubmit = (e) => { + e.preventDefault(); + + const submitData = { + key: item?.key, + limitation: hasLimitation, + governmental_limitation_weight: hasLimitation + ? Number(governmentalValue) + : 0, + free_limitation_weight: hasLimitation ? Number(freeValue) : 0, + }; + + dispatch(slaughterEditDelegatesService(submitData)).then((r) => { + if (r.payload?.error) { + openNotif({ + vertical: "top", + horizontal: "center", + msg: r.payload.error, + severity: "error", + }); + } else { + openNotif({ + vertical: "top", + horizontal: "center", + msg: "عملیات با موفقیت انجام شد.", + severity: "success", + }); + if (updateTable) { + updateTable(); + } + dispatch(CLOSE_MODAL()); + } + }); + }; + + return ( +
    + + + + اطلاعات نماینده: + + + {item?.firstName || item?.first_name}{" "} + {item?.lastName || item?.last_name} + + + + + setHasLimitation(e.target.checked)} + color="primary" + /> + } + label="محدودیت فروش روزانه" + /> + + + {hasLimitation && ( + <> + + setGovernmentalValue(e.target.value)} + inputProps={{ min: 0 }} + /> + + + + setFreeValue(e.target.value)} + inputProps={{ min: 0 }} + /> + + + )} + + + + + +
    + ); +}; diff --git a/src/features/slaughter-house/components/slaughter-house-delegates/DelegatesOperations.js b/src/features/slaughter-house/components/slaughter-house-delegates/DelegatesOperations.js new file mode 100644 index 0000000..fb538c3 --- /dev/null +++ b/src/features/slaughter-house/components/slaughter-house-delegates/DelegatesOperations.js @@ -0,0 +1,139 @@ +import { IconButton, Popover, Typography, Button } from "@mui/material"; +import React, { useState, useContext } from "react"; +import TuneIcon from "@mui/icons-material/Tune"; +import ToggleOnIcon from "@mui/icons-material/ToggleOn"; +import ToggleOffIcon from "@mui/icons-material/ToggleOff"; +import BlockIcon from "@mui/icons-material/Block"; +import { useDispatch } from "react-redux"; +import { AppContext } from "../../../../contexts/AppContext"; +import { OPEN_MODAL } from "../../../../lib/redux/slices/appSlice"; +import { slaughterEditDelegatesService } from "../../services/slaughter-get-delegates-service"; +import { DelegatesLimitationForm } from "./DelegatesLimitationForm"; + +export const DelegatesOperations = ({ item, updateTable }) => { + const [anchorEl, setAnchorEl] = useState(null); + const dispatch = useDispatch(); + const [openNotif] = useContext(AppContext); + + const handleClick = (event) => { + setAnchorEl(event.currentTarget); + }; + + const handleClose = () => { + setAnchorEl(null); + }; + + const open = Boolean(anchorEl); + const id = open ? "popover" : undefined; + + const isActive = item?.active !== undefined ? item.active : !item?.trash; + + const handleToggleActive = () => { + handleClose(); + dispatch( + slaughterEditDelegatesService({ + key: item?.key, + active: !isActive, + }) + ).then((r) => { + if (r.payload?.error) { + openNotif({ + vertical: "top", + horizontal: "center", + msg: r.payload.error, + severity: "error", + }); + } else { + openNotif({ + vertical: "top", + horizontal: "center", + msg: "عملیات با موفقیت انجام شد.", + severity: "success", + }); + if (updateTable) { + updateTable(); + } + } + }); + }; + + return ( +
    + + + + +
    + + +
    +
    +
    + ); +}; diff --git a/src/features/slaughter-house/components/slaughter-house-delegates/KillHouseDelegatesTab.js b/src/features/slaughter-house/components/slaughter-house-delegates/KillHouseDelegatesTab.js new file mode 100644 index 0000000..1f407db --- /dev/null +++ b/src/features/slaughter-house/components/slaughter-house-delegates/KillHouseDelegatesTab.js @@ -0,0 +1,199 @@ +import React, { useEffect, useState, useRef } from "react"; +import { Box, Button, Grid, TextField, Chip } from "@mui/material"; +import { useDispatch } from "react-redux"; +import { slaughterGetDelegatesService } from "../../services/slaughter-get-delegates-service"; +import ResponsiveTable from "../../../../components/responsive-table/ResponsiveTable"; +import { SPACING } from "../../../../data/spacing"; +import { RiSearchLine } from "react-icons/ri"; +import { DelegatesOperations } from "./DelegatesOperations"; + +export const KillHouseDelegatesTab = () => { + const dispatch = useDispatch(); + const [data, setData] = useState([]); + const [totalRows, setTotalRows] = useState(0); + const [perPage, setPerPage] = useState(10); + const [textValue, setTextValue] = useState(""); + const [page, setPage] = useState(1); + const [tableData, setTableData] = useState([]); + const isFirstMount = useRef(true); + + const handleTextChange = (e) => setTextValue(e.target.value); + + const fetchApiData = async (pageNum) => { + const response = await dispatch( + slaughterGetDelegatesService({ + type: "KillHouse", + search: "filter", + value: textValue, + page: pageNum, + page_size: perPage, + }) + ); + + if (response.payload.error) { + console.error("Error fetching data:", response.payload.error); + setData([]); + setTotalRows(0); + } else { + setData(response.payload.data?.results || []); + const count = Number(response.payload.data?.count) || 0; + setTotalRows(count); + } + }; + + const handlePageChange = (pageNum) => { + fetchApiData(pageNum); + setPage(pageNum); + }; + + const handlePerRowsChange = (perRows) => { + setPerPage(Number(perRows)); + setPage(1); + }; + + const updateTableData = () => { + fetchApiData(page); + }; + + useEffect(() => { + if (!data || !Array.isArray(data)) { + setTableData([]); + return; + } + const d = data.map((item, i) => { + const isActive = item?.active !== undefined ? item.active : !item?.trash; + const hasLimitation = item?.limitation; + const limitationBadge = ( + + ); + + const killhouseDisplay = + item?.killHouse?.name && item?.killHouse?.mobile + ? `${item.killHouse.name} (${item.killHouse.mobile})` + : item?.killHouse?.name + ? item.killHouse.name + : "-"; + + return [ + page === 1 ? i + 1 : i + perPage * (page - 1) + 1, + item?.firstName || item?.first_name || "-", + item?.lastName || item?.last_name || "-", + item?.mobile || "-", + item?.city || "-", + killhouseDisplay, + limitationBadge, + item?.governmentalLimitationWeight || 0, + item?.freeLimitationWeight || 0, + , + , + ]; + }); + setTableData(d); + }, [data, page, perPage]); + + useEffect(() => { + fetchApiData(1); + }, []); + + useEffect(() => { + if (isFirstMount.current) { + isFirstMount.current = false; + return; + } + fetchApiData(1); + setPage(1); + }, [perPage]); + + const handleSubmit = async (e) => { + e.preventDefault(); + setPage(1); + const response = await dispatch( + slaughterGetDelegatesService({ + type: "KillHouse", + search: "filter", + value: textValue, + page: 1, + page_size: perPage, + }) + ); + + if (response.payload.error) { + console.error("Error fetching data:", response.payload.error); + setData([]); + setTotalRows(0); + } else { + setData(response.payload.data?.results || []); + const count = Number(response.payload.data?.count) || 0; + setTotalRows(count); + } + }; + + return ( + + +
    + + + + +
    +
    + + + + +
    + ); +}; diff --git a/src/features/slaughter-house/components/slaughter-house-delegates/SlaughterHouseDelegates.js b/src/features/slaughter-house/components/slaughter-house-delegates/SlaughterHouseDelegates.js new file mode 100644 index 0000000..df4c2a3 --- /dev/null +++ b/src/features/slaughter-house/components/slaughter-house-delegates/SlaughterHouseDelegates.js @@ -0,0 +1,27 @@ +import React, { useState } from "react"; +import { Grid } from "../../../../components/grid/Grid"; +import { Tab, Tabs, Box } from "@mui/material"; +import { StewardDelegatesTab } from "./StewardDelegatesTab"; +import { KillHouseDelegatesTab } from "./KillHouseDelegatesTab"; + +export const SlaughterHouseDelegates = () => { + const [value, setValue] = useState(0); + + const handleChange = (event, newValue) => { + setValue(newValue); + }; + + return ( + + + + + + + + {value === 0 && } + {value === 1 && } + + + ); +}; diff --git a/src/features/slaughter-house/components/slaughter-house-delegates/StewardDelegatesTab.js b/src/features/slaughter-house/components/slaughter-house-delegates/StewardDelegatesTab.js new file mode 100644 index 0000000..69d316d --- /dev/null +++ b/src/features/slaughter-house/components/slaughter-house-delegates/StewardDelegatesTab.js @@ -0,0 +1,199 @@ +import React, { useEffect, useState, useRef } from "react"; +import { Box, Button, Grid, TextField, Chip } from "@mui/material"; +import { useDispatch } from "react-redux"; +import { slaughterGetDelegatesService } from "../../services/slaughter-get-delegates-service"; +import ResponsiveTable from "../../../../components/responsive-table/ResponsiveTable"; +import { SPACING } from "../../../../data/spacing"; +import { RiSearchLine } from "react-icons/ri"; +import { DelegatesOperations } from "./DelegatesOperations"; + +export const StewardDelegatesTab = () => { + const dispatch = useDispatch(); + const [data, setData] = useState([]); + const [totalRows, setTotalRows] = useState(0); + const [perPage, setPerPage] = useState(10); + const [textValue, setTextValue] = useState(""); + const [page, setPage] = useState(1); + const [tableData, setTableData] = useState([]); + const isFirstMount = useRef(true); + + const handleTextChange = (e) => setTextValue(e.target.value); + + const fetchApiData = async (pageNum) => { + const response = await dispatch( + slaughterGetDelegatesService({ + type: "Steward", + search: "filter", + value: textValue, + page: pageNum, + page_size: perPage, + }) + ); + + if (response.payload.error) { + console.error("Error fetching data:", response.payload.error); + setData([]); + setTotalRows(0); + } else { + setData(response.payload.data?.results || []); + const count = Number(response.payload.data?.count) || 0; + setTotalRows(count); + } + }; + + const handlePageChange = (pageNum) => { + fetchApiData(pageNum); + setPage(pageNum); + }; + + const handlePerRowsChange = (perRows) => { + setPerPage(Number(perRows)); + setPage(1); + }; + + const updateTableData = () => { + fetchApiData(page); + }; + + useEffect(() => { + if (!data || !Array.isArray(data)) { + setTableData([]); + return; + } + const d = data.map((item, i) => { + const isActive = item?.active !== undefined ? item.active : !item?.trash; + const hasLimitation = item?.limitation; + const limitationBadge = ( + + ); + + const stewardDisplay = + item?.steward?.name && item?.steward?.user?.mobile + ? `${item.steward.name} (${item.steward.user.mobile})` + : item?.steward?.name + ? item.steward.name + : "-"; + + return [ + page === 1 ? i + 1 : i + perPage * (page - 1) + 1, + item?.firstName || item?.first_name || "-", + item?.lastName || item?.last_name || "-", + item?.mobile || "-", + item?.city || "-", + stewardDisplay, + limitationBadge, + item?.governmentalLimitationWeight || 0, + item?.freeLimitationWeight || 0, + , + , + ]; + }); + setTableData(d); + }, [data, page, perPage]); + + useEffect(() => { + fetchApiData(1); + }, []); + + useEffect(() => { + if (isFirstMount.current) { + isFirstMount.current = false; + return; + } + fetchApiData(1); + setPage(1); + }, [perPage]); + + const handleSubmit = async (e) => { + e.preventDefault(); + setPage(1); + const response = await dispatch( + slaughterGetDelegatesService({ + type: "Steward", + search: "filter", + value: textValue, + page: 1, + page_size: perPage, + }) + ); + + if (response.payload.error) { + console.error("Error fetching data:", response.payload.error); + setData([]); + setTotalRows(0); + } else { + setData(response.payload.data?.results || []); + const count = Number(response.payload.data?.count) || 0; + setTotalRows(count); + } + }; + + return ( + + +
    + + + + +
    +
    + + + + +
    + ); +}; diff --git a/src/features/slaughter-house/components/slaughter-house-dispenser-details/SlaughterHouseDispenserDetails.js b/src/features/slaughter-house/components/slaughter-house-dispenser-details/SlaughterHouseDispenserDetails.js new file mode 100644 index 0000000..f3debb9 --- /dev/null +++ b/src/features/slaughter-house/components/slaughter-house-dispenser-details/SlaughterHouseDispenserDetails.js @@ -0,0 +1,307 @@ +import React, { useContext, useEffect, useState } from "react"; +import { Button, TextField } from "@mui/material"; +import { DatePicker } from "@mui/x-date-pickers"; +import moment from "moment"; +import { useDispatch } from "react-redux"; +import axios from "axios"; +import ResponsiveTable from "../../../../components/responsive-table/ResponsiveTable"; +import { + LOADING_END, + LOADING_START, +} from "../../../../lib/redux/slices/appSlice"; +import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl"; +import { Grid } from "../../../../components/grid/Grid"; +import { AppContext } from "../../../../contexts/AppContext"; +import { useParams } from "react-router-dom"; +import { formatJustDate } from "../../../../utils/formatTime"; +import { slaughterGetDispenserDashboardService } from "../../services/slaughter-house-get-dispenser-dashboard-service"; +import { RiSearchLine } from "react-icons/ri"; + +export const SlaughterHouseDispenserDetails = () => { + const { key } = useParams(); + const [, , selectedDate1, setSelectedDate1, selectedDate2, setSelectedDate2] = + useContext(AppContext); + const dispatch = useDispatch(); + useEffect(() => { + const currentDate = moment(new Date()).format("YYYY-MM-DD"); + setSelectedDate1(currentDate); + setSelectedDate2(currentDate); + }, []); + + const handleTextChange = (event) => { + setTextValue(event.target.value); + }; + + const [data, setData] = useState([]); + const [totalRows, setTotalRows] = useState(0); + const [perPage, setPerPage] = useState(10); + const [textValue, setTextValue] = useState(""); + const [page, setPage] = useState(1); + const [tableData, setTableData] = useState([]); + const [dashboardData, setDashboardData] = useState(); + + const fetchApiData = async (page) => { + let response; + dispatch(LOADING_START()); + response = await axios.get( + `dispenser-allocations/?search=filter&value=${textValue}&role=${getRoleFromUrl()}&date1=${selectedDate1}&date2=${selectedDate2}&page=${page}&page_size=${perPage}&dispenser_key=${key}` + ); + dispatch(LOADING_END()); + setData(response.data.results); + setTotalRows(response.data.count); + }; + + const handlePageChange = (page) => { + fetchApiData(page); + setPage(page); + }; + + const handlePerRowsChange = (perRows) => { + setPerPage(perRows); + setPage(1); + }; + + // const updateTable = () => { + // fetchApiData(page !== 0 ? page : 1); + // }; + + useEffect(() => { + fetchApiData(1); + }, []); + + useEffect(() => { + dispatch( + slaughterGetDispenserDashboardService({ + date1: selectedDate1, + date2: selectedDate2, + key: key, + }) + ).then((r) => { + setDashboardData(r.payload.data); + }); + }, [selectedDate1, selectedDate2]); + + const getDispenserType = (item) => { + let type = ""; + switch (item?.dispenser?.dispenserType) { + case "inductor": + type = "واسطه"; + break; + case "salesman": + type = "فروشنده"; + break; + case "driver": + type = `راننده - ${item?.dispenser?.car} (${item?.dispenser?.pelak})`; + break; + default: + break; + } + + return type; + }; + + useEffect(() => { + const d = data?.map((item, i) => { + let sellType, sellerType; + if (item.sellerType === "guilds") { + sellerType = "صنف"; + } else if (item.sellerType === "steward") { + sellerType = "مباشر"; + } + + if (item.sellType === "free") { + sellType = "آزاد"; + } else { + if (item.type === "manual") { + sellType = "اختصاصی (دستی)"; + } else { + sellType = "اختصاصی (اتوماتیک)"; + } + } + + return [ + page === 1 ? i + 1 : i + perPage * (page - 1) + 1, + `${item?.dispenser?.user?.fullname} (${item?.dispenser?.user?.mobile})`, + getDispenserType(item), + item?.guilds ? item?.guilds?.guildsId : item?.steward?.guilds?.guildsId, + formatJustDate(item.date), + sellerType, + sellType, + item?.guilds + ? item?.guilds?.guildsName + : item?.steward?.guilds?.guildsName, + item?.guilds + ? item?.guilds?.user.fullname + : item?.steward?.guilds?.user.fullname, + item?.guilds + ? item?.guilds?.user.nationalId + : item?.steward?.guilds?.user.nationalId, + item?.guilds + ? item?.guilds?.user.mobile + : item?.steward?.guilds?.user.mobile, + item?.guilds + ? item?.guilds?.typeActivity + : item?.steward?.guilds?.typeActivity, + item?.guilds + ? item?.guilds?.areaActivity + : item?.steward?.guilds?.areaActivity, + item?.guilds + ? item?.guilds?.licenseNumber + : item?.steward?.guilds?.licenseNumber, + item?.guilds + ? item?.guilds?.user?.city?.name + : item?.steward?.guilds?.user?.city?.name, + item?.numberOfCarcasses, + item?.weightOfCarcasses, + item?.loggedRegistrationCode ? item.loggedRegistrationCode : "-", + item?.receiverState === "accepted" + ? "تایید شده" + : item?.receiverState === "rejected" + ? "رد شده" + : "در انتظار تایید", + ]; + }); + + setTableData(d); + }, [data]); + + useEffect(() => { + fetchApiData(1); + }, [selectedDate1, selectedDate2, perPage]); + + const handleSubmit = async (event) => { + event.preventDefault(); + dispatch(LOADING_START()); + + try { + const response = await axios.get( + `dispenser-allocations/?role=${getRoleFromUrl()}&search=filter&value=${textValue}&date1=${selectedDate1}&date2=${selectedDate2}&page=${1}&page_size=${perPage}&dispenser_key=${key}` + ); + setData(response.data.results); + setTotalRows(response.data.count); + dispatch(LOADING_END()); + } catch (error) { + console.error("Error fetching data:", error); + } + }; + + return ( + + + + ( + + )} + value={selectedDate1} + onChange={(e) => { + setSelectedDate1(moment(e).format("YYYY-MM-DD")); + }} + /> + + + ( + + )} + value={selectedDate2} + onChange={(e) => { + setSelectedDate2(moment(e).format("YYYY-MM-DD")); + }} + /> + + +
    + + + +
    +
    + + + + + +
    + ); +}; diff --git a/src/features/slaughter-house/components/slaughter-house-dispensers-access-level/SlaughterHouseDispensersAccessLevel.js b/src/features/slaughter-house/components/slaughter-house-dispensers-access-level/SlaughterHouseDispensersAccessLevel.js new file mode 100644 index 0000000..9b7b752 --- /dev/null +++ b/src/features/slaughter-house/components/slaughter-house-dispensers-access-level/SlaughterHouseDispensersAccessLevel.js @@ -0,0 +1,111 @@ +import React, { useContext } from "react"; +import { Button, Checkbox, FormControlLabel, FormGroup } from "@mui/material"; +import { useFormik } from "formik"; +import * as Yup from "yup"; +import { Grid } from "../../../../components/grid/Grid"; +import { AppContext } from "../../../../contexts/AppContext"; +import { CLOSE_MODAL } from "../../../../lib/redux/slices/appSlice"; +import { useDispatch } from "react-redux"; +import { slaughterHouseEditDispenserService } from "../../services/slaughter-house-submit-dispenser-service"; + +const validationSchema = Yup.object({ + free_sale: Yup.boolean(), + free_guilds: Yup.boolean(), + free_stewards: Yup.boolean(), +}); + +export const SlaughterHouseDispensersAccessLevel = ({ updateTable, item }) => { + const [openNotif] = useContext(AppContext); + const dispatch = useDispatch(); + const formik = useFormik({ + initialValues: { + free_sale: item?.freeSale ? item?.freeSale : false, + free_guilds: item?.freeGuilds ? item?.freeGuilds : false, + free_stewards: item?.freeStewards ? item?.freeStewards : false, + }, + validationSchema: validationSchema, + onSubmit: (values) => { + dispatch( + slaughterHouseEditDispenserService({ + dispenser_key: item?.key, + type: "update-acceess-level", + free_sale: values.free_sale, + free_guilds: values.free_guilds, + free_stewards: values.free_stewards, + }) + ).then((r) => { + if (r.payload.error) { + openNotif({ + vertical: "top", + horizontal: "center", + msg: r.payload.error, + severity: "error", + }); + } else { + dispatch(CLOSE_MODAL()); + updateTable(); + openNotif({ + vertical: "top", + horizontal: "center", + msg: "عملیات با موفقیت انجام شد.", + severity: "success", + }); + } + }); + }, + }); + + return ( + +
    + + + } + label="اجازه فروش آزاد" + /> + + } + label="فروش به اصناف آزاد" + /> + + } + label="فروش به مباشرین آزاد" + /> + + {formik.touched.free_stewards && formik.errors.free_stewards ? ( +
    {formik.errors.free_stewards}
    + ) : null} + +
    +
    + ); +}; diff --git a/src/features/slaughter-house/components/slaughter-house-dispensers-operation/SlaughterHouseDispensersOperation.js b/src/features/slaughter-house/components/slaughter-house-dispensers-operation/SlaughterHouseDispensersOperation.js new file mode 100644 index 0000000..4fa1593 --- /dev/null +++ b/src/features/slaughter-house/components/slaughter-house-dispensers-operation/SlaughterHouseDispensersOperation.js @@ -0,0 +1,124 @@ +import { + Button, + IconButton, + Popover, + Tooltip, + Typography, +} from "@mui/material"; +import { useState } from "react"; +import TuneIcon from "@mui/icons-material/Tune"; +import { useDispatch } from "react-redux"; +import { DRAWER, OPEN_MODAL } from "../../../../lib/redux/slices/appSlice"; +import { Grid } from "../../../../components/grid/Grid"; +import { SlaughterHouseSubmitDispenser } from "../slaughter-house-submit-dispenser/SlaughterHouseSubmitDispenser"; +import EditIcon from "@mui/icons-material/Edit"; +import SubtitlesIcon from "@mui/icons-material/Subtitles"; +import { SlaughterHouseDispensersAccessLevel } from "../slaughter-house-dispensers-access-level/SlaughterHouseDispensersAccessLevel"; + +export const SlaughterHouseDispensersOperation = ({ item, updateTable }) => { + const dispatch = useDispatch(); + + const [anchorEl, setAnchorEl] = useState(null); + + const handleClick = (event) => { + setAnchorEl(event.currentTarget); + }; + + const handleClose = () => { + setAnchorEl(null); + }; + + const open = Boolean(anchorEl); + const id = open ? "popover" : undefined; + + return ( +
    + + + + +
    + + + + + + + + +
    +
    +
    + ); +}; diff --git a/src/features/slaughter-house/components/slaughter-house-dispensers-operations/SlaughterHouseDispensersOperations.js b/src/features/slaughter-house/components/slaughter-house-dispensers-operations/SlaughterHouseDispensersOperations.js new file mode 100644 index 0000000..d9fcbe7 --- /dev/null +++ b/src/features/slaughter-house/components/slaughter-house-dispensers-operations/SlaughterHouseDispensersOperations.js @@ -0,0 +1,252 @@ +import React from "react"; +import { SPACING } from "../../../../data/spacing"; +import { Grid } from "../../../../components/grid/Grid"; +import { NavLink } from "../../../../components/nav-link/NavLink"; +import LinkItem from "../../../../components/link-item/LinkItem"; +import { VscBroadcast, VscPerson } from "react-icons/vsc"; +import { + ROUTE_ADMINX_DELEGATES_MANAGEMENT, + ROUTE_ADMINX_DISPENSERS_INVENTORY, + ROUTE_ADMINX_DISPENSERS_KILLHOUSES, + ROUTE_ADMINX_DISPENSERS_MANAGEMENT, + ROUTE_ADMINX_DISPENSERS_MANAGEMENT_V2, + ROUTE_ADMINX_DISPENSERS_STEWARDS, + ROUTE_ADMINX_DISPENSERS_STOCK, + ROUTE_ADMINX_SALE_DESTRIBUTION_DETAILS, + ROUTE_ADMINX_TRANSACTIONS, + ROUTE_CITY_DISPENSERS_INVENTORY, + ROUTE_CITY_REQUEST_DISTRIBUTION, + ROUTE_CITY_REQUEST_TRANSACTIONS, + ROUTE_PROVINCE_DISPENSERS_INVENTORY, + ROUTE_PROVINCE_DISPENSERS_KILLHOUSES, + ROUTE_PROVINCE_DISPENSERS_MANAGEMENT, + ROUTE_PROVINCE_DISPENSERS_STEWARDS, + ROUTE_PROVINCE_FINANCIAL_TRANSACTIONS, + ROUTE_PROVINCE_SALE_DESTRIBUTION_DETAILS, + ROUTE_PROVINCE_SUPERVISOR_DISPENSERS_INVENTORY, + ROUTE_PROVINCE_SUPERVISOR_DISPENSERS_STOCK, + ROUTE_PROVINCE_SUPERVISOR_REQUEST_DISTRIBUTION, + ROUTE_PROVINCE_SUPERVISOR_REQUEST_TRANSACTIONS, + ROUTE_PROVINCE_TRANSACTIONS, + ROUTE_SLAUGHTER_DISPENSERS_KILLHOUSES, + ROUTE_SLAUGHTER_DISPENSERS_MANAGEMENT, + ROUTE_SLAUGHTER_DISPENSERS_STEWARDS, + ROUTE_SUPER_ADMIN_DESTRIBUTION_DETAILS, + ROUTE_SUPER_ADMIN_DISPENSERS_INVENTORY, + ROUTE_SUPER_ADMIN_DISPENSERS_KILLHOUSES, + ROUTE_SUPER_ADMIN_DISPENSERS_MANAGEMENT, + ROUTE_SUPER_ADMIN_DISPENSERS_STEWARDS, + ROUTE_SUPER_ADMIN_DISPENSERS_STOCK, + ROUTE_SUPER_ADMIN_TRANSACTIONS, +} from "../../../../routes/routes"; +import { useLocation } from "react-router-dom"; +import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl"; +import { FaMoneyBill, FaStore, FaWarehouse } from "react-icons/fa"; +import BadgeIcon from "@mui/icons-material/Badge"; + +const ROUTE_MAP = { + management: { + KillHouse: ROUTE_SLAUGHTER_DISPENSERS_MANAGEMENT, + AdminX: ROUTE_ADMINX_DISPENSERS_MANAGEMENT, + SuperAdmin: ROUTE_SUPER_ADMIN_DISPENSERS_MANAGEMENT, + AdminXX: ROUTE_ADMINX_DISPENSERS_MANAGEMENT_V2, + AdminXXX: ROUTE_ADMINX_DELEGATES_MANAGEMENT, + default: ROUTE_PROVINCE_DISPENSERS_MANAGEMENT, + }, + killhouses: { + KillHouse: ROUTE_SLAUGHTER_DISPENSERS_KILLHOUSES, + AdminX: ROUTE_ADMINX_DISPENSERS_KILLHOUSES, + SuperAdmin: ROUTE_SUPER_ADMIN_DISPENSERS_KILLHOUSES, + default: ROUTE_PROVINCE_DISPENSERS_KILLHOUSES, + }, + stewards: { + KillHouse: ROUTE_SLAUGHTER_DISPENSERS_STEWARDS, + AdminX: ROUTE_ADMINX_DISPENSERS_STEWARDS, + SuperAdmin: ROUTE_SUPER_ADMIN_DISPENSERS_STEWARDS, + default: ROUTE_PROVINCE_DISPENSERS_STEWARDS, + }, + inventory: { + AdminX: ROUTE_ADMINX_DISPENSERS_INVENTORY, + SuperAdmin: ROUTE_SUPER_ADMIN_DISPENSERS_INVENTORY, + CityPoultry: ROUTE_CITY_DISPENSERS_INVENTORY, + ProvinceSupervisor: ROUTE_PROVINCE_SUPERVISOR_DISPENSERS_INVENTORY, + default: ROUTE_PROVINCE_DISPENSERS_INVENTORY, + }, + distribution: { + AdminX: ROUTE_ADMINX_SALE_DESTRIBUTION_DETAILS, + SuperAdmin: ROUTE_SUPER_ADMIN_DESTRIBUTION_DETAILS, + ProvinceOperator: ROUTE_PROVINCE_SALE_DESTRIBUTION_DETAILS, + CityPoultry: ROUTE_CITY_REQUEST_DISTRIBUTION, + ProvinceSupervisor: ROUTE_PROVINCE_SUPERVISOR_REQUEST_DISTRIBUTION, + default: ROUTE_PROVINCE_TRANSACTIONS, + }, + transactions: { + AdminX: ROUTE_ADMINX_TRANSACTIONS, + SuperAdmin: ROUTE_SUPER_ADMIN_TRANSACTIONS, + ProvinceFinancial: ROUTE_PROVINCE_FINANCIAL_TRANSACTIONS, + CityPoultry: ROUTE_CITY_REQUEST_TRANSACTIONS, + ProvinceSupervisor: ROUTE_PROVINCE_SUPERVISOR_REQUEST_TRANSACTIONS, + default: ROUTE_PROVINCE_TRANSACTIONS, + }, + stock: { + AdminX: ROUTE_ADMINX_DISPENSERS_STOCK, + SuperAdmin: ROUTE_SUPER_ADMIN_DISPENSERS_STOCK, + ProvinceSupervisor: ROUTE_PROVINCE_SUPERVISOR_DISPENSERS_STOCK, + }, +}; + +const getRoute = (routeType, role) => { + const routeMap = ROUTE_MAP[routeType]; + return routeMap[role] || routeMap.default || null; +}; + +const isActive = (pathname, route) => (pathname === route ? "true" : null); + +export const SlaughterHouseDispensersOperations = () => { + const { pathname } = useLocation(); + const role = getRoleFromUrl(); + const isKillHouse = role === "KillHouse"; + const isAdminX = role === "AdminX"; + const hasStockAccess = [ + "AdminX", + "SuperAdmin", + "ProvinceSupervisor", + ].includes(role); + + const managementRoute = getRoute("management", role); + const managementRouteV2 = getRoute("management", "AdminXX"); + const managementRouteDelegates = getRoute("management", "AdminXXX"); + const killhousesRoute = getRoute("killhouses", role); + const stewardsRoute = getRoute("stewards", role); + const inventoryRoute = getRoute("inventory", role); + const distributionRoute = getRoute("distribution", role); + const transactionsRoute = getRoute("transactions", role); + const stockRoute = getRoute("stock", role); + + return ( + + {isAdminX && ( + + + + } + title="مدیریت نمایندگان" + description="مدیریت نمایندگان" + /> + + + } + title="مدیریت توزیع کنندگان دوم" + description="مدیریت توزیع کنندگان دوم" + /> + + + } + title="مدیریت توزیع کنندگان" + description="مدیریت توزیع کنندگان" + /> + + + {!isKillHouse && ( + + } + title="مدیریت کشتارگاه ها" + description="مدیریت کشتارگاه ها" + /> + + )} + + {!isKillHouse && ( + + } + title="مدیریت مباشرین" + description="مدیریت مباشرین" + /> + + )} + + + )} + + + + {!isKillHouse && inventoryRoute && ( + + } + title="توزیع/فروش کشتارگاه" + description="توزیع/فروش کشتارگاه" + /> + + )} + + {!isKillHouse && distributionRoute && ( + + } + title=" توزیع/فروش مباشر" + description=" توزیع/فروش مباشر" + /> + + )} + + {!isKillHouse && transactionsRoute && ( + + } + title="مدیریت انبار صنوف" + description="تراکنش ها" + /> + + )} + + {hasStockAccess && stockRoute && ( + + } + title="مانده انبار" + description="مانده انبار" + /> + + )} + + + + ); +}; diff --git a/src/features/slaughter-house/components/slaughter-house-dispensers-v2/AllDispensersEditForm.js b/src/features/slaughter-house/components/slaughter-house-dispensers-v2/AllDispensersEditForm.js new file mode 100644 index 0000000..64d3c41 --- /dev/null +++ b/src/features/slaughter-house/components/slaughter-house-dispensers-v2/AllDispensersEditForm.js @@ -0,0 +1,264 @@ +import React, { useContext } from "react"; +import { useFormik } from "formik"; +import * as yup from "yup"; +import { useDispatch } from "react-redux"; +import { Button, TextField, Typography, Box } from "@mui/material"; +import PersonIcon from "@mui/icons-material/Person"; +import PublicIcon from "@mui/icons-material/Public"; +import BadgeIcon from "@mui/icons-material/Badge"; +import CalendarTodayIcon from "@mui/icons-material/CalendarToday"; +import AccountBoxIcon from "@mui/icons-material/AccountBox"; +import BusinessIcon from "@mui/icons-material/Business"; +import { Grid } from "../../../../components/grid/Grid"; +import { SPACING } from "../../../../data/spacing"; +import { CLOSE_MODAL } from "../../../../lib/redux/slices/appSlice"; +import { AppContext } from "../../../../contexts/AppContext"; +import { slaughterHouseEditDispenserService } from "../../services/slaughter-house-submit-dispenser-service"; + +const InfoBox = ({ icon: Icon, label, value, iconSx }) => ( + + + + + {label} + + {value || "-"} + + +); + +const getValidationSchema = () => + yup.object({ + mobile: yup + .string() + .required("شماره همراه الزامی است") + .matches(/^09\d{9}$/, "شماره تلفن باید با 09 شروع شود و 11 رقم باشد"), + }); + +const DispenserForm = ({ formik, userInfo }) => { + return ( +
    + + {userInfo && ( + + + + اطلاعات شخصی + + + + + + + + + + + + + + + + + + + + + )} + + + + + + + + + + + + + + + + + + + {formik.values.dispenser_type === "driver" && ( + <> + + + + {formik.values.pelak && ( + + + + )} + + )} + + + + + + + + + + + + + +
    + ); +}; + +export const AllDispensersEditForm = ({ item, updateTable }) => { + const dispatch = useDispatch(); + const [openNotif] = useContext(AppContext); + + const nationalId = item?.user?.nationalId || item?.user?.nationalCode; + + // Extract userInfo from item.user object + const userInfo = item?.user + ? { + nationalCode: item.user.nationalId || item.user.nationalCode || null, + fatherName: item.user.fatherName || null, + birthday: item.user.birthday || null, + gender: item.user.gender, + identityNo: item.user.identityNo || null, + identitySeries: item.user.identitySeries || null, + identitySerial: item.user.identitySerial || null, + } + : null; + + const formik = useFormik({ + initialValues: { + first_name: item?.user?.firstName || "", + last_name: item?.user?.lastName || "", + mobile: item?.user?.mobile || "", + city: item?.user?.cityName || "", + national_id: nationalId || "", + dispenser_type: item?.dispenserType || "inductor", + limitation_amount: item?.limitationAmount || 0, + driver_car_type: item?.car || "", + pelak: item?.pelak || "", + }, + enableReinitialize: true, + validationSchema: getValidationSchema(), + onSubmit: (values) => { + const submitData = { + key: item?.key, + mobile: values.mobile, + }; + + dispatch(slaughterHouseEditDispenserService(submitData)).then((r) => { + if (r.payload?.error) { + openNotif({ + vertical: "top", + horizontal: "center", + msg: r.payload.error, + severity: "error", + }); + } else { + openNotif({ + vertical: "top", + horizontal: "center", + msg: "عملیات با موفقیت انجام شد.", + severity: "success", + }); + if (updateTable) { + updateTable(); + } + dispatch(CLOSE_MODAL()); + } + }); + }, + }); + + return ; +}; diff --git a/src/features/slaughter-house/components/slaughter-house-dispensers-v2/AllDispensersOperations.js b/src/features/slaughter-house/components/slaughter-house-dispensers-v2/AllDispensersOperations.js new file mode 100644 index 0000000..34a4bf4 --- /dev/null +++ b/src/features/slaughter-house/components/slaughter-house-dispensers-v2/AllDispensersOperations.js @@ -0,0 +1,79 @@ +import { IconButton, Popover, Typography, Button } from "@mui/material"; +import React, { useState } from "react"; +import EditIcon from "@mui/icons-material/Edit"; +import TuneIcon from "@mui/icons-material/Tune"; +import { useDispatch } from "react-redux"; +import { OPEN_MODAL } from "../../../../lib/redux/slices/appSlice"; +import { AllDispensersEditForm } from "./AllDispensersEditForm"; + +export const AllDispensersOperations = ({ item, updateTable }) => { + const [anchorEl, setAnchorEl] = useState(null); + const dispatch = useDispatch(); + + const handleClick = (event) => { + setAnchorEl(event.currentTarget); + }; + + const handleClose = () => { + setAnchorEl(null); + }; + + const open = Boolean(anchorEl); + const id = open ? "popover" : undefined; + + return ( +
    + + + + +
    + +
    +
    +
    + ); +}; diff --git a/src/features/slaughter-house/components/slaughter-house-dispensers-v2/AllDispensersTab.js b/src/features/slaughter-house/components/slaughter-house-dispensers-v2/AllDispensersTab.js new file mode 100644 index 0000000..8ef8617 --- /dev/null +++ b/src/features/slaughter-house/components/slaughter-house-dispensers-v2/AllDispensersTab.js @@ -0,0 +1,162 @@ +import React, { useEffect, useState, useRef } from "react"; +import { Box, Button, Grid, TextField } from "@mui/material"; +import { useDispatch } from "react-redux"; +import { slaughterGetDispenserService } from "../../services/slaughter-get-dispenser-service"; +import ResponsiveTable from "../../../../components/responsive-table/ResponsiveTable"; +import { SPACING } from "../../../../data/spacing"; +import { RiSearchLine } from "react-icons/ri"; +import { AllDispensersOperations } from "./AllDispensersOperations"; + +export const AllDispensersTab = () => { + const dispatch = useDispatch(); + const [data, setData] = useState([]); + const [totalRows, setTotalRows] = useState(0); + const [perPage, setPerPage] = useState(10); + const [textValue, setTextValue] = useState(""); + const [page, setPage] = useState(1); + const [tableData, setTableData] = useState([]); + const isFirstMount = useRef(true); + + const handleTextChange = (e) => setTextValue(e.target.value); + + const fetchApiData = async (pageNum) => { + const response = await dispatch( + slaughterGetDispenserService({ + search: "filter", + value: textValue, + page: pageNum, + page_size: perPage, + }) + ); + + if (response.payload.error) { + console.error("Error fetching data:", response.payload.error); + setData([]); + setTotalRows(0); + } else { + setData(response.payload.data?.results || []); + const count = Number(response.payload.data?.count) || 0; + setTotalRows(count); + } + }; + + const handlePageChange = (pageNum) => { + fetchApiData(pageNum); + setPage(pageNum); + }; + + const handlePerRowsChange = (perRows) => { + setPerPage(Number(perRows)); + setPage(1); + }; + + const updateTableData = () => { + fetchApiData(page !== 0 ? page : 1); + }; + + useEffect(() => { + if (!data || !Array.isArray(data)) { + setTableData([]); + return; + } + const d = data.map((item, i) => { + return [ + page === 1 ? i + 1 : i + perPage * (page - 1) + 1, + item?.user?.firstName || "-", + item?.user?.lastName || "-", + item?.user?.mobile || "-", + item?.user?.cityName || "-", + , + ]; + }); + setTableData(d); + }, [data, page, perPage]); + + useEffect(() => { + fetchApiData(1); + }, []); + + useEffect(() => { + if (isFirstMount.current) { + isFirstMount.current = false; + return; + } + fetchApiData(1); + setPage(1); + }, [perPage]); + + const handleSubmit = async (e) => { + e.preventDefault(); + setPage(1); + const response = await dispatch( + slaughterGetDispenserService({ + search: "filter", + value: textValue, + page: 1, + page_size: perPage, + }) + ); + + if (response.payload.error) { + console.error("Error fetching data:", response.payload.error); + setData([]); + setTotalRows(0); + } else { + setData(response.payload.data?.results || []); + const count = Number(response.payload.data?.count) || 0; + setTotalRows(count); + } + }; + + return ( + + +
    + + + + +
    +
    + + + + +
    + ); +}; diff --git a/src/features/slaughter-house/components/slaughter-house-dispensers-v2/DispenserInfoLimitationForm.js b/src/features/slaughter-house/components/slaughter-house-dispensers-v2/DispenserInfoLimitationForm.js new file mode 100644 index 0000000..a1ef205 --- /dev/null +++ b/src/features/slaughter-house/components/slaughter-house-dispensers-v2/DispenserInfoLimitationForm.js @@ -0,0 +1,135 @@ +import React, { useContext, useState } from "react"; +import { + Button, + TextField, + Typography, + Checkbox, + FormControlLabel, +} from "@mui/material"; +import { useDispatch } from "react-redux"; +import { Grid } from "../../../../components/grid/Grid"; +import { SPACING } from "../../../../data/spacing"; +import { CLOSE_MODAL } from "../../../../lib/redux/slices/appSlice"; +import { AppContext } from "../../../../contexts/AppContext"; +import { slaughterEditDispenserInfoService } from "../../services/slaughter-edit-dispenser-info"; + +export const DispenserInfoLimitationForm = ({ item, updateTable }) => { + const dispatch = useDispatch(); + const [openNotif] = useContext(AppContext); + + const [hasLimitation, setHasLimitation] = useState(item?.limitation || false); + const [governmentalValue, setGovernmentalValue] = useState( + + item?.governmentalLimitationWeight || + 0 + ); + const [freeValue, setFreeValue] = useState( + item?.freeLimitationWeight || 0 + ); + + const handleSubmit = (e) => { + e.preventDefault(); + + const submitData = { + key: item?.key, + limitation: hasLimitation, + governmental_limitation_weight: hasLimitation + ? Number(governmentalValue) + : 0, + free_limitation_weight: hasLimitation ? Number(freeValue) : 0, + }; + + dispatch(slaughterEditDispenserInfoService(submitData)).then((r) => { + if (r.payload?.error) { + openNotif({ + vertical: "top", + horizontal: "center", + msg: r.payload.error, + severity: "error", + }); + } else { + openNotif({ + vertical: "top", + horizontal: "center", + msg: "عملیات با موفقیت انجام شد.", + severity: "success", + }); + if (updateTable) { + updateTable(); + } + dispatch(CLOSE_MODAL()); + } + }); + }; + + return ( +
    + + + + اطلاعات توزیع کننده: + + + {item?.firstName} {item?.lastName} + + + + + setHasLimitation(e.target.checked)} + color="primary" + /> + } + label="محدودیت فروش روزانه" + /> + + + {hasLimitation && ( + <> + + setGovernmentalValue(e.target.value)} + inputProps={{ min: 0 }} + /> + + + + setFreeValue(e.target.value)} + inputProps={{ min: 0 }} + /> + + + )} + + + + + +
    + ); +}; + diff --git a/src/features/slaughter-house/components/slaughter-house-dispensers-v2/DispenserInfoOperations.js b/src/features/slaughter-house/components/slaughter-house-dispensers-v2/DispenserInfoOperations.js new file mode 100644 index 0000000..7ca2d2d --- /dev/null +++ b/src/features/slaughter-house/components/slaughter-house-dispensers-v2/DispenserInfoOperations.js @@ -0,0 +1,140 @@ +import { IconButton, Popover, Typography, Button } from "@mui/material"; +import React, { useState, useContext } from "react"; +import TuneIcon from "@mui/icons-material/Tune"; +import ToggleOnIcon from "@mui/icons-material/ToggleOn"; +import ToggleOffIcon from "@mui/icons-material/ToggleOff"; +import BlockIcon from "@mui/icons-material/Block"; +import { useDispatch } from "react-redux"; +import { AppContext } from "../../../../contexts/AppContext"; +import { OPEN_MODAL } from "../../../../lib/redux/slices/appSlice"; +import { slaughterEditDispenserInfoService } from "../../services/slaughter-edit-dispenser-info"; +import { DispenserInfoLimitationForm } from "./DispenserInfoLimitationForm"; + +export const DispenserInfoOperations = ({ item, updateTable }) => { + const [anchorEl, setAnchorEl] = useState(null); + const dispatch = useDispatch(); + const [openNotif] = useContext(AppContext); + + const handleClick = (event) => { + setAnchorEl(event.currentTarget); + }; + + const handleClose = () => { + setAnchorEl(null); + }; + + const open = Boolean(anchorEl); + const id = open ? "popover" : undefined; + + const isActive = item?.active; + + const handleToggleActive = () => { + handleClose(); + dispatch( + slaughterEditDispenserInfoService({ + key: item?.key, + active: !isActive, + }) + ).then((r) => { + if (r.payload?.error) { + openNotif({ + vertical: "top", + horizontal: "center", + msg: r.payload.error, + severity: "error", + }); + } else { + openNotif({ + vertical: "top", + horizontal: "center", + msg: "عملیات با موفقیت انجام شد.", + severity: "success", + }); + if (updateTable) { + updateTable(); + } + } + }); + }; + + return ( +
    + + + + +
    + + +
    +
    +
    + ); +}; + diff --git a/src/features/slaughter-house/components/slaughter-house-dispensers-v2/KillHouseDispensersTab.js b/src/features/slaughter-house/components/slaughter-house-dispensers-v2/KillHouseDispensersTab.js new file mode 100644 index 0000000..b95c8d1 --- /dev/null +++ b/src/features/slaughter-house/components/slaughter-house-dispensers-v2/KillHouseDispensersTab.js @@ -0,0 +1,199 @@ +import React, { useEffect, useState, useRef } from "react"; +import { Box, Button, Grid, TextField, Chip } from "@mui/material"; +import { useDispatch } from "react-redux"; +import { slaughterGetDispenserInfoService } from "../../services/slaughter-get-dispenser-info"; +import ResponsiveTable from "../../../../components/responsive-table/ResponsiveTable"; +import { SPACING } from "../../../../data/spacing"; +import { RiSearchLine } from "react-icons/ri"; +import { DispenserInfoOperations } from "./DispenserInfoOperations"; + +export const KillHouseDispensersTab = () => { + const dispatch = useDispatch(); + const [data, setData] = useState([]); + const [totalRows, setTotalRows] = useState(0); + const [perPage, setPerPage] = useState(10); + const [textValue, setTextValue] = useState(""); + const [page, setPage] = useState(1); + const [tableData, setTableData] = useState([]); + const isFirstMount = useRef(true); + + const handleTextChange = (e) => setTextValue(e.target.value); + + const fetchApiData = async (pageNum) => { + const response = await dispatch( + slaughterGetDispenserInfoService({ + type: "KillHouse", + search: "filter", + value: textValue, + page: pageNum, + page_size: perPage, + }) + ); + + if (response.payload.error) { + console.error("Error fetching data:", response.payload.error); + setData([]); + setTotalRows(0); + } else { + setData(response.payload.data?.results || []); + const count = Number(response.payload.data?.count) || 0; + setTotalRows(count); + } + }; + + const handlePageChange = (pageNum) => { + fetchApiData(pageNum); + setPage(pageNum); + }; + + const handlePerRowsChange = (perRows) => { + setPerPage(Number(perRows)); + setPage(1); + }; + + useEffect(() => { + if (!data || !Array.isArray(data)) { + setTableData([]); + return; + } + const d = data.map((item, i) => { + const isActive = item?.active; + const hasLimitation = item?.limitation; + const limitationBadge = ( + + ); + + const killhouseDisplay = + item?.killHouse?.name && item?.killHouse?.mobile + ? `${item.killHouse.name} (${item.killHouse.mobile})` + : item?.killHouse?.name + ? item.killHouse.name + : "-"; + + return [ + page === 1 ? i + 1 : i + perPage * (page - 1) + 1, + item?.firstName || "-", + item?.lastName || "-", + item?.mobile || "-", + item?.city || "-", + killhouseDisplay, + limitationBadge, + item?.governmentalLimitationWeight || 0, + item?.freeLimitationWeight || 0, + , + , + ]; + }); + setTableData(d); + }, [data, page, perPage]); + + const updateTableData = () => { + fetchApiData(page); + }; + + useEffect(() => { + fetchApiData(1); + }, []); + + useEffect(() => { + if (isFirstMount.current) { + isFirstMount.current = false; + return; + } + fetchApiData(1); + setPage(1); + }, [perPage]); + + const handleSubmit = async (e) => { + e.preventDefault(); + setPage(1); + const response = await dispatch( + slaughterGetDispenserInfoService({ + type: "KillHouse", + search: "filter", + value: textValue, + page: 1, + page_size: perPage, + }) + ); + + if (response.payload.error) { + console.error("Error fetching data:", response.payload.error); + setData([]); + setTotalRows(0); + } else { + setData(response.payload.data?.results || []); + const count = Number(response.payload.data?.count) || 0; + setTotalRows(count); + } + }; + + return ( + + +
    + + + + +
    +
    + + + + +
    + ); +}; diff --git a/src/features/slaughter-house/components/slaughter-house-dispensers-v2/SlaughterHouseDispensers.js b/src/features/slaughter-house/components/slaughter-house-dispensers-v2/SlaughterHouseDispensers.js new file mode 100644 index 0000000..47115c8 --- /dev/null +++ b/src/features/slaughter-house/components/slaughter-house-dispensers-v2/SlaughterHouseDispensers.js @@ -0,0 +1,30 @@ +import React, { useState } from "react"; +import { Grid } from "../../../../components/grid/Grid"; +import { Tab, Tabs, Box } from "@mui/material"; +import { AllDispensersTab } from "./AllDispensersTab"; +import { KillHouseDispensersTab } from "./KillHouseDispensersTab"; +import { StewardDispensersTab } from "./StewardDispensersTab"; + +export const SlaughterHouseDispensersV2 = () => { + const [value, setValue] = useState(0); + + const handleChange = (event, newValue) => { + setValue(newValue); + }; + + return ( + + + + + + + + + {value === 0 && } + {value === 1 && } + {value === 2 && } + + + ); +}; diff --git a/src/features/slaughter-house/components/slaughter-house-dispensers-v2/StewardDispensersTab.js b/src/features/slaughter-house/components/slaughter-house-dispensers-v2/StewardDispensersTab.js new file mode 100644 index 0000000..b7c1070 --- /dev/null +++ b/src/features/slaughter-house/components/slaughter-house-dispensers-v2/StewardDispensersTab.js @@ -0,0 +1,199 @@ +import React, { useEffect, useState, useRef } from "react"; +import { Box, Button, Grid, TextField, Chip } from "@mui/material"; +import { useDispatch } from "react-redux"; +import { slaughterGetDispenserInfoService } from "../../services/slaughter-get-dispenser-info"; +import ResponsiveTable from "../../../../components/responsive-table/ResponsiveTable"; +import { SPACING } from "../../../../data/spacing"; +import { RiSearchLine } from "react-icons/ri"; +import { DispenserInfoOperations } from "./DispenserInfoOperations"; + +export const StewardDispensersTab = () => { + const dispatch = useDispatch(); + const [data, setData] = useState([]); + const [totalRows, setTotalRows] = useState(0); + const [perPage, setPerPage] = useState(10); + const [textValue, setTextValue] = useState(""); + const [page, setPage] = useState(1); + const [tableData, setTableData] = useState([]); + const isFirstMount = useRef(true); + + const handleTextChange = (e) => setTextValue(e.target.value); + + const fetchApiData = async (pageNum) => { + const response = await dispatch( + slaughterGetDispenserInfoService({ + type: "Steward", + search: "filter", + value: textValue, + page: pageNum, + page_size: perPage, + }) + ); + + if (response.payload.error) { + console.error("Error fetching data:", response.payload.error); + setData([]); + setTotalRows(0); + } else { + setData(response.payload.data?.results || []); + const count = Number(response.payload.data?.count) || 0; + setTotalRows(count); + } + }; + + const handlePageChange = (pageNum) => { + fetchApiData(pageNum); + setPage(pageNum); + }; + + const handlePerRowsChange = (perRows) => { + setPerPage(Number(perRows)); + setPage(1); + }; + + useEffect(() => { + if (!data || !Array.isArray(data)) { + setTableData([]); + return; + } + const d = data.map((item, i) => { + const isActive = item?.active; + const hasLimitation = item?.limitation; + const limitationBadge = ( + + ); + + const stewardDisplay = + item?.steward?.name && item?.steward?.user?.mobile + ? `${item.steward.name} (${item.steward.user.mobile})` + : item?.steward?.name + ? item.steward.name + : "-"; + + return [ + page === 1 ? i + 1 : i + perPage * (page - 1) + 1, + item?.firstName || "-", + item?.lastName || "-", + item?.mobile || "-", + item?.city || "-", + stewardDisplay, + limitationBadge, + item?.governmentalLimitationWeight || 0, + item?.freeLimitationWeight || 0, + , + , + ]; + }); + setTableData(d); + }, [data, page, perPage]); + + const updateTableData = () => { + fetchApiData(page); + }; + + useEffect(() => { + fetchApiData(1); + }, []); + + useEffect(() => { + if (isFirstMount.current) { + isFirstMount.current = false; + return; + } + fetchApiData(1); + setPage(1); + }, [perPage]); + + const handleSubmit = async (e) => { + e.preventDefault(); + setPage(1); + const response = await dispatch( + slaughterGetDispenserInfoService({ + type: "Steward", + search: "filter", + value: textValue, + page: 1, + page_size: perPage, + }) + ); + + if (response.payload.error) { + console.error("Error fetching data:", response.payload.error); + setData([]); + setTotalRows(0); + } else { + setData(response.payload.data?.results || []); + const count = Number(response.payload.data?.count) || 0; + setTotalRows(count); + } + }; + + return ( + + +
    + + + + +
    +
    + + + + +
    + ); +}; diff --git a/src/features/slaughter-house/components/slaughter-house-dispensers/SlaughterHouseDispensers.js b/src/features/slaughter-house/components/slaughter-house-dispensers/SlaughterHouseDispensers.js new file mode 100644 index 0000000..cffe639 --- /dev/null +++ b/src/features/slaughter-house/components/slaughter-house-dispensers/SlaughterHouseDispensers.js @@ -0,0 +1,351 @@ +import React, { useEffect, useState } from "react"; +import { Grid } from "../../../../components/grid/Grid"; +import ResponsiveTable from "../../../../components/responsive-table/ResponsiveTable"; +import { + Button, + IconButton, + Tab, + Tabs, + TextField, + Tooltip, +} from "@mui/material"; +import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl"; +import { + DRAWER, + LOADING_END, + LOADING_START, +} from "../../../../lib/redux/slices/appSlice"; +import { useDispatch } from "react-redux"; +import axios from "axios"; +import { SlaughterHouseSubmitDispenser } from "../slaughter-house-submit-dispenser/SlaughterHouseSubmitDispenser"; +import { SlaughterHouseDispensersOperation } from "../slaughter-house-dispensers-operation/SlaughterHouseDispensersOperation"; +import { slaughterGetDispenserDashboard } from "../../services/slaughter-house-get-dispenser-dashboard"; +import { + ROUTE_ADMINX_DISPENSER_DETAILS, + ROUTE_PROVINCE_DISPENSER_DETAILS, + ROUTE_SLAUGHTER_DISPENSER_DETAILS, + ROUTE_SUPER_ADMIN_DISPENSER_DETAILS, +} from "../../../../routes/routes"; +import { useNavigate } from "react-router-dom"; +import { RiSearchLine } from "react-icons/ri"; +import VisibilityIcon from "@mui/icons-material/Visibility"; + +export const SlaughterHouseDispensers = () => { + const dispatch = useDispatch(); + + const handleTextChange = (event) => { + setTextValue(event.target.value); + }; + + const [data, setData] = useState([]); + const [totalRows, setTotalRows] = useState(0); + const [perPage, setPerPage] = useState(10); + const [textValue, setTextValue] = useState(""); + const [page, setPage] = useState(1); + const [tableData, setTableData] = useState([]); + const [value, setValue] = useState(0); + const [dashboardData, setDashboardData] = useState(); + const navigate = useNavigate(); + + const handleChange = (event, newValue) => { + setValue(newValue); + }; + + const fetchApiData = async (page) => { + let response; + dispatch(LOADING_START()); + response = await axios.get( + `dispenser/?search=filter&value=${textValue}&role=${getRoleFromUrl()}&page=${page}&page_size=${perPage}` + ); + dispatch(LOADING_END()); + setData(response.data.results); + setTotalRows(response.data.count); + }; + + const handlePageChange = (page) => { + fetchApiData(page); + setPage(page); + }; + + const handlePerRowsChange = (perRows) => { + setPerPage(perRows); + setPage(1); + }; + + const updateTable = () => { + fetchApiData(page !== 0 ? page : 1); + }; + + useEffect(() => { + fetchApiData(1); + }, [value]); + + const getDispenserType = (item) => { + let type = ""; + switch (item?.dispenserType) { + case "inductor": + type = "واسطه"; + break; + case "salesman": + type = "فروشنده"; + break; + case "driver": + type = `راننده - ${item?.car} (${item?.pelak})`; + break; + default: + break; + } + + return type; + }; + + useEffect(() => { + const d = data?.map((item, i) => { + return [ + page === 1 ? i + 1 : i + (perPage * page) / 2 + 1, + getDispenserType(item), + item?.user?.fullname, + item?.user?.mobile, + item?.user?.city?.cityName, + item?.killHouse?.name, + item?.limitationAmount?.toLocaleString(), + item?.active ? "فعال" : "غیر فعال", + item?.allocationsInfo?.numberOfAllocations?.toLocaleString(), + item?.allocationsInfo?.totalWeight?.toLocaleString(), + item?.allocationsInfo?.totalQuantity?.toLocaleString(), + item?.allocationsInfo?.numberOfTodayAllocations?.toLocaleString(), + item?.allocationsInfo?.totalTodayQuantity?.toLocaleString(), + item?.allocationsInfo?.totalTodayWeight?.toLocaleString(), + value === 0 ? ( + + ) : ( + + { + navigate( + getRoleFromUrl() === "KillHouse" + ? `${ROUTE_SLAUGHTER_DISPENSER_DETAILS}/${item.key}` + : getRoleFromUrl() === "AdminX" + ? `${ROUTE_ADMINX_DISPENSER_DETAILS}/${item.key}` + : getRoleFromUrl() === "SuperAdmin" + ? `${ROUTE_SUPER_ADMIN_DISPENSER_DETAILS}/${item.key}` + : `${ROUTE_PROVINCE_DISPENSER_DETAILS}/${item.key}` + ); + }} + > + + + + ), + ]; + }); + + setTableData(d); + }, [data, value]); + + useEffect(() => { + fetchApiData(1); + }, [perPage]); + + useEffect(() => { + if (value === 1) { + dispatch(slaughterGetDispenserDashboard()).then((r) => { + setDashboardData(r.payload.data); + }); + } + }, [value]); + + const handleSubmit = async (event) => { + event.preventDefault(); + dispatch(LOADING_START()); + + try { + const response = await axios.get( + `dispenser/?role=${getRoleFromUrl()}&search=filter&value=${textValue}&page=${1}&page_size=${perPage}` + ); + setData(response.data.results); + setTotalRows(response.data.count); + dispatch(LOADING_END()); + } catch (error) { + console.error("Error fetching data:", error); + } + }; + + return ( + + + + + + {value === 0 && ( + <> + + + +
    + + + +
    +
    + + + + )} + + {value === 1 && ( + <> + + + + + +
    + + + +
    +
    + + + + )} +
    + ); +}; diff --git a/src/features/slaughter-house/components/slaughter-house-new-conmplaint/SlaughterHouseNewComplaint.js b/src/features/slaughter-house/components/slaughter-house-new-conmplaint/SlaughterHouseNewComplaint.js new file mode 100644 index 0000000..cb924df --- /dev/null +++ b/src/features/slaughter-house/components/slaughter-house-new-conmplaint/SlaughterHouseNewComplaint.js @@ -0,0 +1,216 @@ +import { + Button, + FormControl, + InputLabel, + MenuItem, + Select, + TextField, + Typography, +} from "@mui/material"; +import { useFormik } from "formik"; +import React, { useContext, useEffect } from "react"; +import { Grid } from "../../../../components/grid/Grid"; +import { ImageUpload } from "../../../../components/image-upload/ImageUpload"; +import { SPACING } from "../../../../data/spacing"; +import { Yup } from "../../../../lib/yup/yup"; +import { fixBase64 } from "../../../../utils/toBase64"; +import { PropTypes } from "prop-types"; +import { useDispatch } from "react-redux"; +import { slaughterNewComplaint } from "../../services/slaughter-new-complaint"; +import { AppContext } from "../../../../contexts/AppContext"; +import { + DRAWER, + LOADING_END, + LOADING_START, +} from "../../../../lib/redux/slices/appSlice"; +import { slaughterGetRegisteredComplaints } from "../../services/slaughter-get-registered-complaints"; +import { slaughterGetComplaints } from "../../services/slaughter-get-complaints"; + +export const SlaughterHouseNewComplaint = ({ barKey, role }) => { + const [openNotif] = useContext(AppContext); + const dispatch = useDispatch(); + const [topic, setTopic] = React.useState(10); + + const [complaintImages, setComplaintImages] = React.useState([]); + const [complaintImagesBase64, setComplaintImagesBase64] = React.useState([]); + + const complaintImageHandler = (imageList, addUpdateIndex) => { + setComplaintImages(imageList); + setComplaintImagesBase64(imageList.map((img) => fixBase64(img.data_url))); + }; + + const isFormValid = (topic) => { + switch (topic) { + case 10: + return ( + formik2.isValid && formik.isValid && complaintImagesBase64.length + ); + default: + return formik.isValid && complaintImagesBase64.length; + } + }; + + const handleChange = (event) => { + setTopic(event.target.value); + }; + + const formik = useFormik({ + initialValues: { + description: "", + }, + validationSchema: Yup.object({ + description: Yup.string() + .required("این فیلد اجباری است!") + .typeError("لطفا فیلد را پر کنید!"), + }), + }); + + const formik2 = useFormik({ + initialValues: { + looses: "", + }, + validationSchema: Yup.object({ + looses: Yup.number() + .required("این فیلد اجباری است!") + .typeError("لطفا عدد وارد کنید!"), + }), + }); + + useEffect(() => { + formik.validateForm(); + formik2.validateForm(); + }, []); + + return ( + + + + موضوع + + + + {topic === 10 && ( + + )} + + + + پیوست تصویر + + + + + + + ); +}; + +SlaughterHouseNewComplaint.propTypes = { + barKey: PropTypes.any, + role: PropTypes.any, +}; diff --git a/src/features/slaughter-house/components/slaughter-house-submit-dispenser/SlaughterHouseSubmitDispenser.js b/src/features/slaughter-house/components/slaughter-house-submit-dispenser/SlaughterHouseSubmitDispenser.js new file mode 100644 index 0000000..f875238 --- /dev/null +++ b/src/features/slaughter-house/components/slaughter-house-submit-dispenser/SlaughterHouseSubmitDispenser.js @@ -0,0 +1,311 @@ +import React, { useContext, useEffect, useState } from "react"; +import { useFormik } from "formik"; +import * as Yup from "yup"; +import { + TextField, + Button, + RadioGroup, + FormControlLabel, + Radio, + FormControl, + FormLabel, + Box, + MenuItem, +} from "@mui/material"; +import { useDispatch, useSelector } from "react-redux"; +import { + slaughterHouseEditDispenserService, + slaughterHouseSubmitDispenserService, +} from "../../services/slaughter-house-submit-dispenser-service"; +import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl"; +import { provinceGetCitiesService } from "../../../province/services/province-get-cities"; +import { CarPelak } from "../../../../components/car-pelak/CarPelak"; +import { Grid } from "../../../../components/grid/Grid"; +import { AppContext } from "../../../../contexts/AppContext"; +import { DRAWER } from "../../../../lib/redux/slices/appSlice"; + +const validationSchema = Yup.object({ + mobile: Yup.string() + .required("این فیلد اجباری است!") + .min(11, "شماره موبایل باید 11 رقم باشد") + .max(11, "شماره موبایل باید 11 رقم باشد") + .matches(/^09\d{9}$/, "شماره موبایل باید با 09 شروع شود و 11 رقم باشد"), + first_name: Yup.string().required("این فیلد اجباریست!"), + last_name: Yup.string().required("این فیلد اجباریست!"), + city: Yup.string().required("این فیلد اجباریست!"), + national_id: Yup.string() + .matches(/^\d{10}$/, "کد ملی ده رقمی است!") + .required("این فیلد اجباریست!"), + dispenser_type: Yup.string().required("این فیلد اجباریست!"), + limitation_amount: Yup.number() + .min(0, "عدد مثبت وارد کنید!") + .required("سقف محدودیت اجباری است"), + driver_car_type: Yup.string().when("dispenser_type", { + is: "driver", + then: Yup.string().required("نوع خودرو اجباری است!"), + }), +}); + +export const SlaughterHouseSubmitDispenser = ({ + updateTable, + isEdit, + item, +}) => { + const dispatch = useDispatch(); + const { provinceGetCities } = useSelector((state) => state.provinceSlice); + const [driverPelak, setDriverPelak] = useState([]); + + const carPelakHandleChange = (pelak1, pelak2, pelak3, pelak4) => { + setDriverPelak([pelak1, pelak2, pelak3, pelak4]); + }; + const [openNotif] = useContext(AppContext); + + useEffect(() => { + dispatch(provinceGetCitiesService()); + }, []); + + const formik = useFormik({ + initialValues: { + mobile: item?.user?.mobile ? item?.user?.mobile : "", + first_name: item?.user?.firstName ? item?.user?.firstName : "", + last_name: item?.user?.lastName ? item?.user?.lastName : "", + city: item?.user?.city?.cityName ? item?.user?.city?.cityName : "", + national_id: item?.user?.nationalId ? item?.user?.nationalId : "", + dispenser_type: item?.dispenserType ? item?.dispenserType : "inductor", + limitation_amount: item?.limitation_amount ? item?.limitation_amount : 0, + driver_car_type: item?.car ? item?.car : "", + }, + validationSchema, + onSubmit: (values) => { + if (!isEdit) { + dispatch( + slaughterHouseSubmitDispenserService({ + mobile: values.mobile, + first_name: values.first_name, + last_name: values.last_name, + city: values.city, + national_id: values.national_id, + dispenser_type: values.dispenser_type, + limitation_amount: values.limitation_amount, + role: getRoleFromUrl(), + pelak: + values.dispenser_type === "driver" + ? driverPelak[0] + + " " + + driverPelak[1] + + " " + + driverPelak[2] + + " " + + driverPelak[3] + : null, + car: values.driver_car_type ? values.driver_car_type : null, + }) + ).then((r) => { + if (r.payload.error) { + openNotif({ + vertical: "top", + horizontal: "center", + msg: r.payload.error, + severity: "error", + }); + } else { + dispatch(DRAWER({ right: false, bottom: false, content: null })); + updateTable(); + openNotif({ + vertical: "top", + horizontal: "center", + msg: "عملیات با موفقیت انجام شد.", + severity: "success", + }); + } + }); + } else { + dispatch( + slaughterHouseEditDispenserService({ + type: "update-profile", + dispenser_key: item?.key, + mobile: values.mobile, + first_name: values.first_name, + last_name: values.last_name, + city: values.city, + national_id: values.national_id, + dispenser_type: values.dispenser_type, + limitation_amount: values.limitation_amount, + role: getRoleFromUrl(), + pelak: + values.dispenser_type === "driver" + ? driverPelak[0] + + " " + + driverPelak[1] + + " " + + driverPelak[2] + + " " + + driverPelak[3] + : null, + car: values.driver_car_type ? values.driver_car_type : null, + }) + ).then((r) => { + if (r.payload.error) { + openNotif({ + vertical: "top", + horizontal: "center", + msg: r.payload.error, + severity: "error", + }); + } else { + dispatch(DRAWER({ right: false, bottom: false, content: null })); + updateTable(); + openNotif({ + vertical: "top", + horizontal: "center", + msg: "عملیات با موفقیت انجام شد.", + severity: "success", + }); + } + }); + } + }, + }); + + return ( + + + + + + + + {provinceGetCities?.map((city) => ( + + {city.name} + + ))} + + + + + ماهیت + + } + label="واسطه" + /> + } + label="فروشنده" + /> + } label="راننده" /> + + + {formik.values.dispenser_type === "driver" && ( + <> + + + + + + )} + + + + ); +}; diff --git a/src/features/slaughter-house/components/slaughter-inventory-free-buy-bars-alives/SlaughterInventoryFreeBuyBarsAlives.js b/src/features/slaughter-house/components/slaughter-inventory-free-buy-bars-alives/SlaughterInventoryFreeBuyBarsAlives.js new file mode 100644 index 0000000..2dd29bb --- /dev/null +++ b/src/features/slaughter-house/components/slaughter-inventory-free-buy-bars-alives/SlaughterInventoryFreeBuyBarsAlives.js @@ -0,0 +1,237 @@ +import React, { useContext, useEffect, useState } from "react"; +import axios from "axios"; +import { useDispatch, useSelector } from "react-redux"; +import { Button, IconButton, Tooltip } from "@mui/material"; +import { Grid } from "../../../../components/grid/Grid"; +import { SPACING } from "../../../../data/spacing"; +import ResponsiveTable from "../../../../components/responsive-table/ResponsiveTable"; +import { + LOADING_END, + LOADING_START, + OPEN_MODAL, +} from "../../../../lib/redux/slices/appSlice"; +import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl"; +import { formatJustDate } from "../../../../utils/formatTime"; +import ShowImage from "../../../../components/show-image/ShowImage"; +import { SlaughterHouseVetBarsOperation } from "../../../slaughter-house-vet/components/slaughter-house-vet-bars-operation/SlaughterHouseVetBarsOperation"; +import SystemUpdateAltIcon from "@mui/icons-material/SystemUpdateAlt"; +import { slaughterGetProfile } from "../../services/slaughter-get-profile"; +import { CheckCleanceCode } from "../../../../components/check-clearance-code/ChechClearanceCode"; +import { SlaughterFreeBarsAlivesOperations } from "../slaughter-free-bars-alives-operations/SlaughterFreeBarsAlivesOperations"; +import { AppContext } from "../../../../contexts/AppContext"; +import { checkPathStartsWith } from "../../../../utils/checkPathStartsWith"; + +export const SlaughterInventoryFreeBuyBarsAlives = ({ + title, + barState, + fetchDashboardData, + withDate, + selectedDate1, + selectedDate2, + searchValue, +}) => { + const dispatch = useDispatch(); + const [openNotif] = useContext(AppContext); + const selectedSubUser = useSelector( + (state) => state.userSlice.selectedSubUser + ); + + useEffect(() => { + dispatch( + slaughterGetProfile({ + role_key: checkPathStartsWith("slaughter") + ? selectedSubUser?.key || "" + : "", + }) + ); + }, [selectedSubUser?.key]); + + const [data, setData] = useState([]); + const [totalRows, setTotalRows] = useState(0); + const [perPage, setPerPage] = useState(10); + const [page, setPage] = useState(1); + const [tableData, setTableData] = useState([]); + + const fetchApiData = async (page) => { + let response; + dispatch(LOADING_START()); + try { + response = await axios.get( + `kill_house_free_bar/?type=live&role=${getRoleFromUrl()}${ + checkPathStartsWith("slaughter") + ? `&role_key=${selectedSubUser?.key}` + : "" + }&page=${page}&page_size=${perPage}&bar_state=${barState}&date_type=input${ + withDate ? `&date1=${selectedDate1}&date2=${selectedDate2}` : "" + }${searchValue ? `&search=filter&value=${searchValue}` : ""}` + ); + setData(response.data.results); + setTotalRows(response.data.count); + } catch (error) { + console.error("Error fetching data:", error); + } finally { + dispatch(LOADING_END()); + } + }; + + const handlePageChange = (page) => { + fetchApiData(page); + setPage(page); + }; + + const handlePerRowsChange = (perRows) => { + setPerPage(perRows); + setPage(1); + }; + + const updateTable = () => { + fetchApiData(page !== 0 ? page : 1); + fetchDashboardData(); + }; + + useEffect(() => { + fetchApiData(1); + }, [ + perPage, + withDate, + selectedDate1, + selectedDate2, + searchValue, + selectedSubUser?.key, + ]); + + useEffect(() => { + const d = data?.map((item, i) => { + return [ + page === 1 ? i + 1 : i + perPage * (page - 1) + 1, + item?.barCode || "-", + item?.registerType === "automatic" ? "سیستمی" : "دستی", + formatJustDate(item.createDate), + `${item?.killHouse?.name} (${item?.killHouse?.killHouseOperator?.user?.mobile})`, + item?.exclusiveKiller + ? `${item?.exclusiveKiller?.name} (${item?.exclusiveKiller?.killHouseOperator?.user?.mobile})` + : "-", + item.buyType === "live" ? "مرغ زنده" : "لاشه", + item.poultryName, + `${item.province}/${item.city}`, + , + item.quantity.toLocaleString(), + item.liveWeight.toLocaleString(), + formatJustDate(item.date), + item.numberOfCarcasses.toLocaleString(), + item.weightOfCarcasses.toLocaleString(), + item?.weightLoss ? item?.weightLoss + "%" : "-", + , + <> + {getRoleFromUrl() === "KillHouse" ? ( + + ) : ( + + )} + , + ]; + }); + + setTableData(d); + }, [data, page, perPage]); + + const userKey = useSelector((state) => state.userSlice.userProfile.key); + + return ( + + + + + { + openNotif({ + vertical: "top", + horizontal: "center", + msg: "فایل اکسل در حال دانلود می باشد، این علمیات ممکن است زمان بر باشد لطفا صبر کنید.", + severity: "success", + }); + const link = `${ + axios.defaults.baseURL + }kill_house_free_bar_excel/?role=${getRoleFromUrl()}${ + checkPathStartsWith("slaughter") + ? `&role_key=${selectedSubUser?.key}` + : "" + }&key=${userKey}&type=live&bar_state=${barState}${ + withDate + ? `&date1=${selectedDate1}&date2=${selectedDate2}` + : "" + }`; + window.location.href = link; + }} + > + + + + + } + data={tableData} + columns={[ + "ردیف", + "کد بار", + "نوع بار", + "تاریخ خرید", + "خریدار", + "کشتارکن", + "محصول", + "فروشنده", + "استان/شهر", + "کدقرنطینه", + "حجم زنده", + "وزن زنده (کیلوگرم)", + "تاریخ ورود به انبار", + "حجم لاشه", + "وزن لاشه (کیلوگرم)", + "درصد افت", + "بارنامه", + "عملیات", + ]} + handlePageChange={handlePageChange} + totalRows={totalRows} + page={page} + perPage={perPage} + handlePerRowsChange={handlePerRowsChange} + title={title} + /> + + + ); +}; diff --git a/src/features/slaughter-house/components/slaughter-inventory-free-buy-bars/SlaughterInventoryFreeBuyBars.js b/src/features/slaughter-house/components/slaughter-inventory-free-buy-bars/SlaughterInventoryFreeBuyBars.js new file mode 100644 index 0000000..23584f4 --- /dev/null +++ b/src/features/slaughter-house/components/slaughter-inventory-free-buy-bars/SlaughterInventoryFreeBuyBars.js @@ -0,0 +1,525 @@ +import React, { useContext, useEffect, useState } from "react"; +import moment from "moment"; +import axios from "axios"; +import { useDispatch, useSelector } from "react-redux"; +import { Button, Checkbox, Tab, Tabs, TextField, Tooltip } from "@mui/material"; +import { DatePicker } from "@mui/x-date-pickers"; +import { Grid } from "../../../../components/grid/Grid"; +import { SPACING } from "../../../../data/spacing"; +import ResponsiveTable from "../../../../components/responsive-table/ResponsiveTable"; +import { + DRAWER, + LOADING_END, + LOADING_START, + OPEN_MODAL, +} from "../../../../lib/redux/slices/appSlice"; +import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl"; +import { AppContext } from "../../../../contexts/AppContext"; +import { SlaughterFreeBarsOperations } from "../slaughter-free-bars-operations/SlaughterFreeBarsOperations"; +import { formatJustDate } from "../../../../utils/formatTime"; +import ShowImage from "../../../../components/show-image/ShowImage"; +import { SlaughterSubmitFreeBar } from "../slaughter-submit-free-bar/SlaughterSubmitFreeBar"; +import { SlaughterHouseVetBarsOperation } from "../../../slaughter-house-vet/components/slaughter-house-vet-bars-operation/SlaughterHouseVetBarsOperation"; +import { RiFileExcel2Fill, RiSearchLine } from "react-icons/ri"; +import { slaughterGetProfile } from "../../services/slaughter-get-profile"; +import { vetFarmGetOutProvinceDashboard } from "../../../vet-farm/services/vet-farm-get-out-province-dashboard"; +import ToggleOffOutlinedIcon from "@mui/icons-material/ToggleOffOutlined"; +import ToggleOnIcon from "@mui/icons-material/ToggleOn"; +import { SlaughterInventoryFreeBuyBarsAlives } from "../slaughter-inventory-free-buy-bars-alives/SlaughterInventoryFreeBuyBarsAlives"; +import { checkPathStartsWith } from "../../../../utils/checkPathStartsWith"; + +export const SlaughterInventoryFreeBuyBars = () => { + const dispatch = useDispatch(); + const [activeTab, setActiveTab] = useState(0); + const handleTabChange = (event, newValue) => { + setActiveTab(newValue); + }; + const selectedSubUser = useSelector( + (state) => state.userSlice.selectedSubUser + ); + + const [, , selectedDate1, setSelectedDate1, selectedDate2, setSelectedDate2] = + useContext(AppContext); + + useEffect(() => { + const currentDate = moment(new Date()).format("YYYY-MM-DD"); + setSelectedDate1(currentDate); + setSelectedDate2(currentDate); + }, []); + + const handleTextChange = (event) => { + setTextValue(event.target.value); + }; + + useEffect(() => { + dispatch( + slaughterGetProfile({ + role_key: checkPathStartsWith("slaughter") + ? selectedSubUser?.key || "" + : "", + }) + ); + }, [selectedSubUser?.key, dispatch]); + + const [data, setData] = useState([]); + const [totalRows, setTotalRows] = useState(0); + const [perPage, setPerPage] = useState(10); + const [textValue, setTextValue] = useState(""); + const [page, setPage] = useState(1); + const [tableData, setTableData] = useState([]); + const [withDate, setWithDate] = useState(false); + const [searchValue, setSearchValue] = useState(""); + + const fetchApiData = async (page) => { + dispatch(LOADING_START()); + const response = await axios.get( + `kill_house_free_bar/?type=${ + activeTab === 0 ? "live" : "carcass" + }&dashboard=true&search=filter&value=${searchValue}&role=${getRoleFromUrl()}${ + checkPathStartsWith("slaughter") + ? `&role_key=${selectedSubUser?.key}` + : "" + }${ + withDate ? `&date1=${selectedDate1}&date2=${selectedDate2}` : "" + }&page=${page}&page_size=${perPage}&date_type=input` + ); + dispatch(LOADING_END()); + setData(response.data.results); + setTotalRows(response.data.count); + }; + + const handlePageChange = (page) => { + fetchApiData(page); + setPage(page); + }; + + const handlePerRowsChange = (perRows) => { + setPerPage(perRows); + setPage(1); + }; + + const updateTable = () => { + setPage(1); + fetchApiData(1); + fetchDashboardData(); + }; + + const fetchDashboardData = () => { + dispatch( + vetFarmGetOutProvinceDashboard({ + search: "filter", + role: getRoleFromUrl(), + role_key: checkPathStartsWith("slaughter") + ? selectedSubUser?.key || "" + : "", + value: searchValue, + type: activeTab === 0 ? "live" : "carcass", + ...(withDate && { + date1: selectedDate1, + date2: selectedDate2, + }), + }) + ).then((r) => { + setDashboardData(r.payload.data); + }); + }; + + useEffect(() => { + fetchApiData(page !== 0 ? page : 1); + fetchDashboardData(); + }, [ + withDate, + selectedDate1, + selectedDate2, + perPage, + activeTab, + searchValue, + selectedSubUser?.key, + ]); + + useEffect(() => { + const d = data?.map((item, i) => { + return [ + page === 1 ? i + 1 : i + perPage * (page - 1) + 1, + item?.barCode || "-", + formatJustDate(item.createDate), + `${item?.killHouse?.name} (${item?.killHouse?.killHouseOperator?.user?.mobile})`, + item?.exclusiveKiller + ? `${item?.exclusiveKiller?.name} (${item?.exclusiveKiller?.killHouseOperator?.user?.mobile})` + : "-", + item.buyType === "live" ? "مرغ زنده" : "لاشه", + item.poultryName, + `${item.province}/${item.city}`, + item.barClearanceCode, + item.numberOfCarcasses.toLocaleString(), + item.weightOfCarcasses.toLocaleString(), + , + <> + {getRoleFromUrl() === "KillHouse" ? ( + + ) : ( + + )} + , + ]; + }); + + setTableData(d); + }, [data]); + + const handleSubmit = async (event) => { + event.preventDefault(); + setSearchValue(textValue); + }; + + const userKey = useSelector((state) => state.userSlice.userProfile.key); + const [dashboardData, setDashboardData] = useState([]); + + return ( + + + + + + + + {activeTab === 0 && ( + + + } + checkedIcon={} + checked={withDate} + onChange={() => { + setWithDate(!withDate); + fetchApiData(1); + }} + color="primary" + size="large" + /> + + ( + + )} + value={selectedDate1} + onChange={(e) => { + setSelectedDate1(moment(e).format("YYYY-MM-DD")); + }} + /> + + + ( + + )} + value={selectedDate2} + onChange={(e) => { + setSelectedDate2(moment(e).format("YYYY-MM-DD")); + }} + /> + + +
    + + + +
    +
    +
    + )} + + + + + + + {activeTab === 0 ? ( + + ) : ( + + )} + + + {activeTab === 0 ? ( + <> + + + + + ) : ( + <> +
    + + + + + ( + + )} + value={selectedDate1} + onChange={(e) => { + setSelectedDate1(moment(e).format("YYYY-MM-DD")); + }} + disabled={!withDate} + /> + + + ( + + )} + value={selectedDate2} + onChange={(e) => { + setSelectedDate2(moment(e).format("YYYY-MM-DD")); + }} + disabled={!withDate} + /> + + + + + +
    + + + )} +
    +
    + ); +}; diff --git a/src/features/slaughter-house/components/slaughter-inventory-in-province-bars/SlaughterInventoryInProvinceBars.js b/src/features/slaughter-house/components/slaughter-inventory-in-province-bars/SlaughterInventoryInProvinceBars.js new file mode 100644 index 0000000..0dce5b9 --- /dev/null +++ b/src/features/slaughter-house/components/slaughter-inventory-in-province-bars/SlaughterInventoryInProvinceBars.js @@ -0,0 +1,337 @@ +import React, { useEffect, useState, useCallback } from "react"; +import { + Button, + Checkbox, + FormControl, + FormControlLabel, + InputLabel, + IconButton, + MenuItem, + Select, + TextField, + Tooltip, +} from "@mui/material"; +import { DatePicker } from "@mui/x-date-pickers"; +import moment from "moment"; +import { useDispatch, useSelector } from "react-redux"; +import axios from "axios"; +import { + LOADING_END, + LOADING_START, + OPEN_MODAL, +} from "../../../../lib/redux/slices/appSlice"; +import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl"; +import ResponsiveTable from "../../../../components/responsive-table/ResponsiveTable"; +import { Grid } from "../../../../components/grid/Grid"; +import { SlaughterSubmitRealInventory } from "../slaughter-submit-real-inventory/SlaughterSubmitRealInventory"; +import SettingsIcon from "@mui/icons-material/Settings"; +import { formatJustDate } from "../../../../utils/formatTime"; +import { RiSearchLine } from "react-icons/ri"; +import { checkPathStartsWith } from "../../../../utils/checkPathStartsWith"; + +export const SlaughterInventoryInProvinceBars = ({ type }) => { + const [selectedDate1, setSelectedDate1] = useState( + moment(new Date()).format("YYYY-MM-DD") + ); + const selectedSubUser = useSelector( + (state) => state.userSlice.selectedSubUser + ); + const [selectedDate2, setSelectedDate2] = useState( + moment(new Date()).format("YYYY-MM-DD") + ); + const dispatch = useDispatch(); + + const handleTextChange = (event) => { + setTextValue(event.target.value); + }; + const [withDate, setWithDate] = useState(type === "entered" ? true : false); + const [data, setData] = useState([]); + const [totalRows, setTotalRows] = useState(0); + const [perPage, setPerPage] = useState(10); + const [textValue, setTextValue] = useState(""); + const [page, setPage] = useState(1); + const [tableData, setTableData] = useState([]); + const [quota, setQuota] = useState("all"); + + const fetchApiData = useCallback( + async (page) => { + dispatch(LOADING_START()); + const response = await axios.get( + `bars_for_kill_house/?search=filter&value=${textValue}&role=${getRoleFromUrl()}${ + withDate + ? `&date1=${selectedDate1}${ + checkPathStartsWith("slaughter") + ? `&role_key=${selectedSubUser?.key}` + : "" + }&date2=${selectedDate2}` + : `` + }&page=${page}&page_size=${perPage}&type=${type}"a=${quota}` + ); + dispatch(LOADING_END()); + setData(response.data.results); + setTotalRows(response.data.count); + }, + [ + textValue, + withDate, + selectedDate1, + selectedDate2, + perPage, + type, + quota, + dispatch, + setData, + selectedSubUser?.key, + setTotalRows, + ] + ); + + const handlePageChange = (page) => { + fetchApiData(page); + setPage(page); + }; + + const handlePerRowsChange = (perRows) => { + setPerPage(perRows); + setPage(1); + }; + + const updateTable = () => { + fetchApiData(page !== 0 ? page : 1); + }; + + useEffect(() => { + const d = data?.map((item, i) => { + return [ + page === 1 ? i + 1 : i + perPage * (page - 1) + 1, + item?.barCode, + formatJustDate(item?.poultryRequest?.date), + `${item?.poultryRequest?.poultryName} (${item?.poultryRequest?.poultryMobile}) - ${item?.poultryRequest?.poultryUserName}`, + item?.poultryRequest?.poultryCity, + `${item?.killhouseUser?.killer ? "کشتارکن" : "کشتارگاه"} ${ + item?.killhouseUser?.name + } (${item?.killhouseUser?.killHouseOperator?.user?.mobile})`, + item?.poultryRequest?.poultryReqOrderCode, + item?.freezing ? "انجماد" : item?.export ? "صادرات" : "عادی", + item?.killer + ? `${item?.killer?.name} (${item?.killer?.killHouseOperator?.user?.mobile})` + : "-", + item?.poultryRequest?.freeSaleInProvince ? "آزاد" : "دولتی", + item?.poultryRequest?.chickenBreed, + `${item?.addCar?.driver?.driverName}/${item?.addCar?.driver?.typeCar}`, + item?.addCar?.driver?.healthCode + ? item?.addCar?.driver?.healthCode + : "-", + item?.clearanceCode ? item?.clearanceCode : "-", + item?.acceptedRealQuantity?.toLocaleString(), + item?.acceptedRealWeight?.toLocaleString(), + item?.weightInfo?.state, + item?.wareHouseAcceptedRealQuantity.toLocaleString(), + item?.wareHouseAcceptedRealWeight.toLocaleString(), + item?.weightInfo?.weightLoss + ? item?.weightInfo?.weightLoss?.toFixed(2) + "%" + : 0 + "%", + item?.weightInfo?.inputLoss + ? item?.weightInfo?.inputLoss?.toFixed(2) + "%" + : 0 + "%", + item?.dateOfWareHouse ? formatJustDate(item?.dateOfWareHouse) : "-", + + { + dispatch( + OPEN_MODAL({ + title: "ثبت موجودی واقعی", + content: ( + + ), + }) + ); + }} + > + + + , + ]; + }); + + setTableData(d); + }, [data]); + + useEffect(() => { + fetchApiData(1); + }, [fetchApiData]); + + const handleSubmit = async (event) => { + event.preventDefault(); + dispatch(LOADING_START()); + + try { + const response = await axios.get( + `bars_for_kill_house/?role=${getRoleFromUrl()}${ + checkPathStartsWith("slaughter") + ? `&role_key=${selectedSubUser?.key}` + : "" + }&search=filter&value=${textValue}${ + withDate ? `&date1=${selectedDate1}&date2=${selectedDate2}` : `` + }&page=${1}&page_size=${perPage}&type=${type}"a=${quota}` + ); + setData(response.data.results); + setTotalRows(response.data.count); + dispatch(LOADING_END()); + } catch (error) { + console.error("Error fetching data:", error); + } + }; + + return ( + + + + {type === "notentered" && ( + + setWithDate(!withDate)} + color="primary" + /> + } + /> + + )} + + + ( + + )} + value={selectedDate1} + onChange={(e) => { + setSelectedDate1(moment(e).format("YYYY-MM-DD")); + }} + /> + + + ( + + )} + value={selectedDate2} + onChange={(e) => { + setSelectedDate2(moment(e).format("YYYY-MM-DD")); + }} + /> + + + + + نوع فروش + + + + +
    + + + +
    +
    + + +
    + ); +}; diff --git a/src/features/slaughter-house/components/slaughter-inventory-operation/SlaughterInventoryOperation.js b/src/features/slaughter-house/components/slaughter-inventory-operation/SlaughterInventoryOperation.js new file mode 100644 index 0000000..68cc3dd --- /dev/null +++ b/src/features/slaughter-house/components/slaughter-inventory-operation/SlaughterInventoryOperation.js @@ -0,0 +1,125 @@ +import { VscFolderActive, VscNewFolder } from "react-icons/vsc"; +import { useLocation } from "react-router-dom"; +import { Grid } from "../../../../components/grid/Grid"; +import LinkItem from "../../../../components/link-item/LinkItem"; +import { NavLink } from "../../../../components/nav-link/NavLink"; +import { SPACING } from "../../../../data/spacing"; +import { + ROUTE_SLAUGHTER_INVENTORY_SELL_CARCASS_IN_PROVINCE, + ROUTE_SLAUGHTER_INVENTORY_SELL_CARCASS_OUT_PROVINCE, + ROUTE_SLAUGHTER_INVENTORY_STOCK, + ROUTE_SLAUGHTER_OUT_PROVINCE_BUY, + ROUTE_SLAUGHTER_SEGMENTATION, +} from "../../../../routes/routes"; +import { slaughterGetProfile } from "../../services/slaughter-get-profile"; +import { + LOADING_END, + LOADING_START, +} from "../../../../lib/redux/slices/appSlice"; +import { useDispatch, useSelector } from "react-redux"; +import { useEffect } from "react"; +// import moment from "moment"; + +export const SlaughterInventoryOperation = () => { + const dispatch = useDispatch(); + const { pathname } = useLocation(); + const { profile } = useSelector((state) => state.slaughterSlice); + + useEffect(() => { + if (!profile) { + dispatch(LOADING_START()); + dispatch(slaughterGetProfile()).then((r) => { + dispatch(LOADING_END()); + }); + } + }, []); + + return ( + + + } + title="ورود به انبار" + /> + + + + } + title="فروش داخل استان" + /> + + + + } + title="فروش به خارج استان" + /> + + + + } + title="خرید خارج از استان" + description="درخواست های در انتظار عملیات وارد کردن اطلاعات بارهای دریافتی" + /> + + + + } + title="قطعه بندی" + /> + + + {/* + } + title="سهم بندی اتوماتیک مباشرین" + /> + */} + + ); +}; diff --git a/src/features/slaughter-house/components/slaughter-inventory-summary/SlaughterInventorySummary.js b/src/features/slaughter-house/components/slaughter-inventory-summary/SlaughterInventorySummary.js new file mode 100644 index 0000000..ad18a72 --- /dev/null +++ b/src/features/slaughter-house/components/slaughter-inventory-summary/SlaughterInventorySummary.js @@ -0,0 +1,121 @@ +import React, { useEffect } from "react"; +import { Grid } from "../../../../components/grid/Grid"; +import ResponsiveTable from "../../../../components/responsive-table/ResponsiveTable"; +import { SlaughterShowProducts } from "../slaughter-show-products/SlaughterShowProducts"; +import { useSelector, useDispatch } from "react-redux"; +import { SPACING } from "../../../../data/spacing"; +import { Button } from "@mui/material"; +import { DRAWER } from "../../../../lib/redux/slices/appSlice"; +import { SlaughterSubmitOperations } from "../slaughter-submit-operations/SlaughterSubmitOperations"; +import { fetchSlaughterBroadcastAndProducts } from "../../services/handle-fetch-slaughter-products"; +import { checkPathStartsWith } from "../../../../utils/checkPathStartsWith"; + +export const SlaughterInventorySummary = ({ priceInfo }) => { + const { distributionInfo, slaughterProducts } = useSelector( + (state) => state.slaughterSlice + ); + const selectedSubUser = useSelector( + (state) => state.userSlice.selectedSubUser + ); + const dispatch = useDispatch(); + + const updateTable = () => { + dispatch( + fetchSlaughterBroadcastAndProducts({ + role_key: checkPathStartsWith("slaughter") + ? selectedSubUser?.key || "" + : "", + }) + ); + }; + + useEffect(() => { + updateTable(); + }, [selectedSubUser?.key]); + + return ( + + + + + + + ); +}; diff --git a/src/features/slaughter-house/components/slaughter-inventory/SlaughterInventory.js b/src/features/slaughter-house/components/slaughter-inventory/SlaughterInventory.js new file mode 100644 index 0000000..48cc42a --- /dev/null +++ b/src/features/slaughter-house/components/slaughter-inventory/SlaughterInventory.js @@ -0,0 +1,116 @@ +import React, { useEffect, useState } from "react"; +import { Grid } from "../../../../components/grid/Grid"; + +import { Tab, Tabs } from "@mui/material"; +import { SPACING } from "../../../../data/spacing"; +import { SlaughterShowProducts } from "../slaughter-show-products/SlaughterShowProducts"; +import { SlaughterInventoryInProvinceBars } from "../slaughter-inventory-in-province-bars/SlaughterInventoryInProvinceBars"; +import { SlaughterInventoryFreeBuyBars } from "../slaughter-inventory-free-buy-bars/SlaughterInventoryFreeBuyBars"; +import { slaughterGetBarsInfo } from "../../services/slaughter-get-distribution-info"; +import { useDispatch } from "react-redux"; +import ResponsiveTable from "../../../../components/responsive-table/ResponsiveTable"; +import { checkPathStartsWith } from "../../../../utils/checkPathStartsWith"; +import { useSelector } from "react-redux"; + +export const SlaughterInventory = () => { + const [value, setValue] = useState("0"); + const [barsInfo, setBarsInfo] = useState([]); + const selectedSubUser = useSelector( + (state) => state.userSlice.selectedSubUser + ); + const handleChange = (event, newValue) => { + setValue(newValue); + }; + + const dispatch = useDispatch(); + + useEffect(() => { + dispatch( + slaughterGetBarsInfo({ + role_key: checkPathStartsWith("slaughter") + ? selectedSubUser?.key || "" + : "", + }) + ).then((r) => { + setBarsInfo(r.payload.data); + }); + }, [dispatch, selectedSubUser?.key]); + + return ( + + + + + + + + + + + + + {value === "0" && ( + + + + + + + + + + + + + )} + + {value === "1" && ( + + + + )} + + ); +}; diff --git a/src/features/slaughter-house/components/slaughter-manage-bars/SlaughterManageBars.js b/src/features/slaughter-house/components/slaughter-manage-bars/SlaughterManageBars.js new file mode 100644 index 0000000..3a8babc --- /dev/null +++ b/src/features/slaughter-house/components/slaughter-manage-bars/SlaughterManageBars.js @@ -0,0 +1,656 @@ +import { useContext, useEffect, useState, useMemo, useCallback } from "react"; +import { AppContext } from "../../../../contexts/AppContext"; +import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl"; +import { + Box, + TextField, + Typography, + Button, + Tooltip, + FormControlLabel, + Checkbox, +} from "@mui/material"; +import moment from "moment"; +import { SPACING } from "../../../../data/spacing"; +import { DatePicker } from "@mui/x-date-pickers"; +import { + LOADING_END, + LOADING_START, +} from "../../../../lib/redux/slices/appSlice"; +import { useDispatch, useSelector } from "react-redux"; +import { format } from "date-fns-jalali"; +import axios from "axios"; +import { formatTime } from "../../../../utils/formatTime"; +import ShowImage from "../../../../components/show-image/ShowImage"; +import { RiFileExcel2Fill, RiSearchLine } from "react-icons/ri"; +import { VetFarmOperationOptions } from "../../../vet-farm/components/vet-farm-operations-options/VetFarmOperationOptions"; +import ResponsiveTable from "../../../../components/responsive-table/ResponsiveTable"; +import { VetFarmEditTrafficCode } from "../../../vet-farm/components/vet-farm-edit-traffic-code/VetFarmEditTrafficCode"; +import { vetFarmGetFinishedBarsOverview } from "../../../vet-farm/services/vet-farm-get-bars-overview"; +import { Grid } from "../../../../components/grid/Grid"; +import { checkPathStartsWith } from "../../../../utils/checkPathStartsWith"; + +// Constants +const ROLES = { + KILL_HOUSE: "KillHouse", + ADMIN_X: "AdminX", + VET_FARM: "VetFarm", + PROVINCE_OPERATOR: "ProvinceOperator", + KILL_HOUSE_VET: "KillHouseVet", + SUPER_ADMIN: "SuperAdmin", + SUPPORTER: "Supporter", +}; + +const KILL_TYPES = { + FREEZING: "انجماد", + EXPORT: "صادرات", + NORMAL: "عادی", +}; + +const ITEM_STATES = { + WAREHOUSE: "ورود به انبار", + REGISTERED: "ثبت اطلاعات بار", + DELETED: "حذف شده", + ACCEPTED: "تایید تخلیه", + PENDING: "در انتظار تخلیه", +}; + +const QUARANTINE_STATES = { + CONTRADICTION: "مغایرت کد رهگیری", + NO_CLEARANCE: "فاقد کد رهگیری", + MERGE: "ادغام", + NOT_APPROVED: "عدم تایید راهداری", +}; + +const DEFAULT_PER_PAGE = 10; +const DEFAULT_PAGE = 1; + +// Helper functions +const formatDate = (date) => { + if (!date) return "-"; + return format(new Date(date), "yyyy/MM/dd"); +}; + +const formatCurrency = (value) => { + return value ? `${value.toLocaleString()} ﷼` : "-"; +}; + +const formatNumber = (value) => { + return value ? value.toLocaleString() : "-"; +}; + +const formatNumberFixed = (value, decimals = 2) => { + return value ? value.toFixed(decimals).toLocaleString() : "-"; +}; + +const formatUserInfo = (name, mobile) => { + return name && mobile ? `${name} (${mobile})` : "-"; +}; + +const getKillType = (item) => { + if (item?.poultryRequest?.freezing) return KILL_TYPES.FREEZING; + if (item?.poultryRequest?.export) return KILL_TYPES.EXPORT; + return KILL_TYPES.NORMAL; +}; + +const getItemState = (item) => { + if (item?.wareHouseConfirmation) { + return ITEM_STATES.WAREHOUSE; + } + if (item?.assignmentStateArchive !== "pending") { + return ITEM_STATES.REGISTERED; + } + if (item.trash === true) { + return ITEM_STATES.DELETED; + } + if (item.vetState === "accepted") { + return ITEM_STATES.ACCEPTED; + } + if (item.vetState === "pending") { + return ITEM_STATES.PENDING; + } + return ""; +}; + +const getQuarantineInfo = (item) => { + if (item?.quarantineQuantity) { + return item.quarantineQuantity; + } + if (item?.quarantineCodeState) { + const stateMap = { + contradiction: QUARANTINE_STATES.CONTRADICTION, + noclearance: QUARANTINE_STATES.NO_CLEARANCE, + merge: QUARANTINE_STATES.MERGE, + }; + return stateMap[item.quarantineCodeState] || QUARANTINE_STATES.NOT_APPROVED; + } + return "-"; +}; + +const buildApiUrl = (params) => { + const { + textValue, + role, + date1, + date2, + page, + perPage, + roleKey, + withoutBarDocument, + } = params; + const baseUrl = "kill_house_assignment_information/"; + const queryParams = new URLSearchParams({ + search: "filter", + value: textValue || "", + role: role || "", + date1: date1 || "", + date2: date2 || "", + page: page || DEFAULT_PAGE, + page_size: perPage || DEFAULT_PER_PAGE, + without_bar_document: withoutBarDocument ? "true" : "false", + }); + + if (roleKey) { + queryParams.append("role_key", roleKey); + } + + return `${baseUrl}?${queryParams.toString()}`; +}; + +const buildExcelUrl = (params) => { + const { baseURL, date1, date2, role, roleKey, userKey, textValue } = params; + const queryParams = new URLSearchParams({ + start: date1 || "", + end: date2 || "", + state: "completed", + role: role || "", + key: userKey || "", + search: "filter", + value: textValue || "", + }); + + if (roleKey) { + queryParams.append("role_key", roleKey); + } + + return `${baseURL}bar_excel/?${queryParams.toString()}`; +}; + +const isTrafficCodeEditable = (role, item) => { + if (!item?.killer?.key) { + return false; + } + + const editableRoles = [ + ROLES.KILL_HOUSE, + ROLES.ADMIN_X, + ROLES.VET_FARM, + ROLES.PROVINCE_OPERATOR, + ROLES.KILL_HOUSE_VET, + ROLES.SUPER_ADMIN, + ROLES.SUPPORTER, + ]; + + return editableRoles.includes(role); +}; + +const canShowDocumentCheckbox = (role) => { + return ( + role === ROLES.SUPER_ADMIN || + role === ROLES.SUPPORTER || + role === ROLES.ADMIN_X + ); +}; + +export const SlaughterManageBars = () => { + const [, , selectedDate1, setSelectedDate1, selectedDate2, setSelectedDate2] = + useContext(AppContext); + + // Redux + const selectedSubUser = useSelector( + (state) => state.userSlice.selectedSubUser + ); + const userKey = useSelector((state) => state.userSlice.userProfile.key); + const dispatch = useDispatch(); + + // State + const [hasDocumentState, setHasDocumentState] = useState(false); + const [data, setData] = useState([]); + const [totalRows, setTotalRows] = useState(0); + const [perPage, setPerPage] = useState(DEFAULT_PER_PAGE); + const [textValue, setTextValue] = useState(""); + const [page, setPage] = useState(DEFAULT_PAGE); + const [tableData, setTableData] = useState([]); + const [dashboardData, setDashboardData] = useState([]); + + // Memoized values + const currentRole = useMemo(() => getRoleFromUrl(), []); + const roleKey = useMemo( + () => (checkPathStartsWith("slaughter") ? selectedSubUser?.key || "" : ""), + [selectedSubUser?.key] + ); + const showDocumentCheckbox = useMemo( + () => canShowDocumentCheckbox(currentRole), + [currentRole] + ); + + // Initialize dates + useEffect(() => { + const currentDate = moment(new Date()).format("YYYY-MM-DD"); + setSelectedDate1(currentDate); + setSelectedDate2(currentDate); + }, [setSelectedDate1, setSelectedDate2]); + + // Fetch API data + const fetchApiData = useCallback( + async (pageNumber = page) => { + dispatch(LOADING_START()); + try { + const url = buildApiUrl({ + textValue, + role: currentRole, + date1: selectedDate1, + date2: selectedDate2, + page: pageNumber || DEFAULT_PAGE, + perPage, + roleKey, + withoutBarDocument: hasDocumentState, + }); + + const response = await axios.get(url); + setData(response.data.results); + setTotalRows(response.data.count); + } catch (error) { + console.error("Error fetching data:", error); + } finally { + dispatch(LOADING_END()); + } + }, + [ + textValue, + currentRole, + selectedDate1, + selectedDate2, + perPage, + roleKey, + hasDocumentState, + page, + dispatch, + ] + ); + + // Fetch dashboard data + const fetchDashboardData = useCallback(() => { + dispatch( + vetFarmGetFinishedBarsOverview({ + selectedDate1, + selectedDate2, + textValue, + hasDocumentState, + roleKey, + }) + ).then((r) => { + setDashboardData(r.payload.data); + }); + }, [ + selectedDate1, + selectedDate2, + textValue, + hasDocumentState, + roleKey, + dispatch, + ]); + + // Handlers + const handlePageChange = (newPage) => { + fetchApiData(newPage); + setPage(newPage); + }; + + const handlePerRowsChange = (newPerRows) => { + setPerPage(newPerRows); + setPage(DEFAULT_PAGE); + }; + + const handleSubmit = async (event) => { + event.preventDefault(); + await fetchApiData(DEFAULT_PAGE); + fetchDashboardData(); + setPage(DEFAULT_PAGE); + }; + + const handleTextChange = (event) => { + setTextValue(event.target.value); + }; + + const handleDateChange1 = (date) => { + if (date) { + setSelectedDate1(moment(date).format("YYYY-MM-DD")); + } + }; + + const handleDateChange2 = (date) => { + if (date) { + setSelectedDate2(moment(date).format("YYYY-MM-DD")); + } + }; + + const handleChangeDocumentState = () => { + setHasDocumentState(!hasDocumentState); + }; + + // Initial data fetch + useEffect(() => { + fetchApiData(DEFAULT_PAGE); + fetchDashboardData(); + // eslint-disable-next-line react-hooks/exhaustive-deps + }, []); + + // Refetch when filters change + useEffect(() => { + fetchApiData(DEFAULT_PAGE); + fetchDashboardData(); + setPage(DEFAULT_PAGE); + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [selectedDate1, selectedDate2, hasDocumentState, perPage, roleKey]); + + // Transform data to table format + useEffect(() => { + const transformedData = data?.map((item, i) => { + const rowNumber = + page === DEFAULT_PAGE ? i + 1 : i + perPage * (page - 1) + 1; + const textColor = item?.trash ? "red" : "black"; + + return [ + rowNumber, + , + + {getItemState(item)} + , + + {item.barCode} + , + formatTime(item.createDate), + getKillType(item), + + {item?.barDocumentStatus?.title || "-"} + , + , + formatNumber(item.acceptedRealQuantity), + formatNumber(item?.acceptedRealWeight), + formatNumber(item?.weightInfo?.finalIndexWeight), + formatUserInfo( + item.killhouseUser?.name, + item.killhouseUser?.killHouseOperator?.user?.mobile + ), + item?.killer + ? formatUserInfo( + item.killer?.name, + item.killer?.killHouseOperator?.user?.mobile + ) + : "-", + formatUserInfo( + item.poultryRequest?.poultry?.user?.fullname, + item.poultryRequest?.poultry?.user?.mobile + ), + item.poultryRequest?.poultry?.unitName || "-", + item?.poultryRequest?.age || "-", + formatNumber(item.quantity), + formatNumber(item?.weightInfo?.weight), + + + , + formatCurrency(item?.amount), + item?.clearanceCode || "-", + getQuarantineInfo(item), + `${item.addCar?.driver?.typeCar || ""} ${ + item.addCar?.driver?.pelak || "" + }`.trim() || "-", + formatUserInfo( + item.addCar?.driver?.driverName, + item.addCar?.driver?.driverMobile + ), + item.poultryRequest?.chickenBreed || "-", + formatNumber(item?.weightInfo?.indexWeight), + formatCurrency(item?.poultryRequest?.amount), + formatCurrency(item?.weightInfo?.killHousePrice), + item?.vetFarm?.vet?.user?.fullname + ? `${item.vetFarm.vet.user.fullname}(${item.vetFarm.vet.user.mobile})` + : "فاقد دامپزشک", + item.killPlace || "-", + item.poultryRequest?.poultry?.address?.city?.name || "-", + formatDate(item?.poultryRequest?.sendDate), + item?.poultryRequest?.orderCode || "-", + formatNumber(item?.wareHouseAcceptedRealQuantity), + formatNumber(item?.wareHouseAcceptedRealWeight), + formatNumber(item?.weightLoss), + ]; + }); + + setTableData(transformedData || []); + }, [data, page, perPage, currentRole, fetchApiData]); + + // Table columns + const dashboardColumns = [ + "تعداد بارها", + "حجم بارها", + "وزن بارها", + "میانگین وزن", + "کمترین سن ", + "بیشترین سن ", + "میانگین سنی", + "بارهای دارای کد قرنطینه", + "حجم بارهای دارای کد قرنطینه", + "بارهای احراز شده از قرنطینه", + "حجم بارهای احراز شده از قرنطینه", + "بارهای فاقد کد قرنطینه", + "حجم بارهای فاقد کد قرنطینه", + "بارهایی که در قرنطینه و رصدیار اختلاف دارند", + "بارهای تکمیل شده کشتارگاه", + "حجم نهایی در کشتارگاه", + "وزن نهایی در کشتارگاه", + "تعداد بار ورودی به انبار", + "حجم لاشه های انبار", + "وزن لاشه های انبار", + "درصد افت بار انبار", + ]; + + const tableColumns = [ + "ردیف", + "عملیات", + "وضعیت", + "کدبار", + "تاریخ ثبت خودرو", + "نوع کشتار", + "وضعیت سند", + "سند (بارنامه)", + "تعداد نهایی", + "وزن نهایی بار (کیلوگرم)", + "میانگین وزن نهایی (کیلوگرم)", + "خریدار", + "کشتارکن اختصاصی", + "مشخصات مرغدار", + "نام فارم", + "سن مرغ", + "تعداد اولیه", + "وزن اولیه بار (کیلوگرم)", + "کد بهداشتی حمل و نقل", + "قیمت مرغ زنده‌ی بار", + "کدرهگیری سامانه قرنطینه", + "تعداد در قرنطینه", + "ماشین", + "راننده", + "نژاد", + "میانگین وزن اولیه (کیلوگرم)", + "قیمت مرغدار", + "قیمت کشتارگاه", + "دامپزشک فارم", + "محل کشتار", + "شهر", + "تاریخ کشتار", + "کدسفارش کشتار", + "حجم لاشه", + "وزن لاشه", + "درصد افت", + ]; + + // Dashboard row data + const renderDashboardCell = (value, isBlue = false) => ( + + {formatNumber(value)} + + ); + + const dashboardRow = [ + renderDashboardCell(dashboardData?.lenKillRequest, true), + renderDashboardCell(dashboardData?.killRequestQuantity), + renderDashboardCell(dashboardData?.killRequestWeight, true), + + {dashboardData?.avgWeight || "-"} + , + renderDashboardCell(dashboardData?.minAge, true), + renderDashboardCell(dashboardData?.maxAge), + renderDashboardCell(dashboardData?.avgAge, true), + renderDashboardCell(dashboardData?.lenKillRequestHasCode), + renderDashboardCell(dashboardData?.quantityOfKillRequestHasCode, true), + renderDashboardCell(dashboardData?.lenKillRequestHasQuarantine), + renderDashboardCell( + dashboardData?.quantityOfKillRequestHasQuarantine, + true + ), + renderDashboardCell(dashboardData?.lenKillRequestHasNotCode), + renderDashboardCell(dashboardData?.quantityOfKillRequestHasNotCode, true), + renderDashboardCell(dashboardData?.differenceBar), + renderDashboardCell(dashboardData?.lenCompleteWithKillHouse, true), + renderDashboardCell(dashboardData?.quantityFinalKillHouse), + renderDashboardCell(dashboardData?.weightFinalKillHouse, true), + renderDashboardCell(dashboardData?.wareHouseBars), + renderDashboardCell(dashboardData?.wareHouseBarsQuantity, true), + renderDashboardCell(dashboardData?.wareHouseBarsWeight), + + {formatNumberFixed(dashboardData?.wareHouseBarsWeightLose)} + , + ]; + + const excelUrl = buildExcelUrl({ + baseURL: axios.defaults.baseURL, + date1: selectedDate1, + date2: selectedDate2, + role: currentRole, + roleKey, + userKey, + textValue, + }); + + return ( + + + + + + } + value={selectedDate1} + onChange={handleDateChange1} + /> + + + } + value={selectedDate2} + onChange={handleDateChange2} + /> + +
    + + + + {!!data?.length && ( + + + + + + + + )} + {showDocumentCheckbox && ( + + } + label="بدون وضعیت سند" + /> + )} +
    + + + + +
    +
    +
    + ); +}; diff --git a/src/features/slaughter-house/components/slaughter-manage-cars/SlaughterManageCars.js b/src/features/slaughter-house/components/slaughter-manage-cars/SlaughterManageCars.js new file mode 100644 index 0000000..eec302f --- /dev/null +++ b/src/features/slaughter-house/components/slaughter-manage-cars/SlaughterManageCars.js @@ -0,0 +1,142 @@ +import { Button, Card, IconButton } from "@mui/material"; +import { useEffect, useState } from "react"; +import { AdvancedTable } from "../../../../components/advanced-table/AdvancedTable"; +import { useDispatch, useSelector } from "react-redux"; +import { slaughterGetCars } from "../../services/slaughter-get-cars"; +import DeleteIcon from "@mui/icons-material/Delete"; +import { + DRAWER, + LOADING_END, + LOADING_START, +} from "../../../../lib/redux/slices/appSlice"; +import { slaughterDeleteCar } from "../../services/slaughter-delete-car"; +import { Grid } from "../../../../components/grid/Grid"; +import { SPACING } from "../../../../data/spacing"; +import { SlaughterNewCar } from "../slaughter-new-car/SlaughterNewCar"; +import { AppContext } from "../../../../contexts/AppContext"; +import { useContext } from "react"; +import { slaughterGetProfile } from "../../services/slaughter-get-profile"; + +export const SlaughterManageCars = () => { + const [dataTable, setDataTable] = useState([]); + const { slaughterHouseCars, profile } = useSelector( + (state) => state.slaughterSlice + ); + const [openNotif] = useContext(AppContext); + + const dispatch = useDispatch(); + + useEffect(() => { + dispatch(slaughterGetProfile()); + dispatch(slaughterGetCars()); + }, []); + + useEffect(() => { + const filteredData = slaughterHouseCars; + const d = filteredData?.map((item, i) => { + return [ + i + 1, + item.typeCar, + item.pelak, + item.capocity, + parseInt(item.healthCode), + // Number(item.healthCode), + item.driverName, + item.driverMobile, + // @todo make onclick delete the car + { + dispatch(LOADING_START()); + dispatch( + slaughterDeleteCar({ + id: item.id, + }) + ).then((r) => { + if (r.error) { + if (r.error.message.includes("403")) { + openNotif({ + vertical: "top", + horizontal: "center", + msg: "امکان حذف بدلیل تخصیص بار فعال به خودرو وجود ندارد!", + severity: "error", + }); + } else { + openNotif({ + vertical: "top", + horizontal: "center", + msg: "مشکلی پیش آمده است!", + severity: "error", + }); + } + } else { + openNotif({ + vertical: "top", + horizontal: "center", + msg: "عملیات با موفقیت انجام شد.", + severity: "success", + }); + } + dispatch(slaughterGetCars()); + dispatch(LOADING_END()); + }); + }} + > + + , + ]; + }); + + setDataTable(d); + }, [slaughterHouseCars]); + + const [tableDataCol] = useState([ + "ردیف", + "مدل خودرو", + "پلاک", + "ظرفیت", + "کد بهداشتی", + "نام راننده", + "موبایل راننده", + "حذف", + ]); + return ( + <> + + + + + + + + + + ); +}; diff --git a/src/features/slaughter-house/components/slaughter-manage-delegates/SlaughterManageDelegates.js b/src/features/slaughter-house/components/slaughter-manage-delegates/SlaughterManageDelegates.js new file mode 100644 index 0000000..4cd8667 --- /dev/null +++ b/src/features/slaughter-house/components/slaughter-manage-delegates/SlaughterManageDelegates.js @@ -0,0 +1,249 @@ +import React, { useEffect, useState, useRef } from "react"; +import { Box, Button, Grid, TextField, Chip } from "@mui/material"; +import { useDispatch, useSelector } from "react-redux"; +import { BackButton } from "../../../../components/back-button/BackButton"; + +import { OPEN_MODAL } from "../../../../lib/redux/slices/appSlice"; +import { SlaughterManageDelegatesForm } from "./SlaughterManageDelegatesForm"; +import { SlaughterManageDelegatesOperations } from "./SlaughterManageDelegatesOperations"; +import { slaughterGetDelegatesInfoService } from "../../services/slaughter-get-delegates-info"; +import ResponsiveTable from "../../../../components/responsive-table/ResponsiveTable"; +import { SPACING } from "../../../../data/spacing"; +import { RiSearchLine } from "react-icons/ri"; +import { formatJustDate } from "../../../../utils/formatTime"; +import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl"; +import { checkPathStartsWith } from "../../../../utils/checkPathStartsWith"; + +const SlaughterManageDelegates = () => { + const dispatch = useDispatch(); + const [data, setData] = useState([]); + const [totalRows, setTotalRows] = useState(0); + const [perPage, setPerPage] = useState(10); + const [textValue, setTextValue] = useState(""); + const [page, setPage] = useState(1); + const [tableData, setTableData] = useState([]); + const isFirstMount = useRef(true); + const isSteward = getRoleFromUrl() === "Steward"; + const selectedSubUser = useSelector( + (state) => state.userSlice.selectedSubUser + ); + const handleTextChange = (e) => setTextValue(e.target.value); + + const fetchApiData = async (pageNum) => { + const response = await dispatch( + slaughterGetDelegatesInfoService({ + search: "filter", + value: textValue, + page: pageNum, + page_size: perPage, + role_key: + checkPathStartsWith("slaughter") || checkPathStartsWith("steward") + ? selectedSubUser?.key || "" + : "", + }) + ); + + if (response.payload.error) { + console.error("Error fetching data:", response.payload.error); + setData([]); + setTotalRows(0); + } else { + setData(response.payload.data?.results || []); + const count = Number(response.payload.data?.count) || 0; + setTotalRows(count); + } + }; + + const handlePageChange = (pageNum) => { + fetchApiData(pageNum); + setPage(pageNum); + }; + + const handlePerRowsChange = (perRows) => { + setPerPage(Number(perRows)); + setPage(1); + }; + + const updateTableData = () => { + fetchApiData(page !== 0 ? page : 1); + }; + + useEffect(() => { + if (!data || !Array.isArray(data)) { + setTableData([]); + return; + } + const d = data.map((item, i) => { + const isActive = item?.trash !== undefined ? !item.trash : null; + const statusBadge = + isActive === null ? ( + "-" + ) : ( + + ); + const hasLimitation = item?.limitation; + const limitationBadge = ( + + ); + const killhouseDisplay = + item?.killHouse?.name && item?.killHouse?.mobile + ? `${item.killHouse.name} (${item.killHouse.mobile})` + : item?.killHouse?.name + ? item.killHouse.name + : "-"; + + const stewardDisplay = + item?.steward?.name && item?.steward?.user?.mobile + ? `${item.steward.name} (${item.steward.user.mobile})` + : item?.steward?.name + ? item.steward.name + : "-"; + + const displayValue = isSteward ? stewardDisplay : killhouseDisplay; + + return [ + page === 1 ? i + 1 : i + perPage * (page - 1) + 1, + item?.createDate ? formatJustDate(item.createDate) : "-", + item?.firstName || "-", + item?.lastName || "-", + item?.mobile || "-", + item?.city || "-", + displayValue, + limitationBadge, + item?.governmentalLimitationWeight || 0, + item?.freeLimitationWeight || 0, + statusBadge, + , + ]; + }); + setTableData(d); + }, [data, page, perPage]); + + useEffect(() => { + fetchApiData(1); + }, [selectedSubUser?.key]); + + useEffect(() => { + if (isFirstMount.current) { + isFirstMount.current = false; + return; + } + fetchApiData(1); + setPage(1); + }, [perPage]); + + const handleSubmit = async (e) => { + e.preventDefault(); + setPage(1); + const response = await dispatch( + slaughterGetDelegatesInfoService({ + search: "filter", + value: textValue, + page: 1, + page_size: perPage, + role_key: checkPathStartsWith("slaughter") + ? selectedSubUser?.key || "" + : "", + }) + ); + + if (response.payload.error) { + console.error("Error fetching data:", response.payload.error); + setData([]); + setTotalRows(0); + } else { + setData(response.payload.data?.results || []); + const count = Number(response.payload.data?.count) || 0; + setTotalRows(count); + } + }; + + const handleOpenModal = () => { + dispatch( + OPEN_MODAL({ + title: "ثبت نماینده جدید", + content: , + size: 300, + }) + ); + }; + + return ( + + + + + + + +
    + + + + + +
    +
    + + + + +
    +
    + ); +}; + +export default SlaughterManageDelegates; diff --git a/src/features/slaughter-house/components/slaughter-manage-delegates/SlaughterManageDelegatesForm.js b/src/features/slaughter-house/components/slaughter-manage-delegates/SlaughterManageDelegatesForm.js new file mode 100644 index 0000000..5467f48 --- /dev/null +++ b/src/features/slaughter-house/components/slaughter-manage-delegates/SlaughterManageDelegatesForm.js @@ -0,0 +1,165 @@ +import React, { useContext } from "react"; +import { useFormik } from "formik"; +import * as yup from "yup"; +import { useDispatch } from "react-redux"; +import { Button, TextField } from "@mui/material"; +import { Grid } from "../../../../components/grid/Grid"; +import { SPACING } from "../../../../data/spacing"; +import { CLOSE_MODAL } from "../../../../lib/redux/slices/appSlice"; +import { AppContext } from "../../../../contexts/AppContext"; +import { + slaughterSubmitRepresentativeService, + slaughterEditRepresentativeService, +} from "../../services/slaughter-submit-delegate"; +import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl"; + +const getValidationSchema = () => + yup.object({ + first_name: yup.string().required("نام الزامی است"), + last_name: yup.string().required("نام خانوادگی الزامی است"), + mobile: yup + .string() + .required("شماره همراه الزامی است") + .matches(/^09\d{9}$/, "شماره تلفن باید با 09 شروع شود و 11 رقم باشد"), + city: yup.string().required("شهر الزامی است"), + }); + +export const SlaughterManageDelegatesForm = ({ updateTable, item, isEdit }) => { + const dispatch = useDispatch(); + const [openNotif] = useContext(AppContext); + + const formik = useFormik({ + initialValues: { + first_name: item?.first_name || item?.firstName || "", + last_name: item?.last_name || item?.lastName || "", + mobile: item?.mobile || "", + city: item?.city || "", + }, + enableReinitialize: true, + validationSchema: getValidationSchema(), + onSubmit: (values) => { + const submitData = isEdit + ? { + key: item?.key, + first_name: values.first_name, + last_name: values.last_name, + mobile: values.mobile, + city: values.city, + } + : { + first_name: values.first_name, + last_name: values.last_name, + mobile: values.mobile, + city: values.city, + role: getRoleFromUrl(), + }; + + const service = isEdit + ? slaughterEditRepresentativeService + : slaughterSubmitRepresentativeService; + + dispatch(service(submitData)).then((r) => { + if (r.payload.error) { + openNotif({ + vertical: "top", + horizontal: "center", + msg: r.payload.error, + severity: "error", + }); + } else { + openNotif({ + vertical: "top", + horizontal: "center", + msg: "عملیات با موفقیت انجام شد.", + severity: "success", + }); + if (updateTable) { + updateTable(); + } + dispatch(CLOSE_MODAL()); + } + }); + }, + }); + + return ( +
    + + + + + + + + + + + + + + + + + + + + + +
    + ); +}; diff --git a/src/features/slaughter-house/components/slaughter-manage-delegates/SlaughterManageDelegatesLimitationForm.js b/src/features/slaughter-house/components/slaughter-manage-delegates/SlaughterManageDelegatesLimitationForm.js new file mode 100644 index 0000000..03363df --- /dev/null +++ b/src/features/slaughter-house/components/slaughter-manage-delegates/SlaughterManageDelegatesLimitationForm.js @@ -0,0 +1,133 @@ +import React, { useContext, useState } from "react"; +import { + Button, + TextField, + Typography, + Checkbox, + FormControlLabel, +} from "@mui/material"; +import { useDispatch } from "react-redux"; +import { Grid } from "../../../../components/grid/Grid"; +import { SPACING } from "../../../../data/spacing"; +import { CLOSE_MODAL } from "../../../../lib/redux/slices/appSlice"; +import { AppContext } from "../../../../contexts/AppContext"; +import { slaughterEditRepresentativeService } from "../../services/slaughter-submit-delegate"; + +export const SlaughterManageDelegatesLimitationForm = ({ + item, + updateTable, +}) => { + const dispatch = useDispatch(); + const [openNotif] = useContext(AppContext); + + const [hasLimitation, setHasLimitation] = useState(item?.limitation || false); + const [governmentalValue, setGovernmentalValue] = useState( + item?.governmentalLimitationWeight || 0 + ); + const [freeValue, setFreeValue] = useState(item?.freeLimitationWeight || 0); + + const handleSubmit = (e) => { + e.preventDefault(); + + const submitData = { + key: item?.key, + limitation: hasLimitation, + governmental_limitation_weight: hasLimitation + ? Number(governmentalValue) + : 0, + free_limitation_weight: hasLimitation ? Number(freeValue) : 0, + }; + + dispatch(slaughterEditRepresentativeService(submitData)).then((r) => { + if (r.payload?.error) { + openNotif({ + vertical: "top", + horizontal: "center", + msg: r.payload.error, + severity: "error", + }); + } else { + openNotif({ + vertical: "top", + horizontal: "center", + msg: "عملیات با موفقیت انجام شد.", + severity: "success", + }); + if (updateTable) { + updateTable(); + } + dispatch(CLOSE_MODAL()); + } + }); + }; + + return ( +
    + + + + اطلاعات نماینده: + + + {item?.firstName} {item?.lastName} + + + + + setHasLimitation(e.target.checked)} + color="primary" + /> + } + label="محدودیت فروش روزانه" + /> + + + {hasLimitation && ( + <> + + setGovernmentalValue(e.target.value)} + inputProps={{ min: 0 }} + /> + + + + setFreeValue(e.target.value)} + inputProps={{ min: 0 }} + /> + + + )} + + + + + +
    + ); +}; diff --git a/src/features/slaughter-house/components/slaughter-manage-delegates/SlaughterManageDelegatesOperations.js b/src/features/slaughter-house/components/slaughter-manage-delegates/SlaughterManageDelegatesOperations.js new file mode 100644 index 0000000..0ba758f --- /dev/null +++ b/src/features/slaughter-house/components/slaughter-manage-delegates/SlaughterManageDelegatesOperations.js @@ -0,0 +1,114 @@ +import { IconButton, Popover, Typography, Button, Box } from "@mui/material"; +import React, { useState } from "react"; +import EditIcon from "@mui/icons-material/Edit"; +import BlockIcon from "@mui/icons-material/Block"; +import TuneIcon from "@mui/icons-material/Tune"; +import { useDispatch } from "react-redux"; +import { OPEN_MODAL } from "../../../../lib/redux/slices/appSlice"; +import { SlaughterManageDelegatesForm } from "./SlaughterManageDelegatesForm"; +import { SlaughterManageDelegatesLimitationForm } from "./SlaughterManageDelegatesLimitationForm"; + +export const SlaughterManageDelegatesOperations = ({ item, updateTable }) => { + const [anchorEl, setAnchorEl] = useState(null); + const dispatch = useDispatch(); + + const handleClick = (event) => { + setAnchorEl(event.currentTarget); + }; + + const handleClose = () => { + setAnchorEl(null); + }; + + const open = Boolean(anchorEl); + const id = open ? "popover" : undefined; + + return ( +
    + + + + + + + + + +
    + ); +}; diff --git a/src/features/slaughter-house/components/slaughter-manage-dispensers/SlaughterManageDispensers.js b/src/features/slaughter-house/components/slaughter-manage-dispensers/SlaughterManageDispensers.js new file mode 100644 index 0000000..2426ad2 --- /dev/null +++ b/src/features/slaughter-house/components/slaughter-manage-dispensers/SlaughterManageDispensers.js @@ -0,0 +1,253 @@ +import React, { useEffect, useState } from "react"; +import { Box, Button, Grid, TextField, Chip } from "@mui/material"; +import { useDispatch, useSelector } from "react-redux"; +import { BackButton } from "../../../../components/back-button/BackButton"; + +import { OPEN_MODAL, CLOSE_MODAL } from "../../../../lib/redux/slices/appSlice"; +import { SlaughterManageDispensersForm } from "./SlaughterManageDispensersForm"; +import { slaughterGetDispenserInfoService } from "../../services/slaughter-get-dispenser-info"; +import ResponsiveTable from "../../../../components/responsive-table/ResponsiveTable"; +import { SPACING } from "../../../../data/spacing"; +import { RiSearchLine } from "react-icons/ri"; +import { formatJustDate } from "../../../../utils/formatTime"; +import { SlaughterManageDispensersOperations } from "./SlaughterManageDispensersOperations"; +import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl"; +import { checkPathStartsWith } from "../../../../utils/checkPathStartsWith"; + +const SlaughterManageDispensers = () => { + const dispatch = useDispatch(); + const [data, setData] = useState([]); + const [totalRows, setTotalRows] = useState(0); + const [perPage, setPerPage] = useState(10); + const [textValue, setTextValue] = useState(""); + const [page, setPage] = useState(1); + const [tableData, setTableData] = useState([]); + const isSteward = getRoleFromUrl() === "Steward"; + const selectedSubUser = useSelector( + (state) => state.userSlice.selectedSubUser + ); + const handleTextChange = (e) => setTextValue(e.target.value); + + const fetchApiData = async (pageNum) => { + const response = await dispatch( + slaughterGetDispenserInfoService({ + search: "filter", + value: textValue, + page: pageNum, + page_size: perPage, + role_key: checkPathStartsWith("slaughter") + ? selectedSubUser?.key || "" + : "", + }) + ); + + if (response.payload.error) { + console.error("Error fetching data:", response.payload.error); + setData([]); + setTotalRows(0); + } else { + setData(response.payload.data?.results || []); + const count = Number(response.payload.data?.count) || 0; + setTotalRows(count); + } + }; + + const handlePageChange = (pageNum) => { + fetchApiData(pageNum); + setPage(pageNum); + }; + + const handlePerRowsChange = (perRows) => { + setPerPage(Number(perRows)); + setPage(1); + }; + + const updateTableData = () => { + fetchApiData(page !== 0 ? page : 1); + }; + + useEffect(() => { + if (!data || !Array.isArray(data)) { + setTableData([]); + return; + } + const d = data.map((item, i) => { + const isActive = item?.active !== undefined ? item.active : null; + const statusBadge = + isActive === null ? ( + "-" + ) : ( + + ); + const hasLimitation = item?.limitation; + const limitationBadge = ( + + ); + const killhouseDisplay = + item?.killHouse?.name && item?.killHouse?.mobile + ? `${item.killHouse.name} (${item.killHouse.mobile})` + : item?.killHouse?.name + ? item.killHouse.name + : "-"; + + const stewardDisplay = + item?.steward?.name && item?.steward?.user?.mobile + ? `${item.steward.name} (${item.steward.user.mobile})` + : item?.steward?.name + ? item.steward.name + : "-"; + + const displayValue = isSteward ? stewardDisplay : killhouseDisplay; + + return [ + page === 1 ? i + 1 : i + perPage * (page - 1) + 1, + item?.createDate ? formatJustDate(item.createDate) : "-", + item?.nationalId || "-", + item?.firstName || "-", + item?.lastName || "-", + item?.mobile || "-", + item?.city || "-", + item?.province || "-", + displayValue, + limitationBadge, + item?.governmentalLimitationWeight || 0, + item?.freeLimitationWeight || 0, + statusBadge, + , + ]; + }); + setTableData(d); + }, [data, page, perPage]); + + useEffect(() => { + fetchApiData(1); + setPage(1); + }, [perPage, selectedSubUser?.key]); + + useEffect(() => { + fetchApiData(1); + }, [selectedSubUser?.key]); + + const handleSubmit = async (e) => { + e.preventDefault(); + setPage(1); + const response = await dispatch( + slaughterGetDispenserInfoService({ + search: "filter", + value: textValue, + page: 1, + page_size: perPage, + role_key: + checkPathStartsWith("slaughter") || checkPathStartsWith("steward") + ? selectedSubUser?.key || "" + : "", + }) + ); + + if (response.payload.error) { + console.error("Error fetching data:", response.payload.error); + setData([]); + setTotalRows(0); + } else { + setData(response.payload.data?.results || []); + const count = Number(response.payload.data?.count) || 0; + setTotalRows(count); + } + }; + + const handleOpenModal = () => { + dispatch( + OPEN_MODAL({ + title: "ثبت توزیع کننده جدید", + content: ( + dispatch(CLOSE_MODAL())} + updateTable={updateTableData} + /> + ), + size: 300, + }) + ); + }; + + return ( + + + + + + + +
    + + + + + +
    +
    + + + + +
    +
    + ); +}; + +export default SlaughterManageDispensers; diff --git a/src/features/slaughter-house/components/slaughter-manage-dispensers/SlaughterManageDispensersForm.js b/src/features/slaughter-house/components/slaughter-manage-dispensers/SlaughterManageDispensersForm.js new file mode 100644 index 0000000..7214df1 --- /dev/null +++ b/src/features/slaughter-house/components/slaughter-manage-dispensers/SlaughterManageDispensersForm.js @@ -0,0 +1,577 @@ +import React, { + useContext, + useEffect, + useState, + useCallback, + useRef, +} from "react"; +import { useFormik } from "formik"; +import * as yup from "yup"; +import { useDispatch, useSelector } from "react-redux"; +import { Button, TextField, Typography, Box } from "@mui/material"; +import PersonIcon from "@mui/icons-material/Person"; +import PublicIcon from "@mui/icons-material/Public"; +import BadgeIcon from "@mui/icons-material/Badge"; +import CalendarTodayIcon from "@mui/icons-material/CalendarToday"; +import AccountBoxIcon from "@mui/icons-material/AccountBox"; +import BusinessIcon from "@mui/icons-material/Business"; +import { Grid } from "../../../../components/grid/Grid"; +import { SPACING } from "../../../../data/spacing"; +import { CLOSE_MODAL, OPEN_MODAL } from "../../../../lib/redux/slices/appSlice"; +import { AppContext } from "../../../../contexts/AppContext"; +import { slaughterGetDispenserUserInfoService } from "../../services/slaughter-get-dispenser-user-info"; +import { provinceGetCitiesService } from "../../../province/services/province-get-cities"; +import { + slaughterHouseSubmitDispenserService, + slaughterHouseEditDispenserService, +} from "../../services/slaughter-house-submit-dispenser-service"; +import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl"; +import { checkPathStartsWith } from "../../../../utils/checkPathStartsWith"; + +const InfoBox = ({ icon: Icon, label, value, iconSx }) => ( + + + + + {label} + + {value || "-"} + + +); + +const getValidationSchema = () => + yup.object({ + mobile: yup + .string() + .required("شماره همراه الزامی است") + .matches(/^09\d{9}$/, "شماره تلفن باید با 09 شروع شود و 11 رقم باشد"), + }); + +const DispenserForm = ({ formik, userInfo }) => { + return ( +
    + + + + اطلاعات توزیع کننده + + + + {/* Additional User Info Section */} + {userInfo && ( + + + + اطلاعات شخصی + + + + + + {userInfo.fatherName && ( + + + + )} + {userInfo.birthDate && ( + + + + )} + {userInfo.gender !== undefined && ( + + + + )} + {userInfo.identityNo && userInfo.identityNo !== "0" && ( + + + + )} + {userInfo.identitySeries && ( + + + + )} + {userInfo.identitySerial && ( + + + + )} + + )} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + {formik.values.dispenser_type === "driver" && ( + <> + + + + {formik.values.pelak && ( + + + + )} + + )} + + + + + + + + + + + + +
    + ); +}; + +const InquiryForm = ({ onInquiry, nationalCode, setNationalCode }) => { + return ( + + + setNationalCode(e.target.value)} + placeholder="کد ملی 10 رقمی را وارد کنید" + inputProps={{ maxLength: 10 }} + /> + + + + + + ); +}; + +export const SlaughterManageDispensersForm = ({ + onClose, + updateTable, + dispenser, + initialUserData, + initialUserInfo, + initialNationalCode, +}) => { + const dispatch = useDispatch(); + const [openNotif] = useContext(AppContext); + const [nationalCode, setNationalCode] = useState( + initialNationalCode || + dispenser?.user?.nationalId || + dispenser?.national_id || + "" + ); + const selectedSubUser = useSelector( + (state) => state.userSlice.selectedSubUser + ); + const [userData, setUserData] = useState( + initialUserData || + (dispenser + ? { + national_id: dispenser?.user?.nationalId || "", + first_name: dispenser?.user?.firstName || "", + last_name: dispenser?.user?.lastName || "", + city: dispenser?.user?.city?.cityName || "", + mobile: dispenser?.user?.mobile || "", + dispenser_type: dispenser?.dispenserType || "inductor", + limitation_amount: dispenser?.limitation_amount || 0, + driver_car_type: dispenser?.car || "", + pelak: dispenser?.pelak || "", + } + : null) + ); + const [userFound, setUserFound] = useState(dispenser ? true : false); // eslint-disable-line no-unused-vars + const [cities, setCities] = useState([]); + const [userInfo, setUserInfo] = useState(initialUserInfo || null); + const sizeUpdatedRef = useRef(!!initialUserData); + + useEffect(() => { + dispatch(provinceGetCitiesService()).then((r) => { + setCities(r.payload.data || []); + }); + }, [dispatch]); + + useEffect(() => { + if (userData && !sizeUpdatedRef.current && !dispenser) { + sizeUpdatedRef.current = true; + const isDesktop = window.innerWidth > 600; + const preservedUserData = userData; + const preservedUserInfo = userInfo; + const preservedNationalCode = nationalCode; + + dispatch( + OPEN_MODAL({ + title: "ثبت توزیع کننده جدید", + content: ( + + ), + size: isDesktop ? 600 : 300, + }) + ); + } + }, [ + userData, + dispatch, + onClose, + updateTable, + dispenser, + userInfo, + nationalCode, + ]); + + const handleInquiry = useCallback(() => { + if (!nationalCode || nationalCode.length !== 10) { + openNotif({ + vertical: "top", + horizontal: "center", + msg: "لطفا کد ملی 10 رقمی معتبر وارد کنید", + severity: "error", + }); + return; + } + + dispatch( + slaughterGetDispenserUserInfoService({ + national_code: nationalCode, + role_key: + checkPathStartsWith("slaughter") || checkPathStartsWith("steward") + ? selectedSubUser?.key || "" + : "", + }) + ).then((r) => { + if (r.payload.error) { + setUserFound(false); + setUserInfo(null); + openNotif({ + vertical: "top", + horizontal: "center", + msg: r.payload.error, + severity: "error", + }); + } else if (r.payload.data) { + const response = r.payload.data; + + if (response.status === true && response.data) { + const userDataFromApi = response.data; + + setUserFound(true); + setUserInfo(userDataFromApi); + + console.log(userDataFromApi); + setUserData({ + national_id: userDataFromApi.nationalCode || nationalCode, + first_name: userDataFromApi.firstName || "", + last_name: userDataFromApi.lastName || "", + city: userDataFromApi.city || "", + mobile: "", // Mobile is not in API response, user must enter it + dispenser_type: "inductor", + limitation_amount: 0, + }); + + openNotif({ + vertical: "top", + horizontal: "center", + msg: "اطلاعات با موفقیت دریافت شد", + severity: "success", + }); + } else if (response.status === false) { + setUserFound(false); + setUserInfo(null); + openNotif({ + vertical: "top", + horizontal: "center", + msg: response.errorDescription || "خطا در دریافت اطلاعات", + severity: "error", + }); + } else { + const userDataFromApi = response.data || response; + + if (userDataFromApi && userDataFromApi.nationalCode) { + setUserFound(true); + setUserInfo(userDataFromApi); + + setUserData({ + national_id: userDataFromApi.nationalCode || nationalCode, + first_name: userDataFromApi.firstName || "", + last_name: userDataFromApi.lastName || "", + city: userDataFromApi.city || "", + mobile: "", + dispenser_type: "inductor", + limitation_amount: 0, + }); + + openNotif({ + vertical: "top", + horizontal: "center", + msg: "اطلاعات با موفقیت دریافت شد", + severity: "success", + }); + } else { + setUserFound(false); + setUserInfo(null); + openNotif({ + vertical: "top", + horizontal: "center", + msg: "خطا در دریافت اطلاعات", + severity: "error", + }); + } + } + } + }); + }, [dispatch, nationalCode, openNotif, selectedSubUser]); + + const formik = useFormik({ + initialValues: { + national_id: + userData?.national_id || + userData?.nationalCode || + userData?.nationalId || + "", + first_name: userData?.first_name || "", + last_name: userData?.last_name || "", + city: userData?.city || "", + mobile: userData?.mobile || "", + dispenser_type: userData?.dispenser_type || "inductor", + limitation_amount: userData?.limitation_amount || 0, + driver_car_type: userData?.driverCarType || userData?.car || "", + pelak: userData?.pelak || "", + }, + validationSchema: getValidationSchema(), + enableReinitialize: true, + onSubmit: (values) => { + const currentUserInfo = userInfo; + const submitData = { + nationalCode: values.national_id || "", + firstName: values.first_name || "", + lastName: values.last_name || "", + fatherName: currentUserInfo?.fatherName || null, + gender: + currentUserInfo?.gender !== undefined ? currentUserInfo.gender : null, + isLive: + currentUserInfo?.isLive !== undefined ? currentUserInfo.isLive : true, + identityNo: currentUserInfo?.identityNo || null, + birthDate: currentUserInfo?.birthDate || null, + city: values.city || currentUserInfo?.city || "", + mobile: values.mobile, + role: getRoleFromUrl(), + }; + + if (dispenser?.key) { + // Edit mode + dispatch( + slaughterHouseEditDispenserService({ + type: "update-profile", + dispenser_key: dispenser.key, + ...submitData, + }) + ).then((r) => { + if (r.payload.error) { + openNotif({ + vertical: "top", + horizontal: "center", + msg: r.payload.error, + severity: "error", + }); + } else { + openNotif({ + vertical: "top", + horizontal: "center", + msg: "عملیات با موفقیت انجام شد.", + severity: "success", + }); + if (updateTable) { + updateTable(); + } + dispatch(CLOSE_MODAL()); + } + }); + } else { + // Create mode + dispatch(slaughterHouseSubmitDispenserService(submitData)).then((r) => { + if (r.payload.error) { + openNotif({ + vertical: "top", + horizontal: "center", + msg: r.payload.error, + severity: "error", + }); + } else { + openNotif({ + vertical: "top", + horizontal: "center", + msg: "عملیات با موفقیت انجام شد.", + severity: "success", + }); + if (updateTable) { + updateTable(); + } + dispatch(CLOSE_MODAL()); + } + }); + } + }, + }); + + if (!userData && !dispenser) { + return ( + + ); + } + + return ; +}; diff --git a/src/features/slaughter-house/components/slaughter-manage-dispensers/SlaughterManageDispensersLimitationForm.js b/src/features/slaughter-house/components/slaughter-manage-dispensers/SlaughterManageDispensersLimitationForm.js new file mode 100644 index 0000000..3842f01 --- /dev/null +++ b/src/features/slaughter-house/components/slaughter-manage-dispensers/SlaughterManageDispensersLimitationForm.js @@ -0,0 +1,133 @@ +import React, { useContext, useState } from "react"; +import { + Button, + TextField, + Typography, + Checkbox, + FormControlLabel, +} from "@mui/material"; +import { useDispatch } from "react-redux"; +import { Grid } from "../../../../components/grid/Grid"; +import { SPACING } from "../../../../data/spacing"; +import { CLOSE_MODAL } from "../../../../lib/redux/slices/appSlice"; +import { AppContext } from "../../../../contexts/AppContext"; +import { slaughterEditDispenserInfoService } from "../../services/slaughter-edit-dispenser-info"; + +export const SlaughterManageDispensersLimitationForm = ({ + item, + updateTable, +}) => { + const dispatch = useDispatch(); + const [openNotif] = useContext(AppContext); + + const [hasLimitation, setHasLimitation] = useState(item?.limitation || false); + const [governmentalValue, setGovernmentalValue] = useState( + item?.governmentalLimitationWeight || 0 + ); + const [freeValue, setFreeValue] = useState(item?.freeLimitationWeight || 0); + + const handleSubmit = (e) => { + e.preventDefault(); + + const submitData = { + key: item?.key, + limitation: hasLimitation, + governmental_limitation_weight: hasLimitation + ? Number(governmentalValue) + : 0, + free_limitation_weight: hasLimitation ? Number(freeValue) : 0, + }; + + dispatch(slaughterEditDispenserInfoService(submitData)).then((r) => { + if (r.payload?.error) { + openNotif({ + vertical: "top", + horizontal: "center", + msg: r.payload.error, + severity: "error", + }); + } else { + openNotif({ + vertical: "top", + horizontal: "center", + msg: "عملیات با موفقیت انجام شد.", + severity: "success", + }); + if (updateTable) { + updateTable(); + } + dispatch(CLOSE_MODAL()); + } + }); + }; + + return ( +
    + + + + اطلاعات توزیع کننده: + + + {item?.firstName} {item?.lastName} + + + + + setHasLimitation(e.target.checked)} + color="primary" + /> + } + label="محدودیت فروش روزانه" + /> + + + {hasLimitation && ( + <> + + setGovernmentalValue(e.target.value)} + inputProps={{ min: 0 }} + /> + + + + setFreeValue(e.target.value)} + inputProps={{ min: 0 }} + /> + + + )} + + + + + +
    + ); +}; diff --git a/src/features/slaughter-house/components/slaughter-manage-dispensers/SlaughterManageDispensersOperations.js b/src/features/slaughter-house/components/slaughter-manage-dispensers/SlaughterManageDispensersOperations.js new file mode 100644 index 0000000..deeeb24 --- /dev/null +++ b/src/features/slaughter-house/components/slaughter-manage-dispensers/SlaughterManageDispensersOperations.js @@ -0,0 +1,82 @@ +import { IconButton, Popover, Typography, Button } from "@mui/material"; +import React, { useState } from "react"; +import TuneIcon from "@mui/icons-material/Tune"; +import BlockIcon from "@mui/icons-material/Block"; +import { useDispatch } from "react-redux"; +import { OPEN_MODAL } from "../../../../lib/redux/slices/appSlice"; +import { SlaughterManageDispensersLimitationForm } from "./SlaughterManageDispensersLimitationForm"; + +export const SlaughterManageDispensersOperations = ({ item, updateTable }) => { + const [anchorEl, setAnchorEl] = useState(null); + const dispatch = useDispatch(); + + const handleClick = (event) => { + setAnchorEl(event.currentTarget); + }; + + const handleClose = () => { + setAnchorEl(null); + }; + + const open = Boolean(anchorEl); + const id = open ? "popover" : undefined; + + const handleOpenLimitationModal = () => { + handleClose(); + dispatch( + OPEN_MODAL({ + title: "تنظیم محدودیت فروش", + content: ( + + ), + size: 400, + }) + ); + }; + + return ( +
    + + + + +
    + +
    +
    +
    + ); +}; + diff --git a/src/features/slaughter-house/components/slaughter-manage-inventory-allocation-operations/SlaughterManageInventoryAllocationOperations.js b/src/features/slaughter-house/components/slaughter-manage-inventory-allocation-operations/SlaughterManageInventoryAllocationOperations.js new file mode 100644 index 0000000..d640f26 --- /dev/null +++ b/src/features/slaughter-house/components/slaughter-manage-inventory-allocation-operations/SlaughterManageInventoryAllocationOperations.js @@ -0,0 +1,266 @@ +import React, { useContext, useState } from "react"; +import { + Button, + IconButton, + List, + ListItemButton, + ListItemIcon, + ListItemText, + Popover, + Typography, +} from "@mui/material"; +import TuneIcon from "@mui/icons-material/Tune"; +import EditIcon from "@mui/icons-material/Edit"; +import CheckCircleOutlineIcon from "@mui/icons-material/CheckCircleOutline"; +import DeleteIcon from "@mui/icons-material/Delete"; +import { Grid } from "../../../../components/grid/Grid"; +import { CLOSE_MODAL, OPEN_MODAL } from "../../../../lib/redux/slices/appSlice"; +import { AppContext } from "../../../../contexts/AppContext"; +import { SPACING } from "../../../../data/spacing"; +import { useDispatch } from "react-redux"; +import { slaughterInventoryFinalSubmitService } from "../../services/slaughter-inventory-final-submit"; +import { slaughterDeleteAllocatedService } from "../../services/salughter-delete-allocated"; +import { SlaughterAllocateToGuild } from "../slaughter-allocate-to-guild/SlaughterAllocateToGuild"; +import { SlaughterAllocateForFreezing } from "../slaughter-allocate-for-freezing/SlaughterAllocateForFreezing"; +import { fetchSlaughterBroadcastAndProducts } from "../../services/handle-fetch-slaughter-products"; + +export const SlaughterManageInventoryAllocationOperations = ({ + fetchApiData, + item, + priceInfo, + remainWeight, +}) => { + const [anchorEl, setAnchorEl] = useState(null); + + const handleClick = (event) => { + setAnchorEl(event.currentTarget); + }; + + const handleClose = () => { + setAnchorEl(null); + }; + + const open = Boolean(anchorEl); + const id = open ? "popover" : undefined; + + const [openNotif] = useContext(AppContext); + + const dispatch = useDispatch(); + + const handleEdit = () => { + handleClose(); + dispatch( + OPEN_MODAL({ + title: "ویرایش تخصیص", + content: + item?.allocationType === "ColdHouse" ? ( + + ) : ( + + ), + }) + ); + }; + + const handleFinalSubmit = () => { + handleClose(); + dispatch( + OPEN_MODAL({ + title: "ثبت نهایی", + content: ( + + + در صورت ثبت نهایی انجام هیچگونه عملیاتی مانند حذف و ویرایش امکان + پذیر نمی باشد. + + + + + + + ), + }) + ); + }; + + const handleDelete = () => { + handleClose(); + dispatch( + OPEN_MODAL({ + title: "آیا مطمئن هستید؟", + content: ( + + + + + + + + + ), + }) + ); + }; + + const options = [ + { + key: "edit", + label: "ویرایش", + icon: EditIcon, + color: "primary.main", + action: handleEdit, + }, + ]; + + if (!item?.registrationCode) { + options.push({ + key: "finalSubmit", + label: "تایید نهایی", + icon: CheckCircleOutlineIcon, + color: "info.main", + action: handleFinalSubmit, + }); + } + + if (!item?.registrationCode) { + options.push({ + key: "delete", + label: "حذف", + icon: DeleteIcon, + color: "error.main", + action: handleDelete, + }); + } + + return ( + + + + + + + {options.map((option) => { + const IconComponent = option.icon; + return ( + + + + + + + ); + })} + + + + ); +}; diff --git a/src/features/slaughter-house/components/slaughter-manage-inventory-allocation-operations/test.js b/src/features/slaughter-house/components/slaughter-manage-inventory-allocation-operations/test.js new file mode 100644 index 0000000..e58b3d0 --- /dev/null +++ b/src/features/slaughter-house/components/slaughter-manage-inventory-allocation-operations/test.js @@ -0,0 +1,191 @@ +import { Button, Typography } from "@mui/material"; +import { useContext } from "react"; +import { useDispatch, useSelector } from "react-redux"; +import { Grid } from "../../../../components/grid/Grid"; +import { AppContext } from "../../../../contexts/AppContext"; +import { CLOSE_MODAL, OPEN_MODAL } from "../../../../lib/redux/slices/appSlice"; +import { slaughterDeleteAllocatedService } from "../../services/salughter-delete-allocated"; +import { slaughterGetUpdatedInventoryStock } from "../../services/salughter-get-updated-inventory-stock"; +import { slaughterManageInventoryAllocationsService } from "../../services/salughter-manage-inventory-allocations"; +import { slaughterGetKillhouseGuildsService } from "../../services/slaughter-get-killhouse-guilds"; +import { slaughterGetKillhouseStewardsService } from "../../services/slaughter-get-killhouse-stewards"; +import { SlaughterAddSteward } from "../slaughter-add-steward/SlaughterAddSteward"; +import { SubmitAuthCode } from "../submit-auth-code/SubmitAuthCode"; +import { slaughterInventoryFinalSubmitService } from "../../services/slaughter-inventory-final-submit"; +import { SPACING } from "../../../../data/spacing"; + +export const SlaughterManageInventoryAllocationOperationsTest = ({ + item, + disabled, +}) => { + const dispatch = useDispatch(); + const [openNotif] = useContext(AppContext); + const [, , selectedDate1] = useContext(AppContext); + const { inventorySelectedKillHouse } = useSelector( + (state) => state.slaughterSlice + ); + + return ( + + {item.systemRegistrationCode && ( + + )} + {!item.systemRegistrationCode && ( + + + + + ), + }) + ); + }} + > + ارسال کداحراز + + )} + + {!item.systemRegistrationCode && ( + <> + + + + )} + + ); +}; diff --git a/src/features/slaughter-house/components/slaughter-morgue-broadcast-management/SlaughterMorgueBroadcastManagement.js b/src/features/slaughter-house/components/slaughter-morgue-broadcast-management/SlaughterMorgueBroadcastManagement.js new file mode 100644 index 0000000..2b7ba1d --- /dev/null +++ b/src/features/slaughter-house/components/slaughter-morgue-broadcast-management/SlaughterMorgueBroadcastManagement.js @@ -0,0 +1,3 @@ +export const SlaughterMorgueBroadcastManagement = () => { + return null; +}; diff --git a/src/features/slaughter-house/components/slaughter-morgue-operation/SlaughterMorgueOperation.js b/src/features/slaughter-house/components/slaughter-morgue-operation/SlaughterMorgueOperation.js new file mode 100644 index 0000000..a0c587b --- /dev/null +++ b/src/features/slaughter-house/components/slaughter-morgue-operation/SlaughterMorgueOperation.js @@ -0,0 +1,47 @@ +import { VscNewFolder } from "react-icons/vsc"; +import { useLocation } from "react-router-dom"; +import { Grid } from "../../../../components/grid/Grid"; +import LinkItem from "../../../../components/link-item/LinkItem"; +import { NavLink } from "../../../../components/nav-link/NavLink"; +import { SPACING } from "../../../../data/spacing"; +import { + ROUTE_SLAUGHTER_MORGUE_BROADCAST_MANAGEMENT, + ROUTE_SLAUGHTER_MORGUE_STOCK, +} from "../../../../routes/routes"; + +export const SlaughterMorgueOperation = () => { + const { pathname } = useLocation(); + return ( + + + } + title="موجودی انبار" + /> + + + } + title="مدیریت پخش" + /> + + + ); +}; diff --git a/src/features/slaughter-house/components/slaughter-morgue-stock/SlaughterMorgueStock.js b/src/features/slaughter-house/components/slaughter-morgue-stock/SlaughterMorgueStock.js new file mode 100644 index 0000000..df05161 --- /dev/null +++ b/src/features/slaughter-house/components/slaughter-morgue-stock/SlaughterMorgueStock.js @@ -0,0 +1,3 @@ +export const SlaughterMorgueStock = () => { + return null; +}; diff --git a/src/features/slaughter-house/components/slaughter-morgue-view/SlaughterMorgueView.js b/src/features/slaughter-house/components/slaughter-morgue-view/SlaughterMorgueView.js new file mode 100644 index 0000000..9ff7c09 --- /dev/null +++ b/src/features/slaughter-house/components/slaughter-morgue-view/SlaughterMorgueView.js @@ -0,0 +1,221 @@ +import React, { useEffect, useState } from "react"; +import { + Checkbox, + FormControlLabel, + Tab, + Tabs, + TextField, +} from "@mui/material"; +import { useDispatch, useSelector } from "react-redux"; +import moment from "moment"; +import { DatePicker } from "@mui/x-date-pickers"; +import { + liveStockGetInventoryData, + liveStockGetInventoryDataDashboard, +} from "../../../live-stock-support/services/live-stock-get-inventory-data"; +import { Grid } from "../../../../components/grid/Grid"; +import ResponsiveTable from "../../../../components/responsive-table/ResponsiveTable"; +import { SPACING } from "../../../../data/spacing"; +import { SlaughterColdHouseBars } from "../slaughter-cold-house-bars/SlaughterColdHouseBars"; +import { useParams } from "react-router-dom"; +import { checkPathStartsWith } from "../../../../utils/checkPathStartsWith"; + +export const SlaughterMorgueView = () => { + const dispatch = useDispatch(); + const [tableData, setTableData] = useState([]); + const [tableDataDashboard, setTableDataDashboard] = useState([]); + const selectedSubUser = useSelector( + (state) => state.userSlice.selectedSubUser + ); + const { key } = useParams(); + + const [withDate, setWithDate] = useState(false); + + const [selectedDate1, setSelectedDate1] = useState( + moment(new Date()).format("YYYY-MM-DD") + ); + const [selectedDate2, setSelectedDate2] = useState( + moment(new Date()).format("YYYY-MM-DD") + ); + + const getDashboardsData = () => { + dispatch( + liveStockGetInventoryData({ + dashboard: true, + cold_house_key: key, + role_key: checkPathStartsWith("slaughter") + ? selectedSubUser?.key || "" + : "", + }) + ).then((r) => { + setTableData(r.payload.data); + }); + dispatch( + liveStockGetInventoryDataDashboard({ + date1: withDate ? selectedDate1 : null, + date2: withDate ? selectedDate2 : null, + cold_house_key: key, + role_key: checkPathStartsWith("slaughter") + ? selectedSubUser?.key || "" + : "", + }) + ).then((r) => { + setTableDataDashboard(r.payload.data); + }); + }; + useEffect(() => { + getDashboardsData(); + }, [dispatch, withDate, selectedDate1, selectedDate2, selectedSubUser?.key]); + + const [value, setValue] = useState(0); + + const handleChange = (event, newValue) => { + setValue(newValue); + }; + + return ( + <> + + + + + + + + + + setWithDate(!withDate)} + color="primary" + /> + } + /> + + + ( + + )} + value={selectedDate1} + onChange={(e) => { + setSelectedDate1(moment(e).format("YYYY-MM-DD")); + }} + /> + + + ( + + )} + value={selectedDate2} + onChange={(e) => { + setSelectedDate2(moment(e).format("YYYY-MM-DD")); + }} + /> + + + + + + + + + {value === 0 && ( + + )} + {value === 1 && ( + + )} + + + + ); +}; diff --git a/src/features/slaughter-house/components/slaughter-new-car/SlaughterNewCar.js b/src/features/slaughter-house/components/slaughter-new-car/SlaughterNewCar.js new file mode 100644 index 0000000..5e88666 --- /dev/null +++ b/src/features/slaughter-house/components/slaughter-new-car/SlaughterNewCar.js @@ -0,0 +1,374 @@ +import { Button, Grid, IconButton, TextField, Typography } from "@mui/material"; +import { SPACING } from "../../../../data/spacing"; +import SendIcon from "@mui/icons-material/Send"; +import { useFormik } from "formik"; +import { Yup } from "../../../../lib/yup/yup"; +import { useEffect } from "react"; +import { + DRAWER, + LOADING_END, + LOADING_START, +} from "../../../../lib/redux/slices/appSlice"; +import { slaughterNewCar } from "../../services/slaughter-new-car"; +import { useDispatch } from "react-redux"; +import { slaughterGetCars } from "../../services/slaughter-get-cars"; +import { AppContext } from "../../../../contexts/AppContext"; +import { useContext } from "react"; +import SearchIcon from "@mui/icons-material/Search"; +import { slaughterGetDriverByHealthCode } from "../../services/slaughter-get-driver-by-health-code"; +import { useState } from "react"; + +export const SlaughterNewCar = ({ cars, killHouseKey }) => { + const dispatch = useDispatch(); + const [openNotif] = useContext(AppContext); + const [userExist, setUserExist] = useState(false); + const [userData, setUserData] = useState(); + const [userKey, setUserKey] = useState(); + const [userChecked, setUserChecked] = useState(false); + + const formik = useFormik({ + initialValues: { + driver_name: "", + driver_mobile: "", + type_car: "ایسوزو", + type_weight: "سنگین", + capocity: "", + health_code: "", + pelak1: "", + pelak2: "الف", + pelak3: "", + pelak4: "", + // name: "", + }, + validationSchema: Yup.object({ + driver_name: Yup.string() + .matches( + /^[ض‌ص‌ث‌ق‌ف‌غ‌ع‌ه‌خ‌خ‌ح‌ج‌چ‌ش‌س‌ی‌ب‌ل‌ا‌ت‌ن‌ن‌م‌ک‌گ‌ظ‌ط‌ز‌ر‌ذ‌د‌و‌پ‌آ‌ژ ]+$/, + "فقط حروف فارسی وارد کنید" + ) + .required("این فیلد اجباری است!") + .typeError("لطفا فیلد را به درستی وارد کنید!"), + driver_mobile: Yup.string() + .test("len", "شماره تلفن باید با 0 شروع شود", (val, context) => { + return context.originalValue && context.originalValue.startsWith("0"); + }) + .test("len", "شماره تماس 11 رقم باید باشد", (val, context) => { + if (context.originalValue) { + return context.originalValue.length === 11; + } + }) + + .required("این فیلد اجباری است!") + .typeError("لطفا عدد وارد کنید!"), + type_weight: Yup.string() + .required("این فیلد اجباری است!") + .typeError("لطفا فیلد را به درستی وارد کنید!"), + capocity: Yup.string() + .required("این فیلد اجباری است!") + .typeError("لطفا فیلد را به درستی وارد کنید!"), + health_code: Yup.string() + .required("این فیلد اجباری است!") + .typeError("لطفا فیلد را به درستی وارد کنید!"), + pelak1: Yup.number() + .required("این فیلد اجباری است!") + .typeError("لطفا عدد وارد کنید!"), + pelak2: Yup.string() + .required("این فیلد اجباری است!") + .typeError("لطفا فیلد را به درستی وارد کنید!"), + pelak3: Yup.number() + .required("این فیلد اجباری است!") + .typeError("لطفا عدد وارد کنید!"), + pelak4: Yup.number() + .required("این فیلد اجباری است!") + .typeError("لطفا عدد وارد کنید!"), + name: Yup.string().typeError("لطفا فیلد را به درستی وارد کنید!"), + }), + }); + + useEffect(() => { + formik.validateForm(); + formik2.validateForm(); + }, []); + + const formik2 = useFormik({ + initialValues: { + health_code_check: "", + }, + validationSchema: Yup.object({ + health_code_check: Yup.number() + .required("این فیلد اجباری است!") + .typeError("لطفا فیلد را به درستی وارد کنید!"), + }), + }); + + return ( + + + + + {!userChecked && ( + <> + ثبت با کد بهداشتی + + + { + if (formik2.values.health_code_check) { + dispatch(LOADING_START()); + dispatch( + slaughterGetDriverByHealthCode( + formik2.values.health_code_check + ) + ).then((r) => { + if (r.error) { + openNotif({ + vertical: "top", + horizontal: "center", + msg: "مشکلی پیش آمده است!", + severity: "error", + }); + } else { + setUserChecked(true); + if (r.payload.data[0]) { + setUserData(r.payload.data[0]); + setUserExist(true); + setUserKey(r.payload.data[0]?.key); + } else { + openNotif({ + vertical: "top", + horizontal: "center", + msg: "راننده پیدا نشد!", + severity: "error", + }); + dispatch( + DRAWER({ + right: false, + bottom: false, + content: null, + }) + ); + setUserExist(false); + } + } + dispatch(LOADING_END()); + }); + } + }} + > + + + + + )} + {userChecked && ( + <> + {userExist ? ( + <> + + + prop.palette.grey["A700"]} + > + نام راننده: + + + {userData.driverName} + {" "} + + + + prop.palette.grey["A700"]} + > + موبایل: + + + {userData.driverMobile} + + + + + prop.palette.grey["A700"]} + > + خودرو: + + + {userData.typeCar} + {" "} + + + + prop.palette.grey["A700"]} + > + پلاک: + + + {userData.pelak} + {" "} + + + + prop.palette.grey["A700"]} + > + ظرفیت: + + + {userData.capocity} + {" "} + + + + ) : ( + <> + خودرو وجود ندارد! + + )} + + + )} + + + + + ); +}; diff --git a/src/features/slaughter-house/components/slaughter-new-factor-file/SlaughterNewFactorFile.js b/src/features/slaughter-house/components/slaughter-new-factor-file/SlaughterNewFactorFile.js new file mode 100644 index 0000000..8e9abd8 --- /dev/null +++ b/src/features/slaughter-house/components/slaughter-new-factor-file/SlaughterNewFactorFile.js @@ -0,0 +1,414 @@ +import React, { forwardRef } from "react"; +import { PropTypes } from "prop-types"; +import { useSystemName } from "../../../../utils/getSystemName"; +import logo from "../../../../assets/images/logo.png"; +import { useCeoName } from "../../../../utils/getCeoName"; + +const styles = { + page: { + width: "210mm", + margin: "0 auto", + display: "flex", + flexDirection: "column", + position: "relative", + direction: "rtl", + fontFamily: "nazanin", + fontWeight: "bold", + }, + container: { + width: "95%", + alignSelf: "center", + pageBreakInside: "avoid", + }, + p: { + fontFamily: "nazanin", + fontWeight: "bold", + pAlign: "justify", + }, + span: { + fontFamily: "nazanin", + fontWeight: "bold", + pAlign: "justify", + }, + invoiceTable: { + width: "100%", + borderCollapse: "collapse", + alignSelf: "center", + marginBottom: "2px", + }, + tableCell: { + border: "1px solid #000", + pAlign: "left", + textAlign: "center", + fontSize: 11, + }, + tableCellMobile: { + border: "1px solid #000", + pAlign: "left", + textAlign: "center", + fontSize: 10, + }, + tableInnerCell: { + border: "1px solid #000", + pAlign: "left", + textAlign: "center", + fontSize: 8, + whiteSpace: "nowrap", + }, + tableHeader: { + backgroundColor: "rgba(211, 211, 211, 0.3)", + pageBreakAfter: "auto", + }, + headerRow: { + backgroundColor: "rgba(211, 211, 211, 0.3)", + color: "black", + pageBreakInside: "avoid", + pageBreakAfter: "auto", + }, + logo: { + width: "60px", + height: "auto", + marginBottom: "10px", + }, + contentContainer: { + display: "flex", + justifyContent: "space-between", + marginTop: "20px", + marginLeft: "100px", + marginRight: "30px", + }, + contentInLine: { + display: "flex", + flexDirection: "column", + alignItems: "center", + }, + mainTitle: { + fontFamily: "nazanin", + fontSize: 11, + pAlign: "center", + fontWeight: "bolder", + }, + signature: { + display: "flex", + flexDirection: "column", + alignItems: "flex-end", + marginLeft: "20px", + }, + watermarkContainer: { + position: "fixed", + top: 450, + left: 0, + right: 30, + bottom: 0, + justifyContent: "center", + alignItems: "center", + opacity: 0.2, + zIndex: -1, + }, + watermarkp: { + fontSize: 100, + fontWeight: "bolder", + color: "grey", + transform: "rotate(-45deg)", + left: "50%", + }, + title: { + fontSize: 12, + fontWeight: "bolder", + pAlign: "center", + }, + titleTopic: { + marginTop: "10px", + fontSize: 12, + fontWeight: "bolder", + pAlign: "center", + }, + firsttitle: { + fontSize: 14, + fontWeight: "bolder", + marginLeft: "40px", + pAlign: "center", + }, + title2: { + fontSize: 10, + marginBottom: 10, + pAlign: "center", + }, + options: { + marginLeft: "50px", + padding: "10px", + marginTop: "15px", + display: "flex", + flexDirection: "column", + alignItems: "flex-start", + }, + divider: { + width: "100%", + height: "2px", + backgroundColor: "red", + marginBottom: 15, + }, + pTitleContainer: { + pAlign: "center", + margin: "15px", + textAlign: "justify", + textJustify: "inter-word", + }, + tableHeaderCell: { + backgroundColor: "rgba(211, 211, 211, 0.3)", + fontSize: 10, + border: "1px solid #000", + padding: "4px", + textAlign: "center", + fontWeight: "bold", + }, + footer: { + pageBreakAfter: "always", + position: "fixed", + left: 0, + bottom: 0, + width: "100%", + }, +}; + +const SlaughterNewFactorFile = forwardRef((props, ref) => { + const { item } = props; + // const { date } = props; + const systemName = useSystemName(); + const ceoName = useCeoName(); + + return ( +
    +
    +
    + logo + + اتحادیه سراسری تعاونی‌های کشاورزی پرورش دهندگان مرغ گوشتی ایران + + + اتحادیه شرکت های تعاونی کشاورزی مرغداران {" ‌"} {systemName} + +
    + +
    + بسمه تعالی +
    + +
    + شماره: + تاریخ: +
    +
    + +
    + + + فاکتور فروش + +
    + +
    + + + + + + + +
    + + خریدار{" "} + + + {" ‌"} + {" ‌"} + { + item?.provinceCheckInfo?.killHouseAssignment?.killHouseRequest + ?.killhouseUser?.killHouseOperator?.user?.fullname + } +
    + + + + + + + + +
    + + فروشنده{" "} + + + {" ‌"} + {" ‌"} + اتحادیه شرکت های تعاونی کشاورزی مرغداران {" ‌"} {systemName} +
    + + + +
    + + + + + + + + + + + + + + + + + + +
    ردیفشرحوزن (کیلوگرم) + قیمت مرغ زنده (کیلوگرم) + قیمت کل (ریال)
    1 + بار شماره + { + item?.provinceCheckInfo?.killHouseAssignment + ?.killHouseRequest?.barCode + } + مرغداری :{" "} + {`${item?.poultryRequest?.poultryName} (${item?.poultryRequest?.poultryUserMobile})`} + + {item?.provinceFactorToKillHouse.netWeight?.toLocaleString()} + + {item?.factorFee?.toLocaleString() + " ﷼"} + + {item?.provinceFactorToKillHouse?.totalFactorAmount?.toLocaleString() + + " ﷼"} +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + جمع فاکتور + + {item?.provinceFactorToKillHouse?.totalFactorAmount?.toLocaleString() + + " ﷼"} +
    تخفیف0
    مالیات0
    عوارض0
    + مبلغ قابل پرداخت (ریال) + + {item?.provinceFactorToKillHouse?.totalFactorAmount?.toLocaleString() + + " ﷼"} +
    + + + +
    +
    +
    + {ceoName} + + مدیرعامل اتحادیه مرغداران{" ‌"} + {systemName} + +
    +
    +
    +
    +

    سامانه رصدیار

    +
    + + {/*
    +
    +

    + {getAddressContent(systemName)} +

    +
    */} +
    +
    + ); +}); + +SlaughterNewFactorFile.displayName = "SlaughterNewFactorFile"; + +export default SlaughterNewFactorFile; + +SlaughterNewFactorFile.propTypes = { + item: PropTypes.any, +}; diff --git a/src/features/slaughter-house/components/slaughter-new-request/SlaughterNewRequestForm.js b/src/features/slaughter-house/components/slaughter-new-request/SlaughterNewRequestForm.js new file mode 100644 index 0000000..72b3413 --- /dev/null +++ b/src/features/slaughter-house/components/slaughter-new-request/SlaughterNewRequestForm.js @@ -0,0 +1,517 @@ +import { + Button, + Checkbox, + FormControl, + FormControlLabel, + FormHelperText, + Grid, + InputLabel, + ListItem, + ListItemIcon, + ListItemText, + MenuItem, + Select, + TextField, + Tooltip, + Typography, +} from "@mui/material"; +import { DatePicker } from "@mui/x-date-pickers"; +import DoneIcon from "@mui/icons-material/Done"; +import { useEffect, useState, useContext } from "react"; +import { useDispatch, useSelector } from "react-redux"; +import { useFormik } from "formik"; +import moment from "moment"; + +import { SPACING } from "../../../../data/spacing"; +import { Yup } from "../../../../lib/yup/yup"; +import { + CLOSE_MODAL, + DRAWER, + LOADING_END, + LOADING_START, + OPEN_MODAL, +} from "../../../../lib/redux/slices/appSlice"; +import { AppContext } from "../../../../contexts/AppContext"; +import { DialogAlert } from "../../../../components/dialog-alert/DialogAlert"; +import { NumberInput } from "../../../../components/number-format-custom/NumberFormatCustom"; +import useUserProfile from "../../../authentication/hooks/useUserProfile"; +import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl"; +import { slaughterNewRequest } from "../../services/slaughter-new-request"; +import { slaughterGetRequests } from "../../services/salughter-get-requests"; +import { slaughterGetProfile } from "../../services/slaughter-get-profile"; +import { slaughterGetKillerKillhousesService } from "../../services/slaughter-get-killers-killhouses"; +import { provinceGetPricing } from "../../../province/services/province-get-pricing"; +import { checkPathStartsWith } from "../../../../utils/checkPathStartsWith"; + +const TIME_RANGES = [ + "12 - 14", + "14 - 16", + "16 - 18", + "18 - 20", + "20 - 22", + "22 - 24", +]; + +const CHICKEN_BREEDS = [ + "آرین", + "راس", + "آربراکرز (آپلاس)", + "کاب", + "هوبارد", + "ترکیبی", + "وارداتی", +]; + +const DEFAULT_INDEX_WEIGHT = 2.7; +const PENALTY_MULTIPLIER = 1000; +const SMS_COST = "5000 تومان"; + +const getInitialValues = (selectedSubUser) => ({ + capacity: "", + recieveTime: "", + selectedKillhouse: selectedSubUser?.key || "", + selectedKillerKillhouse: "", + race: CHICKEN_BREEDS[0], + sellType: { + cash: true, + haveTime: false, + }, + weightType: { + under2AndHalf: false, + over2AndHalf: false, + }, + recieveDate: moment().format("YYYY-MM-DD hh:mm:ss"), + isAccepted: getRoleFromUrl() === "ProvinceOperator", + indexWeight: DEFAULT_INDEX_WEIGHT, +}); + +const getValidationSchema = (selectedSubUser) => + Yup.object({ + capacity: Yup.number() + .required("این فیلد اجباری است!") + .typeError("لطفا عدد وارد کنید!"), + selectedKillhouse: Yup.string().required("این فیلد اجباری است!"), + selectedKillerKillhouse: selectedSubUser?.killer + ? Yup.string().required("این فیلد اجباری است!") + : Yup.string(), + recieveTime: Yup.string() + .required("این فیلد اجباری است!") + .typeError("لطفا وزن را وارد کنید!"), + sellType: Yup.object() + .test("sellType", "نحوه فروش را انتخاب کنید!", (val, context) => { + return ( + context.originalValue && + Object.values(context.originalValue).some((item) => item === true) + ); + }) + .required("این فیلد اجباری است!"), + isAccepted: Yup.boolean() + .test("req", "باید تعهد نامه را بپذیرید!", (val, context) => { + return context.originalValue && context.originalValue === true; + }) + .required("این فیلد اجباری است!"), + }); + +export const SlaughterNewRequestForm = () => { + const [openNotif, , selectedDate1, , selectedDate2] = useContext(AppContext); + const dispatch = useDispatch(); + const [, userProfile] = useUserProfile(); + const { profile, slaughterGetKillerKillhouses } = useSelector( + (state) => state.slaughterSlice + ); + const selectedSubUser = useSelector( + (state) => state.userSlice.selectedSubUser + ); + + const [checkedSms, setCheckedSms] = useState(true); + const [checkedBreedAndWeight, setCheckedBreedAndWeight] = useState(false); + + const formik = useFormik({ + initialValues: getInitialValues(selectedSubUser), + validationSchema: getValidationSchema(selectedSubUser), + }); + + const penaltyPrice = formik.values.capacity * PENALTY_MULTIPLIER; + + const dialogContent = ( + <> + + اینجانب {userProfile.fullname} موافقت خود را نسبت به موارد ذکر شده اعلام + می نمایم. + + + + + + + + + ); + + useEffect(() => { + dispatch( + slaughterGetKillerKillhousesService({ + role_key: checkPathStartsWith("slaughter") + ? selectedSubUser?.key || "" + : "", + }) + ); + dispatch(LOADING_START()); + dispatch( + slaughterGetProfile({ + role_key: checkPathStartsWith("slaughter") + ? selectedSubUser?.key || "" + : "", + }) + ).then(() => { + dispatch(LOADING_END()); + }); + dispatch(provinceGetPricing()); + formik.validateForm(); + }, [selectedSubUser?.key]); + + const handleSubmit = async () => { + dispatch(LOADING_START()); + const result = await dispatch( + slaughterNewRequest({ + kill_capacity: formik.values.capacity, + recive_time: formik.values.recieveTime, + recive_date: formik.values.recieveDate, + low_weight: formik.values.weightType.under2AndHalf, + high_weight: formik.values.weightType.over2AndHalf, + Index_weight: checkedBreedAndWeight + ? formik.values.indexWeight + : DEFAULT_INDEX_WEIGHT, + chicken_breed: checkedBreedAndWeight + ? formik.values.race + : "تعیین نشده", + cash: formik.values.sellType.cash, + credit: formik.values.sellType.haveTime, + sms_payment: checkedSms, + kill_house_key: formik.values.selectedKillhouse, + killer_kill_house_key: formik.values.selectedKillerKillhouse || null, + role: getRoleFromUrl(), + }) + ); + + dispatch(LOADING_END()); + + if (result.payload.error) { + openNotif({ + vertical: "top", + horizontal: "center", + msg: result.payload.error, + severity: "error", + }); + return; + } + + dispatch( + slaughterGetRequests({ + selectedDate1, + selectedDate2, + role_key: checkPathStartsWith("slaughter") + ? selectedSubUser?.key || "" + : "", + }) + ); + dispatch( + OPEN_MODAL({ + title: result.payload.data.result, + content: ( + + ), + }) + ); + openNotif({ + vertical: "top", + horizontal: "center", + msg: "عملیات با موفقیت انجام شد.", + severity: "success", + }); + dispatch(DRAWER({ right: false, bottom: false, content: null })); + }; + + const isProvinceOperator = getRoleFromUrl() === "ProvinceOperator"; + + return ( + + + {!selectedSubUser?.key && ( + + + {selectedSubUser?.killer ? "کشتارکن" : "محل کشتار"} را انتخاب کنید + + + {formik.errors.selectedKillhouse && + formik.touched.selectedKillhouse && ( + + {formik.errors.selectedKillhouse} + + )} + + )} + + {selectedSubUser?.killer && ( + + محل کشتار را انتخاب کنید + + {formik.errors.selectedKillerKillhouse && + formik.touched.selectedKillerKillhouse && ( + + {formik.errors.selectedKillerKillhouse} + + )} + + )} + + + + + + + + بازه زمانی دریافت مرغ مرغدار + + + + + + } + value={formik.values.recieveDate} + error={ + formik.touched.recieveDate + ? Boolean(formik.errors.recieveDate) + : null + } + onChange={(e) => { + formik.setFieldValue( + "recieveDate", + moment(e).format("YYYY-MM-DD hh:mm:ss") + ); + }} + onBlur={formik.handleBlur} + helperText={ + formik.touched.recieveDate && Boolean(formik.errors.recieveDate) + ? formik.errors.recieveDate + : null + } + /> + + + + setCheckedBreedAndWeight(e.target.checked)} + color="primary" + /> + } + label="تعیین نژاد/وزن مرغ" + /> + + {checkedBreedAndWeight && ( + + + نژاد مرغ + + + {formik.touched.race && Boolean(formik.errors.race) + ? formik.errors.race + : null} + + + + + + + + )} + + + {!isProvinceOperator && ( + + + + + } + btnTitle="با تعهد نامه موافق هستم!" + isAccepted={formik.values.isAccepted} + /> + )} + + + setCheckedSms(e.target.checked)} + /> + } + label={ + + + مایل به دریافت پیامک اطلاع رسانی هستم! + + + } + /> + + + + + + + + ); +}; diff --git a/src/features/slaughter-house/components/slaughter-none-reciept-back-modal/SlaughterRecieptBackModal.js b/src/features/slaughter-house/components/slaughter-none-reciept-back-modal/SlaughterRecieptBackModal.js new file mode 100644 index 0000000..c35b3ac --- /dev/null +++ b/src/features/slaughter-house/components/slaughter-none-reciept-back-modal/SlaughterRecieptBackModal.js @@ -0,0 +1,121 @@ +import { + Box, + Button, + Typography, + Stack, + Divider, + TextField, +} from "@mui/material"; +import { useFormik } from "formik"; +import * as Yup from "yup"; +import { SPACING } from "../../../../data/spacing"; +import { Grid } from "../../../../components/grid/Grid"; +import { format } from "date-fns-jalali"; + +export const SlaughterRecieptBackModal = ({ handleSubmit, item }) => { + const validationSchema = Yup.object({ + message: Yup.string().required("پیام الزامی است"), + }); + + const formik = useFormik({ + initialValues: { + message: "", + }, + validationSchema, + onSubmit: (values) => { + handleSubmit(values); + }, + }); + + return ( + + + + + + + کدبار: + {item?.barCode || "-"} + + + + تاریخ کشتار: + + {item?.poultryRequest.sendDate + ? format( + new Date(item?.poultryRequest.sendDate), + "yyyy/MM/dd" + ) + : "-"} + + + + خریدار: + {`${item.killhouseUser?.name}(${item.killhouseUser?.killHouseOperator?.user?.mobile})`} + + + + + + + + مرغدار: + {`${item.poultryRequest?.poultry?.unitName}`} + + + + کد سفارش: + + {item?.poultryRequest.orderCode} + + + + + تعداد اولیه: + + {item.quantity?.toLocaleString()} (قطعه) + + + + وزن : + + {item?.weightInfo?.weight?.toLocaleString()} (کیلوگرم) + + + + + + + + + + + + + ); +}; diff --git a/src/features/slaughter-house/components/slaughter-none-reciept-modal/SlaughterNoneRecieptModal.js b/src/features/slaughter-house/components/slaughter-none-reciept-modal/SlaughterNoneRecieptModal.js new file mode 100644 index 0000000..0764224 --- /dev/null +++ b/src/features/slaughter-house/components/slaughter-none-reciept-modal/SlaughterNoneRecieptModal.js @@ -0,0 +1,152 @@ +import { + Box, + Button, + FormControlLabel, + Radio, + RadioGroup, + TextField, + FormHelperText, + FormControl, + FormLabel, + Typography, + Stack, + Divider, +} from "@mui/material"; +import { useFormik } from "formik"; +import * as Yup from "yup"; +import { SPACING } from "../../../../data/spacing"; +import { Grid } from "../../../../components/grid/Grid"; +import { format } from "date-fns-jalali"; + +export const SlaughterNoneRecieptModal = ({ handleSubmit, item }) => { + const validationSchema = Yup.object({ + state: Yup.string().required("لطفا یک گزینه را انتخاب کنید"), + message: Yup.string().required("پیام الزامی است"), + }); + + const formik = useFormik({ + initialValues: { + state: "accepted", + message: "", + }, + validationSchema, + onSubmit: (values) => { + handleSubmit(values); + }, + }); + + return ( + + + + + + + کدبار: + {item?.barCode || "-"} + + + + تاریخ کشتار: + + {item?.poultryRequest.sendDate + ? format( + new Date(item?.poultryRequest.sendDate), + "yyyy/MM/dd" + ) + : "-"} + + + + + + مرغدار: + {`${item.poultryRequest?.poultry?.unitName}`} + + + + + + + + خریدار: + {`${item.killhouseUser?.name} (${item.killhouseUser?.killHouseOperator?.user?.mobile})`} + + + کد سفارش: + {item?.poultryRequest.orderCode} + + + + تعداد اولیه: + {item.quantity?.toLocaleString()} (قطعه) + + + وزن : + + {item?.weightInfo?.weight?.toLocaleString()} (کیلوگرم) + + + + + + + + + وضعیت + + } + label="تایید" + /> + } label="رد" /> + + {formik.touched.state && formik.errors.state && ( + {formik.errors.state} + )} + + + + + + + + ); +}; diff --git a/src/features/slaughter-house/components/slaughter-none-reciept-operation/SlaughterNoneRecieptOperation.js b/src/features/slaughter-house/components/slaughter-none-reciept-operation/SlaughterNoneRecieptOperation.js new file mode 100644 index 0000000..5d71ce4 --- /dev/null +++ b/src/features/slaughter-house/components/slaughter-none-reciept-operation/SlaughterNoneRecieptOperation.js @@ -0,0 +1,193 @@ +import { useContext, useState } from "react"; +import { Grid } from "../../../../components/grid/Grid"; +import { + Button, + IconButton, + Popover, + Tooltip, + Typography, +} from "@mui/material"; +import TuneIcon from "@mui/icons-material/Tune"; +import ReceiptLongIcon from "@mui/icons-material/ReceiptLong"; +import { CLOSE_MODAL, OPEN_MODAL } from "../../../../lib/redux/slices/appSlice"; +import { useDispatch } from "react-redux"; +import { slaughterNoneRecieptService } from "../../services/slaughter-none-reciept-operation"; +import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl"; +import { AppContext } from "../../../../contexts/AppContext"; +import { SlaughterNoneRecieptModal } from "../slaughter-none-reciept-modal/SlaughterNoneRecieptModal"; +import RestoreIcon from "@mui/icons-material/Restore"; +import { SlaughterRecieptBackModal } from "../slaughter-none-reciept-back-modal/SlaughterRecieptBackModal"; +import { slaughterNoneBackRecieptService } from "../../services/slaughter-none-back-reciept"; + +export const SlaughterNoneRecieptOperation = ({ item, updateTable }) => { + const dispatch = useDispatch(); + const [openNotif] = useContext(AppContext); + const [anchorEl, setAnchorEl] = useState(null); + + const handleClick = (event) => { + setAnchorEl(event.currentTarget); + }; + + const handleClose = () => { + setAnchorEl(null); + }; + + const open = Boolean(anchorEl); + const id = open ? "popover" : undefined; + + const handleSubmit = (values) => { + dispatch( + slaughterNoneRecieptService({ + key: item?.key, + role: getRoleFromUrl(), + state: values.state, + message: values.message, + }) + ).then((r) => { + dispatch(CLOSE_MODAL()); + if (r.payload.error) { + openNotif({ + vertical: "top", + horizontal: "center", + msg: r.payload.error, + severity: "error", + }); + } else { + handleClose(); + updateTable(); + openNotif({ + vertical: "top", + horizontal: "center", + msg: "عملیات با موفقیت انجام شد.", + severity: "success", + }); + } + }); + }; + + const handleBackSubmit = (values) => { + dispatch( + slaughterNoneBackRecieptService({ + key: item?.key, + non_receipt: false, + non_receipt_return: true, + non_receipt_return_message: values.message, + }) + ).then((r) => { + dispatch(CLOSE_MODAL()); + if (r.payload.error) { + openNotif({ + vertical: "top", + horizontal: "center", + msg: r.payload.error, + severity: "error", + }); + } else { + handleClose(); + updateTable(); + openNotif({ + vertical: "top", + horizontal: "center", + msg: "عملیات با موفقیت انجام شد.", + severity: "success", + }); + } + }); + }; + + return ( + + + + + + + {["ProvinceOperator", "SuperAdmin", "AdminX"].includes( + getRoleFromUrl() + ) && ( + + + + )} + + + + + + + ); +}; diff --git a/src/features/slaughter-house/components/slaughter-operations/SlaughterOperations.js b/src/features/slaughter-house/components/slaughter-operations/SlaughterOperations.js new file mode 100644 index 0000000..70d12c0 --- /dev/null +++ b/src/features/slaughter-house/components/slaughter-operations/SlaughterOperations.js @@ -0,0 +1,36 @@ +import { Grid } from "../../../../components/grid/Grid"; +import { SPACING } from "../../../../data/spacing"; +import { NavLink } from "../../../../components/nav-link/NavLink"; +import { useLocation } from "react-router-dom"; +import { Button } from "@mui/material"; +import { ROUTE_SLAUGHTER_CAR_MANAGEMENT } from "../../../../routes/routes"; + +export const SlaughterOperations = () => { + const { pathname } = useLocation(); + + return ( + + {/* + + */} + + + + + ); +}; diff --git a/src/features/slaughter-house/components/slaughter-orders/SlaughterOrders.js b/src/features/slaughter-house/components/slaughter-orders/SlaughterOrders.js new file mode 100644 index 0000000..a4b0030 --- /dev/null +++ b/src/features/slaughter-house/components/slaughter-orders/SlaughterOrders.js @@ -0,0 +1,304 @@ +import React, { useEffect, useState, useCallback } from "react"; +import { + Button, + Checkbox, + FormControlLabel, + IconButton, + TextField, + Tooltip, +} from "@mui/material"; +import { DatePicker } from "@mui/x-date-pickers"; +import moment from "moment"; +import { useDispatch, useSelector } from "react-redux"; +import axios from "axios"; +import { + LOADING_END, + LOADING_START, + OPEN_MODAL, +} from "../../../../lib/redux/slices/appSlice"; +import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl"; +import ResponsiveTable from "../../../../components/responsive-table/ResponsiveTable"; +import { Grid } from "../../../../components/grid/Grid"; +import VisibilityIcon from "@mui/icons-material/Visibility"; +import { formatJustDate } from "../../../../utils/formatTime"; +import { RiSearchLine } from "react-icons/ri"; +import { checkPathStartsWith } from "../../../../utils/checkPathStartsWith"; + +export const SlaughterOrders = () => { + const [selectedDate1, setSelectedDate1] = useState( + moment(new Date()).format("YYYY-MM-DD") + ); + const [selectedDate2, setSelectedDate2] = useState( + moment(new Date()).format("YYYY-MM-DD") + ); + const dispatch = useDispatch(); + const selectedSubUser = useSelector( + (state) => state.userSlice.selectedSubUser + ); + const handleTextChange = (event) => { + setTextValue(event.target.value); + }; + const [withDate, setWithDate] = useState(true); + const [data, setData] = useState([]); + const [totalRows, setTotalRows] = useState(0); + const [perPage, setPerPage] = useState(10); + const [textValue, setTextValue] = useState(""); + const [page, setPage] = useState(1); + const [tableData, setTableData] = useState([]); + + const fetchApiData = useCallback( + async (page) => { + dispatch(LOADING_START()); + const response = await axios.get( + `orders_for_kill_house/?search=filter&value=${textValue}&role=${getRoleFromUrl()}${ + checkPathStartsWith("slaughter") + ? `&role_key=${selectedSubUser?.key}` + : "" + }${ + withDate ? `&date1=${selectedDate1}&date2=${selectedDate2}` : `` + }&page=${page}&page_size=${perPage}` + ); + dispatch(LOADING_END()); + setData(response.data.results); + setTotalRows(response.data.count); + }, + [ + textValue, + withDate, + selectedDate1, + selectedDate2, + perPage, + setData, + setTotalRows, + page, + dispatch, + selectedSubUser?.key, + ] + ); + + const handlePageChange = (page) => { + fetchApiData(page); + setPage(page); + }; + + const handlePerRowsChange = (perRows) => { + setPerPage(perRows); + setPage(1); + }; + + useEffect(() => { + const d = data?.map((item, i) => { + return [ + page === 1 ? i + 1 : i + perPage * (page - 1) + 1, + item?.orderCode, + formatJustDate(item?.date), + item?.customerName, + item?.customerMobile, + item?.customerCity, + item?.productType, + item?.quantity?.toLocaleString(), + item?.weight?.toLocaleString(), + item?.status, + item?.deliveryDate ? formatJustDate(item?.deliveryDate) : "-", + + { + dispatch( + OPEN_MODAL({ + title: "جزئیات سفارش", + content: ( + + + کد سفارش: {item?.orderCode} + + + مشتری: {item?.customerName} + + + تلفن: {item?.customerMobile} + + + شهر: {item?.customerCity} + + + نوع محصول: {item?.productType} + + + حجم: {item?.quantity?.toLocaleString()}{" "} + قطعه + + + وزن: {item?.weight?.toLocaleString()}{" "} + کیلوگرم + + + وضعیت: {item?.status} + + + تاریخ ثبت: {formatJustDate(item?.date)} + + {item?.deliveryDate && ( + + تاریخ تحویل:{" "} + {formatJustDate(item?.deliveryDate)} + + )} + + ), + }) + ); + }} + > + + + , + ]; + }); + + setTableData(d); + }, [data]); + + useEffect(() => { + fetchApiData(1); + }, [selectedSubUser?.key]); + + const handleSubmit = async (event) => { + event.preventDefault(); + dispatch(LOADING_START()); + + try { + const response = await axios.get( + `orders_for_kill_house/?role=${getRoleFromUrl()}${ + checkPathStartsWith("slaughter") + ? `&role_key=${selectedSubUser?.key}` + : "" + }&search=filter&value=${textValue}${ + withDate ? `&date1=${selectedDate1}&date2=${selectedDate2}` : `` + }&page=${1}&page_size=${perPage}` + ); + setData(response.data.results); + setTotalRows(response.data.count); + dispatch(LOADING_END()); + } catch (error) { + console.error("Error fetching data:", error); + } + }; + + return ( + + + + + setWithDate(!withDate)} + color="primary" + /> + } + /> + + + + ( + + )} + value={selectedDate1} + onChange={(e) => { + setSelectedDate1(moment(e).format("YYYY-MM-DD")); + }} + /> + + + ( + + )} + value={selectedDate2} + onChange={(e) => { + setSelectedDate2(moment(e).format("YYYY-MM-DD")); + }} + /> + + + +
    + + + +
    +
    + + +
    + ); +}; diff --git a/src/features/slaughter-house/components/slaughter-out-province-bars/SlaughterOutProvinceBars.js b/src/features/slaughter-house/components/slaughter-out-province-bars/SlaughterOutProvinceBars.js new file mode 100644 index 0000000..86449e2 --- /dev/null +++ b/src/features/slaughter-house/components/slaughter-out-province-bars/SlaughterOutProvinceBars.js @@ -0,0 +1,6 @@ +import React from "react"; +import { SlaughterFreeBuyBars } from "../slaughter-free-buy-bars/SlaughterFreeBuyBars"; + +export const SlaughterOutProvinceBars = () => { + return ; +}; diff --git a/src/features/slaughter-house/components/slaughter-out-province-registration-code-input/SlaughterOutProvinceRegistrationCodeInput.js b/src/features/slaughter-house/components/slaughter-out-province-registration-code-input/SlaughterOutProvinceRegistrationCodeInput.js new file mode 100644 index 0000000..48b0327 --- /dev/null +++ b/src/features/slaughter-house/components/slaughter-out-province-registration-code-input/SlaughterOutProvinceRegistrationCodeInput.js @@ -0,0 +1,101 @@ +import React, { useContext, useState } from "react"; +import { Grid } from "../../../../components/grid/Grid"; +import { Button, TextField } from "@mui/material"; +import { useDispatch } from "react-redux"; +import { AppContext } from "../../../../contexts/AppContext"; +import { slaughterEditOutOfProvinceService } from "../../services/slaughterEditOutOfProvinceService"; +import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl"; +import { Done } from "@mui/icons-material"; + +export const SlaughterOutProvinceRegistrationCodeInput = ({ + item, + fetchApiData, +}) => { + const dispatch = useDispatch(); + const [openNotif] = useContext(AppContext); + const [registrationCode, setRegistrationCode] = useState( + item?.loggedRegistrationCode || "" + ); + + const handleSubmit = () => { + dispatch( + slaughterEditOutOfProvinceService({ + key: item?.key, + register_code: parseInt(registrationCode), + role: getRoleFromUrl(), + // Include all required fields from item + date: item?.date, + buyer_name: item?.buyerName, + buyer_mobile: item?.buyerMobile, + province: item?.province, + city: item?.city, + clearance_code: item?.clearanceCode, + number_of_carcasses: item?.numberOfCarcasses, + quarantine_weight_of_carcasses: item?.quarantineWeightOfCarcasses, + weight_of_carcasses: item?.weightOfCarcasses, + quota: item?.quota, + sale_type: item?.saleType, + ...(item?.buyer?.key && { buyer_key: item?.buyer?.key }), + }) + ).then((r) => { + if (r.payload.error) { + openNotif({ + vertical: "top", + horizontal: "center", + msg: r.payload.error, + severity: "error", + }); + } else { + openNotif({ + vertical: "top", + horizontal: "center", + msg: "کد احراز با موفقیت ثبت شد.", + severity: "success", + }); + fetchApiData(); + } + }); + }; + + return ( + + setRegistrationCode(e.target.value)} + style={{ minWidth: "150px" }} + disabled={item?.loggedRegistrationCode} + placeholder="کد احراز" + inputProps={{ + inputMode: "numeric", + pattern: "[0-9]*", + }} + type="number" + /> + {!item?.loggedRegistrationCode && registrationCode && ( + + )} + + ); +}; diff --git a/src/features/slaughter-house/components/slaughter-out-province-sales-operations/SlaughterOutProvinceSalesOperations.js b/src/features/slaughter-house/components/slaughter-out-province-sales-operations/SlaughterOutProvinceSalesOperations.js new file mode 100644 index 0000000..9534cfd --- /dev/null +++ b/src/features/slaughter-house/components/slaughter-out-province-sales-operations/SlaughterOutProvinceSalesOperations.js @@ -0,0 +1,196 @@ +import React, { useContext, useState } from "react"; +import { + IconButton, + List, + ListItem, + ListItemButton, + ListItemIcon, + ListItemText, + Popover, + Tooltip, + Typography, +} from "@mui/material"; +import { useDispatch } from "react-redux"; +import { AppContext } from "../../../../contexts/AppContext"; +import { DRAWER } from "../../../../lib/redux/slices/appSlice"; +import { slaughterDeleteOutOfProvinceSell } from "../../services/slaughter-delete-out-province-sell"; +import { SlaughterSubmitOutProvinceSell } from "../slaughter-submit-out-province-sell/SlaughterSubmitOutProvinceSell"; +import { fetchSlaughterBroadcastAndProducts } from "../../services/handle-fetch-slaughter-products"; +import { slaughterResendOutProvinceRegistrationCodeService } from "../../services/slaughter-resend-out-province-registration-code"; +import TuneIcon from "@mui/icons-material/Tune"; +import EditIcon from "@mui/icons-material/Edit"; +import DeleteIcon from "@mui/icons-material/Delete"; +import SendIcon from "@mui/icons-material/Send"; + +export const SlaughterOutProvinceSalesOperations = ({ + item, + updateTable, + fetchApiData, + page, +}) => { + const dispatch = useDispatch(); + const [openNotif] = useContext(AppContext); + const [anchorEl, setAnchorEl] = useState(null); + + const openPopover = (event) => { + setAnchorEl(event.currentTarget); + }; + + const closePopover = () => { + setAnchorEl(null); + }; + + const handleEdit = () => { + closePopover(); + dispatch( + DRAWER({ + right: !(window.innerWidth <= 600), + bottom: window.innerWidth <= 600, + title: "ویرایش فروش خارج از استان", + content: ( + + ), + }) + ); + }; + + const handleDelete = () => { + closePopover(); + dispatch(slaughterDeleteOutOfProvinceSell(item?.key)).then((r) => { + if (r.payload.error) { + openNotif({ + vertical: "top", + horizontal: "center", + msg: r.payload.data.result, + severity: "error", + }); + } else { + updateTable(); + dispatch(fetchSlaughterBroadcastAndProducts()); + openNotif({ + vertical: "top", + horizontal: "center", + msg: r.payload.data.result, + severity: "success", + }); + } + }); + }; + + const handleResend = () => { + closePopover(); + dispatch( + slaughterResendOutProvinceRegistrationCodeService({ + key: item?.key, + }) + ).then((r) => { + if (r.payload.error) { + openNotif({ + vertical: "top", + horizontal: "center", + msg: r.payload.error, + severity: "error", + }); + } else { + openNotif({ + vertical: "top", + horizontal: "center", + msg: "کد با موفقیت ارسال شد.", + severity: "success", + }); + fetchApiData(page); + } + }); + }; + + const open = Boolean(anchorEl); + const id = open ? "popover" : undefined; + + return ( +
    + + + + + + + + + + + + + ویرایش + + } + /> + + + + + + + + + + + + حذف + + } + /> + + + + + {item?.systemRegistrationCode && + item?.registrationCode && + !item?.loggedRegistrationCode && ( + + + + + + + + ارسال مجدد کد + + } + /> + + + + )} + + +
    + ); +}; diff --git a/src/features/slaughter-house/components/slaughter-paid-fees/SlaughterPaidFees.js b/src/features/slaughter-house/components/slaughter-paid-fees/SlaughterPaidFees.js new file mode 100644 index 0000000..32108d5 --- /dev/null +++ b/src/features/slaughter-house/components/slaughter-paid-fees/SlaughterPaidFees.js @@ -0,0 +1,463 @@ +import { + Button, + Checkbox, + FormControlLabel, + Pagination, + TextField, + Tooltip, + Typography, +} from "@mui/material"; +import axios from "axios"; +import { useContext, useEffect, useState } from "react"; +import { useDispatch, useSelector } from "react-redux"; +import { Grid } from "../../../../components/grid/Grid"; +import { PageTable } from "../../../../components/page-table/PageTable"; +import { SPACING } from "../../../../data/spacing"; +import { + DRAWER, + LOADING_END, + LOADING_START, + OPEN_MODAL, +} from "../../../../lib/redux/slices/appSlice"; +import { formatJustDate } from "../../../../utils/formatTime"; +import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl"; +import { SlaughterPaymentDetails } from "../slaughter-payment-details/SlaughterPaymentDetails"; +import { SlaughterUnpaidFeesDetails } from "../slaughter-unpaid-fees-details/SlaughterUnpaidFeesDetails"; +import { RiFileExcel2Fill, RiSearchLine } from "react-icons/ri"; +import BoxList from "../../../../components/box-list/BoxList"; +import { AppContext } from "../../../../contexts/AppContext"; +import moment from "moment"; +import { DatePicker } from "@mui/x-date-pickers"; + +export const SlaughterPaidFees = () => { + const [, , selectedDate1, setSelectedDate1, selectedDate2, setSelectedDate2] = + useContext(AppContext); + const [withDate, setWithDate] = useState(false); + + useEffect(() => { + const currentDate = moment(new Date()).format("YYYY-MM-DD"); + setSelectedDate1(currentDate); + setSelectedDate2(currentDate); + }, []); + + const dispatch = useDispatch(); + const userInfo = useSelector((state) => state.userSlice); + const [dataTableM, setDataTableM] = useState([]); + const [data, setData] = useState([]); + const [loading, setLoading] = useState(false); + const [totalRows, setTotalRows] = useState(0); + const [perPage, setPerPage] = useState(10); + + const [textValue, setTextValue] = useState(""); + + const handleTextChange = (event) => { + setTextValue(event.target.value); + }; + + const fetchApiData = async (page, textValue) => { + setLoading(true); + const response = await axios.get( + `province_wage/?type=paid&search=filter&value=${textValue}&role=${getRoleFromUrl()}&page=${page}&page_size=${perPage}${ + withDate ? `&date1=${selectedDate1}&date2=${selectedDate2}` : `` + }` + ); + setData(response.data.results); + setTotalRows(response.data.count); + setLoading(false); + dispatch(LOADING_END()); + }; + + const [page, setPage] = useState(0); + const handleChangePageM = (event, newPage) => { + dispatch(LOADING_START()); + setPage(newPage); + fetchApiData(newPage + 1, textValue); + }; + + const handlePageChange = (page) => { + fetchApiData(page, textValue); + }; + + const handlePerRowsChange = async (newPerPage, page) => { + setLoading(true); + const response = await axios.get( + `province_wage/?type=paid&search=filter&value=${textValue}&page=${page}&page_size=${newPerPage}&search=filter&value=${textValue}${ + withDate ? `&date1=${selectedDate1}&date2=${selectedDate2}` : `` + }` + ); + + setData(response.data.results); + setTotalRows(response.data.count); + setPerPage(newPerPage); + + setLoading(false); + }; + + useEffect(() => { + fetchApiData(1); + }, []); + + useEffect(() => { + fetchApiData(1); + }, [selectedDate1, selectedDate2, withDate]); + + const handleSubmit = async (event) => { + event.preventDefault(); + setLoading(true); + + try { + const response = await axios.get( + `province_wage/?type=paid&role=${getRoleFromUrl()}&search=filter&value=${textValue}${ + withDate ? `&date1=${selectedDate1}&date2=${selectedDate2}` : `` + }` + ); + setData(response.data.results); + setTotalRows(response.data.count); + } catch (error) { + console.error("Error fetching data:", error); + } finally { + setLoading(false); + } + }; + + const columns = [ + { + name: "کدسفارش", + selector: (item) => item?.provinceRequest?.orderCode, + sortable: false, + wrap: true, + allowOverflow: true, + center: true, + // width: "90px", + }, + { + name: "مرغدار (تلفن)", + selector: (item) => + `${item?.provinceRequest?.poultryFullname} (${item?.provinceRequest?.poultryMobile})`, + sortable: false, + wrap: true, + allowOverflow: true, + center: true, + // width: "90px", + }, + { + name: "شهر", + selector: (item) => `${item?.provinceRequest?.poultryCity}`, + sortable: false, + wrap: true, + allowOverflow: true, + center: true, + // width: "80px", + }, + { + name: "تاریخ کشتار", + selector: (item) => formatJustDate(item?.provinceRequest?.sendDate), + sortable: false, + wrap: true, + allowOverflow: true, + center: true, + // width: "80px", + }, + { + name: "محل کشتار", + selector: (item) => item?.provinceRequest?.killPlace, + sortable: false, + wrap: true, + allowOverflow: true, + center: true, + }, + { + name: "نژاد", + selector: (item) => item?.provinceRequest?.breed, + sortable: false, + wrap: true, + allowOverflow: true, + center: true, + // width: "80px", + }, + { + name: "تعداد (قطعه)", + selector: (item) => + item?.provinceRequest?.provinceKillRequestQuantity?.toLocaleString(), + sortable: false, + wrap: true, + allowOverflow: true, + center: true, + // width: "80px", + }, + { + name: "وزن (کیلوگرم)", + selector: (item) => + item?.provinceRequest?.provinceKillRequestTotalWeight?.toLocaleString(), + sortable: false, + wrap: true, + allowOverflow: true, + center: true, + // width: "90px", + }, + { + name: "میانگین وزنی (کیلوگرم)", + selector: (item) => item?.provinceRequest?.indexWeight, + sortable: false, + wrap: true, + allowOverflow: true, + center: true, + // width: "90px", + }, + { + name: "تعرفه اتحادیه (ریال)", + selector: (item) => item?.provinceRequest?.wage?.toLocaleString(), + sortable: false, + wrap: true, + allowOverflow: true, + center: true, + // width: "90px", + }, + { + name: "مبلغ کل تعرفه (ریال)", + selector: (item) => item?.provinceRequest?.totalAmount?.toLocaleString(), + sortable: false, + wrap: true, + allowOverflow: true, + center: true, + // width: "90px", + }, + { + name: "اطلاعات پرداخت", + selector: (item) => { + return ( + + ); + }, + sortable: false, + wrap: true, + allowOverflow: true, + center: true, + // width: "90px", + }, + { + name: "جزییات سفارش", + selector: (item) => ( + + ), + sortable: false, + wrap: true, + allowOverflow: true, + center: true, + // width: "90px", + }, + ]; + + const tableTitle = ( + + + تعرفه های پرداخت شده + + + setWithDate(!withDate)} + color="primary" // Change the color to your preference + /> + } + /> + + + ( + + )} + value={selectedDate1} + onChange={(e) => { + setSelectedDate1(moment(e).format("YYYY-MM-DD")); + }} + /> + + + ( + + )} + value={selectedDate2} + onChange={(e) => { + setSelectedDate2(moment(e).format("YYYY-MM-DD")); + }} + /> + + +
    + + + + + + + + +
    +
    + ); + + const isMobile = window.innerWidth <= 600; + + useEffect(() => { + const d = data?.map((item, i) => { + return [ + item?.provinceRequest?.orderCode, + `${item?.provinceRequest?.poultryFullname} (${item?.provinceRequest?.poultryMobile})`, + `${item?.provinceRequest?.poultryCity}`, + item?.provinceRequest?.totalAmount?.toLocaleString(), + , + , + ]; + }); + + setDataTableM(d); + }, [data]); + + return ( + + {isMobile ? ( + + {tableTitle} + + { + handleChangePageM(event, newPage - 1); + }} + /> + + ) : ( + + )} + + ); +}; diff --git a/src/features/slaughter-house/components/slaughter-pay-factor-requests/SlaughterPayFactorRequests.js b/src/features/slaughter-house/components/slaughter-pay-factor-requests/SlaughterPayFactorRequests.js new file mode 100644 index 0000000..301cf40 --- /dev/null +++ b/src/features/slaughter-house/components/slaughter-pay-factor-requests/SlaughterPayFactorRequests.js @@ -0,0 +1,537 @@ +import { + Box, + Card, + Grid, + IconButton, + Tab, + Tabs, + TextField, + Tooltip, + Typography, +} from "@mui/material"; +import { + ROUTE_PROVINCE_FINANCIAL_FILE, + ROUTE_SLAUGHTER_FILE, +} from "../../../../routes/routes"; +import { AdvancedTable } from "../../../../components/advanced-table/AdvancedTable"; +import { SPACING } from "../../../../data/spacing"; +import { useFormik } from "formik"; +import moment from "moment"; +import { Yup } from "../../../../lib/yup/yup"; +import { useDispatch, useSelector } from "react-redux"; +import { useContext, useEffect, useRef, useState } from "react"; +import { useNavigate } from "react-router-dom"; +import PlagiarismIcon from "@mui/icons-material/Plagiarism"; +import { slaughterGetPayFactorRequestsService } from "../../services/slaughter-get-pay-factor-requests"; +import { DRAWER } from "../../../../lib/redux/slices/appSlice"; +import EditIcon from "@mui/icons-material/Edit"; +import { SlaughterPayProvinceFactorForm } from "../../../file/components/slaughter-pay-province-factor-form/SlaughterPayProvinceFactorForm"; +import { SimpleTable } from "../../../../components/simple-table/SimpleTable"; +import { slaughterGetPaiedFactorsService } from "../../services/slaughter-get-paied-factors"; +import { format } from "date-fns-jalali"; +import { formatJustDate } from "../../../../utils/formatTime"; +import { DatePicker } from "@mui/x-date-pickers"; +import { AppContext } from "../../../../contexts/AppContext"; +import { useReactToPrint } from "react-to-print"; +import SlaughterNewFactorFile from "../slaughter-new-factor-file/SlaughterNewFactorFile"; +import PictureAsPdfIcon from "@mui/icons-material/PictureAsPdf"; + +export const SlaughterPayFactorRequests = () => { + const navigate = useNavigate(); + const [dataTable, setDataTable] = useState([]); + const [paidDataTable, setPaidDataTable] = useState([]); + const { slaughterGetPayFactorRequests, slaughterGetPaiedFactors } = + useSelector((state) => state.slaughterSlice); + const dispatch = useDispatch(); + + const [, , selectedDate1, setSelectedDate1, selectedDate2, setSelectedDate2] = + useContext(AppContext); + + useEffect(() => { + const currentDate = moment(new Date()).format("YYYY-MM-DD"); + setSelectedDate1(currentDate); + setSelectedDate2(currentDate); + }, []); + + useEffect(() => { + dispatch( + slaughterGetPayFactorRequestsService({ selectedDate1, selectedDate2 }) + ); + dispatch(slaughterGetPaiedFactorsService({ selectedDate1, selectedDate2 })); + }, [selectedDate1, selectedDate2]); + + useEffect(() => { + const d = slaughterGetPaiedFactors?.map((item, i) => { + let state = ""; + if (item.state === "accepted") { + state = "تایید شده"; + } else if (item.state === "rejected") { + state = "رد شده"; + } else if (item.state === "pending") { + state = "در انتظار تایید"; + } + return [ + i + 1, + item?.provinceFactor?.factorBarCode, + item?.provinceFactor?.provinceCheckInfo?.killHouseAssignment + ?.killHouseRequest?.killRequest?.killHouse?.name, + item?.provinceFactor?.provinceCheckInfo?.killHouseAssignment + ?.killHouseRequest?.killRequest?.killHouse?.killHouseOperator?.user + ?.mobile, + formatJustDate(item?.provinceFactor?.createDate), + formatJustDate(item?.createDate), + item?.provinceFactor?.totalPrice?.toLocaleString() + " ﷼", + Number(item?.paymentCode), + state, + + بدون بار + , + { + dispatch( + DRAWER({ + title: "انجام عملیات تایید / رد درخواست", + // right: !(window.innerWidth <= 600), + top: !(window.innerWidth <= 600), + bottom: window.innerWidth <= 600, + content: ( + + ), + }) + ); + }} + > + + , + { + navigate( + ROUTE_PROVINCE_FINANCIAL_FILE + + item?.provinceFactor?.poultryRequest?.poultryRequestId + ); + }} + > + + , + ]; + }); + setPaidDataTable(d); + }, [slaughterGetPaiedFactors]); + + useEffect(() => { + const d = slaughterGetPayFactorRequests + ?.filter((item) => item.paidState !== "paid") + .map((item, i) => { + const pricePlusDec = `${ + item.provinceInputAmount + ? item.provinceInputAmount?.toLocaleString() + : "نامشخص" + } ﷼ (شرح: ${item?.reason ? item?.reason : "نامشخص"})`; + + let typeOfChangePrice = item.provinceInputAmountType; + if (typeOfChangePrice === "plus") { + typeOfChangePrice = ( + اضافه شد: {pricePlusDec} + ); + } else { + typeOfChangePrice = ( + کسر شد: {pricePlusDec} + ); + } + + const firstPayed = ( + + کسر شد: {item.killHouseFactorPaymentRemain?.toLocaleString() + " ﷼"} + + ); + + // const totalAmount = + // item.provinceCheckInfo.killHouseAssignment.netWeight * + // (item.factorFee + item.provinceWage); + return [ + i + 1, + item.provinceCheckInfo?.killHouseAssignment?.killHouseRequest + ?.barCode, + format(new Date(item?.poultryRequest?.sendDate), "yyyy/MM/dd"), + `${item.poultryRequest.poultryName} (${item.poultryRequest.poultryUserMobile})`, + item.provinceFactorToKillHouse.killPlace, + item.provinceFactorToKillHouse.realQuantity?.toLocaleString(), + item.provinceFactorToKillHouse.netWeight?.toLocaleString(), + format(new Date(item?.factorDate), "yyyy/MM/dd"), + item.provinceFactorToKillHouse.totalFactorAmount?.toLocaleString() + + " ﷼", + + { + setPdfOptions(item); + }} + size={"large"} + aria-label="delete" + color="success" + > + + + , + { + dispatch( + DRAWER({ + title: "انجام عملیات پرداخت فاکتور", + // right: !(window.innerWidth <= 600), + top: !(window.innerWidth <= 600), + bottom: window.innerWidth <= 600, + content: ( + + + + vvv + , + + vvv + , + ], + ]} + /> + + + + + ), + }) + ); + }} + > + + , + navigate(ROUTE_SLAUGHTER_FILE + item.poultryReqId)} + > + + , + ]; + }); + + setDataTable(d); + }, [slaughterGetPayFactorRequests]); + + const [tableDataCol] = useState([ + "ردیف", + "کد بار", + "تاریخ کشتار", + "مرغدار", + "محل کشتار", + "تعداد واقعی", + "وزن خالص (کیلوگرم)", + "تاریخ صدور فاکتور", + "مبلغ نهایی فاکتور", + "دانلود فاکتور", + "عملیات", + "مشاهده", + ]); + + const formik = useFormik({ + initialValues: { + capacity: "", + recieveTime: "", + recieveDate: moment(Date()).format("YYYY-MM-DD hh:mm:ss"), + }, + validationSchema: Yup.object({ + capacity: Yup.number() + .required("این فیلد اجباری است!") + .typeError("لطفا عدد وارد کنید!"), + recieveTime: Yup.string() + .required("این فیلد اجباری است!") + .typeError("لطفا وزن را وارد کنید!"), + }), + }); + + useEffect(() => { + formik.validateForm(); + }, []); + + const [value, setValue] = useState(0); + + const handleChange = (event, newValue) => { + setValue(newValue); + }; + + const [data, setData] = useState(); + const componentRef = useRef(); + const printPDF = useReactToPrint({ + content: () => componentRef.current, + documentTitle: "فاکتور پرداخت", + onAfterPrint: () => { + setData(null); + }, + }); + + const setPdfOptions = (item) => { + setData(item); + }; + + useEffect(() => { + if (data) { + printPDF(); + } + }, [data, printPDF]); + + return ( + +
    + +
    + + + + + + + + + + + {value === 0 && ( + + + فاکتورهای در انتظار پرداخت + + + ( + + )} + value={selectedDate1} + onChange={(e) => { + setSelectedDate1(moment(e).format("YYYY-MM-DD")); + }} + /> + + + ( + + )} + value={selectedDate2} + onChange={(e) => { + setSelectedDate2(moment(e).format("YYYY-MM-DD")); + }} + /> + +
    + } + columns={tableDataCol} + data={dataTable} + /> + )} + + {value === 1 && ( + + + فاکتورهای پرداخت شده + + + ( + + )} + value={selectedDate1} + onChange={(e) => { + setSelectedDate1(moment(e).format("YYYY-MM-DD")); + }} + /> + + + ( + + )} + value={selectedDate2} + onChange={(e) => { + setSelectedDate2(moment(e).format("YYYY-MM-DD")); + }} + /> + + + } + columns={[ + "ردیف", + "شناسه فاکتور", + "کشتارگاه", + "تلفن کشتارگاه", + "تاریخ صدور فاکتور", + "تاریخ پرداخت فاکتور", + "مبلغ فاکتور نهایی", + "شناسه پرداخت", + "وضعیت", + "سند پرداختی", + "ویرایش سند پرداخت", + "مشاهده", + ]} + data={paidDataTable} + /> + )} + + + ); +}; diff --git a/src/features/slaughter-house/components/slaughter-pay-factor/SlaughterPayFactor.js b/src/features/slaughter-house/components/slaughter-pay-factor/SlaughterPayFactor.js new file mode 100644 index 0000000..fe7c562 --- /dev/null +++ b/src/features/slaughter-house/components/slaughter-pay-factor/SlaughterPayFactor.js @@ -0,0 +1,134 @@ +import React, { useContext, useEffect } from "react"; +import { useFormik } from "formik"; +import * as yup from "yup"; +import { Button, TextField } from "@mui/material"; +import { ImageUpload } from "../../../../components/image-upload/ImageUpload"; +import { fixBase64 } from "../../../../utils/toBase64"; +import { useDispatch } from "react-redux"; +import { slaughterPayFactorService } from "../../services/slaughter-pay-factor"; +import { AppContext } from "../../../../contexts/AppContext"; +import { DRAWER } from "../../../../lib/redux/slices/appSlice"; +import { NumberInput } from "../../../../components/number-format-custom/NumberFormatCustom"; +import { Grid } from "../../../../components/grid/Grid"; +import { SPACING } from "../../../../data/spacing"; +import { slaughterPayProvinceFactor } from "../../../file/services/slaughterPayProvinceFactor"; +import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl"; +import { slaughterFinalFactorsService } from "../../services/slaughter-final-factors"; +import { slaughterFactorsService } from "../../services/slaughter-factors"; + +const validationSchema = yup.object({ + paymentCode: yup.string().required("This field is required"), +}); + +export const SlaughterPayFactor = ({ factorKey, isFinalFactor }) => { + const [image, setImage] = React.useState(); + const [images, setImages] = React.useState([]); + const dispatch = useDispatch(); + const [openNotif] = useContext(AppContext); + const [, , selectedDate1, , selectedDate2] = useContext(AppContext); + + const formik = useFormik({ + initialValues: { + paymentCode: "", + doc: "", + amount: "", + }, + validationSchema, + onSubmit: (values) => { + if (!isFinalFactor) { + dispatch( + slaughterPayFactorService({ + factor_key: factorKey, + image: values.doc, + payment_code: values.paymentCode, + amount: values.amount, + }) + ).then((r) => { + dispatch(DRAWER({ right: false, bottom: false, content: null })); + openNotif({ + vertical: "top", + horizontal: "center", + msg: "عملیات با موفقیت انجام شد.", + severity: "success", + }); + }); + } else { + dispatch( + slaughterPayProvinceFactor({ + key: factorKey, + factor_image: values.doc, + payment_code: values.paymentCode, + role: getRoleFromUrl(), + }) + ).then((r) => { + dispatch(slaughterFactorsService({ selectedDate1, selectedDate2 })); + dispatch(slaughterFinalFactorsService()); + dispatch(DRAWER({ right: false, bottom: false, content: null })); + openNotif({ + vertical: "top", + horizontal: "center", + msg: "عملیات با موفقیت انجام شد.", + severity: "success", + }); + }); + } + }, + }); + + const factorPaymentHandler = (imageList, addUpdateIndex) => { + if (imageList[0]) { + setImage(fixBase64(imageList[0]?.data_url)); + } + setImages(imageList); + }; + + useEffect(() => { + formik.setFieldValue("doc", image); + }, [image]); + + return ( +
    +
    + + {!isFinalFactor && ( + + )} + + + + + +
    + ); +}; diff --git a/src/features/slaughter-house/components/slaughter-pay-fees-gateway/SlaughterPayFeesGateway.js b/src/features/slaughter-house/components/slaughter-pay-fees-gateway/SlaughterPayFeesGateway.js new file mode 100644 index 0000000..72d6b52 --- /dev/null +++ b/src/features/slaughter-house/components/slaughter-pay-fees-gateway/SlaughterPayFeesGateway.js @@ -0,0 +1,107 @@ +import { LinearProgress, Typography } from "@mui/material"; +import { useEffect, useRef, useState } from "react"; +import { useDispatch } from "react-redux"; +import { Grid } from "../../../../components/grid/Grid"; +import { SPACING } from "../../../../data/spacing"; +import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl"; +import { slaughterPaymentRefIdService } from "../../services/salughter-payment-refid"; +import { + provincePaymentRefIdService, + provincePaymentRefIdWagesService, +} from "../../../province/services/province-payment-refId"; + +export const SlaughterPayFeesGateway = ({ + amount, + user_key, + amountWithTax, + isZarinPal, + isPayment, + isPaymentData, + backend, +}) => { + const dispatch = useDispatch(); + const formRef = useRef(); + const [refId, setRefId] = useState(); + const [authority, setAuthority] = useState(); + + const handleSubmit = () => { + formRef.current.submit(); + }; + + useEffect(() => { + if (isZarinPal) { + dispatch( + provincePaymentRefIdService({ + role: getRoleFromUrl(), + total_amount: parseInt(amount), + }) + ).then((r) => { + // setAuthority(r.payload.data?.authority); + setAuthority(r.payload.data?.token); + }); + } else if (isPayment) { + dispatch( + provincePaymentRefIdWagesService({ data: isPaymentData, backend }) + ).then((r) => { + // setAuthority(r.payload.data?.authority); + setAuthority(r.payload.data?.token); + }); + } else { + dispatch( + slaughterPaymentRefIdService({ + role: getRoleFromUrl(), + kill_house_key: user_key, + payment_type: "auto", + amount: parseInt(amount), + amount_with_tax: parseInt(amountWithTax), + }) + ).then((r) => { + setRefId(r.payload.data.refId); + }); + } + }, []); + + useEffect(() => { + if (refId) { + handleSubmit(); + } + }, [refId]); + + useEffect(() => { + if (authority) { + // window.location.href = `https://www.zarinpal.com/pg/StartPay/${authority}`; + // window.location.href = `https://sep.shaparak.ir/OnlinePG/SendToken?token=${authority}`; + handleSubmit(); + } + }, [authority]); + + return ( + + + + در حال انتقال به درگاه پرداخت... + +
    + {/*
    + + +
    */} +
    + + + +
    +
    +
    + ); +}; diff --git a/src/features/slaughter-house/components/slaughter-pay-fees-manual/SlaughterPayFeesManual.js b/src/features/slaughter-house/components/slaughter-pay-fees-manual/SlaughterPayFeesManual.js new file mode 100644 index 0000000..8637b92 --- /dev/null +++ b/src/features/slaughter-house/components/slaughter-pay-fees-manual/SlaughterPayFeesManual.js @@ -0,0 +1,56 @@ +import { Button, Grid, TextField } from "@mui/material"; +import { useContext, useState } from "react"; +import { useDispatch } from "react-redux"; +import { AppContext } from "../../../../contexts/AppContext"; +import { SPACING } from "../../../../data/spacing"; +import { CLOSE_MODAL } from "../../../../lib/redux/slices/appSlice"; +import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl"; +import { slaughterPayingFeesManual } from "../../services/salughter-paying-fees-manual"; + +export const SlaughterPayFeesManual = ({ selectedItems, updateTable }) => { + const dispatch = useDispatch(); + const [openNotif] = useContext(AppContext); + const [inputValue, setInputValue] = useState(""); + + // Function to handle text field changes + const handleInputChange = (event) => { + setInputValue(event.target.value); + }; + + return ( + + + + + ); +}; diff --git a/src/features/slaughter-house/components/slaughter-paying-fees-overview/SlaughterPayingFeesOverview.js b/src/features/slaughter-house/components/slaughter-paying-fees-overview/SlaughterPayingFeesOverview.js new file mode 100644 index 0000000..bac1b3a --- /dev/null +++ b/src/features/slaughter-house/components/slaughter-paying-fees-overview/SlaughterPayingFeesOverview.js @@ -0,0 +1,84 @@ +import { Button, Typography } from "@mui/material"; +import { useDispatch } from "react-redux"; +import { Grid } from "../../../../components/grid/Grid"; +import { SPACING } from "../../../../data/spacing"; +import { OPEN_MODAL } from "../../../../lib/redux/slices/appSlice"; +import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl"; +import { SlaughterPayFeesGateway } from "../slaughter-pay-fees-gateway/SlaughterPayFeesGateway"; +import { SlaughterPayFeesManual } from "../slaughter-pay-fees-manual/SlaughterPayFeesManual"; + +export const SlaughterPayingFeesOverview = ({ + selectedItems, + totalSelectedFees, + totalSelectedWeight, + updateTable, +}) => { + const dispatch = useDispatch(); + + return ( + + تعداد سفارشات انتخاب شده: {selectedItems?.length} + + وزن بارهای انتخاب شده: {totalSelectedWeight?.toLocaleString()} کیلوگرم + + + مبلغ کل تعرفه سفارشات: {totalSelectedFees?.toLocaleString()} ﷼ + + + مبلغ مالیات بر ارزش افزوده{" "} + {Number(totalSelectedFees / 10)?.toLocaleString()} ﷼ + + + مبلغ کل تعرفه + مالیات بر ارزش افزوده:{" "} + {( + Number(totalSelectedFees) + Number(totalSelectedFees / 10) + )?.toLocaleString()}{" "} + ﷼ + + + {Boolean(selectedItems.length) && ( + + {(getRoleFromUrl() === "ProvinceOperator" || + getRoleFromUrl() === "SuperAdmin") && ( + + )} + + + )} + + ); +}; diff --git a/src/features/slaughter-house/components/slaughter-paying-fees/SlaughterPayingFees.js b/src/features/slaughter-house/components/slaughter-paying-fees/SlaughterPayingFees.js new file mode 100644 index 0000000..3f8abbd --- /dev/null +++ b/src/features/slaughter-house/components/slaughter-paying-fees/SlaughterPayingFees.js @@ -0,0 +1,44 @@ +import { TabContext, TabPanel } from "@mui/lab"; +import { Tab, Tabs } from "@mui/material"; +import { useState } from "react"; +import { Grid } from "../../../../components/grid/Grid"; +import { SlaughterArchivedFees } from "../slaughter-archived-fees/SlaughterArchivedFees"; +import { SlaughterPaidFees } from "../slaughter-paid-fees/SlaughterPaidFees"; +import { SlaughterUnpaidFees } from "../slaughter-unpaid-fees/SlaughterUnpaidFees"; + +export const SlaughterPayingFees = () => { + const [tabValue, setTabValue] = useState("1"); + + const handleTabChange = (event, newValue) => { + setTabValue(newValue); + }; + + return ( + + + + + + + + + + + + + + + + + + + + + ); +}; diff --git a/src/features/slaughter-house/components/slaughter-payment-by-weight/SlaughterPaymentByWeight.js b/src/features/slaughter-house/components/slaughter-payment-by-weight/SlaughterPaymentByWeight.js new file mode 100644 index 0000000..ee8b8dd --- /dev/null +++ b/src/features/slaughter-house/components/slaughter-payment-by-weight/SlaughterPaymentByWeight.js @@ -0,0 +1,59 @@ +import React, { useEffect, useState } from "react"; +import { Grid } from "../../../../components/grid/Grid"; +import { SimpleTable } from "../../../../components/simple-table/SimpleTable"; +import { useDispatch, useSelector } from "react-redux"; +import { slaughterGetPaymentByWeightOverview } from "../../services/slaughter-get-payment-by-weight-overview"; +import { SPACING } from "../../../../data/spacing"; +import { Typography } from "@mui/material"; + +export const SlaughterPaymentByWeight = () => { + const dispatch = useDispatch(); + const [tableData, setTableData] = useState(); + + const { slaughterPaymentByWeightOverview } = useSelector( + (item) => item.slaughterSlice + ); + + useEffect(() => { + dispatch(slaughterGetPaymentByWeightOverview()); + }, []); + + useEffect(() => { + const d = slaughterPaymentByWeightOverview?.map((item, i) => { + return [ + i + 1, + item?.name, + item?.wageInfo?.totalPaidWage?.toLocaleString(), + item?.wageInfo?.totalUnpaidWage?.toLocaleString(), + item?.wageInfo?.totalWeight?.toLocaleString(), + item?.wageInfo?.totalWage?.toLocaleString(), + ]; + }); + setTableData(d); + }, [slaughterPaymentByWeightOverview]); + + return ( + + + + + اطلاعات کلی + + {" "} + + } + columns={[ + "ردیف", + "نام کشتارگاه", + "کارمزدهای پرداخت شده (ریال)", + "کارمزدهای پرداخت نشده (ریال)", + "مجموع وزنی", + "مجموع کارمزدها (ریال)", + ]} + data={tableData} + /> + + ); +}; diff --git a/src/features/slaughter-house/components/slaughter-payment-details/SlaughterPaymentDetails.js b/src/features/slaughter-house/components/slaughter-payment-details/SlaughterPaymentDetails.js new file mode 100644 index 0000000..45d7e53 --- /dev/null +++ b/src/features/slaughter-house/components/slaughter-payment-details/SlaughterPaymentDetails.js @@ -0,0 +1,48 @@ +import { Typography } from "@mui/material"; +import { Grid } from "../../../../components/grid/Grid"; +import { getFaUserRole } from "../../../../utils/getFaUserRole"; +import { formatTime } from "../../../../utils/formatTime"; + +export const SlaughterPaymentDetails = ({ item }) => { + return ( + + {item?.cardHolderPan ? ( + <> + + نوع پرداخت: + درگاه پرداخت + + + + شماره کارت: + {item?.cardHolderPan} + + + ) : ( + + نوع پرداخت: + دستی + + )} + + تاریخ پرداخت: + {formatTime(item.date)} + + + + پرداخت کننده: + {item.payer} + + + + نقش: + {getFaUserRole(item.role)} + + + + مبلغ پرداختی: + {item?.totalAmount?.toLocaleString()} ﷼ + + + ); +}; diff --git a/src/features/slaughter-house/components/slaughter-payment-overview/SLaughterPaymentOverview.js b/src/features/slaughter-house/components/slaughter-payment-overview/SLaughterPaymentOverview.js new file mode 100644 index 0000000..3d903f1 --- /dev/null +++ b/src/features/slaughter-house/components/slaughter-payment-overview/SLaughterPaymentOverview.js @@ -0,0 +1,92 @@ +import React, { useEffect, useState } from "react"; +import { SimpleTable } from "../../../../components/simple-table/SimpleTable"; +import { Grid } from "../../../../components/grid/Grid"; +import { SPACING } from "../../../../data/spacing"; +import { useDispatch, useSelector } from "react-redux"; +import { slaughterGetPaymentOverviewInfo } from "../../services/slaughter-get-payment-overview-info"; +import { slaughterGetWalletBalance } from "../../services/get-wallet-balance"; +import { Button, Typography } from "@mui/material"; +import { useNavigate } from "react-router-dom"; +import { ROUTE_SLAUGHTER_WALLET } from "../../../../routes/routes"; + +export const SLaughterPaymentOverview = () => { + const { slaughterPaymentOverview } = useSelector( + (item) => item.slaughterSlice + ); + const dispatch = useDispatch(); + + const [balance, setBalance] = useState(0); + useEffect(() => { + dispatch(slaughterGetWalletBalance()).then((r) => { + setBalance(r.payload.data?.balance); + }); + }, []); + + useEffect(() => { + dispatch(slaughterGetPaymentOverviewInfo()); + }, []); + + const navigate = useNavigate(); + + return ( + + + + + اطلاعات کلی + + + + + موجودی کیف پول: {balance?.toLocaleString()} ﷼ + + + + + } + columns={[ + "تعداد کل سفارشات", + "حجم کل سفارشات (قطعه)", + "وزن کل سفارشات (کیلوگرم)", + "مبلغ کل تعرفه", + "سفارشات پرداخت شده", + "وزن کل پرداخت شده (کیلوگرم)", + "مبلغ کل پرداخت شده (ريال)", + "سفارشات پرداخت نشده", + "وزن کل پرداخت نشده (کیلوگرم)", + "مبلغ کل پرداخت نشده (ريال)", + "سفارشات بایگانی شده", + "وزن کل بایگانی شده", + "مبلغ کل بایگانی شده (ريال)", + ]} + data={[ + [ + slaughterPaymentOverview?.wageInfo?.totalCount.toLocaleString(), + slaughterPaymentOverview?.wageInfo.totalQuantity.toLocaleString(), + slaughterPaymentOverview?.wageInfo.totalWeight.toLocaleString(), + slaughterPaymentOverview?.wageInfo.totalWage?.toLocaleString(), + slaughterPaymentOverview?.wageInfo.paidCount.toLocaleString(), + slaughterPaymentOverview?.wageInfo.totalWeightPaid.toLocaleString(), + slaughterPaymentOverview?.wageInfo.totalPaidWage.toLocaleString(), + slaughterPaymentOverview?.wageInfo.unpaidCount.toLocaleString(), + slaughterPaymentOverview?.wageInfo.totalWeightUnpaid.toLocaleString(), + slaughterPaymentOverview?.wageInfo.totalUnpaidWage.toLocaleString(), + slaughterPaymentOverview?.wageInfo.archiveCount.toLocaleString(), + slaughterPaymentOverview?.wageInfo.totalWeightArchive.toLocaleString(), + slaughterPaymentOverview?.wageInfo.totalArchiveWage.toLocaleString(), + ], + ]} + /> + + ); +}; diff --git a/src/features/slaughter-house/components/slaughter-profile/SlaughterProfile.js b/src/features/slaughter-house/components/slaughter-profile/SlaughterProfile.js new file mode 100644 index 0000000..602df4a --- /dev/null +++ b/src/features/slaughter-house/components/slaughter-profile/SlaughterProfile.js @@ -0,0 +1,71 @@ +import { Box } from "@mui/system"; +import { useEffect } from "react"; +import { useDispatch, useSelector } from "react-redux"; +import { Grid } from "../../../../components/grid/Grid"; +import { SimpleTable } from "../../../../components/simple-table/SimpleTable"; +import { SPACING } from "../../../../data/spacing"; +import { + LOADING_END, + LOADING_START, +} from "../../../../lib/redux/slices/appSlice"; +import { ChangeCardInfo } from "../../../authentication/components/change-card-info/ChangeCardInfo"; +import { slaughterGetProfile } from "../../services/slaughter-get-profile"; + +export const SlaughterProfile = () => { + const { profile } = useSelector((state) => state.slaughterSlice); + const dispatch = useDispatch(); + + useEffect(() => { + dispatch(LOADING_START()); + dispatch(slaughterGetProfile()).then((r) => { + dispatch(LOADING_END()); + }); + }, []); + + return ( + + + + + <> + {profile?.killHouse?.map((killHouse) => { + return ( + + + + ); + })} + + + + + + + + + + ); +}; diff --git a/src/features/slaughter-house/components/slaughter-psp-devices/SlaughterPspDevices.js b/src/features/slaughter-house/components/slaughter-psp-devices/SlaughterPspDevices.js new file mode 100644 index 0000000..3907673 --- /dev/null +++ b/src/features/slaughter-house/components/slaughter-psp-devices/SlaughterPspDevices.js @@ -0,0 +1,5 @@ +const SlaughterPspDevices = () => { + return
    SlaughterPspDevices
    ; +}; + +export default SlaughterPspDevices; diff --git a/src/features/slaughter-house/components/slaughter-rejected-requests/SlaughterRejectedRequests.js b/src/features/slaughter-house/components/slaughter-rejected-requests/SlaughterRejectedRequests.js new file mode 100644 index 0000000..0038838 --- /dev/null +++ b/src/features/slaughter-house/components/slaughter-rejected-requests/SlaughterRejectedRequests.js @@ -0,0 +1,149 @@ +import { Card, Grid, IconButton, TextField, Typography } from "@mui/material"; +import { ROUTE_SLAUGHTER_FILE } from "../../../../routes/routes"; +import { AdvancedTable } from "../../../../components/advanced-table/AdvancedTable"; +import { SPACING } from "../../../../data/spacing"; +import { useFormik } from "formik"; +import moment from "moment"; +import { Yup } from "../../../../lib/yup/yup"; +import { useDispatch, useSelector } from "react-redux"; +import { slaughterGetActiveRequests } from "../../services/slaughter-get-active-requests"; +import { useContext, useEffect, useState } from "react"; +import { useNavigate } from "react-router-dom"; +import PlagiarismIcon from "@mui/icons-material/Plagiarism"; +import { format } from "date-fns-jalali"; +import { AppContext } from "../../../../contexts/AppContext"; +import { DatePicker } from "@mui/x-date-pickers"; + +export const SlaughterRejectedRequests = () => { + const navigate = useNavigate(); + const [, , selectedDate1, setSelectedDate1, selectedDate2, setSelectedDate2] = + useContext(AppContext); + + useEffect(() => { + const currentDate = moment(new Date()).format("YYYY-MM-DD"); + setSelectedDate1(currentDate); + setSelectedDate2(currentDate); + }, []); + + const [dataTable, setDataTable] = useState([]); + const { slaughterActiveRequests } = useSelector( + (state) => state.slaughterSlice + ); + const dispatch = useDispatch(); + + useEffect(() => { + dispatch(slaughterGetActiveRequests({ selectedDate1, selectedDate2 })); + }, [selectedDate1, selectedDate2]); + + useEffect(() => { + const filteredData = slaughterActiveRequests?.filter( + (item, i) => item.provinceKillState === "rejected" + ); + const d = filteredData?.map((item, i) => { + return [ + i + 1, + item.orderCode, + format(new Date(item?.sendDate), "yyyy/MM/dd"), + item.poultryName, + item.poultryMobile, + item.city, + item.province, + item.age, + item.quantity, + navigate(ROUTE_SLAUGHTER_FILE + item.poultryReqId)} + > + + , + ]; + }); + + setDataTable(d); + }, [slaughterActiveRequests]); + + const [tableDataCol] = useState([ + "ردیف", + "کد سفارش", + "تاریخ درخواست", + "مرغدار", + "تلفن مرغدار", + "شهر", + "استان", + "سن مرغ", + "تعداد", + "مشاهده", + ]); + + const formik = useFormik({ + initialValues: { + capacity: "", + recieveTime: "", + recieveDate: moment(Date()).format("YYYY-MM-DD hh:mm:ss"), + }, + validationSchema: Yup.object({ + capacity: Yup.number() + .required("این فیلد اجباری است!") + .typeError("لطفا عدد وارد کنید!"), + recieveTime: Yup.string() + .required("این فیلد اجباری است!") + .typeError("لطفا وزن را وارد کنید!"), + }), + }); + + useEffect(() => { + formik.validateForm(); + }, []); + + return ( + + + + + درخواست های رد شده + + + ( + + )} + value={selectedDate1} + onChange={(e) => { + setSelectedDate1(moment(e).format("YYYY-MM-DD")); + }} + /> + + + ( + + )} + value={selectedDate2} + onChange={(e) => { + setSelectedDate2(moment(e).format("YYYY-MM-DD")); + }} + /> + + + } + columns={tableDataCol} + data={dataTable} + /> + + + ); +}; diff --git a/src/features/slaughter-house/components/slaughter-requests-operations/SlaughterRequestsOperations.js b/src/features/slaughter-house/components/slaughter-requests-operations/SlaughterRequestsOperations.js new file mode 100644 index 0000000..09f5c1c --- /dev/null +++ b/src/features/slaughter-house/components/slaughter-requests-operations/SlaughterRequestsOperations.js @@ -0,0 +1,321 @@ +import { Grid } from "../../../../components/grid/Grid"; +import { SPACING } from "../../../../data/spacing"; +import { NavLink } from "../../../../components/nav-link/NavLink"; +import { useLocation } from "react-router-dom"; +import { + ROUTE_SLAUGHTER_ALLOCATE_CAR_REQUESTS, + ROUTE_SLAUGHTER_ALLOCATION_REQUESTS, + ROUTE_SLAUGHTER_ENTER_BAR_INFO, + // ROUTE_SLAUGHTER_FACTORS, + ROUTE_SLAUGHTER_FINANCIAL_TRANSACTIONS, + ROUTE_SLAUGHTER_INVENTORY, + ROUTE_SLAUGHTER_NEW_REQUESTS, + ROUTE_SLAUGHTER_PAYING_FEES_REQUESTS, + ROUTE_SLAUGHTER_PAY_FACTORS_REQUESTS, + ROUTE_SLAUGHTER_PENDING_REQUESTS, + ROUTE_SLAUGHTER_WALLET, + ROUTE_SLAUGHTERـEXPORT, + ROUTE_SLAUGHTERـFREE_BUY, +} from "../../../../routes/routes"; +import LinkItem from "../../../../components/link-item/LinkItem"; +import { + MdCreateNewFolder, + MdImportExport, + MdLocalShipping, + MdOutlinePendingActions, +} from "react-icons/md"; +import { FaExchangeAlt, FaSellcast, FaTruckLoading } from "react-icons/fa"; +import ErrorIcon from "@mui/icons-material/Error"; +import { MdOutlineWallet } from "react-icons/md"; +import { LineWithText } from "../../../../components/line-with-text/LineWithText"; +import { Typography } from "@mui/material"; +import { VscFolderActive } from "react-icons/vsc"; + +export const SlaughterRequestsOperations = ({ hasPermission }) => { + const { pathname } = useLocation(); + + return ( + + {hasPermission && ( + <> + + + + + + + } + title="ثبت درخواست" + description="مدیریت و ثبت درخواست های کشتار" + /> + + + } + title="خرید مستقیم" + /> + + + } + title="صادرات" + /> + + + } + title={ + + + سفارش های دریافت شده + + + (در انتظار تایید) + + + } + description="مشاهد درخواست های در انتظار تایید اتحادیه" + /> + + + } + title="تخصیصات" + description="مشاهده و تخصیص درخواست ها" + /> + + + + + + + + + + } + title="تخصیص خودرو" + description="اختصاص خودرو به درخواست" + /> + + + } + title="وارد کردن اطلاعات بار" + description="درخواست های در انتظار عملیات وارد کردن اطلاعات بارهای دریافتی" + /> + + + } + title="انبار و توزیع" + description="درخواست های در انتظار عملیات وارد کردن اطلاعات بارهای دریافتی" + /> + + + + + )} + + {!hasPermission && ( + + + + بدلیل عدم پرداخت تعرفه ، امکان استفاده از خدمات سامانه را ندارید! + + + )} + + + + + + + } + title="مدیریت تعرفه ها" + /> + + + } + title="کیف پول" + /> + + {/* + + } + title="فاکتور های اولیه" + description=" مدیریت مشاهده فاکتور اولیه" + /> + */} + + + } + title="مدیریت تراکنش ها" + /> + + + } + title="مدیریت فاکتورها" + description="درخواست های در پرداخت" + /> + + + {/* + } + title="درخواست های فعال" + description="مشاهده درخواست های در جریان" + /> + + + + } + title="درخواست های رد شده" + description="مشاهده درخواست هایی که به دلایل مختلف توسط اتحادیه رد شده است" + /> + + + + } + title="بایگانی" + description="درخواست های پایان یافته" + /> + + + + } + title="فاکتور های نهایی" + description=" مدیریت مشاهده فاکتور نهایی" + /> + */} + + + + ); +}; diff --git a/src/features/slaughter-house/components/slaughter-requests/SlaughterRequests.js b/src/features/slaughter-house/components/slaughter-requests/SlaughterRequests.js new file mode 100644 index 0000000..1c8cbc1 --- /dev/null +++ b/src/features/slaughter-house/components/slaughter-requests/SlaughterRequests.js @@ -0,0 +1,238 @@ +import { Button, Grid, IconButton, TextField } from "@mui/material"; +import DeleteIcon from "@mui/icons-material/Delete"; +import { SPACING } from "../../../../data/spacing"; +import { useDispatch, useSelector } from "react-redux"; +import { + CLOSE_MODAL, + DRAWER, + LOADING_END, + LOADING_START, + OPEN_MODAL, +} from "../../../../lib/redux/slices/appSlice"; +import { slaughterGetRequests } from "../../services/salughter-get-requests"; +import { useContext, useEffect, useState } from "react"; +import { slaughterDeleteRequest } from "../../services/slaughter-delete-request"; +import { AppContext } from "../../../../contexts/AppContext"; +import { SlaughterNewRequestForm } from "../slaughter-new-request/SlaughterNewRequestForm"; +import { formatJustDate } from "../../../../utils/formatTime"; +import { DatePicker } from "@mui/x-date-pickers"; +import moment from "moment/moment"; +import ResponsiveTable from "../../../../components/responsive-table/ResponsiveTable"; +import { checkPathStartsWith } from "../../../../utils/checkPathStartsWith"; +// import { slaughterPayService } from "../../services/salughter-pay"; + +export const SlaughterRequests = () => { + // const [refId, setRefId] = useState(); + const [dataTable, setDataTable] = useState([]); + const { slaughterRequests } = useSelector((state) => state.slaughterSlice); + const dispatch = useDispatch(); + const [openNotif] = useContext(AppContext); + const [, , selectedDate1, setSelectedDate1, selectedDate2, setSelectedDate2] = + useContext(AppContext); + const selectedSubUser = useSelector( + (state) => state.userSlice.selectedSubUser + ); + + useEffect(() => { + const currentDate = moment(new Date()).format("YYYY-MM-DD"); + setSelectedDate1(currentDate); + setSelectedDate2(currentDate); + }, []); + + useEffect(() => { + dispatch( + slaughterGetRequests({ + selectedDate1, + selectedDate2, + role_key: checkPathStartsWith("slaughter") + ? selectedSubUser?.key || "" + : "", + }) + ); + }, [selectedDate1, selectedDate2, selectedSubUser?.key]); + + useEffect(() => { + const d = slaughterRequests?.map((item, i) => { + let state; + if (item.state === "archive") { + state = "بایگانی شده"; + } else if (item.provinceState === "pending") { + state = "در انتظار تایید استان"; + } else if (item.provinceState === "accepted") { + state = "تایید شده توسط استان"; + } else if (item.provinceState === "rejected") { + state = "رد شده توسط استان"; + } + return [ + i + 1, + item.killHouse.name, + formatJustDate(item?.createDate), + item.provinceQuantity + ? item.provinceQuantity.toLocaleString() + : item.killCapacity?.toLocaleString(), + item.provinceQuantity ? item.killCapacity?.toLocaleString() : 0, + item.reciveTime, + formatJustDate(item?.reciveDate), + state, + { + dispatch( + OPEN_MODAL({ + title: "آیا مطمئن هستید؟", + content: ( + + + + + ), + }) + ); + }} + > + + , + ]; + }); + + setDataTable(d); + }, [slaughterRequests]); + + // useEffect(() => { + // dispatch(slaughterPayService()).then((r) => { + // setRefId(r.payload.data.refId); + // }); + // }, []); + + const [tableDataCol] = useState([ + "ردیف", + "نام کشتارگاه", + "تاریخ ایجاد درخواست", + "تعداد درخواست اولیه", + "تعداد مورد تایید", + "زمان دریافت", + "تاریخ درخواستی کشتار", + "وضعیت", + "حذف درخواست", + ]); + + return ( + <> + + + + + ( + + )} + value={selectedDate1} + onChange={(e) => { + setSelectedDate1(moment(e).format("YYYY-MM-DD")); + }} + /> + + + ( + + )} + value={selectedDate2} + onChange={(e) => { + setSelectedDate2(moment(e).format("YYYY-MM-DD")); + }} + /> + + + + + + ); +}; diff --git a/src/features/slaughter-house/components/slaughter-requests/tour.js b/src/features/slaughter-house/components/slaughter-requests/tour.js new file mode 100644 index 0000000..c99d019 --- /dev/null +++ b/src/features/slaughter-house/components/slaughter-requests/tour.js @@ -0,0 +1,20 @@ +export const slaughterRequestsTourSteps = [ + { + selector: ".new-request-form-button", + content: ({ goTo, inDOM }) => ( +
    برای ثبت درخواست کشتار اینجا کلیک کنید.
    + ), + }, + { + selector: ".slaughter-submited-requests", + content: ({ goTo, inDOM }) => ( +
    درخواست های ثبت شده خود را در این قسمت مشاهده می کنید.
    + ), + }, + { + selector: ".slaughter-archived-requests", + content: ({ goTo, inDOM }) => ( +
    درخواست های بایگانی شده شما در این قسمت نمایش داده می شود.
    + ), + }, +]; diff --git a/src/features/slaughter-house/components/slaughter-segmentation/SlaughterSegmentation.js b/src/features/slaughter-house/components/slaughter-segmentation/SlaughterSegmentation.js new file mode 100644 index 0000000..4d86c11 --- /dev/null +++ b/src/features/slaughter-house/components/slaughter-segmentation/SlaughterSegmentation.js @@ -0,0 +1,313 @@ +import { useContext, useEffect, useState } from "react"; +import { useDispatch, useSelector } from "react-redux"; +import moment from "moment"; +import { Button, TextField } from "@mui/material"; +import { DatePicker } from "@mui/x-date-pickers"; +import { RiSearchLine } from "react-icons/ri"; +import axios from "axios"; +import { AppContext } from "../../../../contexts/AppContext"; +import { stawardGetSegmentDashboardService } from "../../../guild/services/steward-get-dashboard-service"; +import { + DRAWER, + LOADING_END, + LOADING_START, +} from "../../../../lib/redux/slices/appSlice"; +import { stewardGetOutSellService } from "../../../guild/services/steward-get-sell-out-service"; +import { formatJustDate, formatTime } from "../../../../utils/formatTime"; +import { StewardSegmentOperation } from "../../../guild/components/StewardSegmentOperation"; +import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl"; +import { Grid } from "../../../../components/grid/Grid"; +import { SPACING } from "../../../../data/spacing"; +import ResponsiveTable from "../../../../components/responsive-table/ResponsiveTable"; +import { StewardSegmentSubmitOperation } from "../../../guild/components/StewardSegmentSubmitOperation"; +import { checkPathStartsWith } from "../../../../utils/checkPathStartsWith"; + +export const SlaughterSegmentation = () => { + const [data, setData] = useState([]); + const [products, setProducts] = useState([]); + const [tableData, setTableData] = useState([]); + const [totalRows, setTotalRows] = useState(0); + const [perPage, setPerPage] = useState(10); + const [textValue, setTextValue] = useState(""); + const [page, setPage] = useState(1); + const [dashboardData, setDashboardData] = useState([]); + const selectedSubUser = useSelector( + (state) => state.userSlice.selectedSubUser + ); + const [, , selectedDate1, setSelectedDate1, selectedDate2, setSelectedDate2] = + useContext(AppContext); + const dispatch = useDispatch(); + + // const userKey = useSelector((state) => state.userSlice.userProfile.key); + + const getDashboardData = () => { + dispatch( + stawardGetSegmentDashboardService({ + value: textValue, + date1: selectedDate1, + date2: selectedDate2, + role: getRoleFromUrl(), + role_key: checkPathStartsWith("slaughter") ? selectedSubUser?.key : "", + }) + ).then((r) => { + setDashboardData(r.payload.data); + }); + }; + + useEffect(() => { + const currentDate = moment(new Date()).format("YYYY-MM-DD"); + setSelectedDate1(currentDate); + setSelectedDate2(currentDate); + }, []); + + const fetchApiData = async (page) => { + dispatch(LOADING_START()); + const response = await axios.get( + `app-segmentation/?search=filter&value=${textValue}&date1=${selectedDate1}&date2=${selectedDate2}&page=${page}&page_size=${perPage}&role=${getRoleFromUrl()}${ + checkPathStartsWith("slaughter") + ? `&role_key=${selectedSubUser?.key}` + : "" + }` + ); + + getDashboardData(); + dispatch(LOADING_END()); + setData(response.data.results); + setTotalRows(response.data.count); + }; + + const handlePageChange = (page) => { + fetchApiData(page); + setPage(page); + }; + const updateTable = () => { + fetchApiData(page); + }; + + const handlePerRowsChange = (perRows) => { + setPerPage(perRows); + setPage(1); + }; + + const handleTextChange = (event) => { + setTextValue(event.target.value); + }; + + useEffect(() => { + fetchApiData(1); + dispatch( + stewardGetOutSellService({ + role_key: checkPathStartsWith("slaughter") + ? selectedSubUser?.key || "" + : "", + }) + ).then((r) => { + setProducts(r.payload.data); + }); + }, []); + + useEffect(() => { + const d = data?.map((item, i) => { + return [ + page === 1 ? i + 1 : i + perPage * (page - 1) + 1, + item?.productionDate ? formatTime(item?.productionDate) : "-", + item?.distributionType === "web" + ? "سایت" + : item?.distributionType === "app" + ? "موبایل" + : item?.distributionType === "pos" + ? "پوز" + : item?.distributionType || "-", + `${item?.buyer?.fullname}(${item?.buyer?.mobile})`, + item?.toGuild + ? `به قطعه بند - ${item?.toGuild?.user?.fullname}(${item?.toGuild?.user?.mobile})` + : "قطعه بندی توسط کشتارگاه", + item?.date ? formatJustDate(item?.date) : "-", + item?.weight, + item?.quota === "governmental" + ? "دولتی" + : item?.quota === "free" + ? "آزاد" + : "-", + item?.saleType === "governmental" + ? "دولتی" + : item?.saleType === "free" + ? "آزاد" + : "-", + , + ]; + }); + + setTableData(d); + }, [data]); + + useEffect(() => { + fetchApiData(1); + }, [selectedDate1, selectedDate2, perPage, selectedSubUser?.key]); + + const handleSubmit = async (event) => { + event.preventDefault(); + dispatch(LOADING_START()); + try { + const response = await axios.get( + `app-segmentation/?search=filter&value=${textValue}&date1=${selectedDate1}&date2=${selectedDate2}&page=${page}&role=${getRoleFromUrl()}${ + checkPathStartsWith("slaughter") + ? `&role_key=${selectedSubUser?.key}` + : "" + }` + ); + setData(response.data.results); + setTotalRows(response.data.count); + getDashboardData(); + dispatch(LOADING_END()); + } catch (error) { + console.error("Error fetching data:", error); + } + }; + + return ( + + + + + +
    + + + + + + + ( + + )} + value={selectedDate1} + onChange={(e) => + setSelectedDate1(moment(e).format("YYYY-MM-DD")) + } + /> + + + ( + + )} + value={selectedDate2} + onChange={(e) => + setSelectedDate2(moment(e).format("YYYY-MM-DD")) + } + /> + + {/* + + */} + +
    + + +
    +
    + ); +}; diff --git a/src/features/slaughter-house/components/slaughter-sell-carcass-in-province-submit-registration-code/SlaughterSellCarcassInProvinceSubmitRegistrationCode.js b/src/features/slaughter-house/components/slaughter-sell-carcass-in-province-submit-registration-code/SlaughterSellCarcassInProvinceSubmitRegistrationCode.js new file mode 100644 index 0000000..77dfc46 --- /dev/null +++ b/src/features/slaughter-house/components/slaughter-sell-carcass-in-province-submit-registration-code/SlaughterSellCarcassInProvinceSubmitRegistrationCode.js @@ -0,0 +1,101 @@ +import React, { useContext } from "react"; +import { Grid } from "../../../../components/grid/Grid"; +import { Button, TextField } from "@mui/material"; +import { useFormik } from "formik"; +import * as yup from "yup"; +import { useDispatch } from "react-redux"; +import { AppContext } from "../../../../contexts/AppContext"; +import { guildAllocatedStockOperationService } from "../../../guild/services/guild-allocated-stock-operation"; +import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl"; + +const validationSchema = yup.object({ + verificationCode: yup + .string() + .required("کد احراز الزامی است") + .matches(/^\d+$/, "کد احراز باید فقط شامل اعداد باشد"), +}); + +export const SlaughterSellCarcassInProvinceSubmitRegistrationCode = ({ + item, + fetchApiData, +}) => { + const dispatch = useDispatch(); + + const [openNotif] = useContext(AppContext); + const formik = useFormik({ + initialValues: { + verificationCode: "", + }, + validationSchema: validationSchema, + onSubmit: (values) => { + dispatch( + guildAllocatedStockOperationService({ + steward_allocation_key: item?.key, + logged_registration_code: values.verificationCode, + role: getRoleFromUrl(), + }) + ).then((r) => { + if (r.payload.error) { + openNotif({ + vertical: "top", + horizontal: "center", + msg: r.payload.error, + severity: "error", + }); + } else { + openNotif({ + vertical: "top", + horizontal: "center", + msg: "عملیات با موفقیت انجام شد.", + severity: "success", + }); + fetchApiData(); + } + }); + }, + }); + + return ( + +
    + + + + + +
    +
    + ); +}; diff --git a/src/features/slaughter-house/components/slaughter-sell-carcass-in-province/ProvinceSellCarcassInProvince.js b/src/features/slaughter-house/components/slaughter-sell-carcass-in-province/ProvinceSellCarcassInProvince.js new file mode 100644 index 0000000..26fd975 --- /dev/null +++ b/src/features/slaughter-house/components/slaughter-sell-carcass-in-province/ProvinceSellCarcassInProvince.js @@ -0,0 +1,691 @@ +import React, { useContext, useEffect, useState } from "react"; +import { Grid } from "../../../../components/grid/Grid"; +import ResponsiveTable from "../../../../components/responsive-table/ResponsiveTable"; +import { useDispatch, useSelector } from "react-redux"; +// import { provinceGetBuyersService } from "../../../province/services/province-get-buyers"; +import { + Button, + IconButton, + List, + ListItemButton, + ListItemIcon, + ListItemText, + Popover, + TextField, + Tooltip, + Typography, +} from "@mui/material"; +import { + CLOSE_MODAL, + DRAWER, + LOADING_END, + LOADING_START, + OPEN_MODAL, +} from "../../../../lib/redux/slices/appSlice"; +import moment from "moment"; +import { AppContext } from "../../../../contexts/AppContext"; +import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl"; +import axios from "axios"; +import { DatePicker } from "@mui/x-date-pickers"; +import { SlaughterAllocateToGuild } from "../slaughter-allocate-to-guild/SlaughterAllocateToGuild"; +import { slaughterInventoryFinalSubmitService } from "../../services/slaughter-inventory-final-submit"; +import { SPACING } from "../../../../data/spacing"; +import { SlaughterManageInventoryAllocationOperations } from "../slaughter-manage-inventory-allocation-operations/SlaughterManageInventoryAllocationOperations"; +import { formatJustDate, formatTime } from "../../../../utils/formatTime"; +import { SlaughterAllocateForFreezing } from "../slaughter-allocate-for-freezing/SlaughterAllocateForFreezing"; +import { RiFileExcel2Fill, RiSearchLine } from "react-icons/ri"; +import { ROUTE_SLAUGHTER_DAILY_LIST } from "../../../../routes/routes"; +import { useNavigate } from "react-router-dom"; +import ShowImage from "../../../../components/show-image/ShowImage"; +import { SlaughterSellCarcassInProvinceSubmitRegistrationCode } from "../slaughter-sell-carcass-in-province-submit-registration-code/SlaughterSellCarcassInProvinceSubmitRegistrationCode"; +import { useProvinceName } from "../../../../utils/getProvinceName"; +import { slaughterDeleteAllocatedService } from "../../services/salughter-delete-allocated"; +import { fetchSlaughterBroadcastAndProducts } from "../../services/handle-fetch-slaughter-products"; +import { slaughterResendStewardAllocationSmsService } from "../../services/slaughter-send-sms-steward-allocation-again"; +import TuneIcon from "@mui/icons-material/Tune"; +import DeleteIcon from "@mui/icons-material/Delete"; +import SmsIcon from "@mui/icons-material/Sms"; +import { getAllocationType } from "../../../../utils/getAllocationType"; +import { checkPathStartsWith } from "../../../../utils/checkPathStartsWith"; + +export const ProvinceSellCarcassInProvince = ({ updateTable, priceInfo }) => { + const province = useProvinceName(); + const userKey = useSelector((state) => state.userSlice.userProfile.key); + const selectedSubUser = useSelector( + (state) => state.userSlice.selectedSubUser + ); + // const [killHouseTable, setKillHouseTable] = useState(); + + const { slaughterProducts } = useSelector((state) => state.slaughterSlice); + + const dispatch = useDispatch(); + const navigate = useNavigate(); + + //allocations **************************************************************************************************************** + + const [, , selectedDate1, setSelectedDate1, selectedDate2, setSelectedDate2] = + useContext(AppContext); + useEffect(() => { + const currentDate = moment(new Date()).format("YYYY-MM-DD"); + setSelectedDate1(currentDate); + setSelectedDate2(currentDate); + }, []); + + const handleTextChange = (event) => { + setTextValue(event.target.value); + }; + + const [data, setData] = useState([]); + const [totalRows, setTotalRows] = useState(0); + const [perPage, setPerPage] = useState(10); + const [textValue, setTextValue] = useState(""); + const [page, setPage] = useState(1); + const [tableData, setTableData] = useState([]); + const [openNotif] = useContext(AppContext); + + const fetchApiData = async (page) => { + dispatch(LOADING_START()); + const response = await axios.get( + `steward-allocation/?search=filter&value=${textValue}&role=${getRoleFromUrl()}${ + checkPathStartsWith("slaughter") + ? `&role_key=${selectedSubUser?.key}` + : "" + }&date1=${selectedDate1}&date2=${selectedDate2}&page=${ + page ? page : 1 + }&page_size=${perPage}` + ); + dispatch(LOADING_END()); + setData(response.data.results); + setTotalRows(response.data.count); + }; + + const handlePageChange = (page) => { + fetchApiData(page); + setPage(page); + }; + + const getAllocationData = (item) => { + let type = `${item?.toKillHouse?.name} - ${item?.toKillHouse?.killHouseOperator?.user?.fullname} (${item?.toKillHouse?.killHouseOperator?.user?.mobile})`; + switch (item?.allocationType) { + case "killhouse_killhouse": + type = `${item?.toKillHouse?.name} - ${item?.toKillHouse?.killHouseOperator?.user?.fullname} (${item?.toKillHouse?.killHouseOperator?.user?.mobile})`; + break; + case "killhouse_steward": + type = `${item?.toStewards?.name} - ${item?.toStewards?.user?.fullname} (${item?.toStewards?.user?.mobile})`; + break; + case "killhouse_guild": + type = `${item?.toGuilds?.guildsName} - ${item?.toGuilds?.user?.fullname} (${item?.toGuilds?.user?.mobile})`; + break; + case "ColdHouse": + type = `${item?.toColdHouse?.name}`; + break; + default: + type = `${item?.toKillHouse?.name} - ${item?.toKillHouse?.killHouseOperator?.user?.fullname} (${item?.toKillHouse?.killHouseOperator?.user?.mobile})`; + break; + } + + return type; + }; + + const handlePerRowsChange = (perRows) => { + setPerPage(perRows); + setPage(1); + }; + + useEffect(() => { + const d = data?.map((item, i) => { + return [ + page === 1 ? i + 1 : i + perPage * (page - 1) + 1, + item?.date ? formatTime(item?.date) : "-", + item?.productionDate ? formatJustDate(item?.productionDate) : "-", + (item?.distributionType === "web" + ? "سایت" + : item?.distributionType === "app" + ? "موبایل" + : item?.distributionType === "pos" + ? "پوز" + : item?.distributionType) || "-", + getAllocationType(item), + getAllocationData(item), + item?.interfaceNumber || "-", + item?.sellType === "exclusive" ? "اختصاصی" : "آزاد", + item?.amount?.toLocaleString() + " ریال", + item?.totalAmount?.toLocaleString() + " ریال", + item?.realNumberOfCarcasses?.toLocaleString(), + item?.realWeightOfCarcasses?.toLocaleString(), + item?.receiverRealNumberOfCarcasses?.toLocaleString(), + item?.receiverRealWeightOfCarcasses?.toLocaleString(), + item?.receiverState === "accepted" ? ( + "تایید شده" + ) : item?.loggedRegistrationCode ? ( + item.loggedRegistrationCode + ) : item?.registrationCode ? ( + + ) : ( + "-" + ), + item?.registrationCode ? "ارسال شده" : "ارسال نشده", + , + item?.quota === "governmental" + ? "دولتی" + : item?.quota === "free" + ? "آزاد" + : "-", + item?.approvedPriceStatus ? "دولتی" : "آزاد", + item?.receiverState === "accepted" || item?.loggedRegistrationCode + ? "تایید شده" + : item?.receiverState === "rejected" + ? "رد شده" + : item?.activeExpireDateTime && + !item?.loggedRegistrationCode && + item?.registrationCode + ? "در انتظار ورود کد احراز" + : "در انتظار تایید", + item?.receiverState === "pending" && + item?.activeExpireDateTime && + !item?.loggedRegistrationCode && + item?.registrationCode ? ( + + ) : ( + + ), + ]; + }); + + setTableData(d); + }, [data]); + + useEffect(() => { + fetchApiData(1); + }, [dispatch, selectedDate1, selectedDate2, perPage, selectedSubUser?.key]); + + const PendingOperationsPopover = ({ item, fetchApiData, updateTable }) => { + const [anchorEl, setAnchorEl] = useState(null); + const open = Boolean(anchorEl); + const id = open ? `pending-popover-${item.key}` : undefined; + + const handleOpen = (event) => { + setAnchorEl(event.currentTarget); + }; + + const handleClose = () => { + setAnchorEl(null); + }; + + const handleDelete = () => { + dispatch( + OPEN_MODAL({ + title: "آیا مطمئن هستید؟", + content: ( + + + + + + + + + ), + }) + ); + }; + + const handleResend = () => { + dispatch( + slaughterResendStewardAllocationSmsService({ + key: item.key, + }) + ).then((r) => { + if (r.payload.error) { + openNotif({ + vertical: "top", + horizontal: "center", + msg: r.payload.error, + severity: "error", + }); + } else { + updateTable(); + openNotif({ + vertical: "top", + horizontal: "center", + msg: "کد با موفقیت ارسال شد.", + severity: "success", + }); + } + }); + }; + + const options = [ + { + key: "delete", + label: "حذف", + icon: DeleteIcon, + color: "error.main", + action: handleDelete, + }, + { + key: "resend", + label: "ارسال مجدد کد", + icon: SmsIcon, + color: "primary.main", + action: handleResend, + }, + ]; + + return ( + + + + + + + {options.map((option) => { + const IconComponent = option.icon; + return ( + { + handleClose(); + option.action(); + }} + sx={{ + borderRadius: 1, + mb: 0.25, + py: 0.5, + "&:last-of-type": { mb: 0 }, + }} + > + + + + + + ); + })} + + + + ); + }; + + const handleSubmit = async (event) => { + event.preventDefault(); + dispatch(LOADING_START()); + + try { + const response = await axios.get( + `steward-allocation/?role=${getRoleFromUrl()}${ + checkPathStartsWith("slaughter") + ? `&role_key=${selectedSubUser?.key}` + : "" + }&search=filter&value=${textValue}&date1=${selectedDate1}&date2=${selectedDate2}&page=${1}&page_size=${perPage}` + ); + setData(response.data.results); + setTotalRows(response.data.count); + dispatch(LOADING_END()); + } catch (error) { + console.error("Error fetching data:", error); + } + }; + + //end allocations **************************************************************************************************************** + + return ( + + + + + + + + + + + ( + + )} + value={selectedDate1} + onChange={(e) => { + setSelectedDate1(moment(e).format("YYYY-MM-DD")); + }} + /> + + + ( + + )} + value={selectedDate2} + onChange={(e) => { + setSelectedDate2(moment(e).format("YYYY-MM-DD")); + }} + /> + + +
    + + + +
    + + + +
    +
    + ), + }) + ); + }} + > + تایید نهایی (یکجا) + + + + +
    + + + + + ); +}; diff --git a/src/features/slaughter-house/components/slaughter-sell-carcass-out-province-add-buyer/SlaughterSellCarcassOutProvinceAddBuyer.js b/src/features/slaughter-house/components/slaughter-sell-carcass-out-province-add-buyer/SlaughterSellCarcassOutProvinceAddBuyer.js new file mode 100644 index 0000000..d03f0aa --- /dev/null +++ b/src/features/slaughter-house/components/slaughter-sell-carcass-out-province-add-buyer/SlaughterSellCarcassOutProvinceAddBuyer.js @@ -0,0 +1,720 @@ +import React, { useContext, useEffect, useState } from "react"; +import { Grid } from "../../../../components/grid/Grid"; +import SearchIcon from "@mui/icons-material/Search"; +import { + Autocomplete, + Button, + IconButton, + Radio, + RadioGroup, + FormControlLabel, + TextField, + Typography, +} from "@mui/material"; +import { useFormik } from "formik"; +import { Yup } from "../../../../lib/yup/yup"; +import { SPACING } from "../../../../data/spacing"; +import { + slaughterEditBuyerDataService, + slaughterSubmitBuyerDataService, +} from "../../services/slaughter-house-submit-buyer"; +import { AppContext } from "../../../../contexts/AppContext"; +import { useDispatch } from "react-redux"; +import { DRAWER } from "../../../../lib/redux/slices/appSlice"; +import { + slaughterGetCitiesService, + slaughterGetProvinceService, +} from "../../services/slaughter-get-provinces"; +import { provinceGetNationalDocumentsService } from "../../../province/services/province-get-national-documents"; +import { LabelField } from "../../../../components/label-field/LabelField"; +import { extractProvinceFromAddress } from "../../../../utils/address"; + +export const SlaughterSellCarcassOutProvinceAddBuyer = ({ + updateTable, + isEdit, + data, + defaultPersonType, + defaultNationalCode, +}) => { + const [openNotif] = useContext(AppContext); + const [userData, setUserData] = useState(null); + const [notFound, setNotFound] = useState(false); + const [inquiryInProgress, setInquiryInProgress] = useState(false); + const [lockedFields, setLockedFields] = useState({}); + const dispatch = useDispatch(); + const [provinceData, setProvinceData] = useState([]); + const [cityData, setCityData] = useState([]); + + const formik = useFormik({ + initialValues: { + mobile: "", + firstName: "", + lastName: "", + unitName: "", + province: "", + city: "", + nationalId: "", + }, + validationSchema: Yup.object({ + mobile: Yup.string() + .required("این فیلد اجباری است!") + .min(11, "شماره موبایل باید 11 رقم باشد") + .max(11, "شماره موبایل باید 11 رقم باشد") + .matches(/^09\d{9}$/, "شماره موبایل باید با 09 شروع شود و 11 رقم باشد"), + firstName: Yup.string() + .required("این فیلد اجباری است!") + .typeError("لطفا فیلد را به درستی وارد کنید!"), + lastName: Yup.string() + .required("این فیلد اجباری است!") + .typeError("لطفا فیلد را به درستی وارد کنید!"), + unitName: Yup.string() + .required("این فیلد اجباری است!") + .typeError("لطفا فیلد را به درستی وارد کنید!"), + province: Yup.string() + .required("این فیلد اجباری است!") + .typeError("لطفا فیلد را به درستی وارد کنید!"), + city: Yup.string() + .required("این فیلد اجباری است!") + .typeError("لطفا فیلد را به درستی وارد کنید!"), + nationalId: Yup.string() + .required("این فیلد اجباری است!") + .matches(/^\d{10,11}$/, "شناسه باید 10 یا 11 رقم و فقط عدد باشد"), + }), + validateOnMount: true, + }); + + const formik2 = useFormik({ + initialValues: { + personType: defaultPersonType || "real", // real | legal + nationalCode: defaultNationalCode || "", + }, + validationSchema: Yup.object({ + personType: Yup.string().oneOf(["real", "legal"]).required(), + nationalCode: Yup.string() + .required("این فیلد اجباری است!") + .when("personType", { + is: "real", + then: (schema) => + schema + .length(10, "کد ملی باید 10 رقم باشد") + .matches(/^\d{10}$/, "کد ملی باید فقط شامل اعداد باشد"), + otherwise: (schema) => + schema + .length(11, "شناسه ملی حقوقی باید 11 رقم باشد") + .matches(/^\d{11}$/, "شناسه ملی حقوقی باید فقط شامل اعداد باشد"), + }), + }), + validateOnMount: true, + }); + + useEffect(() => { + formik.validateForm(); + }, []); + + // Fallback: ensure values are populated from data when editing + useEffect(() => { + if (isEdit && data?.buyer) { + if (data.buyer.isRealPerson === false) { + formik2.setFieldValue("personType", "legal", false); + } + if (data.buyer.nationalCode) { + // formik2.setFieldValue("nationalCode", data.buyer.nationalCode, false); + } else if (data.buyer.parentLegalPersonNationalCode) { + formik2.setFieldValue( + "nationalCode", + data.buyer.parentLegalPersonNationalCode, + false + ); + } + } + }, [isEdit, data]); + + useEffect(() => { + if (userData) { + formik.setValues({ + mobile: userData.mobile || "", + firstName: userData.firstName || "", + lastName: userData.lastName || "", + unitName: userData.unitName || "", + province: userData.province || "", + city: userData.city || "", + nationalId: userData.nationalId || "", + }); + + const fieldKeys = [ + "nationalId", + "mobile", + "firstName", + "lastName", + "unitName", + "city", + ]; + const locks = fieldKeys.reduce((acc, key) => { + const value = userData[key]; + acc[key] = Boolean(value && value !== ""); + return acc; + }, {}); + // Province is not locked so user can change it + locks.province = false; + setLockedFields(locks); + setTimeout(() => { + formik.validateForm(); + }, 1); + } + }, [userData]); + + useEffect(() => { + if (isEdit) { + formik.setValues({ + mobile: data.mobile || "", + firstName: data.firstName || "", + lastName: data.lastName || "", + unitName: data.unitName || "", + province: data.province || "", + city: data.city || "", + nationalId: data.national_id || data.nationalId || "", + }); + setLockedFields({}); + // formik2.setFieldValue( + // "nationalCode", + // data.national_code || + // data.nationalCode || + // data.national_id || + // data.nationalId || + // "" + // ); + setTimeout(() => { + formik.validateForm(); + }, 1); + } + }, [isEdit]); + + useEffect(() => { + dispatch(slaughterGetProvinceService()).then((r) => { + setProvinceData(r.payload.data); + }); + }, []); + + useEffect(() => { + if (formik.values.province) { + setCityData( + [], + dispatch(slaughterGetCitiesService(formik.values.province)).then( + (r) => { + setCityData(r.payload.data); + } + ) + ); + } + }, [formik.values.province]); + + const handleNationalInquiry = async () => { + if (!formik2.isValid || inquiryInProgress) { + return; + } + + const nationalCode = formik2.values.nationalCode; + const personType = formik2.values.personType; + + setInquiryInProgress(true); + setNotFound(false); + setUserData(null); + setLockedFields({}); + + let personData = null; + let selectedGuild = null; + + try { + if (personType === "legal") { + const url = `https://pay.rasadyar.com/national-documents?info=${encodeURIComponent( + nationalCode + )}&type=unit`; + const res = await fetch(url); + const json = await res.json(); + + if (json?.status && json?.data) { + const d = json.data; + const extractedProvince = extractProvinceFromAddress( + d.address || "", + provinceData + ); + const aggregatedUserData = { + mobile: "", + firstName: d.name || "", + lastName: d.name || "", + unitName: d.name || "", + province: d.state || extractedProvince || "", + city: "", // User will select city manually + nationalId: d.nationalCode || nationalCode, + }; + setUserData(aggregatedUserData); + formik2.setFieldValue( + "nationalCode", + aggregatedUserData.nationalId || nationalCode + ); + openNotif({ + vertical: "top", + horizontal: "center", + msg: "اطلاعات حقوقی با موفقیت دریافت شد.", + severity: "success", + }); + } else { + setNotFound(true); + formik.setFieldValue("nationalId", nationalCode); + setLockedFields({}); + openNotif({ + vertical: "top", + horizontal: "center", + msg: "اطلاعات حقوقی برای این شناسه یافت نشد، لطفا اطلاعات را به صورت دستی ثبت کنید.", + severity: "warning", + }); + } + return; + } + + const personResponse = await dispatch( + provinceGetNationalDocumentsService({ + info: nationalCode, + type: "person", + }) + ); + + if (personResponse.payload?.error) { + openNotif({ + vertical: "top", + horizontal: "center", + msg: personResponse.payload.error, + severity: "error", + }); + } else if ( + personResponse.payload?.data?.status && + personResponse.payload?.data?.data + ) { + personData = personResponse.payload.data.data; + } else { + openNotif({ + vertical: "top", + horizontal: "center", + msg: "اطلاعات فردی یافت نشد.", + severity: "warning", + }); + } + + const guildResponse = await dispatch( + provinceGetNationalDocumentsService({ + info: nationalCode, + type: "guild", + }) + ); + + if (guildResponse.payload?.error) { + openNotif({ + vertical: "top", + horizontal: "center", + msg: guildResponse.payload.error, + severity: "error", + }); + } else if ( + guildResponse.payload?.data?.status && + guildResponse.payload?.data?.data + ) { + const guildData = guildResponse.payload.data.data; + const guildArray = Array.isArray(guildData) ? guildData : [guildData]; + if (guildArray.length > 0) { + const activeGuildIndex = guildArray.findIndex( + (g) => g.licenseStatus === "فعال/صادر شده" + ); + selectedGuild = + guildArray[activeGuildIndex !== -1 ? activeGuildIndex : 0]; + } else { + openNotif({ + vertical: "top", + horizontal: "center", + msg: "اطلاعات صنفی برای این کد ملی یافت نشد.", + severity: "warning", + }); + } + } else { + openNotif({ + vertical: "top", + horizontal: "center", + msg: "اطلاعات صنفی برای این کد ملی یافت نشد.", + severity: "warning", + }); + } + + if (!personData && !selectedGuild) { + setNotFound(true); + formik.setFieldValue("nationalId", nationalCode); + setLockedFields({}); + openNotif({ + vertical: "top", + horizontal: "center", + msg: "اطلاعاتی برای این کد ملی یافت نشد، لطفا اطلاعات را به صورت دستی ثبت کنید.", + severity: "warning", + }); + return; + } + + const layerTwo = selectedGuild?.layerTwo || {}; + const aggregatedUserData = { + mobile: + layerTwo.mobilenumber || + personData?.mobile || + layerTwo.phonenumber || + "", + firstName: personData?.firstName || "", + lastName: personData?.lastName || "", + unitName: + selectedGuild?.title || + layerTwo.corporationName || + layerTwo.unionName || + "", + province: selectedGuild?.state || "", + city: selectedGuild?.city || "", + nationalId: + personData?.nationalId || + layerTwo.nationalcode || + selectedGuild?.nationalId || + nationalCode, + }; + + setUserData(aggregatedUserData); + formik2.setFieldValue( + "nationalCode", + aggregatedUserData.nationalId || nationalCode + ); + openNotif({ + vertical: "top", + horizontal: "center", + msg: "اطلاعات با موفقیت دریافت شد.", + severity: "success", + }); + } finally { + setInquiryInProgress(false); + } + }; + + return ( + + + + { + const value = e.target.value; + formik2.setFieldValue("personType", value); + // reset previous results when toggling type + setUserData(null); + setNotFound(false); + setLockedFields({}); + formik.resetForm({ + values: { + mobile: "", + firstName: "", + lastName: "", + unitName: "", + province: "", + city: "", + nationalId: "", + }, + }); + }} + > + } label="حقیقی" /> + } label="حقوقی" /> + + + + {"استعلام "} + {formik2.values.personType === "legal" ? "شناسه ملی حقوقی" : "کد ملی"} + + + + + + + + + + {userData || notFound || isEdit ? ( + + + + + + + + ({ id: i.name, label: i.name })) + : [] + } + disabled={Boolean(lockedFields.province)} + isOptionEqualToValue={(option, value) => option.id === value.id} + onChange={(e, value) => { + formik.setFieldValue("province", value ? value.id : ""); + formik.setFieldValue("city", ""); + }} + value={ + formik.values.province + ? { + id: formik.values.province, + label: formik.values.province, + } + : null + } + renderInput={(params) => ( + + )} + /> + {!notFound && ( + + استان: {formik.values.province} + + )} + + ({ id: i.name, label: i.name })) + : [] + } + isOptionEqualToValue={(option, value) => option.id === value.id} + onChange={(e, value) => { + formik.setFieldValue("city", value ? value.id : ""); + }} + value={ + formik.values.city + ? { + id: formik.values.city, + label: formik.values.city, + } + : null + } + renderInput={(params) => ( + + )} + /> + + {!notFound && ( + + شهر: {formik.values.city} + + )} + + ) : ( + + برای نمایش فرم، ابتدا استعلام کد ملی را انجام دهید. + + )} + + {(userData || notFound || isEdit) && ( + + + + )} + + ); +}; diff --git a/src/features/slaughter-house/components/slaughter-sell-carcass-out-province-buyers/SlaughterSellCarcassOutProvinceBuyers.js b/src/features/slaughter-house/components/slaughter-sell-carcass-out-province-buyers/SlaughterSellCarcassOutProvinceBuyers.js new file mode 100644 index 0000000..b3d8582 --- /dev/null +++ b/src/features/slaughter-house/components/slaughter-sell-carcass-out-province-buyers/SlaughterSellCarcassOutProvinceBuyers.js @@ -0,0 +1,275 @@ +import React, { useEffect, useState } from "react"; +import { + Button, + IconButton, + TextField, + RadioGroup, + FormControlLabel, + Radio, + FormControl, +} from "@mui/material"; +import axios from "axios"; +import ResponsiveTable from "../../../../components/responsive-table/ResponsiveTable"; +import { + DRAWER, + LOADING_END, + LOADING_START, +} from "../../../../lib/redux/slices/appSlice"; +import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl"; +import { Grid } from "../../../../components/grid/Grid"; +import { useDispatch, useSelector } from "react-redux"; +import { SlaughterSellCarcassOutProvinceAddBuyer } from "../slaughter-sell-carcass-out-province-add-buyer/SlaughterSellCarcassOutProvinceAddBuyer"; +import EditIcon from "@mui/icons-material/Edit"; +import { RiSearchLine } from "react-icons/ri"; +import { checkPathStartsWith } from "../../../../utils/checkPathStartsWith"; + +export const SlaughterSellCarcassOutProvinceBuyers = () => { + const handleTextChange = (event) => { + setTextValue(event.target.value); + }; + + const dispatch = useDispatch(); + + const [data, setData] = useState([]); + const [totalRows, setTotalRows] = useState(0); + const [perPage, setPerPage] = useState(10); + const [textValue, setTextValue] = useState(""); + const [page, setPage] = useState(1); + const [tableData, setTableData] = useState([]); + const [personType, setPersonType] = useState("real"); // real | legal + const selectedSubUser = useSelector( + (state) => state.userSlice.selectedSubUser + ); + + const fetchApiData = async (page) => { + dispatch(LOADING_START()); + const response = await axios.get( + `out-province-carcasses-buyer/?search=filter&value=${textValue}&role=${getRoleFromUrl()}${ + checkPathStartsWith("slaughter") + ? `&role_key=${selectedSubUser?.key}` + : "" + }&page=${page}&page_size=${perPage}&state=buyer-list&type=${personType}` + ); + dispatch(LOADING_END()); + setData(response.data.results); + setTotalRows(response.data.count); + }; + + const handlePageChange = (page) => { + fetchApiData(page); + setPage(page); + }; + + const handlePerRowsChange = (perRows) => { + setPerPage(perRows); + setPage(1); + }; + + const updateTable = () => { + fetchApiData(page !== 0 ? page : 1); + }; + + useEffect(() => { + const d = data?.map((item, i) => { + const baseCells = [page === 1 ? i + 1 : i + perPage * (page - 1) + 1]; + const buyerInfoCell = `${item?.fullname} (${item?.mobile})`; + const editCell = ( + { + dispatch( + DRAWER({ + right: !(window.innerWidth <= 600), + bottom: window.innerWidth <= 600, + content: ( + + ), + title: "ویرایش خریدار", + }) + ); + }} + > + + + ); + + if (personType === "real") { + return [ + ...baseCells, + buyerInfoCell, + item?.unitName, + item?.province, + item?.city, + item?.requestsInfo?.numberOfRequests?.toLocaleString(), + item?.requestsInfo?.totalQuantity?.toLocaleString(), + item?.requestsInfo?.totalWeight?.toLocaleString(), + editCell, + ]; + } else { + return [ + ...baseCells, + item?.unitName, + item?.buyer?.parentLegalPersonNationalCode, + item?.province, + item?.city, + item?.requestsInfo?.numberOfRequests?.toLocaleString(), + item?.requestsInfo?.totalQuantity?.toLocaleString(), + item?.requestsInfo?.totalWeight?.toLocaleString(), + editCell, + ]; + } + }); + + setTableData(d); + }, [data, personType, page, perPage, dispatch]); + + useEffect(() => { + fetchApiData(1); + }, [dispatch, perPage, personType, selectedSubUser?.key]); + + const handleSubmit = async (event) => { + event.preventDefault(); + dispatch(LOADING_START()); + + try { + const response = await axios.get( + `out-province-carcasses-buyer/?role=${getRoleFromUrl()}${ + checkPathStartsWith("slaughter") + ? `&role_key=${selectedSubUser?.key}` + : "" + }&search=filter&value=${textValue}&page=${1}&page_size=${perPage}&state=buyer-list&type=${personType}` + ); + setData(response.data.results); + setTotalRows(response.data.count); + dispatch(LOADING_END()); + } catch (error) { + console.error("Error fetching data:", error); + } + }; + + return ( + + + + { + const val = e.target.value; + setPersonType(val); + setPage(1); + }} + > + } label="حقیقی" /> + } label="حقوقی" /> + + + + + + +
    + + + +
    +
    + + +
    + ); +}; diff --git a/src/features/slaughter-house/components/slaughter-sell-carcass-out-province-sell/SlaughterSellCarcassOutProvinceSell.js b/src/features/slaughter-house/components/slaughter-sell-carcass-out-province-sell/SlaughterSellCarcassOutProvinceSell.js new file mode 100644 index 0000000..6db53b5 --- /dev/null +++ b/src/features/slaughter-house/components/slaughter-sell-carcass-out-province-sell/SlaughterSellCarcassOutProvinceSell.js @@ -0,0 +1,345 @@ +import React, { useContext, useEffect, useState } from "react"; +import { Button, TextField, Tooltip } from "@mui/material"; +import { DatePicker } from "@mui/x-date-pickers"; +import moment from "moment"; +import { useDispatch, useSelector } from "react-redux"; +import axios from "axios"; +import ResponsiveTable from "../../../../components/responsive-table/ResponsiveTable"; +import { AppContext } from "../../../../contexts/AppContext"; +import { + DRAWER, + LOADING_END, + LOADING_START, +} from "../../../../lib/redux/slices/appSlice"; +import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl"; +import { Grid } from "../../../../components/grid/Grid"; +import { slaughterSellCarcassOutProvinceGetDashboard } from "../../services/slaughter-sell-carcass-out-province"; +import { RiFileExcel2Fill } from "react-icons/ri"; +import { SlaughterSellCarcassOutProvinceSellSubmitSell } from "../slaughter-sell-carcass-out-province-submit-sell/SlaughterSellCarcassOutProvinceSellSubmitSell"; +import { RiSearchLine } from "react-icons/ri"; +import { CheckCleanceCode } from "../../../../components/check-clearance-code/ChechClearanceCode"; +import { formatJustDate, formatTime } from "../../../../utils/formatTime"; +import { SlaughterOutProvinceRegistrationCodeInput } from "../slaughter-out-province-registration-code-input/SlaughterOutProvinceRegistrationCodeInput"; +import { SlaughterOutProvinceSalesOperations } from "../slaughter-out-province-sales-operations/SlaughterOutProvinceSalesOperations"; +import { checkPathStartsWith } from "../../../../utils/checkPathStartsWith"; + +export const SlaughterSellCarcassOutProvinceSell = () => { + const [, , selectedDate1, setSelectedDate1, selectedDate2, setSelectedDate2] = + useContext(AppContext); + const dispatch = useDispatch(); + useEffect(() => { + const currentDate = moment(new Date()).format("YYYY-MM-DD"); + setSelectedDate1(currentDate); + setSelectedDate2(currentDate); + }, []); + const selectedSubUser = useSelector( + (state) => state.userSlice.selectedSubUser + ); + + const handleTextChange = (event) => { + setTextValue(event.target.value); + }; + + const [data, setData] = useState([]); + const [totalRows, setTotalRows] = useState(0); + const [perPage, setPerPage] = useState(10); + const [textValue, setTextValue] = useState(""); + const [page, setPage] = useState(1); + const [tableData, setTableData] = useState([]); + + const fetchApiData = async (page) => { + dispatch(LOADING_START()); + const response = await axios.get( + `kill_house_free_sale_bar/?search=filter&value=${textValue}&role=${getRoleFromUrl()}${ + checkPathStartsWith("slaughter") + ? `&role_key=${selectedSubUser?.key}` + : "" + }&date1=${selectedDate1}&date2=${selectedDate2}&page=${page}&page_size=${perPage}&type=dashboard` + ); + dispatch(LOADING_END()); + setData(response.data.results); + setTotalRows(response.data.count); + }; + + // const [openNotif] = useContext(AppContext); + + const handlePageChange = (page) => { + fetchApiData(page); + setPage(page); + }; + + const userKey = useSelector((state) => state.userSlice.userProfile.key); + + const handlePerRowsChange = (perRows) => { + setPerPage(perRows); + setPage(1); + }; + + const updateTable = () => { + fetchApiData(page !== 0 ? page : 1); + }; + + useEffect(() => { + const d = data?.map((item, i) => { + return [ + page === 1 ? i + 1 : i + perPage * (page - 1) + 1, + item?.date ? formatTime(item?.date) : "-", + item?.productionDate ? formatJustDate(item?.productionDate) : "-", + (item?.distributionType === "web" + ? "سایت" + : item?.distributionType === "app" + ? "موبایل" + : item?.distributionType === "pos" + ? "پوز" + : item?.distributionType) || "-", + `${item?.buyerName} (${item?.buyerMobile})`, + item?.buyer ? `${item?.buyer?.unitName}` : `${item?.buyerName}`, + item?.province, + item?.city, + // item?.numberOfCarcasses?.toLocaleString(), + item?.clearanceCode && ( + + ), + item?.quarantineWeightOfCarcasses?.toLocaleString(), + item?.weightOfCarcasses?.toLocaleString(), + item?.quota === "governmental" + ? "دولتی" + : item?.quota === "free" + ? "آزاد" + : "-", + item?.saleType === "governmental" + ? "دولتی" + : item?.saleType === "free" + ? "آزاد" + : "-", + item?.systemRegistrationCode ? ( + item?.loggedRegistrationCode ? ( + "تایید شده" + ) : item?.registrationCode ? ( + fetchApiData(page)} + /> + ) : ( + "-" + ) + ) : ( + "-" + ), + , + ]; + }); + + setTableData(d); + }, [data, page]); + + useEffect(() => { + fetchApiData(1); + }, [dispatch, selectedDate1, selectedDate2, perPage, selectedSubUser?.key]); + + const handleSubmit = async (event) => { + event.preventDefault(); + dispatch(LOADING_START()); + + try { + const response = await axios.get( + `kill_house_free_sale_bar/?role=${getRoleFromUrl()}${ + checkPathStartsWith("slaughter") + ? `&role_key=${selectedSubUser?.key}` + : "" + }&search=filter&value=${textValue}&date1=${selectedDate1}&date2=${selectedDate2}&page=${1}&page_size=${perPage}&type=dashboard` + ); + setData(response.data.results); + setTotalRows(response.data.count); + dispatch(LOADING_END()); + } catch (error) { + console.error("Error fetching data:", error); + } + dispatch( + slaughterSellCarcassOutProvinceGetDashboard({ + selectedDate1, + selectedDate2, + role_key: checkPathStartsWith("slaughter") + ? selectedSubUser?.key || "" + : "", + }) + ).then((r) => { + setDashboardData(r.payload.data); + }); + }; + + const [dashboardData, setDashboardData] = useState([]); + + useEffect(() => { + dispatch( + slaughterSellCarcassOutProvinceGetDashboard({ + selectedDate1, + selectedDate2, + role_key: checkPathStartsWith("slaughter") + ? selectedSubUser?.key || "" + : "", + }) + ).then((r) => { + setDashboardData(r.payload.data); + }); + }, [selectedDate1, selectedDate2, selectedSubUser?.key]); + + return ( + + + + ( + + )} + value={selectedDate1} + onChange={(e) => { + setSelectedDate1(moment(e).format("YYYY-MM-DD")); + }} + /> + + + ( + + )} + value={selectedDate2} + onChange={(e) => { + setSelectedDate2(moment(e).format("YYYY-MM-DD")); + }} + /> + + +
    + + + +
    + + + + + +
    + + + + + + + + + + +
    + ); +}; diff --git a/src/features/slaughter-house/components/slaughter-sell-carcass-out-province-submit-sell/SlaughterSellCarcassOutProvinceSellSubmitSell.js b/src/features/slaughter-house/components/slaughter-sell-carcass-out-province-submit-sell/SlaughterSellCarcassOutProvinceSellSubmitSell.js new file mode 100644 index 0000000..249aec7 --- /dev/null +++ b/src/features/slaughter-house/components/slaughter-sell-carcass-out-province-submit-sell/SlaughterSellCarcassOutProvinceSellSubmitSell.js @@ -0,0 +1,617 @@ +import React, { + useContext, + useEffect, + useState, + useCallback, + useRef, +} from "react"; +import { Grid } from "../../../../components/grid/Grid"; +import { SPACING } from "../../../../data/spacing"; +import { + Autocomplete, + Button, + FormControl, + FormControlLabel, + Radio, + RadioGroup, + TextField, + Typography, +} from "@mui/material"; +import { useDispatch, useSelector } from "react-redux"; +import { + slaughterSellCarcassOutProvinceGetBuyers, + slaughterSellCarcassOutProvinceSubmitSell, +} from "../../services/slaughter-sell-carcass-out-province-get-buyers"; +import { Formik, Form, Field } from "formik"; +import * as Yup from "yup"; +import { AppContext } from "../../../../contexts/AppContext"; +import moment from "moment"; +import { DRAWER } from "../../../../lib/redux/slices/appSlice"; +import { slaughterGetProductsService } from "../../services/slaughter-inventory-gets"; +import { NumberInput } from "../../../../components/number-format-custom/NumberFormatCustom"; +import { DatePicker } from "@mui/x-date-pickers"; +import { fetchSlaughterBroadcastAndProducts } from "../../services/handle-fetch-slaughter-products"; +import MonthlyDataCalendar from "../../../../components/date-picker/MonthlyDataCalendar"; +import PersianDate from "persian-date"; +import axios from "axios"; +import { LabelField } from "../../../../components/label-field/LabelField"; +import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl"; +import { checkPathStartsWith } from "../../../../utils/checkPathStartsWith"; + +const getValidationSchema = (selectedDateAmount, productionDate) => + Yup.object({ + weight_of_carcasses: Yup.number() + .required("وزن لاشه‌ها الزامی است") + .integer("عدد باید صحیح باشد!") + .positive("وزن باید عددی مثبت باشد") + .test( + "max-production-date-amount", + `وزن نمی‌تواند بیشتر از موجودی تاریخ تولید (${ + selectedDateAmount?.toLocaleString() || 0 + } کیلوگرم) باشد!`, + function (value) { + if (!selectedDateAmount || selectedDateAmount === null) return true; + return value <= selectedDateAmount; + } + ), + + clearance_code: Yup.string() + .required("کد قرنطینه الزامی است") + .matches( + /^(?=.*[A-Z])(?=.*\d)[A-Z0-9]+$/, + "کد قرنطینه باید ترکیبی از حروف بزرگ انگلیسی و عدد باشد" + ), + date: Yup.date() + .required("تاریخ الزامی است") + .test( + "date-not-before-production", + "تاریخ نمی‌تواند قبل از تاریخ تولید باشد", + function (value) { + if (!productionDate || !value) return true; + return moment(value).isSameOrAfter(moment(productionDate), "day"); + } + ), + }); + +export const SlaughterSellCarcassOutProvinceSellSubmitSell = ({ + updateTable, + fetchItems, + isInventory, +}) => { + const [buterData, setBuyerData] = useState([]); + const [buyerSelected, setBuyerSelected] = useState(null); + const [selectedInventory] = useState("free"); + const [approvedStatus, setApprovedStatus] = useState("governmental"); + const dispatch = useDispatch(); + + const [openNotif] = useContext(AppContext); + + const [selectedCalendarDate, setSelectedCalendarDate] = useState(null); + const [calendarDayData, setCalendarDayData] = useState({}); + const [productionDate, setProductionDate] = useState(null); + const [selectedDateAmount, setSelectedDateAmount] = useState(null); + const [calendarRawData, setCalendarRawData] = useState({ + governmental: [], + free: [], + }); + const { selectedSubUser } = useSelector((state) => state.userSlice); + const formikRef = useRef(null); + + useEffect(() => { + dispatch(slaughterSellCarcassOutProvinceGetBuyers()).then((r) => { + setBuyerData(r.payload.data); + }); + }, [dispatch]); + + const [productData, setProductData] = useState([]); + const [productKey, setProductKey] = useState(null); + + useEffect(() => { + dispatch( + slaughterGetProductsService({ + role_key: checkPathStartsWith("slaughter") + ? selectedSubUser?.key || "" + : "", + }) + ).then((r) => { + // Handle both direct array response and nested data response + const data = r.payload?.data; + if (Array.isArray(data)) { + setProductData(data); + } else if (data?.data && Array.isArray(data.data)) { + setProductData(data.data); + } else { + setProductData([]); + } + }); + }, [dispatch, selectedSubUser]); + + // const handleSellType = (event) => { + // const newType = event.target.value; + // setSelectedInventory(newType); + // }; + + const handleApprovedPrice = (event) => { + const newType = event.target.value; + setApprovedStatus(newType); + + // When governmental is selected, set date to today and disable DatePicker + if (newType === "governmental" && formikRef.current) { + const today = moment(new Date()).format("YYYY-MM-DD"); + formikRef.current.setFieldValue("date", today); + setSelectedFormDate(today); + fetchCalendarData(today); + } + }; + + const handleDateSelect = (dateInfo) => { + if (dateInfo && dateInfo.formattedDate) { + setSelectedCalendarDate(dateInfo.formattedDate); + + const data = calendarDayData[dateInfo.formattedDate]; + + if (data && data.originalDay) { + setProductionDate(data.originalDay); + } + + if (data && data.value1 !== undefined) { + setSelectedDateAmount(data.value1); + } else { + setSelectedDateAmount(null); + } + } + }; + + const transformCalendarData = useCallback((dataArray) => { + if (!Array.isArray(dataArray)) return {}; + + const transformedData = {}; + dataArray.forEach((item) => { + if (item.day && item.amount !== undefined) { + const persianDate = new PersianDate(new Date(item.day)); + const persianDateStr = persianDate.format("YYYY/MM/DD"); + transformedData[persianDateStr] = { + value1: item.amount, + originalDay: item.day, + active: item.active === true, // Store active status + }; + } + }); + return transformedData; + }, []); + + const updateCalendarData = useCallback( + (dataArray) => { + const transformed = transformCalendarData(dataArray); + setCalendarDayData(transformed); + }, + [transformCalendarData] + ); + + const [selectedFormDate, setSelectedFormDate] = useState( + moment(new Date()).format("YYYY-MM-DD") + ); + + const fetchCalendarData = useCallback( + async (dateParam = selectedFormDate) => { + try { + const response = await axios.get("/kill-house-remain-weight/", { + params: { + date: dateParam, + role: getRoleFromUrl(), + role_key: checkPathStartsWith("slaughter") + ? selectedSubUser?.key || "" + : "", + }, + }); + if (response.data) { + setCalendarRawData({ + governmental: response.data.governmental || [], + free: response.data.free || [], + }); + const dataToShow = + approvedStatus === "governmental" + ? response.data.governmental + : response.data.free; + updateCalendarData(dataToShow); + } + } catch (error) { + console.error("Error fetching calendar data:", error); + } + }, + [approvedStatus, updateCalendarData, selectedFormDate, selectedSubUser] + ); + + useEffect(() => { + fetchCalendarData(selectedFormDate); + }, [fetchCalendarData, selectedFormDate]); + + // When governmental is selected, set date to today + useEffect(() => { + if (approvedStatus === "governmental" && formikRef.current) { + const today = moment(new Date()).format("YYYY-MM-DD"); + formikRef.current.setFieldValue("date", today); + setSelectedFormDate(today); + fetchCalendarData(today); + } + }, [approvedStatus, fetchCalendarData]); + + useEffect(() => { + if ( + calendarRawData.governmental.length > 0 || + calendarRawData.free.length > 0 + ) { + const dataToShow = + approvedStatus === "governmental" + ? calendarRawData.governmental + : calendarRawData.free; + updateCalendarData(dataToShow); + setSelectedCalendarDate(null); + setProductionDate(null); + setSelectedDateAmount(null); + } + }, [approvedStatus, calendarRawData, updateCalendarData]); + + return ( + + + + option.disabled} + options={ + buterData + ? buterData.map((i) => ({ + id: i?.key, + label: `${i?.fullname} (${i.mobile}) / استان ${i.province} / شهر ${i.city}`, + item: i, + })) + : [] + } + onChange={(event, value) => { + setBuyerSelected(value?.id); + }} + renderInput={(params) => ( + + )} + /> + + + {buyerSelected && ( + <> + + 0 + ? productData.map((i) => { + return { + data: i, + label: `${i.name || ""}`, + }; + }) + : [] + } + onChange={(event, value) => { + setProductKey(value?.data || null); + }} + renderInput={(params) => ( + + )} + /> + + + { + dispatch( + slaughterSellCarcassOutProvinceSubmitSell({ + buyer_key: buyerSelected, + number_of_carcasses: + Math.round( + values?.weight_of_carcasses / productKey?.weightAverage + ) || 0, + weight_of_carcasses: parseInt(values.weight_of_carcasses), + date: values.date, + clearance_code: values.clearance_code, + product_key: productKey?.key, + sale_type: selectedInventory, + quota: approvedStatus, + production_date: productionDate, + distribution_type: "web", + }) + ).then((r) => { + if (r.payload.error) { + openNotif({ + vertical: "top", + horizontal: "center", + msg: r.payload.error, + severity: "error", + }); + } else { + if (isInventory) { + fetchItems(); + } else { + updateTable(); + } + dispatch(fetchSlaughterBroadcastAndProducts()); + dispatch( + DRAWER({ right: false, bottom: false, content: null }) + ); + openNotif({ + vertical: "top", + horizontal: "center", + msg: "عملیات با موفقیت انجام شد.", + severity: "success", + }); + } + }); + }} + > + {({ values, errors, touched, setFieldValue }) => ( +
    + + + + + + + + } + label="دولتی" + /> + } + label="آزاد" + /> + + + + + { + const formatted = + moment(newValue).format("YYYY-MM-DD"); + setFieldValue("date", formatted); + // Keep a mirrored local state to drive calendar fetches + setSelectedFormDate(formatted); + fetchCalendarData(formatted); + }} + renderInput={(params) => ( + + )} + /> + + + + setFieldValue( + "clearance_code", + e.target.value.toUpperCase() + ) + } + error={ + touched.clearance_code && + Boolean(errors.clearance_code) + } + helperText={ + touched.clearance_code && errors.clearance_code + } + /> + + {/* + + + } + label="قیمت دولتی" + /> + } + label="قیمت آزاد" + /> + + + */} + + + + {productionDate && + values.date && + moment(productionDate).isAfter( + moment(values.date), + "day" + ) && ( + + تاریخ تولید نمی‌تواند بعد از تاریخ انتخابی باشد + + )} + + + + {({ field, form, meta }) => ( + selectedDateAmount) + } + onChange={(e) => { + const value = e.target.value; + if ( + value === "" || + value === null || + value === undefined + ) { + form.setFieldValue("weight_of_carcasses", ""); + return; + } + const intValue = Math.floor(Number(value)); + if (intValue > 0) { + form.setFieldValue( + "weight_of_carcasses", + intValue + ); + } else if (intValue === 0) { + form.setFieldValue("weight_of_carcasses", ""); + } + }} + onBlur={field.onBlur} + helperText={ + selectedDateAmount && + field.value > selectedDateAmount + ? `وزن نمی‌تواند بیشتر از موجودی تاریخ تولید (${selectedDateAmount?.toLocaleString()} کیلوگرم) باشد!` + : meta.touched && meta.error + } + /> + )} + + + + + + + + + + + +
    + )} +
    + + )} +
    +
    + ); +}; diff --git a/src/features/slaughter-house/components/slaughter-sell-carcass-out-province/SlaughterSellCarcassOutProvince.js b/src/features/slaughter-house/components/slaughter-sell-carcass-out-province/SlaughterSellCarcassOutProvince.js new file mode 100644 index 0000000..111da97 --- /dev/null +++ b/src/features/slaughter-house/components/slaughter-sell-carcass-out-province/SlaughterSellCarcassOutProvince.js @@ -0,0 +1,94 @@ +import React, { useEffect, useState } from "react"; +import { Grid } from "../../../../components/grid/Grid"; +import { SPACING } from "../../../../data/spacing"; +import { Box, Tab, Tabs } from "@mui/material"; +import { SlaughterSellCarcassOutProvinceBuyers } from "../slaughter-sell-carcass-out-province-buyers/SlaughterSellCarcassOutProvinceBuyers"; +import { SlaughterSellCarcassOutProvinceSell } from "../slaughter-sell-carcass-out-province-sell/SlaughterSellCarcassOutProvinceSell"; +import { useDispatch, useSelector } from "react-redux"; +import { getKillhouseApprovedPriceState } from "../../../province/services/get-approved-price-state"; +import { SlaughterShowProducts } from "../slaughter-show-products/SlaughterShowProducts"; +import { fetchSlaughterBroadcastAndProducts } from "../../services/handle-fetch-slaughter-products"; +import { checkPathStartsWith } from "../../../../utils/checkPathStartsWith"; + +export const SlaughterSellCarcassOutProvincePage = () => { + const dispatch = useDispatch(); + const selectedSubUser = useSelector( + (state) => state.userSlice.selectedSubUser + ); + const [valueOutProvince, setValueOutProvince] = useState(0); + + const handleChangeTabsetOutProvince = (event, newValue) => { + setValueOutProvince(newValue); + }; + + const fetchData = () => { + dispatch( + fetchSlaughterBroadcastAndProducts({ + role_key: checkPathStartsWith("slaughter") + ? selectedSubUser?.key || "" + : "", + }) + ); + dispatch( + getKillhouseApprovedPriceState({ + role_key: checkPathStartsWith("slaughter") + ? selectedSubUser?.key || "" + : "", + }) + ); + }; + + useEffect(() => { + fetchData(); + }, [dispatch, selectedSubUser?.key]); + + return ( + + + + + + + + + + + + + + {valueOutProvince === 0 && ( + + )} + + {valueOutProvince === 1 && } + + + ); +}; diff --git a/src/features/slaughter-house/components/slaughter-sell-carcass/SlaughterSellCarcass.js b/src/features/slaughter-house/components/slaughter-sell-carcass/SlaughterSellCarcass.js new file mode 100644 index 0000000..24f592d --- /dev/null +++ b/src/features/slaughter-house/components/slaughter-sell-carcass/SlaughterSellCarcass.js @@ -0,0 +1,55 @@ +import React, { useEffect } from "react"; +import { Grid } from "../../../../components/grid/Grid"; +import { SPACING } from "../../../../data/spacing"; +import { useDispatch, useSelector } from "react-redux"; +import { ProvinceSellCarcassInProvince } from "../slaughter-sell-carcass-in-province/ProvinceSellCarcassInProvince"; +import { getKillhouseApprovedPriceState } from "../../../province/services/get-approved-price-state"; +import { SlaughterShowProducts } from "../slaughter-show-products/SlaughterShowProducts"; +import { fetchSlaughterBroadcastAndProducts } from "../../services/handle-fetch-slaughter-products"; +import { checkPathStartsWith } from "../../../../utils/checkPathStartsWith"; + +export const SlaughterSellCarcass = () => { + const dispatch = useDispatch(); + const selectedSubUser = useSelector( + (state) => state.userSlice.selectedSubUser + ); + const { priceInfo } = useSelector((state) => state.slaughterSlice); + + const fetchData = () => { + dispatch( + fetchSlaughterBroadcastAndProducts({ + role_key: checkPathStartsWith("slaughter") ? selectedSubUser?.key : "", + }) + ); + dispatch( + getKillhouseApprovedPriceState({ + role_key: checkPathStartsWith("slaughter") ? selectedSubUser?.key : "", + }) + ); + }; + + useEffect(() => { + fetchData(); + }, [dispatch, selectedSubUser?.key]); + + return ( + + + + + + + + ); +}; diff --git a/src/features/slaughter-house/components/slaughter-send-killer-invoice/SlaughterSendKillerInvoice.js b/src/features/slaughter-house/components/slaughter-send-killer-invoice/SlaughterSendKillerInvoice.js new file mode 100644 index 0000000..a8b28f8 --- /dev/null +++ b/src/features/slaughter-house/components/slaughter-send-killer-invoice/SlaughterSendKillerInvoice.js @@ -0,0 +1,331 @@ +import React, { forwardRef } from "react"; +import logo from "../../../../assets/images/ChickenLogo.png"; +import { useSystemName } from "../../../../utils/getSystemName"; +import { PropTypes } from "prop-types"; +import { formatJustDate } from "../../../../utils/formatTime"; +import ContentCutIcon from "@mui/icons-material/ContentCut"; +import { useCeoAddress } from "../../../../utils/getCeoAddress"; + +const styles = { + page: { + width: "210mm", + margin: "0 auto", + display: "flex", + flexDirection: "column", + position: "relative", + direction: "rtl", + fontFamily: "nazanin", + fontWeight: "bold", + }, + container: { + width: "95%", + alignSelf: "center", + pageBreakInside: "avoid", + }, + p: { + fontFamily: "nazanin", + fontWeight: "bold", + pAlign: "justify", + }, + span: { + fontFamily: "nazanin", + fontWeight: "bold", + pAlign: "justify", + }, + invoiceTable: { + width: "100%", + borderCollapse: "collapse", + alignSelf: "center", + }, + tableCell: { + border: "1px solid #000", + pAlign: "left", + textAlign: "center", + fontSize: 11, + }, + tableCellMobile: { + border: "1px solid #000", + pAlign: "left", + textAlign: "center", + fontSize: 10, + }, + tableInnerCell: { + border: "1px solid #000", + pAlign: "left", + textAlign: "center", + fontSize: 8, + whiteSpace: "nowrap", + }, + tableHeader: { + backgroundColor: "rgba(255, 229, 153, 0.5)", + pageBreakAfter: "auto", + }, + headerRow: { + backgroundColor: "rgba(255, 229, 153, 0.6)", + color: "black", + pageBreakInside: "avoid", + pageBreakAfter: "auto", + }, + logo: { + width: "60px", + height: "auto", + marginBottom: "10px", + }, + contentContainer: { + display: "flex", + justifyContent: "space-between", + marginTop: "20px", + marginLeft: "20px", + marginRight: "30px", + }, + contentInLine: { + display: "flex", + flexDirection: "column", + alignItems: "center", + }, + mainTitle: { + fontFamily: "nazanin", + fontSize: 11, + pAlign: "center", + fontWeight: "bolder", + }, + signature: { + display: "flex", + flexDirection: "column", + alignItems: "flex-end", + marginLeft: "20px", + }, + watermarkContainer: { + position: "fixed", + top: 450, + left: 0, + right: 30, + bottom: 0, + justifyContent: "center", + alignItems: "center", + opacity: 0.2, + zIndex: -1, + }, + watermarkp: { + fontSize: 100, + fontWeight: "bolder", + color: "grey", + transform: "rotate(-45deg)", + left: "50%", + }, + title: { + fontSize: 12, + fontWeight: "bolder", + pAlign: "center", + }, + titleTopic: { + marginTop: "10px", + fontSize: 12, + fontWeight: "bolder", + pAlign: "center", + }, + firsttitle: { + fontSize: 14, + fontWeight: "bolder", + marginLeft: "20px", + pAlign: "center", + }, + title2: { + fontSize: 10, + marginBottom: 10, + pAlign: "center", + }, + options: { + padding: "10px", + marginTop: "15px", + display: "flex", + flexDirection: "column", + alignItems: "flex-start", + }, + divider: { + width: "100%", + height: "2px", + backgroundColor: "red", + marginBottom: 15, + }, + divider2: { + width: "100%", + height: "1px", + background: `repeating-linear-gradient(90deg, transparent, transparent 5px, #f00 5px, #f00 10px)`, + }, + pTitleContainer: { + margin: "15px", + textAlign: "justify", + textJustify: "inter-word", + fontSize: "20px", + }, + tableHeaderCell: { + backgroundColor: "rgba(255, 229, 153, 0.5)", + fontSize: 10, + border: "1px solid #000", + padding: "4px", + textAlign: "center", + fontWeight: "bold", + }, + footer: { + pageBreakAfter: "always", + position: "fixed", + left: 0, + bottom: 0, + width: "100%", + }, + centerText: { + fontSize: "20px", + alignSelf: "center", + textAlign: "center", + }, + cutIcon: { + zIndex: 2, + transform: "rotate(180deg)", + opacity: "60%", + }, +}; + +const SlaughterSendKillerInvoice = forwardRef((props, ref) => { + const { date } = props; + const { amount } = props; + const { breeder } = props; + const { buyer } = props; + const systemName = useSystemName(); + const ceoAdress = useCeoAddress(); + + return ( +
    +
    +
    + logo + اتحادیه شرکتهاي تعاونی کشاورزي + + مرغداران {" ‌"} {systemName} + + ثبت : 5203 تاسیس : 1383 +
    + +
    + بسمه تعالی +
    + +
    + شماره: + تاریخ: {formatJustDate(date)} +
    +
    + +
    +

    سامانه رصدیار

    +
    + +
    + +

    + تاییدیه خریدار +

    + +

    + این حواله در تاریخ {" ‌"} {formatJustDate(date)} جهت بارگیري تعداد{" "} + {amount.toLocaleString()} قطعه مرغ زنده تحویل مرغداري {breeder} گردید. +
    +
    +
    +

    + + + + امضا خریدار آقا/خانم {buyer} + + +
    +
    + +
    + +
    +
    + +

    + مطابق برگ باسکول پیوستی، خروج تعداد {amount.toLocaleString()} قطعه به + وزن ......................... کیلوگرم در تاریخ {" ‌"} + {formatJustDate(date)} از مرغداري آقا/خانم + {" ‌"} + {breeder} + {" ‌"} مورد تایید اینجانب می باشد. +
    +
    +
    +

    + + + امضا خریدار آقا/خانم {buyer} + +
    + +
    + +
    +
    + +

    + تاییدیه مرغداری +

    + +

    + مطابق برگ باسکول پیوستی، خروج تعداد {amount.toLocaleString()} قطعه به + وزن ......................... کیلوگرم توسط آقا/خانم {" ‌"} + {buyer} + {" ‌"} مورد تائید اینجانب {" ‌"} + {breeder} + {" ‌"} مالک / نماینده قانونی مرغداری {" ‌"} + {breeder} + {" ‌"} باشد. +

    +
    + + + + مهر و امضا {breeder}{" "} + { + " ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌" + }{" "} + اثر انگشت + + +
    + +
    +
    +

    + {ceoAdress} +

    +
    +
    + ); +}); + +SlaughterSendKillerInvoice.displayName = "SlaughterSendKillerInvoice"; + +export default SlaughterSendKillerInvoice; + +SlaughterSendKillerInvoice.propTypes = { + item: PropTypes.any, +}; diff --git a/src/features/slaughter-house/components/slaughter-show-products/SlaughterShowProducts.js b/src/features/slaughter-house/components/slaughter-show-products/SlaughterShowProducts.js new file mode 100644 index 0000000..75d5a49 --- /dev/null +++ b/src/features/slaughter-house/components/slaughter-show-products/SlaughterShowProducts.js @@ -0,0 +1,250 @@ +import React, { useContext, useEffect, useState } from "react"; +import { useDispatch, useSelector } from "react-redux"; +import { Grid } from "../../../../components/grid/Grid"; +import ResponsiveTable from "../../../../components/responsive-table/ResponsiveTable"; +import { + Button, + FormControlLabel, + IconButton, + Radio, + RadioGroup, + TextField, + Tooltip, +} from "@mui/material"; +import SystemUpdateAltIcon from "@mui/icons-material/SystemUpdateAlt"; +import { CLOSE_MODAL, OPEN_MODAL } from "../../../../lib/redux/slices/appSlice"; +import { DatePicker } from "@mui/x-date-pickers"; +import moment from "moment"; +import { AppContext } from "../../../../contexts/AppContext"; +import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl"; +import axios from "axios"; +import { useLocation } from "react-router-dom"; +import { + ROUTE_SLAUGHTER_INVENTORY, + ROUTE_STEWARD_INVENTORY, +} from "../../../../routes/routes"; +import { checkPathStartsWith } from "../../../../utils/checkPathStartsWith"; + +export const SlaughterShowProducts = () => { + const { slaughterProducts, distributionInfo } = useSelector( + (state) => state.slaughterSlice + ); + + const [productsTable, setProductsTable] = useState(); + const { pathname } = useLocation(); + + const dispatch = useDispatch(); + + const getWeight = (item) => { + if (getRoleFromUrl() === "KillHouse") { + return [ + item?.totalGovernmentalCarcassesWeight?.toLocaleString(), + item?.provinceFreeCarcassesWeight?.toLocaleString(), + ]; + } else { + return [ + item?.receiveGovernmentalCarcassesWeight?.toLocaleString(), + item?.receiveFreeCarcassesWeight?.toLocaleString(), + ]; + } + }; + + useEffect(() => { + const d = slaughterProducts?.map((item, i) => { + return [ + i + 1, + item?.name, + ...getWeight(item), + item?.freeBuyingCarcassesWeight?.toLocaleString(), + item?.totalCarcassesWeight?.toLocaleString(), + item?.realAllocatedWeight?.toLocaleString(), + item?.totalRemainWeight?.toLocaleString(), + distributionInfo?.totalGovernmentalRemainWeight?.toLocaleString(), + distributionInfo?.totalFreeRemainWeight?.toLocaleString(), + distributionInfo?.totalGovernmentalInputWeight?.toLocaleString(), + distributionInfo?.totalFreeInputWeight?.toLocaleString(), + ]; + }); + + setProductsTable(d); + }, [slaughterProducts, distributionInfo]); + + const getDistributionKeys = () => { + if ( + pathname === ROUTE_SLAUGHTER_INVENTORY || + pathname === ROUTE_STEWARD_INVENTORY + ) { + return []; + } else { + return [ + "مانده دولتی (کیلوگرم)", + " مانده آزاد (کیلوگرم)", + "وزن دولتی (کیلوگرم)", + "وزن آزاد (کیلوگرم)", + ]; + } + }; + + return ( + + + {getRoleFromUrl() === "KillHouse" && ( + + { + dispatch( + OPEN_MODAL({ + title: "دریافت خروجی اکسل", + content: , + }) + ); + }} + > + + + + )} + + } + title={"موجودی انبار"} + columns={[ + "ردیف", + "نام محصول", + "وزن خریدهای دولتی داخل استان (کیلوگرم)", + "وزن خریدهای آزاد داخل استان (کیلوگرم)", + "وزن خریدهای خارج استان (کیلوگرم)", + "کل ورودی به انبار (کیلوگرم)", + "کل فروش (کیلوگرم)", + "مانده انبار (کیلوگرم)", + ...getDistributionKeys(), + ]} + data={productsTable} + customColors={[ + { name: "ردیف", color: "red" }, + { name: "نام محصول", color: "red" }, + { name: "کل ورودی به انبار (کیلوگرم)", color: "red" }, + { name: "وزن خریدهای دولتی داخل استان (کیلوگرم)", color: "red" }, + { name: "وزن خریدهای آزاد داخل استان (کیلوگرم)", color: "red" }, + { name: "وزن خریدهای خارج استان (کیلوگرم)", color: "red" }, + { name: "کل فروش (کیلوگرم)", color: "red" }, + { name: "مانده انبار (کیلوگرم)", color: "green" }, + ]} + /> + + ); +}; + +const HandleDownloadInventoryData = () => { + const [downloadType, setDownloadType] = useState("withdate"); + const selectedSubUser = useSelector( + (state) => state.userSlice.selectedSubUser + ); + const handleChange = (event) => { + setDownloadType(event.target.value); + }; + + const userKey = useSelector((state) => state.userSlice.userProfile.key); + + const [selectedDate1, setSelectedDate1] = useState( + moment(new Date()).format("YYYY-MM-DD") + ); + const [selectedDate2, setSelectedDate2] = useState( + moment(new Date()).format("YYYY-MM-DD") + ); + + const dispatch = useDispatch(); + + const [openNotif] = useContext(AppContext); + return ( + + + } + label="دانلود بر اساس بازه" + /> + } + label="دانلود کلی" + /> + + + {downloadType === "withdate" && ( + + + ( + + )} + value={selectedDate1} + onChange={(e) => { + setSelectedDate1(moment(e).format("YYYY-MM-DD")); + }} + /> + + + ( + + )} + value={selectedDate2} + onChange={(e) => { + setSelectedDate2(moment(e).format("YYYY-MM-DD")); + }} + /> + + + )} + + + + ); +}; diff --git a/src/features/slaughter-house/components/slaughter-stock-wrapper/SlaughterStockWrapper.js b/src/features/slaughter-house/components/slaughter-stock-wrapper/SlaughterStockWrapper.js new file mode 100644 index 0000000..ede007c --- /dev/null +++ b/src/features/slaughter-house/components/slaughter-stock-wrapper/SlaughterStockWrapper.js @@ -0,0 +1,16 @@ +import { Grid } from "../../../../components/grid/Grid"; +import { SlaughterInventory } from "../slaughter-inventory/SlaughterInventory"; + +export const SlaughterStockWrapper = () => { + return ( + + + + ); +}; diff --git a/src/features/slaughter-house/components/slaughter-stock/SlaughterStock.js b/src/features/slaughter-house/components/slaughter-stock/SlaughterStock.js new file mode 100644 index 0000000..9d4392d --- /dev/null +++ b/src/features/slaughter-house/components/slaughter-stock/SlaughterStock.js @@ -0,0 +1,584 @@ +import { + Accordion, + AccordionDetails, + AccordionSummary, + Box, + Button, + FormControl, + IconButton, + InputLabel, + MenuItem, + Select, + TextField, + Tooltip, + Typography, +} from "@mui/material"; +import { DatePicker } from "@mui/x-date-pickers"; +import ExpandMoreIcon from "@mui/icons-material/ExpandMore"; +import moment from "moment/moment"; +import { useContext, useEffect, useState } from "react"; +import { useDispatch, useSelector } from "react-redux"; +import { AdvancedTable } from "../../../../components/advanced-table/AdvancedTable"; +import { Grid } from "../../../../components/grid/Grid"; +import { SimpleTable } from "../../../../components/simple-table/SimpleTable"; +import { AppContext } from "../../../../contexts/AppContext"; +import { SPACING } from "../../../../data/spacing"; +import { DRAWER, OPEN_MODAL } from "../../../../lib/redux/slices/appSlice"; +import { formatJustDate } from "../../../../utils/formatTime"; +import { slaughterGetInventoryStock } from "../../services/salughter-get-inventory-stock"; +import { slaughterGetInventoryFreeBarsService } from "../../services/slaughter-get-inventory-free-bars"; +import { slaughterInventoryBarsService } from "../../services/slaughter-inventory-bars"; +import { SlaughterFreeBarsOperations } from "../slaughter-free-bars-operations/SlaughterFreeBarsOperations"; +import { SlaughterSubmitFreeBar } from "../slaughter-submit-free-bar/SlaughterSubmitFreeBar"; +import { setInventorySelectedKillHouse } from "../../../../lib/redux/slices/slaughterSlice"; +import axios from "axios"; +import { RiFileExcel2Fill } from "react-icons/ri"; +import KeyboardDoubleArrowUpIcon from "@mui/icons-material/KeyboardDoubleArrowUp"; +import KeyboardDoubleArrowDownIcon from "@mui/icons-material/KeyboardDoubleArrowDown"; +import { SlaughterSubmitRealInventory } from "../slaughter-submit-real-inventory/SlaughterSubmitRealInventory"; +import SettingsIcon from "@mui/icons-material/Settings"; +import BoxList from "../../../../components/box-list/BoxList"; +import { RespSlaughterStockBarSystem } from "../resp-slaughter-stock-bar-system/RespSlaughterStockBarSystem"; +export const SlaughterStock = () => { + const [expanded, setExpanded] = useState("panel1"); + + const handleChange = (panel) => (event, isExpanded) => { + setExpanded(isExpanded ? panel : false); + }; + + const dispatch = useDispatch(); + const [freeBarsDataTable, setFreeBarsDataTable] = useState([]); + const [inventoryBarsDataTable, setInventoryBarsDataTable] = useState([]); + const { + slaughterGetInventoryStockData, + inventorySelectedKillHouse, + slaughterGetInventoryFreeBars, + slaughterInventoryBars, + profile, + } = useSelector((state) => state.slaughterSlice); + const [, , selectedDate1, setSelectedDate1] = useContext(AppContext); + const handleChangeInventory = (event) => { + dispatch(setInventorySelectedKillHouse(event.target.value)); + }; + + const updateTable = () => { + dispatch( + slaughterGetInventoryStock({ + date: selectedDate1, + kill_house_key: inventorySelectedKillHouse, + }) + ); + dispatch( + slaughterGetInventoryFreeBarsService({ + selectedDate1, + kill_house_key: inventorySelectedKillHouse, + }) + ); + dispatch( + slaughterInventoryBarsService({ + selectedDate1, + kill_house_key: inventorySelectedKillHouse, + }) + ); + }; + + useEffect(() => { + updateTable(); + }, [selectedDate1, inventorySelectedKillHouse]); + + useEffect(() => { + const d = slaughterGetInventoryFreeBars?.map((item) => { + return [ + item.poultryName, + item.buyType === "live" ? "مرغ زنده" : "کشتار شده", + `${item.province}/${item.city}`, + formatJustDate(item.date), + item.vetFarmName + ? `${item.vetFarmName} (${item.vetFarmMobile})` + : "ندارد", + item.car, + `${item.driverName} (${item.driverMobile})`, + item.barClearanceCode, + item.quantity.toLocaleString(), + item.liveWeight.toLocaleString(), + item.numberOfCarcasses.toLocaleString(), + item.weightOfCarcasses.toLocaleString(), + + doc + , + + , + ]; + }); + setFreeBarsDataTable(d); + }, [slaughterGetInventoryFreeBars]); + + useEffect(() => { + const d = slaughterInventoryBars?.map((item, i) => { + let state = ""; + if (item.assignmentState === "no_state") { + state = "وارد کردن اطلاعات بار"; + } else if (item.assignmentState === "accepted") { + state = "تایید نهایی"; + } else if (item.assignmentState === "pending") { + state = "در انتظار تایید تخلیه"; + } + // const assignmentRealQuantity = + // item.assignmentState === "rejected" + // ? "-" + // : item.assignmentRealQuantity?.toLocaleString(); + + return [ + item.barCode, + item.poultryName, + item.killHouseName, + item.poultryReqOrderCode, + item?.freezing ? "انجماد" : item?.export ? "صادرات" : "عادی", + item.poultryCity, + formatJustDate(item.date), + item.chickenBreed, + item.vetName ? `${item.vetName} (${item.vetMobile})` : "ندارد", + item.killHouseVetName + ? `${item.killHouseVetName} (${item.killHouseVetMobile})` + : "ندارد", + `${item.driverName}/${item.typeCar}`, + item.trafficCode, + item.barClearanceCode ? item.barClearanceCode : "-", + item?.assignmentRealQuantity?.toLocaleString(), + item?.assignmentNetWeight?.toLocaleString(), + state, + item?.wareHouseAcceptedRealQuantity.toLocaleString(), + item?.wareHouseAcceptedRealWeight.toLocaleString(), + item?.weightLoss + "%", + + { + dispatch( + OPEN_MODAL({ + title: "ثبت موجودی واقعی", + content: ( + + ), + }) + ); + }} + > + + + , + ]; + }); + setInventoryBarsDataTable(d); + }, [slaughterInventoryBars]); + + const invenotryStockData = () => { + let data = []; + if ( + slaughterGetInventoryStockData?.updatedWeightOfCarcasses || + slaughterGetInventoryStockData?.updatedNumberOfCarcasses + ) { + data = [ + [ + "سیستمی:", + slaughterGetInventoryStockData?.barQuantity.toLocaleString(), + slaughterGetInventoryStockData?.allocatedQuantity.toLocaleString(), + slaughterGetInventoryStockData?.barLiveWeight.toLocaleString(), + slaughterGetInventoryStockData?.numberOfCarcasses.toLocaleString(), + Number( + slaughterGetInventoryStockData?.weightOfCarcasses.toFixed(0) + ).toLocaleString(), + slaughterGetInventoryStockData?.aveWeightOfCarcasses.toFixed(2), + slaughterGetInventoryStockData?.freeBarQuantity.toLocaleString(), + slaughterGetInventoryStockData?.numberOfFreeCarcasses.toLocaleString(), + slaughterGetInventoryStockData?.freeWeightOfCarcasses.toLocaleString(), + slaughterGetInventoryStockData?.totalBarQuantity.toLocaleString(), + slaughterGetInventoryStockData?.totalNumberOfCarcasses.toLocaleString(), + slaughterGetInventoryStockData?.totalWeightOfCarcasses.toLocaleString(), + ], + [ + "ویرایش:", + slaughterGetInventoryStockData?.barQuantity.toLocaleString(), + slaughterGetInventoryStockData?.allocatedQuantity.toLocaleString(), + slaughterGetInventoryStockData?.barLiveWeight.toLocaleString(), + + {slaughterGetInventoryStockData?.updatedNumberOfCarcasses.toLocaleString()} + {slaughterGetInventoryStockData?.updatedNumberOfCarcasses > + slaughterGetInventoryStockData?.numberOfCarcasses ? ( + + ) : ( + + )} + , + + {Number( + slaughterGetInventoryStockData?.updatedWeightOfCarcasses.toFixed( + 0 + ) + ).toLocaleString()}{" "} + {slaughterGetInventoryStockData?.updatedWeightOfCarcasses > + slaughterGetInventoryStockData?.weightOfCarcasses ? ( + + ) : ( + + )} + , + + + {Number( + slaughterGetInventoryStockData?.updateAveWeightOfCarcasses.toFixed( + 2 + ) + ).toLocaleString()} + {slaughterGetInventoryStockData?.updateAveWeightOfCarcasses > + slaughterGetInventoryStockData?.aveWeightOfCarcasses ? ( + + ) : ( + + )} + , + slaughterGetInventoryStockData?.freeBarQuantity.toLocaleString(), + slaughterGetInventoryStockData?.numberOfFreeCarcasses.toLocaleString(), + slaughterGetInventoryStockData?.freeWeightOfCarcasses.toLocaleString(), + "سسس", + "سسس", + slaughterGetInventoryStockData?.totalBarQuantity.toLocaleString(), + + {Number( + slaughterGetInventoryStockData?.updateTotalNumberOfCarcasses + ).toLocaleString()} + {slaughterGetInventoryStockData?.updateTotalNumberOfCarcasses > + slaughterGetInventoryStockData?.totalNumberOfCarcasses ? ( + + ) : ( + + )} + , + + {Number( + slaughterGetInventoryStockData?.updateTotalWeightOfCarcasses + ).toLocaleString()} + {slaughterGetInventoryStockData?.updateTotalWeightOfCarcasses > + slaughterGetInventoryStockData?.totalWeightOfCarcasses ? ( + + ) : ( + + )} + , + ], + ]; + } else { + data = [ + [ + "سیستمی:", + slaughterGetInventoryStockData?.barQuantity.toLocaleString(), + slaughterGetInventoryStockData?.allocatedQuantity.toLocaleString(), + slaughterGetInventoryStockData?.barLiveWeight.toLocaleString(), + slaughterGetInventoryStockData?.numberOfCarcasses.toLocaleString(), + Number( + slaughterGetInventoryStockData?.weightOfCarcasses.toFixed(0) + ).toLocaleString(), + slaughterGetInventoryStockData?.aveWeightOfCarcasses.toFixed(2), + slaughterGetInventoryStockData?.freeBarQuantity.toLocaleString(), + slaughterGetInventoryStockData?.numberOfFreeCarcasses.toLocaleString(), + slaughterGetInventoryStockData?.freeWeightOfCarcasses.toLocaleString(), + slaughterGetInventoryStockData?.preColdNumberOfCarcassesToWareHouse.toLocaleString(), + slaughterGetInventoryStockData?.preColdWeightOfCarcassesToWareHouse.toLocaleString(), + slaughterGetInventoryStockData?.totalBarQuantity.toLocaleString(), + slaughterGetInventoryStockData?.totalNumberOfCarcasses.toLocaleString(), + slaughterGetInventoryStockData?.totalWeightOfCarcasses.toLocaleString(), + ], + ]; + } + return data; + }; + + const [inventoryDate, setInventoryDate] = useState(new Date(selectedDate1)); + + useEffect(() => { + const tempDate = new Date(inventoryDate); + tempDate.setDate(new Date(selectedDate1).getDate() - 1); + setInventoryDate(tempDate); + }, [selectedDate1]); + + const isMobile = window.innerWidth <= 600; + + return ( + + + + + کشتارگاه + + + + + ( + + )} + value={selectedDate1} + onChange={(e) => { + setSelectedDate1(moment(e).format("YYYY-MM-DD")); + }} + /> + + {isMobile ? ( + + + + ) : ( + + + + موجودی انبار تاریخ کشتار {formatJustDate(inventoryDate)} + + + + + + + + + {/* */} + + + + } + columns={[ + "اطلاعات", + "تعداد بار", + "قطعه بار زنده", + "وزن بار زنده (کیلوگرم)", + "حجم لاشه استحصالی", + "وزن لاشه ها استحصالی(کیلوگرم) ", + "میانگین وزن لاشه ها (کیلوگرم)", + "تعداد بار (خرید آزاد)", + "حجم لاشه (خرید آزاد)", + "وزن لاشه (خرید آزاد) (کیلوگرم)", + "قطعه پیش سرد", + "وزن پیش سرد", + "مجموع بارها", + "مجموع لاشه ها", + "مجموع وزن لاشه ها (کیلوگرم)", + ]} + data={invenotryStockData()} + /> + )} + + + + } + aria-controls="panel1bh-content" + id="panel1bh-header" + > + + اطلاعات بارهای سیستمی + + ({inventoryBarsDataTable?.length} مورد) + + + + + {isMobile ? ( + + ) : ( + + )} + + + + } + aria-controls="panel1bh-content" + id="panel1bh-header" + style={{ + alignItems: "center", + justifyContent: "center", + display: "flex", + }} + > + + اطلاعات بارهای آزاد + + ({freeBarsDataTable?.length} مورد) + + + + + + + + + + ); +}; diff --git a/src/features/slaughter-house/components/slaughter-submit-chicken-price/SlaughterSubmitChickenPrice.js b/src/features/slaughter-house/components/slaughter-submit-chicken-price/SlaughterSubmitChickenPrice.js new file mode 100644 index 0000000..9c07a7d --- /dev/null +++ b/src/features/slaughter-house/components/slaughter-submit-chicken-price/SlaughterSubmitChickenPrice.js @@ -0,0 +1,136 @@ +import React, { useContext } from "react"; +import { TextField, Button, Typography, Divider } from "@mui/material"; +import { useFormik } from "formik"; +import * as Yup from "yup"; +import { useDispatch, useSelector } from "react-redux"; +import { AppContext } from "../../../../contexts/AppContext"; +import { slaughterEditChickenPriceService } from "../../services/slaughter-edit-chicken-price"; +import { CLOSE_MODAL } from "../../../../lib/redux/slices/appSlice"; +import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl"; +import { Grid } from "../../../../components/grid/Grid"; +import { checkPathStartsWith } from "../../../../utils/checkPathStartsWith"; + +export const SlaughterSubmitChickenPrice = ({ fetchData, item }) => { + const dispatch = useDispatch(); + const selectedSubUser = useSelector( + (state) => state.userSlice.selectedSubUser + ); + const [openNotif] = useContext(AppContext); + + const formik = useFormik({ + initialValues: { + chickenPrice: "", + }, + validationSchema: Yup.object({ + chickenPrice: Yup.number() + .required("این فیلد اجباری است!") + .positive("مقدار مثبت وارد کنید!") + .typeError("لطفا عدد وارد کنید!") + .min( + item?.freeSaleInProvince ? 400000 : (item?.amount / 100) * 40, + item?.freeSaleInProvince + ? "حداقل قیمت قابل ثبت چهل هزار تومان است!" + : "اختلاف قیمت وارد شده و قیمت مرغدار باید کمتر از شصت درصد باشد!" + ) + .max( + item?.freeSaleInProvince + ? 2000000 + : (item?.amount / 100) * 60 + item?.amount, + item?.freeSaleInProvince + ? "قیمت متعارف وارد کنید!" + : "اختلاف قیمت وارد شده و قیمت مرغدار باید کمتر از شصت درصد باشد!" + ), + }), + onSubmit: (values) => { + dispatch( + slaughterEditChickenPriceService({ + province_kill_request_key: item?.provinceKillReqKey, + kill_house_price: values.chickenPrice, + role: getRoleFromUrl(), + role_key: checkPathStartsWith("slaughter") + ? selectedSubUser?.key || "" + : "", + }) + ).then((r) => { + if (r.payload.error) { + openNotif({ + vertical: "top", + horizontal: "center", + msg: r.payload.error, + severity: "error", + }); + } else { + openNotif({ + vertical: "top", + horizontal: "center", + msg: "عملیات با موفقیت انجام شد.", + severity: "success", + }); + dispatch(CLOSE_MODAL()); + fetchData(); + } + }); + }, + }); + + return ( +
    + + اطلاعات سفارش + + + + + + نام مرغدار: + + + {`${item.poultryName} (${item.poultryMobile})`} + + + + + + قیمت مرغدار: + + + {item.amount.toLocaleString() + " ﷼"} + + + + + میانگین وزنی: + + + {item?.indexWeight + " کیلوگرم"} + + + + + حجم تخصیص: + + + {item.mainQuantity.toLocaleString() + " قطعه"} + + + + + + + ); +}; diff --git a/src/features/slaughter-house/components/slaughter-submit-export/SlaughterSubmitExport.js b/src/features/slaughter-house/components/slaughter-submit-export/SlaughterSubmitExport.js new file mode 100644 index 0000000..103ceb6 --- /dev/null +++ b/src/features/slaughter-house/components/slaughter-submit-export/SlaughterSubmitExport.js @@ -0,0 +1,602 @@ +import { + Autocomplete, + Button, + CircularProgress, + FormControl, + InputAdornment, + InputLabel, + MenuItem, + Select, + TextField, + Typography, +} from "@mui/material"; +import { DatePicker } from "@mui/x-date-pickers"; +import { useFormik } from "formik"; +import moment from "moment/moment"; +import { useContext, useEffect, useState } from "react"; +import { useDispatch, useSelector } from "react-redux"; +import { Grid } from "../../../../components/grid/Grid"; +import { NumberInput } from "../../../../components/number-format-custom/NumberFormatCustom"; +import { AppContext } from "../../../../contexts/AppContext"; +import { SPACING } from "../../../../data/spacing"; +import { DRAWER } from "../../../../lib/redux/slices/appSlice"; +import { Yup } from "../../../../lib/yup/yup"; +import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl"; +import { slaughterGetKillerKillhousesService } from "../../../slaughter-house/services/slaughter-get-killers-killhouses"; +import { slaughterGetPoultriesService } from "../../services/salughter-get-poultries"; +import { slaughterEditFreeBuyService } from "../../services/slaughter-edit-free-buy"; +import { slaughterGetProfile } from "../../services/slaughter-get-profile"; +import { slaughterSubmitFreeBuyPostService } from "../../services/slaughter-submit-free-buy-post"; +import { slaughterGetKillhousesService } from "../../services/slaughter-get-killhouses"; +import { slaughterGetCountries } from "../../services/slaughter-get-countries"; +import { checkPathStartsWith } from "../../../../utils/checkPathStartsWith"; + +export const SlaughterSubmitExport = ({ edit, updateTable, item }) => { + const [selectedAge1, setSelectedAge1] = useState(1); + const [selectedAge2, setSelectedAge2] = useState(1); + const dispatch = useDispatch(); + const [openNotif] = useContext(AppContext); + const [maxAllowed, setMaxAllowed] = useState(0); + const [isKiller, setIsKiller] = useState(false); + const [countries, setCountries] = useState([]); + const [selectedCountry, setSelectedCountry] = useState( + item?.exportCountry ? item?.exportCountry : "" + ); + const selectedSubUser = useSelector( + (state) => state.userSlice.selectedSubUser + ); + const { + slaughterGetPoultries, + slaughterGetKillerKillhouses, + slaughterGetKillhouses, + } = useSelector((state) => state.slaughterSlice); + + useEffect(() => { + dispatch( + slaughterGetPoultriesService({ + role_key: checkPathStartsWith("slaughter") + ? selectedSubUser?.key || "" + : "", + }) + ); + dispatch( + slaughterGetKillerKillhousesService({ + role_key: checkPathStartsWith("slaughter") + ? selectedSubUser?.key || "" + : "", + }) + ); + dispatch( + slaughterGetProfile({ + role_key: checkPathStartsWith("slaughter") + ? selectedSubUser?.key || "" + : "", + }) + ); + dispatch( + slaughterGetKillhousesService({ + role_key: checkPathStartsWith("slaughter") + ? selectedSubUser?.key || "" + : "", + }) + ); + dispatch( + slaughterGetCountries({ + role_key: checkPathStartsWith("slaughter") + ? selectedSubUser?.key || "" + : "", + }) + ).then((r) => { + setCountries(r.payload.data); + }); + }, [selectedSubUser?.key]); + + const initialValues = { + killhouse: null, + killerPlace: null, + poultry: null, + killDate: item ? new Date(item.createDate) : new Date(), + numberForBuy: item ? item.killCapacity : null, + indexWeight: item ? item.IndexWeight : "", + }; + + const onSubmit = (values) => { + dispatch( + slaughterSubmitFreeBuyPostService({ + kill_capacity: values.numberForBuy, + recive_time: "12 - 14", + recive_date: values.killDate, + low_weight: false, + high_weight: false, + Index_weight: values.indexWeight, + chicken_breed: formik?.values?.poultry?.item?.hatchingAge?.breed, + cash: true, + credit: false, + sms_payment: false, + kill_house_key: values.killhouse, + killer_kill_house_key: values.killerPlace ? values.killerPlace : null, + role: getRoleFromUrl(), + poultry_key: formik?.values?.poultry?.value, + export_status: true, + export_country: selectedCountry, + }) + ).then((r) => { + if (r.payload.error) { + openNotif({ + vertical: "top", + horizontal: "center", + msg: r.payload.error, + severity: "error", + }); + } else { + updateTable(); + openNotif({ + vertical: "top", + horizontal: "center", + msg: "عملیات با موفقیت انجام شد.", + severity: "success", + }); + dispatch( + DRAWER({ + right: false, + bottom: false, + left: false, + content: null, + }) + ); + } + }); + }; + + useEffect(() => { + if (item) { + setMaxAllowed( + item?.poultry?.lastHatchingDiffrentRequestQuantity + ?.leftExportQuantity === null + ? item.poultry?.lastHatchingDiffrentRequestQuantity + ?.lastHatchingRemainQuantity + : item?.poultry?.lastHatchingDiffrentRequestQuantity + ?.leftExportQuantity + ); + } + }, []); + + const validationSchema = Yup.object().shape({ + killhouse: Yup.string("") + .typeError("این فیلد الزامی است") + .required("این فیلد الزامی است"), + poultry: Yup.object("") + .typeError("این فیلد الزامی است") + .required("این فیلد الزامی است"), + numberForBuy: Yup.number() + .typeError("لطفا عدد وارد کنید") + .max(maxAllowed, "تعداد بیش از حد مجاز است") + .required("لطفا عدد وارد کنید") + .positive("لطفا عدد وارد کنید") + .integer("لطفا عدد وارد کنید"), + indexWeight: Yup.number() + .typeError("لطفا عدد وارد کنید") + .required("لطفا عدد وارد کنید") + .positive("لطفا عدد وارد کنید"), + }); + + const formik = useFormik({ + initialValues, + validationSchema, + onSubmit, + }); + + useEffect(() => { + let newVal = formik.values.indexWeight; + const mystring = formik.values?.indexWeight + ?.toString() + ?.split(".") + ?.join(""); + if (formik.values.indexWeight) { + if (mystring.length <= 3) { + if (mystring.length === 2) { + newVal = mystring[0] + "." + mystring[1]; + } + if (mystring.length === 3) { + newVal = mystring[0] + "." + mystring[1] + mystring[2]; + } + } + } + if (isNaN(Number.parseFloat(newVal))) { + formik.setFieldValue("indexWeight", ""); + } else { + formik.setFieldValue("indexWeight", Number.parseFloat(newVal)); + } + }, [formik.values.indexWeight]); + + const handleSubmitSearchByAge = async (event) => { + event.preventDefault(); + + dispatch( + slaughterGetPoultriesService({ + min_age: selectedAge1 ? selectedAge1 : 1, + max_age: selectedAge2 ? selectedAge2 : 1, + role_key: checkPathStartsWith("slaughter") + ? selectedSubUser?.key || "" + : "", + }) + ); + }; + const handleSubmitSearchNoAge = async (event) => { + event.preventDefault(); + setSelectedAge1(1); + setSelectedAge2(1); + dispatch( + slaughterGetPoultriesService({ + role_key: checkPathStartsWith("slaughter"), + }) + ); + }; + + return ( +
    + + {!edit && ( + <> + {slaughterGetKillhouses?.length ? ( + { + const buyerNamePrefix = item?.killer ? "کشتارکن" : "کشتارگاه"; + return { + label: buyerNamePrefix + " " + item.name, + value: item.key, + killer: item.killer, + item: item, + disabled: item.allowDirectBuying, + }; + })} + getOptionDisabled={(option) => !option.disabled} + getOptionLabel={(option) => option.label} + onChange={(_, value) => { + setIsKiller(value.killer); + formik.setFieldValue("killhouse", value.value); + }} + onBlur={formik.handleBlur} + renderInput={(params) => ( + + )} + /> + ) : ( + + )} + + {isKiller && ( + { + return { + label: "کشتارگاه " + item.name, + value: item.key, + }; + })} + getOptionLabel={(option) => option.label} + onChange={(_, value) => + formik.setFieldValue("killerPlace", value.value) + } + onBlur={formik.handleBlur} + renderInput={(params) => ( + + )} + /> + )} + + + + { + setSelectedAge1(event.target.value); + }} + /> + + + { + setSelectedAge2(event.target.value); + }} + /> + + + + + + + + {slaughterGetPoultries?.length ? ( + { + return { + label: `${item.unitName} (${item.user.fullname}) سن: ${item.lastHatchingDiffrentRequestQuantity?.age} روز / نژاد: ${item.lastHatchingDiffrentRequestQuantity?.breed}`, + value: item.key, + item, + }; + })} + getOptionLabel={(option) => option.label} + onChange={(_, value) => { + formik.setFieldValue("poultry", value); + setMaxAllowed( + value?.item?.lastHatchingDiffrentRequestQuantity + ?.leftExportQuantity === null + ? value.item?.lastHatchingRemainQuantity + : value?.item?.lastHatchingDiffrentRequestQuantity + ?.leftExportQuantity + ); + }} + onBlur={formik.handleBlur} + renderInput={(params) => ( + + )} + /> + ) : ( + + موردی یافت نشد! + + )} + + {formik.values.poultry && ( + + + نام و نام خانوادگی: + + {formik?.values?.poultry?.item.user.fullname} + + + + تلفن: + + {formik?.values?.poultry?.item.user.mobile} + + + + آدرس: + + {`${formik?.values?.poultry?.item.address.province.name} - ${formik?.values?.poultry?.item.address.city.name} - ${formik?.values?.poultry?.item.address.address}`} + + + + سن جوجه: + + { + formik?.values?.poultry?.item + ?.lastHatchingDiffrentRequestQuantity?.age + }{" "} + روز + + + + مانده در سالن: + + {formik?.values?.poultry?.item?.lastHatchingRemainQuantity?.toLocaleString()}{" "} + قطعه + + + + مانده قابل صادرات: + + {maxAllowed?.toLocaleString()} قطعه + + + + {/* + نژاد: + + {formik?.values?.poultry?.item?.hatchingAge?.breed} + + */} + + )} + + )} + + } + value={formik.values.killDate} + error={ + formik.touched.killDate ? Boolean(formik.errors.killDate) : null + } + onChange={(e) => { + formik.setFieldValue( + "killDate", + moment(e).format("YYYY-MM-DD hh:mm:ss") + ); + }} + onBlur={formik.handleBlur} + helperText={ + formik.touched.killDate && Boolean(formik.errors.killDate) + ? formik.errors.killDate + : null + } + /> + + + کیلوگرم + ), + }} + error={ + formik.touched.indexWeight && Boolean(formik.errors.indexWeight) + } + helperText={formik.touched.indexWeight && formik.errors.indexWeight} + /> + + + کشور مقصد + + + + {!edit && ( + + )} + {edit && ( + + )} + +
    + ); +}; diff --git a/src/features/slaughter-house/components/slaughter-submit-free-bar/SlaughterSubmitFreeBar.js b/src/features/slaughter-house/components/slaughter-submit-free-bar/SlaughterSubmitFreeBar.js new file mode 100644 index 0000000..6d087ae --- /dev/null +++ b/src/features/slaughter-house/components/slaughter-submit-free-bar/SlaughterSubmitFreeBar.js @@ -0,0 +1,769 @@ +import { + Autocomplete, + Button, + FormControl, + FormControlLabel, + FormLabel, + InputAdornment, + Radio, + RadioGroup, + TextField, + Typography, +} from "@mui/material"; +import { useFormik } from "formik"; +import { useContext, useEffect, useState } from "react"; +import { useDispatch, useSelector } from "react-redux"; +import { Grid } from "../../../../components/grid/Grid"; +import { ImageUpload } from "../../../../components/image-upload/ImageUpload"; +import { AppContext } from "../../../../contexts/AppContext"; +import { SPACING } from "../../../../data/spacing"; +import { DRAWER } from "../../../../lib/redux/slices/appSlice"; +import { Yup } from "../../../../lib/yup/yup"; +import { fixBase64 } from "../../../../utils/toBase64"; +import { slaughterEditFreeSaleService } from "../../services/slaughter-edit-free-sale"; +import { slaughterSubmitFreeSaleService } from "../../services/slaughter-submit-free-sale"; +import { + slaughterGetExclusiveKillersService, + slaughterGetProductsService, +} from "../../services/slaughter-inventory-gets"; +import moment from "moment"; +import { + slaughterGetCitiesService, + slaughterGetProvinceService, +} from "../../services/slaughter-get-provinces"; +import { CarPelak } from "../../../../components/car-pelak/CarPelak"; +import { checkPathStartsWith } from "../../../../utils/checkPathStartsWith"; + +const ValidationSchemaAlive = Yup.object().shape({ + poultry_name: Yup.string().required("نام مرغدار الزامی است"), + poultry_mobile: Yup.string() + .required("شماره موبایل مرغدار الزامی است") + .min(11, "شماره موبایل باید 11 رقم باشد") + .max(11, "شماره موبایل باید 11 رقم باشد") + .matches(/^09\d{9}$/, "شماره موبایل باید با 09 شروع شود و 11 رقم باشد"), + province: Yup.string().required("استان الزامی است"), + city: Yup.string().required("شهر الزامی است"), + clearance_code: Yup.string().required("کد قرنطینه الزامی است"), + quantity: Yup.number() + .required("تعداد الزامی است") + .min(1, "تعداد باید بیشتر از 0 باشد"), + live_weight: Yup.number() + .required("وزن الزامی است") + .min(0.01, "وزن باید بیشتر از 0 باشد"), + bar_image: Yup.string().required("عکس بار الزامی است"), +}); + +const ValidationSchemaCarcass = Yup.object().shape({ + poultry_name: Yup.string().required("نام مرغدار الزامی است"), + poultry_mobile: Yup.string() + .required("شماره موبایل مرغدار الزامی است") + .min(11, "شماره موبایل باید 11 رقم باشد") + .max(11, "شماره موبایل باید 11 رقم باشد") + .matches(/^09\d{9}$/, "شماره موبایل باید با 09 شروع شود و 11 رقم باشد"), + province: Yup.string().required("استان الزامی است"), + city: Yup.string().required("شهر الزامی است"), + clearance_code: Yup.string().required("کد قرنطینه الزامی است"), + bar_image: Yup.string().required("عکس بار الزامی است"), + number_of_carcasses: Yup.number() + .required("حجم لاشه الزامی است") + .min(1, "حجم لاشه باید بیشتر از 0 باشد"), + weight_of_carcasses: Yup.number() + .required("وزن لاشه الزامی است") + .min(0.01, "وزن باید بیشتر از 0 باشد"), +}); + +const DriverSchema = Yup.object().shape({ + driverName: Yup.string(), + driverMobile: Yup.string() + .min(11, "شماره موبایل باید 11 رقم باشد") + .max(11, "شماره موبایل باید 11 رقم باشد") + .matches(/^09\d{9}$/, "شماره موبایل باید با 09 شروع شود و 11 رقم باشد"), +}); + +const ProvinceCityFields = ({ formik, cities, provinces, isEdit }) => ( + <> + ({ id: p.name, label: p.name }))} + value={ + formik.values.province + ? { id: formik.values.province, label: formik.values.province } + : null + } + onChange={(e, value) => { + formik.setFieldValue("province", value ? value.id : ""); + formik.setFieldValue("city", ""); + }} + renderInput={(params) => ( + + )} + /> + + {isEdit && ( + + استان: {formik.values.province} + + )} + + ({ id: c.name, label: c.name }))} + value={ + formik.values.city + ? { id: formik.values.city, label: formik.values.city } + : null + } + onChange={(e, value) => { + formik.setFieldValue("city", value ? value.id : ""); + }} + renderInput={(params) => ( + + )} + /> + + {isEdit && ( + + شهر: {formik.values.city} + + )} + +); + +const AliveFormSection = ({ formik, cities, provinces, isEdit, item }) => ( + <> + + + + + + + + formik.setFieldValue("clearance_code", e.target.value.toUpperCase()) + } + onBlur={formik.handleBlur} + error={ + formik.touched.clearance_code && Boolean(formik.errors.clearance_code) + } + helperText={formik.touched.clearance_code && formik.errors.clearance_code} + /> + + قطعه, + }} + value={formik.values.quantity} + onChange={formik.handleChange} + onBlur={formik.handleBlur} + error={formik.touched.quantity && Boolean(formik.errors.quantity)} + helperText={formik.touched.quantity && formik.errors.quantity} + /> + + کیلوگرم, + }} + value={formik.values.live_weight} + onChange={formik.handleChange} + onBlur={formik.handleBlur} + error={formik.touched.live_weight && Boolean(formik.errors.live_weight)} + helperText={formik.touched.live_weight && formik.errors.live_weight} + /> + +); + +const CarcassFormSection = ({ formik, cities, provinces, isEdit, item }) => ( + <> + + + + + + + + formik.setFieldValue("clearance_code", e.target.value.toUpperCase()) + } + onBlur={formik.handleBlur} + error={ + formik.touched.clearance_code && Boolean(formik.errors.clearance_code) + } + helperText={formik.touched.clearance_code && formik.errors.clearance_code} + /> + + کیلوگرم, + }} + value={formik.values.weight_of_carcasses} + onChange={formik.handleChange} + onBlur={formik.handleBlur} + error={ + formik.touched.weight_of_carcasses && + Boolean(formik.errors.weight_of_carcasses) + } + helperText={ + formik.touched.weight_of_carcasses && formik.errors.weight_of_carcasses + } + /> + + قطعه, + }} + value={formik.values.number_of_carcasses} + onChange={formik.handleChange} + onBlur={formik.handleBlur} + error={ + formik.touched.number_of_carcasses && + Boolean(formik.errors.number_of_carcasses) + } + helperText={ + formik.touched.number_of_carcasses && formik.errors.number_of_carcasses + } + /> + +); + +const CommonFields = ({ formikDriver, setDriverPelak }) => ( + <> + { + setDriverPelak([pelak1, pelak2, pelak3, pelak4]); + }} + /> + + + + + +); + +export const SlaughterSubmitFreeBar = ({ item, updateTable }) => { + const dispatch = useDispatch(); + const [openNotif] = useContext(AppContext); + + const [buyType, setBuyType] = useState( + item ? (item?.buyType === "live" ? "alive" : "carcasses") : "alive" + ); + const [dayEnterInventory, setDayEnterInventory] = useState("today"); + const [productKey, setProductKey] = useState(null); + const [killerKey, setKillerKey] = useState(null); + const [productData, setProductData] = useState([]); + const [killersData, setKillersData] = useState([]); + const [provinceData, setProvinceData] = useState([]); + const [cityData, setCityData] = useState([]); + const [profileImages, setProfileImages] = useState([]); + const [driverPelak, setDriverPelak] = useState([]); + + const selectedSubUser = useSelector( + (state) => state.userSlice.selectedSubUser + ); + + const formik = useFormik({ + initialValues: { + buyType: item + ? item?.buyType === "live" + ? "alive" + : "carcasses" + : "alive", + poultry_name: item ? item.poultryName : "", + poultry_mobile: item ? item.poultryMobile : "", + province: item ? item.province : "", + city: item ? item.city : "", + clearance_code: item ? item.barClearanceCode : "", + quantity: item ? item.quantity : "", + live_weight: item ? item.liveWeight : "", + bar_image: item ? " " : "", + number_of_carcasses: item ? item.numberOfCarcasses : "", + weight_of_carcasses: item ? item.weightOfCarcasses : "", + }, + validationSchema: Yup.lazy((values) => + values.buyType === "alive" + ? ValidationSchemaAlive + : ValidationSchemaCarcass + ), + onSubmit: async (values) => { + try { + const payload = { + driver_name: formikDriver.values.driverName, + driver_mobile: formikDriver.values.driverMobile, + poultry_name: values.poultry_name, + poultry_mobile: values.poultry_mobile, + province: values.province, + city: values.city, + ...(values.clearance_code !== item?.barClearanceCode && { + bar_clearance_code: values.clearance_code, + }), + bar_image: values.bar_image, + killer_key: killerKey ? killerKey : null, + date: + dayEnterInventory === "today" + ? moment(new Date()).format("YYYY-MM-DD") + : moment(new Date()).add(1, "days").format("YYYY-MM-DD"), + buy_type: values.buyType === "alive" ? "live" : "carcass", + product_key: productKey?.key, + role_key: checkPathStartsWith("slaughter") + ? selectedSubUser?.key || "" + : "", + car: driverPelak.join(" "), + ...(values.buyType === "alive" + ? { + quantity: Number(values.quantity), + live_weight: Number(values.live_weight), + } + : { + number_of_carcasses: values.number_of_carcasses, + weight_of_carcasses: values.weight_of_carcasses, + }), + }; + + const response = item + ? await dispatch( + slaughterEditFreeSaleService({ ...payload, key: item.key }) + ) + : await dispatch(slaughterSubmitFreeSaleService(payload)); + + if (response.payload.error) { + openNotif({ + vertical: "top", + horizontal: "center", + msg: response.payload.error, + severity: "error", + }); + } else { + if (updateTable) { + updateTable(); + } + dispatch(DRAWER({ right: false, bottom: false, content: null })); + openNotif({ + vertical: "top", + horizontal: "center", + msg: item + ? "اطلاعات با موفقیت ویرایش شد" + : "اطلاعات خرید شما با موفقیت ثبت شد", + severity: "success", + }); + } + } catch (error) { + openNotif({ + vertical: "top", + horizontal: "center", + msg: "خطا در ارسال اطلاعات", + severity: "error", + }); + } + }, + validateOnMount: true, + }); + + const formikDriver = useFormik({ + initialValues: { + driverName: item?.driverName || "", + driverMobile: item?.driverMobile || "", + }, + validationSchema: DriverSchema, + }); + + const handleBuyTypeChange = (event) => { + setBuyType(event.target.value); + formik.setFieldValue("buyType", event.target.value); + }; + + const handleChangeDayEnterInventory = (event) => { + setDayEnterInventory(event.target.value); + }; + + const factorPaymentHandler = (imageList) => { + if (imageList[0]) { + formik.setFieldValue("bar_image", fixBase64(imageList[0]?.data_url)); + } + setProfileImages(imageList); + }; + + useEffect(() => { + const loadInitialData = async () => { + try { + const [productsRes, killersRes, provincesRes] = await Promise.all([ + dispatch( + slaughterGetProductsService({ + role_key: checkPathStartsWith("slaughter") + ? selectedSubUser?.key || "" + : "", + }) + ), + dispatch(slaughterGetExclusiveKillersService()), + dispatch(slaughterGetProvinceService()), + ]); + + const productsData = productsRes.payload?.data; + if (Array.isArray(productsData)) { + setProductData(productsData); + } else if (productsData?.data && Array.isArray(productsData.data)) { + setProductData(productsData.data); + } else { + setProductData([]); + } + + setKillersData(killersRes.payload.data || []); + setProvinceData(provincesRes.payload.data || []); + + if (item?.province) { + const citiesRes = await dispatch( + slaughterGetCitiesService(item.province) + ); + setCityData(citiesRes.payload.data || []); + } + } catch (error) { + console.error(error); + } + }; + + loadInitialData(); + }, [dispatch, selectedSubUser?.key]); + + useEffect(() => { + if (formik.values.province) { + dispatch(slaughterGetCitiesService(formik.values.province)).then((r) => { + setCityData(r.payload.data || []); + }); + } + }, [formik.values.province, dispatch]); + + return ( + + {item?.registerType !== "automatic" ? ( + + + } + label="مرغ زنده" + /> + } + label="لاشه" + /> + + + {!item && ( + + 0 + ? productData.map((i) => ({ + data: i, + label: i.name || "", + })) + : [] + } + onChange={(event, value) => setProductKey(value?.data || null)} + renderInput={(params) => ( + + )} + /> + + )} + + {!!killersData.length && ( + ({ + data: i.key, + label: `${i.name} (${i?.phone})`, + }))} + onChange={(event, value) => setKillerKey(value?.data)} + renderInput={(params) => ( + + )} + /> + )} + +
    + {buyType === "alive" ? ( + + ) : ( + + )} + + + + {buyType === "alive" && ( + + + تاریخ ورود به انبار + + + } + label="امروز" + /> + } + label="فردا" + /> + + + )} + + + + {formik.touched.bar_image && Boolean(formik.errors.bar_image) && ( + ثبت تصویر بار الزامی است + )} + + + +
    + ) : ( + + ({ + data: i.key, + label: `${i.name} (${i?.phone})`, + }))} + onChange={(event, value) => setKillerKey(value?.data)} + renderInput={(params) => ( + + )} + /> + + قطعه + ), + }} + value={formik.values.quantity} + onChange={formik.handleChange} + onBlur={formik.handleBlur} + error={formik.touched.quantity && Boolean(formik.errors.quantity)} + helperText={formik.touched.quantity && formik.errors.quantity} + /> + + کیلوگرم + ), + }} + value={formik.values.live_weight} + onChange={formik.handleChange} + onBlur={formik.handleBlur} + error={ + formik.touched.live_weight && Boolean(formik.errors.live_weight) + } + helperText={formik.touched.live_weight && formik.errors.live_weight} + /> + + + + )} +
    + ); +}; diff --git a/src/features/slaughter-house/components/slaughter-submit-free-buy/SlaughterSubmitFreeBuy.js b/src/features/slaughter-house/components/slaughter-submit-free-buy/SlaughterSubmitFreeBuy.js new file mode 100644 index 0000000..b221f0d --- /dev/null +++ b/src/features/slaughter-house/components/slaughter-submit-free-buy/SlaughterSubmitFreeBuy.js @@ -0,0 +1,1136 @@ +import { + Autocomplete, + Button, + Checkbox, + FormControl, + FormControlLabel, + FormLabel, + IconButton, + InputAdornment, + Radio, + RadioGroup, + TextField, + Tooltip, + Typography, +} from "@mui/material"; +import CloseIcon from "@mui/icons-material/Close"; +import { DatePicker } from "@mui/x-date-pickers"; +import { useFormik } from "formik"; +import { useContext, useEffect, useState } from "react"; +import { useDispatch, useSelector } from "react-redux"; +import { Grid } from "../../../../components/grid/Grid"; +import { NumberInput } from "../../../../components/number-format-custom/NumberFormatCustom"; +import { AppContext } from "../../../../contexts/AppContext"; +import { SPACING } from "../../../../data/spacing"; +import { DRAWER } from "../../../../lib/redux/slices/appSlice"; +import { Yup } from "../../../../lib/yup/yup"; +import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl"; +import { slaughterGetKillerKillhousesService } from "../../../slaughter-house/services/slaughter-get-killers-killhouses"; +import { slaughterGetPoultriesService } from "../../services/salughter-get-poultries"; +import { slaughterEditFreeBuyService } from "../../services/slaughter-edit-free-buy"; +import { slaughterGetProfile } from "../../services/slaughter-get-profile"; +import { slaughterSubmitFreeBuyPostService } from "../../services/slaughter-submit-free-buy-post"; +import { slaughterGetKillhousesService } from "../../services/slaughter-get-killhouses"; +import { getApprovedPriceState } from "../../../province/services/get-approved-price-state"; +import { paymentGetDeadLines } from "../../services/payment-get-deadlines"; +import { avicultureGetHatchingData } from "../../../aviculture/services/aviculture-get-hatching-data"; +import { provincePolicyValidatePoultryWithSmsStatusService } from "../../../province/services/province-policy-validate-poultry-wth-sms-service"; +import FilterAltIcon from "@mui/icons-material/FilterAlt"; +import { provincePolicyGetWeightRange } from "../../../province/services/province-policy-get-weight-range"; +import { isValidIndexWeight } from "../../../../utils/isValidIndexWeight"; +import { checkPathStartsWith } from "../../../../utils/checkPathStartsWith"; + +export const SlaughterSubmitFreeBuy = ({ edit, updateTable }) => { + const dispatch = useDispatch(); + const [openNotif] = useContext(AppContext); + const [maxAllowed, setMaxAllowed] = useState(false); + const [selectedAge1, setSelectedAge1] = useState(1); + const [selectedAge2, setSelectedAge2] = useState(1); + const [showSearchFields, setShowSearchFields] = useState(false); + const [editPoultry, setEditPoultry] = useState(false); + const selectedSubUser = useSelector( + (state) => state.userSlice.selectedSubUser + ); + const { slaughterGetPoultries, slaughterGetKillerKillhouses } = useSelector( + (state) => state.slaughterSlice + ); + + const { weightRange } = useSelector((state) => state.provinceSlice); + + const [poultryData, setPoultryData] = useState(""); + const [selectedPolutry, setSelectedPolutry] = useState(""); + const [paymentDeadlineDays, setPaymentDeadlineDays] = useState(null); + + const [submitStatus, SetSubmitStatus] = useState(false); + const fetchData = () => { + dispatch( + provincePolicyValidatePoultryWithSmsStatusService({ + role_key: checkPathStartsWith("slaughter") + ? selectedSubUser?.key || "" + : "", + }) + ).then((r) => { + SetSubmitStatus(r.payload.data.poultryStatus); + }); + }; + + useEffect(() => { + dispatch( + slaughterGetProfile({ + role_key: checkPathStartsWith("slaughter") + ? selectedSubUser?.key || "" + : "", + }) + ); + dispatch( + slaughterGetKillhousesService({ + role_key: checkPathStartsWith("slaughter") + ? selectedSubUser?.key || "" + : "", + }) + ); + dispatch( + slaughterGetPoultriesService({ + role_key: checkPathStartsWith("slaughter") + ? selectedSubUser?.key || "" + : "", + }) + ); + dispatch( + slaughterGetKillerKillhousesService({ + role_key: checkPathStartsWith("slaughter") + ? selectedSubUser?.key || "" + : "", + }) + ); + dispatch( + provincePolicyGetWeightRange({ + role_key: checkPathStartsWith("slaughter") + ? selectedSubUser?.key || "" + : "", + }) + ); + fetchData(); + }, [selectedSubUser?.key]); + + const [value, setValue] = useState(edit ? edit?.freeDirectBuying : true); + + const handleChange = (event) => { + setValue(event.target.value === "true" ? true : false); + }; + + const initialValues = { + killhouse: edit ? edit.killHouse.key : selectedSubUser?.key, + killerPlace: edit?.slaughterHouse?.key || null, + poultry: edit ? edit.poultry.key : null, + killDate: edit ? new Date(edit.reciveDate) : new Date(), + numberForBuy: edit ? edit.killCapacity : null, + indexWeight: edit ? edit.IndexWeight : "", + avicultureSellType: "goverment", + poultryPrice: edit ? edit.amount : 0, + hatching_key: edit?.poultryHatching?.key || null, + paymentDeadlineDays: edit?.paymentDeadlineDays?.key, + }; + const onSubmit = (values) => { + if (!paymentDeadlineDays && values.paymentDeadlineDays === 0) { + return; + } + + if ( + getRoleFromUrl() !== "SuperAdmin" && + getRoleFromUrl() !== "AdminX" && + !isValidIndexWeight(weightRange, selectedPolutry?.age, values.indexWeight) + ) { + openNotif({ + vertical: "top", + horizontal: "center", + msg: "میانگین وزنی با احراز سنی مطابقت ندارد. لطفا با اتحادیه تماس بگیرید.", + severity: "error", + }); + } else { + dispatch( + slaughterSubmitFreeBuyPostService({ + kill_capacity: values.numberForBuy, + ...(editPoultry + ? { + direct_buying_intermediary_mobile: + formik2.values.intermediaryMobile, + } + : {}), + recive_time: "12 - 14", + recive_date: values.killDate, + low_weight: false, + high_weight: false, + Index_weight: values.indexWeight, + chicken_breed: selectedPolutry?.chickenBreed, + cash: true, + credit: false, + sms_payment: false, + kill_house_key: values.killhouse, + killer_kill_house_key: values.killerPlace ? values.killerPlace : null, + role: getRoleFromUrl(), + poultry_key: formik.values.poultry, + free_direct_buying: value, + + amount: + data?.approved && + !value && + !( + data?.lowestPrice === 0 && + data?.highestPrice === 0 && + data?.lowestWeight === 0 && + data?.highestWeight === 0 + ) + ? Math.round(approvedPrice) + : Number(values.poultryPrice), + + hatching_key: formik.values.hatching_key, + payment_deadline_days: formik?.values?.paymentDeadlineDays, + confirm_poultry_mobile: formik2.values.userInfoCheck, + }) + ).then((r) => { + if (r.payload.error) { + openNotif({ + vertical: "top", + + horizontal: "center", + msg: r.payload.error, + severity: "error", + }); + } else { + updateTable(); + openNotif({ + vertical: "top", + horizontal: "center", + msg: "عملیات با موفقیت انجام شد.", + severity: "success", + }); + dispatch( + DRAWER({ + right: false, + bottom: false, + left: false, + content: null, + }) + ); + } + }); + } + }; + + const validationSchema = Yup.object().shape({ + killhouse: Yup.string("") + .typeError("این فیلد الزامی است") + .required("این فیلد الزامی است"), + poultry: Yup.string("") + .typeError("این فیلد الزامی است") + .required("این فیلد الزامی است"), + numberForBuy: Yup.number() + .typeError("لطفا عدد وارد کنید") + .max(edit ? Infinity : maxAllowed, "تعداد بیش از حد مجاز است") + .required("لطفا عدد وارد کنید") + .positive("لطفا عدد وارد کنید") + .integer("لطفا عدد وارد کنید"), + indexWeight: Yup.number() + .typeError("لطفا عدد وارد کنید") + .required("لطفا عدد وارد کنید") + .positive("لطفا عدد وارد کنید"), + poultryPrice: Yup.number() + .typeError("لطفا فیلد را به درستی وارد کنید!") + .min(value ? 400000 : 0, "حداقل قیمت پایه ۴۰۰,۰۰۰ ریال ") + .required("این فیلد اجباری است"), + + hatching_key: Yup.string().required("این فیلد الزامی است"), + paymentDeadlineDays: Yup.number().when([], { + is: () => paymentDeadlineDays !== null, + then: Yup.number() + .required("این فیلد الزامی است") + .min(1, "حداقل مقدار باید 1 باشد") + .max( + paymentDeadlineDays, + `حداکثر مقدار باید ${paymentDeadlineDays} باشد` + ), + otherwise: Yup.number().notRequired(), + }), + }); + + const formik = useFormik({ + initialValues, + validationSchema, + onSubmit, + }); + + const formik2 = useFormik({ + initialValues: { + userInfoCheck: "", + intermediaryMobile: "", + }, + validationSchema: Yup.object({ + userInfoCheck: Yup.string() + .min(11, "شماره موبایل باید 11 رقم باشد") + .max(11, "شماره موبایل باید 11 رقم باشد") + .matches(/^0\d{10}$/, "شماره موبایل باید با 09 شروع شود و 11 رقم باشد"), + intermediaryMobile: Yup.string() + .min(11, "شماره موبایل باید 11 رقم باشد") + .max(11, "شماره موبایل باید 11 رقم باشد") + .matches(/^0\d{10}$/, "شماره موبایل باید با 09 شروع شود و 11 رقم باشد"), + }), + }); + + useEffect(() => { + if (formik.values.poultry) { + dispatch( + avicultureGetHatchingData({ + key: formik.values.poultry, + }) + ).then((r) => { + setPoultryData(r.payload.data); + }); + } + }, [formik.values.poultry, selectedSubUser?.key]); + + useEffect(() => { + let newVal = formik.values.indexWeight; + const mystring = formik.values?.indexWeight + ?.toString() + ?.split(".") + ?.join(""); + if (formik.values.indexWeight) { + if (mystring.length <= 3) { + if (mystring.length === 2) { + newVal = mystring[0] + "." + mystring[1]; + } + if (mystring.length === 3) { + newVal = mystring[0] + "." + mystring[1] + mystring[2]; + } + } + } + if (isNaN(Number.parseFloat(newVal))) { + formik.setFieldValue("indexWeight", ""); + } else { + formik.setFieldValue("indexWeight", Number.parseFloat(newVal)); + } + }, [formik.values.indexWeight]); + + const handleSubmitSearchByAge = async (event) => { + event.preventDefault(); + + dispatch( + slaughterGetPoultriesService({ + min_age: selectedAge1 ? selectedAge1 : 1, + max_age: selectedAge2 ? selectedAge2 : 1, + }) + ); + }; + const handleSubmitSearchNoAge = async (event) => { + event.preventDefault(); + setSelectedAge1(1); + setSelectedAge2(1); + dispatch(slaughterGetPoultriesService()); + }; + + useEffect(() => { + if (value === true) { + setMaxAllowed( + selectedPolutry.freeGovernmentalInfo?.leftTotalFreeCommitmentQuantity + ); + } else { + setMaxAllowed(selectedPolutry.leftOver); + } + setTimeout(() => { + formik.validateField("numberForBuy"); + }, 1); + }, [value]); + + const [data, setData] = useState(); + const [approvedPrice, setApprovedPrice] = useState(); + + useEffect(() => { + dispatch( + getApprovedPriceState({ + role_key: checkPathStartsWith("slaughter") + ? selectedSubUser?.key || "" + : "", + }) + ).then((r) => { + setData(r.payload.data); + if (r.payload.data?.approved === false) { + formik.setFieldValue("avicultureSellType", "freePrice"); + } + // Check if approved is true but all price/weight fields are zero + if ( + r.payload.data?.approved === true && + r.payload.data?.lowestPrice === 0 && + r.payload.data?.highestPrice === 0 && + r.payload.data?.lowestWeight === 0 && + r.payload.data?.highestWeight === 0 + ) { + setValue(false); // Set to "دولتی" + } + }); + }, [selectedSubUser?.key]); + + useEffect(() => { + dispatch( + paymentGetDeadLines({ + role_key: checkPathStartsWith("slaughter") + ? selectedSubUser?.key || "" + : "", + }) + ).then((r) => { + const isEnabled = r?.payload?.data?.paymentDeadline; + + const days = r?.payload?.data?.paymentDeadlineDays; + + if (isEnabled === true && days > 0) { + setPaymentDeadlineDays(days); + } + }); + }, [selectedSubUser?.key]); + + useEffect(() => { + if ( + data?.approved && + !( + data?.lowestPrice === 0 && + data?.highestPrice === 0 && + data?.lowestWeight === 0 && + data?.highestWeight === 0 + ) + ) { + if (formik.values.indexWeight * 1000 <= data?.lowestWeight) { + setApprovedPrice(data?.lowestPrice); + } else if (formik.values.indexWeight * 1000 >= data?.highestWeight) { + setApprovedPrice(data?.highestPrice); + } else { + const diffWeight = data?.highestWeight - data?.lowestWeight; + const diffPrice = data?.highestPrice - data?.lowestPrice; + const fraction = diffPrice / diffWeight; + const diffFromMinWeight = + formik.values.indexWeight * 1000 - data?.lowestWeight; + setApprovedPrice(diffFromMinWeight * fraction + data?.lowestPrice); + formik.setFieldValue( + "poultryPrice", + diffFromMinWeight * fraction + data?.lowestPrice + ); + } + } + }, [formik.values.indexWeight]); + + return ( +
    + + <> + {/* {!edit ? ( + slaughterGetKillhouses?.length ? ( + { + const buyerNamePrefix = item?.killer ? "کشتارکن" : "کشتارگاه"; + return { + label: buyerNamePrefix + " " + item.name, + value: item.key, + killer: item.killer, + item: item, + disabled: item.allowDirectBuying, + }; + })} + getOptionDisabled={(option) => !option.disabled} + getOptionLabel={(option) => option.label} + onChange={(_, value) => { + setIsKiller(value.killer); + formik.setFieldValue("killhouse", value.value); + }} + onBlur={formik.handleBlur} + renderInput={(params) => ( + + )} + /> + ) : ( + + ) + ) : null} */} + {selectedSubUser?.killer && ( + { + return { + label: "کشتارگاه " + item.name, + value: item.key, + }; + })} + getOptionLabel={(option) => option.label} + onChange={(_, value) => + formik.setFieldValue("killerPlace", value.value) + } + onBlur={formik.handleBlur} + renderInput={(params) => ( + + )} + /> + )} + {(formik.values.killhouse || formik.values.killerPlace) && ( + <> + + {!edit && ( + + ({ + label: `${item.unitName} (${item.user?.fullname})`, + value: item.key, + item, + })) || [] + } + getOptionLabel={(option) => option.label} + onChange={(_, value) => { + formik.setFieldValue("poultry", value.item.key); + setMaxAllowed(value.item.lastHatchingRemainQuantity); + }} + onBlur={formik.handleBlur} + renderOption={(props, option) => { + const item = option.item; + return ( +
  • + + + {item?.unitName} ({item?.user?.fullname}) + + + {item?.user?.mobile || "-"} |{" "} + {item?.address?.city?.name || "-"} + + +
  • + ); + }} + renderInput={(params) => ( + + )} + /> +
    + )} + {!edit && ( + + + setShowSearchFields(!showSearchFields)} + color={showSearchFields ? "error" : "primary"} + size="large" + > + {showSearchFields ? : } + + + + )} +
    + + {showSearchFields && ( + + + setSelectedAge1(e.target.value)} + /> + + + setSelectedAge2(e.target.value)} + /> + + + + + + + + + + + + + + )} + + {poultryData && ( + + {!edit && ( + { + return { + label: `${item?.poultry.unitName}`, + value: item.key, + item, + }; + })} + onChange={(event, value) => { + setSelectedPolutry(value.item); + formik2.setFieldValue( + "userInfoCheck", + value.item?.poultry?.userprofile?.mobile + ); + formik.setFieldValue("hatching_key", value.value); + }} + renderInput={(params) => ( + + )} + /> + )} + + {formik.values.hatching_key && ( + + {selectedPolutry && ( + + + نام و نام خانوادگی: + + {selectedPolutry?.poultry?.userprofile?.fullName} + + + + + + + تلفن مرغدار: + + { + selectedPolutry?.poultry?.userprofile + ?.mobile + } + + + + + + setEditPoultry(!editPoultry)} + /> + + تلفن واسطه جهت دریافت کد احراز + + + + {editPoultry && ( + + )} + + + آدرس: + + {`شهر ${ + selectedPolutry.poultry?.address?.city?.name + } ${ + selectedPolutry?.poultry?.address?.address + ? "-" + + selectedPolutry?.poultry?.address?.address + : "" + }`} + + + + سن جوجه: + + {selectedPolutry?.chickenAge} روز + + + + مانده در سالن: + + {selectedPolutry?.leftOver?.toLocaleString()} + قطعه + + + + + مانده فروش آزاد: + + + {selectedPolutry?.freeGovernmentalInfo?.leftTotalFreeCommitmentQuantity?.toLocaleString()}{" "} + قطعه + + + + نژاد: + + {selectedPolutry?.chickenBreed} + + + + )} + {submitStatus && + selectedPolutry && + getRoleFromUrl() !== "KillHouse" && ( + + )} + {submitStatus && + selectedPolutry && + getRoleFromUrl() !== "KillHouse" && ( + + احراز پیامکی قیمت مرغدار در استان فعال است. در صورت + ویرایش، تلفن مرغدار در سراسر سامانه با تلفن جدید + جایگزین میگردد! + + )} + {!edit && ( + + } + value={ + formik.values.killDate instanceof Date + ? formik.values.killDate + : formik.values.killDate + ? new Date(formik.values.killDate) + : null + } + error={ + formik.touched.killDate + ? Boolean(formik.errors.killDate) + : null + } + onChange={(e) => { + formik.setFieldValue("killDate", e); + }} + onBlur={formik.handleBlur} + helperText={ + formik.touched.killDate && + Boolean(formik.errors.killDate) + ? formik.errors.killDate + : null + } + /> + + )} + + + + + + کیلوگرم + + ), + }} + error={ + formik.touched.indexWeight && + Boolean(formik.errors.indexWeight) + } + helperText={ + formik.touched.indexWeight && + formik.errors.indexWeight + } + /> + + {data?.approved && + !edit && + !( + data?.lowestPrice === 0 && + data?.highestPrice === 0 && + data?.lowestWeight === 0 && + data?.highestWeight === 0 + ) && ( + + + + قیمت خرید + + + } + label="آزاد" + /> + } + label="دولتی" + /> + + + + )} + {data?.approved && + value === false && + !edit && + !( + data?.lowestPrice === 0 && + data?.highestPrice === 0 && + data?.lowestWeight === 0 && + data?.highestWeight === 0 + ) && ( + + + + + قیمت مصوب: + + + + {approvedPrice + ? Math.round(approvedPrice)?.toLocaleString() + : 0}{" "} + ریال + + + + )} + {(value || + (value === false && + data?.approved && + data?.lowestPrice === 0 && + data?.highestPrice === 0 && + data?.lowestWeight === 0 && + data?.highestWeight === 0)) && + !edit && ( + + + ریال + + ), + }} + value={formik.values.poultryPrice} + error={ + formik.touched.poultryPrice + ? Boolean(formik.errors.poultryPrice) + : null + } + onChange={formik.handleChange} + onBlur={formik.handleBlur} + helperText={ + formik.touched.poultryPrice && + Boolean(formik.errors.poultryPrice) + ? formik.errors.poultryPrice + : null + } + /> + {/* {!data?.approved && + formik.values.avicultureSellType !== + "goverment" && ( + + نوع فروش: آزاد + + )} */} + + )} + + {paymentDeadlineDays && !edit && ( + + + روز + + ), + inputProps: { + min: 1, + max: paymentDeadlineDays, + }, + }} + value={formik.values.paymentDeadlineDays} + onChange={(e) => { + const val = Number(e.target.value); + if (val <= paymentDeadlineDays) { + formik.setFieldValue( + "paymentDeadlineDays", + val + ); + } + }} + onBlur={formik.handleBlur} + error={formik.errors.paymentDeadlineDays} + helperText={ + formik.touched.paymentDeadlineDays && + formik.errors.paymentDeadlineDays + ? formik.errors.paymentDeadlineDays + : paymentDeadlineDays + ? `حداکثر زمان مجاز ${paymentDeadlineDays} روز است` + : "" + } + /> + + )} + + {!edit && ( + + )} + {edit && ( + + )} + + )} + + )} + + )} + +
    +
    + ); +}; diff --git a/src/features/slaughter-house/components/slaughter-submit-operations/SlaughterSubmitOperations.js b/src/features/slaughter-house/components/slaughter-submit-operations/SlaughterSubmitOperations.js new file mode 100644 index 0000000..2fe753b --- /dev/null +++ b/src/features/slaughter-house/components/slaughter-submit-operations/SlaughterSubmitOperations.js @@ -0,0 +1,138 @@ +import React, { useState } from "react"; +import { + FormControl, + InputLabel, + MenuItem, + Select, + Typography, + Box, + Divider, +} from "@mui/material"; +import { Grid } from "../../../../components/grid/Grid"; +import { SPACING } from "../../../../data/spacing"; +import { SlaughterAllocateToGuild } from "../slaughter-allocate-to-guild/SlaughterAllocateToGuild"; +import { SlaughterAllocateForFreezing } from "../slaughter-allocate-for-freezing/SlaughterAllocateForFreezing"; +import { SlaughterSellCarcassOutProvinceSellSubmitSell } from "../slaughter-sell-carcass-out-province-submit-sell/SlaughterSellCarcassOutProvinceSellSubmitSell"; +import { StewardSegmentSubmitOperation } from "../../../guild/components/StewardSegmentSubmitOperation"; + +const operations = [ + { + value: "inProvinceSale", + label: "توزیع/ فروش درون استان", + description: "ثبت توزیع و فروش لاشه داخل استان", + }, + { + value: "coldStorage", + label: "انتقال به سردخانه", + description: "ثبت انتقال لاشه به سردخانه", + }, + { + value: "outProvinceSale", + label: "فروش خارج استان", + description: "ثبت فروش لاشه به خارج از استان", + }, + { + value: "segmentation", + label: "قطعه بندی", + description: "ثبت قطعه بندی لاشه", + }, +]; + +export const SlaughterSubmitOperations = ({ + updateTable, + priceInfo, + slaughterProducts, + fetchApiData, +}) => { + const [selectedOperation, setSelectedOperation] = useState(""); + + const handleOperationChange = (event) => { + setSelectedOperation(event.target.value); + }; + + const getOperationContent = () => { + const commonProps = { + updateTable, + priceInfo, + remainWeight: slaughterProducts?.[0]?.totalRemainWeight, + fetchApiData, + }; + + switch (selectedOperation) { + case "inProvinceSale": + return ( + + ); + case "coldStorage": + return ( + + ); + case "outProvinceSale": + return ( + + ); + case "segmentation": + return ( + + ); + default: + return null; + } + }; + + const selectedOperationData = operations.find( + (op) => op.value === selectedOperation + ); + + return ( + + + انتخاب عملیات + + + + {selectedOperationData && ( + <> + + + + {selectedOperationData.label} + + + {selectedOperationData.description} + + + + )} + + {getOperationContent()} + + ); +}; diff --git a/src/features/slaughter-house/components/slaughter-submit-out-province-sell/SlaughterSubmitOutProvinceSell.js b/src/features/slaughter-house/components/slaughter-submit-out-province-sell/SlaughterSubmitOutProvinceSell.js new file mode 100644 index 0000000..2806440 --- /dev/null +++ b/src/features/slaughter-house/components/slaughter-submit-out-province-sell/SlaughterSubmitOutProvinceSell.js @@ -0,0 +1,186 @@ +import React, { useContext } from "react"; +import { TextField, Button } from "@mui/material"; +import { Formik, Form, Field } from "formik"; +import * as Yup from "yup"; +import { Grid } from "../../../../components/grid/Grid"; +import { AppContext } from "../../../../contexts/AppContext"; +import { useDispatch } from "react-redux"; +import { + guildSubmitOutOfProvinceService, + slaughterSubmitOutOfProvinceService, +} from "../../services/slaughter-submit-out-province-service"; +import { DRAWER } from "../../../../lib/redux/slices/appSlice"; +import { + guildEditOutOfProvinceService, + slaughterEditOutOfProvinceService, +} from "../../services/slaughterEditOutOfProvinceService"; +import { guildGetInventoryStockService } from "../../../guild/services/guild-get-inventory-stock"; +import { guildGetFreeSaleBarService } from "../../../guild/services/guild-get-free-sale-bar"; +import { DatePicker } from "@mui/x-date-pickers"; +import moment from "moment"; +import { fetchSlaughterBroadcastAndProducts } from "../../services/handle-fetch-slaughter-products"; + +const validationSchema = Yup.object().shape({ + quarantineCode: Yup.string().required("کد قرنطینه الزامی است"), + carcassCount: Yup.number().required("حجم لاشه الزامی است"), + carcassWeight: Yup.number().required("وزن لاشه الزامی است"), + date: Yup.string().required("تاریخ الزامی است"), +}); + +export const SlaughterSubmitOutProvinceSell = ({ + fetchItems, + isEdit, + item, + selectedDate, + stewardKey, +}) => { + const dispatch = useDispatch(); + const [openNotif] = useContext(AppContext); + + const initialValues = { + quarantineCode: item?.clearanceCode || "", + carcassCount: item?.numberOfCarcasses || "", + carcassWeight: item?.weightOfCarcasses || "", + date: item?.date || moment().format("YYYY-MM-DD HH:mm:ss"), + }; + + return ( + + { + const payload = { + ...values, + date: values.date, + number_of_carcasses: values.carcassCount, + weight_of_carcasses: values.carcassWeight, + }; + + if (values.quarantineCode !== item?.quarantineCode) { + payload.quarantineCode = values.quarantineCode; + } + + const service = stewardKey + ? isEdit + ? guildEditOutOfProvinceService({ key: item?.key, ...payload }) + : guildSubmitOutOfProvinceService({ + steward_key: stewardKey, + ...payload, + }) + : isEdit + ? slaughterEditOutOfProvinceService({ + key: item?.key, + driver_mobile: values.driverPhone, + ...payload, + }) + : slaughterSubmitOutOfProvinceService({ + driver_mobile: values.driverPhone, + ...payload, + }); + + dispatch(service).then((r) => { + if (r.payload.error) { + openNotif({ + vertical: "top", + horizontal: "center", + msg: r.payload.error, + severity: "error", + }); + } else { + stewardKey + ? dispatch(guildGetInventoryStockService({ date: values.date })) + : fetchItems(); + + stewardKey && + dispatch( + guildGetFreeSaleBarService({ + date: values.date, + steward_key: stewardKey, + }) + ); + + dispatch(fetchSlaughterBroadcastAndProducts()); + dispatch(DRAWER({ right: false, bottom: false, content: null })); + openNotif({ + vertical: "top", + horizontal: "center", + msg: "عملیات با موفقیت انجام شد.", + severity: "success", + }); + } + }); + }} + > + {({ errors, touched, setFieldValue, values }) => ( +
    + + + + + + + + + { + const formatted = moment(val).format("YYYY-MM-DD HH:mm:ss"); + setFieldValue("date", formatted); + }} + renderInput={(params) => ( + + )} + /> + + + + + + + + +
    + )} +
    +
    + ); +}; diff --git a/src/features/slaughter-house/components/slaughter-submit-real-inventory-free-bar/SLaughterSubmitRealInverntoryFreeBar.js b/src/features/slaughter-house/components/slaughter-submit-real-inventory-free-bar/SLaughterSubmitRealInverntoryFreeBar.js new file mode 100644 index 0000000..eeda231 --- /dev/null +++ b/src/features/slaughter-house/components/slaughter-submit-real-inventory-free-bar/SLaughterSubmitRealInverntoryFreeBar.js @@ -0,0 +1,197 @@ +import React, { useContext, useEffect, useState } from "react"; +import { Yup } from "../../../../lib/yup/yup"; +import { useFormik } from "formik"; +import { Grid } from "../../../../components/grid/Grid"; +import { Button, TextField, Typography } from "@mui/material"; +import { + CLOSE_MODAL, + LOADING_START, + OPEN_MODAL, +} from "../../../../lib/redux/slices/appSlice"; +import { SPACING } from "../../../../data/spacing"; +import { useDispatch } from "react-redux"; +import { AppContext } from "../../../../contexts/AppContext"; + +import { slaughterEditFreeSaleService } from "../../services/slaughter-edit-free-sale"; +import { fetchSlaughterBroadcastAndProducts } from "../../services/handle-fetch-slaughter-products"; + +export const SlaughterSubmitRealInventoryFreeBar = ({ item, updateTable }) => { + const [loss, setLoss] = useState("0"); + + const [openNotif] = useContext(AppContext); + const dispatch = useDispatch(); + const formik = useFormik({ + initialValues: { + realNumber: item.numberOfCarcasses ? item.numberOfCarcasses : "", + realWeight: item.weightOfCarcasses ? item.weightOfCarcasses : "", + }, + validationSchema: Yup.object({ + realNumber: Yup.number() + .typeError("لطفا فیلد را به درستی وارد کنید.!") + .required("این فیلد اجباری است!"), + realWeight: Yup.number() + .typeError("لطفا فیلد را به درستی وارد کنید.!") + .required("این فیلد اجباری است!"), + }), + }); + + useEffect(() => { + let difference = item?.liveWeight - formik.values.realWeight; + if (difference < item?.liveWeight) { + setLoss(((difference / item?.liveWeight) * 100).toPrecision(4)); + } else { + setLoss(0); + } + + formik.setFieldValue( + "realNumber", + Math.round(formik.values.realWeight / 1.5) + ); + }, [formik.values.realWeight]); + + const handleAlert = () => { + dispatch( + OPEN_MODAL({ + title: "عملیات با موفقیت انجام شد", + content: ( + <> + + + جهت ویرایش میتوانید حداکثر تا پایان امروز یا قبل از اولین تخصیص + اقدام کنید. + + + + + ), + }) + ); + }; + + useEffect(() => { + formik.validateForm(); + }, []); + + return ( + <> + + + + + وزن بار زنده: {item?.liveWeight?.toLocaleString()} کیلوگرم + + + + + + + + + + + افت: {loss > 0 ? loss : 0}% + + {(loss > 30 || loss < 20) && ( + + درصد افت باید بین 20 تا 30 درصد باشد! + + )} + + + + + + + + ); +}; diff --git a/src/features/slaughter-house/components/slaughter-submit-real-inventory/SlaughterSubmitRealInventory.js b/src/features/slaughter-house/components/slaughter-submit-real-inventory/SlaughterSubmitRealInventory.js new file mode 100644 index 0000000..c239ecb --- /dev/null +++ b/src/features/slaughter-house/components/slaughter-submit-real-inventory/SlaughterSubmitRealInventory.js @@ -0,0 +1,389 @@ +import React, { useContext, useEffect, useState } from "react"; +import { Yup } from "../../../../lib/yup/yup"; +import { useFormik } from "formik"; +import { Grid } from "../../../../components/grid/Grid"; +import { + Button, + FormControl, + FormControlLabel, + Radio, + RadioGroup, + TextField, + Typography, +} from "@mui/material"; +import { CLOSE_MODAL, OPEN_MODAL } from "../../../../lib/redux/slices/appSlice"; +import { SPACING } from "../../../../data/spacing"; +import { useDispatch } from "react-redux"; +import { killhouseSubmitRealInventoryService } from "../../services/killhouse-submit-real-inventory"; +import { AppContext } from "../../../../contexts/AppContext"; +import { provincePolicyGetDropLimitService } from "../../../province/services/province-policy-drop-limit"; +import { fetchSlaughterBroadcastAndProducts } from "../../services/handle-fetch-slaughter-products"; + +export const SlaughterSubmitRealInventory = ({ item, updateTable }) => { + const [value, setValue] = useState("weight"); + const [loss, setLoss] = useState("0"); + const [dropLimits, setDropLimits] = useState({ min: 0, max: 100 }); + + const handleChange = (event) => { + setValue(event.target.value); + }; + const [inputWarehouse, setInputWarehouse] = useState( + item?.killer ? "killer" : "self" + ); + + const handleChangeInputWarehouse = (event) => { + setInputWarehouse(event.target.value); + }; + + const [openNotif] = useContext(AppContext); + const dispatch = useDispatch(); + + useEffect(() => { + dispatch(provincePolicyGetDropLimitService()).then((r) => { + if (r.payload?.data) { + setDropLimits({ + min: parseFloat(r.payload.data.killHouseLimitPercentDown), + max: parseFloat(r.payload.data.killHouseLimitPercentUp), + }); + } + }); + }, []); + + const formik = useFormik({ + initialValues: { + realNumber: item?.acceptedRealQuantity ? item?.acceptedRealQuantity : "", + realWeight: item?.wareHouseAcceptedRealWeight + ? item?.wareHouseAcceptedRealWeight + : 0, + }, + validationSchema: Yup.object({ + realNumber: Yup.number() + .typeError("لطفا فیلد را به درستی وارد کنید.!") + .required("این فیلد اجباری است!") + .min(0, "مقدار نمی‌تواند منفی باشد"), + realWeight: Yup.number() + .typeError("لطفا فیلد را به درستی وارد کنید.!") + .required("این فیلد اجباری است!") + .min(0, "مقدار نمی‌تواند منفی باشد"), + }), + }); + + const formik2 = useFormik({ + initialValues: { + lossWeight: "", + }, + validationSchema: Yup.object({ + lossWeight: Yup.number() + .typeError("لطفا فیلد را به درستی وارد کنید.!") + .required("این فیلد اجباری است!") + .min( + dropLimits.min, + `درصد افت باید بین ${dropLimits.min} تا ${dropLimits.max} درصد باشد!` + ) + .max( + dropLimits.max, + `درصد افت باید بین ${dropLimits.min} تا ${dropLimits.max} درصد باشد!` + ), + }), + }); + + useEffect(() => { + if (value === "weight") { + if (item?.acceptedRealWeight && formik.values.realWeight) { + const difference = item.acceptedRealWeight - formik.values.realWeight; + const calculatedLoss = (difference / item.acceptedRealWeight) * 100; + setLoss(calculatedLoss.toFixed(2)); + } else { + setLoss(0); + } + } else { + if (item?.acceptedRealWeight && formik2.values.lossWeight) { + const percentage = + (item.acceptedRealWeight / 100) * formik2.values.lossWeight; + setLoss((item.acceptedRealWeight - percentage).toFixed(2)); + } else { + setLoss(0); + } + } + }, [formik.values.realWeight, formik2.values.lossWeight, value, item]); + + const isLossInRange = () => { + if (value === "weight") { + return loss >= dropLimits.min && loss <= dropLimits.max; + } else { + return formik2.isValid; + } + }; + + const isFormValid = () => { + if (value === "weight") { + return formik.isValid && isLossInRange(); + } else { + return formik2.isValid; + } + }; + + const handleSubmit = () => { + if (!isFormValid()) return; + + const payload = + value === "weight" + ? { + input_type: "input_weight", + ware_house_accepted_real_quantity: parseInt( + formik.values.realNumber + ), + ware_house_accepted_real_weight: parseInt(formik.values.realWeight), + kill_house_request_key: item?.key, + loss_percent: parseFloat(loss), + } + : { + input_type: "loss_weight", + loss_percent: parseInt(formik2.values.lossWeight), + kill_house_request_key: item?.key, + }; + + dispatch( + killhouseSubmitRealInventoryService({ + ...payload, + ...(item?.killer ? { input_warehouse: inputWarehouse } : {}), + }) + ).then((r) => { + if (r.payload.error) { + openNotif({ + vertical: "top", + horizontal: "center", + msg: r.payload.error, + severity: "error", + }); + } else { + dispatch(CLOSE_MODAL()); + updateTable(); + dispatch(fetchSlaughterBroadcastAndProducts()); + handleAlert(); + } + }); + }; + + const handleAlert = () => { + dispatch( + OPEN_MODAL({ + title: "عملیات با موفقیت انجام شد", + content: ( + <> + + + جهت ویرایش میتوانید حداکثر تا پایان امروز یا قبل از اولین تخصیص + اقدام کنید. + + + + + ), + }) + ); + }; + + return ( + <> + + + + {item?.killer && ( + + کشتارکن: {item?.killer?.name} + + )} + + کد بار: {item.barCode} + + + حجم بار: {item?.acceptedRealQuantity?.toLocaleString()} + + + وزن بار: {item?.acceptedRealWeight?.toLocaleString()} + + + + + } + label="بر اساس وزن ورودی" + /> + } + label="بر اساس درصد افت" + /> + + + + {value === "weight" ? ( + <> + + + + + ) : ( + + )} + + + {item?.killer && ( + + + + } + label="ورود به انبار کشتارگاه" + /> + } + label="ورود به انبار کشتارکن" + /> + + + + )} + + + + {value === "weight" ? ( + + + افت: {loss > 0 ? loss : 0}% + + {!isLossInRange() && ( + + درصد افت باید بین {dropLimits.min} تا {dropLimits.max} درصد + باشد! + + )} + + ) : ( + + وزن: {loss} + + )} + + + + + + + + ); +}; diff --git a/src/features/slaughter-house/components/slaughter-supply-inventory-form/SlaughterSupplyInventoryForm.js b/src/features/slaughter-house/components/slaughter-supply-inventory-form/SlaughterSupplyInventoryForm.js new file mode 100644 index 0000000..3b31866 --- /dev/null +++ b/src/features/slaughter-house/components/slaughter-supply-inventory-form/SlaughterSupplyInventoryForm.js @@ -0,0 +1,191 @@ +import { Button, TextField, Typography } from "@mui/material"; +import { useFormik } from "formik"; +import React, { useContext, useEffect } from "react"; +import { Grid } from "../../../../components/grid/Grid"; +import { SPACING } from "../../../../data/spacing"; +import { Yup } from "../../../../lib/yup/yup"; +import { PropTypes } from "prop-types"; +import { useDispatch } from "react-redux"; +import { AppContext } from "../../../../contexts/AppContext"; +import { + DRAWER, + LOADING_END, + LOADING_START, +} from "../../../../lib/redux/slices/appSlice"; +import { slaughterGetRegisteredComplaints } from "../../services/slaughter-get-registered-complaints"; +import useUserProfile from "../../../authentication/hooks/useUserProfile"; +import { slaughterSupplyInventory } from "../../services/slaughter-supply-inventory"; + +export const SlaughterSupplyInventoryForm = () => { + const [openNotif] = useContext(AppContext); + const dispatch = useDispatch(); + + const [, userProfile] = useUserProfile(); + + const formik = useFormik({ + initialValues: { + description: "", + }, + validationSchema: Yup.object({ + description: Yup.string() + .required("این فیلد اجباری است!") + .typeError("لطفا فیلد را پر کنید!"), + }), + }); + + useEffect(() => { + formik.validateForm(); + }, []); + + return ( + + + + موجودی سیستم 450.000 + + + + + + + + + ); +}; + +SlaughterSupplyInventoryForm.propTypes = { + barKey: PropTypes.any, +}; diff --git a/src/features/slaughter-house/components/slaughter-unpaid-fees-checkbox/SlaughterUnpaidFeesCheckbox.js b/src/features/slaughter-house/components/slaughter-unpaid-fees-checkbox/SlaughterUnpaidFeesCheckbox.js new file mode 100644 index 0000000..b2b5cc7 --- /dev/null +++ b/src/features/slaughter-house/components/slaughter-unpaid-fees-checkbox/SlaughterUnpaidFeesCheckbox.js @@ -0,0 +1,30 @@ +import { Checkbox, FormControlLabel } from "@mui/material"; +import { useState } from "react"; + +export const SlaughterUnpaidFeesCheckbox = ({ + handleSelectedItems, + item, + selectedItems, +}) => { + // Initialize the checkbox state with false (unchecked) + const [isChecked, setIsChecked] = useState( + selectedItems.includes(item.provinceRequest.provinceKillRequestKey) + ); + // Function to handle checkbox state changes + const handleCheckboxChange = (event) => { + setIsChecked(event.target.checked); + handleSelectedItems(item.provinceRequest.provinceKillRequestKey, item); + }; + + return ( + + } + /> + ); +}; diff --git a/src/features/slaughter-house/components/slaughter-unpaid-fees-details/SlaughterUnpaidFeesDetails.js b/src/features/slaughter-house/components/slaughter-unpaid-fees-details/SlaughterUnpaidFeesDetails.js new file mode 100644 index 0000000..db376e8 --- /dev/null +++ b/src/features/slaughter-house/components/slaughter-unpaid-fees-details/SlaughterUnpaidFeesDetails.js @@ -0,0 +1,70 @@ +import { format } from "date-fns-jalali"; +import { useEffect, useState } from "react"; +import { SimpleTable } from "../../../../components/simple-table/SimpleTable"; + +export const SlaughterUnpaidFeesDetails = ({ item }) => { + const [dataTable, setDataTable] = useState([]); + + useEffect(() => { + const d = item?.killHouseRequests?.map((item) => { + const vetfarm = item?.vetFarm?.vet?.user?.fullname + ? item?.vetFarm?.vet?.user?.fullname + + `(${item?.vetFarm?.vet?.user?.mobile})` + : "فاقد دامپزشک"; + + let state = ""; + if (item.vetState === "accepted") { + state = "تایید تخلیه"; + } else if (item.vetState === "pending") { + state = "در انتظار تخلیه"; + } + return [ + item.barCode, + `${item.killhouseUser?.name} (${item.killhouseUser?.killHouseOperator?.user?.mobile})`, + `${item.addCar.driver.typeCar} ${item.addCar.driver.pelak}`, + `${item.addCar.driver.driverName} (${item.addCar.driver.driverMobile})`, + item?.trafficCode, + item.poultryRequest.chickenBreed, + item.quantity?.toLocaleString(), + item?.weightInfo?.weight?.toLocaleString(), + item?.weightInfo?.indexWeight?.toLocaleString(), + `${item.poultryRequest?.poultry?.unitName} (${item.poultryRequest.poultry?.user?.mobile})`, + vetfarm, + item?.clearanceCode ? item?.clearanceCode : "-", + item.killPlace, + item.poultryRequest.poultry.address.city.name, + item?.poultryRequest.sendDate + ? format(new Date(item?.poultryRequest.sendDate), "yyyy/MM/dd") + : "-", + item?.poultryRequest.orderCode, + state, + ]; + }); + setDataTable(d); + }, [item]); + + return ( + + ); +}; diff --git a/src/features/slaughter-house/components/slaughter-unpaid-fees/SlaughterUnpaidFees.js b/src/features/slaughter-house/components/slaughter-unpaid-fees/SlaughterUnpaidFees.js new file mode 100644 index 0000000..28c9f7c --- /dev/null +++ b/src/features/slaughter-house/components/slaughter-unpaid-fees/SlaughterUnpaidFees.js @@ -0,0 +1,604 @@ +import { + Button, + Checkbox, + Divider, + FormControlLabel, + Pagination, + TextField, + Tooltip, + Typography, +} from "@mui/material"; +import axios from "axios"; +import { useContext, useEffect, useState } from "react"; +import { useDispatch, useSelector } from "react-redux"; +import { Grid } from "../../../../components/grid/Grid"; +import { PageTable } from "../../../../components/page-table/PageTable"; +import { SPACING } from "../../../../data/spacing"; +import { + DRAWER, + LOADING_END, + LOADING_START, + OPEN_MODAL, +} from "../../../../lib/redux/slices/appSlice"; +import { formatJustDate } from "../../../../utils/formatTime"; +import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl"; +import { SlaughterPayingFeesOverview } from "../slaughter-paying-fees-overview/SlaughterPayingFeesOverview"; +import { SlaughterUnpaidFeesDetails } from "../slaughter-unpaid-fees-details/SlaughterUnpaidFeesDetails"; +import { RiFileExcel2Fill, RiSearchLine } from "react-icons/ri"; +import BoxList from "../../../../components/box-list/BoxList"; +import { AppContext } from "../../../../contexts/AppContext"; +import { DatePicker } from "@mui/x-date-pickers"; +import moment from "moment"; + +export const SlaughterUnpaidFees = () => { + const [, , selectedDate1, setSelectedDate1, selectedDate2, setSelectedDate2] = + useContext(AppContext); + const [withDate, setWithDate] = useState(false); + const [checked, setChecked] = useState(false); + + useEffect(() => { + const currentDate = moment(new Date()).format("YYYY-MM-DD"); + setSelectedDate1(currentDate); + setSelectedDate2(currentDate); + }, []); + + const dispatch = useDispatch(); + const [data, setData] = useState([]); + const [loading, setLoading] = useState(false); + const [totalRows, setTotalRows] = useState(0); + const [perPage, setPerPage] = useState(50); + const userInfo = useSelector((state) => state.userSlice); + const [selectedItems, setSelectedItems] = useState([]); + const [selectedItemsFull, setSelectedItemsFull] = useState([]); + const [dataTableM, setDataTableM] = useState([]); + const [totalSelectedFees, setTotalSelectedFees] = useState(0); + + const [textValue, setTextValue] = useState(""); + + const totalSelectedWeight = selectedItemsFull?.reduce((accumulator, item) => { + if (selectedItems.includes(item.provinceRequest.provinceKillRequestKey)) { + return ( + accumulator + item?.provinceRequest?.provinceKillRequestTotalWeight + ); + } + return accumulator; + }, 0); + + const handleTextChange = (event) => { + setTextValue(event.target.value); + }; + + const handleSelectedItems = (itemKey, itemFull) => { + setSelectedItems((prevSelectedItems) => { + if (prevSelectedItems.includes(itemKey)) { + const filtered = prevSelectedItems.filter((item) => item !== itemKey); + setSelectedItemsFull((prevSelectedItemsFull) => + prevSelectedItemsFull.filter( + (item) => item.provinceRequest.provinceKillRequestKey !== itemKey + ) + ); + return filtered; + } else { + setSelectedItemsFull((prevSelectedItemsFull) => [ + ...prevSelectedItemsFull, + itemFull, + ]); + return [...prevSelectedItems, itemKey]; + } + }); + }; + + useEffect(() => { + const updateTotalSelectedFees = async () => { + await setTotalSelectedFees((prevTotalSelectedFees) => { + let accumulatedFees = prevTotalSelectedFees; + + data.forEach((item) => { + if (checked) { + if ( + accumulatedFees + item.provinceRequest.totalAmount <= + 1000000000 + ) { + accumulatedFees += item.provinceRequest.totalAmount; + handleSelectedItems( + item.provinceRequest.provinceKillRequestKey, + item + ); + } + } else { + setSelectedItems([]); + setSelectedItemsFull([]); + } + }); + return accumulatedFees; + }); + }; + + updateTotalSelectedFees(); + }, [checked]); + + useEffect(() => { + const newTotalSelectedFees = selectedItemsFull?.reduce( + (accumulator, item) => { + if ( + selectedItems.includes(item.provinceRequest.provinceKillRequestKey) + ) { + return accumulator + item?.provinceRequest?.totalAmount; + } + return accumulator; + }, + 0 + ); + + setTotalSelectedFees(newTotalSelectedFees); + }, [selectedItemsFull, selectedItems]); + + const fetchApiData = async (page, textValue) => { + setLoading(true); + const response = await axios.get( + `province_wage/?type=unpaid&search=filter&value=${textValue}&role=${getRoleFromUrl()}&page=${page}&page_size=${perPage}${ + withDate ? `&date1=${selectedDate1}&date2=${selectedDate2}` : `` + }` + ); + setData(response.data.results); + setTotalRows(response.data.count); + setLoading(false); + dispatch(LOADING_END()); + }; + + const [page, setPage] = useState(0); + const handleChangePageM = (event, newPage) => { + dispatch(LOADING_START()); + setPage(newPage); + fetchApiData(newPage + 1, textValue); + }; + + const handlePageChange = (page) => { + fetchApiData(page, textValue); + }; + + const handlePerRowsChange = async (newPerPage, page) => { + setLoading(true); + const response = await axios.get( + `province_wage/?type=unpaid&search=filter&value=${textValue}&role=${getRoleFromUrl()}&page=${page}&page_size=${newPerPage}${ + withDate ? `&date1=${selectedDate1}&date2=${selectedDate2}` : `` + }` + ); + setData(response.data.results); + setTotalRows(response.data.count); + setPerPage(newPerPage); + + setLoading(false); + }; + + useEffect(() => { + fetchApiData(1); + }, []); + + const updateTable = () => { + return fetchApiData(1); + }; + + const handleSubmit = async (event) => { + event.preventDefault(); + setLoading(true); + + try { + const response = await axios.get( + `province_wage/?type=unpaid&role=${getRoleFromUrl()}&search=filter&value=${textValue}${ + withDate ? `&date1=${selectedDate1}&date2=${selectedDate2}` : `` + }` + ); + setData(response.data.results); + setTotalRows(response.data.count); + } catch (error) { + console.error("Error fetching data:", error); + } finally { + setLoading(false); + } + }; + + useEffect(() => { + fetchApiData(1); + }, [selectedDate1, selectedDate2, withDate]); + + const columns = [ + { + name: "انتخاب", + selector: (item) => ( + + handleSelectedItems( + item.provinceRequest.provinceKillRequestKey, + item + ) + } + color="primary" + /> + } + /> + ), + sortable: true, + wrap: true, + allowOverflow: true, + center: true, + // width: "50px", + }, + { + name: "کدسفارش", + selector: (item) => item?.provinceRequest?.orderCode, + sortable: true, + wrap: true, + allowOverflow: true, + center: true, + // width: "90px", + }, + { + name: "مرغدار (تلفن)", + selector: (item) => + `${item?.provinceRequest?.poultryFullname} (${item?.provinceRequest?.poultryMobile})`, + sortable: true, + wrap: true, + allowOverflow: true, + center: true, + // width: "90px", + }, + { + name: "شهر", + selector: (item) => `${item?.provinceRequest?.poultryCity}`, + sortable: true, + wrap: true, + allowOverflow: true, + center: true, + // width: "80px", + }, + { + name: "تاریخ کشتار", + selector: (item) => formatJustDate(item?.provinceRequest?.sendDate), + sortable: true, + wrap: true, + allowOverflow: true, + center: true, + // width: "80px", + }, + { + name: "محل کشتار", + selector: (item) => item?.provinceRequest?.killPlace, + sortable: true, + wrap: true, + allowOverflow: true, + center: true, + }, + // { + // name: "نژاد", + // selector: (item) => item?.provinceRequest?.breed, + // sortable: true, + // wrap: true, + // allowOverflow: true, + // center: true, + // // width: "80px", + // }, + { + name: "تعداد (قطعه)", + selector: (item) => + item?.provinceRequest?.provinceKillRequestQuantity?.toLocaleString(), + sortable: true, + wrap: true, + allowOverflow: true, + center: true, + // width: "80px", + }, + { + name: "وزن (کیلوگرم)", + selector: (item) => + item?.provinceRequest?.provinceKillRequestTotalWeight?.toLocaleString(), + sortable: true, + wrap: true, + allowOverflow: true, + center: true, + // width: "90px", + }, + { + name: "میانگین وزنی (کیلوگرم)", + selector: (item) => item?.provinceRequest?.indexWeight, + sortable: true, + wrap: true, + allowOverflow: true, + center: true, + // width: "90px", + }, + { + name: "تعرفه اتحادیه (ریال)", + selector: (item) => item?.provinceRequest?.wage?.toLocaleString(), + sortable: true, + wrap: true, + allowOverflow: true, + center: true, + // width: "90px", + }, + { + name: "مبلغ کل تعرفه (ریال)", + selector: (item) => item?.provinceRequest?.totalAmount?.toLocaleString(), + sortable: true, + wrap: true, + allowOverflow: true, + center: true, + // width: "90px", + }, + { + name: "جزییات سفارش", + selector: (item) => ( + + ), + sortable: true, + wrap: true, + allowOverflow: true, + center: true, + // width: "90px", + }, + ]; + + const paymentDisabled = + !selectedItems.length || totalSelectedFees > 1000000000; + + const tableTitle = ( + + + انتخاب همه + { + setChecked(!checked); + }} + color="primary" + /> + + + + setWithDate(!withDate)} + color="primary" + /> + } + /> + + + ( + + )} + value={selectedDate1} + onChange={(e) => { + setSelectedDate1(moment(e).format("YYYY-MM-DD")); + }} + /> + + + ( + + )} + value={selectedDate2} + onChange={(e) => { + setSelectedDate2(moment(e).format("YYYY-MM-DD")); + }} + /> + + +
    + + + + + + + + + +
    + + + + مبلغ کل: {totalSelectedFees.toLocaleString()} ریال + + + + تعداد سفارش: {selectedItems?.length} + + + + + +
    + ); + + const isMobile = window.innerWidth <= 600; + + useEffect(() => { + const d = data?.map((item, i) => { + return [ + + handleSelectedItems( + item.provinceRequest.provinceKillRequestKey, + item + ) + } + color="primary" // Change the color to your preference + /> + } + />, + item?.provinceRequest?.orderCode, + `${item?.provinceRequest?.poultryCity}`, + item?.provinceRequest?.totalAmount?.toLocaleString(), + , + ]; + }); + + setDataTableM(d); + }, [data]); + + return ( + + + تعرفه های پرداخت نشده + + + {isMobile ? ( + <> + {tableTitle} + + { + handleChangePageM(event, newPage - 1); + }} + /> + + ) : ( + + )} + + ); +}; diff --git a/src/features/slaughter-house/components/slaughterdailylistoperatore/SlaughterDailyListOperation.js b/src/features/slaughter-house/components/slaughterdailylistoperatore/SlaughterDailyListOperation.js new file mode 100644 index 0000000..6766457 --- /dev/null +++ b/src/features/slaughter-house/components/slaughterdailylistoperatore/SlaughterDailyListOperation.js @@ -0,0 +1,114 @@ +import { IconButton, Popover, Tooltip } from "@mui/material"; +import { useState } from "react"; +import TuneIcon from "@mui/icons-material/Tune"; +import { Grid } from "../../../../components/grid/Grid"; +import DeleteIcon from "@mui/icons-material/Delete"; + +export const SlaughterDailyListOperation = ({ item, updateTable }) => { + // const dispatch = useDispatch(); + const [anchorEl, setAnchorEl] = useState(null); + + const handleClick = (event) => { + setAnchorEl(event.currentTarget); + }; + + const handleClose = () => { + setAnchorEl(null); + }; + + const open = Boolean(anchorEl); + const id = open ? "popover" : undefined; + + // const [openNotif] = useContext(AppContext); + return ( +
    + + + + +
    + + + { + handleClose(); + // dispatch( + // OPEN_MODAL({ + // title: "آیا مطمئن هستید؟", + // content: ( + // + // + // + // + // + // + // + // + // ), + // }) + // ); + }} + > + + + + +
    +
    +
    + ); +}; diff --git a/src/features/slaughter-house/components/submit-auth-code/SubmitAuthCode.js b/src/features/slaughter-house/components/submit-auth-code/SubmitAuthCode.js new file mode 100644 index 0000000..705d5ee --- /dev/null +++ b/src/features/slaughter-house/components/submit-auth-code/SubmitAuthCode.js @@ -0,0 +1,91 @@ +import { Button, TextField } from "@mui/material"; +import { useFormik } from "formik"; +import { useContext } from "react"; +import { useDispatch, useSelector } from "react-redux"; +import { Grid } from "../../../../components/grid/Grid"; +import { AppContext } from "../../../../contexts/AppContext"; +import { SPACING } from "../../../../data/spacing"; +import { CLOSE_MODAL } from "../../../../lib/redux/slices/appSlice"; +import { Yup } from "../../../../lib/yup/yup"; +import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl"; +import { slaughterManageInventoryAllocationsService } from "../../services/salughter-manage-inventory-allocations"; +import { slaughterAuthCodeSubmitService } from "../../services/slaughter-auth-code-submit"; + +const validationSchema = Yup.object({ + phoneNumber: Yup.string() + .matches(/^\d+$/, "فقط عدد مجاز است") + .required("کداحراز اجباری است"), +}); + +export const SubmitAuthCode = ({ item }) => { + const dispatch = useDispatch(); + const [openNotif] = useContext(AppContext); + const [, , selectedDate1] = useContext(AppContext); + + const { inventorySelectedKillHouse } = useSelector( + (state) => state.slaughterSlice + ); + + const formik = useFormik({ + initialValues: { + phoneNumber: "", + }, + validationSchema: validationSchema, + onSubmit: (values) => { + dispatch( + slaughterAuthCodeSubmitService({ + logged_registration_code: values.phoneNumber, + steward_allocation_key: item.key, + role: getRoleFromUrl(), + }) + ).then((r) => { + dispatch(CLOSE_MODAL()); + if (r.payload.error) { + openNotif({ + vertical: "top", + horizontal: "center", + msg: r.payload.error, + severity: "error", + }); + } else { + dispatch( + slaughterManageInventoryAllocationsService({ + kill_house_key: inventorySelectedKillHouse, + date: selectedDate1, + }) + ); + openNotif({ + vertical: "top", + horizontal: "center", + msg: "عملیات با موفقیت انجام شد.", + severity: "success", + }); + } + }); + }, + }); + + return ( +
    + + + + +
    + ); +}; diff --git a/src/features/slaughter-house/services/edit-verification-direct-buying-code.js b/src/features/slaughter-house/services/edit-verification-direct-buying-code.js new file mode 100644 index 0000000..01f4f63 --- /dev/null +++ b/src/features/slaughter-house/services/edit-verification-direct-buying-code.js @@ -0,0 +1,18 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const verificationDirectBuyingCode = createAsyncThunk( + "VERFICATION_DIRECT_BUYING_CODE", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + try { + const { data, status } = await axios.put("kill_request/0/", d); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e.response.data.result }; + } + } +); diff --git a/src/features/slaughter-house/services/edit_bar_clearance_code.js b/src/features/slaughter-house/services/edit_bar_clearance_code.js new file mode 100644 index 0000000..f927b0f --- /dev/null +++ b/src/features/slaughter-house/services/edit_bar_clearance_code.js @@ -0,0 +1,18 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const editBarClearanceBar = createAsyncThunk( + "EDIT_BAR_CLEARANCE_BAR", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + try { + const { data, status } = await axios.put("kill_house_free_bar/0/", d); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e.response.data.result }; + } + } +); diff --git a/src/features/slaughter-house/services/get-wallet-balance.js b/src/features/slaughter-house/services/get-wallet-balance.js new file mode 100644 index 0000000..d51fce5 --- /dev/null +++ b/src/features/slaughter-house/services/get-wallet-balance.js @@ -0,0 +1,19 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; +import { getRoleFromUrl } from "../../../utils/getRoleFromUrl"; + +export const slaughterGetWalletBalance = createAsyncThunk( + "SLAUGHTER_GET_WALLET_BALANCE", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + const { data, status } = await axios.get("system-wallet/", { + params: { + role: getRoleFromUrl(), + type: "self", + }, + }); + dispatch(LOADING_END()); + return { data, status }; + } +); diff --git a/src/features/slaughter-house/services/handle-fetch-slaughter-products.js b/src/features/slaughter-house/services/handle-fetch-slaughter-products.js new file mode 100644 index 0000000..dd50ce8 --- /dev/null +++ b/src/features/slaughter-house/services/handle-fetch-slaughter-products.js @@ -0,0 +1,65 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; +import { getRoleFromUrl } from "../../../utils/getRoleFromUrl"; +import axios from "axios"; + +export const fetchSlaughterBroadcastAndProducts = createAsyncThunk( + "SLAUGHTER_FETCH_BROADCAST_AND_PRODUCTS", + async (d, { dispatch }) => { + try { + dispatch(LOADING_START()); + const [broadcastResponse, productsResponse] = await Promise.all([ + axios.get( + `${ + getRoleFromUrl() === "KillHouse" ? "kill-house" : "steward" + }-sales-info-dashboard/`, + { + params: { + role: getRoleFromUrl(), + ...d, + }, + } + ), + axios.get("roles-products", { + params: { + role: getRoleFromUrl(), + role_key: d.role_key || "", + }, + }), + ]); + + dispatch(LOADING_END()); + + return { + broadcastData: broadcastResponse.data, + productsData: productsResponse.data, + }; + } catch (error) { + dispatch(LOADING_END()); + throw error; + } + } +); + +export const fetchRolesProducts = createAsyncThunk( + "SLAUGHTER_FETCH_ROLES_PRODUCTS", + async (d, { dispatch }) => { + try { + dispatch(LOADING_START()); + const productsResponse = await axios.get("roles-products", { + params: { + role: getRoleFromUrl(), + role_key: d.role_key || "", + }, + }); + dispatch(LOADING_END()); + + return { + productsData: productsResponse.data, + }; + } catch (error) { + dispatch(LOADING_END()); + throw error; + } + } +); diff --git a/src/features/slaughter-house/services/killhouse-assignment-information-aggregate-load.js b/src/features/slaughter-house/services/killhouse-assignment-information-aggregate-load.js new file mode 100644 index 0000000..a38d642 --- /dev/null +++ b/src/features/slaughter-house/services/killhouse-assignment-information-aggregate-load.js @@ -0,0 +1,22 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const killHouseAssignmentInformationAggregateLoadService = + createAsyncThunk( + "KILL_HOUSE_ASSIGNMENT_INFORMATION_AGGREGATE_LOAD_SERVICE", + async (d, { dispatch }) => { + try { + dispatch(LOADING_START()); + const { data, status } = await axios.put( + "kill_house_assignment_information_aggregate_load/0/", + d + ); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e.response.data.result }; + } + } + ); diff --git a/src/features/slaughter-house/services/killhouse-broadcast-management-move-to-pre-cold.js b/src/features/slaughter-house/services/killhouse-broadcast-management-move-to-pre-cold.js new file mode 100644 index 0000000..28181b4 --- /dev/null +++ b/src/features/slaughter-house/services/killhouse-broadcast-management-move-to-pre-cold.js @@ -0,0 +1,16 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const killHouseBroadCastManagementMoveToPreCold = createAsyncThunk( + "KILL_HOUSE_MOVE_TO_PRE_COLD", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + const { data, status } = await axios.post( + "pre-cold-kill-house-ware-house/", + d + ); + dispatch(LOADING_END()); + return { data, status }; + } +); diff --git a/src/features/slaughter-house/services/killhouse-submit-real-inventory.js b/src/features/slaughter-house/services/killhouse-submit-real-inventory.js new file mode 100644 index 0000000..55fb535 --- /dev/null +++ b/src/features/slaughter-house/services/killhouse-submit-real-inventory.js @@ -0,0 +1,21 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const killhouseSubmitRealInventoryService = createAsyncThunk( + "SLAUGHTER_SUBMIT_REAL_INVENTORY", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + try { + const { data, status } = await axios.put( + "ware-house-accept-kill-house-request/0/", + d + ); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e.response.data.result }; + } + } +); diff --git a/src/features/slaughter-house/services/payment-get-deadlines.js b/src/features/slaughter-house/services/payment-get-deadlines.js new file mode 100644 index 0000000..e363313 --- /dev/null +++ b/src/features/slaughter-house/services/payment-get-deadlines.js @@ -0,0 +1,12 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; + +export const paymentGetDeadLines = createAsyncThunk( + "PAYMENT_GET_DEADLINES", + async (d) => { + const { data, status } = await axios.get("direct-buying-verification/", { + params: d, + }); + return { data, status }; + } +); diff --git a/src/features/slaughter-house/services/province-accept-slaughter-free-buy.js b/src/features/slaughter-house/services/province-accept-slaughter-free-buy.js new file mode 100644 index 0000000..668d661 --- /dev/null +++ b/src/features/slaughter-house/services/province-accept-slaughter-free-buy.js @@ -0,0 +1,18 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const provinceAcceptSlaughterFreeBuyService = createAsyncThunk( + "PROVINCE_ACCEPT_SLAUGHTER_FREE_BUY_SERVICE", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + try { + const { data, status } = await axios.post("check_direct_buying/", d); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e.response.data.result }; + } + } +); diff --git a/src/features/slaughter-house/services/province-dispenser-delete-sale-out.js b/src/features/slaughter-house/services/province-dispenser-delete-sale-out.js new file mode 100644 index 0000000..bbbacdb --- /dev/null +++ b/src/features/slaughter-house/services/province-dispenser-delete-sale-out.js @@ -0,0 +1,17 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const provinceDispenserDeleteService = createAsyncThunk( + "PROVINCE_DELETE_ALLOCATED_SERVICE", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + const { data, status } = await axios.delete("kill_house_free_sale_bar/0/", { + params: { + key: d.key, + }, + }); + dispatch(LOADING_END()); + return { data, status }; + } +); diff --git a/src/features/slaughter-house/services/province-reject-slaughter-free-buy.js b/src/features/slaughter-house/services/province-reject-slaughter-free-buy.js new file mode 100644 index 0000000..adec571 --- /dev/null +++ b/src/features/slaughter-house/services/province-reject-slaughter-free-buy.js @@ -0,0 +1,18 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const provinceRejectSlaughterFreeBuyService = createAsyncThunk( + "PROVINCE_REJECT_SLAUGHTER_FREE_BUY_SERVICE", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + try { + const { data, status } = await axios.post("check_direct_buying/", d); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e.response.data.result }; + } + } +); diff --git a/src/features/slaughter-house/services/salughter-aggregate-quantity.js b/src/features/slaughter-house/services/salughter-aggregate-quantity.js new file mode 100644 index 0000000..1e31500 --- /dev/null +++ b/src/features/slaughter-house/services/salughter-aggregate-quantity.js @@ -0,0 +1,21 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const salughterAggregateQuantityService = createAsyncThunk( + "SALUGHTER_AGGREGATE_QUANTITY_SERVICE", + async (d, { dispatch }) => { + try { + dispatch(LOADING_START()); + const { data, status } = await axios.post( + "kill_house_assignment_information_aggregate_load/", + d + ); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e.response.data.result }; + } + } +); diff --git a/src/features/slaughter-house/services/salughter-delete-allocated.js b/src/features/slaughter-house/services/salughter-delete-allocated.js new file mode 100644 index 0000000..9b4e740 --- /dev/null +++ b/src/features/slaughter-house/services/salughter-delete-allocated.js @@ -0,0 +1,36 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const slaughterDeleteAllocatedService = createAsyncThunk( + "SLAUGHTER_DELETE_ALLOCATED_SERVICE", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + const { data, status } = await axios.delete("steward-allocation/0/", { + params: { + steward_allocation_key: d.steward_allocation_key, + role_key: d.role_key || "", + }, + }); + dispatch(LOADING_END()); + return { data, status }; + } +); + +export const slaughterReturnAllocatedService = createAsyncThunk( + "SLAUGHTER_RETURN_ALLOCATED_SERVICE", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + try { + const { data, status } = await axios.put( + "return-deleted-allocation/0/", + d + ); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e.response.data.result }; + } + } +); diff --git a/src/features/slaughter-house/services/salughter-get-aggregate-load-information.js b/src/features/slaughter-house/services/salughter-get-aggregate-load-information.js new file mode 100644 index 0000000..53109c9 --- /dev/null +++ b/src/features/slaughter-house/services/salughter-get-aggregate-load-information.js @@ -0,0 +1,22 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; +import { getRoleFromUrl } from "../../../utils/getRoleFromUrl"; + +export const slaughterGetAggregateLoadInformationService = createAsyncThunk( + "SLAUGHTER_GET_AGGREGATE_LOAD_INFORMATION_SERVICE", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + const { data, status } = await axios.get( + "kill_house_request_aggregate_load/", + { + params: { + role: getRoleFromUrl(), + date: d.date, + }, + } + ); + dispatch(LOADING_END()); + return { data, status }; + } +); diff --git a/src/features/slaughter-house/services/salughter-get-inventory-stock.js b/src/features/slaughter-house/services/salughter-get-inventory-stock.js new file mode 100644 index 0000000..38a0148 --- /dev/null +++ b/src/features/slaughter-house/services/salughter-get-inventory-stock.js @@ -0,0 +1,18 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const slaughterGetInventoryStock = createAsyncThunk( + "SLAUGHTER_GET_INVENTORY_STOCK", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + const { data, status } = await axios.get("kill_house_ware_house/", { + params: { + kill_house_key: d.kill_house_key, + date: d.date, + }, + }); + dispatch(LOADING_END()); + return { data, status }; + } +); diff --git a/src/features/slaughter-house/services/salughter-get-poultries.js b/src/features/slaughter-house/services/salughter-get-poultries.js new file mode 100644 index 0000000..ed35309 --- /dev/null +++ b/src/features/slaughter-house/services/salughter-get-poultries.js @@ -0,0 +1,23 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; +import { getRoleFromUrl } from "../../../utils/getRoleFromUrl"; + +export const slaughterGetPoultriesService = createAsyncThunk( + "SLAUGHTER_GET_POULTRIES_SERVICE", + async (d = {}, { dispatch }) => { + dispatch(LOADING_START()); + const { data, status } = await axios.get( + "get-all-poultry-for-increase-hatching/", + { + params: { + role: getRoleFromUrl(), + active_hatching: true, + ...d, + }, + } + ); + dispatch(LOADING_END()); + return { data, status }; + } +); diff --git a/src/features/slaughter-house/services/salughter-get-requests.js b/src/features/slaughter-house/services/salughter-get-requests.js new file mode 100644 index 0000000..8c64079 --- /dev/null +++ b/src/features/slaughter-house/services/salughter-get-requests.js @@ -0,0 +1,21 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; +import { getRoleFromUrl } from "../../../utils/getRoleFromUrl"; + +export const slaughterGetRequests = createAsyncThunk( + "SLAUGHTER_GET_REQUESTS", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + const { data, status } = await axios.get("kill_request/", { + params: { + role: getRoleFromUrl(), + role_key: d?.role_key || "", + date1: d.selectedDate1, + date2: d.selectedDate2, + }, + }); + dispatch(LOADING_END()); + return { data, status }; + } +); diff --git a/src/features/slaughter-house/services/salughter-get-updated-inventory-stock.js b/src/features/slaughter-house/services/salughter-get-updated-inventory-stock.js new file mode 100644 index 0000000..8fd6833 --- /dev/null +++ b/src/features/slaughter-house/services/salughter-get-updated-inventory-stock.js @@ -0,0 +1,19 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const slaughterGetUpdatedInventoryStock = createAsyncThunk( + "SLAUGHTER_GET_UPDATED_INVENTORY_STOCK", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + const { data, status } = await axios.get("kill_house_ware_house/", { + params: { + kill_house_key: d.kill_house_key, + date: d.date, + state: "update", + }, + }); + dispatch(LOADING_END()); + return { data, status }; + } +); diff --git a/src/features/slaughter-house/services/salughter-manage-inventory-allocations.js b/src/features/slaughter-house/services/salughter-manage-inventory-allocations.js new file mode 100644 index 0000000..4ec1ae1 --- /dev/null +++ b/src/features/slaughter-house/services/salughter-manage-inventory-allocations.js @@ -0,0 +1,18 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const slaughterManageInventoryAllocationsService = createAsyncThunk( + "SLAUGHTER_MANAGE_INVENTORY_ALLOCATIONS_SERVICE", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + const { data, status } = await axios.get("steward-allocation/", { + params: { + kill_house_key: d.kill_house_key, + date: d.date, + }, + }); + dispatch(LOADING_END()); + return { data, status }; + } +); diff --git a/src/features/slaughter-house/services/salughter-pay.js b/src/features/slaughter-house/services/salughter-pay.js new file mode 100644 index 0000000..3a9f687 --- /dev/null +++ b/src/features/slaughter-house/services/salughter-pay.js @@ -0,0 +1,13 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const slaughterPayService = createAsyncThunk( + "SLAUGHTER_PAY_SERVICE", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + const { data, status } = await axios.get("https://rasadyaar.ir/"); + dispatch(LOADING_END()); + return { data, status }; + } +); diff --git a/src/features/slaughter-house/services/salughter-paying-fees-manual.js b/src/features/slaughter-house/services/salughter-paying-fees-manual.js new file mode 100644 index 0000000..70d880a --- /dev/null +++ b/src/features/slaughter-house/services/salughter-paying-fees-manual.js @@ -0,0 +1,13 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const slaughterPayingFeesManual = createAsyncThunk( + "SLAUGHTER_PAYING_FEES_MANUAL", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + const { data, status } = await axios.post("wage_payment/", d); + dispatch(LOADING_END()); + return { data, status }; + } +); diff --git a/src/features/slaughter-house/services/salughter-payment-refid.js b/src/features/slaughter-house/services/salughter-payment-refid.js new file mode 100644 index 0000000..6ddac71 --- /dev/null +++ b/src/features/slaughter-house/services/salughter-payment-refid.js @@ -0,0 +1,10 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; + +export const slaughterPaymentRefIdService = createAsyncThunk( + "SLAUGHTER_PAYMENT_REF_ID", + async (d, { dispatch }) => { + const { data, status } = await axios.post("wage_payment/", d); + return { data, status }; + } +); diff --git a/src/features/slaughter-house/services/salughter-total-report-daily-broad-cast.js b/src/features/slaughter-house/services/salughter-total-report-daily-broad-cast.js new file mode 100644 index 0000000..a606f7e --- /dev/null +++ b/src/features/slaughter-house/services/salughter-total-report-daily-broad-cast.js @@ -0,0 +1,21 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const totalReportDailyBroadCastService = createAsyncThunk( + "TOTAL_REPORT_DAILY_BROADCAST_SERVICE", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + const { data, status } = await axios.get( + `kill_house_ware_house_total_report_daily_broad_cast`, + { + params: { + date1: d.selectedDate1, + date2: d.selectedDate2, + }, + } + ); + dispatch(LOADING_END()); + return { data, status }; + } +); diff --git a/src/features/slaughter-house/services/slaughetr-morgue-services.js b/src/features/slaughter-house/services/slaughetr-morgue-services.js new file mode 100644 index 0000000..ae15269 --- /dev/null +++ b/src/features/slaughter-house/services/slaughetr-morgue-services.js @@ -0,0 +1,36 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; +import { getRoleFromUrl } from "../../../utils/getRoleFromUrl"; + +export const slaughterGetMorgueDashboardService = createAsyncThunk( + "SLAUGHTER_GET_MORGUE_DASHBOARD", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + const { data, status } = await axios.get( + "total-cold-house-dashboard-roles/", + { + params: { + role: getRoleFromUrl(), + ...d, + }, + } + ); + dispatch(LOADING_END()); + return { data, status }; + } +); + +export const slaughterGetMorguesService = createAsyncThunk( + "SLAUGHTER_GET_MORGUES", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + const { data, status } = await axios.get("kill-house-cold-houses/", { + params: { + role: getRoleFromUrl(), + }, + }); + dispatch(LOADING_END()); + return { data, status }; + } +); diff --git a/src/features/slaughter-house/services/slaughter-add-daily-list.js b/src/features/slaughter-house/services/slaughter-add-daily-list.js new file mode 100644 index 0000000..35074a1 --- /dev/null +++ b/src/features/slaughter-house/services/slaughter-add-daily-list.js @@ -0,0 +1,74 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; +import axios from "axios"; +import { getRoleFromUrl } from "../../../utils/getRoleFromUrl"; + +export const slaughterGetPriceService = createAsyncThunk( + "SLAUGHTER_GET_PRICE_SERVICE", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + const { data, status } = await axios.get("broadcast-price/", { + params: { ...d }, + }); + dispatch(LOADING_END()); + return { data, status }; + } +); + +export const slaughterGetGuildsService = createAsyncThunk( + "SLAUGHTER_GET_GUILDS_FOR_COMMONLY_USED", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + + const { data, status } = await axios.get("guilds/", { + params: { + role: getRoleFromUrl(), + commonly_used: true, + ...d, + }, + }); + + dispatch(LOADING_END()); + return { data, status }; + } +); + +export const slaughterAddDailyListService = createAsyncThunk( + "SLAUGHTER_ADD_DAILY_LIST_SERVICE", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + const { data, status } = await axios.post("commonly-used/", { + role: getRoleFromUrl(), + guild_key_list: d.guild_key_list, + ...d, + }); + dispatch(LOADING_END()); + return { data, status }; + } +); +export const submitBatchAllocationsService = createAsyncThunk( + "SUBMIT_BATCH_ALLOCATIONS", + async (allocations, { dispatch }) => { + dispatch(LOADING_START()); + try { + const response = await axios.post("batch-steward-allocation/", { + allocations_list: allocations, + }); + return response.data; + } finally { + dispatch(LOADING_END()); + } + } +); + +export const slaughterDeleteDailyListService = createAsyncThunk( + "SLAUGHTER_DELETE_DAILY_LIST_SERVICE", + async (commonly_used_key, { dispatch }) => { + dispatch(LOADING_START()); + const { data, status } = await axios.delete( + `commonly-used/0/?commonly_used_key=${commonly_used_key}` + ); + dispatch(LOADING_END()); + return { data, status }; + } +); diff --git a/src/features/slaughter-house/services/slaughter-allocate-steward.js b/src/features/slaughter-house/services/slaughter-allocate-steward.js new file mode 100644 index 0000000..53b679a --- /dev/null +++ b/src/features/slaughter-house/services/slaughter-allocate-steward.js @@ -0,0 +1,33 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const slaughterAllocateStewardService = createAsyncThunk( + "SLAUGHTER_ALLOCATE_STEWARD_SERVICE", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + try { + const { data, status } = await axios.post("steward-allocation/", d); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e.response.data.result }; + } + } +); + +export const slaughterEditAllocateStewardService = createAsyncThunk( + "SLAUGHTER_EDIT_ALLOCATION_STEWARD_SERVICE", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + try { + const { data, status } = await axios.put("steward-allocation/0/", d); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e.response.data.result }; + } + } +); diff --git a/src/features/slaughter-house/services/slaughter-auth-code-submit.js b/src/features/slaughter-house/services/slaughter-auth-code-submit.js new file mode 100644 index 0000000..59c8922 --- /dev/null +++ b/src/features/slaughter-house/services/slaughter-auth-code-submit.js @@ -0,0 +1,18 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const slaughterAuthCodeSubmitService = createAsyncThunk( + "SLAUGHTER_AUTH_CODE_SUBMIT_SERVICE", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + try { + const { data, status } = await axios.put("steward-allocation/0/", d); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e.response.data.result }; + } + } +); diff --git a/src/features/slaughter-house/services/slaughter-bar-dashbored.js b/src/features/slaughter-house/services/slaughter-bar-dashbored.js new file mode 100644 index 0000000..4e35668 --- /dev/null +++ b/src/features/slaughter-house/services/slaughter-bar-dashbored.js @@ -0,0 +1,23 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; +import axios from "axios"; +import { getRoleFromUrl } from "../../../utils/getRoleFromUrl"; + +export const SlaughterBarDashboardService = createAsyncThunk( + "SLAUGHTER_BAR_DASHBOARD_SERVICE", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + const { data, status } = await axios.get("dashboarad_bar_for_kill_house", { + params: { + role: getRoleFromUrl(), + date1: d.selectedDate1, + date2: d.selectedDate2, + filter: "search", + value: d.textValue, + role_key: d.role_key || "", + }, + }); + dispatch(LOADING_END()); + return { data, status }; + } +); diff --git a/src/features/slaughter-house/services/slaughter-delete-allocated-back-kill-request.js b/src/features/slaughter-house/services/slaughter-delete-allocated-back-kill-request.js new file mode 100644 index 0000000..edae4b1 --- /dev/null +++ b/src/features/slaughter-house/services/slaughter-delete-allocated-back-kill-request.js @@ -0,0 +1,23 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const slaughterDeleteAllocatedBackRequestService = createAsyncThunk( + "SLAUGHTER_DELETE_ALLOCATED_BACK_KILL_REQUEST_SERVICE", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + try { + const { data, status } = await axios.delete( + `province_kill_request/0/?return_allocation_quantity=${true}&province_kill_request_key=${ + d.provinceKillRequestKey + }`, + d + ); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e.response.data.result }; + } + } +); diff --git a/src/features/slaughter-house/services/slaughter-delete-allocation-for-freezing.js b/src/features/slaughter-house/services/slaughter-delete-allocation-for-freezing.js new file mode 100644 index 0000000..6bba480 --- /dev/null +++ b/src/features/slaughter-house/services/slaughter-delete-allocation-for-freezing.js @@ -0,0 +1,20 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const slaughterDeleteAllocationForFreezing = createAsyncThunk( + "SLAUGHTER_DELETE_ALLOCATION_FOR_FREEZING", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + try { + const { data, status } = await axios.delete( + `cold-house-allocations/0/?allocation_key=${d}` + ); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e }; + } + } +); diff --git a/src/features/slaughter-house/services/slaughter-delete-car.js b/src/features/slaughter-house/services/slaughter-delete-car.js new file mode 100644 index 0000000..8d4840d --- /dev/null +++ b/src/features/slaughter-house/services/slaughter-delete-car.js @@ -0,0 +1,10 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; + +export const slaughterDeleteCar = createAsyncThunk( + "SLAUGHTER_DELETE_CAR", + async (id) => { + const { data, status } = await axios.delete("kill_house_add_car/" + id.id); + return { data, status }; + } +); diff --git a/src/features/slaughter-house/services/slaughter-delete-factor.js b/src/features/slaughter-house/services/slaughter-delete-factor.js new file mode 100644 index 0000000..3261aa8 --- /dev/null +++ b/src/features/slaughter-house/services/slaughter-delete-factor.js @@ -0,0 +1,18 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const slaughterDeleteFactorService = createAsyncThunk( + "SLAUGHTER_DELETE_FACTOR_SERVICE", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + try { + const { data, status } = await axios.put("kill_request_factor/0/", d); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e.response.data.result }; + } + } +); diff --git a/src/features/slaughter-house/services/slaughter-delete-free-buy.js b/src/features/slaughter-house/services/slaughter-delete-free-buy.js new file mode 100644 index 0000000..223a7ca --- /dev/null +++ b/src/features/slaughter-house/services/slaughter-delete-free-buy.js @@ -0,0 +1,21 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; +import { getRoleFromUrl } from "../../../utils/getRoleFromUrl"; + +export const slaughterDeleteFreeBuyService = createAsyncThunk( + "SLAUGHTER_DELETE_FREE_BUY_SERVICE", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + try { + const { data, status } = await axios.delete( + `kill_request/0/?role=${getRoleFromUrl()}&kill_request_key=${d}` + ); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e.response.data.result }; + } + } +); diff --git a/src/features/slaughter-house/services/slaughter-delete-inventory-free-bar.js b/src/features/slaughter-house/services/slaughter-delete-inventory-free-bar.js new file mode 100644 index 0000000..553bc56 --- /dev/null +++ b/src/features/slaughter-house/services/slaughter-delete-inventory-free-bar.js @@ -0,0 +1,20 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const slaughterDeleteInventoryFreeBarService = createAsyncThunk( + "SLAUGHTER_DELETE_INVENTORY_FREE_BAR_SERVICE", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + try { + const { data, status } = await axios.delete( + "kill_house_free_bar/0/?key=" + d + ); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e.response.data.result }; + } + } +); diff --git a/src/features/slaughter-house/services/slaughter-delete-out-province-sell.js b/src/features/slaughter-house/services/slaughter-delete-out-province-sell.js new file mode 100644 index 0000000..adfb364 --- /dev/null +++ b/src/features/slaughter-house/services/slaughter-delete-out-province-sell.js @@ -0,0 +1,20 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const slaughterDeleteOutOfProvinceSell = createAsyncThunk( + "SLAUGHTER_DELETE_OUT_OF_PROVINCE_SELL", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + try { + const { data, status } = await axios.delete( + `kill_house_free_sale_bar/0/?key=${d}` + ); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e }; + } + } +); diff --git a/src/features/slaughter-house/services/slaughter-delete-request.js b/src/features/slaughter-house/services/slaughter-delete-request.js new file mode 100644 index 0000000..b782b78 --- /dev/null +++ b/src/features/slaughter-house/services/slaughter-delete-request.js @@ -0,0 +1,10 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; + +export const slaughterDeleteRequest = createAsyncThunk( + "SLAUGHTER_DELETE_REQUEST", + async (id) => { + const { data, status } = await axios.delete("kill_request/" + id.id); + return { data, status }; + } +); diff --git a/src/features/slaughter-house/services/slaughter-edit-allocate-steward.js b/src/features/slaughter-house/services/slaughter-edit-allocate-steward.js new file mode 100644 index 0000000..2de1041 --- /dev/null +++ b/src/features/slaughter-house/services/slaughter-edit-allocate-steward.js @@ -0,0 +1,18 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const slaughterEditAllocateStewardService = createAsyncThunk( + "SLAUGHTER_EDIT_ALLOCATE_STEWARD_SERVICE", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + try { + const { data, status } = await axios.put("steward-allocation/0/", d); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e.response.data.result }; + } + } +); diff --git a/src/features/slaughter-house/services/slaughter-edit-allocated-car.js b/src/features/slaughter-house/services/slaughter-edit-allocated-car.js new file mode 100644 index 0000000..f303e62 --- /dev/null +++ b/src/features/slaughter-house/services/slaughter-edit-allocated-car.js @@ -0,0 +1,18 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const slaughterEditAllocatedCarService = createAsyncThunk( + "SLAUGHTER_EDIT_ALLOCATED_CAR_SERVICE", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + try { + const { data, status } = await axios.put("kill_house_requests/0/", d); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e.response?.data?.result || e.message }; + } + } +); diff --git a/src/features/slaughter-house/services/slaughter-edit-chicken-price.js b/src/features/slaughter-house/services/slaughter-edit-chicken-price.js new file mode 100644 index 0000000..07bfa49 --- /dev/null +++ b/src/features/slaughter-house/services/slaughter-edit-chicken-price.js @@ -0,0 +1,18 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const slaughterEditChickenPriceService = createAsyncThunk( + "SLAUGHTER_EDIT_CHICKEN_PRICE_SERVICE", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + try { + const { data, status } = await axios.put("province_kill_request/0/", d); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e.response.data.result }; + } + } +); diff --git a/src/features/slaughter-house/services/slaughter-edit-dispenser-info.js b/src/features/slaughter-house/services/slaughter-edit-dispenser-info.js new file mode 100644 index 0000000..8edf450 --- /dev/null +++ b/src/features/slaughter-house/services/slaughter-edit-dispenser-info.js @@ -0,0 +1,24 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const slaughterEditDispenserInfoService = createAsyncThunk( + "SLAUGHTER_EDIT_DISPENSER_INFO", + async (d, { dispatch }) => { + try { + dispatch(LOADING_START()); + const { data, status } = await axios.put("dispenser-info/0/", d); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { + error: + e.response?.data?.result || + e.response?.data || + "خطا در ویرایش وضعیت", + }; + } + } +); + diff --git a/src/features/slaughter-house/services/slaughter-edit-export.js b/src/features/slaughter-house/services/slaughter-edit-export.js new file mode 100644 index 0000000..b5fba75 --- /dev/null +++ b/src/features/slaughter-house/services/slaughter-edit-export.js @@ -0,0 +1,18 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const slaughterEditExportService = createAsyncThunk( + "SLAUGHTER_EDIT_FREE_BUY_SERVICE", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + try { + const { data, status } = await axios.put("kill_request/0/", d); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e.response.data.result }; + } + } +); diff --git a/src/features/slaughter-house/services/slaughter-edit-free-buy.js b/src/features/slaughter-house/services/slaughter-edit-free-buy.js new file mode 100644 index 0000000..15adff7 --- /dev/null +++ b/src/features/slaughter-house/services/slaughter-edit-free-buy.js @@ -0,0 +1,18 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const slaughterEditFreeBuyService = createAsyncThunk( + "SLAUGHTER_EDIT_FREE_BUY_SERVICE", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + try { + const { data, status } = await axios.put("kill_request/0/", d); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e.response.data.result }; + } + } +); diff --git a/src/features/slaughter-house/services/slaughter-edit-free-sale.js b/src/features/slaughter-house/services/slaughter-edit-free-sale.js new file mode 100644 index 0000000..e0b99f0 --- /dev/null +++ b/src/features/slaughter-house/services/slaughter-edit-free-sale.js @@ -0,0 +1,18 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const slaughterEditFreeSaleService = createAsyncThunk( + "SLAUGHTER_EDIT_FREE_SALE_SERVICE", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + try { + const { data, status } = await axios.put("kill_house_free_bar/0/", d); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e.response.data.result }; + } + } +); diff --git a/src/features/slaughter-house/services/slaughter-edit-stock.js b/src/features/slaughter-house/services/slaughter-edit-stock.js new file mode 100644 index 0000000..8877b3b --- /dev/null +++ b/src/features/slaughter-house/services/slaughter-edit-stock.js @@ -0,0 +1,18 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const slaughterEditStockService = createAsyncThunk( + "SLAUGHTER_EDIT_STOCK_SERVICE", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + try { + const { data, status } = await axios.put("kill_house_ware_house/0/", d); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e.response.data.result }; + } + } +); diff --git a/src/features/slaughter-house/services/slaughter-enter-bar-weight.js b/src/features/slaughter-house/services/slaughter-enter-bar-weight.js new file mode 100644 index 0000000..14357f1 --- /dev/null +++ b/src/features/slaughter-house/services/slaughter-enter-bar-weight.js @@ -0,0 +1,21 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const slaughterEnterBarWeight = createAsyncThunk( + "SLAUGHTER_ENTER_BAR_WEIGHT", + async (d, { dispatch }) => { + try { + dispatch(LOADING_START()); + const { data, status } = await axios.post( + "kill_house_assignment_information/", + d + ); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e.response.data.result }; + } + } +); diff --git a/src/features/slaughter-house/services/slaughter-enter-load-information-get-dashboard.js b/src/features/slaughter-house/services/slaughter-enter-load-information-get-dashboard.js new file mode 100644 index 0000000..5b2d044 --- /dev/null +++ b/src/features/slaughter-house/services/slaughter-enter-load-information-get-dashboard.js @@ -0,0 +1,31 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; +import { getRoleFromUrl } from "../../../utils/getRoleFromUrl"; + +export const slaughterEnterLoadInformationGetDashboard = createAsyncThunk( + "PROVINCE_GET_LOAD_INFO_DASHBOARD", + async (d, { dispatch }) => { + try { + dispatch(LOADING_START()); + const { data, status } = await axios.get( + "dashboard_enter_load_information", + { + params: { + date1: d.selectedDate1, + date2: d.selectedDate2, + role: getRoleFromUrl(), + filter: "search", + value: d.text ? d.text : "", + role_key: d.role_key || "", + }, + } + ); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e.response.data }; + } + } +); diff --git a/src/features/slaughter-house/services/slaughter-factors.js b/src/features/slaughter-house/services/slaughter-factors.js new file mode 100644 index 0000000..16e1a73 --- /dev/null +++ b/src/features/slaughter-house/services/slaughter-factors.js @@ -0,0 +1,15 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const slaughterFactorsService = createAsyncThunk( + "SLAUGHTER_FACTORS_SERVICE", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + const { data, status } = await axios.get("kill_request_factor/", { + params: { date1: d.selectedDate1, date2: d.selectedDate2 }, + }); + dispatch(LOADING_END()); + return { data, status }; + } +); diff --git a/src/features/slaughter-house/services/slaughter-final-factors.js b/src/features/slaughter-house/services/slaughter-final-factors.js new file mode 100644 index 0000000..d8cac83 --- /dev/null +++ b/src/features/slaughter-house/services/slaughter-final-factors.js @@ -0,0 +1,20 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; +import { getRoleFromUrl } from "../../../utils/getRoleFromUrl"; + +export const slaughterFinalFactorsService = createAsyncThunk( + "SLAUGHTER_FINAL_FACTORS_SERVICE", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + const { data, status } = await axios.get("province_factor_to_kill_house/", { + params: { + role: getRoleFromUrl(), + date1: d.selectedDate1, + date2: d.selectedDate2, + }, + }); + dispatch(LOADING_END()); + return { data, status }; + } +); diff --git a/src/features/slaughter-house/services/slaughter-free-buy-dashboard.js b/src/features/slaughter-house/services/slaughter-free-buy-dashboard.js new file mode 100644 index 0000000..6bcd3ff --- /dev/null +++ b/src/features/slaughter-house/services/slaughter-free-buy-dashboard.js @@ -0,0 +1,18 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const slaughterGetFreeBuyDashboardService = createAsyncThunk( + "SLAUGHTER_GET_FREE_BUY_DASHBOARD", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + const { data, status } = await axios.get( + "dashboard_kill_request/?operator=KillHouse", + { + params: d, + } + ); + dispatch(LOADING_END()); + return { data, status }; + } +); diff --git a/src/features/slaughter-house/services/slaughter-get-active-requests.js b/src/features/slaughter-house/services/slaughter-get-active-requests.js new file mode 100644 index 0000000..266d0e9 --- /dev/null +++ b/src/features/slaughter-house/services/slaughter-get-active-requests.js @@ -0,0 +1,21 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; +import { getRoleFromUrl } from "../../../utils/getRoleFromUrl"; +export const slaughterGetActiveRequests = createAsyncThunk( + "SLAUGHTER_GET_ACTIVE_REQUESTS", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + const car = d.isCar ? "car=true" : ""; + const { data, status } = await axios.get("province_kill_request/?" + car, { + params: { + date1: d.selectedDate1, + date2: d.selectedDate2, + role: getRoleFromUrl(), + role_key: d.role_key || "", + }, + }); + dispatch(LOADING_END()); + return { data, status }; + } +); diff --git a/src/features/slaughter-house/services/slaughter-get-allocated-cars.js b/src/features/slaughter-house/services/slaughter-get-allocated-cars.js new file mode 100644 index 0000000..ea12b75 --- /dev/null +++ b/src/features/slaughter-house/services/slaughter-get-allocated-cars.js @@ -0,0 +1,24 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; +import { getRoleFromUrl } from "../../../utils/getRoleFromUrl"; + +export const slaughterGetAllocatedCarsService = createAsyncThunk( + "SLAUGHTER_GET_ALLOCATED_CARS_SERVICE", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + const { data, status } = await axios.get( + "kill_house_request/?operator=KillHouse", + { + params: { + role: getRoleFromUrl(), + date1: d.selectedDate1, + date2: d.selectedDate2, + role_key: d.role_key || "", + }, + } + ); + dispatch(LOADING_END()); + return { data, status }; + } +); diff --git a/src/features/slaughter-house/services/slaughter-get-bar-info-requests.js b/src/features/slaughter-house/services/slaughter-get-bar-info-requests.js new file mode 100644 index 0000000..5198c6b --- /dev/null +++ b/src/features/slaughter-house/services/slaughter-get-bar-info-requests.js @@ -0,0 +1,23 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; +import { getRoleFromUrl } from "../../../utils/getRoleFromUrl"; + +export const slaughterGetBarInfoRequestsService = createAsyncThunk( + "SLAUGHTER_GET_BAR_INFO_REQUESTS", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + const { data, status } = await axios.get( + "kill_house_request/?operator=KillHouse", + { + params: { + role: getRoleFromUrl(), + date1: d.selectedDate1, + date2: d.selectedDate2, + }, + } + ); + dispatch(LOADING_END()); + return { data, status }; + } +); diff --git a/src/features/slaughter-house/services/slaughter-get-bars.js b/src/features/slaughter-house/services/slaughter-get-bars.js new file mode 100644 index 0000000..b8040e3 --- /dev/null +++ b/src/features/slaughter-house/services/slaughter-get-bars.js @@ -0,0 +1,15 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const slaughterGetBars = createAsyncThunk( + "SLAUGHTER_GET_BARS", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + const { data, status } = await axios.get("bars_for_kill_house/", { + params: { freezing: true, kill_house_key: d.key, date: d.date }, + }); + dispatch(LOADING_END()); + return { data, status }; + } +); diff --git a/src/features/slaughter-house/services/slaughter-get-broadcast-management.js b/src/features/slaughter-house/services/slaughter-get-broadcast-management.js new file mode 100644 index 0000000..05dbd96 --- /dev/null +++ b/src/features/slaughter-house/services/slaughter-get-broadcast-management.js @@ -0,0 +1,16 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { getRoleFromUrl } from "../../../utils/getRoleFromUrl"; + +export const slaughterGetBroadcastManagementService = createAsyncThunk( + "SLAUGHTER_GET_BROADCAST_MANAGEMENT_SERVICE", + async (id) => { + const { data, status } = await axios.get("steward/", { + params: { + date: id, + role: getRoleFromUrl(), + }, + }); + return { data, status }; + } +); diff --git a/src/features/slaughter-house/services/slaughter-get-cars.js b/src/features/slaughter-house/services/slaughter-get-cars.js new file mode 100644 index 0000000..8a55bde --- /dev/null +++ b/src/features/slaughter-house/services/slaughter-get-cars.js @@ -0,0 +1,19 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; + +export const slaughterGetCars = createAsyncThunk( + "SLAUGHTER_GET_CARS_SERVICE", + async (d) => { + const parmObj = d + ? { + key: d.id, + kill_house_key: d.killHouseKey, + kill_request_key: d.killRequestKey, + } + : {}; + const { data, status } = await axios.get("kill_house_add_car/", { + params: parmObj, + }); + return { data, status }; + } +); diff --git a/src/features/slaughter-house/services/slaughter-get-cold-houses.js b/src/features/slaughter-house/services/slaughter-get-cold-houses.js new file mode 100644 index 0000000..cee7990 --- /dev/null +++ b/src/features/slaughter-house/services/slaughter-get-cold-houses.js @@ -0,0 +1,15 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const slaughterGetColdHouses = createAsyncThunk( + "SLAUGHTER_GET_COLD_HOUSES", + async (id, { dispatch }) => { + dispatch(LOADING_START()); + const { data, status } = await axios.get("cold-house/", { + params: { total: true }, + }); + dispatch(LOADING_END()); + return { data, status }; + } +); diff --git a/src/features/slaughter-house/services/slaughter-get-complaints.js b/src/features/slaughter-house/services/slaughter-get-complaints.js new file mode 100644 index 0000000..3ef0eab --- /dev/null +++ b/src/features/slaughter-house/services/slaughter-get-complaints.js @@ -0,0 +1,12 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; + +export const slaughterGetComplaints = createAsyncThunk( + "SLAUGHTER_GET_COMLATIONSs", + async (id) => { + const { data, status } = await axios.get( + "kill_house_assignment_information/?role=KillHouse" + ); + return { data, status }; + } +); diff --git a/src/features/slaughter-house/services/slaughter-get-countries.js b/src/features/slaughter-house/services/slaughter-get-countries.js new file mode 100644 index 0000000..0ce13c8 --- /dev/null +++ b/src/features/slaughter-house/services/slaughter-get-countries.js @@ -0,0 +1,15 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const slaughterGetCountries = createAsyncThunk( + "SLAUGHTER_GET_COUNTRIES", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + const { data, status } = await axios.get("get_country/", { + params: d, + }); + dispatch(LOADING_END()); + return { data, status }; + } +); diff --git a/src/features/slaughter-house/services/slaughter-get-delegates-info.js b/src/features/slaughter-house/services/slaughter-get-delegates-info.js new file mode 100644 index 0000000..1ee8c11 --- /dev/null +++ b/src/features/slaughter-house/services/slaughter-get-delegates-info.js @@ -0,0 +1,33 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; +import { getRoleFromUrl } from "../../../utils/getRoleFromUrl"; + +export const slaughterGetDelegatesInfoService = createAsyncThunk( + "SLAUGHTER_GET_REPRESENTATIVE_INFO_SERVICE", + async (params, { dispatch }) => { + try { + dispatch(LOADING_START()); + const { data, status } = await axios.get("representative/", { + params: { + role: getRoleFromUrl(), + search: params.search || "filter", + value: params.value || "", + page: params.page || 1, + page_size: params.page_size || 10, + role_key: params.role_key || "", + }, + }); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { + error: + e.response?.data?.result || + e.response?.data || + "خطا در دریافت اطلاعات", + }; + } + } +); diff --git a/src/features/slaughter-house/services/slaughter-get-delegates-service.js b/src/features/slaughter-house/services/slaughter-get-delegates-service.js new file mode 100644 index 0000000..f390d6d --- /dev/null +++ b/src/features/slaughter-house/services/slaughter-get-delegates-service.js @@ -0,0 +1,47 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; +import { getRoleFromUrl } from "../../../utils/getRoleFromUrl"; + +export const slaughterGetDelegatesService = createAsyncThunk( + "SLAUGHTER_GET_DELEGATES_SERVICE", + async (d, { dispatch }) => { + try { + dispatch(LOADING_START()); + const { data, status } = await axios.get( + `representative/?role=${getRoleFromUrl()}&type=${d.type}&search=${d.search}&value=${d.value}&page=${d.page}&page_size=${d.page_size}` + ); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { + error: + e.response?.data?.result || + e.response?.data || + "خطا در دریافت اطلاعات", + }; + } + } +); + +export const slaughterEditDelegatesService = createAsyncThunk( + "SLAUGHTER_EDIT_DELEGATES_SERVICE", + async (d, { dispatch }) => { + try { + dispatch(LOADING_START()); + const { data, status } = await axios.put("representative/0/", d); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { + error: + e.response?.data?.result || + e.response?.data || + "خطا در ویرایش وضعیت", + }; + } + } +); + diff --git a/src/features/slaughter-house/services/slaughter-get-dispenser-info.js b/src/features/slaughter-house/services/slaughter-get-dispenser-info.js new file mode 100644 index 0000000..cff1db6 --- /dev/null +++ b/src/features/slaughter-house/services/slaughter-get-dispenser-info.js @@ -0,0 +1,34 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; +import { getRoleFromUrl } from "../../../utils/getRoleFromUrl"; + +export const slaughterGetDispenserInfoService = createAsyncThunk( + "SLAUGHTER_GET_DISPENSER_INFO_SERVICE", + async (params, { dispatch }) => { + try { + dispatch(LOADING_START()); + const { data, status } = await axios.get("dispenser-info/", { + params: { + role: getRoleFromUrl(), + type: params.type || "", + search: params.search || "filter", + value: params.value || "", + page: params.page || 1, + page_size: params.page_size || 10, + role_key: params.role_key || "", + }, + }); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { + error: + e.response?.data?.result || + e.response?.data || + "خطا در دریافت اطلاعات", + }; + } + } +); diff --git a/src/features/slaughter-house/services/slaughter-get-dispenser-service.js b/src/features/slaughter-house/services/slaughter-get-dispenser-service.js new file mode 100644 index 0000000..e5b1fb9 --- /dev/null +++ b/src/features/slaughter-house/services/slaughter-get-dispenser-service.js @@ -0,0 +1,32 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; +import { getRoleFromUrl } from "../../../utils/getRoleFromUrl"; + +export const slaughterGetDispenserService = createAsyncThunk( + "SLAUGHTER_GET_DISPENSER_SERVICE", + async (params, { dispatch }) => { + try { + dispatch(LOADING_START()); + const { data, status } = await axios.get("dispenser/", { + params: { + role: getRoleFromUrl(), + search: params.search || "filter", + value: params.value || "", + page: params.page || 1, + page_size: params.page_size || 10, + }, + }); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { + error: + e.response?.data?.result || + e.response?.data || + "خطا در دریافت اطلاعات", + }; + } + } +); diff --git a/src/features/slaughter-house/services/slaughter-get-dispenser-user-info.js b/src/features/slaughter-house/services/slaughter-get-dispenser-user-info.js new file mode 100644 index 0000000..f56329f --- /dev/null +++ b/src/features/slaughter-house/services/slaughter-get-dispenser-user-info.js @@ -0,0 +1,34 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const slaughterGetDispenserUserInfoService = createAsyncThunk( + "SLAUGHTER_GET_DISPENSER_USER_INFO_SERVICE", + async (params, { dispatch }) => { + try { + dispatch(LOADING_START()); + const { data, status } = await axios.get(`get_dispenser_user_info`, { + params: { + national_code: params.national_code || "", + role_key: params.role_key || "", + }, + }); + dispatch(LOADING_END()); + if (data && data.status === false) { + return { + error: data.errorDescription || "خطا در دریافت اطلاعات", + }; + } + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { + error: + e.response?.data?.errorDescription || + e.response?.data?.result || + e.response?.data?.message || + "خطا در دریافت اطلاعات", + }; + } + } +); diff --git a/src/features/slaughter-house/services/slaughter-get-distribution-info.js b/src/features/slaughter-house/services/slaughter-get-distribution-info.js new file mode 100644 index 0000000..971793c --- /dev/null +++ b/src/features/slaughter-house/services/slaughter-get-distribution-info.js @@ -0,0 +1,48 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; +import { getRoleFromUrl } from "../../../utils/getRoleFromUrl"; + +export const slaughterGetDistributionInfo = createAsyncThunk( + "SLAUGHTER_GET_DISTRIBUTION_INFO", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + const { data, status } = await axios.get("kill-house-distribution-info/", { + params: { + role: getRoleFromUrl(), + }, + }); + dispatch(LOADING_END()); + return { data, status }; + } +); +export const slaughterGetVBroadcastInfo = createAsyncThunk( + "SLAUGHTER_GET_BROARDCAST_INFO", + async (d) => { + const { data, status } = await axios.get( + "kill-house-sales-info-dashboard", + { + params: { + role: getRoleFromUrl(), + ...d, + }, + } + ); + return { data, status }; + } +); + +export const slaughterGetBarsInfo = createAsyncThunk( + "SLAUGHTER_GET_BARS_INFO", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + const { data, status } = await axios.get("bars_for_kill_house_dashboard/", { + params: { + role: getRoleFromUrl(), + role_key: d.role_key || "", + }, + }); + dispatch(LOADING_END()); + return { data, status }; + } +); diff --git a/src/features/slaughter-house/services/slaughter-get-driver-by-health-code.js b/src/features/slaughter-house/services/slaughter-get-driver-by-health-code.js new file mode 100644 index 0000000..443e7d8 --- /dev/null +++ b/src/features/slaughter-house/services/slaughter-get-driver-by-health-code.js @@ -0,0 +1,12 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; + +export const slaughterGetDriverByHealthCode = createAsyncThunk( + "SLAUGHETR_GET_DRIVER_BY_HEALTH_CODE", + async (id) => { + const { data, status } = await axios.get( + "kill_house_driver/?health_code=" + id + ); + return { data, status }; + } +); diff --git a/src/features/slaughter-house/services/slaughter-get-export-allow-state.js b/src/features/slaughter-house/services/slaughter-get-export-allow-state.js new file mode 100644 index 0000000..9dabce1 --- /dev/null +++ b/src/features/slaughter-house/services/slaughter-get-export-allow-state.js @@ -0,0 +1,19 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; +import { getRoleFromUrl } from "../../../utils/getRoleFromUrl"; + +export const slaughterGetExportAllowState = createAsyncThunk( + "SLAUGHTER_GET_EXPORT_ALLOW_STATE", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + const { data, status } = await axios.get("allow_direct_buying/", { + params: { + role: getRoleFromUrl(), + ...d, + }, + }); + dispatch(LOADING_END()); + return { data, status }; + } +); diff --git a/src/features/slaughter-house/services/slaughter-get-free-buy-requests.js b/src/features/slaughter-house/services/slaughter-get-free-buy-requests.js new file mode 100644 index 0000000..f288287 --- /dev/null +++ b/src/features/slaughter-house/services/slaughter-get-free-buy-requests.js @@ -0,0 +1,32 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; +import { getRoleFromUrl } from "../../../utils/getRoleFromUrl"; + +export const slaughterGetFreeBuyRequests = createAsyncThunk( + "SLAUGHTER_GET_FREE_BUY_REQUESTS", + async (params, { dispatch }) => { + dispatch(LOADING_START()); + try { + const { data, status } = await axios.get("kill_request/", { + params: { + direct_buying: true, + role: getRoleFromUrl(), + date1: params.date1, + date2: params.date2, + search: "filter", + role_key: params.role_key || "", + value: params.value || "", + ...(params.type && { type: params.type }), + ...(params.page && { page: params.page }), + ...(params.page_size && { page_size: params.page_size }), + }, + }); + dispatch(LOADING_END()); + return { data, status }; + } catch (error) { + dispatch(LOADING_END()); + throw error; + } + } +); diff --git a/src/features/slaughter-house/services/slaughter-get-guilds-for-allocate.js b/src/features/slaughter-house/services/slaughter-get-guilds-for-allocate.js new file mode 100644 index 0000000..ad135d9 --- /dev/null +++ b/src/features/slaughter-house/services/slaughter-get-guilds-for-allocate.js @@ -0,0 +1,43 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; +import { getRoleFromUrl } from "../../../utils/getRoleFromUrl"; + +export const slaughterGetGuildsForAllocateService = createAsyncThunk( + "SLAUGHTER_GET_GUILDS_FOR_ALLOCATE_SERVICE", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + const { data, status } = await axios.get("guilds/", { + params: { role: getRoleFromUrl(), ...d }, + }); + dispatch(LOADING_END()); + return { data, status }; + } +); + +export const slaughterGetColdHousesForAllocateService = createAsyncThunk( + "SLAUGHTER_GET_COLDHOUSES_FOR_ALLOCATE_SERVICE", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + const { data, status } = await axios.get("cold-house/", { + params: { role: getRoleFromUrl(), ...d }, + }); + dispatch(LOADING_END()); + return { data, status }; + } +); + +export const slaughterGetStewardsForAllocateService = createAsyncThunk( + "SLAUGHTER_GET_STEWARDS_FOR_ALLOCATE_SERVICE", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + const { data, status } = await axios.get("main-stewards/", { + params: { + role: getRoleFromUrl(), + ...d, + }, + }); + dispatch(LOADING_END()); + return { data, status }; + } +); diff --git a/src/features/slaughter-house/services/slaughter-get-guilds.js b/src/features/slaughter-house/services/slaughter-get-guilds.js new file mode 100644 index 0000000..e568f47 --- /dev/null +++ b/src/features/slaughter-house/services/slaughter-get-guilds.js @@ -0,0 +1,16 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { getRoleFromUrl } from "../../../utils/getRoleFromUrl"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const slaughterGetGuildsService = createAsyncThunk( + "SLAUGHTER_GET_GUILDS_SERVICE", + async (id, { dispatch }) => { + dispatch(LOADING_START()); + const { data, status } = await axios.get("guilds/", { + params: { role: getRoleFromUrl() }, + }); + dispatch(LOADING_END()); + return { data, status }; + } +); diff --git a/src/features/slaughter-house/services/slaughter-get-inventory-bars.js b/src/features/slaughter-house/services/slaughter-get-inventory-bars.js new file mode 100644 index 0000000..68ec3dc --- /dev/null +++ b/src/features/slaughter-house/services/slaughter-get-inventory-bars.js @@ -0,0 +1,17 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; + +export const slaughterGetInventoryBars = createAsyncThunk( + "SLAUGHTER_GET_INVENTORY_BARS", + async (id) => { + const { data, status } = await axios.get( + "/kill_house_assignment_information/", + { + params: { + date: id, + }, + } + ); + return { data, status }; + } +); diff --git a/src/features/slaughter-house/services/slaughter-get-inventory-free-bars.js b/src/features/slaughter-house/services/slaughter-get-inventory-free-bars.js new file mode 100644 index 0000000..4cb434b --- /dev/null +++ b/src/features/slaughter-house/services/slaughter-get-inventory-free-bars.js @@ -0,0 +1,15 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const slaughterGetInventoryFreeBarsService = createAsyncThunk( + "SLAUGHTER_GET_INVENTORY_FREE_BARS_SERVICE", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + const { data, status } = await axios.get("kill_house_free_bar/", { + params: { date: d.selectedDate1, kill_house_key: d.kill_house_key }, + }); + dispatch(LOADING_END()); + return { data, status }; + } +); diff --git a/src/features/slaughter-house/services/slaughter-get-kill-house-lock-info.js b/src/features/slaughter-house/services/slaughter-get-kill-house-lock-info.js new file mode 100644 index 0000000..a0f1d5d --- /dev/null +++ b/src/features/slaughter-house/services/slaughter-get-kill-house-lock-info.js @@ -0,0 +1,9 @@ +import axios from "axios"; + +export const slaughterGetKillHouseLockInfoService = async () => { + const { data } = await axios.get("kill-house-lock-info/"); + return data; +}; + + + diff --git a/src/features/slaughter-house/services/slaughter-get-killers-killhouses.js b/src/features/slaughter-house/services/slaughter-get-killers-killhouses.js new file mode 100644 index 0000000..e11a686 --- /dev/null +++ b/src/features/slaughter-house/services/slaughter-get-killers-killhouses.js @@ -0,0 +1,17 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const slaughterGetKillerKillhousesService = createAsyncThunk( + "SLAUGHTER_GET_KILLER_KILLHOUSES_SERVICE", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + const { data, status } = await axios.get("kill_house/?kill_house", { + params: { + role_key: d.role_key || "", + }, + }); + dispatch(LOADING_END()); + return { data, status }; + } +); diff --git a/src/features/slaughter-house/services/slaughter-get-killhouse-guilds.js b/src/features/slaughter-house/services/slaughter-get-killhouse-guilds.js new file mode 100644 index 0000000..3cd1296 --- /dev/null +++ b/src/features/slaughter-house/services/slaughter-get-killhouse-guilds.js @@ -0,0 +1,19 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; +import { getRoleFromUrl } from "../../../utils/getRoleFromUrl"; + +export const slaughterGetKillhouseGuildsService = createAsyncThunk( + "SLAUGHTER_GET_KILLHOUSE_GUILDS_SERVICE", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + const { data, status } = await axios.get("guilds/", { + params: { + role: getRoleFromUrl(), + ...d, + }, + }); + dispatch(LOADING_END()); + return { data, status }; + } +); diff --git a/src/features/slaughter-house/services/slaughter-get-killhouse-remain-weight.js b/src/features/slaughter-house/services/slaughter-get-killhouse-remain-weight.js new file mode 100644 index 0000000..a78e32d --- /dev/null +++ b/src/features/slaughter-house/services/slaughter-get-killhouse-remain-weight.js @@ -0,0 +1,20 @@ +import axios from "axios"; + +/** + * @param {string} date - Date in YYYY-MM-DD format + * @returns {Promise<{governmental: Array, free: Array}>} Object containing governmental and free inventory data + */ +export const slaughterGetKillhouseRemainWeight = async (d) => { + try { + const response = await axios.get("/kill-house-remain-weight/", { + params: d, + }); + return { + governmental: response.data?.governmental || [], + free: response.data?.free || [], + }; + } catch (error) { + console.error("Error fetching killhouse remain weight:", error); + throw error; + } +}; diff --git a/src/features/slaughter-house/services/slaughter-get-killhouse-stewards.js b/src/features/slaughter-house/services/slaughter-get-killhouse-stewards.js new file mode 100644 index 0000000..1bab2e5 --- /dev/null +++ b/src/features/slaughter-house/services/slaughter-get-killhouse-stewards.js @@ -0,0 +1,20 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; +import { getRoleFromUrl } from "../../../utils/getRoleFromUrl"; + +export const slaughterGetKillhouseStewardsService = createAsyncThunk( + "SLAUGHTER_GET_KILLHOUSE_STEWARDS_SERVICE", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + const { data, status } = await axios.get("steward/", { + params: { + kill_house_key: d.kill_house_key, + date: d.date, + role: getRoleFromUrl(), + }, + }); + dispatch(LOADING_END()); + return { data, status }; + } +); diff --git a/src/features/slaughter-house/services/slaughter-get-killhouses.js b/src/features/slaughter-house/services/slaughter-get-killhouses.js new file mode 100644 index 0000000..d7041cf --- /dev/null +++ b/src/features/slaughter-house/services/slaughter-get-killhouses.js @@ -0,0 +1,16 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; +import { getRoleFromUrl } from "../../../utils/getRoleFromUrl"; + +export const slaughterGetKillhousesService = createAsyncThunk( + "SLAUGHTERـGETـKILLHOUSESـSERVICE", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + const { data, status } = await axios.get("kill_house/", { + params: { role: getRoleFromUrl(), role_key: d.role_key || "" }, + }); + dispatch(LOADING_END()); + return { data, status }; + } +); diff --git a/src/features/slaughter-house/services/slaughter-get-out-of-province-sells.js b/src/features/slaughter-house/services/slaughter-get-out-of-province-sells.js new file mode 100644 index 0000000..98978b4 --- /dev/null +++ b/src/features/slaughter-house/services/slaughter-get-out-of-province-sells.js @@ -0,0 +1,18 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const slaughterGetOutOfProvinceSells = createAsyncThunk( + "SLAUGHTER_GET_OUT_OF_PROVINCE_SELLS", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + const { data, status } = await axios.get("kill_house_free_sale_bar/", { + params: { + kill_house_key: d.kill_house_key, + date: d.date, + }, + }); + dispatch(LOADING_END()); + return { data, status }; + } +); diff --git a/src/features/slaughter-house/services/slaughter-get-paied-factors.js b/src/features/slaughter-house/services/slaughter-get-paied-factors.js new file mode 100644 index 0000000..71e5d76 --- /dev/null +++ b/src/features/slaughter-house/services/slaughter-get-paied-factors.js @@ -0,0 +1,18 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { getRoleFromUrl } from "../../../utils/getRoleFromUrl"; +export const slaughterGetPaiedFactorsService = createAsyncThunk( + "SLAUGHTER_GET_PAIED_FACTORS", + async (d) => { + const { data, status } = await axios.get( + "kill_house_factor_province/?role=" + getRoleFromUrl(), + { + params: { + date1: d.selectedDate1, + date2: d.selectedDate2, + }, + } + ); + return { data, status }; + } +); diff --git a/src/features/slaughter-house/services/slaughter-get-pay-factor-requests.js b/src/features/slaughter-house/services/slaughter-get-pay-factor-requests.js new file mode 100644 index 0000000..260e61f --- /dev/null +++ b/src/features/slaughter-house/services/slaughter-get-pay-factor-requests.js @@ -0,0 +1,21 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; +import { getRoleFromUrl } from "../../../utils/getRoleFromUrl"; +export const slaughterGetPayFactorRequestsService = createAsyncThunk( + "SLAUGHTER_GET_PAY_FACTOR_REQUESTS", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + const { data, status } = await axios.get( + "province_factor_to_kill_house/?role=" + getRoleFromUrl(), + { + params: { + date1: d.selectedDate1, + date2: d.selectedDate2, + }, + } + ); + dispatch(LOADING_END()); + return { data, status }; + } +); diff --git a/src/features/slaughter-house/services/slaughter-get-payment-by-weight-overview.js b/src/features/slaughter-house/services/slaughter-get-payment-by-weight-overview.js new file mode 100644 index 0000000..d3838a6 --- /dev/null +++ b/src/features/slaughter-house/services/slaughter-get-payment-by-weight-overview.js @@ -0,0 +1,16 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; +import { getRoleFromUrl } from "../../../utils/getRoleFromUrl"; + +export const slaughterGetPaymentByWeightOverview = createAsyncThunk( + "SLAUGHTER_GET_PAYMENT_BY_WEIGHT_OVERVIREW", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + const { data, status } = await axios.get( + `kill_house_wage_dashbord_in_weight/?role=${getRoleFromUrl()}` + ); + dispatch(LOADING_END()); + return { data, status }; + } +); diff --git a/src/features/slaughter-house/services/slaughter-get-payment-overview-info.js b/src/features/slaughter-house/services/slaughter-get-payment-overview-info.js new file mode 100644 index 0000000..3b982ff --- /dev/null +++ b/src/features/slaughter-house/services/slaughter-get-payment-overview-info.js @@ -0,0 +1,13 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const slaughterGetPaymentOverviewInfo = createAsyncThunk( + "SLAUGHTER_GET_PAYMENT_OVERVIEW_INFO", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + const { data, status } = await axios.get("kill_house_wage_dashbord/"); + dispatch(LOADING_END()); + return { data, status }; + } +); diff --git a/src/features/slaughter-house/services/slaughter-get-permision.js b/src/features/slaughter-house/services/slaughter-get-permision.js new file mode 100644 index 0000000..f56cca5 --- /dev/null +++ b/src/features/slaughter-house/services/slaughter-get-permision.js @@ -0,0 +1,13 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const slaughterGetPermisionState = createAsyncThunk( + "SLAUGHTER_GET_PERMISION_STATE", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + const { data, status } = await axios.get("kill_house_purchase_permission/"); + dispatch(LOADING_END()); + return { data, status }; + } +); diff --git a/src/features/slaughter-house/services/slaughter-get-premisson-to-vet.js b/src/features/slaughter-house/services/slaughter-get-premisson-to-vet.js new file mode 100644 index 0000000..0305d89 --- /dev/null +++ b/src/features/slaughter-house/services/slaughter-get-premisson-to-vet.js @@ -0,0 +1,15 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const slaughterGetPermissionToVetService = createAsyncThunk( + "SLAUGHTER_GET_PERMISSION_TO_VET_SERVICE", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + const { data, status } = await axios.get("allow_kill_house_vet/", { + params: d, + }); + dispatch(LOADING_END()); + return { data, status }; + } +); diff --git a/src/features/slaughter-house/services/slaughter-get-profile.js b/src/features/slaughter-house/services/slaughter-get-profile.js new file mode 100644 index 0000000..e239f80 --- /dev/null +++ b/src/features/slaughter-house/services/slaughter-get-profile.js @@ -0,0 +1,15 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const slaughterGetProfile = createAsyncThunk( + "SLAUGHTER_GET_PROFILE", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + const { data, status } = await axios.get("kill_house_operator/0/?profile", { + params: d, + }); + dispatch(LOADING_END()); + return { data, status }; + } +); diff --git a/src/features/slaughter-house/services/slaughter-get-provinces.js b/src/features/slaughter-house/services/slaughter-get-provinces.js new file mode 100644 index 0000000..fecdc3d --- /dev/null +++ b/src/features/slaughter-house/services/slaughter-get-provinces.js @@ -0,0 +1,24 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const slaughterGetProvinceService = createAsyncThunk( + "SLAUGHTER_GET_PROVINCE", + async (_, { dispatch }) => { + dispatch(LOADING_START()); + const { data, status } = await axios.get("iran_province/"); + dispatch(LOADING_END()); + return { data, status }; + } +); + +export const slaughterGetCitiesService = createAsyncThunk( + "SLAUGHTER_GET_CITIES_OF_PROVINCE", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + const { data, status } = await axios.get("iran_city/?name=" + d); + dispatch(LOADING_END()); + + return { data, status }; + } +); diff --git a/src/features/slaughter-house/services/slaughter-get-registered-complaints.js b/src/features/slaughter-house/services/slaughter-get-registered-complaints.js new file mode 100644 index 0000000..fde9949 --- /dev/null +++ b/src/features/slaughter-house/services/slaughter-get-registered-complaints.js @@ -0,0 +1,12 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; + +export const slaughterGetRegisteredComplaints = createAsyncThunk( + "SLAUGHTER_GET_COMLATIONS", + async (id) => { + const { data, status } = await axios.get( + "kill_house_complaint/?role=KillHouse" + ); + return { data, status }; + } +); diff --git a/src/features/slaughter-house/services/slaughter-get-stewards.js b/src/features/slaughter-house/services/slaughter-get-stewards.js new file mode 100644 index 0000000..09fa91a --- /dev/null +++ b/src/features/slaughter-house/services/slaughter-get-stewards.js @@ -0,0 +1,16 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { getRoleFromUrl } from "../../../utils/getRoleFromUrl"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const slaughterGetStewardsService = createAsyncThunk( + "SLAUGHTER_GET_STEWARDS_SERVICE", + async (id, { dispatch }) => { + dispatch(LOADING_START()); + const { data, status } = await axios.get("steward/", { + params: { role: getRoleFromUrl() }, + }); + dispatch(LOADING_END()); + return { data, status }; + } +); diff --git a/src/features/slaughter-house/services/slaughter-house-get-dispenser-dashboard-service.js b/src/features/slaughter-house/services/slaughter-house-get-dispenser-dashboard-service.js new file mode 100644 index 0000000..4112631 --- /dev/null +++ b/src/features/slaughter-house/services/slaughter-house-get-dispenser-dashboard-service.js @@ -0,0 +1,24 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { getRoleFromUrl } from "../../../utils/getRoleFromUrl"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const slaughterGetDispenserDashboardService = createAsyncThunk( + "SLAUGHTER_GET_DISPENSERS_DASHBOARD_SERVICE", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + const { data, status } = await axios.get( + "dispenser-allocations-dashboard/", + { + params: { + role: getRoleFromUrl(), + date1: d.date1, + date2: d.date2, + dispenser_key: d.key, + }, + } + ); + dispatch(LOADING_END()); + return { data, status }; + } +); diff --git a/src/features/slaughter-house/services/slaughter-house-get-dispenser-dashboard.js b/src/features/slaughter-house/services/slaughter-house-get-dispenser-dashboard.js new file mode 100644 index 0000000..8937a2e --- /dev/null +++ b/src/features/slaughter-house/services/slaughter-house-get-dispenser-dashboard.js @@ -0,0 +1,16 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { getRoleFromUrl } from "../../../utils/getRoleFromUrl"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const slaughterGetDispenserDashboard = createAsyncThunk( + "SLAUGHTER_GET_DISPENSERS_DASHBOARD", + async (id, { dispatch }) => { + dispatch(LOADING_START()); + const { data, status } = await axios.get("dispenser-dashboard/", { + params: { role: getRoleFromUrl() }, + }); + dispatch(LOADING_END()); + return { data, status }; + } +); diff --git a/src/features/slaughter-house/services/slaughter-house-submit-buyer.js b/src/features/slaughter-house/services/slaughter-house-submit-buyer.js new file mode 100644 index 0000000..51e85c9 --- /dev/null +++ b/src/features/slaughter-house/services/slaughter-house-submit-buyer.js @@ -0,0 +1,51 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const slaughterGetBuyerDataService = createAsyncThunk( + "SLAUGHTER_GET_BUYER_SERVICE", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + const { data, status } = await axios.get( + "base-out-province-carcasses-buyer/?mobile=" + d + ); + dispatch(LOADING_END()); + return { data, status }; + } +); + +export const slaughterSubmitBuyerDataService = createAsyncThunk( + "SLAUGHTER_SUBMIT_BUYER_SERVICE", + async (d, { dispatch }) => { + try { + dispatch(LOADING_START()); + const { data, status } = await axios.post( + "out-province-carcasses-buyer/", + d + ); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e.response.data.result }; + } + } +); + +export const slaughterEditBuyerDataService = createAsyncThunk( + "SLAUGHTER_EDIT_BUYER_SERVICE", + async (d, { dispatch }) => { + try { + dispatch(LOADING_START()); + const { data, status } = await axios.put( + "out-province-carcasses-buyer/0/", + d + ); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e.response.data.result }; + } + } +); diff --git a/src/features/slaughter-house/services/slaughter-house-submit-dispenser-service.js b/src/features/slaughter-house/services/slaughter-house-submit-dispenser-service.js new file mode 100644 index 0000000..2f02381 --- /dev/null +++ b/src/features/slaughter-house/services/slaughter-house-submit-dispenser-service.js @@ -0,0 +1,37 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const slaughterHouseSubmitDispenserService = createAsyncThunk( + "SLAUGHTER_SUBMIT_DISPENSER", + async (d, { dispatch }) => { + try { + const { data, status } = await axios.post("dispenser/", d); + dispatch(LOADING_START()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e.response.data.result }; + } + } +); + +export const slaughterHouseEditDispenserService = createAsyncThunk( + "SLAUGHTER_EDIT_DISPENSER", + async (d, { dispatch }) => { + try { + dispatch(LOADING_START()); + const { data, status } = await axios.put("dispenser/0/", d); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { + error: + e.response?.data?.result || + e.response?.data || + "خطا در ویرایش توزیع کننده", + }; + } + } +); diff --git a/src/features/slaughter-house/services/slaughter-inventory-bars.js b/src/features/slaughter-house/services/slaughter-inventory-bars.js new file mode 100644 index 0000000..04359ee --- /dev/null +++ b/src/features/slaughter-house/services/slaughter-inventory-bars.js @@ -0,0 +1,19 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const slaughterInventoryBarsService = createAsyncThunk( + "SLAUGHTER_INVENTORY_BARS_SERVICE", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + const { data, status } = await axios.get("bars_for_kill_house/", { + params: { + type: d.type, + date1: d.selectedDate1, + date2: d.selectedDate2, + }, + }); + dispatch(LOADING_END()); + return { data, status }; + } +); diff --git a/src/features/slaughter-house/services/slaughter-inventory-final-submit.js b/src/features/slaughter-house/services/slaughter-inventory-final-submit.js new file mode 100644 index 0000000..76bca1b --- /dev/null +++ b/src/features/slaughter-house/services/slaughter-inventory-final-submit.js @@ -0,0 +1,18 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const slaughterInventoryFinalSubmitService = createAsyncThunk( + "SLAUGHTER_INVENTORY_FINAL_SUBMIT_SERVICE", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + try { + const { data, status } = await axios.put("steward-allocation/0/", d); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e.response.data.result }; + } + } +); diff --git a/src/features/slaughter-house/services/slaughter-inventory-gets.js b/src/features/slaughter-house/services/slaughter-inventory-gets.js new file mode 100644 index 0000000..27b70a2 --- /dev/null +++ b/src/features/slaughter-house/services/slaughter-inventory-gets.js @@ -0,0 +1,31 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; +import axios from "axios"; +import { getRoleFromUrl } from "../../../utils/getRoleFromUrl"; + +export const slaughterGetProductsService = createAsyncThunk( + "SLAUGHTER_INVENTORY_GET_PRODUCTS", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + const { data, status } = await axios.get("roles-products", { + params: { + role: getRoleFromUrl(), + role_key: d.role_key || "", + }, + }); + dispatch(LOADING_END()); + return { data, status }; + } +); + +export const slaughterGetExclusiveKillersService = createAsyncThunk( + "SLAUGHTER_GET_EXCLUSIVE_KILLERS", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + const { data, status } = await axios.get( + "kill_house/?exclusive-killers-free-bar=true" + ); + dispatch(LOADING_END()); + return { data, status }; + } +); diff --git a/src/features/slaughter-house/services/slaughter-manage-bars.js b/src/features/slaughter-house/services/slaughter-manage-bars.js new file mode 100644 index 0000000..97ecd56 --- /dev/null +++ b/src/features/slaughter-house/services/slaughter-manage-bars.js @@ -0,0 +1,23 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; +import { getRoleFromUrl } from "../../../utils/getRoleFromUrl"; + +export const slaughterManageBarsService = createAsyncThunk( + "SLAUGHTER_MANAGE_BARS_SERVICE", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + const { data, status } = await axios.get( + "kill_house_assignment_information/", + { + params: { + role: getRoleFromUrl(), + date1: d.selectedDate1, + date2: d.selectedDate2, + }, + } + ); + dispatch(LOADING_END()); + return { data, status }; + } +); diff --git a/src/features/slaughter-house/services/slaughter-manage-inventory-allocation-for-freezing.js b/src/features/slaughter-house/services/slaughter-manage-inventory-allocation-for-freezing.js new file mode 100644 index 0000000..a73d34f --- /dev/null +++ b/src/features/slaughter-house/services/slaughter-manage-inventory-allocation-for-freezing.js @@ -0,0 +1,19 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const slaughterManageInventoryAllocationForFreezingService = + createAsyncThunk( + "SLAUGHTER_MANAGE_INVENTORY_ALLOCATIONS_FOR_FREEZING_SERVICE", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + const { data, status } = await axios.get("cold-house-allocations/", { + params: { + role: d.role, + date: d.date, + }, + }); + dispatch(LOADING_END()); + return { data, status }; + } + ); diff --git a/src/features/slaughter-house/services/slaughter-new-car.js b/src/features/slaughter-house/services/slaughter-new-car.js new file mode 100644 index 0000000..ed070b0 --- /dev/null +++ b/src/features/slaughter-house/services/slaughter-new-car.js @@ -0,0 +1,10 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; + +export const slaughterNewCar = createAsyncThunk( + "SLAUGHTER_ADD_CAR", + async (d) => { + const { data, status } = await axios.post("kill_house_add_car/", d); + return { data, status }; + } +); diff --git a/src/features/slaughter-house/services/slaughter-new-complaint.js b/src/features/slaughter-house/services/slaughter-new-complaint.js new file mode 100644 index 0000000..ffce74e --- /dev/null +++ b/src/features/slaughter-house/services/slaughter-new-complaint.js @@ -0,0 +1,10 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; + +export const slaughterNewComplaint = createAsyncThunk( + "SLAUGHTER_NEW_COMPLAINT", + async (d) => { + const { data, status } = await axios.post("kill_house_complaint/", d); + return { data, status }; + } +); diff --git a/src/features/slaughter-house/services/slaughter-new-request.js b/src/features/slaughter-house/services/slaughter-new-request.js new file mode 100644 index 0000000..9ffe47a --- /dev/null +++ b/src/features/slaughter-house/services/slaughter-new-request.js @@ -0,0 +1,16 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END } from "../../../lib/redux/slices/appSlice"; + +export const slaughterNewRequest = createAsyncThunk( + "SLAUGHTER_NEW_REQUEST", + async (d, { dispatch }) => { + try { + const { data, status } = await axios.post("kill_request/", d); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e.response.data.result }; + } + } +); diff --git a/src/features/slaughter-house/services/slaughter-none-back-reciept.js b/src/features/slaughter-house/services/slaughter-none-back-reciept.js new file mode 100644 index 0000000..23f98f5 --- /dev/null +++ b/src/features/slaughter-house/services/slaughter-none-back-reciept.js @@ -0,0 +1,21 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; +import axios from "axios"; + +export const slaughterNoneBackRecieptService = createAsyncThunk( + "SLAUGHTER_NONE_RECIEPT_BACK_SERVICE", + async (d, { dispatch }) => { + try { + dispatch(LOADING_START()); + const { data, status } = await axios.put( + "non-receipt-request-return/0/", + d + ); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e.response.data.result }; + } + } +); diff --git a/src/features/slaughter-house/services/slaughter-none-reciept-operation.js b/src/features/slaughter-house/services/slaughter-none-reciept-operation.js new file mode 100644 index 0000000..4450538 --- /dev/null +++ b/src/features/slaughter-house/services/slaughter-none-reciept-operation.js @@ -0,0 +1,18 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; +import axios from "axios"; + +export const slaughterNoneRecieptService = createAsyncThunk( + "SLAUGHTER_NENE_RECIEPT_SERVICE", + async (d, { dispatch }) => { + try { + dispatch(LOADING_START()); + const { data, status } = await axios.put("non-receipt-request/0/", d); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e.response.data.result }; + } + } +); diff --git a/src/features/slaughter-house/services/slaughter-pay-factor.js b/src/features/slaughter-house/services/slaughter-pay-factor.js new file mode 100644 index 0000000..54058ec --- /dev/null +++ b/src/features/slaughter-house/services/slaughter-pay-factor.js @@ -0,0 +1,16 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const slaughterPayFactorService = createAsyncThunk( + "SLAUGHTER_PAY_FACTOR_SERVICE", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + const { data, status } = await axios.post( + "kill_request_factor_payment/", + d + ); + dispatch(LOADING_END()); + return { data, status }; + } +); diff --git a/src/features/slaughter-house/services/slaughter-premisson-to-vet.js b/src/features/slaughter-house/services/slaughter-premisson-to-vet.js new file mode 100644 index 0000000..ede092d --- /dev/null +++ b/src/features/slaughter-house/services/slaughter-premisson-to-vet.js @@ -0,0 +1,13 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const slaughterPermissionToVetService = createAsyncThunk( + "SLAUGHTER_PERMISSION_TO_VET_SERVICE", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + const { data, status } = await axios.post("allow_kill_house_vet/", d); + dispatch(LOADING_END()); + return { data, status }; + } +); diff --git a/src/features/slaughter-house/services/slaughter-remove-allocate-car.js b/src/features/slaughter-house/services/slaughter-remove-allocate-car.js new file mode 100644 index 0000000..593ccdb --- /dev/null +++ b/src/features/slaughter-house/services/slaughter-remove-allocate-car.js @@ -0,0 +1,22 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const slaughterRemoveAllocateCarService = createAsyncThunk( + "SLAUGHTER_REMOVE_ALLOCATE_CAR_SERVICE", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + try { + const { data, status } = await axios.delete("kill_house_request/0/", { + params: { + kill_house_request_key: d, + }, + }); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e.response.data.result }; + } + } +); diff --git a/src/features/slaughter-house/services/slaughter-resend-direct-buying-sms.js b/src/features/slaughter-house/services/slaughter-resend-direct-buying-sms.js new file mode 100644 index 0000000..6526789 --- /dev/null +++ b/src/features/slaughter-house/services/slaughter-resend-direct-buying-sms.js @@ -0,0 +1,21 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const slaughterResendDirectBuyingSmsService = createAsyncThunk( + "SLAUGHTER_RESEND_DIRECT_BUYING_SMS_SERVICE", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + try { + const { data, status } = await axios.post( + "send_again_sms_direct_buying_code/", + d + ); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e.response.data.result }; + } + } +); diff --git a/src/features/slaughter-house/services/slaughter-resend-out-province-registration-code.js b/src/features/slaughter-house/services/slaughter-resend-out-province-registration-code.js new file mode 100644 index 0000000..55c8d4e --- /dev/null +++ b/src/features/slaughter-house/services/slaughter-resend-out-province-registration-code.js @@ -0,0 +1,22 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const slaughterResendOutProvinceRegistrationCodeService = + createAsyncThunk( + "SLAUGHTER_RESEND_OUT_PROVINCE_REGISTRATION_CODE", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + try { + const { data, status } = await axios.post( + "send_again_sms_kill_house_free_sale_bar/", + d + ); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e.response?.data?.result || "خطا در ارسال مجدد کد" }; + } + } + ); diff --git a/src/features/slaughter-house/services/slaughter-return-entered-free-bar.js b/src/features/slaughter-house/services/slaughter-return-entered-free-bar.js new file mode 100644 index 0000000..be46dcd --- /dev/null +++ b/src/features/slaughter-house/services/slaughter-return-entered-free-bar.js @@ -0,0 +1,18 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; +import axios from "axios"; + +export const slaughterReturnEnteredFreeBarService = createAsyncThunk( + "SLAUGHTER_EDIT_RETURN_ENTERED_FREE_BAR_SERVICE", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + try { + const { data, status } = await axios.put("kill_house_free_bar/0/", d); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e.response.data.result }; + } + } +); diff --git a/src/features/slaughter-house/services/slaughter-sell-carcass-out-province-get-buyers.js b/src/features/slaughter-house/services/slaughter-sell-carcass-out-province-get-buyers.js new file mode 100644 index 0000000..3d9e993 --- /dev/null +++ b/src/features/slaughter-house/services/slaughter-sell-carcass-out-province-get-buyers.js @@ -0,0 +1,30 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { getRoleFromUrl } from "../../../utils/getRoleFromUrl"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const slaughterSellCarcassOutProvinceGetBuyers = createAsyncThunk( + "SLAUGHTER_GET_BUYERS_CARCASS", + async (id, { dispatch }) => { + dispatch(LOADING_START()); + const { data, status } = await axios.get("out-province-carcasses-buyer/", { + params: { role: getRoleFromUrl() }, + }); + dispatch(LOADING_END()); + return { data, status }; + } +); + +export const slaughterSellCarcassOutProvinceSubmitSell = createAsyncThunk( + "SLAUGHTER_SUBMIT_CARCASS_OUT_PROVINCE_SELL", + async (d, { dispatch }) => { + try { + const { data, status } = await axios.post(`kill_house_free_sale_bar/`, d); + dispatch(LOADING_START()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e.response.data.result }; + } + } +); diff --git a/src/features/slaughter-house/services/slaughter-sell-carcass-out-province.js b/src/features/slaughter-house/services/slaughter-sell-carcass-out-province.js new file mode 100644 index 0000000..4c0dcfe --- /dev/null +++ b/src/features/slaughter-house/services/slaughter-sell-carcass-out-province.js @@ -0,0 +1,24 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; +import { getRoleFromUrl } from "../../../utils/getRoleFromUrl"; + +export const slaughterSellCarcassOutProvinceGetDashboard = createAsyncThunk( + "SLAUGHTRE_SELL_DASHBOARD", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + const { data, status } = await axios.get( + `dashboard_kill_house_free_sale_bar`, + { + params: { + date1: d.selectedDate1, + date2: d.selectedDate2, + role: getRoleFromUrl(), + role_key: d.role_key || "", + }, + } + ); + dispatch(LOADING_END()); + return { data, status }; + } +); diff --git a/src/features/slaughter-house/services/slaughter-send-sms-steward-allocation-again.js b/src/features/slaughter-house/services/slaughter-send-sms-steward-allocation-again.js new file mode 100644 index 0000000..31636bf --- /dev/null +++ b/src/features/slaughter-house/services/slaughter-send-sms-steward-allocation-again.js @@ -0,0 +1,21 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const slaughterResendStewardAllocationSmsService = createAsyncThunk( + "SLAUGHTER_SEND_SMS_AGAIN_SERVICE", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + try { + const { data, status } = await axios.post( + "send_again_sms_steward_allocation/", + d + ); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e.response.data.result }; + } + } +); diff --git a/src/features/slaughter-house/services/slaughter-submit-allocate-to-freezing.js b/src/features/slaughter-house/services/slaughter-submit-allocate-to-freezing.js new file mode 100644 index 0000000..7d4ef72 --- /dev/null +++ b/src/features/slaughter-house/services/slaughter-submit-allocate-to-freezing.js @@ -0,0 +1,17 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const slaughterSubmitAllocateToFreezing = createAsyncThunk( + "SLAUGHTER_SUBMIT_ALLOCATE_FREEZING", + async (d, { dispatch }) => { + try { + const { data, status } = await axios.post(`cold-house-allocations/`, d); + dispatch(LOADING_START()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e.response.data.result }; + } + } +); diff --git a/src/features/slaughter-house/services/slaughter-submit-delegate.js b/src/features/slaughter-house/services/slaughter-submit-delegate.js new file mode 100644 index 0000000..96a2271 --- /dev/null +++ b/src/features/slaughter-house/services/slaughter-submit-delegate.js @@ -0,0 +1,44 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const slaughterSubmitRepresentativeService = createAsyncThunk( + "SLAUGHTER_SUBMIT_REPRESENTATIVE_SERVICE", + async (d, { dispatch }) => { + try { + dispatch(LOADING_START()); + const { data, status } = await axios.post("representative/", d); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { + error: + e.response?.data?.result || + e.response?.data || + "خطا در ثبت نماینده", + }; + } + } +); + +export const slaughterEditRepresentativeService = createAsyncThunk( + "SLAUGHTER_EDIT_REPRESENTATIVE_SERVICE", + async (d, { dispatch }) => { + try { + dispatch(LOADING_START()); + const { data, status } = await axios.put("representative/0/", d); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { + error: + e.response?.data?.result || + e.response?.data || + "خطا در ویرایش نماینده", + }; + } + } +); + diff --git a/src/features/slaughter-house/services/slaughter-submit-free-buy-post.js b/src/features/slaughter-house/services/slaughter-submit-free-buy-post.js new file mode 100644 index 0000000..bfaccd9 --- /dev/null +++ b/src/features/slaughter-house/services/slaughter-submit-free-buy-post.js @@ -0,0 +1,18 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const slaughterSubmitFreeBuyPostService = createAsyncThunk( + "SLAUGHTER_SUBMIT_FREE_BUY_POST_SERVICE", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + try { + const { data, status } = await axios.post("kill_request/", d); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e.response.data.result }; + } + } +); diff --git a/src/features/slaughter-house/services/slaughter-submit-free-sale.js b/src/features/slaughter-house/services/slaughter-submit-free-sale.js new file mode 100644 index 0000000..145aa66 --- /dev/null +++ b/src/features/slaughter-house/services/slaughter-submit-free-sale.js @@ -0,0 +1,18 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const slaughterSubmitFreeSaleService = createAsyncThunk( + "SLAUGHTER_SUBMIT_FREE_SALE_SERVICE", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + try { + const { data, status } = await axios.post("kill_house_free_bar/", d); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e.response.data.result }; + } + } +); diff --git a/src/features/slaughter-house/services/slaughter-submit-out-province-service.js b/src/features/slaughter-house/services/slaughter-submit-out-province-service.js new file mode 100644 index 0000000..56bbfcb --- /dev/null +++ b/src/features/slaughter-house/services/slaughter-submit-out-province-service.js @@ -0,0 +1,33 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const slaughterSubmitOutOfProvinceService = createAsyncThunk( + "SLAUGHTER_SUBMIT_OUT_OF_PROVINCE_SELL", + async (d, { dispatch }) => { + try { + dispatch(LOADING_START()); + const { data, status } = await axios.post("kill_house_free_sale_bar/", d); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e.response.data.result }; + } + } +); + +export const guildSubmitOutOfProvinceService = createAsyncThunk( + "GUILD_SUBMIT_OUT_OF_PROVINCE_SELL", + async (d, { dispatch }) => { + try { + dispatch(LOADING_START()); + const { data, status } = await axios.post("steward_free_sale_bar/", d); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e.response.data.result }; + } + } +); diff --git a/src/features/slaughter-house/services/slaughter-supply-inventory.js b/src/features/slaughter-house/services/slaughter-supply-inventory.js new file mode 100644 index 0000000..fcdb826 --- /dev/null +++ b/src/features/slaughter-house/services/slaughter-supply-inventory.js @@ -0,0 +1,16 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; + +// axios.defaults.baseURL = "https://core-inventory.iran.liara.run/"; + +export const slaughterSupplyInventory = createAsyncThunk( + "SLAUGHTER_SUPPLY_INVENTORY", + async (basicUserData, warehouseData) => { + const createBasicUser = await axios.post("users/create", basicUserData); + // const userId = createBasicUser.data.Id; + if (createBasicUser.status === 200 || createBasicUser.status === 402) { + await axios.post("warehouses/create/", warehouseData); + } + // return { data, status }; + } +); diff --git a/src/features/slaughter-house/services/slaughter-update-allocation-for-freezing.js b/src/features/slaughter-house/services/slaughter-update-allocation-for-freezing.js new file mode 100644 index 0000000..a4c9d18 --- /dev/null +++ b/src/features/slaughter-house/services/slaughter-update-allocation-for-freezing.js @@ -0,0 +1,18 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const slaughterUpdateAllocationForFreezing = createAsyncThunk( + "SLAUGHTER_UPDATE_ALLOCATION_FOR_FREEZING", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + try { + const { data, status } = await axios.put("cold-house-allocations/0/", d); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e.response.data.result }; + } + } +); diff --git a/src/features/slaughter-house/services/slaughter-update-bar-weight.js b/src/features/slaughter-house/services/slaughter-update-bar-weight.js new file mode 100644 index 0000000..dbc34b8 --- /dev/null +++ b/src/features/slaughter-house/services/slaughter-update-bar-weight.js @@ -0,0 +1,21 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const slaughterUpdateBarWeight = createAsyncThunk( + "SLAUGHTER_UPDATE_BAR_WEIGHT", + async (d, { dispatch }) => { + try { + dispatch(LOADING_START()); + const { data, status } = await axios.put( + "kill_house_assignment_information/0/", + d + ); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e.response.data.result }; + } + } +); diff --git a/src/features/slaughter-house/services/slaughter-update-none-recipt.js b/src/features/slaughter-house/services/slaughter-update-none-recipt.js new file mode 100644 index 0000000..18b89ce --- /dev/null +++ b/src/features/slaughter-house/services/slaughter-update-none-recipt.js @@ -0,0 +1,18 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const slaughterUpdateNoneRecieptService = createAsyncThunk( + "SLAUGHTER_UPDATE_NONE_RECIPT", + async (d, { dispatch }) => { + try { + dispatch(LOADING_START()); + const { data, status } = await axios.put(`kill_house_request/0/`, d); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e.response.data.result }; + } + } +); diff --git a/src/features/slaughter-house/services/slaughterEditOutOfProvinceService.js b/src/features/slaughter-house/services/slaughterEditOutOfProvinceService.js new file mode 100644 index 0000000..6ee94d2 --- /dev/null +++ b/src/features/slaughter-house/services/slaughterEditOutOfProvinceService.js @@ -0,0 +1,36 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const slaughterEditOutOfProvinceService = createAsyncThunk( + "SLAUGHTER_EDIT_OUT_OF_PROVINCE_SELL", + async (d, { dispatch }) => { + try { + dispatch(LOADING_START()); + const { data, status } = await axios.put( + "kill_house_free_sale_bar/0/", + d + ); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e.response.data.result }; + } + } +); + +export const guildEditOutOfProvinceService = createAsyncThunk( + "GUILD_EDIT_OUT_OF_PROVINCE_SELL", + async (d, { dispatch }) => { + try { + dispatch(LOADING_START()); + const { data, status } = await axios.put("steward_free_sale_bar/0/", d); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e.response.data.result }; + } + } +); diff --git a/src/features/slaughter-house/services/total-report-daily-steward-broadcast.js b/src/features/slaughter-house/services/total-report-daily-steward-broadcast.js new file mode 100644 index 0000000..0ba1831 --- /dev/null +++ b/src/features/slaughter-house/services/total-report-daily-steward-broadcast.js @@ -0,0 +1,21 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const totalReportDailyStewardBroadCastService = createAsyncThunk( + "TOTAL_REPORT_DAILY_STEWARD_BROADCAST_SERVICE", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + const { data, status } = await axios.get( + `steward_ware_house_total_report_daily_broad_cast`, + { + params: { + date1: d.selectedDate1, + date2: d.selectedDate2, + }, + } + ); + dispatch(LOADING_END()); + return { data, status }; + } +); diff --git a/src/features/stats/ChickenPriceStats.js b/src/features/stats/ChickenPriceStats.js new file mode 100644 index 0000000..4242f69 --- /dev/null +++ b/src/features/stats/ChickenPriceStats.js @@ -0,0 +1,59 @@ +import { CircularProgress, Typography } from "@mui/material"; +import { useEffect, useState } from "react"; +import { useSelector } from "react-redux"; +import { Grid } from "../../components/grid/Grid"; +import { formatJustDate } from "../../utils/formatTime"; + +export const ChickenPriceStats = ({ province }) => { + const [data, setData] = useState([]); + const [loading, setLoading] = useState(false); + const { authToken } = useSelector((state) => state.userSlice); + + useEffect(() => { + fetch(`${province}total_pricing_dashboard/`, { + headers: { + Authorization: `Bearer ${authToken}`, + }, + }) + .then((response) => response.json()) + .then((data) => { + setData(data); + setLoading(false); + }) + .catch((error) => { + console.error("Error fetching data:", error); + setLoading(false); + }); + }, [province]); + + return ( + <> + {loading ? ( + + ) : ( + + {/* */} + + قیمت روز مرغ + + + + آخرین قیمت: {data?.last_price?.toLocaleString()} ﷼ + + + تاریخ بروزرسانی: {formatJustDate(data?.last_change)} + + + + )} + + ); +}; diff --git a/src/features/stats/DistributeOfCarcasses.js b/src/features/stats/DistributeOfCarcasses.js new file mode 100644 index 0000000..3288cb5 --- /dev/null +++ b/src/features/stats/DistributeOfCarcasses.js @@ -0,0 +1,61 @@ +import { Button, CircularProgress, Typography } from "@mui/material"; +import { useEffect, useState } from "react"; +import { Grid } from "../../components/grid/Grid"; +import moment from "moment"; +import { getRoleFromUrl } from "../../utils/getRoleFromUrl"; + +export const DistributeOfCarcasses = ({ province }) => { + const [data, setData] = useState([]); + const [loading, setLoading] = useState(true); + useEffect(() => { + fetch( + `${province}steward_guilds_allocations_for_statistical_profile/?date=${moment( + new Date() + ).format("YYYY-MM-DD")}&?role=${getRoleFromUrl()}`, + {} + ) + .then((response) => response.json()) + .then((data) => { + setData(data); + setLoading(false); + }) + .catch((error) => { + console.error("Error fetching data:", error); + setLoading(false); + }); + }, [province]); + + return ( + <> + {loading ? ( + + ) : ( + + + توزیع لاشه + + + + تعداد واحد: {data?.allocations?.toLocaleString()} بار + + + حجم لاشه: {data?.real_number_of_carcasses?.toLocaleString()} قطعه + + + وزن لاشه : {data?.real_weight_of_carcasses?.toLocaleString()}{" "} + کیلوگرم + + + + + )} + + ); +}; diff --git a/src/features/stats/FarmsStats.js b/src/features/stats/FarmsStats.js new file mode 100644 index 0000000..46a705e --- /dev/null +++ b/src/features/stats/FarmsStats.js @@ -0,0 +1,74 @@ +import { CircularProgress, Typography } from "@mui/material"; +import { useEffect, useState } from "react"; +import { useSelector } from "react-redux"; +import { Grid } from "../../components/grid/Grid"; +import { getRoleFromUrl } from "../../utils/getRoleFromUrl"; + +export const FarmsStats = ({ province }) => { + const [data, setData] = useState([]); + const [loading, setLoading] = useState(false); + const { authToken } = useSelector((state) => state.userSlice); + + useEffect(() => { + fetch( + `${province}total_poultry_hatching_dashboard/?role=${getRoleFromUrl()}`, + { + headers: { + Authorization: `Bearer ${authToken}`, + }, + } + ) + .then((response) => response.json()) + .then((data) => { + setData(data); + setLoading(false); + }) + .catch((error) => { + console.error("Error fetching data:", error); + setLoading(false); + }); + }, [province]); + + return ( + <> + {loading ? ( + + ) : ( + + {/* */} + + فارم های فعال + + + + تعداد فارم: {data?.poultry_counts?.toLocaleString()} واحد + + + جوجه ریزی:{" "} + {data?.total_poultry_hatchings_quantity?.toLocaleString()} قطعه + + + تلفات (10٪): {data?.losses?.toLocaleString()} قطعه + + + کشتار شده:{" "} + {data?.total_kill_house_request_quantity?.toLocaleString()} قطعه + + + مانده در سالن:{" "} + {data?.total_poultry_hatchings_left?.toLocaleString()} قطعه + + + + )} + + ); +}; diff --git a/src/features/stats/HatchingRemainPredictionStats.js b/src/features/stats/HatchingRemainPredictionStats.js new file mode 100644 index 0000000..8a24f1c --- /dev/null +++ b/src/features/stats/HatchingRemainPredictionStats.js @@ -0,0 +1,192 @@ +import React, { useEffect, useState } from "react"; +import { Button, CircularProgress, TextField, Typography } from "@mui/material"; +import { DatePicker } from "@mui/x-date-pickers"; +import { useFormik } from "formik"; +import { Grid } from "../../components/grid/Grid"; +import { Yup } from "../../lib/yup/yup"; +import { addMonths } from "date-fns-jalali"; +import { useDispatch, useSelector } from "react-redux"; +import { Bar } from "react-chartjs-2"; +import moment from "moment/moment"; +import { formatJustDate } from "../../utils/formatTime"; +import { LOADING_END, LOADING_START } from "../../lib/redux/slices/appSlice"; +import { getRoleFromUrl } from "../../utils/getRoleFromUrl"; + +const validationSchema = Yup.object({ + startDate: Yup.date("تاریخ شروع الزامی است").required( + "تاریخ شروع الزامی است" + ), + endDate: Yup.date("تاریخ شروع الزامی است").required("تاریخ پایان الزامی است"), + textInput: Yup.string("تاریخ شروع الزامی است").required("سن الزامی است"), +}); + +export const HatchingRemainPredictionStats = ({ province }) => { + const dispatch = useDispatch(); + const [data, setData] = useState([]); + const [loading, setLoading] = useState(true); + const { authToken } = useSelector((state) => state.userSlice); + + const fetchData = () => { + dispatch(LOADING_START()); + fetch( + `${province}forecast_hatching_left_over/?date1=${moment( + formik.values.startDate + ).format("YYYY-MM-DD")}&date2=${moment(formik.values.endDate).format( + "YYYY-MM-DD" + )}&age=${formik.values.textInput}&role=${getRoleFromUrl()}`, + { + headers: { + Authorization: `Bearer ${authToken}`, + }, + } + ) + .then((response) => response.json()) + .then((data) => { + setData(data); + setLoading(false); + dispatch(LOADING_END()); + }) + .catch((error) => { + console.error("Error fetching data:", error); + setLoading(false); + dispatch(LOADING_END()); + }); + }; + + useEffect(() => { + fetchData(); + }, [province]); + + const dataSample = { + labels: data.map((item) => formatJustDate(item.date)), + datasets: [ + { + label: "تعداد جوجه ریزی", + data: data.map((item) => item.hatching_left_over), + backgroundColor: "rgba(75,192,192,0.2)", + borderColor: "rgba(75,192,192,1)", + borderWidth: 1, + }, + ], + }; + + const options = { + scales: { + y: { + beginAtZero: true, + }, + }, + plugins: { + rtl: true, // This enables RTL layout + }, + }; + + const today = new Date(); + const defaultEndDate = addMonths(today, 1); + + const formik = useFormik({ + initialValues: { + startDate: today, + endDate: defaultEndDate, + textInput: "45", + }, + validationSchema: validationSchema, + onSubmit: (values) => { + // console.log(values); + fetchData(); + }, + }); + + return ( + + + + جوجه ریزی مانده در سالن براساس بازه زمانی و سن (تلفات پیش فرض 10٪) + +
    + + + formik.setFieldValue("startDate", date)} + renderInput={(params) => ( + + )} + /> + + + formik.setFieldValue("endDate", date)} + renderInput={(params) => ( + + )} + /> + + + + + + + + +
    +
    + + {loading ? ( + + ) : ( + + )} + +
    + ); +}; diff --git a/src/features/stats/HatchingStock.js b/src/features/stats/HatchingStock.js new file mode 100644 index 0000000..c6f85f2 --- /dev/null +++ b/src/features/stats/HatchingStock.js @@ -0,0 +1,86 @@ +import { Bar } from "react-chartjs-2"; +import { Chart as ChartJs } from "chart.js/auto"; +import { useEffect, useState } from "react"; + +import { Button, CircularProgress, Typography } from "@mui/material"; +import { useSelector } from "react-redux"; +import { defaults } from "chart.js"; +import { getRoleFromUrl } from "../../utils/getRoleFromUrl"; + +defaults.font.family = "iranyekan"; + +console.log(ChartJs); + +export const HatchingStock = ({ province }) => { + const [data, setData] = useState([]); + const [loading, setLoading] = useState(true); + const { authToken } = useSelector((state) => state.userSlice); + + useEffect(() => { + fetch(`${province}hatching_age_range/?role=${getRoleFromUrl()}`, { + headers: { + Authorization: `Bearer ${authToken}`, + }, + }) + .then((response) => response.json()) + .then((data) => { + setData(data); + setLoading(false); + }) + .catch((error) => { + console.error("Error fetching data:", error); + setLoading(false); + }); + }, [province]); + + const dataSample = { + labels: data?.filter((item) => item?.quantity).map((item) => item.type), + datasets: [ + { + label: "تعداد جوجه ریزی", + data: data + ?.filter((item) => item.quantity) + ?.map((item) => item.quantity), + backgroundColor: "rgba(75,192,192,0.2)", + borderColor: "rgba(75,192,192,1)", + borderWidth: 1, + }, + ], + }; + + const options = { + scales: { + y: { + beginAtZero: true, + }, + }, + plugins: { + rtl: true, // This enables RTL layout + }, + }; + + return ( + <> + {loading ? ( + + ) : ( + <> + + موجودی جوجه ریزی (مانده در سالن) بر اساس بازه سنی + {(getRoleFromUrl() === "ProvinceOperator" || + getRoleFromUrl() === "SuperAdmin") && ( + + + + )} + + + + )} + + ); +}; diff --git a/src/features/stats/HatchingStockAge.js b/src/features/stats/HatchingStockAge.js new file mode 100644 index 0000000..2ce14f9 --- /dev/null +++ b/src/features/stats/HatchingStockAge.js @@ -0,0 +1,85 @@ +import { Bar } from "react-chartjs-2"; +import { Chart as ChartJs } from "chart.js/auto"; +import { useEffect, useState } from "react"; + +import { Button, CircularProgress, Typography } from "@mui/material"; +import { useSelector } from "react-redux"; +import { defaults } from "chart.js"; +import { getRoleFromUrl } from "../../utils/getRoleFromUrl"; + +defaults.font.family = "iranyekan"; +console.log(ChartJs); + +export const HatchingStockAge = ({ province }) => { + const [data, setData] = useState([]); + const [loading, setLoading] = useState(true); + const { authToken } = useSelector((state) => state.userSlice); + + useEffect(() => { + fetch(`${province}single_hatching_age_range/?role=${getRoleFromUrl()}`, { + headers: { + Authorization: `Bearer ${authToken}`, + }, + }) + .then((response) => response.json()) + .then((data) => { + setData(data); + setLoading(false); + }) + .catch((error) => { + console.error("Error fetching data:", error); + setLoading(false); + }); + }, [province]); + + const dataSample = { + labels: data?.filter((item) => item?.quantity)?.map((item) => item?.type), + datasets: [ + { + label: "تعداد جوجه ریزی", + data: data + .filter((item) => item?.quantity) + .map((item) => item?.quantity), + backgroundColor: "rgba(9, 132, 227,0.3)", + borderColor: "rgba(9, 132, 227,1.0)", + borderWidth: 1, + }, + ], + }; + + const options = { + scales: { + y: { + beginAtZero: true, + }, + }, + plugins: { + rtl: true, // This enables RTL layout + }, + }; + + return ( + <> + {loading ? ( + + ) : ( + <> + + موجودی جوجه ریزی (مانده در سالن) بر اساس سن + {(getRoleFromUrl() === "ProvinceOperator" || + getRoleFromUrl() === "SuperAdmin") && ( + + + + )} + + + + )} + + ); +}; diff --git a/src/features/stats/HatchingStockCity.js b/src/features/stats/HatchingStockCity.js new file mode 100644 index 0000000..57c0d01 --- /dev/null +++ b/src/features/stats/HatchingStockCity.js @@ -0,0 +1,212 @@ +import { Pie } from "react-chartjs-2"; +import { Chart as ChartJs } from "chart.js/auto"; +import { useEffect, useState } from "react"; +import { + Button, + CircularProgress, + FormControl, + MenuItem, + Select, + Tooltip, + Typography, +} from "@mui/material"; +// import { useSelector } from "react-redux"; +import { defaults } from "chart.js"; +import { useSelector } from "react-redux"; +import { Grid } from "../../components/grid/Grid"; +import { format } from "date-fns-jalali"; +import { RiFileExcel2Fill } from "react-icons/ri"; +import { getRoleFromUrl } from "../../utils/getRoleFromUrl"; + +defaults.font.family = "iranyekan"; +console.log(ChartJs); + +export const HatchingStockCity = ({ province }) => { + const [data, setData] = useState([]); + const [loading, setLoading] = useState(false); + const { authToken } = useSelector((state) => state.userSlice); + const userKey = useSelector((state) => state.userSlice.userProfile.key); + + // Create a new Date object + const currentDate = new Date(); + const shamsiDate = format(new Date(currentDate), "M"); + const [selectedMonth, setSelectedMonth] = useState(shamsiDate); + + const handleMonthChange = (event) => { + setSelectedMonth(event.target.value); + }; + + // const ageRanges = data.map((item) => item.age_range); + // const counts = data.map((item) => item.count); + + // const chartData = { + // labels: ageRanges, + // datasets: [ + // { + // data: counts, + // backgroundColor: [ + // "rgba(75, 192, 192, 0.6)", + // "rgba(255, 99, 132, 0.6)", + // "rgba(255, 206, 86, 0.6)", + // // Add more colors here if needed + // ], + // }, + // ], + // }; + + const chartData = { + labels: data.map((item) => item.city), + datasets: [ + { + // label: "Sample Doughnut Chart", + data: data.map((item) => item.percent), + quantity: data.map((item) => item.quantity), + backgroundColor: [ + "#FF6384", + "#36A2EB", + "#FFCE56", + "#4CAF50", + "#9C27B0", + ], + }, + ], + }; + + useEffect(() => { + fetch( + `${province}doughnut_hatching/?month=${selectedMonth}&role=${getRoleFromUrl()}`, + { + headers: { + Authorization: `Bearer ${authToken}`, + }, + } + ) + .then((response) => response.json()) + .then((data) => { + setData(data); + setLoading(false); + }) + .catch((error) => { + console.error("Error fetching data:", error); + setLoading(false); + }); + }, [selectedMonth, province]); + + // const dataSample = { + // labels: data.filter((item) => item.quantity).map((item) => item.type), + // datasets: [ + // { + // label: "تعداد جوجه ریزی", + // data: data.filter((item) => item.quantity).map((item) => item.quantity), + // backgroundColor: "rgba(75,192,192,0.2)", + // borderColor: "rgba(75,192,192,1)", + // borderWidth: 1, + // }, + // ], + // }; + + // const options = { + // scales: { + // y: { + // beginAtZero: true, + // }, + // }, + // plugins: { + // rtl: true, // This enables RTL layout + // }, + // }; + + const options = { + plugins: { + legend: { + display: true, + position: "bottom", + }, + tooltip: { + callbacks: { + label: (context) => { + const label = context.label || ""; + const value = context.formattedValue; + const quantity = context.dataset.quantity[context.dataIndex]; + return `${label}: %${value} - ${quantity?.toLocaleString()} قطعه`; + }, + }, + }, + datalabels: { + color: "#fff", + formatter: (value, context) => { + const txt = `${ + context.chart.data.labels[context.dataIndex] + }: ٪${value}`; + return `${txt}`; + }, + }, + }, + }; + + const months = [ + "فروردین", + "اردیبهشت", + "خرداد", + "تیر", + "مرداد", + "شهریور", + "مهر", + "آبان", + "آذر", + "دی", + "بهمن", + "اسفند", + ]; + + return ( + <> + {loading ? ( + + ) : ( + <> + + + گزارش کل جوجه ریزی بر اساس شهرستان + + + + + + + + + + +
    + +
    + + )} + + ); +}; diff --git a/src/features/stats/HatchingStockCityRemain.js b/src/features/stats/HatchingStockCityRemain.js new file mode 100644 index 0000000..114661f --- /dev/null +++ b/src/features/stats/HatchingStockCityRemain.js @@ -0,0 +1,197 @@ +import { Pie } from "react-chartjs-2"; +import { Chart as ChartJs } from "chart.js/auto"; +import { useEffect, useState } from "react"; +import { + Button, + CircularProgress, + FormControl, + MenuItem, + Select, + Tooltip, + Typography, +} from "@mui/material"; +// import { useSelector } from "react-redux"; +import { defaults } from "chart.js"; +import { useSelector } from "react-redux"; +import ChartDataLabels from "chartjs-plugin-datalabels"; +import { Grid } from "../../components/grid/Grid"; +import { RiFileExcel2Fill } from "react-icons/ri"; +import { getRoleFromUrl } from "../../utils/getRoleFromUrl"; +import { format } from "date-fns-jalali"; + +ChartJs.register(ChartDataLabels); + +defaults.font.family = "iranyekan"; +console.log(ChartJs); + +export const HatchingStockCityRemain = ({ province }) => { + const [data, setData] = useState([]); + const [loading, setLoading] = useState(false); + const { authToken } = useSelector((state) => state.userSlice); + + // Create a new Date object + const currentDate = new Date(); + const shamsiDate = format(new Date(currentDate), "M"); + const [selectedMonth, setSelectedMonth] = useState(shamsiDate); + + const handleMonthChange = (event) => { + setSelectedMonth(event.target.value); + }; + + const months = [ + "فروردین", + "اردیبهشت", + "خرداد", + "تیر", + "مرداد", + "شهریور", + "مهر", + "آبان", + "آذر", + "دی", + "بهمن", + "اسفند", + ]; + + const chartData = { + labels: data.filter((item) => item.percent).map((item) => item.city), + datasets: [ + { + label: "جوجه ریزی", + data: data.filter((item) => item.percent).map((item) => item.percent), + quantity: data.map((item) => item.quantity), + backgroundColor: [ + "#FF6384", + "#36A2EB", + "#FFCE56", + "#4CAF50", + "#9C27B0", + ], + }, + ], + }; + + useEffect(() => { + fetch( + `${province}doughnut_left_hatching/?month=${selectedMonth}&role=${getRoleFromUrl()}`, + { + headers: { + Authorization: `Bearer ${authToken}`, + }, + } + ) + .then((response) => response.json()) + .then((data) => { + setData(data); + setLoading(false); + }) + .catch((error) => { + console.error("Error fetching data:", error); + setLoading(false); + }); + }, [selectedMonth, province]); + + // const dataSample = { + // labels: data.filter((item) => item.quantity).map((item) => item.type), + // datasets: [ + // { + // label: "تعداد جوجه ریزی", + // data: data.filter((item) => item.quantity).map((item) => item.quantity), + // backgroundColor: "rgba(75,192,192,0.2)", + // borderColor: "rgba(75,192,192,1)", + // borderWidth: 1, + // }, + // ], + // }; + + // const options = { + // scales: { + // y: { + // beginAtZero: true, + // }, + // }, + // plugins: { + // rtl: true, // This enables RTL layout + // }, + // }; + + const options = { + plugins: { + legend: { + display: true, + position: "bottom", + }, + tooltip: { + callbacks: { + label: (context) => { + const label = context.label || ""; + const value = context.formattedValue; + const quantity = context.dataset.quantity[context.dataIndex]; + return `${label}: %${value} - ${quantity?.toLocaleString()} قطعه`; + }, + }, + }, + datalabels: { + color: "#fff", + formatter: (value, context) => { + const txt = `${ + context.chart.data.labels[context.dataIndex] + }: ٪${value}`; + return `${txt}`; + }, + }, + }, + }; + + return ( + <> + {loading ? ( + + ) : ( + <> + + + گزارش مانده جوجه ریزی بر اساس شهرستان + + + + + + + + + + + +
    + +
    + + )} + + ); +}; diff --git a/src/features/stats/KillFilesStats.js b/src/features/stats/KillFilesStats.js new file mode 100644 index 0000000..85eeadd --- /dev/null +++ b/src/features/stats/KillFilesStats.js @@ -0,0 +1,72 @@ +import { CircularProgress, Typography } from "@mui/material"; +import { useEffect, useState } from "react"; +import { useSelector } from "react-redux"; +import { Grid } from "../../components/grid/Grid"; +import { getRoleFromUrl } from "../../utils/getRoleFromUrl"; + +export const KillFilesStats = ({ province }) => { + const [data, setData] = useState([]); + const [loading, setLoading] = useState(false); + const { authToken } = useSelector((state) => state.userSlice); + + useEffect(() => { + fetch( + `${province}total_file_poultry_request_dashboard/?role=${getRoleFromUrl()}`, + { + headers: { + Authorization: `Bearer ${authToken}`, + }, + } + ) + .then((response) => response.json()) + .then((data) => { + setData(data); + setLoading(false); + }) + .catch((error) => { + console.error("Error fetching data:", error); + setLoading(false); + }); + }, [province]); + + return ( + <> + {loading ? ( + + ) : ( + + {/* */} + + پرونده های کشتار + + + + کل پرونده ها:{" "} + {data?.total_poultry_request_quantity?.toLocaleString()} + + + تایید شده:{" "} + {data?.accepted_poultry_request_quantity?.toLocaleString()} + + + رد شده:{" "} + {data?.rejected_poultry_request_quantity?.toLocaleString()} + + + بایگانی شده:{" "} + {data?.archive_poultry_request_quantity?.toLocaleString()} + + + + )} + + ); +}; diff --git a/src/features/stats/KillProcessAllocationStats.js b/src/features/stats/KillProcessAllocationStats.js new file mode 100644 index 0000000..74bf04f --- /dev/null +++ b/src/features/stats/KillProcessAllocationStats.js @@ -0,0 +1,72 @@ +import { Button, CircularProgress, Typography } from "@mui/material"; +import { useEffect, useState } from "react"; +import { useSelector } from "react-redux"; +import { Grid } from "../../components/grid/Grid"; +import { getRoleFromUrl } from "../../utils/getRoleFromUrl"; + +export const KillProcessAllocationStats = ({ province }) => { + const [data, setData] = useState([]); + const [loading, setLoading] = useState(true); + const { authToken } = useSelector((state) => state.userSlice); + + useEffect(() => { + fetch( + `${province}province_kill_request_killing_process/?role=${getRoleFromUrl()}`, + { + headers: { + Authorization: `Bearer ${authToken}`, + }, + } + ) + .then((response) => response.json()) + .then((data) => { + setData(data); + setLoading(false); + }) + .catch((error) => { + console.error("Error fetching data:", error); + setLoading(false); + }); + }, []); + + return ( + <> + {loading ? ( + + ) : ( + + + تخصیصات + + + + تعداد کشتارگاه: {data?.kill_house_quantity?.toLocaleString()} واحد + + + تعداد: {data?.province_kill_request_quantity?.toLocaleString()}{" "} + قطعه + + + وزن : {data?.province_kill_request_index_weight?.toLocaleString()}{" "} + کیلوگرم + + + + + + + )} + + ); +}; diff --git a/src/features/stats/KillProcessKillRequestStats.js b/src/features/stats/KillProcessKillRequestStats.js new file mode 100644 index 0000000..72eabe7 --- /dev/null +++ b/src/features/stats/KillProcessKillRequestStats.js @@ -0,0 +1,76 @@ +import { Button, CircularProgress, Typography } from "@mui/material"; +import { useEffect, useState } from "react"; +import { useSelector } from "react-redux"; +import { Grid } from "../../components/grid/Grid"; +import { getRoleFromUrl } from "../../utils/getRoleFromUrl"; + +export const KillProcessKillRequestStats = ({ province }) => { + const [data, setData] = useState([]); + const [loading, setLoading] = useState(true); + const { authToken } = useSelector((state) => state.userSlice); + + useEffect(() => { + fetch( + `${province}poultry_request_killing_process/?role=${getRoleFromUrl()}`, + { + headers: { + Authorization: `Bearer ${authToken}`, + }, + } + ) + .then((response) => response.json()) + .then((data) => { + setData(data); + setLoading(false); + }) + .catch((error) => { + console.error("Error fetching data:", error); + setLoading(false); + }); + }, []); + + return ( + <> + {loading ? ( + + ) : ( + + + درخواست کشتار + + + + تعداد مرغدار: {data?.poultry_quantity?.toLocaleString()} فارم + + + تعداد: {data?.poultry_request_quantity?.toLocaleString()} قطعه + + + وزن : {data?.poultry_request_index_weight?.toLocaleString()}{" "} + کیلوگرم + + + + + + + )} + + ); +}; diff --git a/src/features/stats/KillProcessKillhouseVetStats.js b/src/features/stats/KillProcessKillhouseVetStats.js new file mode 100644 index 0000000..62a6a85 --- /dev/null +++ b/src/features/stats/KillProcessKillhouseVetStats.js @@ -0,0 +1,64 @@ +import { Button, CircularProgress, Typography } from "@mui/material"; +import { useEffect, useState } from "react"; +import { useSelector } from "react-redux"; +import { Grid } from "../../components/grid/Grid"; +import { getRoleFromUrl } from "../../utils/getRoleFromUrl"; + +export const KillProcessKillhouseVetStats = ({ province }) => { + const [data, setData] = useState([]); + const [loading, setLoading] = useState(true); + const { authToken } = useSelector((state) => state.userSlice); + + useEffect(() => { + fetch( + `${province}kill_house__request_vet_killing_process/?role=${getRoleFromUrl()}`, + { + headers: { + Authorization: `Bearer ${authToken}`, + }, + } + ) + .then((response) => response.json()) + .then((data) => { + setData(data); + setLoading(false); + }) + .catch((error) => { + console.error("Error fetching data:", error); + setLoading(false); + }); + }, []); + + return ( + <> + {loading ? ( + + ) : ( + + + کشتارگاه + + + + بار تخلیه شده: {data?.vet_check_counter?.toLocaleString()} بار + + + تعداد: {data?.kill_house_quantity?.toLocaleString()} قطعه + + + وزن : {data?.kill_house_request_weight?.toLocaleString()} کیلوگرم + + + + + )} + + ); +}; diff --git a/src/features/stats/KillProcessVetFarmStats.js b/src/features/stats/KillProcessVetFarmStats.js new file mode 100644 index 0000000..c0d940c --- /dev/null +++ b/src/features/stats/KillProcessVetFarmStats.js @@ -0,0 +1,64 @@ +import { Button, CircularProgress, Typography } from "@mui/material"; +import { useEffect, useState } from "react"; +import { useSelector } from "react-redux"; +import { Grid } from "../../components/grid/Grid"; +import { getRoleFromUrl } from "../../utils/getRoleFromUrl"; + +export const KillProcessVetFarmStats = ({ province }) => { + const [data, setData] = useState([]); + const [loading, setLoading] = useState(true); + const { authToken } = useSelector((state) => state.userSlice); + + useEffect(() => { + fetch( + `${province}kill_house__request_vetfarm_killing_process/?role=${getRoleFromUrl()}`, + { + headers: { + Authorization: `Bearer ${authToken}`, + }, + } + ) + .then((response) => response.json()) + .then((data) => { + setData(data); + setLoading(false); + }) + .catch((error) => { + console.error("Error fetching data:", error); + setLoading(false); + }); + }, []); + + return ( + <> + {loading ? ( + + ) : ( + + + مسئول فنی مزرعه + + + + کد قرنطینه: {data?.clearance_code_counter?.toLocaleString()} بار + + + تعداد: {data?.kill_house_quantity?.toLocaleString()} قطعه + + + وزن : {data?.kill_house_request_weight?.toLocaleString()} کیلوگرم + + + + + )} + + ); +}; diff --git a/src/features/stats/KillRequestsStats.js b/src/features/stats/KillRequestsStats.js new file mode 100644 index 0000000..909351f --- /dev/null +++ b/src/features/stats/KillRequestsStats.js @@ -0,0 +1,73 @@ +import { CircularProgress, Typography } from "@mui/material"; +import { useEffect, useState } from "react"; +import { useSelector } from "react-redux"; +import { Grid } from "../../components/grid/Grid"; +import { getRoleFromUrl } from "../../utils/getRoleFromUrl"; + +export const KillRequestsStats = ({ province }) => { + const [data, setData] = useState([]); + const [loading, setLoading] = useState(false); + const { authToken } = useSelector((state) => state.userSlice); + + useEffect(() => { + fetch( + `${province}total_poultry_request_dashboard/?role=${getRoleFromUrl()}`, + { + headers: { + Authorization: `Bearer ${authToken}`, + }, + } + ) + .then((response) => response.json()) + .then((data) => { + setData(data); + setLoading(false); + }) + .catch((error) => { + console.error("Error fetching data:", error); + setLoading(false); + }); + }, [province]); + + return ( + <> + {loading ? ( + + ) : ( + + {/* */} + + درخواست های کشتار + + + + کل درخواست ها:{" "} + {data?.total_poultry_request_quantity?.toLocaleString()} قطعه + + + تایید شده:{" "} + {data?.accepted_poultry_request_quantity?.toLocaleString()} قطعه + + + کل بارها:{" "} + {data?.total_kill_house_request_quantity?.toLocaleString()} قطعه + + + تخلیه شده:{" "} + {data?.accepted_kill_house_request_quantity?.toLocaleString()}{" "} + قطعه + + + + )} + + ); +}; diff --git a/src/features/stats/NumberOfKills.js b/src/features/stats/NumberOfKills.js new file mode 100644 index 0000000..5c80a1f --- /dev/null +++ b/src/features/stats/NumberOfKills.js @@ -0,0 +1,118 @@ +import { Line } from "react-chartjs-2"; +import { Chart as ChartJs } from "chart.js/auto"; +import { useEffect, useState } from "react"; +import { + Button, + CircularProgress, + FormControl, + MenuItem, + Select, + Typography, +} from "@mui/material"; +import { useSelector } from "react-redux"; +import { defaults } from "chart.js"; +import { formatJustDate } from "../../utils/formatTime"; +import { Grid } from "../../components/grid/Grid"; +import { getRoleFromUrl } from "../../utils/getRoleFromUrl"; + +defaults.font.family = "iranyekan"; + +console.log(ChartJs); + +export const NumberOfKills = ({ province }) => { + const [data, setData] = useState([]); + const [loading, setLoading] = useState(true); + const { authToken } = useSelector((state) => state.userSlice); + const userKey = useSelector((state) => state.userSlice.userProfile.key); + + const [selectedOption, setSelectedOption] = useState(10); + + const handleChange = (event) => { + setSelectedOption(event.target.value); + }; + + useEffect(() => { + fetch( + `${province}number_of_kills/?day=${selectedOption}&role=${getRoleFromUrl()}`, + { + headers: { + Authorization: `Bearer ${authToken}`, + }, + } + ) + .then((response) => response.json()) + .then((data) => { + setData(data); + setLoading(false); + }) + .catch((error) => { + console.error("Error fetching data:", error); + setLoading(false); + }); + }, [selectedOption, province]); + + const dataSample = { + labels: data.map((item) => formatJustDate(item.date)), + datasets: [ + { + label: "تعداد کشتار", + data: data.map((item) => item.quantity), + backgroundColor: "rgba(75,192,192,0.2)", + borderColor: "rgba(75,192,192,1)", + borderWidth: 1, + }, + ], + }; + + const options = { + scales: { + y: { + beginAtZero: true, + }, + }, + plugins: { + rtl: true, // This enables RTL layout + }, + }; + + return ( + <> + {loading ? ( + + ) : ( + <> + + گزارش تعداد کشتار + + + + + + روز گذشته (براساس بار) + + + + + + + )} + + ); +}; diff --git a/src/features/stats/NumberOfKillsByWeight.js b/src/features/stats/NumberOfKillsByWeight.js new file mode 100644 index 0000000..0eb064d --- /dev/null +++ b/src/features/stats/NumberOfKillsByWeight.js @@ -0,0 +1,117 @@ +import { Line } from "react-chartjs-2"; +import { Chart as ChartJs } from "chart.js/auto"; +import { useEffect, useState } from "react"; +import { + Button, + CircularProgress, + FormControl, + MenuItem, + Select, + Typography, +} from "@mui/material"; +import { useSelector } from "react-redux"; +import { defaults } from "chart.js"; +import { formatJustDate } from "../../utils/formatTime"; +import { Grid } from "../../components/grid/Grid"; +import { getRoleFromUrl } from "../../utils/getRoleFromUrl"; + +defaults.font.family = "iranyekan"; + +console.log(ChartJs); + +export const NumberOfKillsByWeight = ({ province }) => { + const [data, setData] = useState([]); + const [loading, setLoading] = useState(true); + const { authToken } = useSelector((state) => state.userSlice); + const userKey = useSelector((state) => state.userSlice.userProfile.key); + const [selectedOption, setSelectedOption] = useState(10); + + const handleChange = (event) => { + setSelectedOption(event.target.value); + }; + + useEffect(() => { + fetch( + `${province}number_of_kills_weight/?day=${selectedOption}&role=${getRoleFromUrl()}`, + { + headers: { + Authorization: `Bearer ${authToken}`, + }, + } + ) + .then((response) => response.json()) + .then((data) => { + setData(data); + setLoading(false); + }) + .catch((error) => { + console.error("Error fetching data:", error); + setLoading(false); + }); + }, [selectedOption, province]); + + const dataSample = { + labels: data.map((item) => formatJustDate(item.date)), + datasets: [ + { + label: "وزن کشتار", + data: data.map((item) => item.weight), + backgroundColor: "rgba(75,192,192,0.2)", + borderColor: "rgba(75,192,192,1)", + borderWidth: 1, + }, + ], + }; + + const options = { + scales: { + y: { + beginAtZero: true, + }, + }, + plugins: { + rtl: true, // This enables RTL layout + }, + }; + + return ( + <> + {loading ? ( + + ) : ( + <> + + گزارش وزن کشتار + + + + + + روز گذشته (براساس بار) + + + + + + + )} + + ); +}; diff --git a/src/features/stats/UserStats.js b/src/features/stats/UserStats.js new file mode 100644 index 0000000..d632ef6 --- /dev/null +++ b/src/features/stats/UserStats.js @@ -0,0 +1,65 @@ +import { CircularProgress, Typography } from "@mui/material"; +import { useEffect, useState } from "react"; +import { useSelector } from "react-redux"; +import { Grid } from "../../components/grid/Grid"; +import { getRoleFromUrl } from "../../utils/getRoleFromUrl"; + +export const UsersStats = ({ province }) => { + const [data, setData] = useState([]); + const [loading, setLoading] = useState(false); + const { authToken } = useSelector((state) => state.userSlice); + + useEffect(() => { + fetch( + `${province}total_system_user_profile_dashboard/?role=${getRoleFromUrl()}`, + { + headers: { + Authorization: `Bearer ${authToken}`, + }, + } + ) + .then((response) => response.json()) + .then((data) => { + setData(data); + setLoading(false); + }) + .catch((error) => { + console.error("Error fetching data:", error); + setLoading(false); + }); + }, [province]); + + return ( + <> + {loading ? ( + + ) : ( + + {/* */} + + کاربران + + + + کل: {data?.users?.toLocaleString()} + + + مرغداران: {data?.poultries?.toLocaleString()} + + + اصناف: {data?.guilds?.toLocaleString()} + + + + )} + + ); +}; diff --git a/src/features/steward/components/steward-buy-out-operations/StewardSellOutOperations.js b/src/features/steward/components/steward-buy-out-operations/StewardSellOutOperations.js new file mode 100644 index 0000000..6e08490 --- /dev/null +++ b/src/features/steward/components/steward-buy-out-operations/StewardSellOutOperations.js @@ -0,0 +1,86 @@ +import { Button, IconButton, Popover } from "@mui/material"; +import { useState } from "react"; +import { useDispatch } from "react-redux"; +import TuneIcon from "@mui/icons-material/Tune"; +import { stewardDeleteFreeBarService } from "../../../guild/services/steward-submit-free-bar-service"; +import { Grid } from "../../../../components/grid/Grid"; +import { DRAWER } from "../../../../lib/redux/slices/appSlice"; +import { StewardSubmitFreeBar } from "../steward-submit-free-bar/StewardSubmitFreeBar"; + +export const StewardSellOutOperations = ({ item, updateTable }) => { + const dispatch = useDispatch(); + const [anchorEl, setAnchorEl] = useState(null); + + const handleClick = (event) => { + setAnchorEl(event.currentTarget); + }; + + const handleClose = () => { + setAnchorEl(null); + }; + + const open = Boolean(anchorEl); + const id = open ? "popover" : undefined; + + const handleDelete = () => { + handleClose(); + dispatch(stewardDeleteFreeBarService(item.key)).then(() => { + updateTable(); + }); + }; + + return ( +
    + + + + +
    + + + + +
    +
    +
    + ); +}; diff --git a/src/features/steward/components/steward-out-province-registration-code-input/StewardOutProvinceRegistrationCodeInput.js b/src/features/steward/components/steward-out-province-registration-code-input/StewardOutProvinceRegistrationCodeInput.js new file mode 100644 index 0000000..dae7bb7 --- /dev/null +++ b/src/features/steward/components/steward-out-province-registration-code-input/StewardOutProvinceRegistrationCodeInput.js @@ -0,0 +1,99 @@ +import React, { useContext, useState } from "react"; +import { Grid } from "../../../../components/grid/Grid"; +import { Button, TextField } from "@mui/material"; +import { useDispatch } from "react-redux"; +import { AppContext } from "../../../../contexts/AppContext"; +import { guildEditOutOfProvinceService } from "../../../slaughter-house/services/slaughterEditOutOfProvinceService"; +import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl"; +import { Done } from "@mui/icons-material"; + +export const StewardOutProvinceRegistrationCodeInput = ({ + item, + fetchApiData, +}) => { + const dispatch = useDispatch(); + const [openNotif] = useContext(AppContext); + const [registrationCode, setRegistrationCode] = useState( + item?.loggedRegistrationCode || "" + ); + + const handleSubmit = () => { + dispatch( + guildEditOutOfProvinceService({ + key: item?.key, + register_code: parseInt(registrationCode), + role: getRoleFromUrl(), + // Include all required fields from item + date: item?.date, + buyer_name: item?.buyerName, + buyer_mobile: item?.buyerMobile, + province: item?.province, + city: item?.city, + clearance_code: item?.clearanceCode, + number_of_carcasses: item?.numberOfCarcasses, + quarantine_weight_of_carcasses: item?.quarantineWeightOfCarcasses, + weight_of_carcasses: item?.weightOfCarcasses, + ...(item?.buyer?.key && { buyer_key: item?.buyer?.key }), + }) + ).then((r) => { + if (r.payload.error) { + openNotif({ + vertical: "top", + horizontal: "center", + msg: r.payload.error, + severity: "error", + }); + } else { + openNotif({ + vertical: "top", + horizontal: "center", + msg: "کد احراز با موفقیت ثبت شد.", + severity: "success", + }); + fetchApiData(); + } + }); + }; + + return ( + + setRegistrationCode(e.target.value)} + style={{ minWidth: "150px" }} + disabled={item?.loggedRegistrationCode} + placeholder="کد احراز" + inputProps={{ + inputMode: "numeric", + pattern: "[0-9]*", + }} + type="number" + /> + {!item?.loggedRegistrationCode && registrationCode && ( + + )} + + ); +}; diff --git a/src/features/steward/components/steward-out-province-sales-operations/StewardOutProvinceSalesOperations.js b/src/features/steward/components/steward-out-province-sales-operations/StewardOutProvinceSalesOperations.js new file mode 100644 index 0000000..edae501 --- /dev/null +++ b/src/features/steward/components/steward-out-province-sales-operations/StewardOutProvinceSalesOperations.js @@ -0,0 +1,177 @@ +import React, { useContext, useState } from "react"; +import { Button, IconButton, Popover, Tooltip } from "@mui/material"; +import { useDispatch } from "react-redux"; +import { Grid } from "../../../../components/grid/Grid"; +import { AppContext } from "../../../../contexts/AppContext"; +import { DRAWER } from "../../../../lib/redux/slices/appSlice"; +import { stewardDeleteOutSellService } from "../../../guild/services/steward-sell-out-delete-service"; +import { StewardSellOutOfProvinceEditSell } from "../steward-purchase-out-province-edit-sell/StewardSellOutOfProvinceEditSell"; +import { fetchStewardBroadcastAndProducts } from "../../services/handle-fetch-steward-products"; +import { stewardResendOutProvinceRegistrationCodeService } from "../../services/steward-resend-out-province-registration-code"; +import TuneIcon from "@mui/icons-material/Tune"; +import EditIcon from "@mui/icons-material/Edit"; +import DeleteIcon from "@mui/icons-material/Delete"; +import SendIcon from "@mui/icons-material/Send"; + +export const StewardOutProvinceSalesOperations = ({ + item, + updateTable, + fetchApiData, + page, +}) => { + const dispatch = useDispatch(); + const [openNotif] = useContext(AppContext); + const [popoverOpen, setPopoverOpen] = useState(false); + const [anchorEl, setAnchorEl] = useState(null); + + const openPopover = (event) => { + setPopoverOpen(true); + setAnchorEl(event.currentTarget); + }; + + const closePopover = () => { + setPopoverOpen(false); + setAnchorEl(null); + }; + + const handleEdit = () => { + closePopover(); + dispatch( + DRAWER({ + right: !(window.innerWidth <= 600), + bottom: window.innerWidth <= 600, + title: "ویرایش فروش خارج از استان", + content: ( + + ), + }) + ); + }; + + const handleDelete = () => { + closePopover(); + dispatch(stewardDeleteOutSellService(item?.key)).then((r) => { + if (r.payload.error) { + openNotif({ + vertical: "top", + horizontal: "center", + msg: r.payload.data.result, + severity: "error", + }); + } else { + updateTable(); + dispatch(fetchStewardBroadcastAndProducts()); + openNotif({ + vertical: "top", + horizontal: "center", + msg: r.payload.data.result, + severity: "success", + }); + } + }); + }; + + const handleResend = () => { + closePopover(); + dispatch( + stewardResendOutProvinceRegistrationCodeService({ + key: item?.key, + }) + ).then((r) => { + if (r.payload.error) { + openNotif({ + vertical: "top", + horizontal: "center", + msg: r.payload.error, + severity: "error", + }); + } else { + openNotif({ + vertical: "top", + horizontal: "center", + msg: "کد با موفقیت ارسال شد.", + severity: "success", + }); + fetchApiData(page); + } + }); + }; + + const open = Boolean(anchorEl); + const id = open ? "popover" : undefined; + + return ( +
    + + + + +
    + + + + + + + + + + {item?.systemRegistrationCode && + item?.registrationCode && + !item?.loggedRegistrationCode && ( + + + + )} + +
    +
    +
    + ); +}; diff --git a/src/features/steward/components/steward-purchase-out-province-add-buyer/StewardSellOutOfProvinceAddBuyer.js b/src/features/steward/components/steward-purchase-out-province-add-buyer/StewardSellOutOfProvinceAddBuyer.js new file mode 100644 index 0000000..304f9fe --- /dev/null +++ b/src/features/steward/components/steward-purchase-out-province-add-buyer/StewardSellOutOfProvinceAddBuyer.js @@ -0,0 +1,420 @@ +import { useFormik } from "formik"; +import { useContext, useEffect, useState } from "react"; +import { useDispatch, useSelector } from "react-redux"; +import { + Autocomplete, + Button, + IconButton, + TextField, + Typography, +} from "@mui/material"; +import SearchIcon from "@mui/icons-material/Search"; +import { Yup } from "../../../../lib/yup/yup"; +import { + slaughterGetCitiesService, + slaughterGetProvinceService, +} from "../../../slaughter-house/services/slaughter-get-provinces"; +import { Grid } from "../../../../components/grid/Grid"; +import { SPACING } from "../../../../data/spacing"; +import { + stewardSellOutGetBuyers, + stewatdSubmitBuyerDataService, +} from "../../../guild/services/steward-sell-out-get-buyers"; +import { DRAWER, LOADING_END } from "../../../../lib/redux/slices/appSlice"; +import { slaughterEditBuyerDataService } from "../../../slaughter-house/services/slaughter-house-submit-buyer"; +import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl"; +import { AppContext } from "../../../../contexts/AppContext"; +import { checkPathStartsWith } from "../../../../utils/checkPathStartsWith"; + +export const StewardSellOutOfProvinceAddBuyer = ({ + updateTable, + isEdit, + data, +}) => { + const [openNotif] = useContext(AppContext); + const [userData, setUserData] = useState(null); + const [notFound, setNotFound] = useState(false); + const dispatch = useDispatch(); + const [provinceData, setProvinceData] = useState([]); + const [cityData, setCityData] = useState([]); + const selectedSubUser = useSelector( + (state) => state.userSlice.selectedSubUser + ); + + const formik = useFormik({ + initialValues: { + mobile: "", + firstName: "", + lastName: "", + unitName: "", + province: "", + city: "", + }, + validationSchema: Yup.object({ + mobile: Yup.string() + .required("این فیلد اجباری است!") + .min(11, "شماره موبایل باید 11 رقم باشد") + .max(11, "شماره موبایل باید 11 رقم باشد") + .matches(/^09\d{9}$/, "شماره موبایل باید با 09 شروع شود و 11 رقم باشد"), + firstName: Yup.string() + .required("این فیلد اجباری است!") + .typeError("لطفا فیلد را به درستی وارد کنید!"), + lastName: Yup.string() + .required("این فیلد اجباری است!") + .typeError("لطفا فیلد را به درستی وارد کنید!"), + unitName: Yup.string() + .required("این فیلد اجباری است!") + .typeError("لطفا فیلد را به درستی وارد کنید!"), + province: Yup.string() + .required("این فیلد اجباری است!") + .typeError("لطفا فیلد را به درستی وارد کنید!"), + city: Yup.string() + .required("این فیلد اجباری است!") + .typeError("لطفا فیلد را به درستی وارد کنید!"), + }), + }); + + const formik2 = useFormik({ + initialValues: { + userInfoCheck: "", + }, + validationSchema: Yup.object({ + userInfoCheck: Yup.string() + .required("این فیلد اجباری است!") + .min(11, "شماره موبایل باید 11 رقم باشد") + .max(11, "شماره موبایل باید 11 رقم باشد") + .matches(/^09\d{9}$/, "شماره موبایل باید با 09 شروع شود و 11 رقم باشد"), + }), + validateOnMount: true, + }); + + useEffect(() => { + formik.validateForm(); + }, []); + + useEffect(() => { + if (userData) { + formik.setValues({ + mobile: userData.mobile || "", + firstName: userData.firstName || "", + lastName: userData.lastName || "", + unitName: userData.unitName || "", + province: userData.province || "", + city: userData.city || "", + }); + setTimeout(() => { + formik.validateForm(); + }, 1); + } + }, [userData]); + + useEffect(() => { + if (isEdit) { + formik.setValues({ + mobile: data.mobile || "", + firstName: data.firstName || "", + lastName: data.lastName || "", + unitName: data.unitName || "", + province: data.province || "", + city: data.city || "", + }); + setTimeout(() => { + formik.validateForm(); + }, 1); + } + }, [isEdit]); + + useEffect(() => { + if (notFound) { + formik.setFieldValue("mobile", formik2.values.userInfoCheck); + } + }, [notFound]); + + useEffect(() => { + dispatch(slaughterGetProvinceService()).then((r) => { + setProvinceData(r.payload.data); + }); + }, []); + + useEffect(() => { + if (formik.values.province) { + setCityData( + [], + dispatch(slaughterGetCitiesService(formik.values.province)).then( + (r) => { + setCityData(r.payload.data); + } + ) + ); + } + }, [formik.values.province]); + + return ( + + {!userData && !isEdit ? ( + + جستجو کاربر + + { + formik2.handleChange(e); + // Reset notFound when user starts typing + if (notFound) { + setNotFound(false); + } + }} + onBlur={formik2.handleBlur} + helperText={ + formik2.touched.userInfoCheck && formik2.errors.userInfoCheck + } + /> + { + dispatch( + stewardSellOutGetBuyers({ + mobile: formik2.values.userInfoCheck, + role_key: checkPathStartsWith("steward") + ? selectedSubUser?.key || "" + : "", + }) + ).then((r) => { + dispatch(LOADING_END()); + if (r.error) { + setNotFound(true); + setUserData(null); + openNotif({ + vertical: "top", + horizontal: "center", + msg: "خریدار یافت نشد، یک خریدار جدید ثبت کنید!", + severity: "error", + }); + } else { + const responseData = r.payload?.data; + // Check if response is an empty array + if ( + Array.isArray(responseData) && + responseData.length === 0 + ) { + setNotFound(true); + setUserData(null); + } else { + setNotFound(false); + setUserData(responseData); + } + } + }); + }} + > + + + + {notFound && ( + + + خریداری یافت نشد + + + )} + + ) : ( + + + + + + + ({ id: i.name, label: i.name })) + : [] + } + onChange={(e, value) => { + formik.setFieldValue("province", value ? value.id : ""); + formik.setFieldValue("city", ""); + }} + renderInput={(params) => ( + + )} + /> + {!notFound && ( + + استان: {formik.values.province} + + )} + + ({ id: i.name, label: i.name })) + : [] + } + onChange={(e, value) => { + formik.setFieldValue("city", value ? value.id : ""); + }} + renderInput={(params) => ( + + )} + /> + + {!notFound && ( + + شهر: {formik.values.city} + + )} + + )} + + {(userData || isEdit) && ( + + + + )} + + ); +}; diff --git a/src/features/steward/components/steward-purchase-out-province-edit-sell/StewardSellOutOfProvinceEditSell.js b/src/features/steward/components/steward-purchase-out-province-edit-sell/StewardSellOutOfProvinceEditSell.js new file mode 100644 index 0000000..dc0752b --- /dev/null +++ b/src/features/steward/components/steward-purchase-out-province-edit-sell/StewardSellOutOfProvinceEditSell.js @@ -0,0 +1,184 @@ +import { useDispatch } from "react-redux"; +import { useContext } from "react"; +import moment from "moment"; +import { Field, Form, Formik } from "formik"; +import { DatePicker } from "@mui/x-date-pickers"; +import { Button, TextField } from "@mui/material"; +import { Yup } from "../../../../lib/yup/yup"; +import { AppContext } from "../../../../contexts/AppContext"; +import { Grid } from "../../../../components/grid/Grid"; +import { guildEditOutOfProvinceService } from "../../../slaughter-house/services/slaughterEditOutOfProvinceService"; +import { + guildSubmitOutOfProvinceService, + slaughterSubmitOutOfProvinceService, +} from "../../../slaughter-house/services/slaughter-submit-out-province-service"; +import { stewardEditBuyerDataService } from "../../../guild/services/steward-edit-sell-out-buyer"; +import { guildGetInventoryStockService } from "../../../guild/services/guild-get-inventory-stock"; +import { guildGetFreeSaleBarService } from "../../../guild/services/guild-get-free-sale-bar"; +import { DRAWER } from "../../../../lib/redux/slices/appSlice"; +import { fetchStewardBroadcastAndProducts } from "../../services/handle-fetch-steward-products"; + +const validationSchema = Yup.object().shape({ + quarantineCode: Yup.string().required("کد قرنطینه الزامی است"), + carcassCount: Yup.number().required("حجم لاشه الزامی است"), + carcassWeight: Yup.number().required("وزن لاشه الزامی است"), + date: Yup.string().required("تاریخ الزامی است"), +}); + +export const StewardSellOutOfProvinceEditSell = ({ + fetchItems, + isEdit, + item, + selectedDate, + stewardKey, +}) => { + const dispatch = useDispatch(); + const [openNotif] = useContext(AppContext); + + const initialValues = { + quarantineCode: item?.clearanceCode || "", + carcassCount: item?.numberOfCarcasses || "0", + carcassWeight: item?.weightOfCarcasses || "", + date: item?.date || moment().format("YYYY-MM-DD HH:mm:ss"), + }; + + return ( + + { + const payload = { + ...values, + date: values.date, + number_of_carcasses: values.carcassCount, + weight_of_carcasses: values.carcassWeight, + }; + + if (values.quarantineCode !== item?.quarantineCode) { + payload.quarantineCode = values.quarantineCode; + } + + const service = stewardKey + ? isEdit + ? guildEditOutOfProvinceService({ key: item?.key, ...payload }) + : guildSubmitOutOfProvinceService({ + steward_key: stewardKey, + ...payload, + }) + : isEdit + ? stewardEditBuyerDataService({ + key: item?.key, + driver_mobile: values.driverPhone, + ...payload, + }) + : slaughterSubmitOutOfProvinceService({ + driver_mobile: values.driverPhone, + ...payload, + }); + + dispatch(service).then((r) => { + if (r.payload.error) { + openNotif({ + vertical: "top", + horizontal: "center", + msg: r.payload.error, + severity: "error", + }); + } else { + stewardKey + ? dispatch(guildGetInventoryStockService({ date: values.date })) + : fetchItems(); + + stewardKey && + dispatch( + guildGetFreeSaleBarService({ + date: values.date, + steward_key: stewardKey, + }) + ); + + dispatch(fetchStewardBroadcastAndProducts()); + dispatch(DRAWER({ right: false, bottom: false, content: null })); + openNotif({ + vertical: "top", + horizontal: "center", + msg: "عملیات با موفقیت انجام شد.", + severity: "success", + }); + } + }); + }} + > + {({ errors, touched, setFieldValue, values }) => ( +
    + + + + + + + + + { + const formatted = moment(val).format("YYYY-MM-DD HH:mm:ss"); + setFieldValue("date", formatted); + }} + renderInput={(params) => ( + + )} + /> + + + + + + + + +
    + )} +
    +
    + ); +}; diff --git a/src/features/steward/components/steward-purchase-out-province-submit-sell/StewardSellOutOfProvinceSubmitSell.js b/src/features/steward/components/steward-purchase-out-province-submit-sell/StewardSellOutOfProvinceSubmitSell.js new file mode 100644 index 0000000..17c57bc --- /dev/null +++ b/src/features/steward/components/steward-purchase-out-province-submit-sell/StewardSellOutOfProvinceSubmitSell.js @@ -0,0 +1,546 @@ +import { useContext, useEffect, useState, useCallback, useRef } from "react"; +import { useDispatch, useSelector } from "react-redux"; +import { + Autocomplete, + Button, + FormControl, + FormControlLabel, + Radio, + RadioGroup, + TextField, +} from "@mui/material"; +import { Field, Form, Formik } from "formik"; +import moment from "moment"; +import { DatePicker } from "@mui/x-date-pickers"; +import { Yup } from "../../../../lib/yup/yup"; +import { stewardSellOutGetBuyers } from "../../../guild/services/steward-sell-out-get-buyers"; +import { AppContext } from "../../../../contexts/AppContext"; +import { stewardGetOutSellService } from "../../../guild/services/steward-get-sell-out-service"; +import { SPACING } from "../../../../data/spacing"; +import { Grid } from "../../../../components/grid/Grid"; +import { stewardSellOuutSubmitSell } from "../../../guild/services/steward-sell-out-submit-sell"; +import { DRAWER } from "../../../../lib/redux/slices/appSlice"; +import { fetchStewardBroadcastAndProducts } from "../../services/handle-fetch-steward-products"; +import MonthlyDataCalendar from "../../../../components/date-picker/MonthlyDataCalendar"; +import PersianDate from "persian-date"; +import axios from "axios"; +import { LabelField } from "../../../../components/label-field/LabelField"; +import { checkPathStartsWith } from "../../../../utils/checkPathStartsWith"; + +const validationSchema = (selectedDateAmount) => + Yup.object({ + weight_of_carcasses: Yup.number() + .required("وزن لاشه‌ها الزامی است") + .positive("وزن باید عددی مثبت باشد") + .test( + "max-production-date-amount", + `وزن نمی‌تواند بیشتر از موجودی تاریخ تولید (${ + selectedDateAmount?.toLocaleString() || 0 + } کیلوگرم) باشد!`, + function (value) { + if (!selectedDateAmount || selectedDateAmount === null) return true; + return value <= selectedDateAmount; + } + ), + + clearance_code: Yup.string() + .required("کد قرنطینه الزامی است") + .matches( + /^(?=.*[A-Z])(?=.*\d)[A-Z0-9]+$/, + "کد قرنطینه باید ترکیبی از حروف بزرگ انگلیسی و عدد باشد" + ), + date: Yup.date().required("تاریخ الزامی است"), + production_date: Yup.string().required("تاریخ تولید الزامی است"), + }); + +export const StewardSellOutOfProvinceSubmitSell = ({ + updateTable, + fetchItems, + isInventory, +}) => { + const [productData, setProductData] = useState([]); + const [productKey, setProductKey] = useState(null); + const [buterData, setBuyerData] = useState([]); + const [buyerSelected, setBuyerSelected] = useState(null); + const [selectedInventory] = useState("free"); + const [approvedStatus, setApprovedStatus] = useState("governmental"); + const [selectedCalendarDate, setSelectedCalendarDate] = useState(null); + const [calendarDayData, setCalendarDayData] = useState({}); + const [productionDate, setProductionDate] = useState(null); + const [selectedDateAmount, setSelectedDateAmount] = useState(null); + const [calendarDateError, setCalendarDateError] = useState(null); + const formikRef = useRef(null); + const dispatch = useDispatch(); + const selectedSubUser = useSelector( + (state) => state.userSlice.selectedSubUser + ); + + const [openNotif] = useContext(AppContext); + + const handleDateSelect = (dateInfo) => { + if (dateInfo && dateInfo.formattedDate) { + setSelectedCalendarDate(dateInfo.formattedDate); + + // Get the data for the selected date + const data = calendarDayData[dateInfo.formattedDate]; + + // Use the original Gregorian date from the API data for production_date + if (data && data.originalDay) { + // Prevent choosing a production date after the main form date + if ( + formikRef.current?.values?.date && + moment(data.originalDay).isAfter( + moment(formikRef.current.values.date), + "day" + ) + ) { + setCalendarDateError( + "تاریخ تولید نمی‌تواند بعد از تاریخ انتخابی باشد" + ); + return; + } + setCalendarDateError(null); + setProductionDate(data.originalDay); + if (formikRef.current) { + formikRef.current.setFieldValue("production_date", data.originalDay); + } + } + + // Get the amount for the selected date + if (data && data.value1 !== undefined) { + setSelectedDateAmount(data.value1); + } else { + setSelectedDateAmount(null); + } + } + }; + + const transformCalendarData = useCallback((dataArray) => { + if (!Array.isArray(dataArray)) return {}; + + const transformedData = {}; + dataArray.forEach((item) => { + // Include all items to show amounts, but store active status + if (item.day && item.amount !== undefined) { + const persianDate = new PersianDate(new Date(item.day)); + const persianDateStr = persianDate.format("YYYY/MM/DD"); + transformedData[persianDateStr] = { + value1: item.amount, + originalDay: item.day, + active: item.active === true, // Store active status + }; + } + }); + return transformedData; + }, []); + + const updateCalendarData = useCallback( + (dataArray) => { + const transformed = transformCalendarData(dataArray); + setCalendarDayData(transformed); + }, + [transformCalendarData] + ); + + const [selectedFormDate, setSelectedFormDate] = useState( + moment(new Date()).format("YYYY-MM-DD") + ); + + const fetchCalendarData = useCallback( + async (dateParam = selectedFormDate) => { + try { + const response = await axios.get("/steward-remain-weight/", { + params: { + date: dateParam, + role_key: checkPathStartsWith("steward") + ? selectedSubUser?.key + : "", + }, + }); + if (response.data) { + const dataToShow = + approvedStatus === "governmental" + ? response.data.governmental + : response.data.free; + updateCalendarData(dataToShow || []); + } + } catch (error) { + console.error("Error fetching calendar data:", error); + } + }, + [approvedStatus, updateCalendarData, selectedFormDate, selectedSubUser] + ); + + useEffect(() => { + dispatch( + stewardSellOutGetBuyers({ + role_key: checkPathStartsWith("steward") ? selectedSubUser?.key : "", + }) + ).then((r) => { + setBuyerData(r.payload.data); + }); + }, [selectedSubUser?.key]); + + useEffect(() => { + dispatch( + stewardGetOutSellService({ + role_key: checkPathStartsWith("steward") ? selectedSubUser?.key : "", + }) + ).then((r) => { + const data = r.payload?.data; + if (Array.isArray(data)) { + setProductData(data); + } else if (data?.data && Array.isArray(data.data)) { + setProductData(data.data); + } else { + setProductData([]); + } + }); + }, [dispatch, selectedSubUser?.key]); + + useEffect(() => { + fetchCalendarData(selectedFormDate); + }, [selectedFormDate, fetchCalendarData]); + + useEffect(() => { + let dateToUse = selectedFormDate; + if (approvedStatus === "governmental" && formikRef.current) { + const today = moment(new Date()).format("YYYY-MM-DD"); + formikRef.current.setFieldValue("date", today); + setSelectedFormDate(today); + dateToUse = today; + } + + fetchCalendarData(dateToUse); + setSelectedCalendarDate(null); + setProductionDate(null); + setSelectedDateAmount(null); + if (formikRef.current) { + formikRef.current.setFieldValue("production_date", ""); + } + }, [ + approvedStatus, + selectedFormDate, + fetchCalendarData, + selectedSubUser?.key, + ]); + + useEffect(() => { + if (formikRef.current) { + formikRef.current.validateForm(); + } + }, [selectedDateAmount]); + + // const handleSellType = (event) => { + // const newType = event.target.value; + // setSelectedInventory(newType); + // }; + + const handleApprovedPrice = (event) => { + const newType = event.target.value; + setApprovedStatus(newType); + + if (newType === "governmental" && formikRef.current) { + const today = moment(new Date()).format("YYYY-MM-DD"); + formikRef.current.setFieldValue("date", today); + setSelectedFormDate(today); + fetchCalendarData(today); + } + }; + + return ( + + + + option.disabled} + options={ + buterData + ? buterData.map((i) => ({ + id: i?.key, + label: `${i?.fullname} (${i.mobile}) / استان ${i.province} / شهر ${i.city}`, + item: i, + })) + : [] + } + onChange={(event, value) => { + setBuyerSelected(value?.id); + }} + renderInput={(params) => ( + + )} + /> + + + {buyerSelected && ( + <> + + 0 + ? productData.map((i) => { + return { + data: i, + label: `${i.name || ""}`, + }; + }) + : [] + } + onChange={(event, value) => { + setProductKey(value?.data || null); + }} + renderInput={(params) => ( + + )} + /> + + + { + dispatch( + stewardSellOuutSubmitSell({ + buyer_key: buyerSelected, + number_of_carcasses: + Math.round( + values?.weight_of_carcasses / productKey?.weightAverage + ) || 0, + weight_of_carcasses: parseInt(values.weight_of_carcasses), + date: values.date, + clearance_code: values.clearance_code, + product_key: productKey?.key, + sale_type: selectedInventory, + quota: approvedStatus, + production_date: values.production_date, + distribution_type: "web", + }) + ).then((r) => { + if (r.payload.error) { + openNotif({ + vertical: "top", + horizontal: "center", + msg: r.payload.error, + severity: "error", + }); + } else { + if (isInventory) { + fetchItems(); + } else { + updateTable(); + } + dispatch(fetchStewardBroadcastAndProducts()); + dispatch( + DRAWER({ right: false, bottom: false, content: null }) + ); + openNotif({ + vertical: "top", + horizontal: "center", + msg: "عملیات با موفقیت انجام شد.", + severity: "success", + }); + } + }); + }} + > + {({ values, errors, touched, setFieldValue }) => ( +
    + + + + + + + + } + label="انبار دولتی" + /> + } + label="انبار آزاد" + /> + + + + + { + const formatted = + moment(newValue).format("YYYY-MM-DD"); + setFieldValue("date", formatted); + setSelectedFormDate(formatted); + fetchCalendarData(formatted); + }} + renderInput={(params) => ( + + )} + /> + + + + setFieldValue( + "clearance_code", + e.target.value.toUpperCase() + ) + } + error={ + touched.clearance_code && + Boolean(errors.clearance_code) + } + helperText={ + touched.clearance_code && errors.clearance_code + } + /> + + + {/* + + + } + label="قیمت دولتی" + /> + } + label="قیمت آزاد" + /> + + + */} + + + + {calendarDateError && ( + + )} + + + + + + + + + +
    + )} +
    + + )} +
    +
    + ); +}; diff --git a/src/features/steward/components/steward-purchase-out-province/StewardPurchaseOutProvince.js b/src/features/steward/components/steward-purchase-out-province/StewardPurchaseOutProvince.js new file mode 100644 index 0000000..1d40092 --- /dev/null +++ b/src/features/steward/components/steward-purchase-out-province/StewardPurchaseOutProvince.js @@ -0,0 +1,293 @@ +import { useContext, useEffect, useState } from "react"; +import { useDispatch, useSelector } from "react-redux"; +import axios from "axios"; +import { Button, TextField, Tooltip } from "@mui/material"; +import { RiFileExcel2Fill, RiSearchLine } from "react-icons/ri"; +import { DatePicker } from "@mui/x-date-pickers"; +import { AppContext } from "../../../../contexts/AppContext"; +import { stawardGetOutDashboardService } from "../../../guild/services/steward-get-out-dashboard"; +import moment from "moment"; +import { + DRAWER, + LOADING_END, + LOADING_START, +} from "../../../../lib/redux/slices/appSlice"; +import { formatJustDate } from "../../../../utils/formatTime"; +import ShowImage from "../../../../components/show-image/ShowImage"; +import { Grid } from "../../../../components/grid/Grid"; +import { SPACING } from "../../../../data/spacing"; +import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl"; +import ResponsiveTable from "../../../../components/responsive-table/ResponsiveTable"; +import { StewardSellOutOperations } from "../steward-buy-out-operations/StewardSellOutOperations"; +import { StewardSubmitFreeBar } from "../steward-submit-free-bar/StewardSubmitFreeBar"; +import { checkPathStartsWith } from "../../../../utils/checkPathStartsWith"; + +export const StewardPurchaseOutProvince = ({ isBarManagemen }) => { + const [data, setData] = useState([]); + + const [tableData, setTableData] = useState([]); + + const [totalRows, setTotalRows] = useState(0); + const [perPage, setPerPage] = useState(10); + const [textValue, setTextValue] = useState(""); + const [page, setPage] = useState(1); + const [dashboardData, setDashboardData] = useState([]); + const [, , selectedDate1, setSelectedDate1, selectedDate2, setSelectedDate2] = + useContext(AppContext); + // const [openNotif] = useContext(AppContext); + const dispatch = useDispatch(); + const selectedSubUser = useSelector( + (state) => state.userSlice.selectedSubUser + ); + + const userKey = useSelector((state) => state.userSlice.userProfile.key); + + const getDashboardData = () => { + dispatch( + stawardGetOutDashboardService({ + date1: selectedDate1, + date2: selectedDate2, + search: "filter", + role_key: checkPathStartsWith("steward") + ? selectedSubUser?.key || "" + : "", + }) + ).then((r) => { + setDashboardData(r.payload.data); + }); + }; + + const fetchApiData = async (page) => { + dispatch(LOADING_START()); + const response = await axios.get( + `steward_free_bar/?search=filter&value=${textValue}&date1=${selectedDate1}&date2=${selectedDate2}&page=${page}&page_size=${perPage}&role=${getRoleFromUrl()}${ + checkPathStartsWith("steward") + ? `&role_key=${selectedSubUser?.key}` + : "" + }` + ); + + getDashboardData(); + dispatch(LOADING_END()); + setData(response.data.results); + setTotalRows(response.data.count); + }; + + // Initialize dates on mount + useEffect(() => { + const currentDate = moment(new Date()).format("YYYY-MM-DD"); + setSelectedDate1(currentDate); + setSelectedDate2(currentDate); + }, []); + + // Fetch data when dates or perPage change (only if dates are set) + useEffect(() => { + if (selectedDate1 && selectedDate2) { + fetchApiData(1); + setPage(1); + } + }, [selectedDate1, selectedDate2, perPage]); + + const handlePageChange = (page) => { + fetchApiData(page); + setPage(page); + }; + const updateTable = () => { + setPage(1); + getDashboardData(); + fetchApiData(1); + }; + + const handlePerRowsChange = (perRows) => { + setPerPage(perRows); + setPage(1); + }; + + const handleTextChange = (event) => { + setTextValue(event.target.value); + }; + + useEffect(() => { + const d = data?.map((item, i) => { + return [ + page === 1 ? i + 1 : i + perPage * (page - 1) + 1, + formatJustDate(item.createDate), + `${item?.killHouseName} (${item?.killHouseMobile})`, + item?.product?.name?.toLocaleString() || "-", + item?.killHouseName?.toLocaleString(), + `${item?.city} (${item?.province})`, + item?.numberOfCarcasses?.toLocaleString() || "-", + item?.weightOfCarcasses?.toLocaleString() || "-", + , + + , + ]; + }); + + setTableData(d); + }, [data, page, perPage]); + + const handleSubmit = async (event) => { + event.preventDefault(); + dispatch(LOADING_START()); + try { + const response = await axios.get( + `steward_free_bar/?search=filter&value=${textValue}&date1=${selectedDate1}&date2=${selectedDate2}&page=${page}&role=${getRoleFromUrl()}${ + checkPathStartsWith("steward") + ? `&role_key=${selectedSubUser?.key}` + : "" + }` + ); + setData(response.data.results); + setTotalRows(response.data.count); + getDashboardData(); + dispatch(LOADING_END()); + } catch (error) { + console.error("Error fetching data:", error); + } + }; + + return ( + + +
    + + {getRoleFromUrl() === "Steward" && !isBarManagemen && ( + + )} + + + + + ( + + )} + value={selectedDate1} + onChange={(e) => + setSelectedDate1(moment(e).format("YYYY-MM-DD")) + } + /> + + + ( + + )} + value={selectedDate2} + onChange={(e) => + setSelectedDate2(moment(e).format("YYYY-MM-DD")) + } + /> + + + + + +
    + + + + + + +
    +
    + ); +}; diff --git a/src/features/steward/components/steward-sell-in-province/StewardSellInProvince.js b/src/features/steward/components/steward-sell-in-province/StewardSellInProvince.js new file mode 100644 index 0000000..da10439 --- /dev/null +++ b/src/features/steward/components/steward-sell-in-province/StewardSellInProvince.js @@ -0,0 +1,109 @@ +import React, { useEffect, useRef, useCallback } from "react"; +import { useDispatch, useSelector } from "react-redux"; +import { Button } from "@mui/material"; +import { useNavigate } from "react-router-dom"; +import { getKillhouseApprovedPriceState } from "../../../province/services/get-approved-price-state"; +import { Grid } from "../../../../components/grid/Grid"; +import { StewardShowProducts } from "../steward-show-products/StewardShowProducts"; +import { DRAWER } from "../../../../lib/redux/slices/appSlice"; +import { StewardAllocationToGuild } from "../../../guild/components/StewardAllocationToGuild"; +import { ROUTE_STEWARD_DAILY_LIST } from "../../../../routes/routes"; +import { StewardShowAllocations } from "../steward-show-allocations/StewardShowAllocations"; +import { checkPathStartsWith } from "../../../../utils/checkPathStartsWith"; + +export const StewardSellInProvince = () => { + const dispatch = useDispatch(); + const allocationsRef = useRef(null); + const selectedSubUser = useSelector( + (state) => state.userSlice.selectedSubUser + ); + const { stewardProducts } = useSelector((state) => state.stewardSlice); + + const navigate = useNavigate(); + + const { priceInfo } = useSelector((state) => state.slaughterSlice); + + const fetchData = useCallback(async () => { + dispatch( + getKillhouseApprovedPriceState({ + role_key: checkPathStartsWith("steward") + ? selectedSubUser?.key || "" + : "", + }) + ); + + if (allocationsRef.current?.updateTable) { + allocationsRef.current.updateTable(); + } + }, [dispatch, selectedSubUser?.key]); + + useEffect(() => { + fetchData(); + }, [selectedSubUser?.key]); + + return ( + + + + + + + + + + + + + + + + ); +}; diff --git a/src/features/steward/components/steward-sell-out-of-province-buyers-edit-buyer/StewardSellOutOfProvinceBuyersEditBuyer.js b/src/features/steward/components/steward-sell-out-of-province-buyers-edit-buyer/StewardSellOutOfProvinceBuyersEditBuyer.js new file mode 100644 index 0000000..06c5705 --- /dev/null +++ b/src/features/steward/components/steward-sell-out-of-province-buyers-edit-buyer/StewardSellOutOfProvinceBuyersEditBuyer.js @@ -0,0 +1,387 @@ +import { useContext, useEffect, useState } from "react"; +import { useDispatch } from "react-redux"; +import { useFormik } from "formik"; +import { + Autocomplete, + Button, + IconButton, + TextField, + Typography, +} from "@mui/material"; +import SearchIcon from "@mui/icons-material/Search"; +import { AppContext } from "../../../../contexts/AppContext"; +import { Yup } from "../../../../lib/yup/yup"; +import { + slaughterGetCitiesService, + slaughterGetProvinceService, +} from "../../../slaughter-house/services/slaughter-get-provinces"; +import { Grid } from "../../../../components/grid/Grid"; +import { SPACING } from "../../../../data/spacing"; +import { + slaughterEditBuyerDataService, + slaughterGetBuyerDataService, + slaughterSubmitBuyerDataService, +} from "../../../slaughter-house/services/slaughter-house-submit-buyer"; +import { DRAWER, LOADING_END } from "../../../../lib/redux/slices/appSlice"; +import { fetchStewardBroadcastAndProducts } from "../../services/handle-fetch-steward-products"; + +export const StewardSellOutOfProvinceBuyersEditBuyer = ({ + updateTable, + isEdit, + data, +}) => { + const [openNotif] = useContext(AppContext); + const [userData, setUserData] = useState(null); + const [notFound, setNotFound] = useState(false); + const dispatch = useDispatch(); + const [provinceData, setProvinceData] = useState([]); + const [cityData, setCityData] = useState([]); + + const formik = useFormik({ + initialValues: { + mobile: "", + firstName: "", + lastName: "", + unitName: "", + province: "", + city: "", + }, + validationSchema: Yup.object({ + mobile: Yup.string() + .required("این فیلد اجباری است!") + .min(11, "شماره موبایل باید 11 رقم باشد") + .max(11, "شماره موبایل باید 11 رقم باشد") + .matches(/^09\d{9}$/, "شماره موبایل باید با 09 شروع شود و 11 رقم باشد"), + firstName: Yup.string() + .required("این فیلد اجباری است!") + .typeError("لطفا فیلد را به درستی وارد کنید!"), + lastName: Yup.string() + .required("این فیلد اجباری است!") + .typeError("لطفا فیلد را به درستی وارد کنید!"), + unitName: Yup.string() + .required("این فیلد اجباری است!") + .typeError("لطفا فیلد را به درستی وارد کنید!"), + province: Yup.string() + .required("این فیلد اجباری است!") + .typeError("لطفا فیلد را به درستی وارد کنید!"), + city: Yup.string() + .required("این فیلد اجباری است!") + .typeError("لطفا فیلد را به درستی وارد کنید!"), + }), + }); + + const formik2 = useFormik({ + initialValues: { + userInfoCheck: "", + }, + validationSchema: Yup.object({ + userInfoCheck: Yup.string() + .required("این فیلد اجباری است!") + .min(11, "شماره موبایل باید 11 رقم باشد") + .max(11, "شماره موبایل باید 11 رقم باشد") + .matches(/^09\d{9}$/, "شماره موبایل باید با 09 شروع شود و 11 رقم باشد"), + }), + validateOnMount: true, + }); + + useEffect(() => { + formik.validateForm(); + }, []); + + useEffect(() => { + if (userData) { + formik.setValues({ + mobile: userData.mobile || "", + firstName: userData.firstName || "", + lastName: userData.lastName || "", + unitName: userData.unitName || "", + province: userData.province || "", + city: userData.city || "", + }); + setTimeout(() => { + formik.validateForm(); + }, 1); + } + }, [userData]); + + useEffect(() => { + if (isEdit) { + formik.setValues({ + mobile: data.mobile || "", + firstName: data.firstName || "", + lastName: data.lastName || "", + unitName: data.unitName || "", + province: data.province || "", + city: data.city || "", + }); + setTimeout(() => { + formik.validateForm(); + }, 1); + } + }, [isEdit]); + + useEffect(() => { + if (notFound) { + formik.setFieldValue("mobile", formik2.values.userInfoCheck); + } + }, [notFound]); + + useEffect(() => { + dispatch(slaughterGetProvinceService()).then((r) => { + setProvinceData(r.payload.data); + }); + }, []); + + useEffect(() => { + if (formik.values.province) { + setCityData( + [], + dispatch(slaughterGetCitiesService(formik.values.province)).then( + (r) => { + setCityData(r.payload.data); + } + ) + ); + } + }, [formik.values.province]); + + return ( + + {!userData && !notFound && !isEdit ? ( + + جستجو کاربر + + + { + dispatch( + slaughterGetBuyerDataService(formik2.values.userInfoCheck) + ).then((r) => { + dispatch(LOADING_END()); + if (r.error) { + setNotFound(true); + openNotif({ + vertical: "top", + horizontal: "center", + msg: "خریدار یافت نشد، یک خریدار جدید ثبت کنید!", + severity: "error", + }); + } else { + setUserData(r.payload.data); + } + }); + }} + > + + + + + ) : ( + + + + + + + ({ id: i.name, label: i.name })) + : [] + } + onChange={(e, value) => { + formik.setFieldValue("province", value ? value.id : ""); + formik.setFieldValue("city", ""); + }} + renderInput={(params) => ( + + )} + /> + {!notFound && ( + + استان: {formik.values.province} + + )} + + ({ id: i.name, label: i.name })) + : [] + } + onChange={(e, value) => { + formik.setFieldValue("city", value ? value.id : ""); + }} + renderInput={(params) => ( + + )} + /> + + {!notFound && ( + + شهر: {formik.values.city} + + )} + + )} + + {(userData || notFound || isEdit) && ( + + + + )} + + ); +}; diff --git a/src/features/steward/components/steward-sell-out-of-province-buyers/StewardSellOutOfProvinceBuyers.js b/src/features/steward/components/steward-sell-out-of-province-buyers/StewardSellOutOfProvinceBuyers.js new file mode 100644 index 0000000..6b06167 --- /dev/null +++ b/src/features/steward/components/steward-sell-out-of-province-buyers/StewardSellOutOfProvinceBuyers.js @@ -0,0 +1,197 @@ +import { useEffect, useState } from "react"; +import { useDispatch, useSelector } from "react-redux"; +import axios from "axios"; +import { Button, IconButton, TextField } from "@mui/material"; +import { RiSearchLine } from "react-icons/ri"; +// import DeleteIcon from "@mui/icons-material/Delete"; +import EditIcon from "@mui/icons-material/Edit"; +import { + DRAWER, + LOADING_END, + LOADING_START, +} from "../../../../lib/redux/slices/appSlice"; +import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl"; +import { Grid } from "../../../../components/grid/Grid"; +import ResponsiveTable from "../../../../components/responsive-table/ResponsiveTable"; +import { StewardSellOutOfProvinceAddBuyer } from "../steward-purchase-out-province-add-buyer/StewardSellOutOfProvinceAddBuyer"; +import { StewardSellOutOfProvinceBuyersEditBuyer } from "../steward-sell-out-of-province-buyers-edit-buyer/StewardSellOutOfProvinceBuyersEditBuyer"; +import { checkPathStartsWith } from "../../../../utils/checkPathStartsWith"; + +export const StewardSellOutOfProvinceBuyers = () => { + const handleTextChange = (event) => { + setTextValue(event.target.value); + }; + + const dispatch = useDispatch(); + + const [data, setData] = useState([]); + const [totalRows, setTotalRows] = useState(0); + const [perPage, setPerPage] = useState(10); + const [textValue, setTextValue] = useState(""); + const [page, setPage] = useState(1); + const [tableData, setTableData] = useState([]); + const selectedSubUser = useSelector( + (state) => state.userSlice.selectedSubUser + ); + + const fetchApiData = async (page) => { + dispatch(LOADING_START()); + const response = await axios.get( + `out-province-carcasses-buyer/?search=filter&value=${textValue}&role=${getRoleFromUrl()}${ + checkPathStartsWith("steward") + ? `&role_key=${selectedSubUser?.key}` + : "" + }&page=${page}&page_size=${perPage}&state=buyer-list` + ); + dispatch(LOADING_END()); + setData(response.data.results); + setTotalRows(response.data.count); + }; + + const handlePageChange = (page) => { + fetchApiData(page); + setPage(page); + }; + + const handlePerRowsChange = (perRows) => { + setPerPage(perRows); + setPage(1); + }; + + const updateTable = () => { + fetchApiData(page !== 0 ? page : 1); + }; + + useEffect(() => { + const d = data?.map((item, i) => { + return [ + page === 1 ? i + 1 : i + perPage * (page - 1) + 1, + `${item?.fullname} (${item?.mobile})`, + item?.unitName, + item?.province, + item?.city, + item?.requestsInfo?.numberOfRequests?.toLocaleString(), + item?.requestsInfo?.totalQuantity?.toLocaleString(), + item?.requestsInfo?.totalWeight?.toLocaleString(), + { + dispatch( + DRAWER({ + right: !(window.innerWidth <= 600), + bottom: window.innerWidth <= 600, + content: ( + + ), + title: "ویرایش خریدار", + }) + ); + }} + > + + , + ]; + }); + + setTableData(d); + }, [data]); + + useEffect(() => { + fetchApiData(1); + setPage(1); + }, [perPage]); + + const handleSubmit = async (event) => { + event.preventDefault(); + dispatch(LOADING_START()); + + try { + const response = await axios.get( + `out-province-carcasses-buyer/?role=${getRoleFromUrl()}${ + checkPathStartsWith("steward") ? selectedSubUser?.key || "" : "" + }&search=filter&value=${textValue}&page=${1}&page_size=${perPage}&state=buyer-list` + ); + setData(response.data.results); + setTotalRows(response.data.count); + dispatch(LOADING_END()); + } catch (error) { + console.error("Error fetching data:", error); + } + }; + + return ( + + + + +
    + + + +
    +
    + + +
    + ); +}; diff --git a/src/features/steward/components/steward-sell-out-of-province-sells/StewardSellOutOfProvinceSells.js b/src/features/steward/components/steward-sell-out-of-province-sells/StewardSellOutOfProvinceSells.js new file mode 100644 index 0000000..0055667 --- /dev/null +++ b/src/features/steward/components/steward-sell-out-of-province-sells/StewardSellOutOfProvinceSells.js @@ -0,0 +1,315 @@ +import { useContext, useEffect, useState } from "react"; +import { useDispatch, useSelector } from "react-redux"; +import moment from "moment"; +import axios from "axios"; +import { Button, TextField } from "@mui/material"; +import { DatePicker } from "@mui/x-date-pickers"; +import { RiSearchLine } from "react-icons/ri"; +import { AppContext } from "../../../../contexts/AppContext"; +import { + DRAWER, + LOADING_END, + LOADING_START, +} from "../../../../lib/redux/slices/appSlice"; +import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl"; +import { formatJustDate, formatTime } from "../../../../utils/formatTime"; +import { CheckCleanceCode } from "../../../../components/check-clearance-code/ChechClearanceCode"; +import { stewardSellOutGetDashboard } from "../../../guild/services/steward-sell-out-get-dashboard"; +import { Grid } from "../../../../components/grid/Grid"; +import ResponsiveTable from "../../../../components/responsive-table/ResponsiveTable"; +import { StewardSellOutOfProvinceSubmitSell } from "../steward-purchase-out-province-submit-sell/StewardSellOutOfProvinceSubmitSell"; +import { StewardOutProvinceRegistrationCodeInput } from "../steward-out-province-registration-code-input/StewardOutProvinceRegistrationCodeInput"; +import { StewardOutProvinceSalesOperations } from "../steward-out-province-sales-operations/StewardOutProvinceSalesOperations"; +import { checkPathStartsWith } from "../../../../utils/checkPathStartsWith"; + +export const StewardSellOutOfProvinceSells = () => { + const [, , selectedDate1, setSelectedDate1, selectedDate2, setSelectedDate2] = + useContext(AppContext); + const dispatch = useDispatch(); + const selectedSubUser = useSelector( + (state) => state.userSlice.selectedSubUser + ); + + const [data, setData] = useState([]); + const [totalRows, setTotalRows] = useState(0); + const [perPage, setPerPage] = useState(10); + const [textValue, setTextValue] = useState(""); + const [page, setPage] = useState(1); + const [tableData, setTableData] = useState([]); + const [dashboardData, setDashboardData] = useState([]); + + const fetchApiData = async (page) => { + dispatch(LOADING_START()); + const response = await axios.get( + `steward_free_sale_bar/?search=filter&value=${textValue}&role=${getRoleFromUrl()}${ + checkPathStartsWith("steward") + ? `&role_key=${selectedSubUser?.key}` + : "" + }&date1=${selectedDate1}&date2=${selectedDate2}&page=${page}&page_size=${perPage}` + ); + dispatch(LOADING_END()); + setData(response.data.results); + setTotalRows(response.data.count); + }; + + const getDashboardData = () => { + dispatch( + stewardSellOutGetDashboard({ + selectedDate1, + selectedDate2, + role_key: checkPathStartsWith("steward") ? selectedSubUser?.key : "", + }) + ).then((r) => { + setDashboardData(r.payload.data); + }); + }; + + useEffect(() => { + const currentDate = moment(new Date()).format("YYYY-MM-DD"); + setSelectedDate1(currentDate); + setSelectedDate2(currentDate); + }, []); + + useEffect(() => { + if (selectedDate1 && selectedDate2) { + fetchApiData(1); + setPage(1); + getDashboardData(); + } + }, [selectedDate1, selectedDate2, perPage]); + + const handleTextChange = (event) => { + setTextValue(event.target.value); + }; + + const handlePageChange = (page) => { + fetchApiData(page); + setPage(page); + }; + + const handlePerRowsChange = (perRows) => { + setPerPage(perRows); + setPage(1); + }; + + const updateTable = () => { + setPage(1); + fetchApiData(1); + getDashboardData(); + }; + + useEffect(() => { + const d = data?.map((item, i) => { + return [ + page === 1 ? i + 1 : i + perPage * (page - 1) + 1, + item?.date ? formatTime(item?.date) : "-", + item?.productionDate ? formatJustDate(item?.productionDate) : "-", + item?.distributionType === "web" + ? "سایت" + : item?.distributionType === "app" + ? "موبایل" + : item?.distributionType === "pos" + ? "پوز" + : item?.distributionType || "-", + `${item?.buyerName} (${item?.buyerMobile})`, + item?.buyer ? `${item?.buyer?.unitName}` : `${item?.buyerName}`, + item?.province, + item?.city, + // item?.numberOfCarcasses?.toLocaleString(), + item?.clearanceCode && ( + + ), + item?.quarantineWeightOfCarcasses?.toLocaleString(), + item?.weightOfCarcasses?.toLocaleString(), + item?.systemRegistrationCode ? ( + item?.loggedRegistrationCode ? ( + "تایید شده" + ) : item?.registrationCode ? ( + fetchApiData(page)} + /> + ) : ( + "-" + ) + ) : ( + "-" + ), + , + ]; + }); + + setTableData(d); + }, [data, page, perPage]); + + const handleSubmit = async (event) => { + event.preventDefault(); + dispatch(LOADING_START()); + + try { + const response = await axios.get( + `steward_free_sale_bar/?role=${getRoleFromUrl()}${ + checkPathStartsWith("steward") + ? `&role_key=${selectedSubUser?.key}` + : "" + }&search=filter&value=${textValue}&date1=${selectedDate1}&date2=${selectedDate2}&page=${1}&page_size=${perPage}` + ); + setData(response.data.results); + setTotalRows(response.data.count); + getDashboardData(); + dispatch(LOADING_END()); + } catch (error) { + console.error("Error fetching data:", error); + dispatch(LOADING_END()); + } + }; + + return ( + + + + ( + + )} + value={selectedDate1} + onChange={(e) => { + setSelectedDate1(moment(e).format("YYYY-MM-DD")); + }} + /> + + + ( + + )} + value={selectedDate2} + onChange={(e) => { + setSelectedDate2(moment(e).format("YYYY-MM-DD")); + }} + /> + + +
    + + + +
    + {/* + + + + */} +
    + + + + + + + + + + +
    + ); +}; diff --git a/src/features/steward/components/steward-sell-out-of-province/StewardSellOutOfProvince.js b/src/features/steward/components/steward-sell-out-of-province/StewardSellOutOfProvince.js new file mode 100644 index 0000000..570a3f9 --- /dev/null +++ b/src/features/steward/components/steward-sell-out-of-province/StewardSellOutOfProvince.js @@ -0,0 +1,78 @@ +import { Box, Tab, Tabs } from "@mui/material"; +import { useEffect, useState } from "react"; +import { useDispatch, useSelector } from "react-redux"; +import { fetchStewardBroadcastAndProducts } from "../../services/handle-fetch-steward-products"; +import { SPACING } from "../../../../data/spacing"; +import { StewardShowProducts } from "../steward-show-products/StewardShowProducts"; +import { Grid } from "../../../../components/grid/Grid"; +import { StewardSellOutOfProvinceSells } from "../steward-sell-out-of-province-sells/StewardSellOutOfProvinceSells"; +import { StewardSellOutOfProvinceBuyers } from "../steward-sell-out-of-province-buyers/StewardSellOutOfProvinceBuyers"; +import { checkPathStartsWith } from "../../../../utils/checkPathStartsWith"; + +export const StewardSellOutOfProvince = () => { + const dispatch = useDispatch(); + const [valueOutProvince, setValueOutProvince] = useState(0); + + const selectedSubUser = useSelector( + (state) => state.userSlice.selectedSubUser + ); + const handleChangeTabsetOutProvince = (event, newValue) => { + setValueOutProvince(newValue); + }; + + useEffect(() => { + dispatch( + fetchStewardBroadcastAndProducts({ + role_key: checkPathStartsWith("steward") ? selectedSubUser?.key : "", + }) + ); + }, [selectedSubUser?.key]); + + return ( + + + + + + + + + + + + + + {valueOutProvince === 0 && } + + {valueOutProvince === 1 && } + + + ); +}; diff --git a/src/features/steward/components/steward-show-allocations-operations/StewardShowAllocationsOperations.js b/src/features/steward/components/steward-show-allocations-operations/StewardShowAllocationsOperations.js new file mode 100644 index 0000000..5fce847 --- /dev/null +++ b/src/features/steward/components/steward-show-allocations-operations/StewardShowAllocationsOperations.js @@ -0,0 +1,165 @@ +import { Button, IconButton, Popover } from "@mui/material"; +import { useState } from "react"; +import TuneIcon from "@mui/icons-material/Tune"; +import { useDispatch, useSelector } from "react-redux"; +import { SlaughterAllocateToGuild } from "../../../slaughter-house/components/slaughter-allocate-to-guild/SlaughterAllocateToGuild"; +import { OPEN_MODAL } from "../../../../lib/redux/slices/appSlice"; +import { Grid } from "../../../../components/grid/Grid"; +import { StewardNorEnterdBarChangeState } from "../../../guild/components/StewardNorEnterdBarChangeState"; +import { slaughterDeleteAllocatedService } from "../../../slaughter-house/services/salughter-delete-allocated"; +import { fetchSlaughterBroadcastAndProducts } from "../../../slaughter-house/services/handle-fetch-slaughter-products"; +import { checkPathStartsWith } from "../../../../utils/checkPathStartsWith"; + +export const StewardShowAllocationsOperations = ({ + item, + type, + handleUpdate, + priceInfo, + remainWeight, + updateTable, +}) => { + const dispatch = useDispatch(); + const [popoverOpen, setPopoverOpen] = useState(false); + const [anchorEl, setAnchorEl] = useState(null); + const selectedSubUser = useSelector( + (state) => state.userSlice.selectedSubUser + ); + const openPopover = (event) => { + setPopoverOpen(true); + setAnchorEl(event.currentTarget); + }; + + const closePopover = () => { + setPopoverOpen(false); + setAnchorEl(null); + }; + + const handleDistributeToGuild = () => { + closePopover(); + const handleEditSuccess = () => { + if (updateTable) updateTable(1); + if (handleUpdate) handleUpdate(); + }; + dispatch( + OPEN_MODAL({ + title: "ویرایش توزیع و فروش محصول", + content: ( + + ), + }) + ); + }; + + return ( + + + + + +
    + + {type && ( + + )} + + {!type && ( + + )} + + {!type && ( + + )} + +
    +
    +
    + ); +}; diff --git a/src/features/steward/components/steward-show-allocations/StewardShowAllocations.js b/src/features/steward/components/steward-show-allocations/StewardShowAllocations.js new file mode 100644 index 0000000..31f83e6 --- /dev/null +++ b/src/features/steward/components/steward-show-allocations/StewardShowAllocations.js @@ -0,0 +1,483 @@ +import React, { + useContext, + useEffect, + useState, + useImperativeHandle, + forwardRef, +} from "react"; +import axios from "axios"; +import moment from "moment"; +import { useDispatch, useSelector } from "react-redux"; +import { Button, TextField, Typography } from "@mui/material"; +import { DatePicker } from "@mui/x-date-pickers"; +import { RiSearchLine } from "react-icons/ri"; +import { AppContext } from "../../../../contexts/AppContext"; +import { + CLOSE_MODAL, + LOADING_END, + LOADING_START, + OPEN_MODAL, +} from "../../../../lib/redux/slices/appSlice"; +import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl"; +import { formatJustDate, formatTime } from "../../../../utils/formatTime"; +import { SPACING } from "../../../../data/spacing"; +import { Grid } from "../../../../components/grid/Grid"; +import { slaughterInventoryFinalSubmitService } from "../../../slaughter-house/services/slaughter-inventory-final-submit"; +import ResponsiveTable from "../../../../components/responsive-table/ResponsiveTable"; +import { StewardShowAllocationsOperations } from "../steward-show-allocations-operations/StewardShowAllocationsOperations"; +import { getAllocationType } from "../../../../utils/getAllocationType"; +import { checkPathStartsWith } from "../../../../utils/checkPathStartsWith"; +// import { format } from "date-fns-jalali"; + +export const StewardShowAllocations = forwardRef( + ({ type, handleUpdate, priceInfo, remainWeight }, ref) => { + const dispatch = useDispatch(); + const [ + , + , + selectedDate1, + setSelectedDate1, + selectedDate2, + setSelectedDate2, + ] = useContext(AppContext); + const selectedSubUser = useSelector( + (state) => state.userSlice.selectedSubUser + ); + useEffect(() => { + const currentDate = moment(new Date()).format("YYYY-MM-DD"); + setSelectedDate1(currentDate); + setSelectedDate2(currentDate); + }, []); + + const handleTextChange = (event) => { + setTextValue(event.target.value); + 8; + }; + + const [data, setData] = useState([]); + const [totalRows, setTotalRows] = useState(0); + const [perPage, setPerPage] = useState(10); + const [textValue, setTextValue] = useState(""); + const [page, setPage] = useState(1); + const [tableData, setTableData] = useState([]); + const [openNotif] = useContext(AppContext); + + const fetchApiData = async (pageParam = 1) => { + try { + dispatch(LOADING_START()); + const response = await axios.get( + `steward-allocation/?role=${getRoleFromUrl()}${ + checkPathStartsWith("steward") + ? `&role_key=${selectedSubUser?.key}` + : "" + }&search=filter&value=${textValue}${ + type !== "not_entered" + ? `&date1=${selectedDate1}&date2=${selectedDate2}` + : "" + }&page=${pageParam}&page_size=${perPage}${ + type ? "&type=" + type : "" + }` + ); + dispatch(LOADING_END()); + setData(response.data.results || []); + setTotalRows(response.data.count || 0); + } catch (err) { + dispatch(LOADING_END()); + console.error("Error fetching allocations:", err); + } + }; + + const updateTable = () => { + fetchApiData(1); + }; + + useImperativeHandle(ref, () => ({ + updateTable, + })); + + const handlePageChange = (newPage) => { + fetchApiData(newPage); + setPage(newPage); + }; + + const getAllocationData = (item) => { + let typeText = `${item?.toKillHouse?.name} - ${item?.toKillHouse?.killHouseOperator?.user?.fullname} (${item?.toKillHouse?.killHouseOperator?.user?.mobile})`; + switch (item?.allocationType) { + case "steward_killhouse": + typeText = `${item?.toKillHouse?.name} - ${item?.toKillHouse?.killHouseOperator?.user?.fullname} (${item?.toKillHouse?.killHouseOperator?.user?.mobile})`; + break; + case "steward_steward": + typeText = `${item?.toStewards?.name} - ${item?.toStewards?.user?.fullname} (${item?.toStewards?.user?.mobile})`; + break; + case "steward_guild": + typeText = `${item?.toGuilds?.guildsName} - ${item?.toGuilds?.user?.fullname} (${item?.toGuilds?.user?.mobile})`; + break; + case "ColdHouse": + typeText = `${item?.toColdHouse?.name}`; + break; + case "killhouse_steward": + typeText = `${item?.toStewards?.name || "-"} - ${ + item?.toStewards?.user?.fullname || "-" + } (${item?.toStewards?.user?.mobile || "-"})`; + break; + case "killhouse_guild": + typeText = `${item?.toGuilds?.guildsName || "-"} - ${ + item?.toGuilds?.user?.fullname || "-" + } (${item?.toGuilds?.user?.mobile || "-"})`; + break; + default: + typeText = `${item?.toKillHouse?.name} - ${item?.toKillHouse?.killHouseOperator?.user?.fullname} (${item?.toKillHouse?.killHouseOperator?.user?.mobile})`; + break; + } + return typeText; + }; + + const getSellerName = (item) => { + let type = ""; + switch (item?.allocationType) { + case "steward_guild": + case "steward_steward": + type = `${!item?.stewards ? "-" : item?.stewards?.user?.fullname} (${ + item?.stewards?.user?.mobile + })`; + break; + case "killhouse_steward": + type = `${!item?.killHouse ? "-" : item?.killHouse?.name} (${ + item?.killHouse?.killHouseOperator?.user?.fullname + } - ${item?.killHouse?.killHouseOperator?.user?.mobile})`; + break; + case "killhouse_guild": + type = `${!item?.killHouse ? "-" : item?.killHouse?.name} (${ + item?.killHouse?.killHouseOperator?.user?.fullname + } - ${item?.killHouse?.killHouseOperator?.user?.mobile})`; + break; + default: + type = `${!item?.steward ? "-" : item?.steward?.user?.fullname} (${ + item?.steward?.user?.mobile + })`; + break; + } + return type; + }; + + const handlePerRowsChange = (perRows) => { + setPerPage(perRows); + setPage(1); + }; + + const getLastItem = () => { + if (!type || type === "not_entered") { + return ["عملیات"]; + } else { + return []; + } + }; + const getRegCodeItemData = (item) => { + if (type === "not_entered") { + return []; + } else { + return [ + item?.loggedRegistrationCode ? item.loggedRegistrationCode : "-", + item?.registrationCode ? "ارسال شده" : "ارسال نشده", + ]; + } + }; + const getRegCodeItemColumns = () => { + if (type === "not_entered") { + return []; + } else { + return ["کداحراز", "وضعیت کد احراز"]; + } + }; + const getAprovedItemData = (item) => { + if (!type) { + return [item?.receiverRealWeightOfCarcasses?.toLocaleString()]; + } else if (type === "not_entered") { + return []; + } else { + return [ + item?.receiverRealNumberOfCarcasses?.toLocaleString(), + item?.receiverRealWeightOfCarcasses?.toLocaleString(), + ]; + } + }; + + const getAprovedItemColumns = () => { + if (!type) { + return ["وزن تایید شده"]; + } else if (type === "not_entered") { + return []; + } else { + return ["حجم تایید شده", "وزن تایید شده"]; + } + }; + + useEffect(() => { + const d = data?.map((item, i) => { + return [ + page === 1 ? i + 1 : i + perPage * (page - 1) + 1, + item?.date ? formatTime(item?.date) : "-", + item?.productionDate ? formatJustDate(item?.productionDate) : "-", + item?.distributionType === "web" + ? "سایت" + : item?.distributionType === "app" + ? "موبایل" + : item?.distributionType === "pos" + ? "پوز" + : item?.distributionType || "-", + getAllocationType(item), + getAllocationData(item), + getSellerName(item), + item?.sellType === "exclusive" ? "اختصاصی" : "آزاد", + item?.amount?.toLocaleString() + " ریال", + item?.totalAmount?.toLocaleString() + " ریال", + item?.realWeightOfCarcasses?.toLocaleString(), + ...getAprovedItemData(item), + ...getRegCodeItemData(item), + item?.weightLossOfCarcasses?.toLocaleString(), + item?.quota === "governmental" + ? "دولتی" + : item?.quota === "free" + ? "آزاد" + : "-", + item?.approvedPriceStatus ? "دولتی" : "آزاد", + item?.receiverState === "accepted" + ? "تایید شده" + : item?.receiverState === "rejected" + ? "رد شده" + : "در انتظار تایید", + , + ]; + }); + + setTableData(d); + }, [data]); + + useEffect(() => { + fetchApiData(1); + }, [dispatch, selectedDate1, selectedDate2, perPage]); + + const handleSubmit = async (event) => { + event.preventDefault(); + dispatch(LOADING_START()); + + try { + const response = await axios.get( + `steward-allocation/?role=${getRoleFromUrl()}${ + checkPathStartsWith("steward") + ? `&role_key=${selectedSubUser?.key}` + : "" + }&search=filter&value=${textValue}${ + type !== "not_entered" + ? `&date1=${selectedDate1}&date2=${selectedDate2}` + : "" + }&page=${page}&page_size=${perPage}${type ? "&type=" + type : ""}` + ); + setData(response.data.results); + setTotalRows(response.data.count); + dispatch(LOADING_END()); + } catch (error) { + console.error("Error fetching data:", error); + dispatch(LOADING_END()); + } + }; + + return ( + + + + {type !== "not_entered" && ( + <> + + ( + + )} + value={selectedDate1} + onChange={(e) => { + setSelectedDate1(moment(e).format("YYYY-MM-DD")); + }} + /> + + + ( + + )} + value={selectedDate2} + onChange={(e) => { + setSelectedDate2(moment(e).format("YYYY-MM-DD")); + }} + /> + + + )} + +
    + + + +
    + + {!(type === "entered" || type === "not_entered") && ( + + +
    +
    + ), + }) + ); + }} + > + تایید نهایی (یکجا) + + )} +
    + + + + + ); + } +); + +StewardShowAllocations.displayName = "StewardShowAllocations"; diff --git a/src/features/steward/components/steward-show-products/StewardShowProducts.js b/src/features/steward/components/steward-show-products/StewardShowProducts.js new file mode 100644 index 0000000..c6dc74f --- /dev/null +++ b/src/features/steward/components/steward-show-products/StewardShowProducts.js @@ -0,0 +1,243 @@ +import React, { useContext, useEffect, useState } from "react"; +import { useDispatch, useSelector } from "react-redux"; +import { Grid } from "../../../../components/grid/Grid"; +import ResponsiveTable from "../../../../components/responsive-table/ResponsiveTable"; +import { + Button, + FormControlLabel, + IconButton, + Radio, + RadioGroup, + TextField, + Tooltip, +} from "@mui/material"; +import SystemUpdateAltIcon from "@mui/icons-material/SystemUpdateAlt"; +import { CLOSE_MODAL, OPEN_MODAL } from "../../../../lib/redux/slices/appSlice"; +import { DatePicker } from "@mui/x-date-pickers"; +import moment from "moment"; +import { AppContext } from "../../../../contexts/AppContext"; +import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl"; +import axios from "axios"; +import { useLocation } from "react-router-dom"; +import { ROUTE_STEWARD_INVENTORY } from "../../../../routes/routes"; +import { checkPathStartsWith } from "../../../../utils/checkPathStartsWith"; + +export const StewardShowProducts = () => { + const { distributionInfo, stewardProducts } = useSelector( + (state) => state.stewardSlice + ); + const [productsTable, setProductsTable] = useState(); + const { pathname } = useLocation(); + + const dispatch = useDispatch(); + + const getWeight = (item) => { + if (getRoleFromUrl() === "KillHouse") { + return [ + item?.totalGovernmentalCarcassesWeight?.toLocaleString(), + item?.provinceFreeCarcassesWeight?.toLocaleString(), + ]; + } else { + return [ + item?.receiveGovernmentalCarcassesWeight?.toLocaleString(), + item?.receiveFreeCarcassesWeight?.toLocaleString(), + ]; + } + }; + + useEffect(() => { + const d = stewardProducts?.map((item, i) => { + return [ + i + 1, + item?.name, + ...getWeight(item), + item?.freeBuyingCarcassesWeight?.toLocaleString(), + item?.totalCarcassesWeight?.toLocaleString(), + item?.realAllocatedWeight?.toLocaleString(), + item?.totalRemainWeight?.toLocaleString(), + distributionInfo?.totalGovernmentalRemainWeight?.toLocaleString(), + distributionInfo?.totalFreeRemainWeight?.toLocaleString(), + distributionInfo?.totalGovernmentalInputWeight?.toLocaleString(), + distributionInfo?.totalFreeInputWeight?.toLocaleString(), + ]; + }); + + setProductsTable(d); + }, [stewardProducts, distributionInfo]); + + const getDistributionKeys = () => { + if (pathname === ROUTE_STEWARD_INVENTORY) { + return []; + } else { + return [ + "مانده دولتی (کیلوگرم)", + " مانده آزاد (کیلوگرم)", + "وزن دولتی (کیلوگرم)", + "وزن آزاد (کیلوگرم)", + ]; + } + }; + + return ( + + + {getRoleFromUrl() === "KillHouse" && ( + + { + dispatch( + OPEN_MODAL({ + title: "دریافت خروجی اکسل", + content: , + }) + ); + }} + > + + + + )} + + } + title={"موجودی انبار"} + columns={[ + "ردیف", + "نام محصول", + "وزن خریدهای دولتی داخل استان (کیلوگرم)", + "وزن خریدهای آزاد داخل استان (کیلوگرم)", + "وزن خریدهای خارج استان (کیلوگرم)", + "کل ورودی به انبار (کیلوگرم)", + "کل فروش (کیلوگرم)", + "مانده انبار (کیلوگرم)", + ...getDistributionKeys(), + ]} + data={productsTable} + customColors={[ + { name: "ردیف", color: "red" }, + { name: "نام محصول", color: "red" }, + { name: "کل ورودی به انبار (کیلوگرم)", color: "red" }, + { name: "وزن خریدهای دولتی داخل استان (کیلوگرم)", color: "red" }, + { name: "وزن خریدهای آزاد داخل استان (کیلوگرم)", color: "red" }, + { name: "وزن خریدهای خارج استان (کیلوگرم)", color: "red" }, + { name: "کل فروش (کیلوگرم)", color: "red" }, + { name: "مانده انبار (کیلوگرم)", color: "green" }, + ]} + /> + + ); +}; + +const HandleDownloadInventoryData = () => { + const [downloadType, setDownloadType] = useState("withdate"); + const selectedSubUser = useSelector( + (state) => state.userSlice.selectedSubUser + ); + const handleChange = (event) => { + setDownloadType(event.target.value); + }; + + const userKey = useSelector((state) => state.userSlice.userProfile.key); + + const [selectedDate1, setSelectedDate1] = useState( + moment(new Date()).format("YYYY-MM-DD") + ); + const [selectedDate2, setSelectedDate2] = useState( + moment(new Date()).format("YYYY-MM-DD") + ); + + const dispatch = useDispatch(); + + const [openNotif] = useContext(AppContext); + return ( + + + } + label="دانلود بر اساس بازه" + /> + } + label="دانلود کلی" + /> + + + {downloadType === "withdate" && ( + + + ( + + )} + value={selectedDate1} + onChange={(e) => { + setSelectedDate1(moment(e).format("YYYY-MM-DD")); + }} + /> + + + ( + + )} + value={selectedDate2} + onChange={(e) => { + setSelectedDate2(moment(e).format("YYYY-MM-DD")); + }} + /> + + + )} + + + + ); +}; diff --git a/src/features/steward/components/steward-stock/StewardStock.js b/src/features/steward/components/steward-stock/StewardStock.js new file mode 100644 index 0000000..8644bb5 --- /dev/null +++ b/src/features/steward/components/steward-stock/StewardStock.js @@ -0,0 +1,116 @@ +import React, { useEffect, useState, useRef } from "react"; +import { useDispatch, useSelector } from "react-redux"; + +import { + Accordion, + AccordionSummary, + AccordionDetails, + Typography, +} from "@mui/material"; +import ExpandMoreIcon from "@mui/icons-material/ExpandMore"; +import { stewardGetBarsInfo } from "../../services/steward-get-bars-info"; +import { Grid } from "../../../../components/grid/Grid"; +import { StewardShowProducts } from "../steward-show-products/StewardShowProducts"; +import ResponsiveTable from "../../../../components/responsive-table/ResponsiveTable"; +import { StewardShowAllocations } from "../steward-show-allocations/StewardShowAllocations"; +import { checkPathStartsWith } from "../../../../utils/checkPathStartsWith"; + +export const StewardStock = () => { + const dispatch = useDispatch(); + const selectedSubUser = useSelector( + (state) => state.userSlice.selectedSubUser + ); + const [barsInfo, setBarsInfo] = useState([]); + const notEnteredRef = useRef(); + const enteredRef = useRef(); + + const handleUpdate = () => { + dispatch( + stewardGetBarsInfo({ + role_key: checkPathStartsWith("steward") ? selectedSubUser?.key : "", + }) + ).then((r) => { + setBarsInfo(r.payload.data); + }); + + if (notEnteredRef.current) { + notEnteredRef.current.updateTable(); + } + if (enteredRef.current) { + enteredRef.current.updateTable(); + } + }; + + useEffect(() => { + handleUpdate(); + }, [dispatch]); + + return ( + + + + + + + + + + + + + + + + }> + بارهای وارد شده + + + + + + + + + + ); +}; diff --git a/src/features/steward/components/steward-submit-free-bar/StewardSubmitFreeBar.js b/src/features/steward/components/steward-submit-free-bar/StewardSubmitFreeBar.js new file mode 100644 index 0000000..3efcd0b --- /dev/null +++ b/src/features/steward/components/steward-submit-free-bar/StewardSubmitFreeBar.js @@ -0,0 +1,369 @@ +import { useContext, useEffect, useState } from "react"; +import { useDispatch, useSelector } from "react-redux"; +import { useFormik } from "formik"; +import moment from "moment"; +import { Autocomplete, Button, InputAdornment, TextField } from "@mui/material"; +import { Yup } from "../../../../lib/yup/yup"; +import { AppContext } from "../../../../contexts/AppContext"; +import { slaughterGetProductsService } from "../../../slaughter-house/services/slaughter-inventory-gets"; +import { + slaughterGetCitiesService, + slaughterGetProvinceService, +} from "../../../slaughter-house/services/slaughter-get-provinces"; +import { fixBase64 } from "../../../../utils/toBase64"; +import { DRAWER } from "../../../../lib/redux/slices/appSlice"; +import { + stewardEditFreeBarService, + stewardSubmitFreeBarService, +} from "../../../guild/services/steward-submit-free-bar-service"; +import { Grid } from "../../../../components/grid/Grid"; +import { SPACING } from "../../../../data/spacing"; +import { ImageUpload } from "../../../../components/image-upload/ImageUpload"; +import { checkPathStartsWith } from "../../../../utils/checkPathStartsWith"; + +const ValidationSchema = Yup.object().shape({ + kill_house_name: Yup.string().required("نام فروشنده الزامی است"), + kill_house_mobile: Yup.string() + .required("شماره موبایل فروشنده الزامی است") + .min(11, "شماره موبایل باید دقیقاً 11 رقم باشد") + .max(11, "شماره موبایل باید دقیقاً 11 رقم باشد"), + province: Yup.string().required("استان الزامی است"), + city: Yup.string().required("شهر الزامی است"), + bar_image: Yup.string().when("$isEdit", { + is: true, + then: Yup.string(), + otherwise: Yup.string().required("عکس بار الزامی است"), + }), + number_of_carcasses: Yup.number() + .required("حجم لاشه الزامی است") + .min(1, "حجم لاشه باید بیشتر از 0 باشد"), + weight_of_carcasses: Yup.number() + .required("وزن لاشه الزامی است") + .min(0.01, "وزن باید بیشتر از 0 باشد"), + product_key: Yup.string().required("انتخاب محصول الزامی است"), +}); + +export const StewardSubmitFreeBar = ({ updateTable, item }) => { + const dispatch = useDispatch(); + const [openNotif] = useContext(AppContext); + const [productData, setProductData] = useState([]); + const [provinceData, setProvinceData] = useState([]); + const [cityData, setCityData] = useState([]); + const [profileImages, setProfileImages] = useState([]); + const selectedSubUser = useSelector( + (state) => state.userSlice.selectedSubUser + ); + + useEffect(() => { + dispatch( + slaughterGetProductsService({ + role_key: checkPathStartsWith("steward") + ? selectedSubUser?.key || "" + : "", + }) + ).then((r) => { + // Handle both direct array response and nested data response + const data = r.payload?.data; + if (Array.isArray(data)) { + setProductData(data); + } else if (data?.data && Array.isArray(data.data)) { + setProductData(data.data); + } else { + setProductData([]); + } + }); + dispatch(slaughterGetProvinceService()).then((r) => { + setProvinceData(r.payload.data); + }); + }, [dispatch, selectedSubUser]); + const formik = useFormik({ + initialValues: { + product_key: item?.productKey || "", + kill_house_name: item?.killHouseName || "", + kill_house_mobile: item?.killHouseMobile || "", + province: item?.province || "", + city: item?.city || "", + bar_image: item?.barImage || "", + number_of_carcasses: item?.numberOfCarcasses || "", + weight_of_carcasses: item?.weightOfCarcasses || "", + date: item?.date || moment(new Date()).format("YYYY-MM-DD HH:mm:ss"), + role_key: checkPathStartsWith("steward") + ? selectedSubUser?.key || "" + : "", + ...(item?.key && { key: item.key }), + }, + validationSchema: ValidationSchema, + onSubmit: (values) => { + if (item?.key) { + if (profileImages.length && profileImages[0]?.data_url) { + values.bar_image = fixBase64(profileImages[0]?.data_url); + } else { + values.bar_image = item.barImage; + } + } + const thenCallback = (r) => { + if (r.payload.error) { + openNotif({ + vertical: "top", + horizontal: "center", + msg: r.payload.error, + severity: "error", + }); + } else { + updateTable(); + dispatch(DRAWER({ right: false, bottom: false, content: null })); + openNotif({ + vertical: "top", + horizontal: "center", + msg: item?.key + ? "اطلاعات خرید با موفقیت ویرایش شد" + : "اطلاعات خرید جدید با موفقیت ثبت شد", + severity: "success", + }); + } + }; + + if (item?.key) { + dispatch(stewardEditFreeBarService(values)).then(thenCallback); + } else { + dispatch(stewardSubmitFreeBarService(values)).then(thenCallback); + } + }, + }); + + const factorPaymentHandler = (imageList) => { + if (imageList[0]) { + formik.setFieldValue("bar_image", fixBase64(imageList[0]?.data_url)); + } + setProfileImages(imageList); + }; + + useEffect(() => { + if (formik.values.province) { + dispatch(slaughterGetCitiesService(formik.values.province)).then((r) => { + setCityData(r.payload.data); + }); + } + }, [formik.values.province]); + useEffect(() => { + if (item?.barImage) { + setProfileImages([{ data_url: item?.barImage }]); + } + }, [item]); + + return ( + + + + 0 + ? productData.map((i) => ({ + id: i.key, + label: i.name || "", + })) + : [] + } + value={ + Array.isArray(productData) && productData.length > 0 + ? productData + .map((i) => ({ id: i.key, label: i.name || "" })) + .find((opt) => opt.id === formik.values.product_key) || null + : null + } + onChange={(event, value) => { + formik.setFieldValue("product_key", value ? value.id : ""); + }} + renderInput={(params) => ( + + )} + /> + + +
    + + + + ({ + id: i.name, + label: i.name, + }))} + value={ + formik.values.province + ? { + id: formik.values.province, + label: formik.values.province, + } + : null + } + onChange={(e, value) => { + formik.setFieldValue("province", value ? value.id : ""); + formik.setFieldValue("city", ""); + }} + renderInput={(params) => ( + + )} + /> + + ({ id: i.name, label: i.name })) + : [] + } + onChange={(e, value) => { + formik.setFieldValue("city", value ? value.id : ""); + formik.setFieldValue("city", value ? value.id : ""); + }} + renderInput={(params) => ( + + )} + /> + + قطعه + ), + }} + value={formik.values.number_of_carcasses} + onChange={formik.handleChange} + onBlur={formik.handleBlur} + error={ + formik.touched.number_of_carcasses && + Boolean(formik.errors.number_of_carcasses) + } + helperText={ + formik.touched.number_of_carcasses && + formik.errors.number_of_carcasses + } + /> + + کیلوگرم + ), + }} + value={formik.values.weight_of_carcasses} + onChange={formik.handleChange} + onBlur={formik.handleBlur} + error={ + formik.touched.weight_of_carcasses && + Boolean(formik.errors.weight_of_carcasses) + } + helperText={ + formik.touched.weight_of_carcasses && + formik.errors.weight_of_carcasses + } + /> + + + + {!profileImages.length && item?.barImage && ( + + bar + + )} + + + +
    +
    + ); +}; diff --git a/src/features/steward/services/handle-fetch-steward-products.js b/src/features/steward/services/handle-fetch-steward-products.js new file mode 100644 index 0000000..c4bfe4c --- /dev/null +++ b/src/features/steward/services/handle-fetch-steward-products.js @@ -0,0 +1,37 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; +import { getRoleFromUrl } from "../../../utils/getRoleFromUrl"; + +export const fetchStewardBroadcastAndProducts = createAsyncThunk( + "STEWARD_FETCH_BROADCAST_AND_PRODUCTS", + async (d, { dispatch }) => { + try { + dispatch(LOADING_START()); + const [broadcastResponse, productsResponse] = await Promise.all([ + axios.get("steward-sales-info-dashboard/", { + params: { + role: getRoleFromUrl(), + role_key: d.role_key || "", + }, + }), + axios.get("roles-products", { + params: { + role: getRoleFromUrl(), + role_key: d.role_key || "", + }, + }), + ]); + + dispatch(LOADING_END()); + + return { + broadcastData: broadcastResponse.data, + productsData: productsResponse.data, + }; + } catch (error) { + dispatch(LOADING_END()); + throw error; + } + } +); diff --git a/src/features/steward/services/steward-get-bars-info.js b/src/features/steward/services/steward-get-bars-info.js new file mode 100644 index 0000000..dbf505d --- /dev/null +++ b/src/features/steward/services/steward-get-bars-info.js @@ -0,0 +1,19 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; +import axios from "axios"; +import { getRoleFromUrl } from "../../../utils/getRoleFromUrl"; + +export const stewardGetBarsInfo = createAsyncThunk( + "STEWARD_GET_BARS_INFO", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + const { data, status } = await axios.get("bars_for_kill_house_dashboard/", { + params: { + role: getRoleFromUrl(), + ...d, + }, + }); + dispatch(LOADING_END()); + return { data, status }; + } +); diff --git a/src/features/steward/services/steward-get-distributions-info.js b/src/features/steward/services/steward-get-distributions-info.js new file mode 100644 index 0000000..c503add --- /dev/null +++ b/src/features/steward/services/steward-get-distributions-info.js @@ -0,0 +1,15 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import { getRoleFromUrl } from "../../../utils/getRoleFromUrl"; +import axios from "axios"; + +export const stewardGetVBroadcastInfo = createAsyncThunk( + "STEWARD_GET_BROARDCAST_INFO", + async (d, { dispatch }) => { + const { data, status } = await axios.get("steward-sales-info-dashboard/", { + params: { + role: getRoleFromUrl(), + }, + }); + return { data, status }; + } +); diff --git a/src/features/steward/services/steward-resend-out-province-registration-code.js b/src/features/steward/services/steward-resend-out-province-registration-code.js new file mode 100644 index 0000000..639f861 --- /dev/null +++ b/src/features/steward/services/steward-resend-out-province-registration-code.js @@ -0,0 +1,21 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const stewardResendOutProvinceRegistrationCodeService = createAsyncThunk( + "STEWARD_RESEND_OUT_PROVINCE_REGISTRATION_CODE", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + try { + const { data, status } = await axios.post( + "send_again_sms_steward_free_sale_bar/", + d + ); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e.response?.data?.result || "خطا در ارسال مجدد کد" }; + } + } +); diff --git a/src/features/super-admin/components/super-admin-requests-operations/SuperAdminRequestsOperations.js b/src/features/super-admin/components/super-admin-requests-operations/SuperAdminRequestsOperations.js new file mode 100644 index 0000000..75e029b --- /dev/null +++ b/src/features/super-admin/components/super-admin-requests-operations/SuperAdminRequestsOperations.js @@ -0,0 +1,311 @@ +import { useLocation } from "react-router-dom"; +import { VscFolderActive, VscNewFolder } from "react-icons/vsc"; +import { + FaTruckLoading, + FaFile, + FaFilePdf, + FaExchangeAlt, + FaHornbill, +} from "react-icons/fa"; +import { useDispatch } from "react-redux"; +import { Grid } from "../../../../components/grid/Grid"; +import { SPACING } from "../../../../data/spacing"; +import { LineWithText } from "../../../../components/line-with-text/LineWithText"; +import { NavLink } from "../../../../components/nav-link/NavLink"; +import LinkItem from "../../../../components/link-item/LinkItem"; +import { + MdCreateNewFolder, + MdImportExport, + MdOutlineRuleFolder, +} from "react-icons/md"; +import { OPEN_MODAL } from "../../../../lib/redux/slices/appSlice"; +import PorvinceGetReportOperations from "../../../province/components/province-get-report-operations/PorvinceGetReportOperations"; +import { + ROUTE_ADMINX_CITY_NEW_REQUESTS, + ROUTE_ADMINX_STATEMENTـOFـNEED_REQUESTS, + ROUTE_ADMINX_ALLOCATION_REQUESTS, + ROUTE_ADMINX_PAYING_FEES_REQUESTS, + ROUTE_ADMINX_EXPORT, + ROUTE_ADMINX_FREE_SALES_REQUESTS, + ROUTE_ADMINX_AUTO_ALLOCATION_REQUESTS, + ROUTE_ADMINX_CHAINS, + ROUTE_PROVINCEـFREE_BUY, + ROUTE_SUPER_ADMIN_TRADING_PANEL, + ROUTE_SUPER_ADMIN_ALLOCATED_REQUESTS, + ROUTE_SUPER_ADMIN_ALLOCATION_REQUESTS, + ROUTE_SUPER_ADMIN_AUTO_ALLOCATION_REQUESTS, + ROUTE_SUPER_ADMIN_CHAINS, + ROUTE_SUPER_ADMIN_CITY_NEW_REQUESTS, + ROUTE_SUPER_ADMIN_EXPORT, + ROUTE_SUPER_ADMIN_FREE_SALES_REQUESTS, + ROUTE_SUPER_ADMIN_ISSUANCE_OF_LETTER, + ROUTE_SUPER_ADMIN_PAYING_FEES_REQUESTS, + ROUTE_SUPER_ADMIN_STATEMENTـOFـNEED_REQUESTS, + ROUTE_SUPER_ADMIN_TRANSACTIONS, + ROUTE_ADMINX_TRANSACTIONS, + ROUTE_ADMINX_ALLOCATED_REQUESTS, + ROUTE_ADMINX_ISSUANCE_OF_LETTER, +} from "../../../../routes/routes"; +import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl"; + +export const SuperAdminRequestsOperations = () => { + const { pathname } = useLocation(); + const dispatch = useDispatch(); + + const getRoleBasedRoute = (superAdminRoute, adminxRoute) => { + return getRoleFromUrl() === "SuperAdmin" ? superAdminRoute : adminxRoute; + }; + + return ( + + + + + + + + } + title="درخواست های کشتار" + description="درخواست های کشتار مرغدار در انتظار بررسی" + /> + + + } + title="اعلام نیاز خریداران" + description="درخواست های کشتار در انتظار بررسی" + /> + + + } + title="تخصیصات" + description="مشاهده و تخصیص درخواست ها" + /> + + + } + title="تعرفه ها" + /> + + + + + + + + + + + } + title="خرید مستقیم" + /> + + + } + title="پنل معاملات" + /> + + + } + title="صادرات" + /> + + + } + title="فروش خارج از استان" + /> + + + } + title="تخصیصات خودکار" + /> + + + } + title="زنجیره ها" + /> + + + + + + + + + + + } + title="مدیریت تخصیصات" + /> + + + + } + title="صدور نامه" + description="ارسال نامه سیستمی" + /> + + + + dispatch( + OPEN_MODAL({ + title: "اطلاعات گزارش", + content: , + }) + ) + } + > + + } + title="گزارش روزانه" + description="گزارش روزانه" + /> + + + + + } + title="تراکنش ها" + /> + + + + + ); +}; diff --git a/src/features/super-admin/components/super-admin-submit-bar-status/SuperAdminSubmitBarStatus.js b/src/features/super-admin/components/super-admin-submit-bar-status/SuperAdminSubmitBarStatus.js new file mode 100644 index 0000000..a62cf83 --- /dev/null +++ b/src/features/super-admin/components/super-admin-submit-bar-status/SuperAdminSubmitBarStatus.js @@ -0,0 +1,112 @@ +import { + Button, + FormControl, + InputLabel, + MenuItem, + Select, + TextField, +} from "@mui/material"; +import React, { useContext, useEffect, useState } from "react"; +import { Grid } from "../../../../components/grid/Grid"; +import { AppContext } from "../../../../contexts/AppContext"; +import { useDispatch, useSelector } from "react-redux"; +import { vetFarmEditTrafficCodeService } from "../../../vet-farm/services/vet-farm-edit-traffic-code"; +import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl"; +import { CLOSE_MODAL } from "../../../../lib/redux/slices/appSlice"; +import { getDocumentStates } from "../../../province/services/getDocumentStates"; +import { checkPathStartsWith } from "../../../../utils/checkPathStartsWith"; + +export const SuperAdminSubmitBarStatus = ({ item, updateTable }) => { + const [documentState, setDocumentState] = useState( + item?.barDocumentStatus?.key ? item?.barDocumentStatus?.key : "" + ); + const [description, setdescription] = useState( + item?.description ? item?.description : "" + ); + const [openNotif] = useContext(AppContext); + const dispatch = useDispatch(); + const selectedSubUser = useSelector( + (state) => state.userSlice.selectedSubUser + ); + const handleStateChange = (event) => { + setDocumentState(event.target.value); + }; + + const handledescriptionChange = (event) => { + setdescription(event.target.value); + }; + + const [listData, setListData] = useState([]); + + useEffect(() => { + dispatch( + getDocumentStates({ + role_key: checkPathStartsWith("slaughter") + ? selectedSubUser?.key || "" + : "", + }) + ).then((r) => { + setListData(r.payload.data); + }); + }, [selectedSubUser?.key]); + + return ( + + + وضعیت سند + + + + + + + + + + ); +}; diff --git a/src/features/supporter/components/SupporterSettlement.js b/src/features/supporter/components/SupporterSettlement.js new file mode 100644 index 0000000..1e2a2ed --- /dev/null +++ b/src/features/supporter/components/SupporterSettlement.js @@ -0,0 +1,283 @@ +import { useState, useEffect, useContext, useCallback } from "react"; +import { Grid } from "../../../components/grid/Grid"; +import { Button, TextField, Tooltip } from "@mui/material"; +import axios from "axios"; +import moment from "moment/moment"; +import { RiFileExcel2Fill, RiSearchLine } from "react-icons/ri"; +import { DatePicker } from "@mui/x-date-pickers"; +import { useDispatch, useSelector } from "react-redux"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; +import { AppContext } from "../../../contexts/AppContext"; +import { getRoleFromUrl } from "../../../utils/getRoleFromUrl"; +import { SPACING } from "../../../data/spacing"; +import ResponsiveTable from "../../../components/responsive-table/ResponsiveTable"; +import { formatJustDate } from "../../../utils/formatTime"; +import { SupporterSettlementOperation } from "./supporter-settlement-operation/SupporterSettlementOperation"; +import SlaughterBuyPdfKillRequest from "../../province/components/province-settlement-pdf-kill-request/ProvinceSettlementPdfKillRequest"; + +const SupporterSettlement = () => { + const dispatch = useDispatch(); + + const [, , selectedDate1, setSelectedDate1, selectedDate2, setSelectedDate2] = + useContext(AppContext); + const [tableData, setTableData] = useState([]); + const [data, setData] = useState([]); + const [totalRows, setTotalRows] = useState(0); + const [perPage, setPerPage] = useState(10); + + const [page, setPage] = useState(1); + const [textValue, setTextValue] = useState(""); + + const userKey = useSelector((state) => state.userSlice.userProfile.key); + + const fetchApiData = useCallback(async () => { + dispatch(LOADING_START()); + try { + const response = await axios.get( + `direct-buying-requests/?role=${getRoleFromUrl()}&status=active"&search=filter&value=${ + textValue || "" + }&date1=${selectedDate1}&date2=${selectedDate2}&page=1&page_size=${perPage}` + ); + dispatch(LOADING_END()); + setData(response?.data?.results); + setTotalRows(response?.data?.count); + } catch (error) { + dispatch(LOADING_END()); + } + }, [selectedDate1, selectedDate2, perPage, page, textValue, dispatch]); + + const handlePerRowsChange = (perRows) => { + setPerPage(perRows); + setPage(1); + }; + + const handlePageChange = (page) => { + fetchApiData(page, textValue); + setPage(page); + }; + + const handleTextChange = (event) => { + setTextValue(event.target.value); + }; + + const handleSubmit = async (event) => { + event.preventDefault(); + dispatch(LOADING_START()); + + try { + const response = await axios.get( + `direct-buying-requests/?role=${getRoleFromUrl()}&status=${"active"}&date1=${selectedDate1}&date2=${selectedDate2}&search=filter&value=${ + textValue || "" + }` + ); + setData(response?.data?.results); + setTotalRows(response?.data?.count); + dispatch(LOADING_END()); + } catch (error) { + console.error("Error fetching data:", error); + } + }; + + useEffect(() => { + fetchApiData(1); + }, [dispatch, selectedDate1, selectedDate2, perPage]); + + const updateTable = useCallback(() => { + fetchApiData(1); + }, [fetchApiData]); + + useEffect(() => { + const d = data?.map((item, i) => { + let paymentStatusText; + switch (item?.paymentDeadlineState) { + case "pending": + paymentStatusText = "بارگزاری سند مالی"; + break; + case "checking": + paymentStatusText = "بررسی مالی اتحادیه"; + break; + case "accepted": + paymentStatusText = "تایید شده"; + break; + + case "rejected": + paymentStatusText = "برگشت داده شده"; + break; + case "archive": + paymentStatusText = "بایگانی شده"; + break; + default: + paymentStatusText = "وضعیت نامشخص"; + } + return [ + page === 1 ? i + 1 : i + perPage * (page - 1) + 1, + + formatJustDate(item?.killRequest?.createDate), + + formatJustDate(item?.killRequest?.reciveDate), + `${item?.killRequest?.killHouse?.name} (${item?.killRequest?.killHouse?.mobile})`, + `${item?.killRequest?.poultry?.age}`, + item?.killRequest?.freeDirectBuying ? "آزاد" : "دولتی", + item?.killRequest?.killHouse + ? item?.killRequest?.killHouse?.name + : item?.killRequest?.slaughterHouse, + + `${item?.killRequest?.poultry?.fullname} (${item?.killRequest?.poultry.mobile})`, + + item?.generalInfo?.age, + + `${ + item?.killRequest?.chickenBreed + ? item?.killRequest?.chickenBreed + : "-" + }`, + item?.totalKilledQuantity?.toLocaleString(), + item?.generalInfo?.IndexWeight, + + item?.totalKilledWeight?.toLocaleString(), + + item?.killRequest?.amount?.toLocaleString(), + + item?.generalInfo?.totalAmount?.toLocaleString(), + + formatJustDate(item?.paymentDeadlineDate), + item?.extensionPaymentDeadlineDate + ? formatJustDate(item?.extensionPaymentDeadlineDate) + : "-", + , + item?.generalInfo?.totalPaidAmount.toLocaleString(), + + paymentStatusText, + item?.paymentDeadlineCheckerFullname, + formatJustDate(item?.paymentDeadlineCheckDate), + item?.paymentDeadlineArchiveMessage, + + , + ]; + }); + + setTableData(d); + }, [data]); + + return ( + <> + + +
    + + + + + ( + + )} + value={selectedDate1} + onChange={(e) => { + setSelectedDate1(moment(e).format("YYYY-MM-DD")); + }} + /> + ( + + )} + value={selectedDate2} + onChange={(e) => { + setSelectedDate2(moment(e).format("YYYY-MM-DD")); + }} + /> + + + + + + + + + + +
    +
    + + +
    + + ); +}; + +export default SupporterSettlement; diff --git a/src/features/supporter/components/supporter-settlement-modal/SupporterSettlemetModal.js b/src/features/supporter/components/supporter-settlement-modal/SupporterSettlemetModal.js new file mode 100644 index 0000000..7a45cea --- /dev/null +++ b/src/features/supporter/components/supporter-settlement-modal/SupporterSettlemetModal.js @@ -0,0 +1,193 @@ +import { Grid, TextField, Button } from "@mui/material"; +import { useEffect, useState } from "react"; +import { freeBuyingPayment } from "../../../province/services/free-buying-payment"; +import { useDispatch } from "react-redux"; +import { formatJustDate } from "../../../../utils/formatTime"; +import ShowImage from "../../../../components/show-image/ShowImage"; +import { AddCommentInSettlemetProvince } from "../../services/AddCommentInSettlemetProvince"; + +function SupporterSettlementModal({ modal_key }) { + const dispatch = useDispatch(); + const [paymentData, setPaymentData] = useState([]); + const [comments, setComments] = useState({}); + const [submitting, setSubmitting] = useState({}); + + useEffect(() => { + if (modal_key) { + dispatch( + freeBuyingPayment({ province_kill_request_key: modal_key }) + ).then((action) => { + const response = action.payload?.data; + if (response && Array.isArray(response)) { + const formattedPayments = response.map((payment) => ({ + ...payment, + date: formatJustDate(payment.date), + })); + + setPaymentData(formattedPayments); + + const initialComments = {}; + formattedPayments.forEach((payment) => { + initialComments[payment.key] = + payment.paymentDeadlineSupporterMessage || ""; + }); + + setComments(initialComments); + } + }); + } + }, [dispatch, modal_key]); + + const handleCommentChange = (paymentKey, value) => { + setComments((prev) => ({ + ...prev, + [paymentKey]: value, + })); + }; + + const handleSubmitComment = (paymentKey) => { + const comment = comments[paymentKey]?.trim() || ""; + + setSubmitting((prev) => ({ ...prev, [paymentKey]: true })); + + const data = { + key: paymentKey, + payment_deadline_supporter_message: comment, + }; + + dispatch(AddCommentInSettlemetProvince(data)) + .then((action) => { + if (action.payload?.status === 200) { + if (modal_key) { + return dispatch( + freeBuyingPayment({ province_kill_request_key: modal_key }) + ).then((action) => { + const response = action.payload?.data; + if (response && Array.isArray(response)) { + const formattedPayments = response.map((payment) => ({ + ...payment, + date: formatJustDate(payment.date), + })); + setPaymentData(formattedPayments); + } + }); + } + } + }) + .finally(() => + setSubmitting((prev) => ({ ...prev, [paymentKey]: false })) + ); + }; + + return ( + + {paymentData.map((payment) => ( + + + {payment.image && ( + + + + )} + + + + + + {payment.date && ( + + + + )} + + + + handleCommentChange(payment.key, e.target.value) + } + InputProps={{ + style: { fontSize: 14 }, + }} + sx={{ + "& .MuiInputBase-root": { + height: "auto", + alignItems: "flex-start", + }, + }} + /> + + + + + + + + ))} + + ); +} + +export default SupporterSettlementModal; diff --git a/src/features/supporter/components/supporter-settlement-operation/SupporterSettlementOperation.js b/src/features/supporter/components/supporter-settlement-operation/SupporterSettlementOperation.js new file mode 100644 index 0000000..779744d --- /dev/null +++ b/src/features/supporter/components/supporter-settlement-operation/SupporterSettlementOperation.js @@ -0,0 +1,62 @@ +import { IconButton } from "@mui/material"; +import { Grid } from "../../../../components/grid/Grid"; +import { useDispatch } from "react-redux"; +import { DRAWER } from "../../../../lib/redux/slices/appSlice"; +import { useState } from "react"; +// import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl"; +import TuneIcon from "@mui/icons-material/Tune"; + +import SupporterSettlementModal from "../supporter-settlement-modal/SupporterSettlemetModal"; + +export const SupporterSettlementOperation = ({ + item, + item_key, + updateTable_data, +}) => { + const dispatch = useDispatch(); + + const [anchorEl, setAnchorEl] = useState(null); + + const handleClick = (event) => { + setAnchorEl(event.currentTarget); + }; + + const handleClose = () => { + setAnchorEl(null); + }; + + const open = Boolean(anchorEl); + const id = open ? "popover" : undefined; + + return ( + + + { + handleClose(); + dispatch( + DRAWER({ + title: "بارگزاری سند", + top: !(window.innerWidth <= 600), + bottom: window.innerWidth <= 600, + size: 1000, + content: ( + + ), + }) + ); + }} + /> + + + ); +}; diff --git a/src/features/supporter/services/AddCommentInSettlemetProvince.js b/src/features/supporter/services/AddCommentInSettlemetProvince.js new file mode 100644 index 0000000..4cf257d --- /dev/null +++ b/src/features/supporter/services/AddCommentInSettlemetProvince.js @@ -0,0 +1,18 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const AddCommentInSettlemetProvince = createAsyncThunk( + "ADD_COMMENT_IN_SETTLEMENT_PROVINCE", + async (d, { dispatch }) => { + try { + dispatch(LOADING_START()); + const { data, status } = await axios.put("direct-buying-payment/0/", d); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e.response.data.result }; + } + } +); diff --git a/src/features/ticket/components/create-ticket/CreateTicket.js b/src/features/ticket/components/create-ticket/CreateTicket.js new file mode 100644 index 0000000..bd30b02 --- /dev/null +++ b/src/features/ticket/components/create-ticket/CreateTicket.js @@ -0,0 +1,572 @@ +import { useContext, useEffect, useState } from "react"; +import useUserProfile from "../../../authentication/hooks/useUserProfile"; +import { useFormik } from "formik"; +import { Yup } from "../../../../lib/yup/yup"; +import { fixBase64 } from "../../../../utils/toBase64"; +import { Grid } from "../../../../components/grid/Grid"; +import { + Autocomplete, + Button, + Checkbox, + FormControl, + FormControlLabel, + InputLabel, + MenuItem, + // Paper, + Select, + TextField, + Typography, + Chip, + Box, + Stack, +} from "@mui/material"; +// import LaunchIcon from "@mui/icons-material/Launch"; +// import SettingsSuggestIcon from "@mui/icons-material/SettingsSuggest"; +// import MarkAsUnreadIcon from "@mui/icons-material/MarkAsUnread"; +import { ImageUpload } from "../../../../components/image-upload/ImageUpload"; +import { getFaUserRole } from "../../../../utils/getFaUserRole"; +import { useDispatch } from "react-redux"; +import { + getTicketPermission, + getTicketUsersFromRole, +} from "../../services/get-ticket-permission"; +import { AppContext } from "../../../../contexts/AppContext"; +import { CreateTicketService } from "../../services/create-ticket"; +import { sendResponseTicketService } from "../../services/send-response"; +import { useNavigate } from "react-router-dom"; +import CloudUploadIcon from "@mui/icons-material/CloudUpload"; +import DeleteIcon from "@mui/icons-material/Delete"; +// import MoreHorizIcon from "@mui/icons-material/MoreHoriz"; +import { styled } from "@mui/material/styles"; + +const VisuallyHiddenInput = styled("input")({ + clip: "rect(0 0 0 0)", + clipPath: "inset(50%)", + height: 1, + overflow: "hidden", + position: "absolute", + bottom: 0, + left: 0, + whiteSpace: "nowrap", + width: 1, +}); + +export const CreateTicket = ({ id, getMessages, fetchMessages }) => { + // const ticketTypes = [ + // { + // title: "درخواست از مدیر", + // icon: , + // color: "#797979", + // }, + // { + // title: "مشکلات فنی", + // icon: , + // color: "#797979", + // }, + // { + // title: "پیشنهاد و انتقاد", + // icon: , + // color: "#797979", + // }, + // ]; + + const isAdmin = () => { + if ( + selectedRole === "CityOperator" || + selectedRole === "ProvinceOperator" || + selectedRole === "AdminX" || + selectedRole === "Supporter" || + selectedRole === "SuperAdmin" + ) { + return true; + } else { + return false; + } + }; + const [role] = useUserProfile(); + const [selectedRole, setSelectedRole] = useState(role[0]); + const [value, setValue] = useState(isAdmin() ? "toRole" : "toUser"); + const [openNotif] = useContext(AppContext); + const navigate = useNavigate(); + + // const handleChangeRadioButton = (event) => { + // formik.setFieldValue("roles", []); + // setValue(event.target.value); + // }; + + const dispatch = useDispatch(); + const handleRoleChange = (event) => { + setSelectedRole(event.target.value); + }; + + const [isChecked, setChecked] = useState(false); + + const handleCheckboxChange = () => { + setChecked(!isChecked); + }; + + const handleFileUpload = (event) => { + const file = event.target.files[0]; + if (file) { + formik.setFieldValue("uploadedFile", file); + } + }; + + const handleDeleteFile = () => { + formik.setFieldValue("uploadedFile", null); + }; + + const formik = useFormik({ + initialValues: { + title: "", + text: "", + users: [], + roles: [], + image: "", + uploadedFile: null, + }, + validationSchema: Yup.object({ + title: Yup.string().required("عنوان تیکت ضروری است"), + text: Yup.string().required("متن تیکت ضروری است"), + }), + onSubmit: (values) => { + // console.log(values); + }, + }); + + useEffect(() => { + formik.validateForm(); + }, []); + + useEffect(() => { + if (!isAdmin()) { + setValue("toUser"); + } + }, [value, selectedRole]); + + const [profileImages, setProfileImages] = useState([]); + + const factorPaymentHandler = (imageList, addUpdateIndex) => { + if (imageList[0]) { + formik.setFieldValue("image", fixBase64(imageList[0]?.data_url)); + } + setProfileImages(imageList); + }; + + const [permissionList, setPermissionList] = useState([]); + const [users, setUsers] = useState([]); + + useEffect(() => { + dispatch(getTicketPermission({ role: selectedRole })).then((r) => { + setPermissionList(r.payload.data); + }); + }, [selectedRole]); + useEffect(() => { + if (formik.values.roles.length && value === "toUser") { + dispatch(getTicketUsersFromRole({ role: formik.values.roles })).then( + (r) => { + setUsers(r.payload.data); + } + ); + } else { + setUsers([]); + } + }, [formik.values.roles, value]); + + const handleCheckboxChangeToRole = (event) => { + if (event.target.checked) { + setValue("toRole"); + formik.setFieldValue("users", []); + formik.setFieldValue("roles", []); + } + }; + + const handleCheckboxChangeToUser = (event) => { + if (event.target.checked) { + setValue("toUser"); + formik.setFieldValue("roles", []); + formik.setFieldValue("users", []); + } + }; + + return ( + + {/* + *": { width: "100px", height: "120px", flex: "0 0 auto" }, + }} + > + {ticketTypes.map((item) => ( + + + {item.icon} + + + {item.title} + + + ))} + + */} + {isNaN(id) && ( + + + + + } + label="ارسال به نقش" + /> + + } + label="ارسال به اشخاص" + /> + + + + {permissionList?.roles?.length && + (value === "toRole" ? isAdmin() : true) ? ( + + + انتخاب نقش + + + + ) : ( + + نقش انتخابی اجازه ارسال تیکت ندارد! + + )} + + {value === "toUser" && ( + <> + {users?.length ? ( + + option.fullname} + onChange={(event, value) => { + formik.setFieldValue("users", value); + }} + renderInput={(params) => ( + + )} + /> + + ) : ( + + موردی یافت نشد! + + )} + + )} + + )} + {role.length > 1 && isNaN(id) && ( + + + انتخاب نقش + + + + )} + + {isNaN(id) && ( + + + + )} + + + + + + + {formik.values.uploadedFile && ( + + } + variant="outlined" + /> + + حجم: {(formik.values.uploadedFile.size / 1024 / 1024).toFixed(2)}{" "} + MB + + + )} + {formik.values.uploadedFile?.size > 5 * 1024 * 1024 && ( + + حداکثر حجم مجاز جهت ارسال فایل 5 مگابایت است! + + )} + + + {isAdmin() && isNaN(id) && ( + + + } + label="فقط خواندنی" + /> + + )} + + + + + + + + ); +}; diff --git a/src/features/ticket/components/show-messages/ShowMissages.js b/src/features/ticket/components/show-messages/ShowMissages.js new file mode 100644 index 0000000..67282ac --- /dev/null +++ b/src/features/ticket/components/show-messages/ShowMissages.js @@ -0,0 +1,168 @@ +import React from "react"; +import { Button, Divider, Typography } from "@mui/material"; +import Tooltip, { tooltipClasses } from "@mui/material/Tooltip"; + +import { motion } from "framer-motion"; +import DoneAllIcon from "@mui/icons-material/DoneAll"; +import CheckIcon from "@mui/icons-material/Check"; +import ShowImage from "../../../../components/show-image/ShowImage"; +import persianDate from "persian-date"; +import { Grid } from "../../../../components/grid/Grid"; +import DownloadIcon from "@mui/icons-material/Download"; +import { styled } from "@mui/material/styles"; + +const containerVariants = { + hidden: { opacity: 0, y: 10 }, + visible: { opacity: 1, y: 0, transition: { duration: 0.3 } }, +}; + +const HtmlTooltip = styled(({ className, ...props }) => ( + +))(({ theme }) => ({ + [`& .${tooltipClasses.tooltip}`]: { + backgroundColor: "#f5f5f9", + color: "rgba(0, 0, 0, 0.87)", + maxWidth: 220, + fontSize: theme.typography.pxToRem(12), + border: "1px solid #dadde9", + }, +})); + +const formatMessage = (message) => { + if (!message) return ""; + + const formattedText = message.replace(/\*\*\*/g, "\n").trim(); + + const lines = formattedText.split("\n"); + + return lines.map((line, index) => ( + + {line} +
    +
    + )); +}; + +export const ShowMissages = ({ data }) => { + const isReffered = (item) => { + if ( + item?.message?.includes("ارجاع داده شد.") && + item?.message?.includes("تیکت شماره") + ) { + return true; + } else { + return false; + } + }; + + return ( + + {data?.map((item, i) => ( + + + + {item?.createdBy?.fullname} + + + + {`${new persianDate(new Date(item?.createdAt)).format( + "dddd DD MMMM" + )} (${new Date(item?.createdAt).toLocaleTimeString([], { + hour: "2-digit", + minute: "2-digit", + hour12: false, + })})`} + + {item?.lastSeen ? ( + + + بازدید شده توسط + + {item?.readBy?.map((item, i) => ( + + {item?.fullname} ({item?.mobile}) + + ))} + + } + > + + + ) : ( + + )} + + + + + + + {formatMessage(item?.message)} + + + {(item?.picture || item?.file) && ( + <> + + + + {item?.picture && ( + + )} + + {item?.file && ( + + )} + + + )} + + ))} + + ); +}; diff --git a/src/features/ticket/components/submit-reffer-ticket/SubmitRefferTicket.js b/src/features/ticket/components/submit-reffer-ticket/SubmitRefferTicket.js new file mode 100644 index 0000000..a90503b --- /dev/null +++ b/src/features/ticket/components/submit-reffer-ticket/SubmitRefferTicket.js @@ -0,0 +1,170 @@ +import React, { useContext, useEffect, useState } from "react"; +import useUserProfile from "../../../authentication/hooks/useUserProfile"; +import { Grid } from "../../../../components/grid/Grid"; +import { + Autocomplete, + Button, + FormControl, + InputLabel, + MenuItem, + Select, + TextField, + Typography, +} from "@mui/material"; +import { getFaUserRole } from "../../../../utils/getFaUserRole"; +import { Yup } from "../../../../lib/yup/yup"; +import { useFormik } from "formik"; +import { + getTicketPermission, + getTicketUsersFromRole, +} from "../../services/get-ticket-permission"; +import { useDispatch } from "react-redux"; +import { EditTicketService } from "../../services/create-ticket"; +import { AppContext } from "../../../../contexts/AppContext"; +import { CLOSE_MODAL } from "../../../../lib/redux/slices/appSlice"; +import { sortRoles } from "../../../../utils/sortRoles"; + +export const SubmitRefferTicket = ({ fetchMessages, ticket }) => { + const [role] = useUserProfile(); + const [openNotif] = useContext(AppContext); + const [users, setUsers] = useState([]); + const dispatch = useDispatch(); + + const formik = useFormik({ + initialValues: { + users: "", + roles: [], + }, + validationSchema: Yup.object({ + users: Yup.array().required("حداقل یک کاربر انتخاب کنید!"), + }), + onSubmit: (values) => { + // console.log(values); + }, + }); + + const [permissionList, setPermissionList] = useState([]); + + useEffect(() => { + dispatch(getTicketPermission({ role: sortRoles(role)[0] })).then((r) => { + setPermissionList(r.payload.data); + }); + }, []); + + useEffect(() => { + if (formik.values.roles.length) { + dispatch(getTicketUsersFromRole({ role: formik.values.roles })).then( + (r) => { + setUsers(r.payload.data); + } + ); + } + }, [formik.values.roles]); + + useEffect(() => { + formik.validateForm(); + }, [dispatch]); + + return ( + + + {permissionList?.roles?.length ? ( + + + انتخاب نقش + + + + ) : ( + + نقش انتخابی اجازه ارسال تیکت ندارد! + + )} + + + + {users?.length ? ( + + + `${option.fullname || "-"} (${option.mobile})` + } + onChange={(event, value) => { + formik.setFieldValue("users", value); + }} + renderInput={(params) => ( + + )} + /> + + ) : ( + + موردی یافت نشد! + + )} + + + + ); +}; diff --git a/src/features/ticket/components/ticket-all-view/TicketAllView.js b/src/features/ticket/components/ticket-all-view/TicketAllView.js new file mode 100644 index 0000000..f4dbe30 --- /dev/null +++ b/src/features/ticket/components/ticket-all-view/TicketAllView.js @@ -0,0 +1,28 @@ +import React, { useState } from "react"; +import { Grid } from "../../../../components/grid/Grid"; +import { Tab, Tabs } from "@mui/material"; +import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl"; + +export const TicketAllView = () => { + const [value, setValue] = useState("0"); + + const handleChange = (event, newValue) => { + setValue(newValue); + }; + return ( + + {(getRoleFromUrl() === "AdminX" || + getRoleFromUrl() === "SuperAdmin" || + getRoleFromUrl() === "ProvinceOperator") && ( + + + + + )} + + ); +}; diff --git a/src/features/ticket/components/ticket-create/TicketCreate.js b/src/features/ticket/components/ticket-create/TicketCreate.js new file mode 100644 index 0000000..28abdc7 --- /dev/null +++ b/src/features/ticket/components/ticket-create/TicketCreate.js @@ -0,0 +1,166 @@ +import { + Button, + FormControl, + InputLabel, + MenuItem, + Select, + TextField, +} from "@mui/material"; +import { useFormik } from "formik"; +import { useContext, useEffect, useState } from "react"; +import { useDispatch } from "react-redux"; +import { Grid } from "../../../../components/grid/Grid"; +import { ImageUpload } from "../../../../components/image-upload/ImageUpload"; +import { AppContext } from "../../../../contexts/AppContext"; +import { SPACING } from "../../../../data/spacing"; +import { + DRAWER, + LOADING_END, + LOADING_START, +} from "../../../../lib/redux/slices/appSlice"; +import { Yup } from "../../../../lib/yup/yup"; +import { fixBase64 } from "../../../../utils/toBase64"; +import { ticketCreateTicket } from "../../services/ticket-create-ticket"; +import { ticketGetCreatedTickets } from "../../services/ticket-get-created-tickets"; + +export const TicketCreate = () => { + const dispatch = useDispatch(); + const [openNotif] = useContext(AppContext); + const formik = useFormik({ + initialValues: { + title: "", + supportUnit: "", + content: "", + image: [], + }, + validationSchema: Yup.object({ + title: Yup.string().required("این فیلد اجباری است!"), + supportUnit: Yup.string().required("این فیلد اجباری است!"), + content: Yup.string().required("این فیلد اجباری است!"), + }), + }); + + useEffect(() => { + formik.validateForm(); + }, []); + + const [attachmentImages, setAttachmentImages] = useState([]); + + const attachmentsHandler = (imageList, addUpdateIndex) => { + const base64Urls = imageList.map((image) => fixBase64(image.data_url)); + formik.setFieldValue("image", base64Urls); + setAttachmentImages(imageList); + }; + + return ( + + + + + + + + واحد مربوطه + + + + + + + + + + + + + ); +}; diff --git a/src/features/ticket/components/ticket-customer-item/TicketCustomerItem.js b/src/features/ticket/components/ticket-customer-item/TicketCustomerItem.js new file mode 100644 index 0000000..edfa3d6 --- /dev/null +++ b/src/features/ticket/components/ticket-customer-item/TicketCustomerItem.js @@ -0,0 +1,79 @@ +import { + TimelineConnector, + TimelineContent, + TimelineDot, + TimelineItem, + TimelineSeparator, +} from "@mui/lab"; +import { Typography } from "@mui/material"; +import { PropTypes } from "prop-types"; +import { Grid } from "../../../../components/grid/Grid"; +import { SPACING } from "../../../../data/spacing"; +import { formatTime } from "../../../../utils/formatTime"; +import QuestionMarkIcon from "@mui/icons-material/QuestionMark"; + +export const TicketCustomerItem = ({ item }) => { + return ( + + + + + + + + + + + + {item.title} + + - + prop.palette.grey["A700"]} + > + {formatTime(item.createDate)} + + + + + + + {item.content} + + {Boolean(item.image?.length) && ( + <> + + prop.palette.grey["A700"]} + > + پیوست ها + + + + {item.image.map((img, i) => { + return ( + + ticket + + ); + })} + + + )} + + + + + ); +}; + +TicketCustomerItem.propTypes = { + item: PropTypes.any, +}; diff --git a/src/features/ticket/components/ticket-operator-item/TicketOperatorItem.js b/src/features/ticket/components/ticket-operator-item/TicketOperatorItem.js new file mode 100644 index 0000000..ee8804c --- /dev/null +++ b/src/features/ticket/components/ticket-operator-item/TicketOperatorItem.js @@ -0,0 +1,79 @@ +import { + TimelineConnector, + TimelineContent, + TimelineDot, + TimelineItem, + TimelineSeparator, +} from "@mui/lab"; +import { Typography } from "@mui/material"; +import { PropTypes } from "prop-types"; +import { Grid } from "../../../../components/grid/Grid"; +import { SPACING } from "../../../../data/spacing"; +import { formatTime } from "../../../../utils/formatTime"; +import SupportAgentIcon from "@mui/icons-material/SupportAgent"; + +export const TicketOperatorItem = ({ item }) => { + return ( + + + + + + + + + + + + {item.title} + + - + prop.palette.grey["A700"]} + > + {formatTime(item.createDate)} + + + + + + + {item.content} + + {Boolean(item.image?.length) && ( + <> + + prop.palette.grey["A700"]} + > + پیوست ها + + + + {item.image.map((img, i) => { + return ( + + ticket + + ); + })} + + + )} + + + + + ); +}; + +TicketOperatorItem.propTypes = { + item: PropTypes.any, +}; diff --git a/src/features/ticket/components/ticket-respond/TicketRespond.js b/src/features/ticket/components/ticket-respond/TicketRespond.js new file mode 100644 index 0000000..8784dcb --- /dev/null +++ b/src/features/ticket/components/ticket-respond/TicketRespond.js @@ -0,0 +1,157 @@ +import { Button, TextField } from "@mui/material"; +import { useFormik } from "formik"; +import { Grid } from "../../../../components/grid/Grid"; +import { Yup } from "../../../../lib/yup/yup"; +import { PropTypes } from "prop-types"; +import { SPACING } from "../../../../data/spacing"; +import { useContext, useEffect, useState } from "react"; +import { fixBase64 } from "../../../../utils/toBase64"; +import { + DRAWER, + LOADING_END, + LOADING_START, +} from "../../../../lib/redux/slices/appSlice"; +import { ticketRespondTicket } from "../../services/ticket-respond-ticket"; +import { useDispatch } from "react-redux"; +import { AppContext } from "../../../../contexts/AppContext"; +import { ImageUpload } from "../../../../components/image-upload/ImageUpload"; +import { ticketCreateTicket } from "../../services/ticket-create-ticket"; +import { ticketGetCreatedTickets } from "../../services/ticket-get-created-tickets"; +import { ticketGetOperatorTickets } from "../../services/ticket-get-operator-tickets"; + +export const TicketRespond = ({ + ticketKey, + questionKey, + customer, + supportUnit, +}) => { + const [openNotif] = useContext(AppContext); + const dispatch = useDispatch(); + const formik = useFormik({ + initialValues: { + content: "", + title: "", + image: [], + }, + validationSchema: Yup.object({ + content: Yup.string().required("این فیلد اجباری است!"), + title: Yup.string().required("این فیلد اجباری است!"), + }), + }); + + useEffect(() => { + formik.validateForm(); + }, []); + + const [attachmentImages, setAttachmentImages] = useState([]); + const attachmentsHandler = (imageList, addUpdateIndex) => { + const base64Urls = imageList.map((image) => fixBase64(image.data_url)); + formik.setFieldValue("image", base64Urls); + setAttachmentImages(imageList); + }; + + return ( + + + + + + + + + + + + + + + ); +}; + +TicketRespond.propTypes = { + ticketKey: PropTypes.any, + questionKey: PropTypes.any, + customer: PropTypes.any, + supportUnit: PropTypes.any, +}; diff --git a/src/features/ticket/components/ticket-view/TicketView.js b/src/features/ticket/components/ticket-view/TicketView.js new file mode 100644 index 0000000..028b2cc --- /dev/null +++ b/src/features/ticket/components/ticket-view/TicketView.js @@ -0,0 +1,187 @@ +import React, { useEffect, useState } from "react"; +import { Grid } from "../../../../components/grid/Grid"; +import { BackButton } from "../../../../components/back-button/BackButton"; +import { useParams } from "react-router-dom"; +import { CreateTicket } from "../create-ticket/CreateTicket"; +import { ShowMissages } from "../show-messages/ShowMissages"; +import { useDispatch } from "react-redux"; +import { getMessagesService } from "../../services/get-messages"; +import { Button, Typography } from "@mui/material"; +import { formatJustDate } from "../../../../utils/formatTime"; +import ForwardToInboxIcon from "@mui/icons-material/ForwardToInbox"; +import { OPEN_MODAL } from "../../../../lib/redux/slices/appSlice"; +import { SubmitRefferTicket } from "../submit-reffer-ticket/SubmitRefferTicket"; + +export const TicketView = () => { + const { create, id } = useParams(); + const dispatch = useDispatch(); + const [data, setData] = useState(); + const [canSeeMessages, setCanSeeMessages] = useState(); + const fetchMessages = () => { + dispatch(getMessagesService({ ticket: id })).then((r) => { + setData(r.payload.data); + }); + }; + + useEffect(() => { + let intervalId; + + if (create === "false") { + fetchMessages(); + intervalId = setInterval(fetchMessages, 3000); + } + + return () => { + if (intervalId) { + clearInterval(intervalId); + } + }; + }, [dispatch, id, create]); + + useEffect(() => { + if (data?.length) { + if ( + data[0]?.ticket?.readOnly === true || + data[0]?.ticket?.status === "closed" + ) { + setCanSeeMessages(false); + } + } else { + setCanSeeMessages(true); + } + }, [data]); + + const isReffered = (data) => { + if (data) { + if ( + data.some( + (item) => + item.message?.includes("ارجاع داده شد.") && + item?.message?.includes("تیکت شماره") + ) + ) { + return true; + } else { + return false; + } + } + }; + + return ( + + + + + + {data && ( + + + عنوان: {"‌‌"} + {data[0]?.ticket?.title} + + + تاریخ ایجاد: {"‌‌"} + + {formatJustDate(data[0]?.ticket?.createDate)} + + + + وضعیت تیکت: {"‌‌"} + + {data[0]?.ticket?.status === "open" + ? "باز" + : data[0]?.ticket?.status === "answered" + ? "باز" + : "بسته"} + {isReffered(data) && " (ارجاع داده شده) "} + {data[0]?.ticket?.readOnly && "(فقط خواندنی)"} + + + {Object.prototype.hasOwnProperty.call(data[0], "readBy") && ( + + + + )} + {/* + دریافت کنندگان: {"‌‌"} + + {data[0]?.ticket?.toUser.length + ? data[0]?.ticket?.toUser?.map( + (option, index) => + `${option?.fullname} ${ + index + 1 !== data[0]?.ticket?.toUser?.length + ? " - " + : "" + }` + ) + : data[0]?.ticket?.toRole?.map( + (option, index) => + `${getFaUserRole(option.name)} ${ + index + 1 !== data[0]?.ticket?.toRole?.length + ? " - " + : "" + }` + )} + + */} + + )} + + {canSeeMessages && ( + + + + )} + {create === "false" && ( + + + + )} + + ); +}; diff --git a/src/features/ticket/services/create-ticket.js b/src/features/ticket/services/create-ticket.js new file mode 100644 index 0000000..509472f --- /dev/null +++ b/src/features/ticket/services/create-ticket.js @@ -0,0 +1,44 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const CreateTicketService = createAsyncThunk( + "CREATE_TICKET", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + + try { + const { data, status } = await axios.post("ticket/", d); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e.response.data.result }; + } + } +); + +export const CloseTicketService = createAsyncThunk( + "CLOSE_TICKET", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + const { data, status } = await axios.put("ticket/0/", d); + dispatch(LOADING_END()); + return { data, status }; + } +); + +export const EditTicketService = createAsyncThunk( + "EDIT_TICKET", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + try { + const { data, status } = await axios.put("ticket/0/", d); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e.response.data.result }; + } + } +); diff --git a/src/features/ticket/services/get-messages.js b/src/features/ticket/services/get-messages.js new file mode 100644 index 0000000..aa1f1c2 --- /dev/null +++ b/src/features/ticket/services/get-messages.js @@ -0,0 +1,14 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; + +export const getMessagesService = createAsyncThunk( + "GET_MESSAGES", + async (d, { dispatch }) => { + const { data, status } = await axios.get(`message/`, { + params: { + ticket: d.ticket, + }, + }); + return { data, status }; + } +); diff --git a/src/features/ticket/services/get-ticket-permission.js b/src/features/ticket/services/get-ticket-permission.js new file mode 100644 index 0000000..4444a65 --- /dev/null +++ b/src/features/ticket/services/get-ticket-permission.js @@ -0,0 +1,34 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const getTicketPermission = createAsyncThunk( + "GET_TICKET_PERMISSION", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + const { data, status } = await axios.get(`ticket-permission/`, { + params: { + role: d.role, + }, + }); + dispatch(LOADING_END()); + return { data, status }; + } +); + +export const getTicketUsersFromRole = createAsyncThunk( + "GET_TICKET_USERS_FROM_ROLE", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + + const roles = Array.isArray(d.role) ? d.role.join(",") : d.role; + + const { data, status } = await axios.get(`get-user-from-role/`, { + params: { + role: roles, + }, + }); + dispatch(LOADING_END()); + return { data, status }; + } +); diff --git a/src/features/ticket/services/send-response.js b/src/features/ticket/services/send-response.js new file mode 100644 index 0000000..bfa7a2c --- /dev/null +++ b/src/features/ticket/services/send-response.js @@ -0,0 +1,13 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const sendResponseTicketService = createAsyncThunk( + "RESPONSE_TICKET", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + const { data, status } = await axios.post("message/", d); + dispatch(LOADING_END()); + return { data, status }; + } +); diff --git a/src/features/ticket/services/ticket-close-ticket.js b/src/features/ticket/services/ticket-close-ticket.js new file mode 100644 index 0000000..100cc4b --- /dev/null +++ b/src/features/ticket/services/ticket-close-ticket.js @@ -0,0 +1,10 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; + +export const ticketCloseTicket = createAsyncThunk( + "TICKET_CLOSE_TICKET", + async (d) => { + const { data, status } = await axios.put("/create_ticket/0/", d); + return { data, status }; + } +); diff --git a/src/features/ticket/services/ticket-create-ticket.js b/src/features/ticket/services/ticket-create-ticket.js new file mode 100644 index 0000000..858eedd --- /dev/null +++ b/src/features/ticket/services/ticket-create-ticket.js @@ -0,0 +1,10 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; + +export const ticketCreateTicket = createAsyncThunk( + "TICKET_CREATE_TICKET", + async (d) => { + const { data, status } = await axios.post("/create_ticket/", d); + return { data, status }; + } +); diff --git a/src/features/ticket/services/ticket-get-created-tickets.js b/src/features/ticket/services/ticket-get-created-tickets.js new file mode 100644 index 0000000..ed8cb73 --- /dev/null +++ b/src/features/ticket/services/ticket-get-created-tickets.js @@ -0,0 +1,12 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; + +export const ticketGetCreatedTickets = createAsyncThunk( + "TICKET_GET_CREATED_TICKETS", + async () => { + const { data, status } = await axios.get("/create_ticket/", { + params: { all: true }, + }); + return { data, status }; + } +); diff --git a/src/features/ticket/services/ticket-get-operator-tickets.js b/src/features/ticket/services/ticket-get-operator-tickets.js new file mode 100644 index 0000000..39f8b65 --- /dev/null +++ b/src/features/ticket/services/ticket-get-operator-tickets.js @@ -0,0 +1,12 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; + +export const ticketGetOperatorTickets = createAsyncThunk( + "TICKET_GET_OPERATOR_TICKETS", + async () => { + const { data, status } = await axios.get("/respond/", { + params: { all: true }, + }); + return { data, status }; + } +); diff --git a/src/features/ticket/services/ticket-respond-ticket.js b/src/features/ticket/services/ticket-respond-ticket.js new file mode 100644 index 0000000..acb1c69 --- /dev/null +++ b/src/features/ticket/services/ticket-respond-ticket.js @@ -0,0 +1,10 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; + +export const ticketRespondTicket = createAsyncThunk( + "TICKET_RESPOND_TICKET", + async (d) => { + const { data, status } = await axios.post("/respond/", d); + return { data, status }; + } +); diff --git a/src/features/vet-farm/components/parent-company-sale-out-of-province/ParentCompanyOutOfProvince.js b/src/features/vet-farm/components/parent-company-sale-out-of-province/ParentCompanyOutOfProvince.js new file mode 100644 index 0000000..cbacb94 --- /dev/null +++ b/src/features/vet-farm/components/parent-company-sale-out-of-province/ParentCompanyOutOfProvince.js @@ -0,0 +1,517 @@ +import React, { useContext, useEffect, useState } from "react"; +import { Button, TextField, Tooltip, Typography } from "@mui/material"; +import { DatePicker } from "@mui/x-date-pickers"; +import moment from "moment"; +import axios from "axios"; +import { RiFileExcel2Fill, RiSearchLine } from "react-icons/ri"; +import { useDispatch, useSelector } from "react-redux"; +import { Grid } from "../../../../components/grid/Grid"; +import { PageTable } from "../../../../components/page-table/PageTable"; +import { VetFarmSubmitClearanceCode } from "../vet-farm-submit-clearance-code/VetFarmSubmitClearanceCode"; +import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl"; +import { VetFarmEditOutOfProvinceTrafficCode } from "../vet-farm-edit-out-out-province-traffic-code/VetFarmEditOutOfProvinceTrafficCode"; +import { formatJustDate } from "../../../../utils/formatTime"; +import { AppContext } from "../../../../contexts/AppContext"; +import ResponsiveTable from "../../../../components/responsive-table/ResponsiveTable"; +import { vetFarmOutProvinceGetDashboard } from "../../services/vet-farm-out-province-get-dashboard"; + +export const ParentCompanyOutOfProvince = ({ readOnly, province }) => { + const [data, setData] = useState([]); + const [loading, setLoading] = useState(false); + const [totalRows, setTotalRows] = useState(0); + const [perPage, setPerPage] = useState(10); + const [textValue, setTextValue] = useState(""); + + const handleTextChange = (event) => { + setTextValue(event.target.value); + }; + const [, , selectedDate1, setSelectedDate1, selectedDate2, setSelectedDate2] = + useContext(AppContext); + + const fetchApiData = async (page, textValue) => { + setLoading(true); + const response = await axios.get( + `${province}parent-company-out-province-poultry-requests/?search=filter&value=${textValue}&page=${page}&role=${getRoleFromUrl()}&page_size=${perPage}&date1=${selectedDate1}&date2=${selectedDate2}&state=accepted` + ); + setData(response.data.results); + setTotalRows(response.data.count); + setLoading(false); + }; + + const handlePageChange = (page) => { + fetchApiData(page, textValue); + }; + + const handlePerRowsChange = async (newPerPage, page) => { + setLoading(true); + const response = await axios.get( + `${province}parent-company-out-province-poultry-requests/?search=filter&value=${textValue}&page=${page}&role=${getRoleFromUrl()}&page_size=${newPerPage}&date1=${selectedDate1}&date2=${selectedDate2}&state=accepted` + ); + + setData(response.data.results); + setTotalRows(response.data.count); + setPerPage(newPerPage); + + setLoading(false); + }; + + useEffect(() => { + fetchApiData(1); + }, []); + + const handleSubmit = async (event) => { + event.preventDefault(); + setLoading(true); + + try { + const response = await axios.get( + `${province}parent-company-out-province-poultry-requests/?search=filter&value=${textValue}&date1=${selectedDate1}&date2=${selectedDate2}&state=accepted&role=${getRoleFromUrl()}` + ); + setData(response.data.results); + setTotalRows(response.data.count); + } catch (error) { + console.error("Error fetching data:", error); + } finally { + setLoading(false); + } + }; + const userKey = useSelector((state) => state.userSlice.userProfile.key); + + useEffect(() => { + fetchApiData(1); + }, [selectedDate1, selectedDate2, province]); + + // const getBuyerType = (item) => { + // let buyerType = "-"; + // if (item.buyer.buyerType === "freezing") { + // buyerType = "انجماد"; + // } else if (item.buyer.buyerType === "killer") { + // buyerType = "کشتارکن"; + // } else if (item.buyer.buyerType === "killhouse") { + // buyerType = "کشتارگاه"; + // } + + // return buyerType; + // }; + + const columns = [ + { + name: "ردیف", + selector: (item, i) => i + 1, + sortable: true, + wrap: true, + allowOverflow: true, + center: true, + width: "60px", + }, + { + name: "وضعیت", + selector: (item) => ( + + {item.outState} + + ), + sortable: true, + wrap: true, + allowOverflow: true, + center: true, + // width: "80px", + }, + { + name: "ثبت کننده سفارش", + selector: (item, i) => { + return `${item?.registrar?.fullname}`; + }, + sortable: false, + wrap: true, + allowOverflow: true, + center: true, + }, + { + name: "کد سفارش", + selector: (item) => item.orderCode, + sortable: true, + wrap: true, + allowOverflow: true, + center: true, + // width: "80px", + }, + { + name: "اطلاعات خریدار", + selector: (item) => + item.buyer?.firstName + ? `${item.buyer?.firstName} ${item.buyer?.lastName} (${item.buyer?.mobile}) / ${item.buyer.province} - ${item.buyer.city}` + : `${item.buyerFullname} (${item.buyerMobile}) / ${item.buyerProvince} - ${item.buyerCity}`, + sortable: true, + wrap: true, + allowOverflow: true, + center: true, + // width: "80px", + }, + { + name: "پرداخت کننده", + selector: (item) => (item?.hasWage ? item?.payerFullname : "-"), + sortable: true, + wrap: true, + allowOverflow: true, + center: true, + // width: "80px", + }, + { + name: "مرغدار", + selector: (item) => + `${item.poultry?.unitName} (${item.poultry.user.mobile})`, + sortable: true, + wrap: true, + allowOverflow: true, + center: true, + // width: "80px", + }, + { + name: "میانگین وزن (کیلوگرم)", + selector: (item) => item.IndexWeight?.toLocaleString(), + sortable: true, + wrap: true, + allowOverflow: true, + center: true, + // width: "80px", + }, + { + name: "تعداد", + selector: (item) => item.quantity.toLocaleString(), + sortable: true, + wrap: true, + allowOverflow: true, + center: true, + // width: "80px", + }, + { + name: "وزن کل (کیلوگرم)", + selector: (item) => + Math.floor(item.IndexWeight * item.quantity)?.toLocaleString(), + sortable: true, + wrap: true, + allowOverflow: true, + center: true, + // width: "80px", + }, + { + name: "ثبت کد قرنطینه", + selector: (item) => ( + + ), + sortable: true, + wrap: true, + allowOverflow: true, + center: true, + width: "140px", + }, + { + name: "کد بهداشتی ماشین", + selector: (item) => + readOnly ? ( + item?.outProvinceDriverInfo?.driverhealthCode + ) : ( + + ), + sortable: true, + wrap: true, + allowOverflow: true, + center: true, + width: "140px", + }, + { + name: "نوع خودرو", + selector: (item) => + item?.outProvinceDriverInfo?.driverCar + ? item?.outProvinceDriverInfo?.driverCar + : "-", + sortable: true, + wrap: true, + allowOverflow: true, + center: true, + // width: "80px", + }, + { + name: "پلاک", + selector: (item) => + item?.outProvinceDriverInfo?.driverPelak + ? item?.outProvinceDriverInfo?.driverPelak + : "-", + sortable: true, + wrap: true, + allowOverflow: true, + center: true, + // width: "80px", + }, + { + name: "نام راننده", + selector: (item) => + item?.outProvinceDriverInfo?.driverName + ? item?.outProvinceDriverInfo?.driverName + : "-", + sortable: true, + wrap: true, + allowOverflow: true, + center: true, + // width: "80px", + }, + { + name: "تلفن راننده", + selector: (item) => + item?.outProvinceDriverInfo?.driverMobile + ? item?.outProvinceDriverInfo?.driverMobile + : "-", + sortable: true, + wrap: true, + allowOverflow: true, + center: true, + // width: "80px", + }, + { + name: "تاریخ ثبت درخواست", + selector: (item) => formatJustDate(item.createDate), + sortable: true, + wrap: true, + allowOverflow: true, + center: true, + // width: "80px", + }, + { + name: "تاریخ کشتار", + selector: (item) => formatJustDate(item.sendDate), + sortable: true, + wrap: true, + allowOverflow: true, + center: true, + // width: "80px", + }, + { + name: "سن مرغ", + selector: (item) => item.hatching.age, + sortable: true, + wrap: true, + allowOverflow: true, + center: true, + // width: "80px", + }, + + { + name: "نوع کشتار", + selector: (item) => (item?.freezing ? "انجماد" : "عادی"), + sortable: true, + wrap: true, + allowOverflow: true, + center: true, + // width: "80px", + }, + { + name: "تعرفه", + selector: (item) => (item?.hasWage ? "دارد" : "ندارد"), + sortable: true, + wrap: true, + allowOverflow: true, + center: true, + // width: "80px", + }, + { + name: "شهر", + selector: (item) => item.hatching?.city, + sortable: true, + wrap: true, + allowOverflow: true, + center: true, + // width: "80px", + }, + { + name: "استان", + selector: (item) => item.hatching?.province, + sortable: true, + wrap: true, + allowOverflow: true, + center: true, + // width: "80px", + }, + + { + name: "مانده در سالن", + selector: (item) => item.hatching.leftOver?.toLocaleString(), + sortable: true, + wrap: true, + allowOverflow: true, + center: true, + // width: "80px", + }, + { + name: "جوجه ریزی اولیه", + selector: (item) => item.hatching.hatchingQuantity?.toLocaleString(), + sortable: true, + wrap: true, + allowOverflow: true, + center: true, + // width: "80px", + }, + + // { + // name: "ماهیت خریدار", + // selector: (item) => getBuyerType(item), + // sortable: true, + // wrap: true, + // allowOverflow: true, + // center: true, + // // width: "80px", + // }, + + // { + // name: "عملیات", + // selector: (item) => item?.outProvinceDriverInfo?.driverhealthCode, + // sortable: true, + // wrap: true, + // allowOverflow: true, + // center: true, + // // width: "80px", + // }, + ]; + + const dispatch = useDispatch(); + + const [dashboardData, setDashboardData] = useState([]); + + useEffect(() => { + dispatch( + vetFarmOutProvinceGetDashboard({ + selectedDate1, + selectedDate2, + text: textValue, + province, + }) + ).then((r) => { + setDashboardData(r.payload.data); + }); + }, [selectedDate1, selectedDate2, province]); + + return ( + + + + + درخواست های فروش خارج از استان + + + + ( + + )} + value={selectedDate1} + onChange={(e) => { + setSelectedDate1(moment(e).format("YYYY-MM-DD")); + }} + /> + + + ( + + )} + value={selectedDate2} + onChange={(e) => { + setSelectedDate2(moment(e).format("YYYY-MM-DD")); + }} + /> + +
    + + + + + + + + + + +
    + + + + + + + + +
    + ); +}; diff --git a/src/features/vet-farm/components/parent-company-vet-farm-operation/ParentCompanyVetFarmOperation.js b/src/features/vet-farm/components/parent-company-vet-farm-operation/ParentCompanyVetFarmOperation.js new file mode 100644 index 0000000..b760af3 --- /dev/null +++ b/src/features/vet-farm/components/parent-company-vet-farm-operation/ParentCompanyVetFarmOperation.js @@ -0,0 +1,1053 @@ +import { + Button, + Checkbox, + FormControlLabel, + IconButton, + Tab, + Tabs, + TextField, + Tooltip, + Typography, +} from "@mui/material"; +import { format } from "date-fns-jalali"; +import { useContext, useEffect, useState } from "react"; +import { useDispatch, useSelector } from "react-redux"; +// import { AdvancedTable } from "../../../../components/advanced-table/AdvancedTable"; +import { Grid } from "../../../../components/grid/Grid"; +// import { vetFarmGetAllocatedService } from "../../services/vet-farm-get-allocated"; +import { VetFarmOperationRow } from "../vet-farm-operation-row/VetFarmOperationRow"; +import { DatePicker } from "@mui/x-date-pickers"; +import moment from "moment/moment"; +import { SPACING } from "../../../../data/spacing"; +import { AppContext } from "../../../../contexts/AppContext"; +import axios from "axios"; +import { RiFileExcel2Fill, RiSearchLine } from "react-icons/ri"; +import { + LOADING_END, + LOADING_START, + OPEN_MODAL, +} from "../../../../lib/redux/slices/appSlice"; +import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl"; +// import { getFaUserRole } from "../../../../utils/getFaUserRole"; +import { VetFarmSubmitContradicts } from "../vet-farm-submit-contradicts/VetFarmSubmitContradicts"; +import { VetFarmEditTrafficCode } from "../vet-farm-edit-traffic-code/VetFarmEditTrafficCode"; +import { VetFarmEditQuarantineCodeState } from "../vet-farm-edit-quarantine-code-state/VetFarmEditQuarantineCodeState"; +import { formatTime } from "../../../../utils/formatTime"; +import { parentCompanyGetBarsOverview } from "../../services/vet-farm-get-bars-overview"; +import { ChainBarManagement } from "../../../province/components/chain-bar-management/ChainBarManagement"; +import ShowImage from "../../../../components/show-image/ShowImage"; +import ResponsiveTable from "../../../../components/responsive-table/ResponsiveTable"; +import Accordion from "@mui/material/Accordion"; +import AccordionSummary from "@mui/material/AccordionSummary"; +import AccordionDetails from "@mui/material/AccordionDetails"; +import ArrowDownwardIcon from "@mui/icons-material/ArrowDownward"; +import { VetFarmAggregateBars } from "../vet-farm-aggregate-bars/VetFarmAggregateBars"; +import { vetFarmDeleteAggregateBarService } from "../../services/vet-farm-delete-aggregate-bar"; +import RefreshIcon from "@mui/icons-material/Refresh"; +import { ParentCompanyOutOfProvince } from "../parent-company-sale-out-of-province/ParentCompanyOutOfProvince"; + +export const ParentCompanyVetFarmOperation = ({ province }) => { + const [, , selectedDate1, setSelectedDate1, selectedDate2, setSelectedDate2] = + useContext(AppContext); + const userInfo = useSelector((state) => state.userSlice); + const { parentCompanyBarsOverview } = useSelector( + (state) => state.vetFarmSlice + ); + + useEffect(() => { + const currentDate = moment(new Date()).format("YYYY-MM-DD"); + setSelectedDate1(currentDate); + setSelectedDate2(currentDate); + }, []); + // const { vetFarmGetDeletedBars } = useSelector((state) => state.vetFarmSlice); + + const [selectedTab, setSelectedTab] = useState(0); + + const handleTabChange = (event, newValue) => { + setSelectedTab(newValue); + }; + + const [hasDocumentState, setHasDocumentState] = useState(false); + const handleChangeDocumentState = () => { + setHasDocumentState(!hasDocumentState); + }; + + const dispatch = useDispatch(); + // const [dataTable, setDataTable] = useState([]); + // const [dataDeletedTable, setDataDeletedTable] = useState([]); + + const getItemState = (item) => { + let state = ""; + if (item.trash === true) { + state = "حذف شده"; + } else if (item?.wareHouseConfirmation) { + state = "ورود به انبار"; + } else if (item?.assignmentStateArchive !== "pending") { + state = "ثبت اطلاعات بار"; + } else { + if (item.vetState === "accepted") { + state = "تایید تخلیه"; + } else if (item.vetState === "pending") { + state = "در انتظار تخلیه"; + } + } + + return ( + + {state} + + ); + }; + + const [data, setData] = useState([]); + const [totalRows, setTotalRows] = useState(0); + const [perPage, setPerPage] = useState(10); + + const fetchApiData = async (page) => { + let response; + dispatch(LOADING_START()); + response = await axios.get( + `${province}parent_company_kill_house_request_bar_management/?check&search=filter&value=${textValue}&role=${getRoleFromUrl()}&date1=${selectedDate1}&date2=${selectedDate2}&page=${page}&page_size=${perPage}&without_quarantine_code_state=${hasDocumentState}` + ); + dispatch(LOADING_END()); + setData(response.data.results); + setTotalRows(response.data.count); + }; + + const [page, setPage] = useState(1); + const handlePageChange = (page) => { + fetchApiData(page); + setPage(page); + }; + + const handlePerRowsChange = (perRows) => { + setPerPage(perRows); + setPage(1); + }; + + const updateTable = () => { + fetchApiData(page !== 0 ? page : 1); + }; + + const aggregateStatus = false; + + useEffect(() => { + // dispatch(vetFarmGetAllocatedService({ selectedDate1, selectedDate2 })); + fetchApiData(page); + dispatch( + parentCompanyGetBarsOverview({ + selectedDate1, + selectedDate2, + textValue, + hasDocumentState, + province, + }) + ); + }, [selectedDate1, selectedDate2, hasDocumentState, perPage, province]); + + useEffect(() => { + fetchApiData(1); + }, []); + + const [tableData, setTableData] = useState([]); + const [aggregates, setAggregates] = useState([]); + + useEffect(() => { + const d = data?.map((item, i) => { + return [ + + {aggregateStatus?.allow && + (getRoleFromUrl() === "VetFarm" || + getRoleFromUrl() === "AdminX" || + getRoleFromUrl() === "SuperAdmin") && ( + + {item?.clearanceCode && item?.aggregateCode ? ( + + + option.aggregateCode === item?.aggregateCode + ).length < 3 + } + key={i} + onClick={() => { + dispatch( + vetFarmDeleteAggregateBarService({ + kill_house_request_key: item?.key, + }) + ).then((r) => { + if (r.payload.error) { + openNotif({ + vertical: "top", + horizontal: "center", + msg: r.payload.error, + severity: "error", + }); + } else { + setAggregates([]); + updateTable(); + openNotif({ + vertical: "top", + horizontal: "center", + msg: "عملیات با موفقیت انجام شد.", + severity: "success", + }); + } + }); + }} + > + + +
    + } + /> + ) : ( + option?.barCode === item?.barCode + ).length > 0 + } + onChange={() => { + if ( + aggregates.some( + (option) => option?.barCode === item?.barCode + ) + ) { + setAggregates( + aggregates.filter( + (option) => option?.barCode !== item?.barCode + ) + ); + } else { + if (item?.aggregateCode) { + setAggregates( + data?.filter( + (option) => + option?.aggregateCode === + item?.aggregateCode + ) + ); + } else { + setAggregates([...aggregates, item]); + } + } + }} + color="primary" + /> + } + /> + )} + + )} + {page === 1 ? i + 1 : i + (perPage * page) / 2 + 1} + , + item?.aggregateCode ? ( + + {" "} + { + if (aggregateValidationHasError()) { + openNotif({ + vertical: "top", + horizontal: "center", + msg: `فقط بارهای با خریدار و مرغدار یکسان و با مجموع تعداد حداکثر ${aggregateStatus?.limitation} میتوانید ادغام کنید!`, + severity: "error", + }); + } else { + dispatch( + OPEN_MODAL({ + title: "مشاهده بارهای ادغام شده", + content: ( + + option?.aggregateCode === item?.aggregateCode + )} + /> + ), + }) + ); + } + }} + > + دارد + + + ) : ( + ندارد + ), + getItemState(item), + + {item.barCode} + , + formatTime(item.createDate), + item?.poultryRequest?.freezing + ? "انجماد" + : item?.poultryRequest?.export + ? "صادرات" + : "عادی", + `${item.killhouseUser?.name} (${item.killhouseUser?.killHouseOperator?.user?.mobile})`, + item?.killer + ? `${item?.killer?.name} (${item?.killer?.killHouseOperator?.user?.mobile})` + : "-", + `${item.poultryRequest?.poultry?.user?.fullname} (${item.poultryRequest.poultry?.user?.mobile})`, + `${item.poultryRequest?.poultry?.unitName}`, + item.quantity?.toLocaleString(), + item?.weightInfo?.weight?.toLocaleString(), + , + , + <> + {item?.quarantineQuantity ? ( + + ) : ( + <> + {item?.quarantineCodeState && + (item?.quarantineCodeState === "contradiction" + ? "مغایرت کد رهگیری" + : item?.quarantineCodeState === "noclearance" + ? "فاقد کد رهگیری" + : item?.quarantineCodeState === "merge" + ? "ادغام" + : "عدم تایید راهداری")} + + {(getRoleFromUrl() === "ProvinceOperator" || + getRoleFromUrl() === "SuperAdmin" || + getRoleFromUrl() === "AdminX" || + getRoleFromUrl() === "Supporter") && ( + + )} + + )} + , + // item?.realAddCar?.driver + // ? `${item?.realAddCar?.driver?.typeCar} (${ + // item?.realAddCar?.driver?.pelak + // ? item?.realAddCar?.driver?.pelak + // : "نامشخص" + // })` + // : "-", + `${item.addCar.driver.typeCar} ${item.addCar.driver.pelak}`, + `${item.addCar.driver.driverName} (${item.addCar.driver.driverMobile})`, + item.poultryRequest.chickenBreed, + item?.weightInfo?.indexWeight?.toLocaleString(), + item?.poultryRequest?.amount?.toLocaleString() + " ﷼", + item?.weightInfo?.killHousePrice?.toLocaleString() + " ﷼", + item?.vetFarm?.vet?.user?.fullname + ? item?.vetFarm?.vet?.user?.fullname + + `(${item?.vetFarm?.vet?.user?.mobile})` + : "فاقد دامپزشک", + `${item.killPlace}`, + item.poultryRequest.poultry.address.city.name, + item?.poultryRequest.sendDate + ? format(new Date(item?.poultryRequest.sendDate), "yyyy/MM/dd") + : "-", + item?.poultryRequest.orderCode, + + {item?.barDocumentStatus?.title + ? item?.barDocumentStatus?.title + : "-"} + , + + , + item.acceptedRealQuantity?.toLocaleString(), + item?.acceptedRealWeight?.toLocaleString(), + item?.weightInfo?.finalIndexWeight?.toLocaleString(), + item?.wareHouseAcceptedRealQuantity?.toLocaleString(), + item?.wareHouseAcceptedRealWeight?.toLocaleString(), + item?.weightLoss?.toLocaleString(), + ]; + }); + + setTableData(d); + }, [data, aggregates]); + + const [openNotif] = useContext(AppContext); + + const handleDateChange1 = (date) => { + setSelectedDate1(date); + }; + + const handleDateChange2 = (date) => { + setSelectedDate2(date); + }; + + const [textValue, setTextValue] = useState(""); + + const handleTextChange = (event) => { + setTextValue(event.target.value); + }; + + const handleSubmit = async (event) => { + event.preventDefault(); + dispatch(LOADING_START()); + + try { + const response = await axios.get( + `${province}parent_company_kill_house_request_bar_management/?check&role=${getRoleFromUrl()}&search=filter&value=${textValue}&date1=${selectedDate1}&date2=${selectedDate2}&page=${1}&page_size=${perPage}&without_quarantine_code_state=${hasDocumentState}` + ); + setData(response.data.results); + setTotalRows(response.data.count); + dispatch(LOADING_END()); + } catch (error) { + console.error("Error fetching data:", error); + } + dispatch( + parentCompanyGetBarsOverview({ selectedDate1, selectedDate2, textValue }) + ); + }; + + useEffect(() => { + if (selectedTab === 0) { + fetchApiData(1); + } + }, [selectedDate1, selectedDate2, hasDocumentState, selectedTab]); + + const userKey = useSelector((state) => state.userSlice.userProfile.key); + + const tableTitle = ( + + + مدیریت بارها + + } + value={selectedDate1} + onChange={(e) => { + handleDateChange1(moment(e).format("YYYY-MM-DD")); + }} + /> + + + } + value={selectedDate2} + onChange={(e) => { + handleDateChange2(moment(e).format("YYYY-MM-DD")); + }} + /> + +
    + + + + + {(getRoleFromUrl() === "SuperAdmin" || + getRoleFromUrl() === "Supporter" || + getRoleFromUrl() === "AdminX") && ( + + } + label="بدون وضعیت قرنطینه" + /> + )} +
    + + + } + aria-controls="panel1-content" + id="panel1-header" + > + گزارش خروجی ها + + + + + + + {/* */} + + {/* */} + + + خروجی اکسل + + + {getRoleFromUrl() !== "VetFarm" && + getRoleFromUrl() !== "CityPoultry" && ( + + + {/* */} + + {/* */} + + گزارش جامع + + )} + + + + {/* */} + + {/* */} + + + پایش کشتارگاه + + + + + + {/* */} + + + + گزارش عملکرد کشتارگاه ها + + + + + + + {/* */} + + پایش بارها + + + + + +
    + ); + + let tabs = ( + + + + + + ); + + const aggregateValidationHasError = () => { + return ( + aggregates?.reduce((total, obj) => total + obj?.quantity, 0) > + aggregateStatus?.limitation || + !aggregates.every( + (obj) => + obj.poultryRequest?.poultry?.unitName === + aggregates[0]?.poultryRequest?.poultry?.unitName && + obj.killhouseUser?.name === aggregates[0]?.killhouseUser?.name + ) + ); + }; + + return ( + + + {tabs} + + {selectedTab === 0 && ( + + {tableTitle} + + + {parentCompanyBarsOverview?.lenKillRequest?.toLocaleString()} + , + + {parentCompanyBarsOverview?.killRequestQuantity?.toLocaleString()} + , + + {parentCompanyBarsOverview?.killRequestWeight?.toLocaleString()} + , + + {parentCompanyBarsOverview?.avgWeight} + , + + {parentCompanyBarsOverview?.minAge} + , + + {parentCompanyBarsOverview?.maxAge} + , + + {parentCompanyBarsOverview?.avgAge} + , + + {parentCompanyBarsOverview?.lenKillRequestHasCode?.toLocaleString()} + , + + {parentCompanyBarsOverview?.quantityOfKillRequestHasCode?.toLocaleString()} + , + + {parentCompanyBarsOverview?.lenKillRequestHasQuarantine?.toLocaleString()} + , + + {parentCompanyBarsOverview?.quantityOfKillRequestHasQuarantine?.toLocaleString()} + , + + {parentCompanyBarsOverview?.lenKillRequestHasNotCode?.toLocaleString()} + , + + {parentCompanyBarsOverview?.quantityOfKillRequestHasNotCode?.toLocaleString()} + , + + {parentCompanyBarsOverview?.differenceBar?.toLocaleString()} + , + + {parentCompanyBarsOverview?.lenCompleteWithKillHouse?.toLocaleString()} + , + + {parentCompanyBarsOverview?.quantityFinalKillHouse?.toLocaleString()} + , + + {parentCompanyBarsOverview?.weightFinalKillHouse?.toLocaleString()} + , + + {parentCompanyBarsOverview?.wareHouseBars?.toLocaleString()} + , + + {parentCompanyBarsOverview?.wareHouseBarsQuantity?.toLocaleString()} + , + + {parentCompanyBarsOverview?.wareHouseBarsWeight?.toLocaleString()} + , + + {parentCompanyBarsOverview?.wareHouseBarsWeightLose + ?.toFixed(2) + ?.toLocaleString()} + , + ], + ]} + /> + + + {aggregateStatus?.allow && + (getRoleFromUrl() === "VetFarm" || + getRoleFromUrl() === "AdminX" || + getRoleFromUrl() === "SuperAdmin") && ( + + + + )} + + + + )} + + {selectedTab === 4 && ( + + + + )} + + {selectedTab === 5 && } + + ); +}; + +// const DisabledWrap = ({ children, checked }) => { +// return {children}; +// }; diff --git a/src/features/vet-farm/components/ver-farm-profile/VetFarmProfile.js b/src/features/vet-farm/components/ver-farm-profile/VetFarmProfile.js new file mode 100644 index 0000000..7a15d0c --- /dev/null +++ b/src/features/vet-farm/components/ver-farm-profile/VetFarmProfile.js @@ -0,0 +1,59 @@ +import { Box } from "@mui/system"; +import { useEffect } from "react"; +import { useDispatch, useSelector } from "react-redux"; +import { Grid } from "../../../../components/grid/Grid"; +// import { SimpleTable } from "../../../../components/simple-table/SimpleTable"; +import { SPACING } from "../../../../data/spacing"; +import { + LOADING_END, + LOADING_START, +} from "../../../../lib/redux/slices/appSlice"; +import { ChangeCardInfo } from "../../../authentication/components/change-card-info/ChangeCardInfo"; +import { vatFarmGetProfile } from "../../services/vet-farm-get-profile"; + +export const VetFarmProfile = () => { + const { profile } = useSelector((state) => state.vetFarmSlice); + const dispatch = useDispatch(); + + useEffect(() => { + dispatch(LOADING_START()); + dispatch(vatFarmGetProfile()).then((r) => { + dispatch(LOADING_END()); + }); + }, []); + + return ( + + + + + <> + {/* + + */} + + + + + + + + + ); +}; diff --git a/src/features/vet-farm/components/vet-farm-aggregate-bars/VetFarmAggregateBars.js b/src/features/vet-farm/components/vet-farm-aggregate-bars/VetFarmAggregateBars.js new file mode 100644 index 0000000..da8623b --- /dev/null +++ b/src/features/vet-farm/components/vet-farm-aggregate-bars/VetFarmAggregateBars.js @@ -0,0 +1,280 @@ +import React, { useContext, useEffect, useState } from "react"; +import { Grid, Button, TextField, Typography, IconButton } from "@mui/material"; +import { SimpleTable } from "../../../../components/simple-table/SimpleTable"; +import { useFormik } from "formik"; +import * as Yup from "yup"; +import { AppContext } from "../../../../contexts/AppContext"; +import { useDispatch } from "react-redux"; +import { + vetFarmReturnAggregateBars, + vetFarmSubmitAggregateBars, +} from "../../services/vet-farm-submit-aggegate-bars"; +import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl"; +import { CLOSE_MODAL } from "../../../../lib/redux/slices/appSlice"; +import DeleteIcon from "@mui/icons-material/Delete"; +import { vetFarmDeleteAggregateBarService } from "../../services/vet-farm-delete-aggregate-bar"; + +export const VetFarmAggregateBars = ({ + bars, + updateTable, + canReturn, + setAggregates, + toShow, +}) => { + const [tableData, setTableData] = useState([]); + const dispatch = useDispatch(); + const [openNotif] = useContext(AppContext); + + const [allBars, setAllBars] = useState(bars); + + useEffect(() => { + let d; + if (!toShow || !allBars[0]?.aggregateCode) { + d = allBars?.map((item, i) => { + return [ + i + 1, + item?.barCode, + item.quantity?.toLocaleString(), + item?.weightInfo?.weight?.toLocaleString(), + { + dispatch( + vetFarmDeleteAggregateBarService({ + kill_house_request_key: item?.key, + }) + ).then((r) => { + if (r.payload.error) { + openNotif({ + vertical: "top", + horizontal: "center", + msg: r.payload.error, + severity: "error", + }); + } else { + setAllBars( + allBars?.filter((option) => option?.key !== item?.key) + ); + setAggregates([]); + updateTable(); + openNotif({ + vertical: "top", + horizontal: "center", + msg: "عملیات با موفقیت انجام شد.", + severity: "success", + }); + } + }); + }} + > + + , + ]; + }); + } else { + d = allBars?.map((item, i) => { + return [ + i + 1, + item?.barCode, + item.quantity?.toLocaleString(), + item?.weightInfo?.weight?.toLocaleString(), + ]; + }); + } + + setTableData(d); + }, [allBars]); + + const formik = useFormik({ + initialValues: { + clearanceCode: "", + trafficCode: "", + }, + validationSchema: Yup.object({ + clearanceCode: Yup.string().required("این فیلد اجباری است!"), + trafficCode: Yup.string().required("این فیلد اجباری است!"), + }), + }); + + useEffect(() => { + formik.validateForm(); + }, []); + + const handleClearanceCodeChange = (event) => { + const { value } = event.target; + formik.setFieldValue("clearanceCode", value.toUpperCase()); + }; + + const isSubmitButtonVisible = + (formik.values.clearanceCode && formik.values.trafficCode) || + (!formik.values.clearanceCode && !formik.values.trafficCode); + + return ( + + + + خریدار:{" "} + {`${allBars[0]?.killhouseUser?.name} (${allBars[0]?.killhouseUser?.killHouseOperator?.user?.mobile})`} + + + + + مرغدار:{" "} + {`${allBars[0]?.poultryRequest?.poultry?.unitName} (${allBars[0]?.poultryRequest.poultry?.user?.mobile})`} + + + + + مجموع حجم بار:{" "} + {allBars + ?.reduce((total, obj) => total + obj?.quantity, 0) + .toLocaleString()}{" "} + قطعه + + + + + {!toShow && ( + <> + + + + + + + + + + + + + {canReturn && ( + + )} + + + )} + + ); +}; diff --git a/src/features/vet-farm/components/vet-farm-cancel-bar/VetFarmCancelBar.js b/src/features/vet-farm/components/vet-farm-cancel-bar/VetFarmCancelBar.js new file mode 100644 index 0000000..987b448 --- /dev/null +++ b/src/features/vet-farm/components/vet-farm-cancel-bar/VetFarmCancelBar.js @@ -0,0 +1,126 @@ +import { + Button, + FormControl, + InputLabel, + MenuItem, + Select, + Typography, +} from "@mui/material"; +import { useContext, useState } from "react"; +import { useDispatch, useSelector } from "react-redux"; +import { Grid } from "../../../../components/grid/Grid"; +import { AppContext } from "../../../../contexts/AppContext"; +import { SPACING } from "../../../../data/spacing"; +import { CLOSE_MODAL, DRAWER } from "../../../../lib/redux/slices/appSlice"; +import { slaughterHouseVetNewRequests } from "../../../slaughter-house-vet/services/slaughter-house-vet-new-requests"; +import { vetFarmCancelBarService } from "../../services/vet-farm-cancel-bar"; +import { vetFarmGetAllocatedService } from "../../services/vet-farm-get-allocated"; +import { vetFarmGetDeletedBarsService } from "../../services/vet-farm-get-deleted-bars"; +import { checkPathStartsWith } from "../../../../utils/checkPathStartsWith"; + +export const VetFarmCancelBar = ({ killHouseRequestKey, updateTable }) => { + const dispatch = useDispatch(); + const [openNotif, , selectedDate1, , selectedDate2] = useContext(AppContext); + const [selectedOption, setSelectedOption] = useState(null); + const selectedSubUser = useSelector( + (state) => state.userSlice.selectedSubUser + ); + const handleSelectChange = (event) => { + setSelectedOption(event.target.value); + }; + + return ( + + + در صورت لغو بار کل اطلاعات حذف گردیده و تعداد مرغ تخصیصی به جوجه ریزی + مرغدار برمیگردد. + + + + دلیل لغو بار + + + + + + ); +}; diff --git a/src/features/vet-farm/components/vet-farm-delete-bar/VetFarmDeleteBar.js b/src/features/vet-farm/components/vet-farm-delete-bar/VetFarmDeleteBar.js new file mode 100644 index 0000000..74340ac --- /dev/null +++ b/src/features/vet-farm/components/vet-farm-delete-bar/VetFarmDeleteBar.js @@ -0,0 +1,115 @@ +import React, { useContext } from "react"; +import { Grid } from "../../../../components/grid/Grid"; +import { Button, Typography } from "@mui/material"; +import { + CLOSE_MODAL, + LOADING_END, + LOADING_START, +} from "../../../../lib/redux/slices/appSlice"; +import { useDispatch } from "react-redux"; +import { SPACING } from "../../../../data/spacing"; +import { vetFarmDeleteBarService } from "../../services/vet-farm-delete-bar"; +import { AppContext } from "../../../../contexts/AppContext"; + +export const VetFarmDeleteBar = ({ updateTable, item }) => { + const dispatch = useDispatch(); + const [openNotif] = useContext(AppContext); + return ( + + + پس از حذف امکان بازگشت تغییرات مقدور نیست! + + + + + + + ); +}; diff --git a/src/features/vet-farm/components/vet-farm-deleted-bars/VetFarmDeletedBars.js b/src/features/vet-farm/components/vet-farm-deleted-bars/VetFarmDeletedBars.js new file mode 100644 index 0000000..6b943c0 --- /dev/null +++ b/src/features/vet-farm/components/vet-farm-deleted-bars/VetFarmDeletedBars.js @@ -0,0 +1,525 @@ +import React, { useContext, useEffect, useState } from "react"; +import { Button, TextField, Tooltip, Typography } from "@mui/material"; +import { DatePicker } from "@mui/x-date-pickers"; +import moment from "moment"; +import { useDispatch, useSelector } from "react-redux"; +import axios from "axios"; +import { RiFileExcel2Fill, RiSearchLine } from "react-icons/ri"; +import { AppContext } from "../../../../contexts/AppContext"; +import ResponsiveTable from "../../../../components/responsive-table/ResponsiveTable"; +import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl"; +import { getFaUserRole } from "../../../../utils/getFaUserRole"; +import { + LOADING_END, + LOADING_START, +} from "../../../../lib/redux/slices/appSlice"; +import { vetFarmGetDeletedBarsDahsboard } from "../../services/vet-farm-get-deleted-bars-dashboard"; + +import { Grid } from "../../../../components/grid/Grid"; +import { format } from "date-fns-jalali"; +import { SPACING } from "../../../../data/spacing"; +import { checkPathStartsWith } from "../../../../utils/checkPathStartsWith"; + +export const VetFarmDeletedBars = () => { + const [data, setData] = useState([]); + const [totalRows, setTotalRows] = useState(0); + const [perPage, setPerPage] = useState(10); + const [textValue, setTextValue] = useState(""); + const [page, setPage] = useState(1); + const [dashboardData, setDashboardData] = useState([]); + const [dataTableM, setDataTableM] = useState([]); + const [has500Error, setHas500Error] = useState(false); + const selectedSubUser = useSelector( + (state) => state.userSlice.selectedSubUser + ); + const [ + openNotif, + , + selectedDate1, + setSelectedDate1, + selectedDate2, + setSelectedDate2, + ] = useContext(AppContext); + + const userKey = useSelector((state) => state.userSlice?.userProfile?.key); + + const dispatch = useDispatch(); + + useEffect(() => { + const currentDate = moment(new Date()).format("YYYY-MM-DD"); + setSelectedDate1(currentDate); + setSelectedDate2(currentDate); + }, []); + + const handleTextChange = (event) => { + setTextValue(event.target.value); + }; + + const fetchApiData = async (page) => { + // Prevent request if there was a 500 error + if (has500Error) { + return; + } + + dispatch(LOADING_START()); + try { + const response = await axios.get( + `kill_house_request_bar_management/?check&deleted_requests&search=filter&value=${textValue}&role=${getRoleFromUrl()}${ + checkPathStartsWith("slaughter") + ? `&role_key=${selectedSubUser?.key}` + : "" + }&date1=${selectedDate1}&date2=${selectedDate2}&page=${page}&page_size=${perPage}` + ); + // Reset error state on successful response + setHas500Error(false); + setData(response.data?.results || []); + setTotalRows(response.data?.count || 0); + } catch (error) { + console.error("Error fetching data:", error); + const errorMessage = error?.message || ""; + const status = error?.response?.status; + const is500Error = errorMessage.includes("500") || status === 500; + + if (is500Error) { + setHas500Error(true); + openNotif({ + vertical: "top", + horizontal: "center", + msg: "مشکلی در دریافت اطلاعات پیش آمده است!", + severity: "error", + }); + } else { + openNotif({ + vertical: "top", + horizontal: "center", + msg: "مشکلی در دریافت اطلاعات پیش آمده است!", + severity: "error", + }); + } + setData([]); + setTotalRows(0); + } finally { + dispatch(LOADING_END()); + } + }; + + const handlePageChange = (page) => { + fetchApiData(page); + setPage(page); + }; + + const handlePerRowsChange = (perRows) => { + setPerPage(perRows); + setPage(1); + }; + + // const updateTable = () => { + // fetchApiData(page !== 0 ? page : 1); + // }; + + useEffect(() => { + // Prevent request if there was a 500 error + if (has500Error) { + return; + } + + fetchApiData(1); + dispatch( + vetFarmGetDeletedBarsDahsboard({ + selectedDate1, + selectedDate2, + role_key: checkPathStartsWith("slaughter") + ? selectedSubUser?.key || "" + : "", + }) + ) + .then((r) => { + if (r?.error) { + const errorMessage = r.error?.message || ""; + const is500Error = + errorMessage.includes("500") || + r.error?.status === 500 || + r.error?.statusCode === 500; + + if (is500Error) { + setHas500Error(true); + openNotif({ + vertical: "top", + horizontal: "center", + msg: "مشکلی در دریافت اطلاعات پیش آمده است!", + severity: "error", + }); + } else { + openNotif({ + vertical: "top", + horizontal: "center", + msg: "مشکلی در دریافت اطلاعات پیش آمده است!", + severity: "error", + }); + } + setDashboardData([]); + } else if (r?.payload?.data) { + // Reset error state on successful response + setHas500Error(false); + setDashboardData(r.payload.data); + } else { + setDashboardData([]); + } + }) + .catch((error) => { + console.error("Error fetching dashboard data:", error); + const errorMessage = error?.message || ""; + const status = error?.response?.status; + const is500Error = errorMessage.includes("500") || status === 500; + + if (is500Error) { + setHas500Error(true); + openNotif({ + vertical: "top", + horizontal: "center", + msg: "مشکلی در دریافت اطلاعات پیش آمده است!", + severity: "error", + }); + } else { + openNotif({ + vertical: "top", + horizontal: "center", + msg: "مشکلی در دریافت اطلاعات پیش آمده است!", + severity: "error", + }); + } + setDashboardData([]); + }); + }, [dispatch, selectedDate1, selectedDate2, perPage, selectedSubUser?.key]); + + // Reset error state when dates or filters change + useEffect(() => { + setHas500Error(false); + }, [selectedDate1, selectedDate2, textValue]); + + const handleSubmit = async (event) => { + event.preventDefault(); + // Reset error state on manual submit (user retry) + setHas500Error(false); + dispatch(LOADING_START()); + + try { + const response = await axios.get( + `kill_house_request_bar_management/?check&deleted_requests&search=filter&value=${textValue}&role=${getRoleFromUrl()}${ + checkPathStartsWith("slaughter") + ? `&role_key=${selectedSubUser?.key}` + : "" + }&date1=${selectedDate1}&date2=${selectedDate2}&page=1&page_size=${perPage}` + ); + // Reset error state on successful response + setHas500Error(false); + setData(response.data?.results || []); + setTotalRows(response.data?.count || 0); + dispatch(LOADING_END()); + } catch (error) { + console.error("Error fetching data:", error); + const errorMessage = error?.message || ""; + const status = error?.response?.status; + const is500Error = errorMessage.includes("500") || status === 500; + + if (is500Error) { + setHas500Error(true); + openNotif({ + vertical: "top", + horizontal: "center", + msg: "مشکلی در دریافت اطلاعات پیش آمده است!", + severity: "error", + }); + } else { + openNotif({ + vertical: "top", + horizontal: "center", + msg: "مشکلی در دریافت اطلاعات پیش آمده است!", + severity: "error", + }); + } + setData([]); + setTotalRows(0); + dispatch(LOADING_END()); + } + }; + const handleDateChange1 = (date) => { + setSelectedDate1(date); + }; + + const handleDateChange2 = (date) => { + setSelectedDate2(date); + }; + + useEffect(() => { + if (!data || !Array.isArray(data)) { + setDataTableM([]); + return; + } + + const d = data.map((item, i) => { + return [ + page === 1 ? i + 1 : i + perPage * (page - 1) + 1, + item?.barCode || "", + + item?.vetFarm?.vet?.user?.fullname + ? item.vetFarm.vet.user.fullname + + `(${item?.vetFarm?.vet?.user?.mobile || ""})` + : "فاقد دامپزشک", + + item?.poultryRequest?.freezing ? "انجماد" : "عادی", + + item?.poultryRequest?.freeSaleInProvince ? "آزاد" : "دولتی", + + `${item?.addCar?.driver?.typeCar || ""} ${ + item?.addCar?.driver?.pelak || "" + }`, + + `${item?.addCar?.driver?.driverName || ""} (${ + item?.addCar?.driver?.driverMobile || "" + })`, + + `${item?.killhouseUser?.name || ""} (${ + item?.killhouseUser?.killHouseOperator?.user?.mobile || "" + })`, + + item?.killer + ? `${item.killer?.name || ""} (${ + item.killer?.killHouseOperator?.user?.mobile || "" + })` + : "-", + + `${item?.poultryRequest?.poultry?.unitName || ""} (${ + item?.poultryRequest?.poultry?.user?.mobile || "" + })`, + + item?.poultryRequest?.poultry?.address?.city?.name || "", + item?.poultryRequest?.age || "", + + item?.killPlace || "", + + item?.poultryRequest?.amount + ? item.poultryRequest.amount.toLocaleString() + " ﷼" + : "0 ﷼", + + item?.weightInfo?.killHousePrice + ? item.weightInfo.killHousePrice.toLocaleString() + " ﷼" + : "0 ﷼", + + item?.poultryRequest?.sendDate + ? (() => { + try { + const date = new Date(item.poultryRequest.sendDate); + return isNaN(date.getTime()) ? "-" : format(date, "yyyy/MM/dd"); + } catch (error) { + console.error("Error formatting sendDate:", error); + return "-"; + } + })() + : "-", + + item?.poultryRequest?.orderCode || "", + + item?.poultryRequest?.chickenBreed || "", + + item?.quantity ? item.quantity.toLocaleString() : "0", + + item?.trafficCode || "", + item?.amount ? item.amount.toLocaleString() + " ﷼" : "0 ﷼", + item?.clearanceCode || "-", + + item?.barRemover + ? `${item.barRemover?.fullName || ""} (${getFaUserRole( + item.barRemover?.role + )}) (${ + item.barRemover?.date + ? (() => { + try { + const date = new Date(item.barRemover.date); + return isNaN(date.getTime()) + ? "-" + : format(date, "yyyy/MM/dd"); + } catch (error) { + console.error("Error formatting barRemover date:", error); + return "-"; + } + })() + : "-" + })` + : "-", + item?.nonReceipt ? `(عدم وصول) ${item?.message || ""}` : "-", + ]; + }); + + setDataTableM(d); + }, [data, page, perPage]); + + const tableTitle = ( + + + بارهای حذف شده + + } + value={selectedDate1} + onChange={(e) => { + handleDateChange1(moment(e).format("YYYY-MM-DD")); + }} + /> + + + } + value={selectedDate2} + onChange={(e) => { + handleDateChange2(moment(e).format("YYYY-MM-DD")); + }} + /> + + + + + {(getRoleFromUrl() === "ProvinceOperator" || + getRoleFromUrl() === "SuperAdmin" || + getRoleFromUrl() === "AdminX" || + getRoleFromUrl() === "Supporter" || + getRoleFromUrl() === "CityJahad" || + getRoleFromUrl() === "CityPoultry" || + getRoleFromUrl() === "KillHouse") && ( + + + + + + )} + + + ); + + return ( + + + {tableTitle} + + + + + + + ); +}; diff --git a/src/features/vet-farm/components/vet-farm-edit-out-out-province-traffic-code/VetFarmEditOutOfProvinceTrafficCode.js b/src/features/vet-farm/components/vet-farm-edit-out-out-province-traffic-code/VetFarmEditOutOfProvinceTrafficCode.js new file mode 100644 index 0000000..f0c6810 --- /dev/null +++ b/src/features/vet-farm/components/vet-farm-edit-out-out-province-traffic-code/VetFarmEditOutOfProvinceTrafficCode.js @@ -0,0 +1,145 @@ +import { + Button, + IconButton, + TextField, + Tooltip, + Typography, +} from "@mui/material"; +import { useContext, useState, useEffect } from "react"; +import { Grid } from "../../../../components/grid/Grid"; +import EditIcon from "@mui/icons-material/Edit"; +import AddCircleOutlineIcon from "@mui/icons-material/AddCircleOutline"; +import { useDispatch } from "react-redux"; +import { AppContext } from "../../../../contexts/AppContext"; +import { vetFarmGetOutOfProvinceRequests } from "../../services/vet-farm-get-out-of-province-requests"; +import { vetFarmEditOutOfProvinceDriverHealthCode } from "../../services/vet-farm-edit-out-of-province-driver-health-code"; +import { CLOSE_MODAL, OPEN_MODAL } from "../../../../lib/redux/slices/appSlice"; + +export const VetFarmEditOutOfProvinceTrafficCode = ({ trafficCode, item }) => { + const dispatch = useDispatch(); + const [openNotif] = useContext(AppContext); + const [, , selectedDate1, , selectedDate2] = useContext(AppContext); + + const handleSubmit = (value) => { + dispatch( + vetFarmEditOutOfProvinceDriverHealthCode({ + poultry_request_key: item?.key, + driver_health_code: value, + }) + ).then((r) => { + if (r.error) { + openNotif({ + vertical: "top", + horizontal: "center", + msg: "مشکلی پیش آمده است!", + severity: "error", + }); + } else { + openNotif({ + vertical: "top", + horizontal: "center", + msg: "عملیات با موفقیت انجام شد.", + severity: "success", + }); + dispatch( + vetFarmGetOutOfProvinceRequests({ + selectedDate1, + selectedDate2, + }) + ); + dispatch(CLOSE_MODAL()); + } + }); + }; + + const handleOpenModal = () => { + dispatch( + OPEN_MODAL({ + title: "ویرایش کد بهداشتی ماشین", + size: "auto", + content: ( + dispatch(CLOSE_MODAL())} + /> + ), + }) + ); + }; + + return ( + + {trafficCode ? ( + {trafficCode} + ) : null} + + + {trafficCode ? ( + + ) : ( + + )} + + + + ); +}; + +const OutOfProvinceTrafficCodeModal = ({ + initialValue, + onSubmit, + onCancel, +}) => { + const [value, setValue] = useState(initialValue); + + useEffect(() => { + setValue(initialValue); + }, [initialValue]); + + const handleSave = () => { + if (!value || value === initialValue) { + return; + } + onSubmit(value); + }; + + return ( + + setValue(event.target.value)} + size="small" + fullWidth + /> + + + + + + ); +}; diff --git a/src/features/vet-farm/components/vet-farm-edit-quarantine-code-state/VetFarmEditQuarantineCodeState.js b/src/features/vet-farm/components/vet-farm-edit-quarantine-code-state/VetFarmEditQuarantineCodeState.js new file mode 100644 index 0000000..818f6c2 --- /dev/null +++ b/src/features/vet-farm/components/vet-farm-edit-quarantine-code-state/VetFarmEditQuarantineCodeState.js @@ -0,0 +1,129 @@ +import { + IconButton, + InputAdornment, + TextField, + Typography, +} from "@mui/material"; +import { useContext, useEffect, useState } from "react"; +import { Grid } from "../../../../components/grid/Grid"; +import EditIcon from "@mui/icons-material/Edit"; +import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl"; +import { AppContext } from "../../../../contexts/AppContext"; +import { vetFarmSubmitContradictsService } from "../../services/vet-farm-submit-contdadicts"; +import { + LOADING_END, + LOADING_START, +} from "../../../../lib/redux/slices/appSlice"; +import { useDispatch } from "react-redux"; +// import { vetFarmGetAllocatedService } from "../../services/vet-farm-get-allocated"; +// import { slaughterGetAllocatedCarsService } from "../../../slaughter-house/services/slaughter-get-allocated-cars"; + +export const VetFarmEditQuarantineCodeState = ({ code, item, updateTable }) => { + const [openNotif] = useContext(AppContext); + const [isEditMode, setIsEditMode] = useState(false); + const [value, setValue] = useState(code); + const dispatch = useDispatch(); + const handleChange = (event) => { + setValue(event.target.value); + }; + + useEffect(() => { + setValue(code); + setIsEditMode(false); + }, [code]); + + return ( + + {isEditMode ? ( + + + + { + setIsEditMode(!isEditMode); + dispatch(LOADING_START()); + dispatch( + vetFarmSubmitContradictsService({ + key: item.key, + quarantine_quantity: value, + }) + ).then((r) => { + dispatch(LOADING_END()); + if (r.payload.error) { + openNotif({ + vertical: "top", + horizontal: "center", + msg: "مشکلی بوجود آمده است!", + severity: "error", + }); + } else { + openNotif({ + vertical: "top", + horizontal: "center", + msg: "عملیات با موفقیت انجام شد.", + severity: "success", + }); + updateTable(); + } + }); + }} + > + ثبت + + { + setIsEditMode(!isEditMode); + }} + > + لغو + + + + ), + }} + /> + + ) : ( + + + {code?.toLocaleString()} + + {(getRoleFromUrl() === "AdminX" || + getRoleFromUrl() === "SuperAdmin") && + item.trash !== true && ( + { + setIsEditMode(!isEditMode); + }} + > + + + )} + + )} + + ); +}; diff --git a/src/features/vet-farm/components/vet-farm-edit-traffic-code/VetFarmEditTrafficCode.js b/src/features/vet-farm/components/vet-farm-edit-traffic-code/VetFarmEditTrafficCode.js new file mode 100644 index 0000000..16c279f --- /dev/null +++ b/src/features/vet-farm/components/vet-farm-edit-traffic-code/VetFarmEditTrafficCode.js @@ -0,0 +1,159 @@ +import { + Button, + IconButton, + TextField, + Tooltip, + Typography, +} from "@mui/material"; +import { useContext, useEffect, useState } from "react"; +import { Grid } from "../../../../components/grid/Grid"; +import { Edit } from "@mui/icons-material"; +import { useDispatch } from "react-redux"; +import { vetFarmEditTrafficCodeService } from "../../services/vet-farm-edit-traffic-code"; +import { AppContext } from "../../../../contexts/AppContext"; +import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl"; +import { CLOSE_MODAL, OPEN_MODAL } from "../../../../lib/redux/slices/appSlice"; + +export const VetFarmEditTrafficCode = ({ + trafficCode, + killHouseRequestKey, + updateTable, + isEditable = true, +}) => { + const dispatch = useDispatch(); + const [openNotif] = useContext(AppContext); + + if (!isEditable) { + return ( + + {trafficCode || "-"} + + ); + } + + const handleOpenModal = () => { + dispatch( + OPEN_MODAL({ + title: "ویرایش کد حمل و نقل", + size: "auto", + content: ( + { + dispatch( + vetFarmEditTrafficCodeService({ + key: killHouseRequestKey, + traffic_code: newCode, + role: getRoleFromUrl(), + }) + ).then((r) => { + if (r.payload.error) { + openNotif({ + vertical: "top", + horizontal: "center", + msg: r.payload.error, + severity: "error", + }); + } else { + openNotif({ + vertical: "top", + horizontal: "center", + msg: "عملیات با موفقیت انجام شد.", + severity: "success", + }); + updateTable(); + dispatch(CLOSE_MODAL()); + } + }); + }} + onCancel={() => dispatch(CLOSE_MODAL())} + /> + ), + }) + ); + }; + + return ( + + {trafficCode || "-"} + + + + + + + ); +}; + +const TrafficCodeModal = ({ initialValue, onSubmit, onCancel }) => { + const [value, setValue] = useState(initialValue); + + useEffect(() => { + setValue(initialValue); + }, [initialValue]); + + const handleSubmit = () => { + if (!value) { + return; + } + onSubmit(value); + }; + + return ( + + setValue(event.target.value)} + inputProps={{ + inputMode: "numeric", + pattern: "[0-9]*", + }} + fullWidth + /> + + + + + + ); +}; diff --git a/src/features/vet-farm/components/vet-farm-inspection-history/VetFarmInspectionHistory.js b/src/features/vet-farm/components/vet-farm-inspection-history/VetFarmInspectionHistory.js new file mode 100644 index 0000000..c66f023 --- /dev/null +++ b/src/features/vet-farm/components/vet-farm-inspection-history/VetFarmInspectionHistory.js @@ -0,0 +1,134 @@ +import { + Timeline, + TimelineConnector, + TimelineDot, + TimelineItem, + TimelineOppositeContent, + TimelineSeparator, +} from "@mui/lab"; +import { IconButton, Typography } from "@mui/material"; +import { useEffect } from "react"; +import { useDispatch, useSelector } from "react-redux"; +import { useNavigate, useParams } from "react-router-dom"; +import { Grid } from "../../../../components/grid/Grid"; +import { SimpleTable } from "../../../../components/simple-table/SimpleTable"; +import { SPACING } from "../../../../data/spacing"; +import { formatJustDate, formatJustTime } from "../../../../utils/formatTime"; +import { getVetFarmInspectionHistory } from "../../services/vet-farm-get-inspection-history"; +import NavigateNextIcon from "@mui/icons-material/NavigateNext"; +export const VetFarmInspectionHistory = () => { + const navigate = useNavigate(); + + const { inspectionid } = useParams(); + const id = inspectionid; + const { vetFarmInspectionHistory, pending } = useSelector( + (state) => state.vetFarmSlice + ); + const dispatch = useDispatch(); + + useEffect(() => { + dispatch(getVetFarmInspectionHistory(id)); + }, []); + + return ( + <> + {!pending && ( + + + navigate(-1)} + > + + بازگشت + + + + + {vetFarmInspectionHistory?.map((item, i) => { + return ( + <> + + + + + + + + + + + بازرسی مورخ {formatJustDate(item.createDate)} ساعت{" "} + {formatJustTime(item.createDate)} + + + + + + + { + return [ + + + دانلود + + , + ]; + }) + : "بدون پیوست", + ], + ]} + /> + + + + + + ); + })} + {!vetFarmInspectionHistory?.length && ( + + برای این مرغداری بازرسی ثبت نشده است. + + )} + + + )} + + ); +}; diff --git a/src/features/vet-farm/components/vet-farm-operation-row/VetFarmOperationRow.js b/src/features/vet-farm/components/vet-farm-operation-row/VetFarmOperationRow.js new file mode 100644 index 0000000..c3cb139 --- /dev/null +++ b/src/features/vet-farm/components/vet-farm-operation-row/VetFarmOperationRow.js @@ -0,0 +1,259 @@ +import React, { useContext, useEffect, useRef } from "react"; +import { useFormik } from "formik"; +import { + Button, + InputAdornment, + TextField, + Tooltip, + Typography, +} from "@mui/material"; +import { Grid } from "../../../../components/grid/Grid"; +import { useDispatch } from "react-redux"; +import { vetFarmCheckAllocation } from "../../services/vet-farm-check-allocation"; +import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl"; +import { vetFarmEditCodeAllocation } from "../../services/vet-farm-edit-code-allocation"; +import PageviewIcon from "@mui/icons-material/Pageview"; +import { Done } from "@mui/icons-material"; +import { PropTypes } from "prop-types"; +import { AppContext } from "../../../../contexts/AppContext"; +import { format } from "date-fns"; + +export const VetFarmOperationRow = ({ + item, + updateTable, + isEditable = true, +}) => { + const dispatch = useDispatch(); + const [openNotif] = useContext(AppContext); + + // Calculate if field should be locked/readonly + const isLocked = item?.aggregateCode + ? !item?.clearanceCode + : getRoleFromUrl() === "ProvinceOperator" || + getRoleFromUrl() === "VetSupervisor" || + getRoleFromUrl() === "VetFarm" || + getRoleFromUrl() === "AdminX" || + getRoleFromUrl() === "SuperAdmin" || + getRoleFromUrl() === "Supporter" + ? false + : item.trash === true || item?.quarantineQuantity + ? true + : false; + + const formik = useFormik({ + initialValues: { + name: "", + }, + validate: (values) => { + const errors = {}; + + // Check if field is empty + if (!values.name) { + errors.name = "این فیلد اجباری است"; + } + + // Check if field contains at least one letter and one number + const pattern = /^(?=.*[A-Za-z])(?=.*\d)[A-Za-z\d]+$/; + if (!pattern.test(values.name)) { + errors.name = "باید شامل اعداد و حروف انگلیسی باشد"; + } + + return errors; + }, + }); + + useEffect(() => { + if (formik.values.name) { + formik.values.name = formik.values.name.toUpperCase(); + } + }, [formik.values]); + + useEffect(() => { + formik.setFieldValue("name", item?.clearanceCode || ""); + }, [item]); + + useEffect(() => { + formik.validateForm(); + }, []); + + const handleSubmit = () => { + if (item.clearanceCode) { + dispatch( + vetFarmEditCodeAllocation({ + kill_house_request_key: item.key, + code: formik.values.name, + role: getRoleFromUrl(), + }) + ).then((r) => { + if (r.payload.error) { + openNotif({ + vertical: "top", + horizontal: "center", + msg: r.payload.error, + severity: "error", + }); + } else { + openNotif({ + vertical: "top", + horizontal: "center", + msg: "عملیات با موفقیت انجام شد.", + severity: "success", + }); + updateTable(); + } + }); + } else { + formik.setFieldValue("name", ""); + dispatch( + vetFarmCheckAllocation({ + kill_house_request_key: item.key, + code: formik.values.name, + role: getRoleFromUrl(), + }) + ).then((r) => { + if (r.payload.error) { + openNotif({ + vertical: "top", + horizontal: "center", + msg: r.payload.error, + severity: "error", + }); + } else { + openNotif({ + vertical: "top", + horizontal: "center", + msg: "عملیات با موفقیت انجام شد.", + severity: "success", + }); + updateTable(); + } + }); + } + }; + + if (!isEditable) { + return ( + + {item?.clearanceCode ? item.clearanceCode : "-"} + + ); + } + + return ( + <> + + + {item.clearanceCode && ( + + )} + + ), + }} + /> + {!isLocked && ( + + )} + + {item?.registerar?.date && ( + + {`${format(new Date(item?.registerar?.date), "yyyy/MM/dd")} ${ + item?.registerar?.name + }`} + + )} + + ); +}; + +const ViewCodeComponent = ({ clearanceCode }) => { + const formRef = useRef(null); + + const handleImageClick = () => { + if (formRef.current) { + formRef.current.submit(); + } + }; + return ( + + +
    + + + + +
    +
    + ); +}; + +VetFarmOperationRow.propTypes = { + item: PropTypes.any, + updateTable: PropTypes.any, + isEditable: PropTypes.bool, +}; diff --git a/src/features/vet-farm/components/vet-farm-operation/VetFarmOperation.js b/src/features/vet-farm/components/vet-farm-operation/VetFarmOperation.js new file mode 100644 index 0000000..5fe2e77 --- /dev/null +++ b/src/features/vet-farm/components/vet-farm-operation/VetFarmOperation.js @@ -0,0 +1,1787 @@ +import { + Button, + Checkbox, + Chip, + FormControlLabel, + IconButton, + Tab, + Tabs, + TextField, + Tooltip, + Typography, +} from "@mui/material"; +import VisibilityIcon from "@mui/icons-material/Visibility"; +import AddCircleOutlineIcon from "@mui/icons-material/AddCircleOutline"; +import EditIcon from "@mui/icons-material/Edit"; +import { format } from "date-fns-jalali"; +import { useContext, useEffect, useState } from "react"; +import { useDispatch, useSelector } from "react-redux"; +// import { AdvancedTable } from "../../../../components/advanced-table/AdvancedTable"; +import { Grid } from "../../../../components/grid/Grid"; +// import { vetFarmGetAllocatedService } from "../../services/vet-farm-get-allocated"; +import { VetFarmOperationRow } from "../vet-farm-operation-row/VetFarmOperationRow"; +import { DatePicker } from "@mui/x-date-pickers"; +import moment from "moment/moment"; +import { SPACING } from "../../../../data/spacing"; +import { AppContext } from "../../../../contexts/AppContext"; +import axios from "axios"; +import { SiGooglemessages } from "react-icons/si"; +import { RiFileExcel2Fill, RiSearchLine } from "react-icons/ri"; + +import { + DRAWER, + LOADING_END, + LOADING_START, + OPEN_MODAL, +} from "../../../../lib/redux/slices/appSlice"; +import { vetFarmGetDeletedBarsService } from "../../services/vet-farm-get-deleted-bars"; +import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl"; +// import { getFaUserRole } from "../../../../utils/getFaUserRole"; +import { VetFarmDeletedBars } from "../vet-farm-deleted-bars/VetFarmDeletedBars"; +import { EnterAggregateLoadInformation } from "../../../slaughter-house/components/enter-aggregate-load-information/EnterAggregateLoadInformation"; +import { SlaughterManageBars } from "../../../slaughter-house/components/slaughter-manage-bars/SlaughterManageBars"; +import { VetFarmSubmitContradicts } from "../vet-farm-submit-contradicts/VetFarmSubmitContradicts"; +import { VetFarmEditTrafficCode } from "../vet-farm-edit-traffic-code/VetFarmEditTrafficCode"; +import { VetFarmEditQuarantineCodeState } from "../vet-farm-edit-quarantine-code-state/VetFarmEditQuarantineCodeState"; +import { VetFarmOutOfProvince } from "../vet-farm-sale-out-of-province/VetFarmOutOfProvince"; +import { formatJustDate, formatTime } from "../../../../utils/formatTime"; +import { vetFarmGetBarsOverview } from "../../services/vet-farm-get-bars-overview"; +import { ChainBarManagement } from "../../../province/components/chain-bar-management/ChainBarManagement"; +import ShowImage from "../../../../components/show-image/ShowImage"; +import { VetFarmOperationOptions } from "../vet-farm-operations-options/VetFarmOperationOptions"; +import ResponsiveTable from "../../../../components/responsive-table/ResponsiveTable"; +import { SlaughterOutProvinceBars } from "../../../slaughter-house/components/slaughter-out-province-bars/SlaughterOutProvinceBars"; +import { provincePolicyGetAggregateBarInfoAllowStatus } from "../../../province/services/province-policy-get-aggregate-bar-info-allow-state"; +import { VetFarmAggregateBars } from "../vet-farm-aggregate-bars/VetFarmAggregateBars"; +import { vetFarmDeleteAggregateBarService } from "../../services/vet-farm-delete-aggregate-bar"; +import RefreshIcon from "@mui/icons-material/Refresh"; +import { SimpleTable } from "../../../../components/simple-table/SimpleTable"; +import { SlaughterEnterNoneReciept } from "../../../slaughter-house/components/slaughter-enter-none-receipt/SlaughterEnterNoneReciept"; +import SupporterSettlement from "../../../supporter/components/SupporterSettlement"; + +export const VetFarmOperation = () => { + const [data, setData] = useState([]); + const [totalRows, setTotalRows] = useState(0); + const [perPage, setPerPage] = useState(10); + const [selectedTab, setSelectedTab] = useState(0); + const [tableData, setTableData] = useState([]); + const [aggregates, setAggregates] = useState([]); + const [page, setPage] = useState(1); + const [aggregateStatus, setAggregateStatus] = useState(false); + const [hasDocumentState, setHasDocumentState] = useState(false); + const [textValue, setTextValue] = useState(""); + const [has500Error, setHas500Error] = useState(false); + + const dispatch = useDispatch(); + + const [, , selectedDate1, setSelectedDate1, selectedDate2, setSelectedDate2] = + useContext(AppContext); + const userInfo = useSelector((state) => state.userSlice); + const { vetFarmBarsOverview } = useSelector((state) => state.vetFarmSlice); + + useEffect(() => { + const currentDate = moment(new Date()).format("YYYY-MM-DD"); + setSelectedDate1(currentDate); + setSelectedDate2(currentDate); + }, []); + // const { vetFarmGetDeletedBars } = useSelector((state) => state.vetFarmSlice); + + const handleTabChange = (event, newValue) => { + setSelectedTab(newValue); + }; + + const handleChangeDocumentState = () => { + setHasDocumentState(!hasDocumentState); + }; + + // const [dataTable, setDataTable] = useState([]); + // const [dataDeletedTable, setDataDeletedTable] = useState([]); + + const information = () => { + if (getRoleFromUrl() !== "VetFarm") { + return ["گزارش اختلاف فارم"]; + } else { + return []; + } + }; + + const renderReportCell = (item, i) => { + if (getRoleFromUrl() === "VetFarm") { + return []; + } + + return item?.priceRegisterDate + ? [ + + { + dispatch( + DRAWER({ + top: !(window.innerWidth <= 600), + bottom: window.innerWidth <= 600, + title: "گزارش ", + content: ( + + , + , + ], + ]} + /> + ), + }) + ); + }} + > + + + , + ] + : ["بدون گزارش"]; + }; + + const getItemState = (item) => { + let state = ""; + let color = "default"; + + if (item.trash === true) { + state = "حذف شده"; + color = "error"; + } else if (item?.wareHouseConfirmation) { + state = "ورود به انبار"; + color = "success"; + } else if (item?.assignmentStateArchive !== "pending") { + state = "ثبت اطلاعات بار"; + color = "info"; + } else if (item.vetState === "accepted") { + state = "تایید تخلیه"; + color = "success"; + } else if (item.vetState === "pending") { + state = "در انتظار تخلیه"; + color = "warning"; + } else { + state = "نامشخص"; + } + + return ( + + ); + }; + + const fetchApiData = async (page) => { + // Prevent request if there was a 500 error + if (has500Error) { + return; + } + + dispatch(LOADING_START()); + try { + const response = await axios.get( + `kill_house_request_bar_management/?check&search=filter&value=${textValue}&role=${getRoleFromUrl()}&date1=${selectedDate1}&date2=${selectedDate2}&page=${page}&page_size=${perPage}&without_quarantine_code_state=${hasDocumentState}` + ); + // Reset error state on successful response + setHas500Error(false); + setData(response.data?.results || []); + setTotalRows(response.data?.count || 0); + } catch (error) { + console.error("Error fetching data:", error); + const errorMessage = error?.message || ""; + const status = error?.response?.status; + const is500Error = errorMessage.includes("500") || status === 500; + + if (is500Error) { + setHas500Error(true); + openNotif({ + vertical: "top", + horizontal: "center", + msg: "مشکلی در دریافت اطلاعات پیش آمده است!", + severity: "error", + }); + } else { + openNotif({ + vertical: "top", + horizontal: "center", + msg: "مشکلی در دریافت اطلاعات پیش آمده است!", + severity: "error", + }); + } + setData([]); + setTotalRows(0); + } finally { + dispatch(LOADING_END()); + } + }; + + const handlePageChange = (page) => { + fetchApiData(page); + setPage(page); + }; + + const handlePerRowsChange = (perRows) => { + setPerPage(perRows); + setPage(1); + }; + + const updateTable = () => { + fetchApiData(page !== 0 ? page : 1); + }; + + useEffect(() => { + // Prevent request if there was a 500 error + if (has500Error) { + return; + } + + // dispatch(vetFarmGetAllocatedService({ selectedDate1, selectedDate2 })); + fetchApiData(page); + dispatch(vetFarmGetDeletedBarsService({ selectedDate1, selectedDate2 })) + .then((r) => { + if (r?.error) { + const errorMessage = r.error?.message || ""; + const is500Error = + errorMessage.includes("500") || + r.error?.status === 500 || + r.error?.statusCode === 500; + + if (is500Error) { + setHas500Error(true); + openNotif({ + vertical: "top", + horizontal: "center", + msg: "مشکلی در دریافت اطلاعات پیش آمده است!", + severity: "error", + }); + } + } else { + setHas500Error(false); + } + }) + .catch((error) => { + console.error("Error fetching deleted bars:", error); + const errorMessage = error?.message || ""; + const status = error?.response?.status; + const is500Error = errorMessage.includes("500") || status === 500; + + if (is500Error) { + setHas500Error(true); + openNotif({ + vertical: "top", + horizontal: "center", + msg: "مشکلی در دریافت اطلاعات پیش آمده است!", + severity: "error", + }); + } + }); + dispatch( + vetFarmGetBarsOverview({ + selectedDate1, + selectedDate2, + textValue, + hasDocumentState, + }) + ) + .then((r) => { + if (r?.error) { + const errorMessage = r.error?.message || ""; + const is500Error = + errorMessage.includes("500") || + r.error?.status === 500 || + r.error?.statusCode === 500; + + if (is500Error) { + setHas500Error(true); + openNotif({ + vertical: "top", + horizontal: "center", + msg: "مشکلی در دریافت اطلاعات پیش آمده است!", + severity: "error", + }); + } + } else { + setHas500Error(false); + } + }) + .catch((error) => { + console.error("Error fetching bars overview:", error); + const errorMessage = error?.message || ""; + const status = error?.response?.status; + const is500Error = errorMessage.includes("500") || status === 500; + + if (is500Error) { + setHas500Error(true); + openNotif({ + vertical: "top", + horizontal: "center", + msg: "مشکلی در دریافت اطلاعات پیش آمده است!", + severity: "error", + }); + } + }); + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [selectedDate1, selectedDate2, hasDocumentState, perPage]); + + // Reset error state when dates or filters change + useEffect(() => { + setHas500Error(false); + }, [selectedDate1, selectedDate2, hasDocumentState, textValue]); + + useEffect(() => { + fetchApiData(1); + dispatch(provincePolicyGetAggregateBarInfoAllowStatus()) + .then((r) => { + if (r?.error) { + const errorMessage = r.error?.message || ""; + const is500Error = + errorMessage.includes("500") || + r.error?.status === 500 || + r.error?.statusCode === 500; + + if (is500Error) { + setHas500Error(true); + openNotif({ + vertical: "top", + horizontal: "center", + msg: "مشکلی در دریافت اطلاعات پیش آمده است!", + severity: "error", + }); + } + setAggregateStatus(false); + } else if (r?.payload?.data) { + setHas500Error(false); + setAggregateStatus(r.payload.data); + } else { + setAggregateStatus(false); + } + }) + .catch((error) => { + console.error("Error fetching aggregate status:", error); + const errorMessage = error?.message || ""; + const status = error?.response?.status; + const is500Error = errorMessage.includes("500") || status === 500; + + if (is500Error) { + setHas500Error(true); + openNotif({ + vertical: "top", + horizontal: "center", + msg: "مشکلی در دریافت اطلاعات پیش آمده است!", + severity: "error", + }); + } + setAggregateStatus(false); + }); + // eslint-disable-next-line react-hooks/exhaustive-deps + }, []); + + useEffect(() => { + if (!data || !Array.isArray(data)) { + setTableData([]); + return; + } + + const d = data.map((item, i) => { + return [ + + {aggregateStatus?.allow && + (getRoleFromUrl() === "VetFarm" || + getRoleFromUrl() === "AdminX" || + getRoleFromUrl() === "SuperAdmin") && ( + + {item?.clearanceCode && item?.aggregateCode ? ( + + + option.aggregateCode === item?.aggregateCode + ).length < 3 + } + key={i} + onClick={() => { + dispatch( + vetFarmDeleteAggregateBarService({ + kill_house_request_key: item?.key, + }) + ) + .then((r) => { + if (r?.error || r?.payload?.error) { + const errorMsg = + r.payload?.error || r.error?.message || ""; + const is500Error = + errorMsg.includes("500") || + r.error?.status === 500 || + r.error?.statusCode === 500; + + if (is500Error) { + setHas500Error(true); + openNotif({ + vertical: "top", + horizontal: "center", + msg: "مشکلی در دریافت اطلاعات پیش آمده است!", + severity: "error", + }); + } else { + openNotif({ + vertical: "top", + horizontal: "center", + msg: + errorMsg || + "مشکلی در حذف از ادغام پیش آمده است!", + severity: "error", + }); + } + } else { + // Reset error state on successful response + setHas500Error(false); + setAggregates([]); + updateTable(); + openNotif({ + vertical: "top", + horizontal: "center", + msg: "عملیات با موفقیت انجام شد.", + severity: "success", + }); + } + }) + .catch((error) => { + console.error( + "Error deleting aggregate bar:", + error + ); + const errorMessage = error?.message || ""; + const status = error?.response?.status; + const is500Error = + errorMessage.includes("500") || + status === 500; + + if (is500Error) { + setHas500Error(true); + openNotif({ + vertical: "top", + horizontal: "center", + msg: "مشکلی در دریافت اطلاعات پیش آمده است!", + severity: "error", + }); + } else { + openNotif({ + vertical: "top", + horizontal: "center", + msg: "مشکلی در حذف از ادغام پیش آمده است!", + severity: "error", + }); + } + }); + }} + > + + + + } + /> + ) : ( + option?.barCode === item?.barCode + ).length > 0 + } + onChange={() => { + if ( + aggregates.some( + (option) => option?.barCode === item?.barCode + ) + ) { + setAggregates( + aggregates.filter( + (option) => option?.barCode !== item?.barCode + ) + ); + } else { + if (item?.aggregateCode) { + setAggregates( + data?.filter( + (option) => + option?.aggregateCode === + item?.aggregateCode + ) + ); + } else { + setAggregates([...aggregates, item]); + } + } + }} + color="primary" + /> + } + /> + )} + + )} + {page === 1 ? i + 1 : i + (perPage * page) / 2 + 1} + , + item?.aggregateCode ? ( + + {" "} + { + if (aggregateValidationHasError()) { + openNotif({ + vertical: "top", + horizontal: "center", + msg: `فقط بارهای با خریدار و مرغدار یکسان و با مجموع تعداد حداکثر ${aggregateStatus?.limitation} میتوانید ادغام کنید!`, + severity: "error", + }); + } else { + dispatch( + OPEN_MODAL({ + title: "مشاهده بارهای ادغام شده", + content: ( + + option?.aggregateCode === item?.aggregateCode + )} + /> + ), + }) + ); + } + }} + > + دارد + + + ) : ( + ندارد + ), + getItemState(item), + + {item?.barCode || ""} + {item?.priceRegisterDate ? "✉️" : ""} + , + item?.createDate ? formatTime(item.createDate) : "-", + item?.poultryRequest?.freezing + ? "انجماد" + : item?.poultryRequest?.export + ? "صادرات" + : "عادی", + item?.poultryRequest?.freeSaleInProvince ? "آزاد" : "دولتی", + `${item?.killhouseUser?.name || ""} (${ + item?.killhouseUser?.killHouseOperator?.user?.mobile || "" + })`, + item?.killer + ? `${item.killer?.name || ""} (${ + item.killer?.killHouseOperator?.user?.mobile || "" + })` + : "-", + `${item?.poultryRequest?.poultry?.user?.fullname || ""} (${ + item?.poultryRequest?.poultry?.user?.mobile || "" + })`, + item?.poultryRequest?.poultry?.unitName || "", + item?.quantity ? item.quantity.toLocaleString() : "0", + item?.weightInfo?.weight + ? item.weightInfo.weight.toLocaleString() + : "0", + <> + + , + item?.amount ? item.amount.toLocaleString() + " ﷼" : "0 ﷼", + + , + <> + {item?.quarantineQuantity ? ( + + ) : ( + <> + {item?.quarantineCodeState && + (item?.quarantineCodeState === "contradiction" + ? "مغایرت کد رهگیری" + : item?.quarantineCodeState === "noclearance" + ? "فاقد کد رهگیری" + : item?.quarantineCodeState === "merge" + ? "ادغام" + : "عدم تایید راهداری")} + + {(getRoleFromUrl() === "SuperAdmin" || + getRoleFromUrl() === "AdminX") && ( + + { + dispatch( + OPEN_MODAL({ + title: "تعداد ثبت شده در قرنطینه", + content: ( + + ), + }) + ); + }} + > + {item?.quarantineCodeState ? ( + + ) : ( + + )} + + + )} + + )} + , + + // item?.realAddCar?.driver + // ? `${item?.realAddCar?.driver?.typeCar} (${ + // item?.realAddCar?.driver?.pelak + // ? item?.realAddCar?.driver?.pelak + // : "نامشخص" + // })` + // : "-", + `${item?.addCar?.driver?.typeCar || ""} ${ + item?.addCar?.driver?.pelak || "" + }`, + `${item?.addCar?.driver?.driverName || ""} (${ + item?.addCar?.driver?.driverMobile || "" + })`, + item?.poultryRequest?.chickenBreed || "", + item?.poultryRequest?.age + ? item.poultryRequest.age.toLocaleString() + : "0", + item?.weightInfo?.indexWeight + ? item.weightInfo.indexWeight.toLocaleString() + : "0", + ...(getRoleFromUrl() === "VetFarm" + ? [] + : [ + (item?.poultryRequest?.amount + ? item.poultryRequest.amount.toLocaleString() + : "0") + " ﷼", + (item?.weightInfo?.killHousePrice + ? item.weightInfo.killHousePrice.toLocaleString() + : "0") + " ﷼", + (item?.price ? item.price.toLocaleString() : "0") + "﷼", + ]), + item?.vetFarm?.vet?.user?.fullname + ? item.vetFarm.vet.user.fullname + + `(${item?.vetFarm?.vet?.user?.mobile || ""})` + : "فاقد دامپزشک", + item?.killPlace || "-", + item?.poultryRequest?.poultry?.address?.city?.name || "", + item?.poultryRequest.sendDate + ? format(new Date(item?.poultryRequest.sendDate), "yyyy/MM/dd") + : "-", + item?.poultryRequest.orderCode, + ...(getRoleFromUrl() === "VetFarm" + ? [] + : [ + + {item?.barDocumentStatus ? ( + + + {item?.barDocumentStatus?.title || "-"} + + + ) : ( + - + )} + , + , + item?.acceptedRealQuantity + ? item.acceptedRealQuantity.toLocaleString() + : "0", + item?.acceptedRealWeight + ? item.acceptedRealWeight.toLocaleString() + : "0", + item?.weightInfo?.finalIndexWeight + ? item.weightInfo.finalIndexWeight.toLocaleString() + : "0", + item?.wareHouseAcceptedRealQuantity + ? item.wareHouseAcceptedRealQuantity.toLocaleString() + : "0", + item?.wareHouseAcceptedRealWeight + ? item.wareHouseAcceptedRealWeight.toLocaleString() + : "0", + item?.weightLoss ? item.weightLoss.toLocaleString() : "0", + ]), + ...renderReportCell(item, i), + , + ]; + }); + + setTableData(d); + }, [data, aggregates]); + + const [openNotif] = useContext(AppContext); + + const handleDateChange1 = (date) => { + setSelectedDate1(date); + }; + + const handleDateChange2 = (date) => { + setSelectedDate2(date); + }; + + const handleTextChange = (event) => { + setTextValue(event.target.value); + }; + + const handleSubmit = async (event) => { + event.preventDefault(); + // Reset error state on manual submit (user retry) + setHas500Error(false); + dispatch(LOADING_START()); + + try { + const response = await axios.get( + `kill_house_request_bar_management/?check&role=${getRoleFromUrl()}&search=filter&value=${textValue}&date1=${selectedDate1}&date2=${selectedDate2}&page=${1}&page_size=${perPage}&without_quarantine_code_state=${hasDocumentState}` + ); + // Reset error state on successful response + setHas500Error(false); + setData(response.data?.results || []); + setTotalRows(response.data?.count || 0); + dispatch(LOADING_END()); + } catch (error) { + console.error("Error fetching data:", error); + const errorMessage = error?.message || ""; + const status = error?.response?.status; + const is500Error = errorMessage.includes("500") || status === 500; + + if (is500Error) { + setHas500Error(true); + openNotif({ + vertical: "top", + horizontal: "center", + msg: "مشکلی در دریافت اطلاعات پیش آمده است!", + severity: "error", + }); + } else { + openNotif({ + vertical: "top", + horizontal: "center", + msg: "مشکلی در دریافت اطلاعات پیش آمده است!", + severity: "error", + }); + } + setData([]); + setTotalRows(0); + dispatch(LOADING_END()); + } + dispatch( + vetFarmGetBarsOverview({ selectedDate1, selectedDate2, textValue }) + ) + .then((r) => { + if (r?.error) { + const errorMessage = r.error?.message || ""; + const is500Error = + errorMessage.includes("500") || + r.error?.status === 500 || + r.error?.statusCode === 500; + + if (is500Error) { + setHas500Error(true); + openNotif({ + vertical: "top", + horizontal: "center", + msg: "مشکلی در دریافت اطلاعات پیش آمده است!", + severity: "error", + }); + } + } else { + setHas500Error(false); + } + }) + .catch((error) => { + console.error("Error fetching bars overview:", error); + const errorMessage = error?.message || ""; + const status = error?.response?.status; + const is500Error = errorMessage.includes("500") || status === 500; + + if (is500Error) { + setHas500Error(true); + openNotif({ + vertical: "top", + horizontal: "center", + msg: "مشکلی در دریافت اطلاعات پیش آمده است!", + severity: "error", + }); + } + }); + }; + + useEffect(() => { + if (selectedTab === 0) { + fetchApiData(1); + } + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [selectedDate1, selectedDate2, hasDocumentState, selectedTab]); + + const ExcelExportButton = ({ pathLink, name, isSlaughter = false }) => { + const date = isSlaughter + ? `date1=${selectedDate1}&date2=${selectedDate2}` + : `start=${selectedDate1}&end=${selectedDate2}`; + + return ( + { + openNotif({ + vertical: "top", + horizontal: "center", + msg: "فایل اکسل در حال دانلود می باشد، این علمیات ممکن است زمان بر باشد لطفا صبر کنید.", + severity: "success", + }); + const link = `${axios.defaults.baseURL}${pathLink}/?${date}&key=${ + userInfo?.userProfile?.key || "" + }&role=${getRoleFromUrl()}&search=filter&value=${textValue || ""}`; + window.location.href = link; + }} + > + + + + + {name} + + + ); + }; + + const ProvinceOperatorButtons = ({ openNotif }) => { + const [isActiveOutProvinceMessage, setIsActiveOutProvinceMessage] = + useState(false); + const [isActiveInsideProvinceMessage, setIsActiveInsideProvinceMessage] = + useState(false); + + return ( + <> + {/* Out of Province Message */} + + + + + + پیام بار خارج استان + + + + {/* In Province Message */} + + + + + + پیام بار داخل استان + + + + ); + }; + + const tableTitle = ( + + {getRoleFromUrl() !== "ProvinceOperator" && ( + + + + {getRoleFromUrl() !== "VetFarm" && + getRoleFromUrl() !== "CityPoultry" && ( + + )} + + {(getRoleFromUrl() === "ProvinceOperator" || + getRoleFromUrl() === "ProvinceSupervisor" || + getRoleFromUrl() === "SuperAdmin" || + getRoleFromUrl() === "Supporter" || + getRoleFromUrl() === "AdminX" || + getRoleFromUrl() === "VetSupervisor") && ( + + )} + + {(getRoleFromUrl() === "ProvinceOperator" || + getRoleFromUrl() === "ProvinceSupervisor" || + getRoleFromUrl() === "SuperAdmin" || + getRoleFromUrl() === "Supporter" || + getRoleFromUrl() === "AdminX" || + getRoleFromUrl() === "VetSupervisor") && ( + + )} + + {getRoleFromUrl() !== "CityPoultry" && + getRoleFromUrl() !== "VetFarm" && ( + + )} + + {getRoleFromUrl() === "ProvinceOperator" && ( + + )} + + )} + + + مدیریت بارها + + ( + + )} + value={selectedDate1} + onChange={(e) => { + handleDateChange1(moment(e).format("YYYY-MM-DD")); + }} + /> + ( + + )} + value={selectedDate2} + onChange={(e) => { + handleDateChange2(moment(e).format("YYYY-MM-DD")); + }} + /> +
    + + + + {(getRoleFromUrl() === "SuperAdmin" || + getRoleFromUrl() === "Supporter" || + getRoleFromUrl() === "AdminX") && ( + + } + label="بدون وضعیت قرنطینه" + /> + )} +
    +
    +
    + ); + + let tabs; + + if ( + getRoleFromUrl() === "ProvinceOperator" || + getRoleFromUrl() === "SuperAdmin" || + getRoleFromUrl() === "CityOperator" || + getRoleFromUrl() === "AdminX" || + getRoleFromUrl() === "Supporter" + ) { + tabs = ( + + + + + + + + + + {getRoleFromUrl() === "Supporter" || + (getRoleFromUrl() === "AdminX" && ( + + ))} + + ); + } else if (getRoleFromUrl() === "LiveStockSupport") { + tabs = null; + } else { + tabs = ( + + + + {(getRoleFromUrl() === "VetFarm" || + getRoleFromUrl() === "VetSupervisor" || + getRoleFromUrl() === "ProvinceSupervisor") && ( + + )} + + {(getRoleFromUrl() === "VetFarm" || + getRoleFromUrl() === "VetSupervisor" || + getRoleFromUrl() === "ProvinceSupervisor") && ( + + )} + + {!getRoleFromUrl() === "VetFarm" && ( + + )} + + {getRoleFromUrl() !== "KillHouse" && } + + ); + } + + const aggregateValidationHasError = () => { + return ( + aggregates?.reduce((total, obj) => total + obj?.quantity, 0) > + aggregateStatus?.limitation || + !aggregates.every( + (obj) => + obj.poultryRequest?.poultry?.unitName === + aggregates[0]?.poultryRequest?.poultry?.unitName && + obj.killhouseUser?.name === aggregates[0]?.killhouseUser?.name + ) + ); + }; + + return ( + + + {tabs} + + {selectedTab === 0 && ( + + {tableTitle} + + + {vetFarmBarsOverview?.lenKillRequest + ? vetFarmBarsOverview.lenKillRequest.toLocaleString() + : "0"} + , + + {vetFarmBarsOverview?.killRequestQuantity + ? vetFarmBarsOverview.killRequestQuantity.toLocaleString() + : "0"} + , + + {vetFarmBarsOverview?.killRequestWeight + ? vetFarmBarsOverview.killRequestWeight.toLocaleString() + : "0"} + , + + {vetFarmBarsOverview?.allGovernmentalQuantity + ? vetFarmBarsOverview.allGovernmentalQuantity.toLocaleString() + : "0"} + , + + {vetFarmBarsOverview?.allGovernmentalWeight + ? vetFarmBarsOverview.allGovernmentalWeight.toLocaleString() + : "0"} + , + + {vetFarmBarsOverview?.allFreeQuantity + ? vetFarmBarsOverview.allFreeQuantity.toLocaleString() + : "0"} + , + + {vetFarmBarsOverview?.allFreeWeight + ? vetFarmBarsOverview.allFreeWeight.toLocaleString() + : "0"} + , + + {vetFarmBarsOverview?.avgWeight || "0"} + , + + {vetFarmBarsOverview?.minAge || "0"} + , + + {vetFarmBarsOverview?.maxAge || "0"} + , + + {vetFarmBarsOverview?.avgAge || "0"} + , + + {vetFarmBarsOverview?.lenKillRequestHasCode + ? vetFarmBarsOverview.lenKillRequestHasCode.toLocaleString() + : "0"} + , + + + {vetFarmBarsOverview?.lenKillRequestHasNotCode + ? vetFarmBarsOverview.lenKillRequestHasNotCode.toLocaleString() + : "0"} + , + + {vetFarmBarsOverview?.quantityOfKillRequestHasNotCode + ? vetFarmBarsOverview.quantityOfKillRequestHasNotCode.toLocaleString() + : "0"} + , + + {vetFarmBarsOverview?.differenceBar + ? vetFarmBarsOverview.differenceBar.toLocaleString() + : "0"} + , + + {vetFarmBarsOverview?.finalRealQuantity + ? vetFarmBarsOverview.finalRealQuantity.toLocaleString() + : "0"} + , + + {vetFarmBarsOverview?.lenCompleteWithKillHouse + ? vetFarmBarsOverview.lenCompleteWithKillHouse.toLocaleString() + : "0"} + , + + {vetFarmBarsOverview?.quantityFinalKillHouse + ? vetFarmBarsOverview.quantityFinalKillHouse.toLocaleString() + : "0"} + , + + {vetFarmBarsOverview?.weightFinalKillHouse + ? vetFarmBarsOverview.weightFinalKillHouse.toLocaleString() + : "0"} + , + + {vetFarmBarsOverview?.wareHouseBars + ? vetFarmBarsOverview.wareHouseBars.toLocaleString() + : "0"} + , + + {vetFarmBarsOverview?.wareHouseBarsQuantity + ? vetFarmBarsOverview.wareHouseBarsQuantity.toLocaleString() + : "0"} + , + + {vetFarmBarsOverview?.wareHouseBarsWeight + ? vetFarmBarsOverview.wareHouseBarsWeight.toLocaleString() + : "0"} + , + + {vetFarmBarsOverview?.wareHouseBarsWeightLose + ? vetFarmBarsOverview.wareHouseBarsWeightLose + .toFixed(2) + .toLocaleString() + : "0"} + , + ], + ]} + /> + + + {aggregateStatus?.allow && + (getRoleFromUrl() === "VetFarm" || + getRoleFromUrl() === "AdminX" || + getRoleFromUrl() === "SuperAdmin") && ( + + + + )} + + + + )} + + {selectedTab === 1 && } + {selectedTab === 2 && } + + {selectedTab === 3 && ( + + + + )} + + {(getRoleFromUrl() === "ProvinceOperator" || + getRoleFromUrl() === "CityOperator" || + getRoleFromUrl() === "SuperAdmin" || + getRoleFromUrl() === "VetFarm" || + getRoleFromUrl() === "VetSupervisor" || + getRoleFromUrl() === "AdminX" || + getRoleFromUrl() === "Supporter" || + getRoleFromUrl() === "ProvinceSupervisor") && ( + <> + {selectedTab === 4 && ( + + + + )} + + )} + + {selectedTab === 5 && } + {selectedTab === 6 && } + {selectedTab === 7 && } + {selectedTab === 8 && } + + ); +}; + +// const DisabledWrap = ({ children, checked }) => { +// return {children}; +// }; diff --git a/src/features/vet-farm/components/vet-farm-operations-options/VetFarmOperationOptions.js b/src/features/vet-farm/components/vet-farm-operations-options/VetFarmOperationOptions.js new file mode 100644 index 0000000..3d22f35 --- /dev/null +++ b/src/features/vet-farm/components/vet-farm-operations-options/VetFarmOperationOptions.js @@ -0,0 +1,300 @@ +import React, { useState } from "react"; +import { useDispatch, useSelector } from "react-redux"; +import { Grid } from "../../../../components/grid/Grid"; +import { RiFileExcel2Fill } from "react-icons/ri"; +import { Box, IconButton, Popover, Tooltip, Typography } from "@mui/material"; +import axios from "axios"; +import { DRAWER, OPEN_MODAL } from "../../../../lib/redux/slices/appSlice"; +import { VetFarmCancelBar } from "../vet-farm-cancel-bar/VetFarmCancelBar"; +import { SuperAdminSubmitBarStatus } from "../../../super-admin/components/super-admin-submit-bar-status/SuperAdminSubmitBarStatus"; +import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl"; +import TuneIcon from "@mui/icons-material/Tune"; +import ImageSearchIcon from "@mui/icons-material/ImageSearch"; +import CancelIcon from "@mui/icons-material/Delete"; +import { SlaughterEnterBarWeight } from "../../../file/components/slaughter-enter-bar-weight/SlaughterEnterBarWeight"; +import EditIcon from "@mui/icons-material/Edit"; +import DeleteForeverIcon from "@mui/icons-material/DeleteForever"; +import { VetFarmDeleteBar } from "../vet-farm-delete-bar/VetFarmDeleteBar"; +import LibraryAddIcon from "@mui/icons-material/LibraryAdd"; +import { VetFarmSavePrice } from "../vet-farm-save-price/VetFarmSavePrice"; +import { alpha, useTheme } from "@mui/material/styles"; +import { checkPathStartsWith } from "../../../../utils/checkPathStartsWith"; +export const VetFarmOperationOptions = ({ item, updateTable, isComplete }) => { + const dispatch = useDispatch(); + const selectedSubUser = useSelector( + (state) => state.userSlice.selectedSubUser + ); + const [anchorEl, setAnchorEl] = useState(null); + const theme = useTheme(); + const role = getRoleFromUrl(); + const isSuperAdmin = role === "SuperAdmin"; + const isSupporter = role === "Supporter"; + const isProvinceOperator = role === "ProvinceOperator"; + const isCityVet = role === "CityVet"; + const isVetFarm = role === "VetFarm"; + const isAdminX = role === "AdminX"; + + const canSubmitStatus = isSuperAdmin || isSupporter; + const canDeleteBar = isAdminX || isSuperAdmin || isSupporter; + const showCancelAction = + item.assignmentStateArchive === "pending" && + item.trash !== true && + !isVetFarm; + const cancelDisabled = + isSuperAdmin || isSupporter || isProvinceOperator || isCityVet; + const showPriceAction = !isVetFarm; + const showEnterBarInfoAction = isComplete; + const showDeleteBarAction = !isComplete && canDeleteBar; + const showExcelAction = !isComplete; + + const ExcelIcon = () => ( + + + + ); + + const renderAction = ({ + title, + IconComponent, + colorKey, + onClick, + disabled = false, + hidden = false, + componentProps, + placement = "left", + }) => { + if (hidden) { + return null; + } + + const paletteMain = + theme.palette[colorKey]?.main ?? theme.palette.primary.main; + const hoverBackground = alpha(paletteMain, 0.1); + + const handleActivation = () => { + if (disabled) { + return; + } + onClick?.(); + }; + + const handleKeyDown = (event) => { + if (event.key === "Enter" || event.key === " ") { + event.preventDefault(); + handleActivation(); + } + }; + + return ( + + + + + + + {title} + + + + + + ); + }; + + const handleClick = (event) => { + setAnchorEl(event.currentTarget); + }; + + const handleClose = () => { + setAnchorEl(null); + }; + + const open = Boolean(anchorEl); + const id = open ? "popover" : undefined; + + return ( + + + + + + + + {renderAction({ + title: "ثبت وضعیت سند", + IconComponent: ImageSearchIcon, + colorKey: "primary", + hidden: !canSubmitStatus, + disabled: item.assignmentInfo?.assignmentState === false, + onClick: () => { + handleClose(); + dispatch( + OPEN_MODAL({ + title: "ثبت وضعیت سند", + content: ( + + ), + }) + ); + }, + })} + + {renderAction({ + title: "ورود اطلاعات بار", + IconComponent: EditIcon, + colorKey: "primary", + hidden: !showEnterBarInfoAction, + placement: "right", + onClick: () => { + handleClose(); + dispatch( + DRAWER({ + title: "انجام عملیات تخصیص", + top: !(window.innerWidth <= 600), + bottom: window.innerWidth <= 600, + content: ( + + ), + }) + ); + }, + })} + + {renderAction({ + title: "لغو بار", + IconComponent: CancelIcon, + colorKey: "error", + hidden: !showCancelAction, + disabled: cancelDisabled, + onClick: () => { + handleClose(); + dispatch( + OPEN_MODAL({ + title: "لغو بار", + content: ( + + ), + }) + ); + }, + })} + + {renderAction({ + title: "حذف کامل بار", + IconComponent: DeleteForeverIcon, + colorKey: "error", + hidden: !showDeleteBarAction, + disabled: item?.trash, + onClick: () => { + handleClose(); + dispatch( + OPEN_MODAL({ + title: "آیا از حذف بار اطمینان دارید؟", + content: ( + + ), + }) + ); + }, + })} + + {renderAction({ + title: "خروجی اکسل", + IconComponent: ExcelIcon, + colorKey: "success", + hidden: !showExcelAction, + placement: "left", + onClick: () => handleClose(), + componentProps: { + component: "a", + href: `${ + axios.defaults.baseURL + }bar_for_each_persion_excel/?code=${item.barCode}${ + checkPathStartsWith("slaughter") + ? `&role_key=${selectedSubUser?.key}` + : "" + }`, + rel: "noreferrer", + target: "_blank", + }, + })} + + {renderAction({ + title: item?.priceRegisterDate + ? "ویرایش گزارش قیمت" + : "ثبت گزارش قیمت", + IconComponent: LibraryAddIcon, + colorKey: "primary", + hidden: !showPriceAction, + placement: "left-start", + onClick: () => { + handleClose(); + dispatch( + OPEN_MODAL({ + title: item?.priceRegisterDate + ? "ویرایش گزارش قیمت" + : "ثبت گزارش قیمت", + content: ( + + ), + }) + ); + }, + })} + + + + + ); +}; diff --git a/src/features/vet-farm/components/vet-farm-operations/VetFarmOperations.js b/src/features/vet-farm/components/vet-farm-operations/VetFarmOperations.js new file mode 100644 index 0000000..257f714 --- /dev/null +++ b/src/features/vet-farm/components/vet-farm-operations/VetFarmOperations.js @@ -0,0 +1,28 @@ +import { Grid } from "../../../../components/grid/Grid"; +import { SPACING } from "../../../../data/spacing"; +import { NavLink } from "../../../../components/nav-link/NavLink"; +import { useLocation } from "react-router-dom"; +import { Button } from "@mui/material"; +import { ROUTE_VETFARM_REGISTER_INFO } from "../../../../routes/routes"; + +export const VetFarmOperations = () => { + const { pathname } = useLocation(); + + return ( + + + + + + ); +}; diff --git a/src/features/vet-farm/components/vet-farm-sale-out-of-province/VetFarmOutOfProvince.js b/src/features/vet-farm/components/vet-farm-sale-out-of-province/VetFarmOutOfProvince.js new file mode 100644 index 0000000..dde5010 --- /dev/null +++ b/src/features/vet-farm/components/vet-farm-sale-out-of-province/VetFarmOutOfProvince.js @@ -0,0 +1,348 @@ +import React, { useContext, useEffect, useState } from "react"; +import { + Button, + IconButton, + TextField, + Tooltip, + Typography, +} from "@mui/material"; +import { DatePicker } from "@mui/x-date-pickers"; +import moment from "moment"; +import { useDispatch, useSelector } from "react-redux"; +import axios from "axios"; +import { RiFileExcel2Fill, RiSearchLine } from "react-icons/ri"; +import { AppContext } from "../../../../contexts/AppContext"; +import ResponsiveTable from "../../../../components/responsive-table/ResponsiveTable"; +import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl"; +import { + LOADING_END, + LOADING_START, + OPEN_MODAL, +} from "../../../../lib/redux/slices/appSlice"; +import { VetFarmSubmitClearanceCode } from "../vet-farm-submit-clearance-code/VetFarmSubmitClearanceCode"; +import { VetFarmEditOutOfProvinceTrafficCode } from "../vet-farm-edit-out-out-province-traffic-code/VetFarmEditOutOfProvinceTrafficCode"; +import { Grid } from "../../../../components/grid/Grid"; +import { vetFarmOutProvinceGetDashboard } from "../../services/vet-farm-out-province-get-dashboard"; +import { formatJustDate } from "../../../../utils/formatTime"; +import AddCircleOutlineIcon from "@mui/icons-material/AddCircleOutline"; +import VisibilityIcon from "@mui/icons-material/Visibility"; + +export const VetFarmOutOfProvince = ({ readOnly }) => { + const [data, setData] = useState([]); + const [totalRows, setTotalRows] = useState(0); + const [perPage, setPerPage] = useState(10); + const [textValue, setTextValue] = useState(""); + const [page, setPage] = useState(1); + const [dashboardData, setDashboardData] = useState([]); + const [dataTableM, setDataTableM] = useState([]); + + const [, , selectedDate1, setSelectedDate1, selectedDate2, setSelectedDate2] = + useContext(AppContext); + + const userKey = useSelector((state) => state.userSlice.userProfile.key); + + const dispatch = useDispatch(); + + useEffect(() => { + const currentDate = moment(new Date()).format("YYYY-MM-DD"); + setSelectedDate1(currentDate); + setSelectedDate2(currentDate); + }, []); + + const handleTextChange = (event) => { + setTextValue(event.target.value); + }; + + const fetchApiData = async (page) => { + dispatch(LOADING_START()); + const response = await axios.get( + `out-province-poultry-requests/?search=filter&value=${textValue}&page=${page}&role=${getRoleFromUrl()}&page_size=${perPage}&date1=${selectedDate1}&date2=${selectedDate2}&state=accepted` + ); + + dispatch(LOADING_END()); + setData(response.data.results); + setTotalRows(response.data.count); + }; + + const handlePageChange = (page) => { + fetchApiData(page); + setPage(page); + }; + + const handlePerRowsChange = (perRows) => { + setPerPage(perRows); + setPage(1); + }; + + const updateTable = () => { + fetchApiData(page !== 0 ? page : 1); + }; + useEffect(() => { + fetchApiData(1); + dispatch( + vetFarmOutProvinceGetDashboard({ + selectedDate1, + selectedDate2, + text: textValue, + }) + ).then((r) => { + setDashboardData(r.payload.data); + }); + }, [dispatch, selectedDate1, selectedDate2, perPage]); + + const handleSubmit = async (event) => { + event.preventDefault(); + dispatch(LOADING_START()); + + try { + const response = await axios.get( + `out-province-poultry-requests/?search=filter&value=${textValue}&date1=${selectedDate1}&date2=${selectedDate2}&state=accepted&role=${getRoleFromUrl()}` + ); + + setData(response.data.results); + setTotalRows(response.data.count); + dispatch(LOADING_END()); + } catch (error) { + console.error("Error fetching data:", error); + } + }; + + useEffect(() => { + const d = data?.map((item, i) => { + return [ + page === 1 ? i + 1 : i + perPage * (page - 1) + 1, + + + {item.outState} + , + `${item?.registrar?.fullname}`, + item.orderCode, + item.buyer?.firstName + ? `${item.buyer?.firstName} ${item.buyer?.lastName} (${item.buyer?.mobile}) / ${item.buyer.province} - ${item.buyer.city}` + : `${item.buyerFullname} (${item.buyerMobile}) / ${item.buyerProvince} - ${item.buyerCity}`, + item?.hasWage ? item?.payerFullname : "-", + `${item.poultry?.unitName} (${item.poultry.user.mobile})`, + item?.poultry?.age, + item?.IndexWeight?.toLocaleString(), + // item?.killer + // ? `${item?.killer?.name} (${item?.killer?.killHouseOperator?.user?.mobile})` + // : "-", + item.quantity.toLocaleString(), + Math.floor(item.IndexWeight * item.quantity)?.toLocaleString(), + + { + dispatch( + OPEN_MODAL({ + title: "ثبت کد قرنطینه", + size: { + xs: "340px", + md: "690px", + }, + content: ( + + ), + }) + ); + }} + > + {getRoleFromUrl() === "VetFarm" || getRoleFromUrl() === "AdminX" ? ( + + ) : ( + + )} + + , + + item?.totalSystemQuarantineQuantity?.toLocaleString() || "-", + readOnly ? ( + item?.outProvinceDriverInfo?.driverhealthCode + ) : ( + + ), + + item?.outProvinceDriverInfo?.driverCar || "-", + item?.outProvinceDriverInfo?.driverPelak + ? item?.outProvinceDriverInfo?.driverPelak + : "-", + item?.outProvinceDriverInfo?.driverName + ? item?.outProvinceDriverInfo?.driverName + : "", + item?.outProvinceDriverInfo?.driverMobile + ? item?.outProvinceDriverInfo?.driverMobile + : "", + formatJustDate(item?.createDate), + formatJustDate(item?.sendDate), + item?.totalWageAmount || "-", + item?.hatching?.city, + item?.hatching?.province, + item?.hatching?.leftOver?.toLocaleString(), + item?.hatching?.hatchingQuantity?.toLocaleString(), + ]; + }); + + setDataTableM(d); + }, [data]); + + const tableTitle = ( + + + ( + + )} + value={selectedDate1} + onChange={(e) => { + setSelectedDate1(moment(e).format("YYYY-MM-DD")); + }} + /> + + + ( + + )} + value={selectedDate2} + onChange={(e) => { + setSelectedDate2(moment(e).format("YYYY-MM-DD")); + }} + /> + +
    + + + + + + + + + + +
    + ); + + return ( + + + {tableTitle} + + + + + + + ); +}; diff --git a/src/features/vet-farm/components/vet-farm-save-price/VetFarmSavePrice.js b/src/features/vet-farm/components/vet-farm-save-price/VetFarmSavePrice.js new file mode 100644 index 0000000..43cbeb7 --- /dev/null +++ b/src/features/vet-farm/components/vet-farm-save-price/VetFarmSavePrice.js @@ -0,0 +1,201 @@ +import { useFormik } from "formik"; +import { useContext, useEffect, useState } from "react"; +import { useDispatch } from "react-redux"; +import { Yup } from "../../../../lib/yup/yup"; +import { Grid } from "../../../../components/grid/Grid"; +import { + Button, + FormControlLabel, + TextField, + Typography, + RadioGroup, + Radio, + FormLabel, + FormControl, + CircularProgress, +} from "@mui/material"; +import { FileUploader } from "../../../../components/file-uploader/FileUploader"; +import { CLOSE_MODAL } from "../../../../lib/redux/slices/appSlice"; +import { AppContext } from "../../../../contexts/AppContext"; +import { vetFarmSavePriceService } from "../../services/vet-farm-save-price"; + +export const VetFarmSavePrice = ({ item, updateTable }) => { + const [openNotif] = useContext(AppContext); + const [filesList, setFilesList] = useState([]); + const [isSubmitting, setIsSubmitting] = useState(false); + const dispatch = useDispatch(); + + const isEditMode = !!item?.priceRegisterDate; + const hanleFilesChange = (e) => { + setFilesList(e); + }; + + const formik = useFormik({ + initialValues: { + key: item.key || "", + price: item?.price || "", + description: item?.description || "", + settlementType: item?.settlement_type || "cash", + }, + validationSchema: Yup.object({ + price: Yup.number() + .required("لطفا قیمت را وارد کنید") + .typeError("لطفا یک عدد معتبر وارد کنید") + .min(0, "قیمت نمی‌تواند منفی باشد"), + description: Yup.string() + .required("این فیلد اجباری است!") + .min(10, "توضیحات باید حداقل ۱۰ کاراکتر باشد") + .max(500, "توضیحات نمی‌تواند بیشتر از ۵۰۰ کاراکتر باشد"), + settlementType: Yup.string().required("نوع تسویه الزامی است"), + }), + onSubmit: (values) => { + setIsSubmitting(true); + + const formData = new FormData(); + formData.append("key", item?.key); + formData.append("settlement_type", values.settlementType); + formData.append("price", values.price); + formData.append("description", values.description); + + filesList.forEach((file) => { + formData.append(`file`, file); + }); + + dispatch(vetFarmSavePriceService(formData)).then((r) => { + if (r.payload.error) { + openNotif({ + vertical: "top", + horizontal: "center", + msg: r.payload.error, + severity: "error", + }); + } else { + setIsSubmitting(false); + updateTable(); + dispatch(CLOSE_MODAL()); + openNotif({ + vertical: "top", + horizontal: "center", + msg: isEditMode + ? "ویرایش با موفقیت انجام شد." + : "ثبت با موفقیت انجام شد.", + severity: "success", + }); + } + }); + }, + }); + + useEffect(() => { + if (isEditMode) { + formik.setValues({ + key: item?.key || "", + price: item.price || "", + description: item.description || "", + settlementType: item.settlement_type || "cash", + }); + } + formik.validateForm(); + }, [item]); + + return ( +
    + + + + نوع تسویه + + } label="نقدی" /> + } + label="مدت دار" + /> + + + + + + + + + + + + + + + {isEditMode + ? "فایل‌های موجود:" + : "لطفا فایل‌های مورد نیاز را آپلود کنید"} + + + + {isEditMode + ? "توجه: آپلود فایل جدید باعث جایگزینی فایل‌های قبلی می‌شود" + : "حداکثر حجم هر فایل: 5MB"} + + + + + + + + + +
    + ); +}; diff --git a/src/features/vet-farm/components/vet-farm-submit-clearance-code/VetFarmSubmitClearanceCode.js b/src/features/vet-farm/components/vet-farm-submit-clearance-code/VetFarmSubmitClearanceCode.js new file mode 100644 index 0000000..3a616cb --- /dev/null +++ b/src/features/vet-farm/components/vet-farm-submit-clearance-code/VetFarmSubmitClearanceCode.js @@ -0,0 +1,578 @@ +import React, { useContext, useRef, useState, useEffect } from "react"; +import { + InputAdornment, + TextField, + Tooltip, + CircularProgress, + Grid, + Box, + Button, + Paper, + Typography, + IconButton, + Collapse, + useMediaQuery, + useTheme, +} from "@mui/material"; +import { useDispatch } from "react-redux"; +import PageviewIcon from "@mui/icons-material/Pageview"; +import EditIcon from "@mui/icons-material/Edit"; +import DeleteIcon from "@mui/icons-material/Delete"; +import { PropTypes } from "prop-types"; +import { AppContext } from "../../../../contexts/AppContext"; +import { LabelField } from "../../../../components/label-field/LabelField"; +import { vetFarmSubmitClearenceCodeService } from "../../services/vet-farm-submit-quarantine-code"; +import { vetFarmEditQuarantineCodeService } from "../../services/vet-farm-edit-quarantine-code"; +import { vetFarmGetQuarantineCodeService } from "../../services/vet-farm-get-quarantine-code"; +import { vetFarmDeleteQuarantineCodeService } from "../../services/vet-farm-delete-quarantine-code"; +import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl"; +import { CLOSE_MODAL } from "../../../../lib/redux/slices/appSlice"; + +export const VetFarmSubmitClearanceCode = ({ readOnly, updateTable, item }) => { + const dispatch = useDispatch(); + const [openNotif] = useContext(AppContext); + const theme = useTheme(); + const isMobile = useMediaQuery(theme.breakpoints.down("md")); + const [currentSubmittingIndex, setCurrentSubmittingIndex] = useState(null); + const [codes, setCodes] = useState([]); + const [isAddNewCodeOpen, setIsAddNewCodeOpen] = useState(false); + const [newCode, setNewCode] = useState({ + code: "", + quantity: "", + trafficCode: "", + requestCodeKey: "", + }); + + const role = getRoleFromUrl() === "VetFarm" || getRoleFromUrl() === "AdminX"; + + const fetchQuarantineCodes = () => { + dispatch( + vetFarmGetQuarantineCodeService({ + poultry_request_key: item?.key, + }) + ).then((r) => { + if (r.payload?.data) { + setCodes( + r.payload.data.map((code) => ({ + ...code, + requestCodeKey: code.key, + isEdit: false, + })) + ); + } + }); + }; + + useEffect(() => { + fetchQuarantineCodes(); + }, [dispatch, item?.key]); + + const handleSubmitNewCode = () => { + dispatch(CLOSE_MODAL()); + + if (!newCode.code || !newCode.quantity) { + openNotif({ + vertical: "top", + horizontal: "center", + msg: "لطفا کد و تعداد را وارد کنید", + severity: "error", + }); + return; + } + + dispatch( + vetFarmSubmitClearenceCodeService({ + quarantine_code: newCode.code.toUpperCase(), + quarantine_quantity: newCode.quantity, + traffic_code: newCode.trafficCode || null, + poultry_request_key: item?.key, + }) + ).then((r) => { + if (r.payload.error) { + openNotif({ + vertical: "top", + horizontal: "center", + msg: r.payload.error, + severity: "error", + }); + } else { + openNotif({ + vertical: "top", + horizontal: "center", + msg: "کد با موفقیت ثبت شد", + severity: "success", + }); + + fetchQuarantineCodes(); + + setCodes([ + ...codes, + { + quarantineCode: newCode.code.toUpperCase(), + quarantineQuantity: newCode.quantity, + trafficCode: newCode.trafficCode, + requestCodeKey: r.payload?.key, + isEdit: false, + }, + ]); + setNewCode({ code: "", quantity: "", trafficCode: "" }); + + if (updateTable) updateTable(); + } + }); + }; + + const handleEditCode = (index) => { + const codeItem = codes[index]; + + if (!codeItem.quarantineCode || !codeItem.quarantineQuantity) { + openNotif({ + vertical: "top", + horizontal: "center", + msg: "لطفا کد و تعداد را وارد کنید", + severity: "error", + }); + return; + } + + setCurrentSubmittingIndex(index); + + dispatch( + vetFarmEditQuarantineCodeService({ + request_code_key: codeItem?.requestCodeKey, + quarantine_code: codeItem?.quarantineCode.toUpperCase(), + quarantine_quantity: codeItem?.quarantineQuantity, + traffic_code: codeItem?.trafficCode || null, + }) + ) + .then((r) => { + if (r.payload.error) { + openNotif({ + vertical: "top", + horizontal: "center", + msg: r.payload.error || "خطا در ویرایش کد", + severity: "error", + }); + } else { + openNotif({ + vertical: "top", + horizontal: "center", + msg: "کد با موفقیت ویرایش شد", + severity: "success", + }); + + setCodes((prevCodes) => + prevCodes.map((code, i) => + i === index ? { ...code, isEdit: false } : code + ) + ); + fetchQuarantineCodes(); + + if (updateTable) updateTable(); + } + }) + .finally(() => { + setCurrentSubmittingIndex(null); + }); + }; + + const handleDeleteCode = (index) => { + const codeItem = codes[index]; + if (!codeItem?.requestCodeKey) return; + + setCurrentSubmittingIndex(index); + + dispatch( + vetFarmDeleteQuarantineCodeService({ + request_code_key: codeItem?.requestCodeKey, + }) + ) + .then((r) => { + if (r.error) { + openNotif({ + vertical: "top", + horizontal: "center", + msg: r.error, + severity: "error", + }); + } else { + openNotif({ + vertical: "top", + horizontal: "center", + msg: "کد با موفقیت حذف شد", + severity: "success", + }); + + setCodes((prevCodes) => prevCodes.filter((_, i) => i !== index)); + fetchQuarantineCodes(); + + if (updateTable) updateTable(); + } + }) + .finally(() => { + setCurrentSubmittingIndex(null); + }); + }; + + const handleCodeChange = (index, field, value) => { + setCodes((prevCodes) => + prevCodes.map((code, i) => + i === index ? { ...code, [field]: value } : code + ) + ); + }; + + const toggleEdit = (index) => { + setCodes((prevCodes) => + prevCodes.map((code, i) => + i === index ? { ...code, isEdit: !code.isEdit } : code + ) + ); + }; + + const handleNewCodeChange = (field, value) => { + setNewCode({ + ...newCode, + [field]: value, + }); + }; + + return ( + + + {codes.length > 0 && ( + + + کدهای ثبت شده: + + {codes.map((codeItem, index) => ( + + + + handleCodeChange(index, "trafficCode", e.target.value) + } + disabled={!codeItem.isEdit || !role} + sx={{ width: { xs: "46%", md: "160px" } }} + /> + + handleCodeChange(index, "quarantineCode", e.target.value) + } + disabled={!codeItem.isEdit || !role} + InputProps={{ + startAdornment: ( + + + + ), + }} + sx={{ width: { xs: "46%", md: "160px" } }} + /> + + + handleCodeChange( + index, + "quarantineQuantity", + e.target.value + ) + } + disabled={!codeItem.isEdit || !role} + sx={{ width: { xs: "35%", md: "80px" } }} + /> + + {codeItem.isEdit ? ( + + ) : ( + + {role && ( + toggleEdit(index)} + disabled={readOnly} + size="small" + > + + + )} + {role && ( + handleDeleteCode(index)} + disabled={ + readOnly || currentSubmittingIndex === index + } + size="small" + > + + + )} + + + استعلام + + + {codeItem?.systemQuarantineQuantity} + + + + )} + + + ))} + + )} + + + {role && !readOnly && ( + <> + {isMobile ? ( + <> + + + + + + + + handleNewCodeChange( + "trafficCode", + e.target.value.toUpperCase() + ) + } + fullWidth + /> + + + + handleNewCodeChange( + "code", + e.target.value.toUpperCase() + ) + } + fullWidth + /> + + + + + handleNewCodeChange("quantity", e.target.value) + } + fullWidth + /> + + + + + + + + + ) : ( + + + + + + handleNewCodeChange( + "trafficCode", + e.target.value.toUpperCase() + ) + } + fullWidth + /> + + + + handleNewCodeChange( + "code", + e.target.value.toUpperCase() + ) + } + fullWidth + /> + + + + + handleNewCodeChange("quantity", e.target.value) + } + fullWidth + /> + + + + + + + + )} + + )} + + ); +}; + +const ViewCodeComponent = ({ clearanceCode }) => { + const formRef = useRef(null); + + const handleImageClick = () => { + if (formRef.current) { + formRef.current.submit(); + } + }; + + return ( + +
    + + + +
    + ); +}; + +VetFarmSubmitClearanceCode.propTypes = { + item: PropTypes.shape({ + key: PropTypes.string, + quarantine_code: PropTypes.string, + quarantine_quantity: PropTypes.string, + quarantineCodes: PropTypes.array, + }), + updateTable: PropTypes.func, + readOnly: PropTypes.bool, +}; + +VetFarmSubmitClearanceCode.defaultProps = { + readOnly: false, + updateTable: () => {}, +}; diff --git a/src/features/vet-farm/components/vet-farm-submit-contradicts/VetFarmSubmitContradicts.js b/src/features/vet-farm/components/vet-farm-submit-contradicts/VetFarmSubmitContradicts.js new file mode 100644 index 0000000..b08a37b --- /dev/null +++ b/src/features/vet-farm/components/vet-farm-submit-contradicts/VetFarmSubmitContradicts.js @@ -0,0 +1,211 @@ +import React, { useContext } from "react"; +import { Yup } from "../../../../lib/yup/yup"; +import { useFormik } from "formik"; +import { Grid } from "../../../../components/grid/Grid"; +import { Button, TextField } from "@mui/material"; +import { + CLOSE_MODAL, + LOADING_END, + LOADING_START, +} from "../../../../lib/redux/slices/appSlice"; +import { SPACING } from "../../../../data/spacing"; +import { useDispatch } from "react-redux"; +import { vetFarmSubmitContradictsService } from "../../services/vet-farm-submit-contdadicts"; +import { AppContext } from "../../../../contexts/AppContext"; +import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl"; + +export const VetFarmSubmitContradicts = ({ item, updateTable }) => { + const [openNotif] = useContext(AppContext); + const dispatch = useDispatch(); + const formik = useFormik({ + initialValues: { + realNumber: "", + }, + validationSchema: Yup.object({ + realNumber: Yup.string() + .typeError("لطفا فیلد را به درستی وارد کنید.!") + .required("این فیلد اجباری است!"), + }), + }); + + return ( + <> + + + + + + + + + + + + + + + ); +}; diff --git a/src/features/vet-farm/components/vet-farm-submit-farm-info-form/VetFarmSubmitFarmInfoForm.js b/src/features/vet-farm/components/vet-farm-submit-farm-info-form/VetFarmSubmitFarmInfoForm.js new file mode 100644 index 0000000..c7b1b19 --- /dev/null +++ b/src/features/vet-farm/components/vet-farm-submit-farm-info-form/VetFarmSubmitFarmInfoForm.js @@ -0,0 +1,420 @@ +import { + Autocomplete, + Button, + // Checkbox, + Card, + CardContent, + CardActions, + FormControl, + IconButton, + InputLabel, + ListItemText, + MenuItem, + OutlinedInput, + Select, + TextField, + Typography, + Box, +} from "@mui/material"; +import { Grid } from "../../../../components/grid/Grid"; +import { SPACING } from "../../../../data/spacing"; +import React, { useContext, useEffect, useRef, useState } from "react"; +import { Yup } from "../../../../lib/yup/yup"; +import { useFormik } from "formik"; +import SearchIcon from "@mui/icons-material/Search"; +import DeleteIcon from "@mui/icons-material/Delete"; + +import { + DRAWER, + LOADING_END, + LOADING_START, +} from "../../../../lib/redux/slices/appSlice"; +import { useDispatch } from "react-redux"; +import { vetFarmNewFarm } from "../../services/vet-farm-new-farm"; +import { getVetFarmData } from "../../services/vet-farm-get-farm-data"; +import { getVetFarms } from "../../services/vet-farm-get-farms"; +import { AppContext } from "../../../../contexts/AppContext"; +import { inspectorDeleteVetFarmService } from "../../../inspector/services/inspector-delete-vet-farm"; + +export const VetFarmSubmitFarmInfoForm = ({ + vetFarmKey, + item, + updateTable, +}) => { + const [isExistPolutry, setIsExistPolutry] = useState(true); + const [poultryKey, setPolutryKey] = useState(""); + const [polutryData, setpolutryData] = useState(""); + + // const [numberOfhalls, setNumberOfHalls] = useState(1); + const [numberOfHallsArray, setNumberOfHallsArray] = useState([]); + const [registerVetHalls, setRegisterVetHalls] = useState([]); + + const [openNotif] = useContext(AppContext); + + const ITEM_HEIGHT = 48; + const ITEM_PADDING_TOP = 8; + const MenuProps = { + PaperProps: { + style: { + maxHeight: ITEM_HEIGHT * 4.5 + ITEM_PADDING_TOP, + width: 250, + }, + }, + }; + + const [hallName, setHallName] = React.useState([]); + const [avicultureData, setAvicultureData] = React.useState([]); + + useEffect(() => { + if (polutryData) { + setAvicultureData( + polutryData?.map((item) => ({ + id: item.key, + label: item.unitName, + halls: item.numberOfHalls, + registerVetHalls: item.registerVetHalls, + })) + ); + } + }, [polutryData]); + + const handleChange = (event) => { + const { + target: { value }, + } = event; + + setHallName(typeof value === "string" ? value.split(",") : value); + }; + + const dispatch = useDispatch(); + const formik = useFormik({ + initialValues: { + uniqueID: "", + hatching: "", + }, + validationSchema: Yup.object({ + uniqueID: Yup.number() + .required("این فیلد اجباری است!") + .typeError("لطفا فیلد را به صورت عددی وارد کنید!"), + hatching: Yup.string() + .required("این فیلد اجباری است!") + .typeError("لطفا فیلد را به درستی وارد کنید!"), + }), + }); + + // useEffect(() => { + // if (formik.values.uniqueID) { + // dispatch(LOADING_START()); + // // setNumberOfHalls(); + // setNumberOfHallsArray([]); + // setHallName([]); + // dispatch(getVetFarmData(formik.values.uniqueID)).then((r) => { + // if (r.error) { + // dispatch(LOADING_END()); + // openNotif({ + // vertical: "top", + // horizontal: "center", + // msg: "مرغداری با این شناسه یافت نشد!", + // severity: "error", + // }); + // } + // if (r.payload.data) { + // dispatch(LOADING_END()); + // setIsExistPolutry(false); + // setpolutryData(r.payload.data); + // } + // }); + // } + // }, [formik.values.uniqueID]); + + // useEffect(() => { + // dispatch(avicultureGetHalls()).then((r) => { + // setNumberOfHalls(r.payload.data[0]?.poultry.numberOfHalls); + // if (r) + // }); + // }, [poultryKey]); + + useEffect(() => { + formik.validateForm(); + }, []); + + const poultryRef = useRef(); + + useEffect(() => { + const el = poultryRef.current.querySelector( + ".MuiAutocomplete-popupIndicator" + ); + el.click(); + }, [avicultureData]); + + return ( + + + + + { + if (formik.values.uniqueID) { + dispatch(LOADING_START()); + // setNumberOfHalls(); + setNumberOfHallsArray([]); + setHallName([]); + dispatch(getVetFarmData(formik.values.uniqueID)).then((r) => { + if (r.error) { + dispatch(LOADING_END()); + openNotif({ + vertical: "top", + horizontal: "center", + msg: "مرغداری با این شناسه یافت نشد!", + severity: "error", + }); + } + if (r.payload.data) { + dispatch(LOADING_END()); + setIsExistPolutry(false); + setpolutryData(r.payload.data); + poultryRef.current.focus(); + } + }); + } + }} + > + + + + + + { + setPolutryKey(value.id); + // setNumberOfHalls(value.halls); + setRegisterVetHalls(value.registerVetHalls); + setHallName([]); + setNumberOfHallsArray(new Array(value.halls).fill("*")); + }} + renderInput={(params) => ( + + )} + /> + + + + + + {numberOfHallsArray.length ? "انتخاب سالن" : "سالنی موجود نیست"} + + + + + + + + + + + فارم های ثبت شده + + + {item?.farms?.map((it, i) => { + return ( + + + + + + {it.poultryName} + + + + + + + + + ); + })} + + + + ); +}; diff --git a/src/features/vet-farm/components/vet-farm-submit-farm-info-losses/VetFarmSubmitFarmInfoLosses.js b/src/features/vet-farm/components/vet-farm-submit-farm-info-losses/VetFarmSubmitFarmInfoLosses.js new file mode 100644 index 0000000..7a6ace8 --- /dev/null +++ b/src/features/vet-farm/components/vet-farm-submit-farm-info-losses/VetFarmSubmitFarmInfoLosses.js @@ -0,0 +1,123 @@ +import React, { useContext } from "react"; +import { useFormik } from "formik"; +import * as Yup from "yup"; +import { + Radio, + RadioGroup, + FormControlLabel, + FormControl, + TextField, + Button, + Typography, +} from "@mui/material"; +import { Grid } from "../../../../components/grid/Grid"; +import { useDispatch } from "react-redux"; +import { cityEditHatchingQuantityService } from "../../../city/services/city-edit-hatching-quantity"; +import { AppContext } from "../../../../contexts/AppContext"; +import { CLOSE_MODAL } from "../../../../lib/redux/slices/appSlice"; + +export const VetFarmSubmitFarmInfoLosses = ({ item, updateTable }) => { + const dispatch = useDispatch(); + + const [openNotif] = useContext(AppContext); + const formik = useFormik({ + initialValues: { + lossType: "aggregate", + lossVolume: "", + }, + validationSchema: Yup.object({ + lossType: Yup.string().required("لطفاً نوع خسارت را انتخاب کنید."), + lossVolume: Yup.string() + .required("لطفاً حجم تلفات را وارد کنید.") + .matches(/^\d+$/, "حجم تلفات باید عدد باشد."), + }), + onSubmit: (values) => { + dispatch( + cityEditHatchingQuantityService({ + key: item?.key, + end_period_losses: true, + type: values.lossType, + losses: parseInt(values.lossVolume), + }) + ).then((r) => { + if (r.payload.error) { + openNotif({ + vertical: "top", + horizontal: "center", + msg: r.payload.error, + severity: "error", + }); + } else { + openNotif({ + vertical: "top", + horizontal: "center", + msg: "عملیات با موفقیت انجام شد.", + severity: "success", + }); + updateTable(); + dispatch(CLOSE_MODAL()); + } + }); + }, + }); + + return ( +
    + + + + + } + label="کل تلفات دوره (پایان کار)" + /> + } + label="افزودن به تلفات دامپزشک فارم" + /> + + {formik.touched.lossType && formik.errors.lossType && ( +
    + {formik.errors.lossType} +
    + )} +
    +
    + + + + + + {formik.values.lossType === "aggregate" && ( + + اخطار: تلفات وارد شده جایگزین کل تلفات خواهد شد! + + )} + + + + +
    +
    + ); +}; diff --git a/src/features/vet-farm/components/vet-farm-submit-farm-info/VetFarmSubmitFarmInfo.js b/src/features/vet-farm/components/vet-farm-submit-farm-info/VetFarmSubmitFarmInfo.js new file mode 100644 index 0000000..589879a --- /dev/null +++ b/src/features/vet-farm/components/vet-farm-submit-farm-info/VetFarmSubmitFarmInfo.js @@ -0,0 +1,365 @@ +import React, { useContext, useEffect, useState } from "react"; +import { + Button, + IconButton, + List, + ListItem, + ListItemButton, + ListItemIcon, + Popover, + TextField, + Typography, +} from "@mui/material"; +import { useDispatch } from "react-redux"; +import axios from "axios"; +import { + CLOSE_MODAL, + DRAWER, + LOADING_END, + LOADING_START, + OPEN_MODAL, +} from "../../../../lib/redux/slices/appSlice"; +import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl"; +import { Grid } from "../../../../components/grid/Grid"; +import ResponsiveTable from "../../../../components/responsive-table/ResponsiveTable"; +import { ROUTE_VETFARM_INSPECTIONS } from "../../../../routes/routes"; +import { VetFarmSubmitInspectionForm } from "../vet-farm-submit-inspection-form/VetFarmSubmitInspectionForm"; +import { useNavigate } from "react-router-dom"; +import { AppContext } from "../../../../contexts/AppContext"; +import { vetFarmDeleteFarm } from "../../services/vet-farm-delete-farm"; +import DeleteOutlineOutlinedIcon from "@mui/icons-material/DeleteOutlineOutlined"; +import VisibilityIcon from "@mui/icons-material/Visibility"; +import PlaylistAddCheckOutlinedIcon from "@mui/icons-material/PlaylistAddCheckOutlined"; +import TuneIcon from "@mui/icons-material/Tune"; +import { RiSearchLine } from "react-icons/ri"; + +export const VetFarmSubmitFarmInfo = () => { + const dispatch = useDispatch(); + const navigate = useNavigate(); + + const handleTextChange = (event) => { + setTextValue(event.target.value); + }; + const [openNotif] = useContext(AppContext); + + const [data, setData] = useState([]); + const [totalRows, setTotalRows] = useState(0); + const [perPage, setPerPage] = useState(10); + const [textValue, setTextValue] = useState(""); + const [page, setPage] = useState(1); + const [tableData, setTableData] = useState([]); + + const fetchApiData = async (page) => { + dispatch(LOADING_START()); + const response = await axios.get( + `management_vet_farm/?search=filter&value=${textValue}&role=${getRoleFromUrl()}&page=${page}&page_size=${perPage}` + ); + dispatch(LOADING_END()); + setData(response.data.results); + setTotalRows(response.data.count); + }; + + const handlePageChange = (page) => { + fetchApiData(page); + setPage(page); + }; + + const handlePerRowsChange = (perRows) => { + setPerPage(perRows); + setPage(1); + }; + + const updateTable = () => { + fetchApiData(page !== 0 ? page : 1); + }; + + const VetFarmActions = ({ item, index }) => { + const [anchorEl, setAnchorEl] = useState(null); + + const handleOpen = (event) => { + setAnchorEl(event.currentTarget); + }; + + const handleClose = () => { + setAnchorEl(null); + }; + + const open = Boolean(anchorEl); + const id = open ? `vet-farm-actions-${item?.key ?? index}` : undefined; + + const handleView = () => { + handleClose(); + navigate(ROUTE_VETFARM_INSPECTIONS + item.key); + }; + + const handleCreateInspection = () => { + handleClose(); + dispatch( + DRAWER({ + right: !(window.innerWidth <= 600), + bottom: window.innerWidth <= 600, + title: "ثبت اطلاعات بازرسی", + content: ( + + ), + }) + ); + }; + + const handleDelete = () => { + handleClose(); + dispatch( + OPEN_MODAL({ + title: "سالن را حذف میکنید؟", + content: ( + + + + + + + + + ), + }) + ); + }; + + return ( + <> + + + + + + + + + + + نمایش پرونده + + + + + + + + ایجاد بازرسی + + + + + + + + حذف فارم + + + + + + ); + }; + + useEffect(() => { + const d = data?.map((item, i) => { + if (getRoleFromUrl() === "VetFarm") { + return [ + page === 1 ? i + 1 : i + perPage * (page - 1) + 1, + item.poultry?.breedingUniqueId + ? Number(item.poultry.breedingUniqueId) + : "-", + item.poultry?.unitName, + item.poultry?.address?.city?.name, + item.hall ? item.hall : "ندارد", + item.inspectionInfo.numberOfInspections + ? item.inspectionInfo.numberOfInspections + : 0, + item?.hatchingQuantity, + item.vetfarmLosses, + item.inspectionInfo.numberOfHatching + ? "%" + + Math.round( + (item.vetfarmLosses * 100) / + item.inspectionInfo.numberOfHatching + ) + : 0, + , + ]; + } else { + return [ + page === 1 ? i + 1 : i + perPage * (page - 1) + 1, + item.breedingUniqueId ? Number(item.breedingUniqueId) : "-", + item.unitName, + item?.address?.city?.name, + item?.hatchingQuantity?.period + ? item?.hatchingQuantity?.period + : "ندارد", + item?.hatchingQuantity?.totalQuantity?.toLocaleString(), + item?.hatchingQuantity?.leftOver?.toLocaleString(), + item?.hatchingQuantity?.unionLosses?.toLocaleString(), + item?.hatchingQuantity?.vetFarmLosses?.toLocaleString(), + item?.hatchingQuantity?.totalLosses?.toLocaleString(), + ]; + } + }); + + setTableData(d); + }, [data]); + + useEffect(() => { + fetchApiData(1); + }, [dispatch, perPage]); + + const handleSubmit = async (event) => { + event.preventDefault(); + dispatch(LOADING_START()); + + try { + const response = await axios.get( + `management_vet_farm/?role=${getRoleFromUrl()}&search=filter&value=${textValue}&page=${1}&page_size=${perPage}` + ); + setData(response.data.results); + setTotalRows(response.data.count); + dispatch(LOADING_END()); + } catch (error) { + console.error("Error fetching data:", error); + } + }; + + return ( + +
    + + + + + +
    + ); +}; diff --git a/src/features/vet-farm/components/vet-farm-submit-inspection-form/VetFarmSubmitInspectionForm.js b/src/features/vet-farm/components/vet-farm-submit-inspection-form/VetFarmSubmitInspectionForm.js new file mode 100644 index 0000000..d86d80a --- /dev/null +++ b/src/features/vet-farm/components/vet-farm-submit-inspection-form/VetFarmSubmitInspectionForm.js @@ -0,0 +1,336 @@ +import { Button, TextField, Typography } from "@mui/material"; +import { ImageUpload } from "../../../../components/image-upload/ImageUpload"; +import { fixBase64 } from "../../../../utils/toBase64"; +import { Grid } from "../../../../components/grid/Grid"; +import { SPACING } from "../../../../data/spacing"; +import React, { useContext, useEffect } from "react"; +import { Yup } from "../../../../lib/yup/yup"; +import { useFormik } from "formik"; +import { useState } from "react"; +import { useDispatch } from "react-redux"; +import { + DRAWER, + LOADING_END, + LOADING_START, +} from "../../../../lib/redux/slices/appSlice"; +import { vetFarmNewInspect } from "../../services/vet-farm-new-inspect"; +import { vetFarmGetHatchingData } from "../../services/vet-farm-get-hatching-data"; +import { PropTypes } from "prop-types"; +import { AppContext } from "../../../../contexts/AppContext"; + +export const VetFarmSubmitInspectionForm = ({ + id, + hall, + poultrykey, + updateTable, +}) => { + const dispatch = useDispatch(); + const [hatchingData, setHatchingData] = useState(""); + const [inspectionImages, setInspectionImages] = React.useState([]); + + const inspectionImageHandler = (imageList, addUpdateIndex) => { + setInspectionImages(imageList); + }; + const [openNotif] = useContext(AppContext); + + useEffect(() => { + dispatch(LOADING_START()); + dispatch(vetFarmGetHatchingData(id + "&hall=" + hall)).then((r) => { + if (r.error) { + openNotif({ + vertical: "top", + horizontal: "center", + msg: "اطلاعات جوجه ریزی یافت نشد!", + severity: "error", + }); + dispatch(DRAWER({ right: false, bottom: false, content: null })); + } else { + setHatchingData(r.payload.data); + + if (!r.payload.data.length) { + setHatchingData(null); + } + + dispatch(LOADING_END()); + } + + dispatch(LOADING_END()); + }); + }, []); + + const formik = useFormik({ + initialValues: { + topic: "", + description: "", + losses: "", + }, + validationSchema: Yup.object({ + topic: Yup.string() + .required("این فیلد اجباری است!") + .typeError("لطفا فیلد را به درستی وارد کنید!"), + description: Yup.string() + .required("این فیلد اجباری است!") + .typeError("لطفا فیلد را به درستی وارد کنید!"), + losses: Yup.number().typeError("لطفا فیلد را به درستی وارد کنید!"), + }), + }); + + useEffect(() => { + formik.validateForm(); + // getUserGeolocationDetail(); + }, []); + + return ( + + + {hatchingData && ( + <> + + prop.palette.grey["A700"]} + > + دوره جوجه ریزی + + + {`دوره ${hatchingData[0]?.period} سالن ${hatchingData[0]?.hall} نژاد ${hatchingData[0]?.chickenBreed} باقیمانده ${hatchingData[0]?.leftOver} قطعه`} + {" "} + + + {/* + ({ + id: i.key, + race: i.chickenBreed, + selected: i, + label: `دوره ${i.period} سالن ${i.hall} نژاد ${i.chickenBreed} باقیمانده ${i.leftOver} قطعه`, + })) + : [] + } + onChange={(event, value) => { + sethatchingKey(value.id); + }} + renderInput={(params) => ( + + )} + /> + */} + + + + + )} + + + + + + + پیوست تصویر + + + + + + + + + ); +}; + +VetFarmSubmitInspectionForm.propTypes = { + id: PropTypes.string, + hall: PropTypes.string, + poultrykey: PropTypes.string, +}; diff --git a/src/features/vet-farm/services/vet-farm-cancel-bar.js b/src/features/vet-farm/services/vet-farm-cancel-bar.js new file mode 100644 index 0000000..6e8365f --- /dev/null +++ b/src/features/vet-farm/services/vet-farm-cancel-bar.js @@ -0,0 +1,28 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; +import { getRoleFromUrl } from "../../../utils/getRoleFromUrl"; + +export const vetFarmCancelBarService = createAsyncThunk( + "VET_FARM_CANCEL_BAR_SERVICE", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + try { + const { data, status } = await axios.delete( + "kill_house_request/0/?delete_bar&", + { + params: { + kill_house_request_key: d.kill_house_request_key, + message: d.message, + role: getRoleFromUrl(), + }, + } + ); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e.response.data.result }; + } + } +); diff --git a/src/features/vet-farm/services/vet-farm-check-allocation.js b/src/features/vet-farm/services/vet-farm-check-allocation.js new file mode 100644 index 0000000..c9f3390 --- /dev/null +++ b/src/features/vet-farm/services/vet-farm-check-allocation.js @@ -0,0 +1,21 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const vetFarmCheckAllocation = createAsyncThunk( + "VET_FARM_CHECK_ALLOCATION", + async (d, { dispatch }) => { + try { + dispatch(LOADING_START()); + const { data, status } = await axios.post( + "vet_check_province_kill_request/", + d + ); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e.response.data.result }; + } + } +); diff --git a/src/features/vet-farm/services/vet-farm-delete-aggregate-bar.js b/src/features/vet-farm/services/vet-farm-delete-aggregate-bar.js new file mode 100644 index 0000000..91253b3 --- /dev/null +++ b/src/features/vet-farm/services/vet-farm-delete-aggregate-bar.js @@ -0,0 +1,23 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const vetFarmDeleteAggregateBarService = createAsyncThunk( + "VET_FARM_DELETE_AGGREGATE_BAR", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + try { + const { data, status } = await axios.delete( + `vet_check_province_kill_request/0/`, + { + params: d, + } + ); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e.response.data.result }; + } + } +); diff --git a/src/features/vet-farm/services/vet-farm-delete-bar.js b/src/features/vet-farm/services/vet-farm-delete-bar.js new file mode 100644 index 0000000..bf077be --- /dev/null +++ b/src/features/vet-farm/services/vet-farm-delete-bar.js @@ -0,0 +1,20 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const vetFarmDeleteBarService = createAsyncThunk( + "VET_FARM_DELETE_BAR", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + try { + const { data, status } = await axios.delete(`delete-bar/0/`, { + params: d, + }); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e.response.data.result }; + } + } +); diff --git a/src/features/vet-farm/services/vet-farm-delete-farm.js b/src/features/vet-farm/services/vet-farm-delete-farm.js new file mode 100644 index 0000000..9c1522f --- /dev/null +++ b/src/features/vet-farm/services/vet-farm-delete-farm.js @@ -0,0 +1,10 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; + +export const vetFarmDeleteFarm = createAsyncThunk( + "VET_FARM_NEW_FARM", + async (d) => { + const data = await axios.delete("vet_farm/0/?vet_farm_key=" + d); + return data; + } +); diff --git a/src/features/vet-farm/services/vet-farm-delete-quarantine-code.js b/src/features/vet-farm/services/vet-farm-delete-quarantine-code.js new file mode 100644 index 0000000..e7e4e3c --- /dev/null +++ b/src/features/vet-farm/services/vet-farm-delete-quarantine-code.js @@ -0,0 +1,23 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; +import axios from "axios"; + +export const vetFarmDeleteQuarantineCodeService = createAsyncThunk( + "VET_FARM_DELETE_QUARANTINE_CODE_SERVICE", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + try { + const { data, status } = await axios.delete( + `poultry-request-quarantine-code/0/`, + { + params: d, + } + ); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e.response.data.result }; + } + } +); diff --git a/src/features/vet-farm/services/vet-farm-edit-code-allocation.js b/src/features/vet-farm/services/vet-farm-edit-code-allocation.js new file mode 100644 index 0000000..a0541b7 --- /dev/null +++ b/src/features/vet-farm/services/vet-farm-edit-code-allocation.js @@ -0,0 +1,21 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const vetFarmEditCodeAllocation = createAsyncThunk( + "VET_FARM_EDIT_CODE_ALLOCATION", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + try { + const { data, status } = await axios.put( + "vet_check_province_kill_request/0/", + d + ); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e.response.data.result }; + } + } +); diff --git a/src/features/vet-farm/services/vet-farm-edit-out-of-province-driver-health-code.js b/src/features/vet-farm/services/vet-farm-edit-out-of-province-driver-health-code.js new file mode 100644 index 0000000..fe16f59 --- /dev/null +++ b/src/features/vet-farm/services/vet-farm-edit-out-of-province-driver-health-code.js @@ -0,0 +1,21 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const vetFarmEditOutOfProvinceDriverHealthCode = createAsyncThunk( + "VET_FARM_EDIT_OUT_DRIVER_CODE", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + try { + const { data, status } = await axios.put( + "out-province-poultry-requests/0/", + d + ); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e.response.data.result }; + } + } +); diff --git a/src/features/vet-farm/services/vet-farm-edit-quarantine-code.js b/src/features/vet-farm/services/vet-farm-edit-quarantine-code.js new file mode 100644 index 0000000..adc6ffd --- /dev/null +++ b/src/features/vet-farm/services/vet-farm-edit-quarantine-code.js @@ -0,0 +1,21 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; +import axios from "axios"; + +export const vetFarmEditQuarantineCodeService = createAsyncThunk( + "VET_EDIT_QUARANTINE_CODE_SERVICE", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + try { + const { data, status } = await axios.put( + `poultry-request-quarantine-code/0/`, + d + ); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e.response.data.result }; + } + } +); diff --git a/src/features/vet-farm/services/vet-farm-edit-traffic-code.js b/src/features/vet-farm/services/vet-farm-edit-traffic-code.js new file mode 100644 index 0000000..f06a4e0 --- /dev/null +++ b/src/features/vet-farm/services/vet-farm-edit-traffic-code.js @@ -0,0 +1,18 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const vetFarmEditTrafficCodeService = createAsyncThunk( + "VET_FARM_EDIT_TRAFFIC_CODE_SERVICE", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + try { + const { data, status } = await axios.put("kill_house_request/0/", d); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e.response.data.result }; + } + } +); diff --git a/src/features/vet-farm/services/vet-farm-free-sale-submit-clearance-code.js b/src/features/vet-farm/services/vet-farm-free-sale-submit-clearance-code.js new file mode 100644 index 0000000..e4a6c0f --- /dev/null +++ b/src/features/vet-farm/services/vet-farm-free-sale-submit-clearance-code.js @@ -0,0 +1,10 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; + +export const vetFarmFreeSaleSubmitClearanceCode = createAsyncThunk( + "VET_FARM_SUBMIT_CLEARANCE_CODE", + async (d) => { + const { data, status } = await axios.put(`/Poultry_Request/0/`, d); + return { data, status }; + } +); diff --git a/src/features/vet-farm/services/vet-farm-get-allocated.js b/src/features/vet-farm/services/vet-farm-get-allocated.js new file mode 100644 index 0000000..bb9b252 --- /dev/null +++ b/src/features/vet-farm/services/vet-farm-get-allocated.js @@ -0,0 +1,24 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; +import { getRoleFromUrl } from "../../../utils/getRoleFromUrl"; + +export const vetFarmGetAllocatedService = createAsyncThunk( + "VET_FARM_GET_ALLOCATED_SERVICE", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + const roleAndCheck = `?role=${getRoleFromUrl()}&check`; + const { data, status } = await axios.get( + `Poultry_Request/${roleAndCheck}`, + { + params: { + date1: d.selectedDate1, + date2: d.selectedDate2, + role_key: d.role_key || "", + }, + } + ); + dispatch(LOADING_END()); + return { data, status }; + } +); diff --git a/src/features/vet-farm/services/vet-farm-get-bars-overview.js b/src/features/vet-farm/services/vet-farm-get-bars-overview.js new file mode 100644 index 0000000..10c7e0a --- /dev/null +++ b/src/features/vet-farm/services/vet-farm-get-bars-overview.js @@ -0,0 +1,66 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; +import { getRoleFromUrl } from "../../../utils/getRoleFromUrl"; + +export const vetFarmGetBarsOverview = createAsyncThunk( + "VET_FARM_GET_OVERVIEW_BARS_SERVICE", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + const { data, status } = await axios.get(`dashboard_detail_of_killing`, { + params: { + date1: d.selectedDate1, + date2: d.selectedDate2, + role: getRoleFromUrl(), + search: "filter", + value: d.textValue, + without_quarantine_code_state: d.hasDocumentState, + }, + }); + dispatch(LOADING_END()); + return { data, status }; + } +); + +export const parentCompanyGetBarsOverview = createAsyncThunk( + "PARENT_COMPANY_GET_OVERVIEW_BARS_SERVICE", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + const { data, status } = await axios.get( + `${d.province}parent_company_dashboard_detail_of_killing`, + { + params: { + date1: d.selectedDate1, + date2: d.selectedDate2, + role: getRoleFromUrl(), + search: "filter", + value: d.textValue, + without_quarantine_code_state: d.hasDocumentState, + }, + } + ); + dispatch(LOADING_END()); + return { data, status }; + } +); + +export const vetFarmGetFinishedBarsOverview = createAsyncThunk( + "VET_FARM_GET_OVERVIEW_BARS_SERVICE", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + const { data, status } = await axios.get(`dashboard_detail_of_killing`, { + params: { + date1: d.selectedDate1, + date2: d.selectedDate2, + role: getRoleFromUrl(), + search: "filter", + value: d.textValue, + type: "assignment", + without_bar_document: d.hasDocumentState, + role_key: d?.roleKey || "", + }, + }); + dispatch(LOADING_END()); + return { data, status }; + } +); diff --git a/src/features/vet-farm/services/vet-farm-get-deleted-bars-dashboard.js b/src/features/vet-farm/services/vet-farm-get-deleted-bars-dashboard.js new file mode 100644 index 0000000..853e74b --- /dev/null +++ b/src/features/vet-farm/services/vet-farm-get-deleted-bars-dashboard.js @@ -0,0 +1,20 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { getRoleFromUrl } from "../../../utils/getRoleFromUrl"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const vetFarmGetDeletedBarsDahsboard = createAsyncThunk( + "DELETED_BARS_DASHBOARD", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + const { data, status } = await axios.get(`dashboard_delete_bar`, { + params: { + date1: d.selectedDate1, + date2: d.selectedDate2, + role: getRoleFromUrl(), + }, + }); + dispatch(LOADING_END()); + return { data, status }; + } +); diff --git a/src/features/vet-farm/services/vet-farm-get-deleted-bars.js b/src/features/vet-farm/services/vet-farm-get-deleted-bars.js new file mode 100644 index 0000000..fecb0a7 --- /dev/null +++ b/src/features/vet-farm/services/vet-farm-get-deleted-bars.js @@ -0,0 +1,24 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; +import { getRoleFromUrl } from "../../../utils/getRoleFromUrl"; + +export const vetFarmGetDeletedBarsService = createAsyncThunk( + "VET_FARM_GET_DELETED_BARS_SERVICE", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + const { data, status } = await axios.get( + `Poultry_Request/?check&deleted_requests`, + { + params: { + role: getRoleFromUrl(), + date1: d.selectedDate1, + date2: d.selectedDate2, + role_key: d.role_key || "", + }, + } + ); + dispatch(LOADING_END()); + return { data, status }; + } +); diff --git a/src/features/vet-farm/services/vet-farm-get-farm-data.js b/src/features/vet-farm/services/vet-farm-get-farm-data.js new file mode 100644 index 0000000..cfb292d --- /dev/null +++ b/src/features/vet-farm/services/vet-farm-get-farm-data.js @@ -0,0 +1,12 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; + +export const getVetFarmData = createAsyncThunk( + "VET_GET_VET_FARM_DATA", + async (id) => { + const { data, status } = await axios.get( + "Poultry/?type=filter&value=" + id + ); + return { data, status }; + } +); diff --git a/src/features/vet-farm/services/vet-farm-get-farms.js b/src/features/vet-farm/services/vet-farm-get-farms.js new file mode 100644 index 0000000..37318b9 --- /dev/null +++ b/src/features/vet-farm/services/vet-farm-get-farms.js @@ -0,0 +1,7 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; + +export const getVetFarms = createAsyncThunk("VET_GET_VET_FARMS", async () => { + const { data, status } = await axios.get("vet_farm"); + return { data, status }; +}); diff --git a/src/features/vet-farm/services/vet-farm-get-hatching-data.js b/src/features/vet-farm/services/vet-farm-get-hatching-data.js new file mode 100644 index 0000000..fc53071 --- /dev/null +++ b/src/features/vet-farm/services/vet-farm-get-hatching-data.js @@ -0,0 +1,10 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; + +export const vetFarmGetHatchingData = createAsyncThunk( + "VET_GET_HATCHING", + async (id) => { + const { data, status } = await axios.get("poultry_hatching/?key=" + id); + return { data, status }; + } +); diff --git a/src/features/vet-farm/services/vet-farm-get-hatching.js b/src/features/vet-farm/services/vet-farm-get-hatching.js new file mode 100644 index 0000000..5d8e7ed --- /dev/null +++ b/src/features/vet-farm/services/vet-farm-get-hatching.js @@ -0,0 +1,10 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; + +export const getHatchingData = createAsyncThunk( + "VET_GET_HATCHING", + async (key) => { + const { data, status } = await axios.get("poultry_hatching/?key=" + key); + return { data, status }; + } +); diff --git a/src/features/vet-farm/services/vet-farm-get-inspection-history.js b/src/features/vet-farm/services/vet-farm-get-inspection-history.js new file mode 100644 index 0000000..ff93301 --- /dev/null +++ b/src/features/vet-farm/services/vet-farm-get-inspection-history.js @@ -0,0 +1,10 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; + +export const getVetFarmInspectionHistory = createAsyncThunk( + "VET_GET_VET_FARM_INSPECTION_HISTORY", + async (id) => { + const { data, status } = await axios.get("vet_farm_inspection/?key=" + id); + return { data, status }; + } +); diff --git a/src/features/vet-farm/services/vet-farm-get-out-of-province-requests.js b/src/features/vet-farm/services/vet-farm-get-out-of-province-requests.js new file mode 100644 index 0000000..82435f4 --- /dev/null +++ b/src/features/vet-farm/services/vet-farm-get-out-of-province-requests.js @@ -0,0 +1,23 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; +import { getRoleFromUrl } from "../../../utils/getRoleFromUrl"; + +export const vetFarmGetOutOfProvinceRequests = createAsyncThunk( + "VET_FARM_GET_OUT_OF_PROVINCE_REQUESTS", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + const { data, status } = await axios.get( + `temporary-out-province-poultry-requests`, + { + params: { + role: getRoleFromUrl(), + date1: d.selectedDate1, + date2: d.selectedDate2, + }, + } + ); + dispatch(LOADING_END()); + return { data, status }; + } +); diff --git a/src/features/vet-farm/services/vet-farm-get-out-province-dashboard.js b/src/features/vet-farm/services/vet-farm-get-out-province-dashboard.js new file mode 100644 index 0000000..154a49b --- /dev/null +++ b/src/features/vet-farm/services/vet-farm-get-out-province-dashboard.js @@ -0,0 +1,17 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const vetFarmGetOutProvinceDashboard = createAsyncThunk( + "VET_FARM_GET_OUT_PROVINCE_DASHBOARD", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + const { data, status } = await axios.get(`dashboard_kill_house_free_bar`, { + params: { + ...d, + }, + }); + dispatch(LOADING_END()); + return { data, status }; + } +); diff --git a/src/features/vet-farm/services/vet-farm-get-profile.js b/src/features/vet-farm/services/vet-farm-get-profile.js new file mode 100644 index 0000000..aafef3d --- /dev/null +++ b/src/features/vet-farm/services/vet-farm-get-profile.js @@ -0,0 +1,10 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; + +export const vatFarmGetProfile = createAsyncThunk( + "VET_FARM_GET_PROFILE", + async () => { + const { data, status } = await axios.get("vet/0/?profile"); + return { data, status }; + } +); diff --git a/src/features/vet-farm/services/vet-farm-get-quarantine-code.js b/src/features/vet-farm/services/vet-farm-get-quarantine-code.js new file mode 100644 index 0000000..3675386 --- /dev/null +++ b/src/features/vet-farm/services/vet-farm-get-quarantine-code.js @@ -0,0 +1,16 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; +import axios from "axios"; + +export const vetFarmGetQuarantineCodeService = createAsyncThunk( + "VET_FARM_GET_QUARANTINE_CODE_SERVICE", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + const { data, status } = await axios.get( + `poultry-request-quarantine-code`, + { params: d } + ); + dispatch(LOADING_END()); + return { data, status }; + } +); diff --git a/src/features/vet-farm/services/vet-farm-new-farm.js b/src/features/vet-farm/services/vet-farm-new-farm.js new file mode 100644 index 0000000..00fe265 --- /dev/null +++ b/src/features/vet-farm/services/vet-farm-new-farm.js @@ -0,0 +1,10 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; + +export const vetFarmNewFarm = createAsyncThunk( + "VET_FARM_NEW_FARM", + async (d) => { + const { data, status } = await axios.post("vet_farm/", d); + return { data, status }; + } +); diff --git a/src/features/vet-farm/services/vet-farm-new-inspect.js b/src/features/vet-farm/services/vet-farm-new-inspect.js new file mode 100644 index 0000000..711fb86 --- /dev/null +++ b/src/features/vet-farm/services/vet-farm-new-inspect.js @@ -0,0 +1,10 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; + +export const vetFarmNewInspect = createAsyncThunk( + "VET_FARM_NEW_INSPECT", + async (d) => { + const { data, status } = await axios.post("vet_farm_inspection/", d); + return { data, status }; + } +); diff --git a/src/features/vet-farm/services/vet-farm-out-province-get-dashboard.js b/src/features/vet-farm/services/vet-farm-out-province-get-dashboard.js new file mode 100644 index 0000000..3de54d3 --- /dev/null +++ b/src/features/vet-farm/services/vet-farm-out-province-get-dashboard.js @@ -0,0 +1,28 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; +import { getRoleFromUrl } from "../../../utils/getRoleFromUrl"; + +export const vetFarmOutProvinceGetDashboard = createAsyncThunk( + "VET_OUT_PRO_DASHBOARD", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + const { data, status } = await axios.get( + `${ + d.province ? d.province + "parent-company-" : "" + }dashboard-out-province-poultry-requests`, + { + params: { + date1: d.selectedDate1, + date2: d.selectedDate2, + role: getRoleFromUrl(), + filter: "search", + value: d.text ? d.text : "", + state: "accepted", + }, + } + ); + dispatch(LOADING_END()); + return { data, status }; + } +); diff --git a/src/features/vet-farm/services/vet-farm-save-price.js b/src/features/vet-farm/services/vet-farm-save-price.js new file mode 100644 index 0000000..c1a39ea --- /dev/null +++ b/src/features/vet-farm/services/vet-farm-save-price.js @@ -0,0 +1,21 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const vetFarmSavePriceService = createAsyncThunk( + "VET-FARM_SAVE_PRICE_SERVICE", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + try { + const { data, status } = await axios.put( + "kill_house_request_pricing/0/", + d + ); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e.response.data.result }; + } + } +); diff --git a/src/features/vet-farm/services/vet-farm-submit-aggegate-bars.js b/src/features/vet-farm/services/vet-farm-submit-aggegate-bars.js new file mode 100644 index 0000000..23c1086 --- /dev/null +++ b/src/features/vet-farm/services/vet-farm-submit-aggegate-bars.js @@ -0,0 +1,39 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const vetFarmSubmitAggregateBars = createAsyncThunk( + "VET_FARM_SUBMIT_AGGREGATE_BARS", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + try { + const { data, status } = await axios.post( + `aggregate-vet-check-province-kill-request/`, + d + ); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e.response.data.result }; + } + } +); + +export const vetFarmReturnAggregateBars = createAsyncThunk( + "VET_FARM_SUBMIT_AGGREGATE_BARS", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + try { + const { data, status } = await axios.put( + `aggregate-vet-check-province-kill-request/0/`, + d + ); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e.response.data.result }; + } + } +); diff --git a/src/features/vet-farm/services/vet-farm-submit-contdadicts.js b/src/features/vet-farm/services/vet-farm-submit-contdadicts.js new file mode 100644 index 0000000..4a7e403 --- /dev/null +++ b/src/features/vet-farm/services/vet-farm-submit-contdadicts.js @@ -0,0 +1,10 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; + +export const vetFarmSubmitContradictsService = createAsyncThunk( + "VET_FARM_SUBMIT_CONTRADICTS", + async (d) => { + const { data, status } = await axios.put(`kill_house_request/0/`, d); + return { data, status }; + } +); diff --git a/src/features/vet-farm/services/vet-farm-submit-quarantine-code.js b/src/features/vet-farm/services/vet-farm-submit-quarantine-code.js new file mode 100644 index 0000000..b22fe93 --- /dev/null +++ b/src/features/vet-farm/services/vet-farm-submit-quarantine-code.js @@ -0,0 +1,21 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; +import axios from "axios"; + +export const vetFarmSubmitClearenceCodeService = createAsyncThunk( + "VET_FARM_EDIT_OUT_DRIVER_CODE", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + try { + const { data, status } = await axios.post( + "poultry-request-quarantine-code/", + d + ); + dispatch(LOADING_END()); + return { data, status }; + } catch (e) { + dispatch(LOADING_END()); + return { error: e.response.data.result }; + } + } +); diff --git a/src/features/visors/components/visor-statics-national-info/VisorStaticsNationalInfo.js b/src/features/visors/components/visor-statics-national-info/VisorStaticsNationalInfo.js new file mode 100644 index 0000000..98637d5 --- /dev/null +++ b/src/features/visors/components/visor-statics-national-info/VisorStaticsNationalInfo.js @@ -0,0 +1,262 @@ +import React, { useContext, useState } from "react"; +import { Grid } from "../../../../components/grid/Grid"; +import { + Autocomplete, + Box, + Checkbox, + Tab, + Tabs, + TextField, + Typography, +} from "@mui/material"; +import ShowChartIcon from "@mui/icons-material/ShowChart"; +import { + Chart as ChartJS, + CategoryScale, + LinearScale, + PointElement, + LineElement, + Title, + Tooltip, + Legend, +} from "chart.js"; +import { VisorStaticsNationalInfoCountry } from "./parts/VisorStaticsNationalInfoCountry"; +import { DatePicker } from "@mui/x-date-pickers"; +import moment from "moment"; +import { getSamasatProvinces } from "../../../../utils/getSamasatProvinces"; +import { AppContext } from "../../../../contexts/AppContext"; +import ToggleOffOutlinedIcon from "@mui/icons-material/ToggleOffOutlined"; +import ToggleOnIcon from "@mui/icons-material/ToggleOn"; +import { VisorStaticsNationalInfoBreeds } from "./parts/VisorStaticsNationalInfoBreeds"; + +ChartJS.register( + CategoryScale, + LinearScale, + PointElement, + LineElement, + Title, + Tooltip, + Legend +); + +export const VisorStaticsNationalInfo = () => { + const [, , selectedDate1, setSelectedDate1, selectedDate2, setSelectedDate2] = + useContext(AppContext); + const [value, setValue] = useState("breed"); + const [withDate, setWithDate] = useState(false); + const [selectedProvince, setSelectedProvince] = useState(""); + + const handleChange = (event, newValue) => { + setValue(newValue); + }; + const getProvinceList = () => { + return [{ name: "همه" }, ...getSamasatProvinces()]; + }; + + const boxItems = [ + { + title: "لورم ایپسوم", + icon: , + value: 2000, + }, + { + title: "لورم ایپسوم", + icon: , + value: 2000, + }, + { + title: "لورم ایپسوم", + icon: , + value: 2000, + }, + { + title: "لورم ایپسوم", + icon: , + value: 2000, + }, + ]; + + return ( + + + + + + + + + + + + + + { + return { + label: i.name, + }; + })} + onChange={(event, value) => { + if (value.label !== "همه") { + setSelectedProvince(value.label); + } else { + setSelectedProvince(""); + } + }} + renderInput={(params) => ( + + )} + /> + + + + } + checkedIcon={} + checked={withDate} + onChange={() => setWithDate(!withDate)} + color="primary" + size="large" + /> + + + ( + + )} + value={selectedDate1} + onChange={(e) => { + setSelectedDate1(moment(e).format("YYYY-MM-DD")); + }} + /> + + + ( + + )} + value={selectedDate2} + onChange={(e) => { + setSelectedDate2(moment(e).format("YYYY-MM-DD")); + }} + /> + + + + + {true === false && ( + + {boxItems?.map((item, i) => ( + + + + {item?.title} + + {item.icon} + + + {item?.value} + + + + + + + ))} + + )} + + {value === "breed" && ( + + )} + + {value === "national" && ( + + )} + + ); +}; diff --git a/src/features/visors/components/visor-statics-national-info/parts/VisorStaticsNationalInfoBreeds.js b/src/features/visors/components/visor-statics-national-info/parts/VisorStaticsNationalInfoBreeds.js new file mode 100644 index 0000000..a09203d --- /dev/null +++ b/src/features/visors/components/visor-statics-national-info/parts/VisorStaticsNationalInfoBreeds.js @@ -0,0 +1,392 @@ +import React, { useEffect, useState } from "react"; +import { visorsGetNationalInfoService } from "../../../services/get-visor-national-info"; +import { useDispatch } from "react-redux"; +import { Line, Doughnut } from "react-chartjs-2"; // Add Bar to the imports +import { Grid } from "../../../../../components/grid/Grid"; +import { Box, Typography } from "@mui/material"; +import { + Chart as ChartJS, + ArcElement, + Tooltip, + Legend, + CategoryScale, + LinearScale, + PointElement, + LineElement, + BarElement, +} from "chart.js"; +import { AdvancedChart } from "../../../../../components/advanced-chart/AdvancedChart"; + +ChartJS.register( + ArcElement, + Tooltip, + Legend, + CategoryScale, + LinearScale, + PointElement, + LineElement, + BarElement +); + +export const VisorStaticsNationalInfoBreeds = ({ + selectedProvince, + selectedDate1, + selectedDate2, + withDate, +}) => { + const dispatch = useDispatch(); + + const [chartsData, setChartsData] = useState({}); + + useEffect(() => { + dispatch( + visorsGetNationalInfoService({ + selectedProvince, + selectedDate1, + selectedDate2, + withDate, + type: "pedigree", + }) + ).then((r) => { + setChartsData(r.payload.data); + }); + }, [dispatch, selectedProvince, selectedDate1, selectedDate2, withDate]); + + const getChartData = (name) => { + let data; + switch (name) { + case "average-age": + data = { + labels: chartsData?.pedigreeNameAverageAge?.map( + (item) => item?.PedigreeName + ), + chartList: chartsData?.pedigreeNameAverageAge?.map( + (item) => item?.averageAge + ), + }; + break; + case "hatching-sum": + data = { + labels: chartsData?.pedigreeNameHatchingSum?.map( + (item) => item?.PedigreeName + ), + chartList: chartsData?.pedigreeNameHatchingSum?.map( + (item) => item?.chickSum + ), + }; + break; + case "hatching-count": + data = { + labels: chartsData?.pedigreeNameHatchingCount?.map( + (item) => item?.PedigreeName + ), + chartList: chartsData?.pedigreeNameHatchingCount?.map( + (item) => item?.chickCount + ), + }; + break; + + default: + break; + } + + if (name === "hatching-sum") { + const backgroundColors = [ + "rgba(255, 99, 132, 0.7)", + "rgba(54, 162, 235, 0.7)", + "rgba(255, 206, 86, 0.7)", + "rgba(75, 192, 192, 0.7)", + "rgba(153, 102, 255, 0.7)", + "rgba(255, 159, 64, 0.7)", + ]; + + return { + labels: data?.labels, + datasets: [ + { + data: data?.chartList, + backgroundColor: backgroundColors, + borderColor: "#fff", + borderWidth: 2, + hoverOffset: 10, + }, + ], + }; + } + + return { + labels: data?.labels, + datasets: [ + { + label: name === "hatching-count" ? "تعداد" : "سن", + data: data?.chartList, + borderColor: "#3A3A3A", + backgroundColor: "rgba(16, 185, 129, 0.1)", + borderWidth: 2, + tension: 0.3, + pointRadius: 0, + pointHoverRadius: 6, + pointBackgroundColor: "#3A3A3A", + pointHoverBackgroundColor: "#3A3A3A", + fill: true, + }, + ], + }; + }; + + const chartOptions = { + responsive: true, + maintainAspectRatio: false, + plugins: { + legend: { + display: false, + rtl: true, + labels: { + usePointStyle: true, + padding: 20, + font: { + family: "iranyekan", + size: 14, + }, + }, + }, + tooltip: { + mode: "index", + intersect: false, + backgroundColor: "#1E293B", + titleFont: { + family: "iranyekan", + size: 14, + weight: "bold", + }, + bodyFont: { + family: "iranyekan", + size: 12, + }, + padding: 12, + cornerRadius: 8, + displayColors: true, + rtl: true, + }, + }, + scales: { + x: { + grid: { + display: false, + drawBorder: false, + }, + ticks: { + color: "#64748B", + font: { + family: "iranyekan", + size: 12, + }, + }, + }, + y: { + grid: { + display: false, + drawBorder: false, + }, + ticks: { + color: "#64748B", + font: { + family: "iranyekan", + size: 11, + }, + padding: 10, + }, + }, + }, + interaction: { + mode: "nearest", + axis: "x", + intersect: false, + }, + }; + + const doughnutOptions = { + responsive: true, + maintainAspectRatio: false, + plugins: { + legend: { + position: "right", + rtl: true, + labels: { + usePointStyle: true, + padding: 20, + font: { + family: "iranyekan", + size: 14, + }, + }, + }, + tooltip: { + backgroundColor: "#1E293B", + titleFont: { + family: "iranyekan", + size: 14, + weight: "bold", + }, + bodyFont: { + family: "iranyekan", + size: 12, + }, + padding: 12, + cornerRadius: 8, + displayColors: true, + rtl: true, + }, + }, + cutout: "70%", + }; + + const getBreedByProvince = (originalData) => { + if (originalData) { + const allPedigrees = new Set(); + originalData.forEach((province) => { + province.breeds.forEach((breed) => { + allPedigrees.add(breed.pedigree); + }); + }); + + const pedigreeNames = Array.from(allPedigrees); + + const result = pedigreeNames.map((name) => { + const data = originalData.map((province) => { + const breed = province.breeds.find((b) => b.pedigree === name); + return breed ? breed.hatchingSum : 0; + }); + + return { + name: name, + data: data, + }; + }); + + return result; + } else { + return null; + } + }; + + const getEvacuationByPedigree = (originalData) => { + if (originalData) { + return [ + { + name: "درصد تلفات نسبت به جوجه ریزی نژاد", + data: originalData?.map((item) => item.pedigree), + }, + { + name: "درصد تلفات نسبت به کل جوجه ریزی", + data: originalData?.map((item) => item.total), + }, + ]; + } else { + return null; + } + }; + + return ( + + + + میانگین سنی کشتار + + + + + + + + حجم جوجه ریزی + + + + + + {chartsData && ( + + province.province + )} + info={getBreedByProvince(chartsData?.provinceResult)} + /> + + )} + + + تعداد جوجه ریزی + + + + + + + + pedigree.pedigreeName + )} + info={getEvacuationByPedigree( + chartsData?.pedigreeEvacuationHatchingPercent + )} + /> + + + + ); +}; diff --git a/src/features/visors/components/visor-statics-national-info/parts/VisorStaticsNationalInfoCountry.js b/src/features/visors/components/visor-statics-national-info/parts/VisorStaticsNationalInfoCountry.js new file mode 100644 index 0000000..ef6b507 --- /dev/null +++ b/src/features/visors/components/visor-statics-national-info/parts/VisorStaticsNationalInfoCountry.js @@ -0,0 +1,225 @@ +import React, { useEffect, useState } from "react"; +import { visorsGetNationalInfoService } from "../../../services/get-visor-national-info"; +import { useDispatch } from "react-redux"; +import { Grid } from "../../../../../components/grid/Grid"; +import { + Chart as ChartJS, + ArcElement, + Tooltip, + Legend, + CategoryScale, + LinearScale, + PointElement, + LineElement, + BarElement, +} from "chart.js"; +import { AdvancedChart } from "../../../../../components/advanced-chart/AdvancedChart"; + +ChartJS.register( + ArcElement, + Tooltip, + Legend, + CategoryScale, + LinearScale, + PointElement, + LineElement, + BarElement +); + +export const VisorStaticsNationalInfoCountry = ({ + selectedProvince, + selectedDate1, + selectedDate2, + withDate, +}) => { + const dispatch = useDispatch(); + + const [chartsData, setChartsData] = useState({}); + + useEffect(() => { + dispatch( + visorsGetNationalInfoService({ + selectedProvince, + selectedDate1, + selectedDate2, + withDate, + type: "province", + }) + ).then((r) => { + setChartsData(r.payload.data); + }); + }, [dispatch, selectedProvince, selectedDate1, selectedDate2, withDate]); + + const getBreedByProvince = (originalData, type) => { + if (originalData) { + if (type === "sum-hatching") { + const data = originalData?.map((item) => item?.chickSum || 0); + + return [ + { + name: "حجم جوجه ریزی", + data: data, + }, + ]; + } else if (type === "average-age") { + const data = originalData?.map((item) => item?.averageAge || 0); + + return [ + { + name: "میانگین سنی", + data: data, + }, + ]; + } else if (type === "evacuation") { + const data = originalData?.map((item) => item?.evacuationHatching || 0); + + return [ + { + name: "درصد تلفات", + data: data, + }, + ]; + } else if (type === "leftover") { + const data = originalData?.map((item) => item?.leftOver || 0); + + return [ + { + name: "باقیمانده", + data: data, + }, + ]; + } else if (type === "sum-transport") { + const data = originalData?.map((item) => item?.goodAmount || 0); + + return [ + { + name: "حجم کشتار", + data: data, + }, + ]; + } + } else { + return null; + } + }; + + return ( + + {chartsData && ( + <> + + province.ProvinceName + )} + info={getBreedByProvince( + chartsData?.provinceHatchingSum, + "sum-hatching" + )} + /> + + + + province.ProvinceName + )} + info={getBreedByProvince( + chartsData?.provinceNameAverageAge, + "average-age" + )} + /> + + + + province.ProvinceName + )} + info={getBreedByProvince( + chartsData?.provinceEvacuationHatchingPercent, + "evacuation" + )} + /> + + + + province.ProvinceName + )} + info={getBreedByProvince( + chartsData?.provinceNameLeftover, + "leftover" + )} + /> + + + + province.ProvinceName + )} + info={getBreedByProvince( + chartsData?.provinceSumTransporting, + "sum-transport" + )} + /> + + + )} + + ); +}; diff --git a/src/features/visors/components/visor-statics-prediction-charts/VisorStaticsPredictionCharts.js b/src/features/visors/components/visor-statics-prediction-charts/VisorStaticsPredictionCharts.js new file mode 100644 index 0000000..d1d73ec --- /dev/null +++ b/src/features/visors/components/visor-statics-prediction-charts/VisorStaticsPredictionCharts.js @@ -0,0 +1,606 @@ +import React, { useContext, useEffect, useState } from "react"; +import { + Grid, + Box, + Typography, + MenuItem, + Select, + FormControl, + InputLabel, + FormHelperText, + TextField, + Button, + Tooltip, + IconButton, +} from "@mui/material"; +import { useFormik } from "formik"; +import * as Yup from "yup"; +import { DatePicker } from "@mui/x-date-pickers"; +import moment from "moment"; +import { AppContext } from "../../../../contexts/AppContext"; +import { Line } from "react-chartjs-2"; +import { useDispatch } from "react-redux"; +import { visorsGetPredictionStaticsChartService } from "../../services/get-visor-prediction-chart"; +import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl"; +import { formatJustDate } from "../../../../utils/formatTime"; +import ResponsiveTable from "../../../../components/responsive-table/ResponsiveTable"; +import { Chart } from "chart.js"; +import annotationPlugin from "chartjs-plugin-annotation"; +import RemoveRedEyeIcon from "@mui/icons-material/RemoveRedEye"; + +import { + ROUTE_ADMINX_VISOR_STATICS_PREDICTION, + ROUTE_CITY_VISOR_STATICS_PREDICTION, + ROUTE_COMMERCE_VISOR_STATICS_PREDICTION, + ROUTE_OBSERVATORY_VISOR_STATICS_PREDICTION, + ROUTE_PROVINCE_SUPERVISOR_STATICS_PREDICTION, + ROUTE_PROVINCEـVISOR_STATICS_PREDICTION, + ROUTE_SUPER_ADMIN_VISOR_STATICS_PREDICTION, + ROUTE_VETـSUPERVISOR_STATICS_PREDICTION, +} from "../../../../routes/routes"; +import { NumberInput } from "../../../../components/number-format-custom/NumberFormatCustom"; +import axios from "axios"; +Chart.register(annotationPlugin); +export const VisorStaticsPredictionCharts = () => { + const [, , selectedDate1, setSelectedDate1, selectedDate2, setSelectedDate2] = + useContext(AppContext); + const dispatch = useDispatch(); + + const [tablesData, setTableData] = useState([]); + const [originData, setOriginData] = useState([]); + + const [chartData, setChartData] = useState(null); + const [openNotif] = useContext(AppContext); + + useEffect(() => { + const currentDate = moment().format("YYYY-MM-DD"); + setSelectedDate1(currentDate); + setSelectedDate2(currentDate); + }, [setSelectedDate1, setSelectedDate2]); + + const getDetailRoute = (item) => { + const route = + getRoleFromUrl() === "AdminX" + ? ROUTE_ADMINX_VISOR_STATICS_PREDICTION + : getRoleFromUrl() === "SuperAdmin" + ? ROUTE_SUPER_ADMIN_VISOR_STATICS_PREDICTION + : getRoleFromUrl() === "CityOperator" + ? ROUTE_CITY_VISOR_STATICS_PREDICTION + : getRoleFromUrl() === "ProvinceOperator" + ? ROUTE_PROVINCEـVISOR_STATICS_PREDICTION + : getRoleFromUrl() === "VetSupervisor" + ? ROUTE_VETـSUPERVISOR_STATICS_PREDICTION + : getRoleFromUrl() === "Commerce" + ? ROUTE_COMMERCE_VISOR_STATICS_PREDICTION + : getRoleFromUrl() === "ProvinceSupervisor" + ? ROUTE_PROVINCE_SUPERVISOR_STATICS_PREDICTION + : getRoleFromUrl() === "Observatory" + ? ROUTE_OBSERVATORY_VISOR_STATICS_PREDICTION + : ROUTE_ADMINX_VISOR_STATICS_PREDICTION; + + return route + item?.hatchings.join(",").toString() + "/" + item?.date; + }; + + const formik = useFormik({ + initialValues: { + consumption_limit_type: "", + killing_age_external_type: "", + killing_age: "", + time_frame_type: "all", + consumption_limit: "", + killing_age_internal_type: "", + }, + validationSchema: Yup.object({ + consumption_limit_type: Yup.string() + .required("این گزینه الزامی است") + .typeError("لطفا فیلد را به درستی پر کنید!"), + killing_age_external_type: Yup.string() + .required("این گزینه الزامی است") + .typeError("لطفا فیلد را به درستی پر کنید!"), + consumption_limit: Yup.number() + .required("این گزینه الزامی است") + .typeError("لطفا فیلد را به درستی پر کنید!"), + killing_age: Yup.number().when("killing_age_external_type", { + is: "manual", + then: Yup.number() + .required("این گزینه الزامی است") + .typeError("لطفا فیلد را به درستی پر کنید!"), + }), + ave_kill_age_select: Yup.string().when("ave_kill_age", { + is: "behavior", + then: Yup.string() + .required("این گزینه الزامی است") + .typeError("لطفا فیلد را به درستی پر کنید!"), + }), + killing_age_internal_type: Yup.string().when( + "killing_age_external_type", + { + is: "poultry_ave_killing_age", + then: Yup.string() + .required("این گزینه الزامی است") + .typeError("لطفا فیلد را به درستی پر کنید!"), + } + ), + }), + onSubmit: (values) => { + let req = { + consumption_limit_type: values.consumption_limit_type, + killing_age_external_type: values.killing_age_external_type, + killing_age: + values.killing_age_external_type === "manual" + ? values.killing_age + : null, + time_frame_type: values.time_frame_type, + consumption_limit: values.consumption_limit, + killing_age_internal_type: + values.killing_age_external_type === "poultry_ave_killing_age" + ? values.killing_age_internal_type + : null, + date1: values.time_frame_type === "manual" ? selectedDate1 : null, + date2: values.time_frame_type === "manual" ? selectedDate2 : null, + role: getRoleFromUrl(), + }; + + req = Object.fromEntries( + Object.entries(req).filter(([_, value]) => value !== null) + ); + + dispatch(visorsGetPredictionStaticsChartService(req)).then((r) => { + if (r.payload.error) { + openNotif({ + vertical: "top", + horizontal: "center", + msg: r.payload.error, + severity: "error", + }); + } else { + setChartData( + transformData(r.payload.data, formik.values.consumption_limit) + ); + setOriginData(r.payload.data); + + const d = r.payload.data.map((option, index) => { + return [ + index + 1, + formatJustDate(option?.date), + option?.poultry?.toLocaleString(), + option?.quantity?.toLocaleString(), + option?.weight?.toLocaleString(), + Array.isArray(option?.age) + ? option.age.map((age, i) => age).join(" - ") + : option?.age, + + window.open(getDetailRoute(option), "_blank")} + > + + + , + ]; + }); + setTableData(d); + } + }); + }, + }); + + const handleDownloadExcel = () => { + let req = { + consumption_limit_type: formik.values.consumption_limit_type, + killing_age_external_type: formik.values.killing_age_external_type, + killing_age: + formik.values.killing_age_external_type === "manual" + ? formik.values.killing_age + : null, + time_frame_type: formik.values.time_frame_type, + consumption_limit: formik.values.consumption_limit, + killing_age_internal_type: + formik.values.killing_age_external_type === "poultry_ave_killing_age" + ? formik.values.killing_age_internal_type + : null, + date1: formik.values.time_frame_type === "manual" ? selectedDate1 : null, + date2: formik.values.time_frame_type === "manual" ? selectedDate2 : null, + role: getRoleFromUrl(), + }; + + req = Object.fromEntries( + Object.entries(req).filter(([_, value]) => value !== null) + ); + + const queryString = new URLSearchParams(req).toString(); + + return queryString; + }; + + useEffect(() => { + formik.validateForm(); + }, []); + + const chartOptions = { + scales: { + y: { + beginAtZero: true, + min: 0, + }, + }, + onClick: (event, elements) => { + if (elements.length > 0) { + const clickedElementIndex = elements[0]?.index; + let route = getDetailRoute(originData[clickedElementIndex]); + window.open(route, "_blank"); + } + }, + plugins: { + annotation: { + annotations: { + line1: { + type: "line", + yMin: formik.values.consumption_limit, + yMax: formik.values.consumption_limit, + borderColor: "red", + borderWidth: 2, + borderDash: [5, 5], + label: { + display: true, + content: "حد مصرف", + position: "end", + backgroundColor: "rgba(255, 99, 132, 0.8)", + font: { + size: 14, + weight: "bold", + }, + padding: 5, + }, + }, + }, + }, + }, + }; + + const transformData = (data, consumptionLimit) => { + if (data?.length) { + return { + labels: data?.map((item) => formatJustDate(item.date)), + datasets: [ + { + label: + formik.values.consumption_limit_type === "quantity" + ? "حجم موجودی (قطعه)" + : "وزن موجودی (کیلوگرم)", + data: + formik.values.consumption_limit_type === "quantity" + ? data?.map((item) => item.quantity) + : data?.map((item) => item.weight), + borderColor: "rgba(75, 192, 192, 1)", + backgroundColor: "rgba(75, 192, 192, 0.2)", + borderWidth: 2, + pointRadius: 5, + pointBackgroundColor: "yellow", + pointHoverRadius: 7, + fill: true, + tension: 0.4, + }, + ], + annotations: { + line1: { + type: "line", + yMin: consumptionLimit, + yMax: consumptionLimit, + borderColor: "rgba(255, 99, 132, 1)", + borderWidth: 3, + borderDash: [5, 5], + label: { + enabled: true, + content: "حد مصرف", + position: "end", + backgroundColor: "rgba(255, 99, 132, 0.8)", + font: { + size: 14, + weight: "bold", + }, + }, + }, + }, + }; + } else { + return null; + } + }; + + return ( + + + + پیش بینی موجودی + + + + {/* مصرف */} + + + حد مصرف + + + {formik.touched.consumption_limit_type && + formik.errors.consumption_limit_type} + + + + + + {formik.values.consumption_limit_type && ( + + )} + + + {/* میانگین سن کشتار */} + + + میانگین سن کشتار * + + + {formik.touched.killing_age_external_type && + formik.errors.killing_age_external_type} + + + + + + {formik.values.killing_age_external_type && ( + <> + {formik.values.killing_age_external_type === + "poultry_ave_killing_age" ? ( + + رفتار سنی کشتار + + + {formik.touched.killing_age_internal_type && + formik.errors.killing_age_internal_type} + + + ) : ( + + )} + + )} + + + {/* تاریخ پیش بینی */} + + + تاریخ پیش بینی * + + + {formik.touched.time_frame_type && + formik.errors.time_frame_type} + + + + + {formik.values.time_frame_type === "manual" && ( + <> + + + setSelectedDate1(moment(e).format("YYYY-MM-DD")) + } + renderInput={(params) => ( + + )} + /> + + + + setSelectedDate2(moment(e).format("YYYY-MM-DD")) + } + renderInput={(params) => ( + + )} + /> + + + )} + + + + + + + + + + + + + {chartData && ( + + + + )} + + ); +}; diff --git a/src/features/visors/components/visor-statics-prediction-details/VisorStaticsPredictionDetails.js b/src/features/visors/components/visor-statics-prediction-details/VisorStaticsPredictionDetails.js new file mode 100644 index 0000000..d3484d8 --- /dev/null +++ b/src/features/visors/components/visor-statics-prediction-details/VisorStaticsPredictionDetails.js @@ -0,0 +1,175 @@ +import React, { useEffect, useState } from "react"; +import { Button, TextField } from "@mui/material"; +import { useDispatch } from "react-redux"; +import axios from "axios"; +import { RiSearchLine } from "react-icons/ri"; +import { + LOADING_END, + LOADING_START, +} from "../../../../lib/redux/slices/appSlice"; +import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl"; +import { Grid } from "../../../../components/grid/Grid"; +import ResponsiveTable from "../../../../components/responsive-table/ResponsiveTable"; +import { formatJustDate } from "../../../../utils/formatTime"; +import { useParams } from "react-router-dom"; + +export const VisorStaticsPredictionDetails = () => { + const { key, date } = useParams(); + const dispatch = useDispatch(); + const handleTextChange = (event) => { + setTextValue(event.target.value); + }; + + const [data, setData] = useState([]); + const [totalRows, setTotalRows] = useState(0); + const [perPage, setPerPage] = useState(10); + const [textValue, setTextValue] = useState(""); + const [page, setPage] = useState(1); + const [tableData, setTableData] = useState([]); + + const fetchApiData = async (page) => { + let response; + dispatch(LOADING_START()); + response = await axios.get( + `poultry_hatching_prediction/?search=filter&value=${textValue}&role=${getRoleFromUrl()}&page=${page}&page_size=${perPage}&hatching_list=${key}` + ); + dispatch(LOADING_END()); + setData(response.data.results); + setTotalRows(response.data.count); + }; + + const handlePageChange = (page) => { + fetchApiData(page); + setPage(page); + }; + + const handlePerRowsChange = (perRows) => { + setPerPage(perRows); + setPage(1); + }; + + // const updateTable = () => { + // fetchApiData(page !== 0 ? page : 1); + // }; + + useEffect(() => { + const d = data?.map((item, i) => { + return [ + page === 1 ? i + 1 : i + perPage * (page - 1) + 1, + item?.poultry?.unitName, + item?.poultry?.fullname || "-", + item?.poultry?.killingAveAge?.toLocaleString(), + item?.poultry?.realKillingAveWeight?.toLocaleString(), + item?.period?.toLocaleString(), + formatJustDate(item?.date), + item?.quantity?.toLocaleString(), + item?.generalInfo?.age?.toLocaleString(), + item?.chickenBreed || "-", + item?.generalInfo?.totalQuantity?.toLocaleString(), + item?.generalInfo?.totalWeight?.toLocaleString(), + item?.generalInfo?.provinceKillRequests?.toLocaleString(), + item?.generalInfo?.provinceKillRequestsQuantity?.toLocaleString(), + item?.generalInfo?.provinceKillRequestsWeight?.toLocaleString(), + item?.leftOver?.toLocaleString(), + Math.round( + item?.poultry?.realKillingAveWeight * item?.leftOver + ).toLocaleString(), + Math.round( + item?.poultry?.realKillingAveWeight * item?.leftOver * 0.75 + ).toLocaleString(), + ]; + }); + + setTableData(d); + }, [data]); + + useEffect(() => { + fetchApiData(1); + }, [dispatch, perPage]); + + const handleSubmit = async (event) => { + event.preventDefault(); + dispatch(LOADING_START()); + + try { + const response = await axios.get( + `poultry_hatching_prediction/?role=${getRoleFromUrl()}&search=filter&value=${textValue}&page=${1}&page_size=${perPage}&hatching_list=${key}` + ); + setData(response.data.results); + setTotalRows(response.data.count); + dispatch(LOADING_END()); + } catch (error) { + console.error("Error fetching data:", error); + } + }; + + return ( + + + +
    + + + +
    +
    + + +
    + ); +}; diff --git a/src/features/visors/components/visor-statics-prediction-hatchings/VisorStaticsPredictionHatchings.js b/src/features/visors/components/visor-statics-prediction-hatchings/VisorStaticsPredictionHatchings.js new file mode 100644 index 0000000..da40441 --- /dev/null +++ b/src/features/visors/components/visor-statics-prediction-hatchings/VisorStaticsPredictionHatchings.js @@ -0,0 +1,167 @@ +import React, { useEffect, useState } from "react"; +import { Button, TextField } from "@mui/material"; +import { useDispatch } from "react-redux"; +import axios from "axios"; +import { RiSearchLine } from "react-icons/ri"; +import { + LOADING_END, + LOADING_START, +} from "../../../../lib/redux/slices/appSlice"; +import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl"; +import { Grid } from "../../../../components/grid/Grid"; +import ResponsiveTable from "../../../../components/responsive-table/ResponsiveTable"; +import { formatJustDate } from "../../../../utils/formatTime"; + +export const VisorStaticsPredictionHatchings = () => { + const dispatch = useDispatch(); + + const handleTextChange = (event) => { + setTextValue(event.target.value); + }; + + const [data, setData] = useState([]); + const [totalRows, setTotalRows] = useState(0); + const [perPage, setPerPage] = useState(10); + const [textValue, setTextValue] = useState(""); + const [page, setPage] = useState(1); + const [tableData, setTableData] = useState([]); + + const fetchApiData = async (page) => { + let response; + dispatch(LOADING_START()); + response = await axios.get( + `poultry_hatching_prediction/?search=filter&value=${textValue}&role=${getRoleFromUrl()}&page=${page}&page_size=${perPage}` + ); + dispatch(LOADING_END()); + setData(response.data.results); + setTotalRows(response.data.count); + }; + + const handlePageChange = (page) => { + fetchApiData(page); + setPage(page); + }; + + const handlePerRowsChange = (perRows) => { + setPerPage(perRows); + setPage(1); + }; + + // const updateTable = () => { + // fetchApiData(page !== 0 ? page : 1); + // }; + + useEffect(() => { + const d = data?.map((item, i) => { + return [ + page === 1 ? i + 1 : i + perPage * (page - 1) + 1, + item?.poultry?.unitName, + item?.poultry?.fullname || "-", + item?.poultry?.killingAveAge?.toLocaleString(), + item?.poultry?.realKillingAveWeight?.toLocaleString(), + item?.period?.toLocaleString(), + formatJustDate(item?.date), + item?.quantity?.toLocaleString(), + item?.generalInfo?.age?.toLocaleString(), + item?.chickenBreed || "-", + item?.generalInfo?.totalQuantity?.toLocaleString(), + item?.generalInfo?.totalWeight?.toLocaleString(), + item?.generalInfo?.provinceKillRequests?.toLocaleString(), + item?.generalInfo?.provinceKillRequestsQuantity?.toLocaleString(), + item?.generalInfo?.provinceKillRequestsWeight?.toLocaleString(), + item?.leftOver?.toLocaleString(), + Math.round( + item?.poultry?.realKillingAveWeight * item?.leftOver + ).toLocaleString(), + Math.round( + item?.poultry?.realKillingAveWeight * item?.leftOver * 0.75 + ).toLocaleString(), + ]; + }); + + setTableData(d); + }, [data]); + + useEffect(() => { + fetchApiData(1); + }, [dispatch, perPage]); + + const handleSubmit = async (event) => { + event.preventDefault(); + dispatch(LOADING_START()); + + try { + const response = await axios.get( + `poultry_hatching_prediction/?role=${getRoleFromUrl()}&search=filter&value=${textValue}&page=${1}&page_size=${perPage}` + ); + setData(response.data.results); + setTotalRows(response.data.count); + dispatch(LOADING_END()); + } catch (error) { + console.error("Error fetching data:", error); + } + }; + + return ( + + + +
    + + + +
    +
    + + +
    + ); +}; diff --git a/src/features/visors/components/visor-statics-prediction/VisorStaticsPrediction.js b/src/features/visors/components/visor-statics-prediction/VisorStaticsPrediction.js new file mode 100644 index 0000000..cc9614e --- /dev/null +++ b/src/features/visors/components/visor-statics-prediction/VisorStaticsPrediction.js @@ -0,0 +1,104 @@ +import React, { useEffect, useState } from "react"; +import { Grid } from "../../../../components/grid/Grid"; +import { useDispatch } from "react-redux"; +import { visorsGetPredictionStaticsDashboardService } from "../../services/get-visor-prediction-dashboard"; +import ResponsiveTable from "../../../../components/responsive-table/ResponsiveTable"; +import { VisorStaticsPredictionCharts } from "../visor-statics-prediction-charts/VisorStaticsPredictionCharts"; +import { VisorStaticsPredictionHatchings } from "../visor-statics-prediction-hatchings/VisorStaticsPredictionHatchings"; +import { IconButton, Tooltip } from "@mui/material"; +import ArrowDownwardIcon from "@mui/icons-material/ArrowDownward"; +import ArrowUpwardIcon from "@mui/icons-material/ArrowUpward"; +import { motion, AnimatePresence } from "framer-motion"; // Import Framer Motion + +export const VisorStaticsPrediction = () => { + const dispatch = useDispatch(); + + const [dashboardData, setDashboardData] = useState([]); + const [showHatchings, setShowHatchings] = useState(false); + + useEffect(() => { + dispatch(visorsGetPredictionStaticsDashboardService()).then((r) => { + setDashboardData(r.payload.data); + }); + }, [dispatch]); + + return ( + + + + { + setShowHatchings(!showHatchings); + }} + > + {showHatchings ? : } + + + } + columns={[ + "جوجه ریزی های فعال", + "حجم جوجه ریزی فعال", + "میانگین سنی", + "میانگین سن کشتار ", + "میانگین وزن کشتار ", + "حجم کشتار", + "وزن کشتار", + "تعداد بارها", + "حجم بارها", + "وزن بارها", + "تخصیص بدون بار", + "حجم تخصیص بدون بار", + "وزن تخصیص بدون بار", + "حجم مانده در سالن", + ]} + data={[ + [ + dashboardData?.hatchings?.toLocaleString(), + dashboardData?.totalHatchingQuantity?.toLocaleString(), + dashboardData?.aveNowAge?.toLocaleString(), + dashboardData?.aveAge?.toLocaleString(), + dashboardData?.aveWeight?.toLocaleString(), + dashboardData?.totalQuantity?.toLocaleString(), + dashboardData?.totalWeight?.toLocaleString(), + dashboardData?.killHouseRequests?.toLocaleString(), + dashboardData?.killHouseRequestsQuantity?.toLocaleString(), + dashboardData?.provinceKillRequestsWeight?.toLocaleString(), + dashboardData?.provinceKillRequests?.toLocaleString(), + dashboardData?.provinceKillRequestsQuantity?.toLocaleString(), + dashboardData?.provinceKillRequestsWeight?.toLocaleString(), + dashboardData?.totalHatchingLeftOver?.toLocaleString(), + ], + ]} + title={"خلاصه اطلاعات"} + /> + + {showHatchings && ( + + + + + + )} + + + + + + ); +}; diff --git a/src/features/visors/components/visors-statics-main-page/VisorsStaticsMainPage.js b/src/features/visors/components/visors-statics-main-page/VisorsStaticsMainPage.js new file mode 100644 index 0000000..55bea44 --- /dev/null +++ b/src/features/visors/components/visors-statics-main-page/VisorsStaticsMainPage.js @@ -0,0 +1,547 @@ +import React, { useEffect, useState } from "react"; +import html2canvas from "html2canvas"; +import { Grid } from "../../../../components/grid/Grid"; +import { SPACING } from "../../../../data/spacing"; +import { + Button, + Checkbox, + Divider, + FormControl, + FormControlLabel, + InputLabel, + MenuItem, + Popover, + Select, + Typography, + IconButton, + Dialog, + DialogContent, + DialogTitle, +} from "@mui/material"; +import AddchartIcon from "@mui/icons-material/Addchart"; +import FullscreenIcon from "@mui/icons-material/Fullscreen"; +import FullscreenExitIcon from "@mui/icons-material/FullscreenExit"; +import { useDispatch } from "react-redux"; +import { visorsGetStaticsService } from "../../services/get-visors-statics"; +import { Line } from "react-chartjs-2"; +import CloseIcon from "@mui/icons-material/Close"; +import FmdBadIcon from "@mui/icons-material/FmdBad"; +import Accordion from "@mui/material/Accordion"; +import AccordionSummary from "@mui/material/AccordionSummary"; +import AccordionDetails from "@mui/material/AccordionDetails"; +import ExpandMoreIcon from "@mui/icons-material/ExpandMore"; +import DownloadIcon from "@mui/icons-material/Download"; +import { + Chart as ChartJS, + CategoryScale, + LinearScale, + PointElement, + LineElement, + Title, + Tooltip, + Legend, +} from "chart.js"; +import { formatJustDate, getPersianMonth } from "../../../../utils/formatTime"; +import { RiFileExcel2Fill } from "react-icons/ri"; +import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl"; + +ChartJS.register( + CategoryScale, + LinearScale, + PointElement, + LineElement, + Title, + Tooltip, + Legend +); + +export const VisorsStaticsMainPage = () => { + // chart states + const [barsState, setBarsState] = useState(false); + const [bars, setBars] = useState(null); + const [fullSizeChart, setFullSizeChart] = useState(null); + + // order state for charts + const [chartOrder, setChartOrder] = useState([ + "hasCodeData", + "quarantineQuantityData", + "assignmentStateArchiveData", + "acceptedAssignmentRealWeightData", + "hasntCodeData", + "differenceBarData", + "wareHouseConfirmationData", + "wareHouseAcceptedRealWeightData", + "weightYearData", + ]); + + // visibility states for each chart + const [chartVisibility, setChartVisibility] = useState({ + hasCodeData: true, + quarantineQuantityData: true, + assignmentStateArchiveData: true, + acceptedAssignmentRealWeightData: true, + hasntCodeData: true, + differenceBarData: true, + wareHouseConfirmationData: true, + wareHouseAcceptedRealWeightData: true, + weightYearData: true, + }); + + // end charts + const dispatch = useDispatch(); + const [anchorEl, setAnchorEl] = useState(null); + + const [threshold, setThreshold] = useState("threeMonths"); + const [fullSizeTitle, setFullSizeTitle] = useState(""); + + const handleChange = (event) => { + setThreshold(event.target.value); + }; + + const handleClick = (event) => { + setAnchorEl(event.currentTarget); + }; + + const handleClose = () => { + setAnchorEl(null); + }; + + const handleFullSizeOpen = (chartData) => { + setFullSizeChart(chartData); + }; + + const handleFullSizeClose = () => { + setFullSizeChart(null); + }; + + const handleVisibilityChange = (chartKey) => { + setChartVisibility({ + ...chartVisibility, + [chartKey]: !chartVisibility[chartKey], + }); + }; + + useEffect(() => { + if (barsState) { + dispatch(visorsGetStaticsService({ type: threshold })).then((r) => { + setBars(r.payload.data); + }); + } else { + setBars(null); + } + }, [barsState, threshold]); + + const open = Boolean(anchorEl); + const id = open ? "simple-popover" : undefined; + + const transformData = (data) => { + return { + labels: + threshold !== "month" + ? data.map((item) => getPersianMonth(item.date)) + : data.map((item) => formatJustDate(item.date)), + datasets: [ + { + label: "درصد", + data: data.map((item) => item.percent), + borderColor: "rgba(55, 41, 145, 0.6)", + backgroundColor: "rgba(75, 192, 192, 0.2)", + }, + ], + }; + }; + + const chartOptions = { + scales: { + y: { + beginAtZero: true, + min: 0, + }, + }, + }; + + const hasCodeData = bars ? transformData(bars.hasCode) : null; + const quarantineQuantityData = bars + ? transformData(bars.quarantineQuantity) + : null; + const differenceBarData = bars ? transformData(bars.differenceBar) : null; + const assignmentStateArchiveData = bars + ? transformData(bars.assignmentStateArchive) + : null; + const acceptedAssignmentRealWeightData = bars + ? transformData(bars.acceptedAssignmentRealWeight) + : null; + const hasntCodeData = bars ? transformData(bars.hasntCode) : null; + const wareHouseConfirmationData = bars + ? transformData(bars.wareHouseConfirmation) + : null; + const wareHouseAcceptedRealWeightData = bars + ? transformData(bars.wareHouseAcceptedRealWeight) + : null; + const weightYearData = bars ? transformData(bars.weightYear) : null; + + const chartsData = { + hasCodeData: { title: "درصد بارهای دارای کد قرنطینه", data: hasCodeData }, + quarantineQuantityData: { + title: "درصد تعداد بارهای احراز شده از قرنطینه", + data: quarantineQuantityData, + }, + assignmentStateArchiveData: { + title: "درصد تعداد بارهای تکمیل شده کشتارگاه", + data: assignmentStateArchiveData, + }, + acceptedAssignmentRealWeightData: { + title: "درصد وزن نهایی در کشتارگاه نسبت به وزن کل", + data: acceptedAssignmentRealWeightData, + }, + hasntCodeData: { + title: "درصد بارهای فاقد کد قرنطینه", + data: hasntCodeData, + }, + differenceBarData: { + title: "درصد بارهای اختلاف دار در قرنطینه و رصدیار", + data: differenceBarData, + }, + wareHouseConfirmationData: { + title: "درصد تعداد بارهای ورودی به انبار", + data: wareHouseConfirmationData, + }, + wareHouseAcceptedRealWeightData: { + title: "درصد وزن لاشه ها در انبار نسبت به وزن کل", + data: wareHouseAcceptedRealWeightData, + }, + weightYearData: { + title: "درصد وزن لاشه در انبار نسبت به وزن نهایی در کشتارگاه", + data: weightYearData, + }, + }; + + const handleDragStart = (event, index) => { + event.dataTransfer.setData("draggedIndex", index); + }; + + const handleDrop = (event, dropIndex) => { + const draggedIndex = event.dataTransfer.getData("draggedIndex"); + const reordered = Array.from(chartOrder); + const [removed] = reordered.splice(draggedIndex, 1); + reordered.splice(dropIndex, 0, removed); + setChartOrder(reordered); + }; + + const handleDragOver = (event) => { + event.preventDefault(); + }; + + const downloadScreenshot = () => { + const gridElement = document.getElementById("screenshot-container"); + html2canvas(gridElement).then((canvas) => { + const link = document.createElement("a"); + link.href = canvas.toDataURL("image/png"); + link.download = "پایش آماری.png"; + link.click(); + }); + }; + + const downloadSingleScreenshot = () => { + const gridElement = document.getElementById("screenshot-single-container"); + html2canvas(gridElement).then((canvas) => { + const link = document.createElement("a"); + link.href = canvas.toDataURL("image/png"); + link.download = "پایش آماری.png"; + link.click(); + }); + }; + + return ( + + + + + + + + انتخاب نمودار + + + + + + { + handleClose(); + setBarsState(!barsState); + }} + /> + } + label={"اطلاعات مدیریت بار"} + /> + + + + + + + + پایش آماری + + + + + + + انتخاب بازه + + + + {getRoleFromUrl() === "AdminX" && ( + + + + + + )} + + + {barsState && ( + { + setBarsState(false); + setBars(null); + }} + style={{ cursor: "pointer" }} + > + + + {" "} + + اطلاعات مدیریت بار + + + )} + + + + + + + + با کشیدن و رها کردن نمودارها میتوانید ترتیب نمایش آنها را تغییر + دهید.{" "} + + + + + + + + + + {bars && ( + + } + aria-controls="panel1-content" + id="panel1-header" + > + + فیلتر نمودارها + + + + + {Object.keys(chartsData).map((chartKey) => ( + + handleVisibilityChange(chartKey)} + /> + } + label={chartsData[chartKey].title} + /> + + ))} + + + + )} + + + + {bars && ( + <> + {chartOrder.map((chartKey, index) => { + const chart = chartsData[chartKey]; + return ( + chartVisibility[chartKey] && ( + handleDragStart(event, index)} + onDrop={(event) => handleDrop(event, index)} + onDragOver={handleDragOver} + onDoubleClick={() => { + setFullSizeTitle(chart.title); + handleFullSizeOpen(chart.data); + }} + > + + {chart.title} + + { + setFullSizeTitle(chart.title); + handleFullSizeOpen(chart.data); + }} + > + + + + + ) + ); + })} + + )} + + + {fullSizeChart && ( + + + + + + + + + + + + + + + + + {fullSizeTitle} + + + + + + )} + + ); +}; diff --git a/src/features/visors/components/visors-statics-operations/VisorsStaticsOperations.js b/src/features/visors/components/visors-statics-operations/VisorsStaticsOperations.js new file mode 100644 index 0000000..f5b9f28 --- /dev/null +++ b/src/features/visors/components/visors-statics-operations/VisorsStaticsOperations.js @@ -0,0 +1,181 @@ +import React from "react"; +import { useLocation } from "react-router-dom"; +import { Grid } from "../../../../components/grid/Grid"; +import { SPACING } from "../../../../data/spacing"; +import LinkItem from "../../../../components/link-item/LinkItem"; +import { + VscPieChart, + VscGraph, + VscGraphLine, + VscRunAll, +} from "react-icons/vsc"; +import { NavLink } from "../../../../components/nav-link/NavLink"; +import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl"; +import { + ROUTE_ADMIN_NATIONAL_STATICS, + ROUTE_ADMIN_STATICS, + ROUTE_ADMINX_NATIONAL_STATICS, + ROUTE_ADMINX_STATICS, + ROUTE_ADMINX_VISOR_STATICS_CHARTS, + ROUTE_ADMINX_VISOR_STATICS_PREDICTION, + ROUTE_CITY_POULTRY_STATICS, + ROUTE_CITY_STATICS, + ROUTE_CITY_VISOR_STATICS_CHARTS, + ROUTE_CITY_VISOR_STATICS_PREDICTION, + ROUTE_COMMERCE_STATICS, + ROUTE_COMMERCE_VISOR_STATICS_CHARTS, + ROUTE_COMMERCE_VISOR_STATICS_PREDICTION, + ROUTE_INSPECTOR_STATICS, + ROUTE_JAHAD_KILLS_STATS, + ROUTE_OBSERVATORY_VISOR_STATICS_CHARTS, + ROUTE_OBSERVATORY_VISOR_STATICS_PREDICTION, + ROUTE_PROVINCE_FINANCIAL_STATICS, + ROUTE_PROVINCE_NATIONAL_STATICS, + ROUTE_PROVINCE_STATICS, + ROUTE_PROVINCE_SUPERVISOR_STATICS_CHARTS, + ROUTE_PROVINCE_SUPERVISOR_STATICS_PREDICTION, + ROUTE_PROVINCEـVISOR_STATICS_CHARTS, + ROUTE_PROVINCEـVISOR_STATICS_PREDICTION, + ROUTE_SUPER_ADMIN_NATIONAL_STATICS, + ROUTE_SUPER_ADMIN_STATICS, + ROUTE_SUPER_ADMIN_VISOR_STATICS_CHARTS, + ROUTE_SUPER_ADMIN_VISOR_STATICS_PREDICTION, + ROUTE_VETـSUPERVISOR_STATICS, + ROUTE_VETـSUPERVISOR_STATICS_CHARTS, + ROUTE_VETـSUPERVISOR_STATICS_PREDICTION, +} from "../../../../routes/routes"; + +export const VisorsStaticsOperations = () => { + const { pathname } = useLocation(); + + return ( + + + + + } + title="پایش آمار کشتار" + description="پایش آمار کشتار" + /> + + + + } + title="پیش بینی موجودی" + description="پیش بینی موجودی" + /> + + + + } + title="آمار و اطلاعات" + description="آمار و اطلاعات" + /> + + + + } + title="پایش کشوری" + description="پایش کشوری" + /> + + + + + ); +}; diff --git a/src/features/visors/services/fetch-samasat-transport-chickens.js b/src/features/visors/services/fetch-samasat-transport-chickens.js new file mode 100644 index 0000000..82347fb --- /dev/null +++ b/src/features/visors/services/fetch-samasat-transport-chickens.js @@ -0,0 +1,38 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const cityFetchSamasatTransportChickens = createAsyncThunk( + "FETCH_SAMASAT_CHICKENS", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + const { data, status } = await axios.post( + "https://pay.rasadyar.net/transporting-chickens/", + d + ); + dispatch(LOADING_END()); + return { data, status }; + } +); +export const cityFetchSamasatTransportChickensDetails = createAsyncThunk( + "FETCH_SAMASAT_CHICKENS_DETAILS", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + const { data, status } = await axios.post( + "https://pay.rasadyar.net/transporting-chickens-details/", + d + ); + dispatch(LOADING_END()); + return { data, status }; + } +); + +export const visorsGetSamasatCookieService = createAsyncThunk( + "VISORS_GET_COOKIE", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + const { data, status } = await axios.get(`cookie-samasat`); + dispatch(LOADING_END()); + return { data, status }; + } +); diff --git a/src/features/visors/services/get-visor-national-info.js b/src/features/visors/services/get-visor-national-info.js new file mode 100644 index 0000000..b91e9da --- /dev/null +++ b/src/features/visors/services/get-visor-national-info.js @@ -0,0 +1,22 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const visorsGetNationalInfoService = createAsyncThunk( + "VISORS_GET_NATIONAL_iNFO", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + const { data, status } = await axios.get( + `https://rsibackend.rasadyar.com/app/hatching-analysis-` + d.type, + { + params: { + date1: d.withDate ? d.selectedDate1 : null, + date2: d.withDate ? d.selectedDate2 : null, + province: d.selectedProvince ? d.selectedProvince : null, + }, + } + ); + dispatch(LOADING_END()); + return { data, status }; + } +); diff --git a/src/features/visors/services/get-visor-prediction-chart.js b/src/features/visors/services/get-visor-prediction-chart.js new file mode 100644 index 0000000..727acd9 --- /dev/null +++ b/src/features/visors/services/get-visor-prediction-chart.js @@ -0,0 +1,18 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const visorsGetPredictionStaticsChartService = createAsyncThunk( + "VISORS_GET_PREDICTION_STATICS_CHART", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + const { data, status } = await axios.get( + `poultry_hatching_prediction_chart`, + { + params: d, + } + ); + dispatch(LOADING_END()); + return { data, status }; + } +); diff --git a/src/features/visors/services/get-visor-prediction-dashboard.js b/src/features/visors/services/get-visor-prediction-dashboard.js new file mode 100644 index 0000000..a75211c --- /dev/null +++ b/src/features/visors/services/get-visor-prediction-dashboard.js @@ -0,0 +1,21 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { getRoleFromUrl } from "../../../utils/getRoleFromUrl"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const visorsGetPredictionStaticsDashboardService = createAsyncThunk( + "VISORS_GET_PREDICTION_STATICS_DASHBOARD", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + const { data, status } = await axios.get( + `poultry_hatching_prediction_dashboard`, + { + params: { + role: getRoleFromUrl(), + }, + } + ); + dispatch(LOADING_END()); + return { data, status }; + } +); diff --git a/src/features/visors/services/get-visors-statics.js b/src/features/visors/services/get-visors-statics.js new file mode 100644 index 0000000..001434f --- /dev/null +++ b/src/features/visors/services/get-visors-statics.js @@ -0,0 +1,19 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import axios from "axios"; +import { getRoleFromUrl } from "../../../utils/getRoleFromUrl"; +import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice"; + +export const visorsGetStaticsService = createAsyncThunk( + "VISORS_GET_STATICS", + async (d, { dispatch }) => { + dispatch(LOADING_START()); + const { data, status } = await axios.get(`data_report_percentages`, { + params: { + role: getRoleFromUrl(), + type: d.type, + }, + }); + dispatch(LOADING_END()); + return { data, status }; + } +); diff --git a/src/hooks/useAuthToken.js b/src/hooks/useAuthToken.js new file mode 100644 index 0000000..627472c --- /dev/null +++ b/src/hooks/useAuthToken.js @@ -0,0 +1,9 @@ +import { useSelector } from "react-redux"; + +// Custom hook to retrieve the authentication token from Redux +export const useAuthToken = () => { + // Replace 'authToken' with the appropriate selector for your authentication token in Redux + const { authToken } = useSelector((state) => state.userSlice); + + return authToken; +}; diff --git a/src/hooks/useLocalStorage.js b/src/hooks/useLocalStorage.js new file mode 100644 index 0000000..b215c5a --- /dev/null +++ b/src/hooks/useLocalStorage.js @@ -0,0 +1,13 @@ +import React from "react"; + +export const useLocalStorage = (storageKey, fallbackState) => { + const [value, setValue] = React.useState( + JSON.parse(localStorage.getItem(storageKey)) ?? fallbackState + ); + + React.useEffect(() => { + localStorage.setItem(storageKey, JSON.stringify(value)); + }, [value, storageKey]); + + return [value, setValue]; +}; diff --git a/src/index.css b/src/index.css new file mode 100644 index 0000000..69578c3 --- /dev/null +++ b/src/index.css @@ -0,0 +1,473 @@ +@import url("./assets/fonts/fonts.css"); +body { + margin: 0; + font-family: "IRANSans", -apple-system, BlinkMacSystemFont, "Segoe UI", + "Roboto", "Oxygen", "Ubuntu", "Cantarell", "Fira Sans", "Droid Sans", + "Helvetica Neue", sans-serif; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; + /* zoom: 90%; */ + overflow-x: hidden; +} +code { + font-family: source-code-pro, Menlo, Monaco, Consolas, "Courier New", + monospace; +} + +.process-table { + overflow-x: scroll; +} + +.process-table { + font-family: "iranyekan" !important; +} +.process-table th { + font-size: 14px; +} +.process-table td { + font-size: 12px; +} + +.process-table table { + width: 100%; + border-collapse: collapse; + border: 1px solid #ddd; +} + +.process-table th, +.process-table td { + border: 1px solid #ddd; + padding: 8px; + width: 300px !important; +} + +.process-table th { + background-color: #f2f2f2; +} + +@media only screen and (max-width: 400px) { + .resp-table.simple-table .MuiTableCell-root { + width: 50%; + /* border: 1px solid #ccc; */ + border: none; + margin-bottom: 5px; + margin-top: 5px; + } + + .resp-table.simple-table .MuiTableCell-root div { + display: block; + margin: auto; + } + + .resp-table.simple-table .MuiTableCell-root:nth-child(odd) { + /* background-color: red; */ + border-left: 1px solid #ccc !important; + } +} + +.row-item-table-accordion { + flex-direction: row-reverse; +} + +.page-table { + font-family: "iranyekan"; + margin-top: 30px; +} + +.rdt_TableHeadRow { + background-color: #ddd; +} + +.rdt_TableCol_Sortable div { + white-space: normal !important; +} + +.header-stats { + border: 1px solid rgb(221, 221, 221); + padding: 8px; + border-radius: 20px 20px 0px 0px; + background: #e9f5ff; + border-top: 5px solid #2196f3; + border-bottom: 0px; +} + +.stats-wrap { + background-color: rgb(238, 238, 238); + border: 1px solid #ccc; + width: 240px; +} + +.stats-title { + background-color: rgb(231, 231, 231); + border: 1px solid #ccc; + padding: 10px; + margin: 0px !important; +} + +.stats-content { + padding: 10px !important; +} + +.credit { + margin-top: 8px; + position: sticky; + bottom: 0; + left: 50%; + right: 50%; + background: #2196f3; + color: white; + padding: 4px 0; + z-index: 999; +} + +/* .scroll-table .MuiPaper-root { + width: 1000px; + position: initial; + overflow: scroll; +} */ + +.ExcelTable2007 table { + width: 100%; + border-collapse: collapse; +} + +.ExcelTable2007 th, +.ExcelTable2007 td { + border: 1px solid #ddd; + padding: 8px; + text-align: center; + font-family: iranyekan, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, + "Helvetica Neue", sans-serif, Arial, "Apple Color Emoji", "Segoe UI Emoji", + "Segoe UI Symbol"; +} + +.ExcelTable2007 th { + background-color: #f2f2f2; +} + +.ExcelTable2007 .heading { + font-weight: bold; +} + +/* .my-table { + width: 100%; +} +.my-table tbody > .MuiTableRow-root { + border: 1px solid; +} + +.my-table tbody > tr > th { + border: 1px solid !important; +} + +.my-table th > .row-kill-request { + border-bottom: 1px solid !important; +} +.my-table th > .row-kill-request:last-child { + border-bottom: 0px solid !important; +} */ + +.percent-input-quota input { + text-align: center; +} + +.auto-allocation-table { + font-family: iranyekan; + border-collapse: collapse; + width: 100%; +} + +.auto-allocation-table th, +.auto-allocation-table td { + border: 1px solid #adadad; + padding: 8px; + text-align: center; +} + +.auto-allocation-table th { + background-color: #f2f2f2; + text-align: center; +} + +.auto-allocation-table { + border-collapse: collapse; +} + +.MuiTable-head th { + font-weight: bold; + border-bottom: 2px solid #ddd; + text-align: left; + padding: 10px; +} + +.MuiTableCell-root { + padding: 10px; +} + +.no-border-flex-table { + display: inline-flex; + white-space: nowrap; + flex-direction: column; + border: none !important; +} + +.my-table .loop-kill-request { + padding: 0; +} + +.table-section:first-child { + overflow-x: scroll; +} + +.rnc { + display: flex; + flex-direction: row; + width: 100%; +} + +.rnc-row { + display: flex; + align-items: stretch; + margin: 0 0 10px 0; +} + +.rnc-column { + display: flex; + flex-direction: column; + justify-content: space-between; + margin: 0 0 0 10px; +} + +.rnc-canvas { + box-sizing: border-box; + background-color: #fff; + border-radius: 4px; +} + +.rnc-button { + display: flex; + justify-content: center; + align-items: center; + font-size: 16px; + background: #fff; + color: inherit; + border: none; + padding: 0; + width: 25px; + height: 20px; + box-sizing: border-box; + border-radius: 4px; +} + +.rnc-button svg { + width: 1em; + height: 1em; + fill: currentColor; +} + +.rnc-input { + display: none; + border: none; + padding: 10px 6px; + font-size: inherit; + font-family: inherit; +} + +.MuiTimelineItem-positionRight:before { + content: "" !important; + flex: none !important; +} + +.simple-table .MuiTableCell-root { + padding: 8px 0px 8px 0px !important; +} + +.muirtl-1gyekjj-MuiTimelineItem-root:before { + padding: 0px !important; +} + +.images-file { + border-radius: 5px; +} + +.reactour__helper--is-open div:first-child { + padding-top: 25px; +} +.reactour__helper--is-open { + border-radius: 4px !important; +} +.reactour__helper--is-open { + border-radius: 4px !important; +} +.reactour__mask { + border-radius: 10px !important; + background-color: red; +} +/* reactor controls rtl */ +.sc-bZQynM.diKbXs { + direction: ltr; +} + +@media only screen and (max-width: 600px) { + .rnc { + flex-direction: column; + } + .rnc-row { + justify-content: space-between; + align-items: center; + } + .rnc-column { + flex-direction: row; + gap: 40px; + } + .rnc-button { + font-size: 32px; + } +} + +.timerIcon { + animation-duration: 1s; + animation-name: example; + animation-timing-function: ease-in-out; + animation-iteration-count: infinite; +} + +@keyframes example { + from { + transform: scale(0.7); + } + to { + transform: scale(0.9); + } +} + +/* table */ + +.table-styles { + border-collapse: collapse; + font-family: "iranyekan", sans-serif; + font-size: 12px; + text-align: center; + box-shadow: 0px 0px 5px rgb(190, 127, 127); + overflow-x: auto; + width: 100%; +} +.table-styles th { + padding: 5px; +} + +.green-header { + background-color: #4caf50; + color: white; +} + +.strong-blue-cell-combine { + color: white; + background-color: #007bff; + text-align: center; +} + +.blue-cell, +.light-green-cell, +.light-blue-cell, +.green-cell, +.strong-blue-cell, +.light-yellow-cell, +.sky-blue-cell, +.brown-cell, +.green-header th, +.yellow-cell, +.red-cell { + color: white; + border: 1px solid #ce9c9c; + transition: background-color 0.3s; +} + +.blue-cell:hover, +.light-blue-cell:hover, +.green-cell:hover, +.strong-blue-cell:hover, +.light-yellow-cell:hover, +.sky-blue-cell:hover, +.brown-cell:hover, +.green-header th:hover, +.light-green-cell:hover, +.yellow-cell:hover, +.red-cell:hover { + background-color: #333; + color: white !important; +} + +.light-green-cell { + color: rgb(99, 97, 97); + border: 1px solid #ce9c9c; +} + +.blue-cell { + background-color: #2196f3; +} + +.light-blue-cell { + background-color: #6195aa; +} + +.green-cell { + background-color: #4caf50; +} + +.light-green-cell { + background-color: #90ee90; +} + +.strong-blue-cell { + background-color: #007bff; +} + +.yellow-cell { + background-color: #ffeb3b; + color: black !important; +} + +.detail-cell { + background-color: #f8f8ce; +} + +.light-yellow-cell { + background-color: #d4af37; +} + +.sky-blue-cell { + background-color: #87cefa; +} + +.brown-cell { + background-color: #b16128; +} + +.red-cell { + background-color: #ff6347; +} + +.centered-cell { + text-align: center; + border: 1px solid #ce9c9c; + padding: 5px; +} + +.table-container { + width: 100%; + display: flex; + justify-content: center; +} + +.last-table-container { + width: 78vw; + display: flex; + justify-content: center; +} + +.muirtl-1yt3g2g-MuiTableCell-root { + line-height: 1.2 !important; +} + +/* end table */ diff --git a/src/index.js b/src/index.js new file mode 100644 index 0000000..ad2ea75 --- /dev/null +++ b/src/index.js @@ -0,0 +1,33 @@ +import React from "react"; +import ReactDOM from "react-dom/client"; +import "./index.css"; +import App from "./App"; +import * as serviceWorkerRegistration from "./serviceWorkerRegistration"; +import reportWebVitals from "./reportWebVitals"; +import { BrowserRouter } from "react-router-dom"; +import { Provider } from "react-redux"; +import { PersistGate } from "redux-persist/integration/react"; +import { persistor, store } from "./lib/redux/store"; + +const root = ReactDOM.createRoot(document.getElementById("root")); +root.render( + // + + + + + + + + // +); + +// If you want your app to work offline and load faster, you can change +// unregister() to register() below. Note this comes with some pitfalls. +// Learn more about service workers: https://cra.link/PWA +serviceWorkerRegistration.register(); + +// If you want to start measuring performance in your app, pass a function +// to log results (for example: reportWebVitals(console.log)) +// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals +reportWebVitals(); diff --git a/src/layouts/bottom-navigation/BottomNavigation.js b/src/layouts/bottom-navigation/BottomNavigation.js new file mode 100644 index 0000000..32a3c66 --- /dev/null +++ b/src/layouts/bottom-navigation/BottomNavigation.js @@ -0,0 +1,27 @@ +import * as React from "react"; +import Box from "@mui/material/Box"; +import BottomNavigation from "@mui/material/BottomNavigation"; +import BottomNavigationAction from "@mui/material/BottomNavigationAction"; +import RestoreIcon from "@mui/icons-material/Restore"; +import FavoriteIcon from "@mui/icons-material/Favorite"; +import LocationOnIcon from "@mui/icons-material/LocationOn"; + +export default function SimpleBottomNavigation() { + const [value, setValue] = React.useState(0); + + return ( + + { + setValue(newValue); + }} + > + } /> + } /> + } /> + + + ); +} diff --git a/src/layouts/fallback/Fallback.js b/src/layouts/fallback/Fallback.js new file mode 100644 index 0000000..0fc1c71 --- /dev/null +++ b/src/layouts/fallback/Fallback.js @@ -0,0 +1,11 @@ +import { CircularProgress } from "@mui/material"; +import { Grid } from "../../components/grid/Grid"; +import { SPACING } from "../../data/spacing"; + +export const Fallback = () => { + return ( + + + + ); +}; diff --git a/src/layouts/header-operations/HeaderOperations.js b/src/layouts/header-operations/HeaderOperations.js new file mode 100644 index 0000000..cb72876 --- /dev/null +++ b/src/layouts/header-operations/HeaderOperations.js @@ -0,0 +1,420 @@ +import React, { useEffect, useState } from "react"; +import { + Avatar, + Badge, + Box, + Button, + IconButton, + Menu, + Tooltip, + Typography, +} from "@mui/material"; +import { useDispatch, useSelector } from "react-redux"; +import { Grid } from "../../components/grid/Grid"; +import { + ROUTE_GENERAL_MESSAGES, + ROUTE_GENERAL_SUPPORT, + ROUTE_GENERAL_TICKET_LIST, + ROUTE_GENERAL_TRAINING, + ROUTE_GENERAL_USER_PROFILE, +} from "../../routes/routes"; +import PermPhoneMsgIcon from "@mui/icons-material/PermPhoneMsg"; +import EmailIcon from "@mui/icons-material/Email"; +import { useNavigate } from "react-router-dom"; +import AccountCircleRoundedIcon from "@mui/icons-material/AccountCircleRounded"; +import ExitToAppIcon from "@mui/icons-material/ExitToApp"; +import { + BACKDROP_HIDE, + CLOSE_MODAL, + DRAWER, + OPEN_MODAL, +} from "../../lib/redux/slices/appSlice"; +import { + LOG_OUT, + SET_ADMIN_TOKEN, + SET_SELECTED_ROLE, + SET_SELECTED_SUB_USER, +} from "../../lib/redux/slices/userSlice"; +import PlayCircleIcon from "@mui/icons-material/PlayCircle"; +import KeyboardReturnIcon from "@mui/icons-material/KeyboardReturn"; +import DraftsIcon from "@mui/icons-material/Drafts"; +import { motion } from "framer-motion"; +import { getUnseenMessages } from "../../features/authentication/services/getUnseenMessage"; +import { ChevronLeft } from "@mui/icons-material"; + +export const HeaderOperations = () => { + const [anchorEl, setAnchorEl] = useState(null); + const open = Boolean(anchorEl); + const dispatch = useDispatch(); + const userProfile = useSelector((state) => state.userSlice.loginUserProfile); + const navigate = useNavigate(); + + const handleMenuToggle = (event) => { + setAnchorEl(event.currentTarget); + }; + + const [unseenMessages, setUnseenMessages] = useState({ + state: false, + num: 0, + }); + const role = useSelector((state) => state.userSlice.role); + + const handleMenuClose = () => { + setAnchorEl(null); + }; + + useEffect(() => { + dispatch(getUnseenMessages()) + .then((r) => { + if (r?.payload?.data) { + setUnseenMessages(r.payload.data); + } + }) + .catch((error) => { + console.error("Error fetching unseen messages:", error); + setUnseenMessages({ + state: false, + num: 0, + }); + }); + }, [dispatch]); + + function stringAvatar(name) { + if (name) { + const nameArr = name + ?.split(" ") + ?.filter((item) => item) + ?.map((item) => item[0]); + return { + sx: { + bgcolor: "#353b48", + }, + children: nameArr[0], + }; + } + return {}; + } + + return ( + + + { + navigate(ROUTE_GENERAL_TICKET_LIST); + }} + > + {unseenMessages?.state ? ( + + + + + + ) : ( + + )} + + + + + + + + + + {userProfile?.fullname || "-"} + + + {userProfile?.mobile || "-"} + + + + + + { + navigate(ROUTE_GENERAL_USER_PROFILE); + handleMenuClose(); + }} + sx={{ + cursor: "pointer", + }} + > + + {userProfile?.image && + userProfile?.image !== "empty" && + userProfile?.fullname ? ( + + ) : ( + + )} + + + {userProfile?.fullname} + + + موبایل: {userProfile?.mobile} + + + + + + + + {/* */} + + + + {role?.includes("KillHouse") && ( + + + + )} + + + + + + + + + + + + + ), + }) + ); + }} + > + خروج + + + + + ); +}; diff --git a/src/layouts/header/Header.js b/src/layouts/header/Header.js new file mode 100644 index 0000000..0e356df --- /dev/null +++ b/src/layouts/header/Header.js @@ -0,0 +1,309 @@ +import { AppBar, Box, IconButton, Typography } from "@mui/material"; +import React from "react"; +import logo from "../../assets/images/logo.png"; +import iranView from "../../assets/images/IranOutlined.png"; +import HomeIcon from "@mui/icons-material/Home"; +import { useDispatch, useSelector } from "react-redux"; +import { Grid } from "../../components/grid/Grid"; +import { HeaderOperations } from "../header-operations/HeaderOperations"; +import { getRoleItems } from "../../utils/getRolesItems"; +import { useLocation, useNavigate } from "react-router-dom"; +import { sortRoles } from "../../utils/sortRoles"; +import { getRoleFromUrl } from "../../utils/getRoleFromUrl"; +import { useSystemName } from "../../utils/getSystemName"; +import CloudSyncIcon from "@mui/icons-material/CloudSync"; +import { tokenVerifiction } from "../../features/authentication/services/token-verifiction"; +import { LOADING_END, LOADING_START } from "../../lib/redux/slices/appSlice"; +import { loginWithPassword } from "../../features/authentication/services/login"; +import { SET_ADMIN_TOKEN } from "../../lib/redux/slices/userSlice"; +import { + getLiveStockRoles, + getUserTypeOfActivity, +} from "../../utils/getUserTypeOfActivity"; +import { getLiveStockItems } from "../../utils/getLivestock"; +import { AppMenu } from "../menu/Menu"; + +export const Header = () => { + const role = useSelector((state) => state.userSlice.role); + const navigate = useNavigate(); + const { pathname } = useLocation(); + // const authToken = useSelector((state) => state.userSlice.authToken); + const systemName = useSystemName(); + const adminToken = useSelector((state) => state.userSlice.adminToken); + const dispatch = useDispatch(); + const { typeActivitySelected } = useSelector((state) => state.userSlice); + + const userType = getUserTypeOfActivity([getRoleFromUrl()]); + + return ( + + + {/* + + + + {/* + + */} + + + + + + {/* */} + + { + navigate("/"); + }} + sx={{ + fontSize: 18, + fontWeight: 700, + color: "inherit", + textDecoration: "none", + mr: 2, + cursor: "pointer", + }} + > + {`رصـــد یـــار (سامانه رصد و پایش زنجیره تامین، تولید و توزیع کالای اساسی ) ${ + role.length === 1 && role[0] === "ParentCompany" + ? "شرکت مادر" + : systemName + }`} + + { + navigate("/"); + }} + sx={{ + fontSize: 18, + fontWeight: 700, + color: "inherit", + textDecoration: "none", + mr: 2, + cursor: "pointer", + }} + > + {"سامانه رصدیار"} + + + + + + + {adminToken && ( + { + dispatch(LOADING_START()); + dispatch(tokenVerifiction({ token: adminToken })).then((r) => { + dispatch(SET_ADMIN_TOKEN(null)); + dispatch( + loginWithPassword({ + mobile: r.payload.data?.username, + password: r.payload.data?.password, + }) + ).then(() => { + dispatch(LOADING_END()); + dispatch(SET_ADMIN_TOKEN(null)); + navigate("/"); + }); + }); + }} + > + + + )} + + + + + + + + + + + theme.palette.primary.main, + borderRadius: "8px", + backgroundColor: (theme) => + pathname === "/" + ? theme.palette.primary.light + : "transparent", + cursor: "pointer", + "&:hover": { + backgroundColor: "#EFEFEF", + }, + }} + onClick={() => { + navigate("/"); + }} + > + {pathname === "/" && } + + + خانه + + + + {(userType + ? (!!getRoleItems(getRoleFromUrl()).length && + getRoleItems(getRoleFromUrl())) || + getLiveStockItems(getRoleFromUrl()) + : typeActivitySelected === "Livestock" + ? getLiveStockItems(getLiveStockRoles(role)[0]) + : getRoleItems(sortRoles(role)[0]) + ) + .slice(0, 10) + .map((item, i) => ( + theme.palette.primary.main, + backgroundColor: (theme) => + pathname === item?.route + ? theme.palette.primary.light + : "transparent", + "&:hover": { + backgroundColor: "#EFEFEF", + }, + cursor: "pointer", + }} + onClick={() => { + navigate(item?.route); + }} + > + {pathname === item?.route && item?.icon} + + {item?.text} + + + ))} + + + + + + ); +}; diff --git a/src/layouts/menu/Menu.js b/src/layouts/menu/Menu.js new file mode 100644 index 0000000..4930fd1 --- /dev/null +++ b/src/layouts/menu/Menu.js @@ -0,0 +1,413 @@ +import React, { useEffect, useState } from "react"; +import { + Box, + IconButton, + Menu, + Typography, + List, + ListItem, + ListItemText, + Divider, + ListItemIcon, + Chip, + Button, + Autocomplete, + TextField, +} from "@mui/material"; +import WidgetsIcon from "@mui/icons-material/Widgets"; +import useUserProfile from "../../features/authentication/hooks/useUserProfile"; +import { getFaUserRole } from "../../utils/getFaUserRole"; +import { getIconUserRole } from "../../utils/getRoleIcon"; +import { getRoleItems } from "../../utils/getRolesItems"; +import { useLocation, useNavigate } from "react-router-dom"; +import { DRAWER, OPEN_MODAL } from "../../lib/redux/slices/appSlice"; +import { useDispatch } from "react-redux"; +import { motion } from "framer-motion"; +import { sortRoles } from "../../utils/sortRoles"; +import PorvinceGetReportOperations from "../../features/province/components/province-get-report-operations/PorvinceGetReportOperations"; +import SummarizeIcon from "@mui/icons-material/Summarize"; +import PushPinIcon from "@mui/icons-material/PushPin"; +import PushPinOutlinedIcon from "@mui/icons-material/PushPinOutlined"; +import { Grid } from "../../components/grid/Grid"; +import { getLiveStockItems } from "../../utils/getLivestock"; +import { getPoultryRoles } from "../../utils/getUserTypeOfActivity"; + +export const AppMenu = ({ color }) => { + const [anchorEl, setAnchorEl] = useState(null); + const [pinned, setPinned] = useState(false); + const open = Boolean(anchorEl); + const dispatch = useDispatch(); + const navigate = useNavigate(); + const { pathname } = useLocation(); + const [selectedRole, setSelectedRole] = useState(null); + const [hoveredRole, setHoveredRole] = useState(null); + const [role] = useUserProfile(); + + // Active role is either hovered or selected + const activeRole = hoveredRole || selectedRole; + + const autocompleteItems = []; + if (role) { + for (let i = 0; i < role.length; i++) { + const items = getRoleItems(role[i]); + items.forEach((item) => { + autocompleteItems.push({ ...item, role: role[i] }); + }); + + const liveStockItems = getLiveStockItems(role[i]); + liveStockItems.forEach((item) => { + autocompleteItems.push({ ...item, role: role[i] }); + }); + } + } + + useEffect(() => { + if (role?.length === 1) { + setSelectedRole(role[0]); + } else if (role?.length > 1) { + // Auto-select first role for multi-role users + setSelectedRole(sortRoles(role)[0]); + } + }, [role]); + + const handleMenuToggle = (event) => { + setAnchorEl(event.currentTarget); + }; + + const handleMenuClose = () => { + if (!pinned) { + setAnchorEl(null); + } + }; + + const handlePinToggle = () => { + setPinned((prev) => !prev); + }; + + const handleAutocompleteChange = (event, value) => { + if (value?.route) { + navigate(value.route); + setSelectedRole(value.role); + if (!pinned) { + setAnchorEl(null); + } + } + }; + + const renderSearch = ( + + + + {pinned ? : } + + + + ({ + label: item.text, + route: item.route, + role: item.role, + disabled: item.disabled || false, + index, + }))} + groupBy={(option) => + role?.length !== 1 ? getFaUserRole(option.role) : false + } + getOptionDisabled={(option) => option.disabled} + getOptionLabel={(option) => option.label || ""} + onChange={handleAutocompleteChange} + renderInput={(params) => ( + + )} + renderOption={(props, option) => ( + + {option.label} + + )} + /> + + + ); + + return ( + + + + {renderSearch} + + + {/* Two Column Layout */} + + {/* Left Column - Roles List (only show if multiple roles) */} + {role?.length > 1 && ( + <> + + + {sortRoles(role).map((item, index) => ( + setSelectedRole(item)} + onMouseEnter={() => setHoveredRole(item)} + sx={{ + p: 1.5, + borderBottom: "1px solid", + borderColor: "divider", + bgcolor: + selectedRole === item + ? "primary.light" + : hoveredRole === item + ? "action.hover" + : "transparent", + transition: "all 0.2s", + }} + > + + {getIconUserRole(item)} + + + + ))} + + + + )} + + {/* Right Column - Menu Items */} + + {activeRole && ( + <> + {role?.length === 1 && ( + + + + )} + + + + {(() => { + const menuItems = getPoultryRoles([activeRole]).length + ? getRoleItems(activeRole) + : getLiveStockItems(activeRole); + + if (!menuItems || menuItems.length === 0) { + return ( + + + آیتم منویی برای نمایش وجود ندارد + + + ); + } + + return menuItems.map((item, index) => ( + { + setSelectedRole(activeRole); + handleMenuClose(); + dispatch( + DRAWER({ + right: false, + bottom: false, + content: null, + }) + ); + navigate(item?.route); + }} + sx={{ + p: 1, + borderRadius: 1, + mb: 0.5, + "&:hover": { + bgcolor: "action.hover", + }, + }} + > + + {item?.icon} + + + + )); + })()} + + {(activeRole === "ProvinceOperator" || + activeRole === "SuperAdmin" || + activeRole === "Commerce" || + activeRole === "ProvinceSupervisor" || + activeRole === "AdminX") && ( + { + setSelectedRole(activeRole); + handleMenuClose(); + dispatch( + DRAWER({ + right: false, + bottom: false, + content: null, + }) + ); + dispatch( + OPEN_MODAL({ + title: "اطلاعات گزارش", + content: , + }) + ); + }} + sx={{ + p: 1, + borderRadius: 1, + mb: 0.5, + "&:hover": { + bgcolor: "action.hover", + }, + }} + > + + + + + + )} + + + + )} + + + + + ); +}; diff --git a/src/layouts/sidebar/SidebarMenuItem.js b/src/layouts/sidebar/SidebarMenuItem.js new file mode 100644 index 0000000..16f6df8 --- /dev/null +++ b/src/layouts/sidebar/SidebarMenuItem.js @@ -0,0 +1,59 @@ +import { ListItemButton, ListItemIcon, ListItemText } from "@mui/material"; +import EggIcon from "@mui/icons-material/Egg"; +import { useState } from "react"; +import { Grid } from "../../components/grid/Grid"; +import KeyboardArrowDownIcon from "@mui/icons-material/KeyboardArrowDown"; +import KeyboardArrowLeftIcon from "@mui/icons-material/KeyboardArrowLeft"; +import { SPACING } from "../../data/spacing"; + +export const SidebarMenuItem = () => { + const [isOpen, setIsOpen] = useState(false); + + // useEffect(() => { + // if (!sidebarState) { + // setIsOpen(false); + // } + // }, [sidebarState]); + + return ( + <> + { + // dispatch(DRAWER({ right: false, bottom: false, content: null })); + // navigate(ROUTE_PROVINCE_HATCHING); + // closeSidebar(); + setIsOpen(!isOpen); + }} + > + + + + {isOpen ? : } + + + {isOpen && ( + + { + // dispatch(DRAWER({ right: false, bottom: false, content: null })); + // navigate(ROUTE_PROVINCE_HATCHING); + // closeSidebar(); + setIsOpen(true); + }} + > + + + + + )} + + ); +}; diff --git a/src/layouts/sidebar/components/CollapsibleMenuSection.js b/src/layouts/sidebar/components/CollapsibleMenuSection.js new file mode 100644 index 0000000..61536e2 --- /dev/null +++ b/src/layouts/sidebar/components/CollapsibleMenuSection.js @@ -0,0 +1,70 @@ +import React from "react"; +import { + ListItemButton, + ListItemIcon, + ListItemText, + Collapse, + List, + Tooltip, +} from "@mui/material"; +import ExpandLess from "@mui/icons-material/ExpandLess"; +import ExpandMore from "@mui/icons-material/ExpandMore"; +import { MenuItem } from "./MenuItem"; + +export const CollapsibleMenuSection = React.memo( + ({ + icon, + text, + tooltip, + open, + isExpanded, + onToggle, + items = [], + onItemClick, + onClose, + }) => { + const header = ( + + {icon} + + {isExpanded ? : } + + ); + + return ( + <> + {tooltip && !open ? ( + + {header} + + ) : ( + header + )} + + + {items.map((item, index) => ( + + ))} + + + + ); + } +); + +CollapsibleMenuSection.displayName = "CollapsibleMenuSection"; diff --git a/src/layouts/sidebar/components/LogoutButton.js b/src/layouts/sidebar/components/LogoutButton.js new file mode 100644 index 0000000..f0414e6 --- /dev/null +++ b/src/layouts/sidebar/components/LogoutButton.js @@ -0,0 +1,78 @@ +import React from "react"; +import { + ListItemButton, + ListItemIcon, + ListItemText, + Tooltip, + Button, + Grid, +} from "@mui/material"; +import LogoutIcon from "@mui/icons-material/Logout"; +import { useDispatch } from "react-redux"; +import { LOG_OUT } from "../../../lib/redux/slices/userSlice"; +import { + BACKDROP_HIDE, + CLOSE_MODAL, + DRAWER, + OPEN_MODAL, +} from "../../../lib/redux/slices/appSlice"; +import { SPACING } from "../../../data/spacing"; + +export const LogoutButton = React.memo(({ open, onClose }) => { + const dispatch = useDispatch(); + + const handleLogout = () => { + onClose(); + dispatch(DRAWER({ right: false, bottom: false, content: null })); + dispatch( + OPEN_MODAL({ + title: "از سامانه خارج میشوید؟", + content: ( + + + + + ), + }) + ); + }; + + const content = ( + + + + + + + ); + + if (!open) { + return ( + + {content} + + ); + } + + return content; +}); + +LogoutButton.displayName = "LogoutButton"; diff --git a/src/layouts/sidebar/components/MenuItem.js b/src/layouts/sidebar/components/MenuItem.js new file mode 100644 index 0000000..15fa74d --- /dev/null +++ b/src/layouts/sidebar/components/MenuItem.js @@ -0,0 +1,67 @@ +import React from "react"; +import { + ListItemButton, + ListItemIcon, + ListItemText, + Tooltip, +} from "@mui/material"; +import { useLocation, useNavigate } from "react-router-dom"; +import { useDispatch } from "react-redux"; +import { DRAWER } from "../../../lib/redux/slices/appSlice"; + +export const MenuItem = React.memo( + ({ + icon, + text, + route, + tooltip, + open, + disabled = false, + onClick, + onClose, + }) => { + const navigate = useNavigate(); + const { pathname } = useLocation(); + const dispatch = useDispatch(); + const isSelected = pathname.includes(route); + + const handleClick = () => { + if (disabled) return; + + dispatch(DRAWER({ right: false, bottom: false, content: null })); + + if (onClick) { + onClick(); + } else if (route) { + navigate(route); + } + + if (onClose) { + onClose(); + } + }; + + const content = ( + + {icon || null} + + + ); + + if (tooltip && !open) { + return ( + + {content} + + ); + } + + return content; + } +); + +MenuItem.displayName = "MenuItem"; diff --git a/src/layouts/sidebar/components/RoleAccordion.js b/src/layouts/sidebar/components/RoleAccordion.js new file mode 100644 index 0000000..24e596b --- /dev/null +++ b/src/layouts/sidebar/components/RoleAccordion.js @@ -0,0 +1,103 @@ +import React from "react"; +import { Accordion, AccordionSummary, Typography, Grid } from "@mui/material"; +import ExpandMoreIcon from "@mui/icons-material/ExpandMore"; +import { motion } from "framer-motion"; +import { getFaUserRole } from "../../../utils/getFaUserRole"; +import { getIconUserRole } from "../../../utils/getRoleIcon"; + +export const RoleAccordion = React.memo( + ({ role, open, isExpanded, onToggle, children }) => { + return ( + + + } + style={{ + backgroundColor: isExpanded ? "#0fb9b1" : "#dfe6e9", + boxShadow: isExpanded ? "inset 0 0 2px rgba(0,0,0,0.75)" : "none", + }} + > + {open ? ( + + + + + {getIconUserRole(role)} + + + + + {getFaUserRole(role)} + + + + + ) : ( + + {getIconUserRole(role)} + + )} + + + {children} + + + ); + } +); + +RoleAccordion.displayName = "RoleAccordion"; diff --git a/src/layouts/sidebar/components/RoleMenuRenderer.js b/src/layouts/sidebar/components/RoleMenuRenderer.js new file mode 100644 index 0000000..77634bf --- /dev/null +++ b/src/layouts/sidebar/components/RoleMenuRenderer.js @@ -0,0 +1,64 @@ +import React from "react"; +import { CollapsibleMenuSection } from "./CollapsibleMenuSection"; +import { MenuItem } from "./MenuItem"; +import { useDispatch } from "react-redux"; +import { OPEN_MODAL } from "../../../lib/redux/slices/appSlice"; + +export const RoleMenuRenderer = React.memo( + ({ menuConfig, open, openSub, onToggleSub, onClose }) => { + const dispatch = useDispatch(); + + const handleModalItem = (item) => { + if (item.isModal && item.modalContent) { + const ModalContent = item.modalContent; + dispatch( + OPEN_MODAL({ + title: item.modalTitle || "اطلاعات", + content: React.isValidElement(ModalContent) ? ( + ModalContent + ) : ( + + ), + }) + ); + } + }; + + return ( + <> + {menuConfig.collapsibleSections?.map((section) => ( + onToggleSub(section.key)} + items={section.items} + onClose={onClose} + /> + ))} + + {menuConfig.regularItems?.map((item, index) => { + if (item.isModal) { + return ( + handleModalItem(item)} + onClose={onClose} + /> + ); + } + return ( + + ); + })} + + ); + } +); + +RoleMenuRenderer.displayName = "RoleMenuRenderer"; diff --git a/src/layouts/sidebar/components/SidebarHeader.js b/src/layouts/sidebar/components/SidebarHeader.js new file mode 100644 index 0000000..ad19acd --- /dev/null +++ b/src/layouts/sidebar/components/SidebarHeader.js @@ -0,0 +1,137 @@ +import React from "react"; +import { Avatar, IconButton, Tooltip, Typography, Grid } from "@mui/material"; +import AccountBoxIcon from "@mui/icons-material/AccountBox"; +import EmailIcon from "@mui/icons-material/Email"; +import LightbulbIcon from "@mui/icons-material/Lightbulb"; +import PermPhoneMsgIcon from "@mui/icons-material/PermPhoneMsg"; +import { useNavigate } from "react-router-dom"; +import { useDispatch } from "react-redux"; +import { DRAWER } from "../../../lib/redux/slices/appSlice"; +import { + ROUTE_GENERAL_USER_PROFILE, + ROUTE_GENERAL_MESSAGES, + ROUTE_GENERAL_TRAINING, + ROUTE_GENERAL_SUPPORT, +} from "../../../routes/routes"; +import PersianDate from "persian-date"; +import { SPACING } from "../../../data/spacing"; + +const stringAvatar = (name) => { + if (name) { + const nameArr = name + ?.split(" ") + ?.filter((item) => item) + ?.map((item) => item[0]); + return { + sx: { + bgcolor: "#353b48", + }, + children: nameArr[0], + }; + } + return {}; +}; + +export const SidebarHeader = React.memo(({ userProfile, open, onClose }) => { + const navigate = useNavigate(); + const dispatch = useDispatch(); + + const handleNavigation = (route) => { + dispatch(DRAWER({ right: false, bottom: false, content: null })); + navigate(route); + if (onClose) onClose(); + }; + + return ( + <> + + + {userProfile?.image && + userProfile?.image !== "empty" && + userProfile?.fullname ? ( + + ) : ( + + )} + {open && ( + + {userProfile?.fullname} + + موبایل: {userProfile?.mobile} + + + )} + + + + + + handleNavigation(ROUTE_GENERAL_USER_PROFILE)} + > + + + + + handleNavigation(ROUTE_GENERAL_MESSAGES)} + > + + + + + handleNavigation(ROUTE_GENERAL_TRAINING)} + > + + + + + handleNavigation(ROUTE_GENERAL_SUPPORT)} + > + + + + + + {open && ( + + + {new PersianDate().toLocale("fa").format("dddd DD MMMM")} + + + )} + + ); +}); + +SidebarHeader.displayName = "SidebarHeader"; diff --git a/src/layouts/sidebar/constants/menuItemHelpers.js b/src/layouts/sidebar/constants/menuItemHelpers.js new file mode 100644 index 0000000..00706d5 --- /dev/null +++ b/src/layouts/sidebar/constants/menuItemHelpers.js @@ -0,0 +1,140 @@ +import React from "react"; +import { + FeaturedPlayListIcon, + AddShoppingCartIcon, + AssignmentIcon, + LocalOfferIcon, + ShoppingCartIcon, + FlightIcon, + BusinessIcon, + LanIcon, + AssignmentTurnedInIcon, + AutoFixHighIcon, + DraftsIcon, + CompareArrowsIcon, + EggIcon, + AttachMoneyIcon, + PieChart, + NoteAltIcon, + SupportIcon, + SettingsSuggestIcon, + SettingsInputCompositeIcon, + AccountTreeIcon, + LocalShippingIcon, + CorporateFareIcon, + PersonAddAltIcon, + DirectionsCarIcon, + FactoryIcon, + InventoryIcon, + MailOutlineIcon, + CoPresentIcon, + WarehouseIcon, + SummarizeIcon, + EqualizerIcon, + ReportIcon, + PaymentIcon, + TaskAltIcon, + NewReleasesIcon, + ArchiveIcon, + WarningIcon, + FolderOpenIcon, + MeetingRoomIcon, + AttachFileIcon, + AssignmentLateIcon, + PendingActionsIcon, + MonetizationOnIcon, + AccountBalanceWalletIcon, + SwapHorizontalCircleIcon, + ReceiptIcon, + PaidIcon, + FactCheckIcon, + LoopIcon, + CreditScoreIcon, + ToggleOnIcon, + DocumentScanner, + AcUnitIcon, + KitchenIcon, + ReceiptLongIcon, +} from "@mui/icons-material"; +import { + Folder, + AttachMoney, + FileCopy, + Archive, + Warning, + AddBox, +} from "@mui/icons-material"; +import { FaFile } from "react-icons/fa"; + +// Helper to create menu items with consistent structure +export const createMenuItem = (route, icon, text) => ({ + route, + icon: React.createElement(icon), + text, +}); + +// Common icons as components +export const Icons = { + FeaturedPlayList: FeaturedPlayListIcon, + AddShoppingCart: AddShoppingCartIcon, + Assignment: AssignmentIcon, + LocalOffer: LocalOfferIcon, + ShoppingCart: ShoppingCartIcon, + Flight: FlightIcon, + Business: BusinessIcon, + Lan: LanIcon, + AssignmentTurnedIn: AssignmentTurnedInIcon, + AutoFixHigh: AutoFixHighIcon, + Drafts: DraftsIcon, + CompareArrows: CompareArrowsIcon, + Egg: EggIcon, + AttachMoney: AttachMoneyIcon, + PieChart, + NoteAlt: NoteAltIcon, + Support: SupportIcon, + SettingsSuggest: SettingsSuggestIcon, + SettingsInputComposite: SettingsInputCompositeIcon, + AccountTree: AccountTreeIcon, + LocalShipping: LocalShippingIcon, + CorporateFare: CorporateFareIcon, + PersonAddAlt: PersonAddAltIcon, + DirectionsCar: DirectionsCarIcon, + Factory: FactoryIcon, + Inventory: InventoryIcon, + MailOutline: MailOutlineIcon, + CoPresent: CoPresentIcon, + Warehouse: WarehouseIcon, + Summarize: SummarizeIcon, + Equalizer: EqualizerIcon, + Report: ReportIcon, + Payment: PaymentIcon, + TaskAlt: TaskAltIcon, + NewReleases: NewReleasesIcon, + Archive: ArchiveIcon, + Warning: WarningIcon, + FolderOpen: FolderOpenIcon, + MeetingRoom: MeetingRoomIcon, + AttachFile: AttachFileIcon, + AssignmentLate: AssignmentLateIcon, + PendingActions: PendingActionsIcon, + MonetizationOn: MonetizationOnIcon, + AccountBalanceWallet: AccountBalanceWalletIcon, + SwapHorizontalCircle: SwapHorizontalCircleIcon, + Receipt: ReceiptIcon, + Paid: PaidIcon, + FactCheck: FactCheckIcon, + Loop: LoopIcon, + CreditScore: CreditScoreIcon, + ToggleOn: ToggleOnIcon, + DocumentScanner, + AcUnit: AcUnitIcon, + Kitchen: KitchenIcon, + ReceiptLong: ReceiptLongIcon, + Folder, + AttachMoneyIcon: AttachMoney, + FileCopy, + ArchiveIcon: Archive, + WarningIcon: Warning, + AddBox, + FaFile, +}; diff --git a/src/layouts/sidebar/constants/roleMenuConfigs.js b/src/layouts/sidebar/constants/roleMenuConfigs.js new file mode 100644 index 0000000..dc330e6 --- /dev/null +++ b/src/layouts/sidebar/constants/roleMenuConfigs.js @@ -0,0 +1,620 @@ +import React from "react"; +import { Icons, createMenuItem } from "./menuItemHelpers"; +import * as ROUTES from "../../../routes/routes"; +import PorvinceGetReportOperations from "../../../features/province/components/province-get-report-operations/PorvinceGetReportOperations"; + +// Province Menu Items +export const getProvinceMenuItems = () => ({ + collapsibleSections: [ + { + key: "province", + icon: Icons.SettingsSuggest, + text: "پنل مدیریت", + items: [ + createMenuItem( + ROUTES.ROUTE_PROVINCE_CITY_NEW_REQUESTS, + Icons.FeaturedPlayList, + "مدیریت درخواست ها" + ), + createMenuItem( + ROUTES.ROUTE_PROVINCE_STATEMENTـOFـNEED_REQUESTS, + Icons.AddShoppingCart, + "اعلام نیاز خریداران" + ), + createMenuItem( + ROUTES.ROUTE_PROVINCE_ALLOCATION_REQUESTS, + Icons.Assignment, + "تخصیصات" + ), + createMenuItem( + ROUTES.ROUTE_PROVINCE_PAYING_FEES_REQUESTS, + Icons.LocalOffer, + "تعرفه ها" + ), + createMenuItem( + ROUTES.ROUTE_PROVINCEـFREE_BUY, + Icons.ShoppingCart, + "خرید مستقیم" + ), + createMenuItem(ROUTES.ROUTE_PROVINCEـEXPORT, Icons.Flight, "صادرات"), + createMenuItem( + ROUTES.ROUTE_PROVINCE_FREE_SALES_REQUESTS, + Icons.Business, + "فروش به خارج استان" + ), + createMenuItem(ROUTES.ROUTE_PROVINCE_CHAINS, Icons.Lan, "زنجیره ها"), + createMenuItem( + ROUTES.ROUTE_PROVINCE_ALLOCATED_REQUESTS, + Icons.AssignmentTurnedIn, + "مدیریت تخصیصات" + ), + createMenuItem( + ROUTES.ROUTE_PROVINCE_AUTO_ALLOCATION_REQUESTS, + Icons.AutoFixHigh, + "تخصیصات خودکار" + ), + createMenuItem( + ROUTES.ROUTE_PROVINCE_ISSUANCE_OF_LETTER, + Icons.Drafts, + "صدور نامه" + ), + createMenuItem( + ROUTES.ROUTE_PROVINCE_TRANSACTIONS, + Icons.CompareArrows, + "تراکنش ها" + ), + ], + }, + ], + regularItems: [ + { + icon: React.createElement(Icons.Summarize), + text: "گزارش روزانه", + isModal: true, + modalContent: PorvinceGetReportOperations, + modalTitle: "اطلاعات گزارش", + }, + createMenuItem( + ROUTES.ROUTE_PROVINCEـVISOR_STATICS, + Icons.Equalizer, + "تحلیل داده" + ), + createMenuItem(ROUTES.ROUTE_PROVINCE_HATCHING, Icons.Egg, "مدیریت کشتار"), + createMenuItem( + ROUTES.ROUTE_PROVINCEـHATCHINGS, + Icons.SettingsInputComposite, + "مدیریت جوجه ریزی" + ), + createMenuItem( + ROUTES.ROUTE_PROVINCE_PRICING3, + Icons.AttachMoney, + "قیمت روز" + ), + createMenuItem( + ROUTES.ROUTE_PROVINCE_STATICS, + Icons.PieChart, + "آمار و اطلاعات" + ), + createMenuItem(ROUTES.ROUTE_PROVINCE_REPORT, Icons.FaFile, "گزارشات"), + createMenuItem( + ROUTES.ROUTE_PROVINCE_ROUTE_FILES_STATE, + Icons.AccountTree, + "پرونده های کشتار" + ), + createMenuItem( + ROUTES.ROUTE_PROVINCE_ROUTE_ALLOCATIONS, + Icons.LocalShipping, + "مدیریت بارها" + ), + createMenuItem( + ROUTES.ROUTE_PROVINCE_DISPENSERS, + Icons.CoPresent, + "مدیریت توزیع" + ), + createMenuItem( + ROUTES.ROUTE_PROVINCE_ROUTE_MANAGE_GUILDS, + Icons.CorporateFare, + "مدیریت اصناف" + ), + createMenuItem(ROUTES.ROUTE_PROVINCE_CARS, Icons.DirectionsCar, "خودروها"), + createMenuItem(ROUTES.ROUTE_PROVINCE_USERS, Icons.PersonAddAlt, "کاربران"), + createMenuItem( + ROUTES.ROUTE_PROVINCE_GUILD_TRANSACTIONS, + Icons.ReceiptLong, + "مدیریت تراکنش ها" + ), + createMenuItem( + ROUTES.ROUTE_PROVINCE_POULTRIES, + Icons.PersonAddAlt, + "مدیریت فارم ها" + ), + createMenuItem(ROUTES.ROUTE_PROVINCE_SLAUGHTERS, Icons.Factory, "خریداران"), + createMenuItem(ROUTES.ROUTE_PROVINCE_PRODUCTS, Icons.Inventory, "محصولات"), + createMenuItem( + ROUTES.ROUTE_PROVINCEـBROADCAST_MANAGEMENT, + Icons.PersonAddAlt, + "مدیریت پخش" + ), + createMenuItem( + ROUTES.ROUTE_PROVINCE_ASSIGN_VET_FARM, + Icons.PersonAddAlt, + "دامپزشکان" + ), + createMenuItem( + ROUTES.ROUTE_PROVINCE_ROUTE_SMS, + Icons.MailOutline, + "پنل اطلاع رسانی" + ), + createMenuItem(ROUTES.ROUTE_PROVINCE_TICKET, Icons.Support, "تیکت ها"), + ], +}); + +// City Menu Items +export const getCityMenuItems = () => ({ + collapsibleSections: [ + { + key: "city", + icon: Icons.SettingsSuggest, + text: "پنل مدیریت", + items: [ + createMenuItem( + ROUTES.ROUTE_CITY_NEW_REQUESTS, + Icons.NewReleases, + "درخواست های جدید" + ), + createMenuItem( + ROUTES.ROUTE_CITY_ACTIVE_REQUESTS, + Icons.TaskAlt, + "درخواست های فعال" + ), + createMenuItem( + ROUTES.ROUTE_CITY_AWAITING_PAYMENT_REQUESTS, + Icons.Payment, + "در انتظار پرداخت" + ), + createMenuItem( + ROUTES.ROUTE_CITY_AWAITING_INSPECTION_REQUESTS, + Icons.Report, + "در انتظار بازرسی" + ), + createMenuItem( + ROUTES.ROUTE_CITY_REJECTED_REQUESTS, + Icons.Report, + "درخواست های رد شده" + ), + createMenuItem( + ROUTES.ROUTE_CITY_FREE_SALES_REQUESTS, + Icons.FolderOpen, + "فروش خارج از استان" + ), + createMenuItem( + ROUTES.ROUTE_CITY_ARCHIVED_REQUESTS, + Icons.Archive, + "بایگانی" + ), + ], + }, + ], + regularItems: [ + createMenuItem( + ROUTES.ROUTE_CITY_VISOR_STATICS, + Icons.Equalizer, + "تحلیل داده" + ), + createMenuItem(ROUTES.ROUTE_CITY_HATCHING, Icons.Egg, "مدیریت کشتار"), + createMenuItem( + ROUTES.ROUTE_CITY_ROUTE_FILES_STATE, + Icons.AccountTree, + "پرونده های کشتار" + ), + createMenuItem( + ROUTES.ROUTE_CITYـHATCHINGS, + Icons.SettingsInputComposite, + "مدیریت جوجه ریزی" + ), + createMenuItem( + ROUTES.ROUTE_CITY_ROUTE_ALLOCATIONS, + Icons.LocalShipping, + "مدیریت بارها" + ), + createMenuItem(ROUTES.ROUTE_CITY_PRICING, Icons.AttachMoney, "قیمت روز"), + createMenuItem( + ROUTES.ROUTE_CITY_POULTRIES, + Icons.PersonAddAlt, + "مدیریت فارم ها" + ), + createMenuItem( + ROUTES.ROUTE_CITY_POULTRY_FARMS, + Icons.Warehouse, + "مرغداران" + ), + createMenuItem(ROUTES.ROUTE_CITY_STATICS, Icons.PieChart, "آمار و اطلاعات"), + createMenuItem( + ROUTES.ROUTE_CITY_USER_MANAGEMENT, + Icons.PersonAddAlt, + "کاربران" + ), + createMenuItem(ROUTES.ROUTE_CITY_TICKET, Icons.Support, "تیکت ها"), + ], +}); + +// Inspector Menu Items +export const getInspectorMenuItems = () => ({ + collapsibleSections: [ + { + key: "inspector", + icon: Icons.SettingsSuggest, + text: "پنل مدیریت", + items: [ + createMenuItem( + ROUTES.ROUTE_INSPECTOR_REQUESTS_NEW_REQUESTS, + Icons.Folder, + "درخواست های جدید" + ), + createMenuItem( + ROUTES.ROUTE_PROVINCE_INSPECTOR_AWAITING_PAYMENT_REQUESTS, + Icons.AttachMoneyIcon, + "در انتظار پرداخت" + ), + createMenuItem( + ROUTES.ROUTE_PROVINCE_INSPECTOR_AWAITING_INSPECTION_REQUESTS, + Icons.FileCopy, + "در انتظار بازرسی" + ), + createMenuItem( + ROUTES.ROUTE_INSPECTOR_REJECTED_REQUESTS, + Icons.WarningIcon, + "درخواست های رد شده" + ), + createMenuItem( + ROUTES.ROUTE_INSPECTOR_ARCHIVED_REQUESTS, + Icons.ArchiveIcon, + "بایگانی" + ), + ], + }, + ], + regularItems: [ + createMenuItem( + ROUTES.ROUTE_INSPECTOR_STATICS, + Icons.PieChart, + "آمار و اطلاعات" + ), + createMenuItem( + ROUTES.ROUTE_PROVINCE_INSPECTOR_REPORTING, + Icons.NoteAlt, + "گزارشات" + ), + createMenuItem( + ROUTES.ROUTE_PROVINCE_INSPECTOR_TICKET, + Icons.Support, + "تیکت ها" + ), + ], +}); + +// Aviculture Menu Items +export const getAvicultureMenuItems = () => ({ + collapsibleSections: [ + { + key: "avicuture", + icon: Icons.SettingsSuggest, + text: "پنل مدیریت", + items: [ + createMenuItem( + ROUTES.ROUTE_AVICULTURE_HATCHING, + Icons.Egg, + "جوجه ریزی" + ), + createMenuItem( + ROUTES.ROUTE_AVICULTURE_SUBMIT_REQUEST, + Icons.AttachFile, + "درخواست های کشتار" + ), + createMenuItem( + ROUTES.ROUTE_AVICULTURE_AWAITING_PAYMENT_REQUESTS, + Icons.Payment, + "در انتظار پرداخت" + ), + createMenuItem( + ROUTES.ROUTE_AVICULTURE_AWAITING_INSPECTION_REQUESTS, + Icons.AssignmentLate, + "در انتظار بازرسی" + ), + createMenuItem( + ROUTES.ROUTE_AVICULTURE_REJECTED_REQUESTS, + Icons.Warning, + "درخواست های رد شده" + ), + createMenuItem( + ROUTES.ROUTE_AVICULTURE_ARCHIVED_REQUESTS, + Icons.Archive, + "بایگانی" + ), + createMenuItem( + ROUTES.ROUTE_AVICULTURE_GIVE_PERMISSION, + Icons.Archive, + "وکالت" + ), + ], + }, + ], + regularItems: [ + createMenuItem( + ROUTES.ROUTE_AVICULTURE_PRICING, + Icons.AttachMoney, + "قیمت روز" + ), + createMenuItem( + ROUTES.ROUTE_AVICULTURE_ROUTE_HALLS, + Icons.MeetingRoom, + "سالن ها" + ), + createMenuItem(ROUTES.ROUTE_AVICULTURE_TICKET, Icons.Support, "تیکت ها"), + ], +}); + +// Slaughter House Menu Items +export const getSlaughterHouseMenuItems = (slaughterPermissionState) => ({ + collapsibleSections: [ + { + key: "slaughter", + icon: Icons.SettingsSuggest, + text: "پنل مدیریت", + items: [ + createMenuItem( + ROUTES.ROUTE_SLAUGHTER_NEW_REQUESTS, + Icons.FeaturedPlayList, + "ثبت درخواست" + ), + createMenuItem( + ROUTES.ROUTE_SLAUGHTERـFREE_BUY, + Icons.ShoppingCart, + "خرید مستقیم" + ), + createMenuItem(ROUTES.ROUTE_SLAUGHTERـEXPORT, Icons.Flight, "صادرات"), + createMenuItem( + ROUTES.ROUTE_SLAUGHTER_PENDING_REQUESTS, + Icons.PendingActions, + "سفارش های دریافت شده" + ), + createMenuItem( + ROUTES.ROUTE_SLAUGHTER_ALLOCATION_REQUESTS, + Icons.AssignmentTurnedIn, + "تخصیصات" + ), + createMenuItem( + ROUTES.ROUTE_SLAUGHTER_ALLOCATE_CAR_REQUESTS, + Icons.LocalShipping, + "تخصیص خودرو" + ), + createMenuItem( + ROUTES.ROUTE_SLAUGHTER_ENTER_BAR_INFO, + Icons.LocalShipping, + "وارد کردن اطلاعات بار" + ), + createMenuItem( + ROUTES.ROUTE_SLAUGHTER_PAYING_FEES_REQUESTS, + Icons.MonetizationOn, + "مدیریت تعرفه ها" + ), + createMenuItem( + ROUTES.ROUTE_SLAUGHTER_WALLET, + Icons.AccountBalanceWallet, + "کیف پول" + ), + createMenuItem( + ROUTES.ROUTE_SLAUGHTER_FINANCIAL_TRANSACTIONS, + Icons.SwapHorizontalCircle, + "مدیریت تراکنش ها" + ), + createMenuItem( + ROUTES.ROUTE_SLAUGHTER_PAY_FACTORS_REQUESTS, + Icons.Receipt, + "مدیریت فاکتورها" + ), + ], + }, + ], + regularItems: [ + { + ...createMenuItem( + ROUTES.ROUTE_SLAUGHTER_ROUTE_MANAGE_BARS, + Icons.CorporateFare, + "مدیریت بارها" + ), + disabled: !slaughterPermissionState, + }, + { + ...createMenuItem( + ROUTES.ROUTE_SLAUGHTER_ROUTE_MANAGE_GUILDS, + Icons.CorporateFare, + "مدیریت اصناف" + ), + disabled: !slaughterPermissionState, + }, + { + ...createMenuItem( + ROUTES.ROUTE_SLAUGHTER_PRICING, + Icons.AttachMoney, + "قیمت روز" + ), + disabled: !slaughterPermissionState, + }, + { + ...createMenuItem( + ROUTES.ROUTE_SLAUGHTER_CAR_MANAGEMENT, + Icons.DirectionsCar, + "خودروها" + ), + disabled: !slaughterPermissionState, + }, + { + ...createMenuItem( + ROUTES.ROUTE_SLAUGHTER_DISPENSERS, + Icons.CoPresent, + "مدیریت توزیع" + ), + disabled: true, + }, + { + ...createMenuItem( + ROUTES.ROUTE_SLAUGHTER_INVENTORY, + Icons.Warehouse, + "انبار و توزیع" + ), + disabled: !slaughterPermissionState, + }, + { + ...createMenuItem(ROUTES.ROUTE_SLAUGHTER_MORGUE, Icons.AcUnit, "سردخانه"), + disabled: !slaughterPermissionState, + }, + ], +}); + +// Province Financial Menu Items +export const getProvinceFinancialMenuItems = () => ({ + collapsibleSections: [ + { + key: "provinceFinancial", + icon: Icons.SettingsSuggest, + text: "پنل مدیریت", + items: [ + createMenuItem( + ROUTES.ROUTE_PROVINCE_FINANCIAL_PENDING_REQUESTS, + Icons.PendingActions, + "صدور فاکتور" + ), + createMenuItem( + ROUTES.ROUTE_PROVINCE_FINANCIAL_AWAITING_PAYMENT_REQUESTS, + Icons.AttachMoney, + "در انتظار پرداخت" + ), + createMenuItem( + ROUTES.ROUTE_PROVINCE_FINANCIAL_CHECK_PAYED_FACTOR_REQUESTS, + Icons.Paid, + "فاکتورهای پرداخت شده" + ), + createMenuItem( + ROUTES.ROUTE_PROVINCE_FINANCIAL_TRANSACTIONS, + Icons.Loop, + "تراکنش ها" + ), + createMenuItem( + ROUTES.ROUTE_PROVINCE_FINANCIAL_FINAL_FACTORS_REQUESTS, + Icons.FactCheck, + "اسناد مالی" + ), + createMenuItem( + ROUTES.ROUTE_PROVINCE_FINANCIAL_ACTIVE_REQUESTS, + Icons.FolderOpen, + "درخواست های فعال" + ), + createMenuItem( + ROUTES.ROUTE_PROVINCE_FINANCIAL_AWAITING_INSPECTION_REQUESTS, + Icons.PendingActions, + "در انتظار بازرسی" + ), + createMenuItem( + ROUTES.ROUTE_PROVINCE_FINANCIAL_ARCHIVED_REQUESTS, + Icons.Archive, + "بایگانی" + ), + ], + }, + ], + regularItems: [ + createMenuItem( + ROUTES.ROUTE_PROVINCE_FINANCIAL_SETTLEMENT, + Icons.CreditScore, + "تسویه حساب" + ), + createMenuItem( + ROUTES.ROUTE_PROVINCE_PRICING, + Icons.AttachMoney, + "قیمت گذاری" + ), + createMenuItem( + ROUTES.ROUTE_PROVINCE_FINANCIAL_STATICS, + Icons.PieChart, + "آمار و اطلاعات" + ), + createMenuItem( + ROUTES.ROUTE_PROVINCE_FINANCIAL_TICKET, + Icons.Support, + "تیکت ها" + ), + createMenuItem( + ROUTES.ROUTE_PROVINCE_FINANCIAL_DOCUMENT_REGISTRATION, + Icons.AttachMoney, + "ثبت سند مالی" + ), + ], +}); + +// Vet Farm Menu Items +export const getVetFarmMenuItems = () => ({ + regularItems: [ + createMenuItem( + ROUTES.ROUTE_VETFARM_ROUTE_ALLOCATIONS, + Icons.SettingsSuggest, + "کدرهگیری قرنطینه" + ), + createMenuItem( + ROUTES.ROUTE_VETFARM_REGISTER_INFO, + Icons.Vaccines, + "مدیریت فارم" + ), + ], +}); + +// Driver Menu Items +export const getDriverMenuItems = () => ({ + regularItems: [ + createMenuItem( + ROUTES.ROUTE_DRIVER_REQUESTS, + Icons.SettingsSuggest, + "پنل مدیریت" + ), + ], +}); + +// Dispenser Menu Items +export const getDispenserMenuItems = () => ({ + regularItems: [ + createMenuItem( + ROUTES.ROUTE_DISPENSER_DASHBOARD, + Icons.SettingsSuggest, + "پنل مدیریت" + ), + ], +}); + +// Factory function to get menu items by role +export const getMenuItemsByRole = (role, additionalProps = {}) => { + switch (role) { + case "ProvinceOperator": + return getProvinceMenuItems(); + case "CityOperator": + return getCityMenuItems(); + case "ProvinceInspector": + case "Admin": + return getInspectorMenuItems(); + case "Poultry": + return getAvicultureMenuItems(); + case "KillHouse": + return getSlaughterHouseMenuItems( + additionalProps.slaughterPermissionState + ); + case "ProvinceFinancial": + return getProvinceFinancialMenuItems(); + case "VetFarm": + return getVetFarmMenuItems(); + case "Driver": + return getDriverMenuItems(); + case "Dispenser": + return getDispenserMenuItems(); + default: + return { collapsibleSections: [], regularItems: [] }; + } +}; diff --git a/src/layouts/sidebar/hooks/useResponsiveSidebar.js b/src/layouts/sidebar/hooks/useResponsiveSidebar.js new file mode 100644 index 0000000..f07c6c8 --- /dev/null +++ b/src/layouts/sidebar/hooks/useResponsiveSidebar.js @@ -0,0 +1,22 @@ +import { useState, useEffect } from "react"; + +export const useResponsiveSidebar = () => { + const [width, setWidth] = useState( + typeof window !== "undefined" ? window.innerWidth : 768 + ); + + useEffect(() => { + const handleWindowSizeChange = () => { + setWidth(window.innerWidth); + }; + + window.addEventListener("resize", handleWindowSizeChange); + return () => { + window.removeEventListener("resize", handleWindowSizeChange); + }; + }, []); + + const isMobile = width <= 768; + + return { isMobile, width }; +}; diff --git a/src/layouts/sidebar/hooks/useSidebarState.js b/src/layouts/sidebar/hooks/useSidebarState.js new file mode 100644 index 0000000..43373df --- /dev/null +++ b/src/layouts/sidebar/hooks/useSidebarState.js @@ -0,0 +1,86 @@ +import { useState, useEffect, useContext } from "react"; +import { useDispatch } from "react-redux"; +import { SidebarContext } from "../../../contexts/SidebarContext"; +import { + BACKDROP_HIDE, + BACKDROP_SHOW, +} from "../../../lib/redux/slices/appSlice"; + +export const useSidebarState = () => { + const [open, setOpen] = useState(false); + const [expandedItems, setExpandedItems] = useState([]); + const [openSub, setOpenSub] = useState({ + province: false, + adminx: false, + slaughter: false, + avicuture: false, + city: false, + provinceFinancial: false, + inspector: false, + slaughterVet: false, + superAdmin: false, + }); + const [sidebarMobileState, setSidebarMobileState] = + useContext(SidebarContext); + const dispatch = useDispatch(); + + const closeSidebar = () => { + setSidebarMobileState(false); + setOpen(false); + }; + + const handleAccordionChange = (index) => { + setExpandedItems((prev) => { + const newExpandedItems = [...prev]; + const currentIndex = newExpandedItems.indexOf(index); + if (currentIndex === -1) { + newExpandedItems.push(index); + } else { + newExpandedItems.splice(currentIndex, 1); + } + return newExpandedItems; + }); + }; + + const toggleSubMenu = (key) => { + setOpenSub((prev) => ({ + ...prev, + [key]: !prev[key], + })); + }; + + useEffect(() => { + setOpen(sidebarMobileState); + }, [sidebarMobileState]); + + useEffect(() => { + if (open) { + dispatch(BACKDROP_SHOW()); + } else { + dispatch(BACKDROP_HIDE()); + } + }, [open, dispatch]); + + useEffect(() => { + const handleDocumentClick = (e) => { + if (open && !e.target.closest("#sidebar")) { + closeSidebar(); + } + }; + + document.addEventListener("click", handleDocumentClick); + return () => { + document.removeEventListener("click", handleDocumentClick); + }; + }, [open]); + + return { + open, + setOpen, + expandedItems, + openSub, + closeSidebar, + handleAccordionChange, + toggleSubMenu, + }; +}; diff --git a/src/layouts/sidebar/sidebar.js b/src/layouts/sidebar/sidebar.js new file mode 100644 index 0000000..4211b3d --- /dev/null +++ b/src/layouts/sidebar/sidebar.js @@ -0,0 +1,154 @@ +import * as React from "react"; +import { styled } from "@mui/material/styles"; +import MuiDrawer from "@mui/material/Drawer"; +import List from "@mui/material/List"; +import { useDispatch, useSelector } from "react-redux"; +import { getUserProfile } from "../../features/authentication/services/getUserProfile"; +import { useUserProfile } from "../../features/authentication/hooks/useUserProfile"; +import { SidebarHeader } from "./components/SidebarHeader"; +import { LogoutButton } from "./components/LogoutButton"; +import { RoleAccordion } from "./components/RoleAccordion"; +import { RoleMenuRenderer } from "./components/RoleMenuRenderer"; +import { useSidebarState } from "./hooks/useSidebarState"; +import { useResponsiveSidebar } from "./hooks/useResponsiveSidebar"; +import { getMenuItemsByRole } from "./constants/roleMenuConfigs"; + +const drawerWidth = 280; + +const openedMixin = (theme) => ({ + width: drawerWidth, + transition: theme.transitions.create("width", { + easing: theme.transitions.easing.sharp, + duration: theme.transitions.duration.enteringScreen, + }), + overflowX: "hidden", +}); + +const closedMixin = (theme) => ({ + transition: theme.transitions.create("width", { + easing: theme.transitions.easing.sharp, + duration: theme.transitions.duration.leavingScreen, + }), + overflowX: "hidden", + width: `calc(${theme.spacing(7)} + 1px)`, + [theme.breakpoints.up("sm")]: { + width: `calc(${theme.spacing(8)} + 1px)`, + }, +}); + +const Drawer = styled(MuiDrawer, { + shouldForwardProp: (prop) => prop !== "open", +})(({ theme, open }) => ({ + width: drawerWidth, + flexShrink: 0, + whiteSpace: "nowrap", + boxSizing: "border-box", + position: "absolute", + ...(open && { + ...openedMixin(theme), + "& .MuiDrawer-paper": openedMixin(theme), + }), + ...(!open && { + ...closedMixin(theme), + "& .MuiDrawer-paper": closedMixin(theme), + }), +})); + +export const Sidebar = () => { + const dispatch = useDispatch(); + const [role, userProfile] = useUserProfile(); + const roles = [...role]; + const { slaughterPermissionState } = useSelector( + (item) => item.slaughterSlice + ); + + const { + open, + setOpen, + expandedItems, + openSub, + closeSidebar, + handleAccordionChange, + toggleSubMenu, + } = useSidebarState(); + + const { isMobile } = useResponsiveSidebar(); + + React.useEffect(() => { + if (Array.isArray(role)) { + roles.sort(); + } + dispatch(getUserProfile()); + }, [dispatch, role, roles]); + + return ( + { + if (!isMobile) { + setOpen(true); + } + }} + onMouseLeave={() => { + if (!isMobile) { + setOpen(false); + } + }} + variant="permanent" + open={open} + sx={{ + display: { + xs: open ? "block" : "none", + sm: open ? "block" : "none", + md: "block", + }, + zIndex: (theme) => theme.zIndex.drawer + 11, + }} + > + + + + {roles.map((userRole, i) => { + const menuConfig = getMenuItemsByRole(userRole, { + slaughterPermissionState, + }); + const isExpanded = expandedItems.includes(i); + + // Skip rendering if no menu items + if ( + (!menuConfig.collapsibleSections || + menuConfig.collapsibleSections.length === 0) && + (!menuConfig.regularItems || menuConfig.regularItems.length === 0) + ) { + return null; + } + + return ( + handleAccordionChange(i)} + > + + + ); + })} + + + + + ); +}; diff --git a/src/layouts/site-map/SiteMap.js b/src/layouts/site-map/SiteMap.js new file mode 100644 index 0000000..5786c21 --- /dev/null +++ b/src/layouts/site-map/SiteMap.js @@ -0,0 +1,399 @@ +import React, { useState, useEffect } from "react"; +import { Grid } from "../../components/grid/Grid"; +import { + Typography, + Select, + MenuItem, + FormControl, + Box, + IconButton, + Button, + InputLabel, + CircularProgress, +} from "@mui/material"; +import EditIcon from "@mui/icons-material/Edit"; +import { getFaUserRole } from "../../utils/getFaUserRole"; +import { getRoleFromUrl } from "../../utils/getRoleFromUrl"; +import { getRoleItems } from "../../utils/getRolesItems"; +import { useLocation, useNavigate } from "react-router-dom"; +import { useSelector, useDispatch } from "react-redux"; +import { getLiveStockItems } from "../../utils/getLivestock"; +import arrow from "../../assets/images/arrow.png"; +import { SET_SELECTED_SUB_USER } from "../../lib/redux/slices/userSlice"; +import { OPEN_MODAL, CLOSE_MODAL } from "../../lib/redux/slices/appSlice"; +import { getUserRoleInfo } from "../../features/authentication/services/getUserRoleInfo"; + +// Edit Modal Content Component +const EditModalContent = ({ + initialRole, + initialSubUser, + subUsers: initialSubUsers, + onSubmit, + onCancel, + userKey, +}) => { + const dispatch = useDispatch(); + const [selectedSubUserInModal, setSelectedSubUserInModal] = + useState(initialSubUser); + const [subUsers, setSubUsers] = useState(initialSubUsers || []); + const [loadingSubUsers, setLoadingSubUsers] = useState(false); + + const rolesNeedingSubUsers = [ + "Steward", + "ColdHouseSteward", + "KillHouse", + "Guilds", + ]; + + const getRoleLabel = (role) => { + switch (role) { + case "KillHouse": + return "نام کشتارگاه"; + case "ColdHouseSteward": + case "Steward": + return "نام مباشر"; + case "Guilds": + return "نام صنف"; + default: + return "انتخاب واحد"; + } + }; + + const fetchSubUsers = React.useCallback( + (role) => { + if (role && rolesNeedingSubUsers.includes(role) && userKey) { + setLoadingSubUsers(true); + dispatch(getUserRoleInfo({ userKey, role })) + .unwrap() + .then((result) => { + if (result?.data && Array.isArray(result.data)) { + setSubUsers(result.data); + } else { + setSubUsers([]); + } + setLoadingSubUsers(false); + }) + .catch((error) => { + console.error("Error fetching subUsers:", error); + setSubUsers([]); + setLoadingSubUsers(false); + }); + } else { + setSubUsers([]); + setLoadingSubUsers(false); + } + }, + [userKey, dispatch, rolesNeedingSubUsers] + ); + + useEffect(() => { + if (initialRole) { + if (initialSubUsers && initialSubUsers.length > 0) { + return; + } + fetchSubUsers(initialRole); + } + }, [initialRole]); + + return ( + + {rolesNeedingSubUsers.includes(initialRole) && ( + + + + {getRoleLabel(initialRole)} + + {loadingSubUsers ? ( + + + + ) : ( + + )} + + + )} + + + + + + + + + + ); +}; + +export const SiteMap = () => { + const { pathname } = useLocation(); + const navigate = useNavigate(); + const dispatch = useDispatch(); + + const { subMenuText, mediatorText } = useSelector((state) => state.userSlice); + const selectedSubUser = useSelector( + (state) => state.userSlice.selectedSubUser + ); + const subUsers = useSelector((state) => state.userSlice.subUsers); + const userProfile = useSelector((state) => state.userSlice.userProfile); + const loginUserProfile = useSelector( + (state) => state.userSlice.loginUserProfile + ); + const userKey = userProfile?.key || loginUserProfile?.key; + + // Check if current route is slaughter, senf, or steward + const isAllowedRoute = + pathname.startsWith("/slaughter") || + pathname.startsWith("/senf") || + pathname.startsWith("/steward"); + + const showSecondPath = + !getRoleItems(getRoleFromUrl())?.find( + (element) => element.route === pathname + ) && + !getLiveStockItems(getRoleFromUrl())?.find( + (element) => element.route === pathname + ); + + const pathFound = + getRoleItems(getRoleFromUrl())?.find( + (element) => element.route === mediatorText + )?.text || + getLiveStockItems(getRoleFromUrl())?.find( + (element) => element.route === mediatorText + )?.text; + + const getRoleLabel = (role) => { + switch (role) { + case "KillHouse": + return "کشتارگاه"; + case "Steward": + return "مباشر"; + case "Guilds": + return "صنف"; + default: + return "کشتارگاه"; // Default fallback + } + }; + + const currentRole = getRoleFromUrl(); + const roleLabel = getRoleLabel(currentRole); + const subUserName = selectedSubUser?.unit; + + const handleOpenEditModal = () => { + const initialRole = getRoleFromUrl() || ""; + const initialSubUser = selectedSubUser?.key || ""; + + dispatch( + OPEN_MODAL({ + title: "تغییر واحد", + content: ( + dispatch(CLOSE_MODAL())} + userKey={userKey} + /> + ), + size: 400, + }) + ); + }; + + const handleSubmit = (selectedSubUserInModal) => { + dispatch(CLOSE_MODAL()); + dispatch( + OPEN_MODAL({ + title: "تأیید تغییرات", + content: ( + + + + آیا از تغییر واحد مطمئن هستید؟ + + + + + + + + + + + + ), + size: 300, + }) + ); + }; + + const handleConfirmSubmit = (selectedSubUserInModal) => { + if (selectedSubUserInModal) { + const subUser = subUsers.find((u) => u.key === selectedSubUserInModal); + if (subUser) { + dispatch(SET_SELECTED_SUB_USER(subUser)); + } + } + dispatch(CLOSE_MODAL()); + }; + + return ( + + + + navigate("/")} + sx={{ cursor: "pointer" }} + > + {getFaUserRole(getRoleFromUrl())} + + arrow + + {showSecondPath && pathFound && ( + <> + navigate(-1)} + style={{ cursor: "pointer" }} + > + {pathFound} + + + arrow + + )} + + + {!/\d/.test(pathname) + ? getRoleItems(getRoleFromUrl())?.find( + (element) => element.route === pathname + )?.text || + getLiveStockItems(getRoleFromUrl())?.find( + (element) => element.route === pathname + )?.text || + subMenuText + : "نمایش"} + + + + {isAllowedRoute && subUsers && subUsers.length > 1 && ( + + + نام {roleLabel} :{" "} + + {subUserName} + + + + + + + )} + + + ); +}; diff --git a/src/lib/axios/axios.js b/src/lib/axios/axios.js new file mode 100644 index 0000000..f4d0749 --- /dev/null +++ b/src/lib/axios/axios.js @@ -0,0 +1,53 @@ +import { showSnackbar } from "../../utils/showSnackbar"; +import { LOADING_END } from "../redux/slices/appSlice"; +import { LOG_OUT } from "../redux/slices/userSlice"; +import { store } from "../redux/store"; +import camelize from "camelize"; + +export function SetupAxios(axios) { + const updateBaseUrl = () => { + const userPath = store.getState().userSlice.userPath; + axios.defaults.baseURL = userPath; + }; + + updateBaseUrl(); + + const unsubscribe = store.subscribe(() => { + const currentUserPath = store.getState().userSlice.userPath; + if (currentUserPath !== axios.defaults.baseURL) { + updateBaseUrl(); + } + }); + + axios.interceptors.request.use( + (config) => { + const { + userSlice: { authToken }, + } = store.getState(); + if (authToken) { + config.headers.Authorization = `Bearer ${authToken}`; + config.headers.Accept = "application/json"; + } else { + config.headers.Authorization = "Bearer null"; + } + return config; + }, + (err) => Promise.reject(err) + ); + + axios.interceptors.response.use( + (response) => camelize(response), + (error) => { + if (error.response && error.response.status === 401) { + showSnackbar("مدت زمان فعالیت شما به اتمام رسیده است.", "error"); + store.dispatch(LOADING_END()); + setTimeout(() => { + store.dispatch(LOG_OUT()); + }, 3000); + } + return Promise.reject(error); + } + ); + + return unsubscribe; +} diff --git a/src/lib/redux/slices/adminExtraReducers.js b/src/lib/redux/slices/adminExtraReducers.js new file mode 100644 index 0000000..26d4a13 --- /dev/null +++ b/src/lib/redux/slices/adminExtraReducers.js @@ -0,0 +1,19 @@ +import { adminGetCharts } from "../../../features/admin/services/admin-get-charts"; +import { adminGetHatchingByPeriod } from "../../../features/admin/services/admin-get-hatching-by-period"; + +export const adminExtraReducers = { + [adminGetCharts.fulfilled]: (state, { payload }) => { + state.statics = payload.data; + state.pending = false; + }, + [adminGetCharts.pending]: (state) => { + state.pending = true; + }, + [adminGetHatchingByPeriod.fulfilled]: (state, { payload }) => { + state.hatchingByPeriod = payload.data; + state.pending = false; + }, + [adminGetHatchingByPeriod.pending]: (state) => { + state.pending = true; + }, +}; diff --git a/src/lib/redux/slices/adminReducers.js b/src/lib/redux/slices/adminReducers.js new file mode 100644 index 0000000..1d70850 --- /dev/null +++ b/src/lib/redux/slices/adminReducers.js @@ -0,0 +1,5 @@ +export const adminReducers = { + EMPTY_HATCHING: (state, action) => { + state.hatchingByPeriod = []; + }, +}; diff --git a/src/lib/redux/slices/adminSlice.js b/src/lib/redux/slices/adminSlice.js new file mode 100644 index 0000000..9535014 --- /dev/null +++ b/src/lib/redux/slices/adminSlice.js @@ -0,0 +1,20 @@ +import { createSlice } from "@reduxjs/toolkit"; +import { adminExtraReducers } from "./adminExtraReducers"; +import { adminReducers } from "./adminReducers"; + +const initialState = { + pending: false, + statics: null, + hatchingByPeriod: null, +}; + +const slice = createSlice({ + name: "admin", + initialState, + reducers: adminReducers, + extraReducers: adminExtraReducers, +}); + +export const { reducer: adminSlice } = slice; + +export const { EMPTY_HATCHING } = slice.actions; diff --git a/src/lib/redux/slices/appReducers.js b/src/lib/redux/slices/appReducers.js new file mode 100644 index 0000000..75f9e04 --- /dev/null +++ b/src/lib/redux/slices/appReducers.js @@ -0,0 +1,36 @@ +export const appReducers = { + LOADING_START: (state, action) => { + state.loading = true; + }, + LOADING_END: (state, action) => { + state.loading = false; + }, + BACKDROP_SHOW: (state, action) => { + state.backdrop = true; + }, + BACKDROP_HIDE: (state, action) => { + state.backdrop = false; + }, + OPEN_MODAL: (state, action) => { + state.modal = { + modalState: true, + modalContent: action.payload.content, + modalTitle: action.payload.title, + modalOnClose: action.payload.onClose, + modalSize: action.payload.size, + }; + }, + CLOSE_MODAL: (state) => { + state.modal = { modalState: false, modalContent: null, modalTitle: null }; + }, + DRAWER: (state, action) => { + state.drawer = { + ...state.drawer, + ...action.payload, + }; + }, + + RESET_TIME_TO_LOGOUT: (state, action) => { + state.inActiveTime = 1800; + }, +}; diff --git a/src/lib/redux/slices/appSlice.js b/src/lib/redux/slices/appSlice.js new file mode 100644 index 0000000..e1c8e9f --- /dev/null +++ b/src/lib/redux/slices/appSlice.js @@ -0,0 +1,42 @@ +import { createSlice } from "@reduxjs/toolkit"; +import { appReducers } from "./appReducers"; + +const initialState = { + pending: false, + inActiveTime: 1800, + modal: { + modalState: false, + modalContent: null, + modalTitle: null, + modalOnClose: null, + modalSize: 500, + }, + drawer: { + top: false, + left: false, + bottom: false, + right: false, + content: null, + title: null, + }, +}; + +const slice = createSlice({ + name: "app", + initialState, + reducers: appReducers, + extraReducers: {}, +}); + +export const { reducer: appSlice } = slice; + +export const { + LOADING_START, + LOADING_END, + CLOSE_MODAL, + OPEN_MODAL, + DRAWER, + BACKDROP_SHOW, + BACKDROP_HIDE, + RESET_TIME_TO_LOGOUT, +} = slice.actions; diff --git a/src/lib/redux/slices/auctionExtraReducers.js b/src/lib/redux/slices/auctionExtraReducers.js new file mode 100644 index 0000000..132991f --- /dev/null +++ b/src/lib/redux/slices/auctionExtraReducers.js @@ -0,0 +1,19 @@ +import { auctionGetAuctions } from "../../../features/auction/services/auction-get-auctions"; +import { auctionSlaughterRequests } from "../../../features/auction/services/auction-slaughter-requests"; + +export const auctionExtraReducers = { + [auctionSlaughterRequests.fulfilled]: (state, { payload }) => { + state.auctionSlaughterRequestsData = payload.data; + state.pending = false; + }, + [auctionSlaughterRequests.pending]: (state) => { + state.pending = true; + }, + [auctionGetAuctions.fulfilled]: (state, { payload }) => { + state.auctions = payload.data; + state.pending = false; + }, + [auctionGetAuctions.pending]: (state) => { + state.pending = true; + }, +}; diff --git a/src/lib/redux/slices/auctionReducers.js b/src/lib/redux/slices/auctionReducers.js new file mode 100644 index 0000000..eca2af1 --- /dev/null +++ b/src/lib/redux/slices/auctionReducers.js @@ -0,0 +1,26 @@ +export const auctionReducers = { + auctionFilterByDate: (state, action) => { + state.filterByDate = action.payload; + }, + auctionFilterByProvince: (state, action) => { + state.filterByProvince = action.payload; + }, + auctionFilterByCity: (state, action) => { + state.filterByCity = action.payload; + }, + auctionFilterByQuantity: (state, action) => { + state.filterByQuantity = action.payload; + }, + auctionFilterByAge: (state, action) => { + state.filterByAge = action.payload; + }, + auctionFilterByRace: (state, action) => { + state.filterByRace = action.payload; + }, + auctionFilterByWeight: (state, action) => { + state.filterByWeight = action.payload; + }, + auctionFilterByPrice: (state, action) => { + state.filterByPrice = action.payload; + }, +}; diff --git a/src/lib/redux/slices/auctionSlice.js b/src/lib/redux/slices/auctionSlice.js new file mode 100644 index 0000000..fc3e257 --- /dev/null +++ b/src/lib/redux/slices/auctionSlice.js @@ -0,0 +1,39 @@ +import { createSlice } from "@reduxjs/toolkit"; +import { auctionExtraReducers } from "./auctionExtraReducers"; +import { auctionReducers } from "./auctionReducers"; +// import { auctionReducers } from "./auctionReducers"; + +const initialState = { + pending: false, + auctions: [], + filterByDate: null, + filterByProvinceAndCity: null, + auctionSlaughterRequestsData: [], + provinceFilter: null, + cityFilter: null, + quantityFilter: null, + ageFilter: null, + raceFilter: null, + weightFilter: null, + priceFilter: null, +}; + +const slice = createSlice({ + name: "auction", + initialState, + extraReducers: auctionExtraReducers, + reducers: auctionReducers, +}); + +export const { reducer: auctionSlice } = slice; + +export const { + auctionFilterByDate, + auctionFilterByCity, + auctionFilterByProvince, + auctionFilterByQuantity, + auctionFilterByAge, + auctionFilterByRace, + auctionFilterByWeight, + auctionFilterByPrice, +} = slice.actions; diff --git a/src/lib/redux/slices/avicultureExtraReducers.js b/src/lib/redux/slices/avicultureExtraReducers.js new file mode 100644 index 0000000..4a11d9e --- /dev/null +++ b/src/lib/redux/slices/avicultureExtraReducers.js @@ -0,0 +1,87 @@ +import { avicultureGetProfile } from "../../../features/aviculture/services/aviculture-get-profile"; +import { avicultureNewRequest } from "../../../features/aviculture/services/aviculture-new-request"; +import { avicultureGetRequests } from "../../../features/aviculture/services/aviculture-requests"; +import { avicultureGetHatchings } from "../../../features/aviculture/services/aviculture-get-hatchings"; +import { avicultureGetChickenPrice } from "../../../features/aviculture/services/aviculture-get-chicken-price"; +import { avicultureGetHallsInfo } from "../../../features/aviculture/services/aviculture-get-halls-info"; +import { avicultureGetHallInspects } from "../../../features/aviculture/services/aviculture-get-hall-inspects"; +import { avicultureGetSlaughters } from "../../../features/aviculture/services/aviculture-get-slaughters"; +import { avicultureGetReports } from "../../../features/aviculture/services/aviculture-get-reports"; +import { avicultureHatchingRequestsService } from "../../../features/aviculture/services/aviculture-hatching-requests"; +import { avicultureRequestsStateProcessService } from "../../../features/aviculture/services/aviculture-requests-state-process"; + +export const avicultureExtraReducers = { + [avicultureNewRequest.fulfilled]: (state, { payload }) => { + state.pending = false; + }, + [avicultureNewRequest.pending]: (state) => { + state.pending = true; + }, + [avicultureGetRequests.fulfilled]: (state, { payload }) => { + state.avicultureRequests = payload.data; + state.pending = false; + }, + [avicultureRequestsStateProcessService.fulfilled]: (state, { payload }) => { + state.avicultureRequestsStateProcess = payload.data; + state.pending = true; + }, + [avicultureRequestsStateProcessService.pending]: (state, { payload }) => { + state.pending = false; + }, + [avicultureGetRequests.pending]: (state) => { + state.pending = true; + }, + [avicultureGetHatchings.fulfilled]: (state, { payload }) => { + state.avicultureHatchings = payload.data; + state.pending = false; + }, + [avicultureGetHatchings.pending]: (state) => { + state.pending = true; + }, + [avicultureGetProfile.fulfilled]: (state, { payload }) => { + state.profile = payload.data; + state.pending = false; + }, + [avicultureGetProfile.pending]: (state) => { + state.pending = true; + }, + [avicultureGetChickenPrice.fulfilled]: (state, { payload }) => { + state.avicultureChickenPrice = payload.data; + state.pending = false; + }, + [avicultureGetChickenPrice.pending]: (state) => { + state.pending = true; + }, + [avicultureGetHallsInfo.fulfilled]: (state, { payload }) => { + state.avicultureHallsInfo = payload.data; + state.pending = false; + }, + [avicultureGetHallsInfo.pending]: (state) => { + state.pending = true; + }, + [avicultureGetHallInspects.fulfilled]: (state, { payload }) => { + state.avicultureHallInspects = payload.data; + state.pending = false; + }, + [avicultureGetHallInspects.pending]: (state) => { + state.pending = true; + }, + [avicultureGetSlaughters.fulfilled]: (state, { payload }) => { + payload.data.sort((a, b) => b.quantitySum - a.quantitySum); + state.avicultureSlaughters = payload.data; + state.pending = false; + }, + [avicultureGetSlaughters.pending]: (state) => { + state.pending = true; + }, + [avicultureGetReports.fulfilled]: (state, { payload }) => { + state.reports = payload.data; + state.pending = false; + }, + [avicultureGetReports.pending]: (state) => { + state.pending = true; + }, + [avicultureHatchingRequestsService.fulfilled]: (state, { payload }) => { + state.avicultureHatchingRequests = payload.data; + }, +}; diff --git a/src/lib/redux/slices/avicultureSlice.js b/src/lib/redux/slices/avicultureSlice.js new file mode 100644 index 0000000..7070d39 --- /dev/null +++ b/src/lib/redux/slices/avicultureSlice.js @@ -0,0 +1,22 @@ +import { createSlice } from "@reduxjs/toolkit"; +import { avicultureExtraReducers } from "./avicultureExtraReducers"; + +const initialState = { + pending: false, + avicultureRequests: [], + avicultureChickenPrice: null, + avicultureHallsInfo: null, + avicultureHallInspects: null, + profile: null, + tickets: [], + reports: [], +}; + +const slice = createSlice({ + name: "aviculture", + initialState, + reducers: {}, + extraReducers: avicultureExtraReducers, +}); + +export const { reducer: avicultureSlice } = slice; diff --git a/src/lib/redux/slices/cityExtraReducer.js b/src/lib/redux/slices/cityExtraReducer.js new file mode 100644 index 0000000..6098174 --- /dev/null +++ b/src/lib/redux/slices/cityExtraReducer.js @@ -0,0 +1,81 @@ +import { cityGetArchiveHatchingsService } from "../../../features/city/services/city-get-archive-hatchings"; +import { cityGetHatchingInfo } from "../../../features/city/services/city-get-hatching-info"; +import { cityGetHatchingInfoFull } from "../../../features/city/services/city-get-hatching-info-full"; +import { cityGetHatchings } from "../../../features/city/services/city-get-hatchings"; +import { cityGetHatchingsByAge } from "../../../features/city/services/city-get-hatchings-by-age"; +import { cityGetPoultriesService } from "../../../features/city/services/city-get-poultries"; +import { cityGetPoultryFarm } from "../../../features/city/services/city-get-poultry-farms"; +import { cityGetProfile } from "../../../features/city/services/city-get-profile"; +import { cityGetUserProfiles } from "../../../features/city/services/city-get-user-profiles"; +import { getPoultryRequestsTotalQuantityService } from "../../../features/city/services/get-poultry-requests-total-quantity"; +import { getSlaughtersKillRequestService } from "../../../features/city/services/get-slaughters-kill-request"; +import { hourLimitKillRequestService } from "../../../features/city/services/hour-limit-kill-request"; +import { checkRequestByCity } from "../../../features/file/services/checkRequestByCity"; + +export const cityExtraReducers = { + [checkRequestByCity.fulfilled]: (state, { payload }) => { + state.pending = false; + }, + [checkRequestByCity.pending]: (state) => { + state.pending = true; + }, + [cityGetProfile.fulfilled]: (state, { payload }) => { + state.profile = payload.data; + state.pending = false; + }, + [cityGetProfile.pending]: (state) => { + state.pending = true; + }, + [cityGetPoultryFarm.fulfilled]: (state, { payload }) => { + state.poultryFarms = payload.data; + state.pending = false; + }, + [cityGetPoultryFarm.pending]: (state) => { + state.pending = true; + }, + [cityGetUserProfiles.fulfilled]: (state, { payload }) => { + state.cityUsers = payload.data; + state.pending = false; + }, + [cityGetUserProfiles.pending]: (state) => { + state.pending = true; + }, + [cityGetHatchings.fulfilled]: (state, { payload }) => { + state.hatchings = payload.data; + state.pending = false; + }, + [cityGetHatchingsByAge.fulfilled]: (state, { payload }) => { + state.hatchings = payload.data; + state.pending = false; + }, + [cityGetHatchings.pending]: (state) => { + state.pending = true; + }, + [getPoultryRequestsTotalQuantityService.fulfilled]: (state, { payload }) => { + state.poultryRequestsTotalQuantity = payload.data; + }, + [hourLimitKillRequestService.fulfilled]: (state, { payload }) => { + state.hourLimitKillRequest = payload.data; + }, + [getSlaughtersKillRequestService.fulfilled]: (state, { payload }) => { + state.getSlaughtersKillRequest = payload.data; + }, + [cityGetArchiveHatchingsService.fulfilled]: (state, { payload }) => { + state.cityGetArchiveHatchings = payload.data; + }, + [cityGetPoultriesService.fulfilled]: (state, { payload }) => { + state.cityGetPoultries = payload.data.map((item) => { + return { + label: `${item.unitName} (${item.address.city.name}) (${item.user.fullname}) (${item.user.mobile}) / ${item.lastHatchingRemainQuantity} قطعه`, + value: item.user.mobile, + disabled: item.lastHatchingRemainQuantity, + }; + }); + }, + [cityGetHatchingInfo.fulfilled]: (state, { payload }) => { + state.hatchingInfoWithDate = payload.data; + }, + [cityGetHatchingInfoFull.fulfilled]: (state, { payload }) => { + state.hatchingInfoFull = payload.data; + }, +}; diff --git a/src/lib/redux/slices/cityReducers.js b/src/lib/redux/slices/cityReducers.js new file mode 100644 index 0000000..18c3686 --- /dev/null +++ b/src/lib/redux/slices/cityReducers.js @@ -0,0 +1,5 @@ +export const cityReducers = { + reloadHatchings: (state) => { + state.hatchingAdded = !state.hatchingAdded; + }, +}; diff --git a/src/lib/redux/slices/citySlice.js b/src/lib/redux/slices/citySlice.js new file mode 100644 index 0000000..fe2ea63 --- /dev/null +++ b/src/lib/redux/slices/citySlice.js @@ -0,0 +1,22 @@ +import { createSlice } from "@reduxjs/toolkit"; +import { cityExtraReducers } from "./cityExtraReducer"; +import { cityReducers } from "./cityReducers"; +const initialState = { + pending: false, + modalState: false, + profile: null, + cityUsers: null, + hatchings: null, + hatchingAdded: "false", +}; + +const slice = createSlice({ + name: "city", + initialState, + extraReducers: cityExtraReducers, + reducers: cityReducers, +}); + +export const { reducer: citySlice } = slice; + +export const { reloadHatchings } = slice.actions; diff --git a/src/lib/redux/slices/driverExtraReducers.js b/src/lib/redux/slices/driverExtraReducers.js new file mode 100644 index 0000000..532a46f --- /dev/null +++ b/src/lib/redux/slices/driverExtraReducers.js @@ -0,0 +1,27 @@ +import { driverGetCars } from "../../../features/driver/services/driver-get-cars"; +import { driverGetProfile } from "../../../features/driver/services/driver-get-profile"; +import { driverGetRequests } from "../../../features/driver/services/driver-get-requests"; + +export const driverExtraReducers = { + [driverGetRequests.fulfilled]: (state, { payload }) => { + state.driverRequests = payload.data; + state.pending = false; + }, + [driverGetRequests.pending]: (state) => { + state.pending = true; + }, + [driverGetCars.fulfilled]: (state, { payload }) => { + state.driverCars = payload.data; + state.pending = false; + }, + [driverGetCars.pending]: (state) => { + state.pending = true; + }, + [driverGetProfile.fulfilled]: (state, { payload }) => { + state.profile = payload.data.profile; + state.pending = false; + }, + [driverGetProfile.pending]: (state) => { + state.pending = true; + }, +}; diff --git a/src/lib/redux/slices/driverSlice.js b/src/lib/redux/slices/driverSlice.js new file mode 100644 index 0000000..68fe4b6 --- /dev/null +++ b/src/lib/redux/slices/driverSlice.js @@ -0,0 +1,19 @@ +import { createSlice } from "@reduxjs/toolkit"; +import { driverExtraReducers } from "./driverExtraReducers"; + +const initialState = { + pending: false, + modalState: false, + driverRequests: [], + driverCars: [], + profile: null, +}; + +const slice = createSlice({ + name: "driver", + initialState, + extraReducers: driverExtraReducers, + reducers: {}, +}); + +export const { reducer: driverSlice } = slice; diff --git a/src/lib/redux/slices/fileExtraReducers.js b/src/lib/redux/slices/fileExtraReducers.js new file mode 100644 index 0000000..c29be6c --- /dev/null +++ b/src/lib/redux/slices/fileExtraReducers.js @@ -0,0 +1,66 @@ +import { + getFileProcess, + getFileProcessOther, +} from "../../../features/file/services/getFileProcess"; +import { getSlaughterHousesRequest } from "../../../features/file/services/getSlaughterHousesRequest"; +import { getAllocationInformation } from "../../../features/file/services/get-allocation-information"; +import { provinceDoAllocation } from "../../../features/file/services/province-do-allocation"; +import { getAcceptedSlaughterRequest } from "../../../features/file/services/getAcceptedSlaughterRequest"; +import { getMonthlyPercent } from "../../../features/file/services/get-monthly-percent"; +import { poultryRequestIndexWeightService } from "../../../features/file/services/city-edit-avculture.info"; + +export const fileExtraReducers = { + [getFileProcess.fulfilled]: (state, { payload }) => { + state.pending = false; + state.file = payload.data; + }, + [getFileProcess.pending]: (state) => { + state.pending = true; + // state.file = null; + }, + [getFileProcessOther.fulfilled]: (state, { payload }) => { + state.pending = false; + state.file = payload.data; + }, + [getFileProcessOther.pending]: (state) => { + state.pending = true; + // state.file = null; + }, + [getAcceptedSlaughterRequest.fulfilled]: (state, { payload }) => { + state.pending = false; + state.acceptedSlaughterRequest = payload.data; + }, + [getAcceptedSlaughterRequest.pending]: (state) => { + state.pending = true; + }, + [getSlaughterHousesRequest.fulfilled]: (state, { payload }) => { + state.pending = false; + state.slaughterHousesRequest = payload.data; + }, + [getSlaughterHousesRequest.pending]: (state) => { + state.pending = true; + }, + [getAllocationInformation.fulfilled]: (state, { payload }) => { + state.pending = false; + state.allocationInformation = payload.data; + }, + [getAllocationInformation.pending]: (state) => { + state.pending = true; + }, + [provinceDoAllocation.fulfilled]: (state, { payload }) => { + state.pending = false; + }, + [provinceDoAllocation.pending]: (state) => { + state.pending = true; + }, + [getMonthlyPercent.fulfilled]: (state, { payload }) => { + state.pending = false; + state.monthlyData = payload.data; + }, + [poultryRequestIndexWeightService.fulfilled]: (state, { payload }) => { + state.poultryRequestIndexWeight = payload.data; + }, + [getMonthlyPercent.pending]: (state) => { + state.pending = true; + }, +}; diff --git a/src/lib/redux/slices/fileReducers.js b/src/lib/redux/slices/fileReducers.js new file mode 100644 index 0000000..1e98833 --- /dev/null +++ b/src/lib/redux/slices/fileReducers.js @@ -0,0 +1,8 @@ +export const fileReducers = { + cleanFile: (state, action) => { + state.file = null; + }, + CHANGE_SELECTED_ROLES: (state, action) => { + state.selectedRoles = action.payload; + }, +}; diff --git a/src/lib/redux/slices/fileSlice.js b/src/lib/redux/slices/fileSlice.js new file mode 100644 index 0000000..23d8eea --- /dev/null +++ b/src/lib/redux/slices/fileSlice.js @@ -0,0 +1,23 @@ +import { createSlice } from "@reduxjs/toolkit"; +import { fileExtraReducers } from "./fileExtraReducers"; +import { fileReducers } from "./fileReducers"; + +const initialState = { + pending: false, + file: null, + slaughterHousesRequest: [], + allocationInformation: null, + acceptedSlaughterRequest: null, + selectedRoles: [], +}; + +const slice = createSlice({ + name: "file", + initialState, + extraReducers: fileExtraReducers, + reducers: fileReducers, +}); + +export const { reducer: fileSlice } = slice; + +export const { cleanFile, CHANGE_SELECTED_ROLES } = slice.actions; diff --git a/src/lib/redux/slices/generalExtraReducers.js b/src/lib/redux/slices/generalExtraReducers.js new file mode 100644 index 0000000..b37107c --- /dev/null +++ b/src/lib/redux/slices/generalExtraReducers.js @@ -0,0 +1,75 @@ +import { getRequestsAwaitingInspection } from "../../../components/requests-awaiting-inspections/service"; +import { getRequestsAwaitingPayment } from "../../../components/requests-awaiting-payment/service"; +import { cityVetGetProfileService } from "../../../features/city-vet/services/city-vet-profile"; +import { guildGetFreeBars } from "../../../features/guild/services/guild-get-free-bars"; +import { guildGetFreeSaleBarService } from "../../../features/guild/services/guild-get-free-sale-bar"; +import { guildGetStewardsService } from "../../../features/guild/services/guild-get-guilds"; +import { guildGetInventoryAllocatedService } from "../../../features/guild/services/guild-get-inventory-allocated"; +import { guildGetInventoryStockService } from "../../../features/guild/services/guild-get-inventory-stock"; +import { guildGetProfile } from "../../../features/guild/services/guild-get-profile"; +import { guildGetStewards } from "../../../features/guild/services/guild-get-stewards"; +import { guildGetAllocationData } from "../../../features/guild/services/guildGetAllocationData"; +import { senfGetInventoryAllocatedService } from "../../../features/guild/services/senf-get-inventory-allocated"; +import { senfGetInventoryStockService } from "../../../features/guild/services/senf-get-inventory-stock"; +import { senfGetAllocationDashboardService } from "../../../features/guild/services/senf-get-allocation-dashboard"; +import { guildSalesInfoDashboardService } from "../../../features/guild/services/guild-sales-info-dashboard"; + +export const generalExtraReducers = { + [guildGetProfile.fulfilled]: (state, { payload }) => { + state.guildProfile = payload.data; + }, + [getRequestsAwaitingPayment.fulfilled]: (state, { payload }) => { + state.pending = false; + state.awaitingPaymentRequests = payload.data; + }, + [getRequestsAwaitingPayment.pending]: (state) => { + state.pending = true; + }, + [getRequestsAwaitingInspection.fulfilled]: (state, { payload }) => { + state.pending = false; + state.awaitingInspectionRequests = payload.data; + }, + [getRequestsAwaitingInspection.pending]: (state) => { + state.pending = true; + }, + [cityVetGetProfileService.fulfilled]: (state, { payload }) => { + state.cityVetGetProfile = payload.data; + }, + [guildGetInventoryStockService.fulfilled]: (state, { payload }) => { + state.guildGetInventoryStock = payload.data; + }, + [guildGetFreeSaleBarService.fulfilled]: (state, { payload }) => { + state.guildFreeSaleBars = payload.data; + }, + [senfGetInventoryStockService.fulfilled]: (state, { payload }) => { + state.senfGetInventoryStock = payload.data; + }, + [senfGetAllocationDashboardService.fulfilled]: (state, { payload }) => { + state.senfGetInventoryStock = payload.data; + }, + [guildGetStewards.fulfilled]: (state, { payload }) => { + state.guildStewards = payload.data; + }, + [guildGetInventoryAllocatedService.fulfilled]: (state, { payload }) => { + state.guildGetInventoryAllocated = payload.data; + }, + [guildGetFreeBars.fulfilled]: (state, { payload }) => { + state.guildFreeBars = payload.data; + }, + [senfGetInventoryAllocatedService.fulfilled]: (state, { payload }) => { + state.senfGetInventoryAllocated = payload.data; + }, + [guildGetStewardsService.fulfilled]: (state, { payload }) => { + state.guildGetStewardsState = payload.data.map((item) => ({ + label: `${item?.guildsName} (${item?.user?.city}) / ${item?.user?.fullname} (${item?.user?.mobile})`, + value: item.key, + })); + }, + [guildGetAllocationData.fulfilled]: (state, { payload }) => { + state.guildGetGuildData = payload.data; + state.pending = false; + }, + [guildSalesInfoDashboardService.fulfilled]: (state, { payload }) => { + state.guildSalesInfoDashboard = payload.data; + }, +}; diff --git a/src/lib/redux/slices/generalSlice.js b/src/lib/redux/slices/generalSlice.js new file mode 100644 index 0000000..808ef43 --- /dev/null +++ b/src/lib/redux/slices/generalSlice.js @@ -0,0 +1,18 @@ +import { createSlice } from "@reduxjs/toolkit"; +import { generalExtraReducers } from "./generalExtraReducers"; + +const initialState = { + pending: false, + awaitingPaymentRequests: null, + awaitingInspectionRequests: null, +}; + +const slice = createSlice({ + name: "general", + initialState, + extraReducers: generalExtraReducers, +}); + +export const { reducer: generalSlice } = slice; + +export const { cleanFile } = slice.actions; diff --git a/src/lib/redux/slices/inspectorExtraReducers.js b/src/lib/redux/slices/inspectorExtraReducers.js new file mode 100644 index 0000000..c40a124 --- /dev/null +++ b/src/lib/redux/slices/inspectorExtraReducers.js @@ -0,0 +1,24 @@ +import { inspectorGetKillHousesService } from "../../../features/inspector/services/inspector-get-kill-houses"; +import { inspectorGetProfile } from "../../../features/inspector/services/inspector-get-profile"; +import { inspectorGetNewRequests } from "../../../features/inspector/services/inspector-new-requests"; +import { manageFarmGetFarmsService } from "../../../features/inspector/services/manage-farm-get-farms"; + +export const inspectorExtraReducers = { + [inspectorGetNewRequests.fulfilled]: (state, { payload }) => { + state.inspectorNewRequests = payload.data; + state.pending = false; + }, + [inspectorGetNewRequests.pending]: (state) => { + state.pending = true; + }, + [inspectorGetProfile.fulfilled]: (state, { payload }) => { + state.profile = payload.data; + state.pending = false; + }, + [manageFarmGetFarmsService.fulfilled]: (state, { payload }) => { + state.manageFarmGetFarms = payload.data; + }, + [inspectorGetKillHousesService.fulfilled]: (state, { payload }) => { + state.inspectorGetKillHouses = payload.data; + }, +}; diff --git a/src/lib/redux/slices/inspectorSlice.js b/src/lib/redux/slices/inspectorSlice.js new file mode 100644 index 0000000..c25ae3c --- /dev/null +++ b/src/lib/redux/slices/inspectorSlice.js @@ -0,0 +1,17 @@ +import { createSlice } from "@reduxjs/toolkit"; +import { inspectorExtraReducers } from "./inspectorExtraReducers"; + +const initialState = { + inspectorNewRequests: null, + pending: false, + profile: null, +}; + +const slice = createSlice({ + name: "inspector", + initialState, + extraReducers: inspectorExtraReducers, + reducers: {}, +}); + +export const { reducer: inspectorSlice } = slice; diff --git a/src/lib/redux/slices/jahadExtraReducers.js b/src/lib/redux/slices/jahadExtraReducers.js new file mode 100644 index 0000000..c90d0da --- /dev/null +++ b/src/lib/redux/slices/jahadExtraReducers.js @@ -0,0 +1,18 @@ +import { jahadIllegalKillingService } from "../../../features/jahad/services/jahad-illegal-killing"; +import { jahadGetProfile } from "../../../features/jahad/services/jahadGetProfile"; +import { killsDailyReportService } from "../../../features/jahad/services/kills-daily-report-service"; + +export const jahadExtraReducers = { + [jahadGetProfile.fulfilled]: (state, { payload }) => { + state.profile = payload.data; + state.pending = false; + }, + [killsDailyReportService.fulfilled]: (state, { payload }) => { + state.killsDailyReport = payload.data; + state.pending = false; + }, + [jahadIllegalKillingService.fulfilled]: (state, { payload }) => { + state.jahadIllegalKilling = payload.data; + state.pending = false; + }, +}; diff --git a/src/lib/redux/slices/jahadSlice.js b/src/lib/redux/slices/jahadSlice.js new file mode 100644 index 0000000..afd937b --- /dev/null +++ b/src/lib/redux/slices/jahadSlice.js @@ -0,0 +1,16 @@ +import { createSlice } from "@reduxjs/toolkit"; +import { jahadExtraReducers } from "./jahadExtraReducers"; + +const initialState = { + profile: null, + jahadIllegalKilling: [], +}; + +const slice = createSlice({ + name: "jahad", + initialState, + extraReducers: jahadExtraReducers, + reducers: {}, +}); + +export const { reducer: jahadSlice } = slice; diff --git a/src/lib/redux/slices/liveStockExtraReducers.js b/src/lib/redux/slices/liveStockExtraReducers.js new file mode 100644 index 0000000..8bc1d7e --- /dev/null +++ b/src/lib/redux/slices/liveStockExtraReducers.js @@ -0,0 +1,13 @@ +import { liveStockGetFreezingRequests } from "../../../features/live-stock-support/services/live-stock-get-freezing-requests"; +import { liveStockGetInventoryData } from "../../../features/live-stock-support/services/live-stock-get-inventory-data"; + +export const liveStockExtraReducers = { + [liveStockGetFreezingRequests.fulfilled]: (state, { payload }) => { + state.freezingRequests = payload.data; + state.pending = false; + }, + [liveStockGetInventoryData.fulfilled]: (state, { payload }) => { + state.inventoryData = payload.data; + state.pending = false; + }, +}; diff --git a/src/lib/redux/slices/liveStockSlice.js b/src/lib/redux/slices/liveStockSlice.js new file mode 100644 index 0000000..5695b5b --- /dev/null +++ b/src/lib/redux/slices/liveStockSlice.js @@ -0,0 +1,15 @@ +import { createSlice } from "@reduxjs/toolkit"; +import { liveStockExtraReducers } from "./liveStockExtraReducers"; + +const initialState = { + pending: false, +}; + +const slice = createSlice({ + name: "liveStock", + initialState, + extraReducers: liveStockExtraReducers, + reducers: {}, +}); + +export const { reducer: liveStockSlice } = slice; diff --git a/src/lib/redux/slices/messageExtraReducers.js b/src/lib/redux/slices/messageExtraReducers.js new file mode 100644 index 0000000..386add0 --- /dev/null +++ b/src/lib/redux/slices/messageExtraReducers.js @@ -0,0 +1,19 @@ +import { messagesGetSenderMessages } from "../../../features/messages/services/messages-get-sender-messages"; +import { messagesGetReciverMessages } from "../../../features/messages/services/messages-get-reciver-messages"; + +export const messageExtraReducers = { + [messagesGetSenderMessages.fulfilled]: (state, { payload }) => { + state.senderMessages = payload.data; + state.pending = false; + }, + [messagesGetSenderMessages.pending]: (state) => { + state.pending = true; + }, + [messagesGetReciverMessages.fulfilled]: (state, { payload }) => { + state.reciverMessages = payload.data; + state.pending = false; + }, + [messagesGetReciverMessages.pending]: (state) => { + state.pending = true; + }, +}; diff --git a/src/lib/redux/slices/messageSlice.js b/src/lib/redux/slices/messageSlice.js new file mode 100644 index 0000000..e230f88 --- /dev/null +++ b/src/lib/redux/slices/messageSlice.js @@ -0,0 +1,17 @@ +import { createSlice } from "@reduxjs/toolkit"; +import { messageExtraReducers } from "./messageExtraReducers"; + +const initialState = { + pending: false, + senderMessages: null, + reciverMessages: null, +}; + +const slice = createSlice({ + name: "province", + initialState, + extraReducers: messageExtraReducers, + reducers: {}, +}); + +export const { reducer: messageSlice } = slice; diff --git a/src/lib/redux/slices/provinceExtraReducers.js b/src/lib/redux/slices/provinceExtraReducers.js new file mode 100644 index 0000000..7e4d1a9 --- /dev/null +++ b/src/lib/redux/slices/provinceExtraReducers.js @@ -0,0 +1,298 @@ +import { getPoultryRequestsTotalQuantityService } from "../../../features/city/services/get-poultry-requests-total-quantity"; +import { provinceGetFieldOfWorks } from "../../../features/province/services/ProvinceGetFieldOfWorks"; +import { provinceGetCasesOverview } from "../../../features/province/services/get-cases-overview"; +import { getCitiesService } from "../../../features/province/services/get-cities"; +import { getGuildsSettingsService } from "../../../features/province/services/get-guilds-settings"; +import { getManagePoultriesService } from "../../../features/province/services/get-manage-poultries"; +import { getPolicyProvinceFeeService } from "../../../features/province/services/get-policy-province-fee"; +import { getProvinceBuyerStewardAllocationService } from "../../../features/province/services/get-province-buyer-steward-allocation"; +import { getProvinceBuyersAllocationsService } from "../../../features/province/services/get-province-buyers-allocations"; +import { getProvinceFeeTotalOverviewService } from "../../../features/province/services/get-province-fee-total-overview"; +import { getProvinceNewRequests } from "../../../features/province/services/get-province-new-requests"; +import { getProvinceStewardAllocationsService } from "../../../features/province/services/get-province-steward.allocation"; +import { manageProcessBuyReqService } from "../../../features/province/services/manage-process-buy-req"; +import { provinceCasesGetTableDetails } from "../../../features/province/services/province-cases-get-table-details"; +import { provinceChainsGetCompanies } from "../../../features/province/services/province-chains-get-companies"; +import { provinceFreeSaleBuyers } from "../../../features/province/services/province-free-sales-get-buyers"; +import { provinceGetActiveRequestsService } from "../../../features/province/services/province-get-active-requests"; +import { provinceGetAllRequests } from "../../../features/province/services/province-get-all-requests"; +import { provinceGetAllocatedRequestsService } from "../../../features/province/services/province-get-allocated-requests"; +import { provinceGetArchiveAutoAllocationsService } from "../../../features/province/services/province-get-archive-auto-allocations"; +import { provinceGetAutoAllocationsService } from "../../../features/province/services/province-get-auto-allocations"; +import { provinceGetBuyersService } from "../../../features/province/services/province-get-buyers"; +import { provinceGetCars } from "../../../features/province/services/province-get-cars"; +import { provinceGetCaseStatusService } from "../../../features/province/services/province-get-case-status"; +import { provinceGetCitiesService } from "../../../features/province/services/province-get-cities"; +import { provinceGetDeletedAllocatedRequestsService } from "../../../features/province/services/province-get-deleted-allocated-requests"; +import { provinceGetFilesStateService } from "../../../features/province/services/province-get-files-state"; +import { provinceGetFreeSalesRequestsService } from "../../../features/province/services/province-get-free-sales-requests"; +import { provinceGetGuildsService } from "../../../features/province/services/province-get-guilds"; +import { provinceGetGuildsNumbersNamesService } from "../../../features/province/services/province-get-guilds-numbers-names"; +import { provinceGetKillhousesService } from "../../../features/province/services/province-get-killhouses"; +import { provinceGetKillhousesGuildsService } from "../../../features/province/services/province-get-killhouses-guilds"; +import { provinceGetManageUsersService } from "../../../features/province/services/province-get-manage-users"; +import { provinceGetOnlyKillHousesService } from "../../../features/province/services/province-get-only-kill-houses"; +import { + parentConpanyGetPaymentByWeightOverview, + provinceGetPaymentByWeightOverview, +} from "../../../features/province/services/province-get-payment-by-weight-overview"; +import { provinceGetPolicyAvicultureCommitService } from "../../../features/province/services/province-get-policy-aviculture-commit"; +import { provinceGetPoultriesService } from "../../../features/province/services/province-get-poultries"; +import { provinceGetPricing } from "../../../features/province/services/province-get-pricing"; +import { provinceGetProducts } from "../../../features/province/services/province-get-producrs"; +import { provinceGetProfile } from "../../../features/province/services/province-get-profile"; +import { provinceGetRejectedRequests } from "../../../features/province/services/province-get-rejected-requests"; +import { provinceGetSlaughterSurveillanceService } from "../../../features/province/services/province-get-slaughter-surverillance-service"; +import { provinceGetSlaughterhousesQuotaService } from "../../../features/province/services/province-get-slaughterhouses-quota"; +import { provinceGetSmsLincenseService } from "../../../features/province/services/province-get-sms-license"; +import { provinceGetStewardsService } from "../../../features/province/services/province-get-stewards"; +import { provinceGetTotalReportAgentShareService } from "../../../features/province/services/province-get-total-report-agent-share"; +import { provinceGetUserByKey } from "../../../features/province/services/province-get-user-by-key"; +import { provinceGetUserProfiles } from "../../../features/province/services/province-get-user-profiles"; +import { provincePaymentGetKillersOfKillhousesInfo } from "../../../features/province/services/province-payment-get-killers-of-killhouses-info"; +import { provincePolicyGetWeightRange } from "../../../features/province/services/province-policy-get-weight-range"; +import { provinceGetTypeActivity } from "../../../features/province/services/provinceGetTypeActivity"; +import { totalReportDailyBroadCastService } from "../../../features/slaughter-house/services/salughter-total-report-daily-broad-cast"; +import { totalReportDailyStewardBroadCastService } from "../../../features/slaughter-house/services/total-report-daily-steward-broadcast"; +import { getKillhouseRemainWeight } from "../../../features/province/components/province-dispensers-stock-slug/service"; + +export const provinceExtraReducers = { + [getProvinceNewRequests.fulfilled]: (state, { payload }) => { + state.provinceNewRequests = payload.data; + state.pending = false; + }, + [provinceGetProfile.fulfilled]: (state, { payload }) => { + state.profile = payload.data; + state.pending = false; + }, + [getProvinceNewRequests.pending]: (state) => { + state.pending = true; + }, + [provinceGetAllRequests.fulfilled]: (state, { payload }) => { + state.provinceAllRequests = payload.data; + state.pending = false; + }, + [provinceGetAllRequests.pending]: (state) => { + state.pending = true; + }, + [provinceGetPricing.fulfilled]: (state, { payload }) => { + state.provincePrices = payload.data; + state.pending = false; + }, + [provinceGetPricing.pending]: (state) => { + state.pending = true; + }, + [provinceGetRejectedRequests.fulfilled]: (state, { payload }) => { + state.provinceRejectedRequests = payload.data; + state.pending = false; + }, + [provinceGetRejectedRequests.pending]: (state) => { + state.pending = true; + }, + [provinceGetCars.fulfilled]: (state, { payload }) => { + state.provinceCars = payload.data; + state.pending = false; + }, + [getProvinceBuyersAllocationsService.fulfilled]: (state, { payload }) => { + state.getProvinceBuyersAllocations = payload.data; + state.pending = false; + }, + [getProvinceStewardAllocationsService.fulfilled]: (state, { payload }) => { + state.getProvinceStewardAllocations = payload.data; + state.pending = false; + }, + [provinceGetCars.pending]: (state) => { + state.pending = true; + }, + [provinceGetUserProfiles.fulfilled]: (state, { payload }) => { + state.provinceUsers = payload.data; + state.pending = false; + }, + [provinceGetUserProfiles.pending]: (state) => { + state.pending = true; + }, + [provinceGetUserByKey.fulfilled]: (state, { payload }) => { + state.provinceUserInfo = payload.data; + state.pending = false; + }, + [provinceGetUserByKey.pending]: (state) => { + state.pending = true; + }, + [getPoultryRequestsTotalQuantityService.fulfilled]: (state, { payload }) => { + state.poultryRequestsTotalQuantity = payload.data; + }, + [provinceGetSmsLincenseService.fulfilled]: (state, { payload }) => { + state.provinceGetSmsLincense = payload.data; + }, + [provinceGetActiveRequestsService.fulfilled]: (state, { payload }) => { + state.provinceGetActiveRequests = payload.data; + }, + [provinceGetCaseStatusService.fulfilled]: (state, { payload }) => { + state.provinceGetCaseStatus = payload.data; + }, + [provinceGetCitiesService.fulfilled]: (state, { payload }) => { + state.provinceGetCities = payload.data; + }, + [provinceGetTypeActivity.fulfilled]: (state, { payload }) => { + state.provinceTypeActivity = payload.data; + }, + [provinceGetFieldOfWorks.fulfilled]: (state, { payload }) => { + state.provinceGetAreActivity = payload.data; + }, + [provinceGetOnlyKillHousesService.fulfilled]: (state, { payload }) => { + state.provinceGetOnlyKillHouses = payload.data; + }, + [provinceGetPoultriesService.fulfilled]: (state, { payload }) => { + state.provinceGetPoultries = payload.data; + }, + [provinceGetFreeSalesRequestsService.fulfilled]: (state, { payload }) => { + state.provinceGetFreeSalesRequests = payload.data; + }, + [provinceGetSlaughterhousesQuotaService.fulfilled]: (state, { payload }) => { + state.provinceGetSlaughterhousesQuota = payload.data; + }, + [provinceGetFilesStateService.fulfilled]: (state, { payload }) => { + state.provinceGetFilesState = payload.data; + }, + [provinceGetAutoAllocationsService.fulfilled]: (state, { payload }) => { + state.provinceGetAutoAllocations = payload.data; + }, + [provinceGetBuyersService.fulfilled]: (state, { payload }) => { + state.provinceGetBuyersOptions = payload.data.map((item) => { + return { + label: item.name, + value: item.key, + }; + }); + state.provinceGetBuyers = payload.data; + }, + [provinceGetAllocatedRequestsService.fulfilled]: (state, { payload }) => { + state.provinceGetAllocatedRequests = payload.data; + }, + [provinceGetDeletedAllocatedRequestsService.fulfilled]: ( + state, + { payload } + ) => { + state.provinceGetDeletedAllocatedRequests = payload.data; + }, + [provinceGetArchiveAutoAllocationsService.fulfilled]: ( + state, + { payload } + ) => { + state.provinceGetArchiveAutoAllocations = payload.data; + }, + [provinceGetManageUsersService.fulfilled]: (state, { payload }) => { + state.provinceGetManageUsers = payload.data; + }, + [getGuildsSettingsService.fulfilled]: (state, { payload }) => { + state.getGuildsSettings = payload.data; + }, + [getManagePoultriesService.fulfilled]: (state, { payload }) => { + state.getManagePoultries = payload.data; + }, + [provinceGetKillhousesService.fulfilled]: (state, { payload }) => { + state.provinceGetKillhouses = payload.data; + }, + [totalReportDailyBroadCastService.fulfilled]: (state, { payload }) => { + state.totalReportDailyBroadCast = payload.data; + }, + [totalReportDailyStewardBroadCastService.fulfilled]: (state, { payload }) => { + state.totalReportStewardDailyBroadCast = payload.data; + }, + [provinceGetKillhousesGuildsService.fulfilled]: (state, { payload }) => { + state.provinceGetKillhousesGuilds = payload.data; + }, + [provinceGetGuildsNumbersNamesService.fulfilled]: (state, { payload }) => { + state.provinceGetGuildsNumbersNames = payload.data; + }, + [getPolicyProvinceFeeService.fulfilled]: (state, { payload }) => { + state.getPolicyProvinceFee = payload.data; + }, + [getProvinceFeeTotalOverviewService.fulfilled]: (state, { payload }) => { + state.getProvinceFeeTotalOverview = payload.data; + }, + [manageProcessBuyReqService.fulfilled]: (state, { payload }) => { + state.manageProcessBuyReq = payload.data; + }, + [provinceGetTotalReportAgentShareService.fulfilled]: (state, { payload }) => { + state.provinceGetTotalReportAgentShare = payload.data; + }, + [provinceGetProducts.fulfilled]: (state, { payload }) => { + state.provinceProductList = payload.data; + }, + [provinceGetPolicyAvicultureCommitService.fulfilled]: ( + state, + { payload } + ) => { + state.provinceGetPolicyAvicultureCommit = payload.data; + }, + [getProvinceBuyerStewardAllocationService.fulfilled]: ( + state, + { payload } + ) => { + state.getProvinceBuyerStewardAllocation = payload.data; + }, + [provinceCasesGetTableDetails.fulfilled]: (state, { payload }) => { + state.casesTableDetails = payload.data; + }, + [provinceGetSlaughterSurveillanceService.fulfilled]: (state, { payload }) => { + state.slaughterSurveillance = payload.data; + }, + [provinceGetStewardsService.fulfilled]: (state, { payload }) => { + state.provinceGetStewards = payload.data; + state.provinceGetStewardsOptions = payload.data.map((item) => { + return { + label: `${item.guilds.guildsName}/مالک ${item.guilds.user.fullname}/${item.guilds.user.mobile}`, + value: item.key, + }; + }); + }, + [getCitiesService.fulfilled]: (state, { payload }) => { + state.getCities = payload.data; + state.getCitiesOptions = payload.data.map((item) => { + return { + label: `${item.unitName} (${item.address.city.name})`, + value: item.unitName, + }; + }); + }, + [provinceGetGuildsService.fulfilled]: (state, { payload }) => { + state.provinceGetGuildsOptions = payload?.data?.map((item) => { + return { + label: `${item.guildsName} (${item.user.mobile})`, + value: item.key, + }; + }); + state.provinceGetGuilds = payload?.data; + }, + [provinceGetCasesOverview.fulfilled]: (state, { payload }) => { + state.casesOverview = payload.data; + }, + [provinceChainsGetCompanies.fulfilled]: (state, { payload }) => { + state.chainCompanies = payload.data; + }, + [provinceGetPaymentByWeightOverview.fulfilled]: (state, { payload }) => { + state.provincePaymentByWeightOverview = payload.data; + }, + [parentConpanyGetPaymentByWeightOverview.fulfilled]: (state, { payload }) => { + state.parentCompanyPaymentByWeightOverview = payload.data; + }, + [provinceFreeSaleBuyers.fulfilled]: (state, { payload }) => { + state.provinceFreeSaleAllBuyers = payload.data; + }, + [provincePolicyGetWeightRange.fulfilled]: (state, { payload }) => { + state.weightRange = payload.data?.map((item) => { + const { fromAge, toAge, fromWeight, toWeight } = item; + return { fromAge, toAge, fromWeight, toWeight }; + }); + }, + [provincePaymentGetKillersOfKillhousesInfo.fulfilled]: ( + state, + { payload } + ) => { + state.provincePaymentKillersOfKillhouses = payload.data.wageInfo; + }, + [getKillhouseRemainWeight.fulfilled]: (state, { payload }) => { + state.killhouseRemainWeight = payload.data; + }, +}; diff --git a/src/lib/redux/slices/provinceFinancialExtraReducers.js b/src/lib/redux/slices/provinceFinancialExtraReducers.js new file mode 100644 index 0000000..bcccfb7 --- /dev/null +++ b/src/lib/redux/slices/provinceFinancialExtraReducers.js @@ -0,0 +1,87 @@ +import { provinceFinancialGetFinalFactorsService } from "../../../features/province-finacial/services/province-financial-get-final-factors-service"; +import { provinceFinancialGetFinancialHistory } from "../../../features/province-finacial/services/province-financial-get-financial-history"; +import { provinceFinancialGetPayedFactorsService } from "../../../features/province-finacial/services/province-financial-get-payed-factors-service"; +import { provinceFinancialGetPendingRequestsService } from "../../../features/province-finacial/services/province-financial-get-pending-requests"; +import { provinceFinancialGetRegisteredComplaints } from "../../../features/province-finacial/services/province-financial-get-registered-compaints"; +import { provinceFinancialGetRequests } from "../../../features/province-finacial/services/province-financial-get-requests"; +import { provinceFinancialGetSlaughterSattlementService } from "../../../features/province-finacial/services/province-financial-get-slaughter-sattlement-service"; +import { provinceFinancialGetTransactionInfo } from "../../../features/province-finacial/services/province-financial-get-transaction-info"; +import { provinceFinancialGetUserFinancialInfo } from "../../../features/province-finacial/services/province-financial-get-user-financial-info"; +import { provinceFinancialGetUsersWaletinfo } from "../../../features/province-finacial/services/province-financial-get-users-walet-info"; +import { ticketGetOperatorTickets } from "../../../features/ticket/services/ticket-get-operator-tickets"; + +export const provinceFinancialExtraReducers = { + [provinceFinancialGetRequests.fulfilled]: (state, { payload }) => { + state.provinceFinancial = payload.data; + state.pending = false; + }, + [provinceFinancialGetRequests.pending]: (state) => { + state.pending = true; + }, + [ticketGetOperatorTickets.fulfilled]: (state, { payload }) => { + state.tickets = payload.data; + state.pending = false; + }, + [ticketGetOperatorTickets.pending]: (state) => { + state.pending = true; + }, + [provinceFinancialGetUsersWaletinfo.fulfilled]: (state, { payload }) => { + state.userWaletInfo = payload.data; + state.pending = false; + }, + [provinceFinancialGetUsersWaletinfo.pending]: (state) => { + state.pending = true; + }, + [provinceFinancialGetRegisteredComplaints.fulfilled]: ( + state, + { payload } + ) => { + state.registeredComplaints = payload.data; + state.pending = false; + }, + [provinceFinancialGetRegisteredComplaints.pending]: (state) => { + state.pending = true; + }, + [provinceFinancialGetUserFinancialInfo.fulfilled]: (state, { payload }) => { + state.userFinancialInfo = payload.data; + state.pending = false; + }, + [provinceFinancialGetUserFinancialInfo.pending]: (state) => { + state.pending = true; + }, + [provinceFinancialGetFinancialHistory.fulfilled]: (state, { payload }) => { + state.financialHistory = payload.data; + state.pending = false; + }, + [provinceFinancialGetFinancialHistory.pending]: (state) => { + state.pending = true; + }, + [provinceFinancialGetTransactionInfo.fulfilled]: (state, { payload }) => { + state.transactionInfo = payload.data; + state.pending = false; + }, + [provinceFinancialGetTransactionInfo.pending]: (state) => { + state.pending = true; + }, + [provinceFinancialGetPendingRequestsService.fulfilled]: ( + state, + { payload } + ) => { + const pendingRequestsData = Array.isArray(payload.data) + ? payload.data + : payload.data?.results || []; + state.provinceFinancialGetPendingRequests = pendingRequestsData; + }, + [provinceFinancialGetPayedFactorsService.fulfilled]: (state, { payload }) => { + state.provinceFinancialGetPayedFactors = payload.data; + }, + [provinceFinancialGetFinalFactorsService.fulfilled]: (state, { payload }) => { + state.provinceFinancialGetFinalFactors = payload.data; + }, + [provinceFinancialGetSlaughterSattlementService.fulfilled]: ( + state, + { payload } + ) => { + state.provinceFinancialGetSlaughterSattlement = payload.data; + }, +}; diff --git a/src/lib/redux/slices/provinceFinancialSlice.js b/src/lib/redux/slices/provinceFinancialSlice.js new file mode 100644 index 0000000..76d34ec --- /dev/null +++ b/src/lib/redux/slices/provinceFinancialSlice.js @@ -0,0 +1,24 @@ +import { createSlice } from "@reduxjs/toolkit"; +import { provinceFinancialExtraReducers } from "./provinceFinancialExtraReducers"; + +const initialState = { + loading: true, + modalState: false, + provinceFinancial: [], + tickets: [], + debts: null, + registeredComplaints: null, + userWaletInfo: null, + userFinancialInfo: null, + financialHistory: null, + transactionInfo: null, +}; + +const slice = createSlice({ + name: "provinceFinancial", + initialState, + extraReducers: provinceFinancialExtraReducers, + reducers: {}, +}); + +export const { reducer: provinceFinancialSlice } = slice; diff --git a/src/lib/redux/slices/provinceSlice.js b/src/lib/redux/slices/provinceSlice.js new file mode 100644 index 0000000..6d5548d --- /dev/null +++ b/src/lib/redux/slices/provinceSlice.js @@ -0,0 +1,23 @@ +import { createSlice } from "@reduxjs/toolkit"; +import { provinceExtraReducers } from "./provinceExtraReducers"; + +const initialState = { + pending: false, + provinceNewRequests: null, + provinceAllRequests: null, + provincePrices: null, + provinceUsers: null, + provinceUserInfo: null, + profile: null, + provinceCars: null, + killhouseRemainWeight: null, +}; + +const slice = createSlice({ + name: "province", + initialState, + extraReducers: provinceExtraReducers, + reducers: {}, +}); + +export const { reducer: provinceSlice } = slice; diff --git a/src/lib/redux/slices/slaughterExtraReducer.js b/src/lib/redux/slices/slaughterExtraReducer.js new file mode 100644 index 0000000..e6934d0 --- /dev/null +++ b/src/lib/redux/slices/slaughterExtraReducer.js @@ -0,0 +1,197 @@ +import { slaughterGetCars } from "../../../features/slaughter-house/services/slaughter-get-cars"; +import { slaughterGetRequests } from "../../../features/slaughter-house/services/salughter-get-requests"; +import { slaughterGetActiveRequests } from "../../../features/slaughter-house/services/slaughter-get-active-requests"; +import { slaughterGetProfile } from "../../../features/slaughter-house/services/slaughter-get-profile"; +import { slaughterGetComplaints } from "../../../features/slaughter-house/services/slaughter-get-complaints"; +import { slaughterGetRegisteredComplaints } from "../../../features/slaughter-house/services/slaughter-get-registered-complaints"; +import { slaughterGetInventoryBars } from "../../../features/slaughter-house/services/slaughter-get-inventory-bars"; +import { slaughterGetKillerKillhousesService } from "../../../features/slaughter-house/services/slaughter-get-killers-killhouses"; +import { slaughterFactorsService } from "../../../features/slaughter-house/services/slaughter-factors"; +import { slaughterFinalFactorsService } from "../../../features/slaughter-house/services/slaughter-final-factors"; +import { slaughterGetBarInfoRequestsService } from "../../../features/slaughter-house/services/slaughter-get-bar-info-requests"; +import { slaughterGetPayFactorRequestsService } from "../../../features/slaughter-house/services/slaughter-get-pay-factor-requests"; +import { slaughterGetPermissionToVetService } from "../../../features/slaughter-house/services/slaughter-get-premisson-to-vet"; +import { slaughterGetAllocatedCarsService } from "../../../features/slaughter-house/services/slaughter-get-allocated-cars"; +import { slaughterGetPaiedFactorsService } from "../../../features/slaughter-house/services/slaughter-get-paied-factors"; +import { slaughterManageBarsService } from "../../../features/slaughter-house/services/slaughter-manage-bars"; +import { slaughterGetInventoryStock } from "../../../features/slaughter-house/services/salughter-get-inventory-stock"; +import { slaughterGetInventoryFreeBarsService } from "../../../features/slaughter-house/services/slaughter-get-inventory-free-bars"; +import { slaughterInventoryBarsService } from "../../../features/slaughter-house/services/slaughter-inventory-bars"; +import { slaughterGetStewardsService } from "../../../features/slaughter-house/services/slaughter-get-stewards"; +import { slaughterGetKillhouseStewardsService } from "../../../features/slaughter-house/services/slaughter-get-killhouse-stewards"; +import { slaughterGetGuildsService } from "../../../features/slaughter-house/services/slaughter-get-guilds"; +import { slaughterManageInventoryAllocationsService } from "../../../features/slaughter-house/services/salughter-manage-inventory-allocations"; +import { slaughterGetUpdatedInventoryStock } from "../../../features/slaughter-house/services/salughter-get-updated-inventory-stock"; +import { slaughterGetKillhouseGuildsService } from "../../../features/slaughter-house/services/slaughter-get-killhouse-guilds"; +import { slaughterGetPoultriesService } from "../../../features/slaughter-house/services/salughter-get-poultries"; +import { slaughterGetKillhousesService } from "../../../features/slaughter-house/services/slaughter-get-killhouses"; +import { slaughterGetAggregateLoadInformationService } from "../../../features/slaughter-house/services/salughter-get-aggregate-load-information"; +import { slaughterManageInventoryAllocationForFreezingService } from "../../../features/slaughter-house/services/slaughter-manage-inventory-allocation-for-freezing"; +import { slaughterGetOutOfProvinceSells } from "../../../features/slaughter-house/services/slaughter-get-out-of-province-sells"; +import { slaughterGetPermisionState } from "../../../features/slaughter-house/services/slaughter-get-permision"; +import { slaughterGetPaymentOverviewInfo } from "../../../features/slaughter-house/services/slaughter-get-payment-overview-info"; +import { slaughterGetPaymentByWeightOverview } from "../../../features/slaughter-house/services/slaughter-get-payment-by-weight-overview"; +import { slaughterGetProductsService } from "../../../features/slaughter-house/services/slaughter-inventory-gets"; +import { getKillhouseApprovedPriceState } from "../../../features/province/services/get-approved-price-state"; +import { slaughterGetVBroadcastInfo } from "../../../features/slaughter-house/services/slaughter-get-distribution-info"; +import { fetchSlaughterBroadcastAndProducts } from "../../../features/slaughter-house/services/handle-fetch-slaughter-products"; + +export const slaughterExtraReducer = { + [slaughterGetCars.fulfilled]: (state, { payload }) => { + state.pending = false; + state.slaughterHouseCars = payload.data; + }, + [slaughterGetProfile.fulfilled]: (state, { payload }) => { + state.profile = payload.data; + state.inventorySelectedKillHouse = payload.data.killHouse[0]?.key; + state.pending = false; + }, + [slaughterGetCars.pending]: (state) => { + state.pending = true; + }, + [slaughterGetRequests.fulfilled]: (state, { payload }) => { + state.pending = false; + state.slaughterRequests = payload.data; + }, + [slaughterGetRequests.pending]: (state) => { + state.pending = true; + }, + [slaughterGetActiveRequests.fulfilled]: (state, { payload }) => { + state.pending = false; + state.slaughterActiveRequests = payload.data; + }, + [slaughterGetKillhousesService.fulfilled]: (state, { payload }) => { + state.slaughterGetKillhouses = payload.data; + }, + [slaughterGetAggregateLoadInformationService.fulfilled]: ( + state, + { payload } + ) => { + state.slaughterGetAggregateLoadInformation = payload.data; + }, + [slaughterGetActiveRequests.pending]: (state) => { + state.pending = true; + }, + [slaughterGetComplaints.fulfilled]: (state, { payload }) => { + state.pending = false; + state.slaughterHouseComplaints = payload.data; + }, + [slaughterGetComplaints.pending]: (state) => { + state.pending = true; + }, + [slaughterGetRegisteredComplaints.fulfilled]: (state, { payload }) => { + state.pending = false; + state.slaughterHouseRegisteredComplaints = payload.data; + }, + [slaughterGetRegisteredComplaints.pending]: (state) => { + state.pending = true; + }, + [slaughterGetInventoryBars.fulfilled]: (state, { payload }) => { + state.pending = false; + state.slaughterHouseInventoryBars = payload.data; + }, + [slaughterGetInventoryBars.pending]: (state) => { + state.pending = true; + }, + [slaughterGetKillerKillhousesService.fulfilled]: (state, { payload }) => { + state.slaughterGetKillerKillhouses = payload.data; + }, + [slaughterFactorsService.fulfilled]: (state, { payload }) => { + state.slaughterFactors = payload.data; + }, + [slaughterFinalFactorsService.fulfilled]: (state, { payload }) => { + state.slaughterFinalFactors = payload.data; + }, + [slaughterGetBarInfoRequestsService.fulfilled]: (state, { payload }) => { + state.slaughterGetBarInfoRequests = payload.data; + }, + [slaughterGetPayFactorRequestsService.fulfilled]: (state, { payload }) => { + state.slaughterGetPayFactorRequests = payload.data; + }, + [slaughterGetPermissionToVetService.fulfilled]: (state, { payload }) => { + state.slaughterGetPermissionToVet = payload.data; + }, + [slaughterGetAllocatedCarsService.fulfilled]: (state, { payload }) => { + state.slaughterGetAllocatedCars = payload.data; + }, + [slaughterGetPaiedFactorsService.fulfilled]: (state, { payload }) => { + state.slaughterGetPaiedFactors = payload.data; + }, + [slaughterManageBarsService.fulfilled]: (state, { payload }) => { + state.slaughterManageBars = payload.data; + }, + [slaughterGetInventoryStock.fulfilled]: (state, { payload }) => { + state.slaughterGetInventoryStockData = payload.data; + }, + [slaughterGetInventoryFreeBarsService.fulfilled]: (state, { payload }) => { + state.slaughterGetInventoryFreeBars = payload.data; + }, + [slaughterInventoryBarsService.fulfilled]: (state, { payload }) => { + state.slaughterInventoryBars = payload.data; + }, + [fetchSlaughterBroadcastAndProducts.fulfilled]: (state, { payload }) => { + state.slaughterProducts = payload.productsData; + state.distributionInfo = payload.broadcastData; + }, + [slaughterGetProductsService.fulfilled]: (state, { payload }) => { + state.slaughterProducts = payload.data; + }, + [slaughterGetVBroadcastInfo.fulfilled]: (state, { payload }) => { + state.distributionInfo = payload.data; + }, + [getKillhouseApprovedPriceState.fulfilled]: (state, { payload }) => { + state.priceInfo = payload.data; + }, + [slaughterGetStewardsService.fulfilled]: (state, { payload }) => { + state.slaughterGetStewards = payload.data.map((item) => ({ + label: `${item.guilds.guildsName} (${item.guilds.user.city}) / ${item.guilds.user.fullname} (${item.guilds.user.mobile})`, + value: item.key, + })); + }, + [slaughterGetKillhouseStewardsService.fulfilled]: (state, { payload }) => { + state.slaughterGetKillhouseStewards = payload.data; + }, + [slaughterGetUpdatedInventoryStock.fulfilled]: (state, { payload }) => { + state.slaughterUpdatedInventoryStock = payload.data; + }, + [slaughterManageInventoryAllocationsService.fulfilled]: ( + state, + { payload } + ) => { + state.slaughterManageInventoryAllocations = payload.data; + }, + [slaughterManageInventoryAllocationForFreezingService.fulfilled]: ( + state, + { payload } + ) => { + state.slaughterManageInventoryAllocationsForFreezing = payload.data; + }, + [slaughterGetGuildsService.fulfilled]: (state, { payload }) => { + state.slaughterGetGuilds = payload.data.map((item) => ({ + label: `${item.guildsName} (${item.user.city}) / ${item.user.fullname} (${item.user.mobile})`, + value: item.key, + })); + }, + [slaughterGetKillhouseStewardsService.fulfilled]: (state, { payload }) => { + state.slaughterGetKillhouseStewards = payload.data; + }, + [slaughterGetOutOfProvinceSells.fulfilled]: (state, { payload }) => { + state.slaughterOutOfProvinceSellsState = payload.data; + }, + [slaughterGetKillhouseGuildsService.fulfilled]: (state, { payload }) => { + state.slaughterGetKillhouseGuilds = payload.data; + }, + [slaughterGetPoultriesService.fulfilled]: (state, { payload }) => { + state.slaughterGetPoultries = payload.data; + }, + [slaughterGetPermisionState.fulfilled]: (state, { payload }) => { + state.slaughterPermissionState = payload.data?.permission; + state.slaughterExclusiveState = payload.data?.exclusive; + }, + [slaughterGetPaymentOverviewInfo.fulfilled]: (state, { payload }) => { + state.slaughterPaymentOverview = payload.data; + }, + [slaughterGetPaymentByWeightOverview.fulfilled]: (state, { payload }) => { + state.slaughterPaymentByWeightOverview = payload.data; + }, +}; diff --git a/src/lib/redux/slices/slaughterHouseVetSlice.js b/src/lib/redux/slices/slaughterHouseVetSlice.js new file mode 100644 index 0000000..21390ca --- /dev/null +++ b/src/lib/redux/slices/slaughterHouseVetSlice.js @@ -0,0 +1,18 @@ +import { createSlice } from "@reduxjs/toolkit"; +import { slaughterHouseVetExtraReducers } from "./slaughterHouseVetSliceExtraReducers"; + +const initialState = { + pending: false, + profile: null, + newRequests: [], + slaughterHouseVetComplaints: null, +}; + +const slice = createSlice({ + name: "slaughterHouseVet", + initialState, + extraReducers: slaughterHouseVetExtraReducers, + reducers: {}, +}); + +export const { reducer: slaughterHouseVetSlice } = slice; diff --git a/src/lib/redux/slices/slaughterHouseVetSliceExtraReducers.js b/src/lib/redux/slices/slaughterHouseVetSliceExtraReducers.js new file mode 100644 index 0000000..d7b77f0 --- /dev/null +++ b/src/lib/redux/slices/slaughterHouseVetSliceExtraReducers.js @@ -0,0 +1,27 @@ +import { slaughterHouseVetGetComplaints } from "../../../features/slaughter-house-vet/services/slaughter-house-vet-get-complaints"; +import { slaughterHouseVetGetProfile } from "../../../features/slaughter-house-vet/services/slaughter-house-vet-get-profile"; +import { slaughterHouseVetNewRequests } from "../../../features/slaughter-house-vet/services/slaughter-house-vet-new-requests"; + +export const slaughterHouseVetExtraReducers = { + [slaughterHouseVetGetProfile.fulfilled]: (state, { payload }) => { + state.profile = payload.data; + state.pending = false; + }, + [slaughterHouseVetGetProfile.pending]: (state) => { + state.pending = true; + }, + [slaughterHouseVetNewRequests.fulfilled]: (state, { payload }) => { + state.newRequests = payload.data; + state.pending = false; + }, + [slaughterHouseVetNewRequests.pending]: (state) => { + state.pending = true; + }, + [slaughterHouseVetGetComplaints.fulfilled]: (state, { payload }) => { + state.pending = false; + state.slaughterHouseVetComplaints = payload.data; + }, + [slaughterHouseVetGetComplaints.pending]: (state) => { + state.pending = true; + }, +}; diff --git a/src/lib/redux/slices/slaughterSlice.js b/src/lib/redux/slices/slaughterSlice.js new file mode 100644 index 0000000..1ebcff2 --- /dev/null +++ b/src/lib/redux/slices/slaughterSlice.js @@ -0,0 +1,28 @@ +import { createSlice } from "@reduxjs/toolkit"; +import { slaughterExtraReducer } from "./slaughterExtraReducer"; + +const initialState = { + pending: false, + modalState: false, + slaughterGetRequests: null, + slaughterGetActiveRequests: null, + slaughterHouseCars: null, + slaughterHouseComplaints: null, + slaughterHouseRegisteredComplaints: null, + profile: null, + inventorySelectedKillHouse: null, +}; + +const slice = createSlice({ + name: "slaughter", + initialState, + extraReducers: slaughterExtraReducer, + reducers: { + setInventorySelectedKillHouse: (state, action) => { + state.inventorySelectedKillHouse = action.payload; + }, + }, +}); + +export const { setInventorySelectedKillHouse } = slice.actions; +export const { reducer: slaughterSlice } = slice; diff --git a/src/lib/redux/slices/stewardExtraReducers.js b/src/lib/redux/slices/stewardExtraReducers.js new file mode 100644 index 0000000..5c293d4 --- /dev/null +++ b/src/lib/redux/slices/stewardExtraReducers.js @@ -0,0 +1,13 @@ +import { fetchStewardBroadcastAndProducts } from "../../../features/steward/services/handle-fetch-steward-products"; +import { stewardGetVBroadcastInfo } from "../../../features/steward/services/steward-get-distributions-info"; + +export const stewardExtraReducer = { + [stewardGetVBroadcastInfo.fulfilled]: (state, { payload }) => { + state.pending = false; + state.distributionInfo = payload.data; + }, + [fetchStewardBroadcastAndProducts.fulfilled]: (state, { payload }) => { + state.stewardProducts = payload.productsData; + state.distributionInfo = payload.broadcastData; + }, +}; diff --git a/src/lib/redux/slices/stewardSlice.js b/src/lib/redux/slices/stewardSlice.js new file mode 100644 index 0000000..d638dcc --- /dev/null +++ b/src/lib/redux/slices/stewardSlice.js @@ -0,0 +1,16 @@ +import { createSlice } from "@reduxjs/toolkit"; +import { stewardExtraReducer } from "./stewardExtraReducers"; + +const initialState = { + pending: false, + modalState: false, +}; + +const slice = createSlice({ + name: "province", + initialState, + extraReducers: stewardExtraReducer, + reducers: {}, +}); + +export const { reducer: stewardSlice } = slice; diff --git a/src/lib/redux/slices/ticketExtraReducers.js b/src/lib/redux/slices/ticketExtraReducers.js new file mode 100644 index 0000000..f29eb87 --- /dev/null +++ b/src/lib/redux/slices/ticketExtraReducers.js @@ -0,0 +1,19 @@ +import { ticketGetCreatedTickets } from "../../../features/ticket/services/ticket-get-created-tickets"; +import { ticketGetOperatorTickets } from "../../../features/ticket/services/ticket-get-operator-tickets"; + +export const ticketExtraReducers = { + [ticketGetCreatedTickets.fulfilled]: (state, { payload }) => { + state.tickets = payload.data; + state.pending = false; + }, + [ticketGetCreatedTickets.pending]: (state) => { + state.pending = true; + }, + [ticketGetOperatorTickets.fulfilled]: (state, { payload }) => { + state.operatorTickets = payload.data; + state.pending = false; + }, + [ticketGetOperatorTickets.pending]: (state) => { + state.pending = true; + }, +}; diff --git a/src/lib/redux/slices/ticketSlice.js b/src/lib/redux/slices/ticketSlice.js new file mode 100644 index 0000000..b29abbb --- /dev/null +++ b/src/lib/redux/slices/ticketSlice.js @@ -0,0 +1,17 @@ +import { createSlice } from "@reduxjs/toolkit"; +import { ticketExtraReducers } from "./ticketExtraReducers"; + +const initialState = { + pending: false, + tickets: [], + operatorTickets: [], +}; + +const slice = createSlice({ + name: "tickets", + initialState, + extraReducers: ticketExtraReducers, + reducers: {}, +}); + +export const { reducer: ticketSlice } = slice; diff --git a/src/lib/redux/slices/userExtraReducers.js b/src/lib/redux/slices/userExtraReducers.js new file mode 100644 index 0000000..5f46ff3 --- /dev/null +++ b/src/lib/redux/slices/userExtraReducers.js @@ -0,0 +1,91 @@ +import { getUserMovingTextsService } from "../../../features/authentication/services/getUserMovingTexts"; +import { getUserProfile } from "../../../features/authentication/services/getUserProfile"; +import { getUserRoleInfo } from "../../../features/authentication/services/getUserRoleInfo"; +import { + changePassword, + checkUserPath, + loginSendMobile, + loginWithPassword, +} from "../../../features/authentication/services/login"; + +export const userExtraReducers = { + [loginSendMobile.fulfilled]: (state, { payload }) => { + state.pending = false; + }, + [loginSendMobile.pending]: (state) => { + state.pending = true; + }, + [loginWithPassword.fulfilled]: (state, { payload }) => { + state.pending = false; + state.authToken = payload.data.accessToken; + state.tokenExpiresIn = payload.data.expiresIn; + const filteredRoles = payload.data.role.filter( + (role) => role !== "ProvinceInspector" + ); + state.role = filteredRoles; + state.loginUserProfile = payload.data; + }, + [loginWithPassword.pending]: (state) => { + state.pending = true; + }, + [getUserProfile.fulfilled]: (state, { payload }) => { + state.pending = false; + state.userProfile = payload.data; + }, + [checkUserPath.pending]: (state) => { + state.pending = true; + }, + [checkUserPath.fulfilled]: (state, { payload }) => { + state.pending = false; + state.userPath = payload.data.backend + "/"; + }, + [getUserProfile.pending]: (state) => { + state.pending = true; + }, + [changePassword.fulfilled]: (state) => { + state.pending = false; + }, + [changePassword.pending]: (state) => { + state.pending = true; + }, + [changePassword.pending]: (state) => { + state.pending = true; + }, + [getUserMovingTextsService.fulfilled]: (state, { payload }) => { + let fulltext = ""; + if (payload.data.length) { + payload.data.forEach((element) => { + if (element !== "undefined") { + fulltext = + fulltext + + "‌‌‌‌‌‌‌‌‌‌‌‌‌‌‌‌‌‌‌‌‌‌‌‌‌‌‌‌‌‌‌‌‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌‌‌‌‌‌‌‌‌‌‌‌‌‌‌‌‌‌‌‌‌‌‌‌‌‌‌‌‌‌‌‌‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ " + + element?.movingText; + } + }); + } else { + fulltext = null; + } + state.pending = false; + state.userMovingTexts = fulltext; + }, + [getUserRoleInfo.fulfilled]: (state, { payload }) => { + state.pending = false; + if (payload.data && Array.isArray(payload.data)) { + state.subUsers = payload.data; + if (payload.data.length > 0) { + state.selectedSubUser = payload.data[0]; + } + } else { + state.subUsers = []; + state.selectedSubUser = null; + } + }, + [getUserRoleInfo.pending]: (state) => { + state.pending = true; + }, + [getUserRoleInfo.rejected]: (state) => { + state.pending = false; + state.subUsers = []; + state.selectedSubUser = null; + }, +}; diff --git a/src/lib/redux/slices/userReducers.js b/src/lib/redux/slices/userReducers.js new file mode 100644 index 0000000..296ace5 --- /dev/null +++ b/src/lib/redux/slices/userReducers.js @@ -0,0 +1,57 @@ +import storage from "redux-persist/lib/storage"; + +export const userReducers = { + LOG_OUT: (state, action) => { + storage.removeItem("persist:root"); + state.authToken = null; + state.isFirstLogin = true; + state.typeActivitySelected = null; + state = null; + // window.location.reload(); + + // Safe localStorage operations + try { + const dashboardOrder = localStorage.getItem("dashboard_custom_order"); + localStorage.clear(); + if (dashboardOrder) { + localStorage.setItem("dashboard_custom_order", dashboardOrder); + } + } catch (e) { + // Silent fail + } + }, + AUTO_SIGN_IN: (state, action) => { + state.authToken = action.payload.accessToken; + state.tokenExpiresIn = action.payload.expiresIn; + state.role = action.payload.role; + state.loginUserProfile = action.payload; + // localStorage.clear(); + }, + IS_FIRST_LOGIN: (state, action) => { + state.isFirstLogin = action.payload; + }, + SET_MEDIATOR_TEXT: (state, action) => { + state.mediatorText = action.payload; + }, + SET_SUBMENU_TEXT: (state, action) => { + state.subMenuText = action.payload; + }, + SET_USER_PATH: (state, action) => { + state.userPath = action.payload; + }, + SET_ADMIN_TOKEN: (state, action) => { + state.adminToken = action.payload; + }, + SET_TYPE_ACTIVITY_SELECTED: (state, action) => { + state.typeActivitySelected = action.payload; + }, + SET_SELECTED_ROLE: (state, action) => { + state.selectedRole = action.payload; + }, + SET_SELECTED_SUB_USER: (state, action) => { + state.selectedSubUser = action.payload; + }, + SET_SUB_USERS: (state, action) => { + state.subUsers = action.payload; + }, +}; diff --git a/src/lib/redux/slices/userSlice.js b/src/lib/redux/slices/userSlice.js new file mode 100644 index 0000000..c0b90d6 --- /dev/null +++ b/src/lib/redux/slices/userSlice.js @@ -0,0 +1,41 @@ +import { createSlice } from "@reduxjs/toolkit"; +import { userExtraReducers } from "./userExtraReducers"; +import { userReducers } from "./userReducers"; + +const initialState = { + statusModal: false, + typeActivitySelected: null, + pending: false, + authToken: null, + adminToken: null, + userProfile: {}, + loginUserProfile: {}, + role: null, + selectedRole: null, + selectedSubUser: null, + subUsers: [], + isFirstLogin: true, + userPath: "https://habackend.rasadyar.com/", +}; +const slice = createSlice({ + name: "user", + initialState, + reducers: userReducers, + extraReducers: userExtraReducers, +}); + +export const { + LOG_OUT, + AUTO_SIGN_IN, + IS_FIRST_LOGIN, + SET_MEDIATOR_TEXT, + SET_SUBMENU_TEXT, + SET_USER_PATH, + SET_ADMIN_TOKEN, + SET_TYPE_ACTIVITY_SELECTED, + SET_SELECTED_ROLE, + SET_SELECTED_SUB_USER, + SET_SUB_USERS, +} = slice.actions; +// export default slice.reducer; +export const { reducer: userSlice } = slice; diff --git a/src/lib/redux/slices/vetFarmExtraReducers.js b/src/lib/redux/slices/vetFarmExtraReducers.js new file mode 100644 index 0000000..75fe738 --- /dev/null +++ b/src/lib/redux/slices/vetFarmExtraReducers.js @@ -0,0 +1,47 @@ +import { vetFarmGetAllocatedService } from "../../../features/vet-farm/services/vet-farm-get-allocated"; +import { + parentCompanyGetBarsOverview, + vetFarmGetBarsOverview, +} from "../../../features/vet-farm/services/vet-farm-get-bars-overview"; +import { vetFarmGetDeletedBarsService } from "../../../features/vet-farm/services/vet-farm-get-deleted-bars"; +import { getVetFarms } from "../../../features/vet-farm/services/vet-farm-get-farms"; +import { getVetFarmInspectionHistory } from "../../../features/vet-farm/services/vet-farm-get-inspection-history"; +import { vetFarmGetOutOfProvinceRequests } from "../../../features/vet-farm/services/vet-farm-get-out-of-province-requests"; +import { vatFarmGetProfile } from "../../../features/vet-farm/services/vet-farm-get-profile"; + +export const vetFarmExtraReducers = { + [getVetFarms.fulfilled]: (state, { payload }) => { + state.vetFarms = payload.data; + state.pending = false; + }, + [getVetFarms.pending]: (state) => { + state.pending = true; + }, + [getVetFarmInspectionHistory.fulfilled]: (state, { payload }) => { + state.vetFarmInspectionHistory = payload.data; + state.pending = false; + }, + [getVetFarmInspectionHistory.pending]: (state) => { + state.pending = true; + }, + [vatFarmGetProfile.fulfilled]: (state, { payload }) => { + state.profile = payload.data; + state.pending = false; + }, + [vetFarmGetAllocatedService.fulfilled]: (state, { payload }) => { + state.vetFarmGetAllocated = payload.data; + state.pending = false; + }, + [vetFarmGetDeletedBarsService.fulfilled]: (state, { payload }) => { + state.vetFarmGetDeletedBars = payload.data; + }, + [vetFarmGetOutOfProvinceRequests.fulfilled]: (state, { payload }) => { + state.vetOutOfProvinceRequests = payload.data; + }, + [vetFarmGetBarsOverview.fulfilled]: (state, { payload }) => { + state.vetFarmBarsOverview = payload.data; + }, + [parentCompanyGetBarsOverview.fulfilled]: (state, { payload }) => { + state.parentCompanyBarsOverview = payload.data; + }, +}; diff --git a/src/lib/redux/slices/vetFarmSlice.js b/src/lib/redux/slices/vetFarmSlice.js new file mode 100644 index 0000000..ffa8ace --- /dev/null +++ b/src/lib/redux/slices/vetFarmSlice.js @@ -0,0 +1,18 @@ +import { createSlice } from "@reduxjs/toolkit"; +import { vetFarmExtraReducers } from "./vetFarmExtraReducers"; + +const initialState = { + pending: false, + provinceNewRequests: null, + provincePrices: null, + profile: null, +}; + +const slice = createSlice({ + name: "vatFarm", + initialState, + extraReducers: vetFarmExtraReducers, + reducers: {}, +}); + +export const { reducer: vetFarmSlice } = slice; diff --git a/src/lib/redux/store.js b/src/lib/redux/store.js new file mode 100644 index 0000000..722b36a --- /dev/null +++ b/src/lib/redux/store.js @@ -0,0 +1,62 @@ +import { configureStore, combineReducers } from "@reduxjs/toolkit"; +import storage from "redux-persist/lib/storage"; +import { persistReducer, persistStore } from "redux-persist"; +import thunk from "redux-thunk"; +import { userSlice } from "./slices/userSlice"; +import { appSlice } from "./slices/appSlice"; +import { avicultureSlice } from "./slices/avicultureSlice"; +import { citySlice } from "./slices/citySlice"; +import { slaughterSlice } from "./slices/slaughterSlice"; +import { provinceSlice } from "./slices/provinceSlice"; +import { fileSlice } from "./slices/fileSlice"; +import { vetFarmSlice } from "./slices/vetFarmSlice"; +import { auctionSlice } from "./slices/auctionSlice"; +import { driverSlice } from "./slices/driverSlice"; +import { provinceFinancialSlice } from "./slices/provinceFinancialSlice"; +import { messageSlice } from "./slices/messageSlice"; +import { inspectorSlice } from "./slices/inspectorSlice"; +import { slaughterHouseVetSlice } from "./slices/slaughterHouseVetSlice"; +import { ticketSlice } from "./slices/ticketSlice"; +import { generalSlice } from "./slices/generalSlice"; +import { adminSlice } from "./slices/adminSlice"; +import { jahadSlice } from "./slices/jahadSlice"; +import { liveStockSlice } from "./slices/liveStockSlice"; +import { stewardSlice } from "./slices/stewardSlice"; + +const reducer = combineReducers({ + userSlice, + appSlice, + avicultureSlice, + citySlice, + slaughterSlice, + provinceSlice, + fileSlice, + vetFarmSlice, + auctionSlice, + driverSlice, + provinceFinancialSlice, + messageSlice, + inspectorSlice, + slaughterHouseVetSlice, + ticketSlice, + generalSlice, + adminSlice, + jahadSlice, + liveStockSlice, + stewardSlice, +}); + +const persistConfig = { + key: "root", + storage, +}; + +const persistedReducer = persistReducer(persistConfig, reducer); + +export const store = configureStore({ + reducer: persistedReducer, + // devTools: process.env.NODE_ENV !== 'production', + middleware: [thunk], +}); + +export const persistor = persistStore(store); diff --git a/src/lib/yup/yup.js b/src/lib/yup/yup.js new file mode 100644 index 0000000..4f77873 --- /dev/null +++ b/src/lib/yup/yup.js @@ -0,0 +1,3 @@ +import * as Yup from "yup"; + +export { Yup }; diff --git a/src/pages/AccessDashboard.js b/src/pages/AccessDashboard.js new file mode 100644 index 0000000..8454606 --- /dev/null +++ b/src/pages/AccessDashboard.js @@ -0,0 +1,1076 @@ +import React, { useContext, useEffect, useState } from "react"; +import { + Grid, + Card, + Chip, + Divider, + Box, + Typography, + Autocomplete, + TextField, + IconButton, + Tooltip, + // ToggleButton, + // ToggleButtonGroup, +} from "@mui/material"; +import { useNavigate } from "react-router-dom"; +import { useDispatch, useSelector } from "react-redux"; +import { getRoleItems } from "../utils/getRolesItems"; +import { getFaUserRole } from "../utils/getFaUserRole"; +import { sortRoles } from "../utils/sortRoles"; +import { getUserProfile } from "../features/authentication/services/getUserProfile"; +import { AppContext } from "../contexts/AppContext"; +import { getLiveStockItems } from "../utils/getLivestock"; +import { + getBarSquareRoles, + getLiveStockRoles, + getPoultryRoles, + getUserTypeOfActivity, +} from "../utils/getUserTypeOfActivity"; +// import poultry from "../assets/images/poultry.png"; +// import livestock from "../assets/images/livestock.png"; +// import livestockColor from "../assets/images/livestockColor.png"; +// import poultryColor from "../assets/images/poultryColor.png"; +// import barSquare from "../assets/images/barSquare.png"; +// import barSquareColor from "../assets/images/barSquareColor.png"; + +// import { SET_TYPE_ACTIVITY_SELECTED } from "../lib/redux/slices/userSlice"; +import { getBarSquareItems } from "../utils/getBarSquareItems"; +import { trackItemClick } from "../utils/usageTracker"; +import { + applyCustomOrder, + saveRoleCustomOrder, + reorderArray, +} from "../utils/dashboardCustomization"; +import EditIcon from "@mui/icons-material/Edit"; +import SaveIcon from "@mui/icons-material/Save"; +import { Check, OpenWith } from "@mui/icons-material"; +import { SlaughterBalanceStatusButton } from "../features/slaughter-house/components/slaughter-balance-status-button/SlaughterBalanceStatusButton"; + +// Function to convert numbers to Persian numerals + +const AccessDashboard = () => { + const [openNotif] = useContext(AppContext); + const navigate = useNavigate(); + const userRoles = useSelector((state) => state.userSlice.role); + // const userInfo = useSelector( + // (state) => state.userSlice.loginUserProfile.mobile + // ); + const { typeActivitySelected } = useSelector((state) => state.userSlice); + const dispatch = useDispatch(); + const [autocompleteValue, setAutocompleteValue] = React.useState(null); + + const [editModes, setEditModes] = useState({}); + + const [draggedItems, setDraggedItems] = useState({}); + + const [draggingCardIndex, setDraggingCardIndex] = useState(null); + + useEffect(() => { + dispatch(getUserProfile()); + }, []); + + const getInitialSelection = () => { + if (typeActivitySelected) { + return typeActivitySelected; + } + if (getUserTypeOfActivity(userRoles) === "LiveStock") { + return "Livestock"; + } + return "Poultry"; + }; + + const [selected] = useState(getInitialSelection()); + + // const handleSelection = (event, newSelection) => { + // if (newSelection !== null) { + // setSelected(newSelection); + // dispatch(SET_TYPE_ACTIVITY_SELECTED(newSelection)); + // } + // }; + + const autocompleteItems = []; + if (userRoles) { + for (const role of userRoles) { + const items = getRoleItems(role); + items.forEach((item) => { + autocompleteItems.push({ ...item, role }); + }); + + const liveStockItems = getLiveStockItems(role); + liveStockItems.forEach((item) => { + autocompleteItems.push({ ...item, role }); + }); + } + } + + const handleAutocompleteChange = (event, value) => { + setAutocompleteValue(null); + if (value?.route) { + trackItemClick(value.role, value.route); + setTimeout(() => navigate(value.route), 0); + } + }; + + const handleCardClick = (roleItem, role) => { + if (editModes[role]) return; + + if (roleItem?.disabled) { + openNotif({ + vertical: "top", + horizontal: "center", + msg: roleItem.disabledText || "این بخش در دست توسعه است !", + severity: "error", + }); + } else { + trackItemClick(role, roleItem.route); + navigate(roleItem.route); + } + }; + + const toggleEditMode = (role, items) => { + const isEnteringEditMode = !editModes[role]; + + if (isEnteringEditMode) { + setEditModes({ ...editModes, [role]: true }); + setDraggedItems({ ...draggedItems, [role]: items }); + } else { + saveRoleCustomOrder(role, draggedItems[role]); + setEditModes({ ...editModes, [role]: false }); + openNotif({ + vertical: "top", + horizontal: "center", + msg: "ترتیب کارت‌ها ذخیره شد", + severity: "success", + }); + } + }; + + const handleCardMouseDown = (index) => { + setDraggingCardIndex(index); + }; + + const handleCardMouseUp = () => { + setDraggingCardIndex(null); + }; + + const handleDragStart = (e, index) => { + e.dataTransfer.effectAllowed = "move"; + e.dataTransfer.setData("text/html", index); + setDraggingCardIndex(index); + }; + + const handleDragOver = (e) => { + e.preventDefault(); + e.dataTransfer.dropEffect = "move"; + }; + + const handleDrop = (e, role, dropIndex) => { + e.preventDefault(); + const dragIndex = parseInt(e.dataTransfer.getData("text/html")); + + if (dragIndex === dropIndex) return; + + const currentItems = draggedItems[role] || []; + const reorderedItems = reorderArray(currentItems, dragIndex, dropIndex); + + setDraggedItems({ ...draggedItems, [role]: reorderedItems }); + }; + + const handleDragEnd = () => { + setDraggingCardIndex(null); + }; + + const getItemsForRole = (items, role) => { + if (editModes[role] && draggedItems[role]) { + return draggedItems[role]; + } + + return applyCustomOrder(items, role); + }; + + const renderContent = () => { + if (selected === "Poultry") { + return renderPoultrySection(); + } + if (selected === "Livestock") { + return renderLivestockSection(); + } + return renderBarSquareSection(); + }; + + return ( + <> + {} + + + + ({ + label: item.text, + route: item.route, + role: item.role, + disabled: item.disabled || false, + index, + }))} + groupBy={(option) => + userRoles?.length !== 1 ? getFaUserRole(option.role) : false + } + getOptionDisabled={(option) => option.disabled} + getOptionLabel={(option) => option.label || ""} + value={autocompleteValue} + onChange={handleAutocompleteChange} + onClose={() => setAutocompleteValue(null)} + renderInput={(params) => ( + + )} + renderOption={(props, option) => ( + + {option.label} + + )} + style={{ + backgroundColor: "white", + borderRadius: 4, + }} + /> + {userRoles && userRoles.includes("KillHouse") && ( + + )} + {/* + {getUserTypeOfActivity(userRoles) === "Both" && ( + + + + poultry + طیور + + + + livestock + دام + + {userInfo === "09011110911" && ( + + barSquare + میدان بار + + )} + + + )} + */} + + + {renderContent()} + + + + ); + + function renderPoultrySection() { + return ( + + {sortRoles(getPoultryRoles(userRoles))?.map((item, i) => ( + + + + + + toggleEditMode( + item, + getItemsForRole(getRoleItems(item), item) + ) + } + sx={{ + position: "absolute", + top: 2, + right: 0, + zIndex: 10, + backgroundColor: editModes[item] + ? "success.main" + : "primary.main", + color: "white", + "&:hover": { + backgroundColor: editModes[item] + ? "success.dark" + : "primary.dark", + }, + width: 24, + height: 24, + }} + size="small" + > + {editModes[item] ? ( + + ) : ( + + )} + + + + + + + + + + {getItemsForRole(getRoleItems(item), item)?.map( + (roleItem, index) => ( + + + editModes[item] && handleDragStart(e, index) + } + onDragEnd={handleDragEnd} + onDragOver={(e) => editModes[item] && handleDragOver(e)} + onDrop={(e) => + editModes[item] && handleDrop(e, item, index) + } + onMouseDown={() => + editModes[item] && handleCardMouseDown(index) + } + onMouseUp={handleCardMouseUp} + onTouchStart={() => + editModes[item] && handleCardMouseDown(index) + } + onTouchEnd={handleCardMouseUp} + sx={{ + width: "100%", + aspectRatio: "1/1", + borderRadius: "8px", + display: "flex", + alignItems: "center", + justifyContent: "center", + textAlign: "center", + cursor: editModes[item] ? "move" : "pointer", + transition: + "transform 0.2s ease-in-out, box-shadow 0.2s ease-in-out", + position: "relative", + backgroundSize: "cover", + backgroundPosition: "center", + color: (theme) => theme.palette.primary.main, + borderStyle: "solid", + borderWidth: "1px", + borderColor: (theme) => theme.palette.primary.main, + opacity: editModes[item] ? 0.9 : 1, + "&:hover": { + transform: editModes[item] + ? "scale(1.02)" + : "scale(1.05)", + boxShadow: "0 4px 12px rgba(0,0,0,0.15)", + backgroundColor: (theme) => + theme.palette.primary.light, + }, + }} + onClick={() => handleCardClick(roleItem, item)} + > + {} + {editModes[item] && ( + + + + )} + + {roleItem.icon && ( + + {React.cloneElement(roleItem.icon, { + sx: { + fontSize: { + xs: "2rem", + sm: "2.5rem", + xxl: "2.8rem", + xxxl: "3.2rem", + }, + }, + })} + + )} + theme.palette.primary.dark, + }} + > + {roleItem.text} + + + + + ) + )} + + + + ))} + + ); + } + + function renderLivestockSection() { + return ( + + {sortRoles(getLiveStockRoles(userRoles))?.map((item, i) => ( + + + + + + toggleEditMode( + item, + getItemsForRole(getLiveStockItems(item), item) + ) + } + sx={{ + position: "absolute", + top: -8, + right: 8, + zIndex: 10, + backgroundColor: editModes[item] + ? "success.main" + : "primary.main", + color: "white", + "&:hover": { + backgroundColor: editModes[item] + ? "success.dark" + : "primary.dark", + }, + width: 32, + height: 32, + }} + size="small" + > + {editModes[item] ? ( + + ) : ( + + )} + + + + + + + + + + {getItemsForRole(getLiveStockItems(item), item)?.map( + (roleItem, index) => ( + + + editModes[item] && handleDragStart(e, index) + } + onDragEnd={handleDragEnd} + onDragOver={(e) => editModes[item] && handleDragOver(e)} + onDrop={(e) => + editModes[item] && handleDrop(e, item, index) + } + onMouseDown={() => + editModes[item] && handleCardMouseDown(index) + } + onMouseUp={handleCardMouseUp} + onTouchStart={() => + editModes[item] && handleCardMouseDown(index) + } + onTouchEnd={handleCardMouseUp} + sx={{ + width: "100%", + aspectRatio: "1/1", + borderRadius: "8px", + display: "flex", + alignItems: "center", + justifyContent: "center", + textAlign: "center", + cursor: editModes[item] ? "move" : "pointer", + transition: + "transform 0.2s ease-in-out, box-shadow 0.2s ease-in-out", + position: "relative", + backgroundSize: "cover", + backgroundPosition: "center", + color: (theme) => theme.palette.info.main, + borderStyle: "solid", + borderWidth: "1px", + borderColor: (theme) => theme.palette.primary.main, + opacity: editModes[item] ? 0.9 : 1, + "&:hover": { + transform: editModes[item] + ? "scale(1.02)" + : "scale(1.05)", + boxShadow: "0 4px 12px rgba(0,0,0,0.15)", + backgroundColor: (theme) => + theme.palette.primary.light, + }, + }} + onClick={() => handleCardClick(roleItem, item)} + > + {} + {editModes[item] && ( + + + + )} + + {roleItem.icon && ( + + {React.cloneElement(roleItem.icon, { + sx: { + fontSize: { + xs: "2rem", + sm: "2.5rem", + }, + }, + })} + + )} + theme.palette.primary.dark, + }} + > + {roleItem.text} + + + + + ) + )} + + + + ))} + + ); + } + + function renderBarSquareSection() { + return ( + + {sortRoles(getBarSquareRoles(["BarSquareProvinceJahad"]))?.map( + (item, i) => ( + + + + + + toggleEditMode( + item, + getItemsForRole(getBarSquareItems(item), item) + ) + } + sx={{ + position: "absolute", + top: -8, + right: 8, + zIndex: 10, + backgroundColor: editModes[item] + ? "success.main" + : "primary.main", + color: "white", + "&:hover": { + backgroundColor: editModes[item] + ? "success.dark" + : "primary.dark", + }, + width: 32, + height: 32, + }} + size="small" + > + {editModes[item] ? ( + + ) : ( + + )} + + + + + + + + + + {getItemsForRole(getBarSquareItems(item), item)?.map( + (roleItem, index) => ( + + + editModes[item] && handleDragStart(e, index) + } + onDragEnd={handleDragEnd} + onDragOver={(e) => + editModes[item] && handleDragOver(e) + } + onDrop={(e) => + editModes[item] && handleDrop(e, item, index) + } + onMouseDown={() => + editModes[item] && handleCardMouseDown(index) + } + onMouseUp={handleCardMouseUp} + onTouchStart={() => + editModes[item] && handleCardMouseDown(index) + } + onTouchEnd={handleCardMouseUp} + onClick={() => handleCardClick(roleItem, item)} + sx={{ + width: "100%", + aspectRatio: "1/1", + borderRadius: "8px", + display: "flex", + alignItems: "center", + justifyContent: "center", + textAlign: "center", + cursor: editModes[item] ? "move" : "pointer", + transition: + "transform 0.2s ease-in-out, box-shadow 0.2s ease-in-out", + position: "relative", + backgroundSize: "cover", + backgroundPosition: "center", + color: "orange", + borderStyle: "solid", + borderWidth: "1px", + borderColor: (theme) => theme.palette.primary.main, + opacity: editModes[item] ? 0.9 : 1, + "&:hover": { + transform: editModes[item] + ? "scale(1.02)" + : "scale(1.05)", + boxShadow: "0 4px 12px rgba(0,0,0,0.15)", + backgroundColor: (theme) => + theme.palette.primary.light, + }, + }} + > + + {roleItem.icon && ( + + {React.cloneElement(roleItem.icon, { + sx: { + fontSize: { + xs: "2rem", + sm: "2.5rem", + lg: "3rem", + }, + }, + })} + + )} + theme.palette.primary.dark, + }} + > + {roleItem.text} + + + + + ) + )} + + + + ) + )} + + ); + } +}; + +export default AccessDashboard; diff --git a/src/pages/AcessDashboardV2.js b/src/pages/AcessDashboardV2.js new file mode 100644 index 0000000..2a62914 --- /dev/null +++ b/src/pages/AcessDashboardV2.js @@ -0,0 +1,1434 @@ +import React, { useContext, useEffect, useState } from "react"; +import { + Grid, + Card, + Chip, + Divider, + Box, + Typography, + IconButton, + Tooltip, + Dialog, + DialogTitle, + DialogContent, + Button, + Select, + MenuItem, + FormControl, + InputLabel, + Skeleton, +} from "@mui/material"; +import { useNavigate } from "react-router-dom"; +import { useDispatch, useSelector } from "react-redux"; +import { getRoleItems } from "../utils/getRolesItems"; +import { getFaUserRole } from "../utils/getFaUserRole"; +import { sortRoles } from "../utils/sortRoles"; +import { getUserProfile } from "../features/authentication/services/getUserProfile"; +import { getUserRoleInfo } from "../features/authentication/services/getUserRoleInfo"; +import { AppContext } from "../contexts/AppContext"; +import { getLiveStockItems } from "../utils/getLivestock"; +import { + getBarSquareRoles, + getLiveStockRoles, + getPoultryRoles, + getUserTypeOfActivity, +} from "../utils/getUserTypeOfActivity"; + +import { + SET_SELECTED_ROLE, + SET_SELECTED_SUB_USER, + SET_SUB_USERS, +} from "../lib/redux/slices/userSlice"; +import { getBarSquareItems } from "../utils/getBarSquareItems"; +import { trackItemClick } from "../utils/usageTracker"; +import { + applyCustomOrder, + saveRoleCustomOrder, + reorderArray, +} from "../utils/dashboardCustomization"; +import EditIcon from "@mui/icons-material/Edit"; +import SaveIcon from "@mui/icons-material/Save"; +import { Check, OpenWith } from "@mui/icons-material"; +import FolderOffIcon from "@mui/icons-material/FolderOff"; +import { SlaughterBalanceStatusButton } from "../features/slaughter-house/components/slaughter-balance-status-button/SlaughterBalanceStatusButton"; + +const AccessDashboardV2 = () => { + const [openNotif] = useContext(AppContext); + const navigate = useNavigate(); + const userRoles = useSelector((state) => state.userSlice.role); + const { + typeActivitySelected, + selectedRole, + userProfile, + loginUserProfile, + subUsers: reduxSubUsers, + selectedSubUser: reduxSelectedSubUser, + } = useSelector((state) => state.userSlice); + const dispatch = useDispatch(); + + const [editModes, setEditModes] = useState({}); + + const [draggedItems, setDraggedItems] = useState({}); + + const [draggingCardIndex, setDraggingCardIndex] = useState(null); + + const [roleSelectionModalOpen, setRoleSelectionModalOpen] = useState(false); + const [selectedRoleLocal, setSelectedRoleLocal] = useState(selectedRole); + const [subUsers, setSubUsers] = useState([]); + const [selectedSubUser, setSelectedSubUser] = useState(null); + const [isLoading, setIsLoading] = useState(false); + + useEffect(() => { + dispatch(getUserProfile()); + }, []); + + useEffect(() => { + if (userRoles && userRoles.length > 0 && !selectedRole) { + if (userRoles.length === 1) { + const role = userRoles[0]; + dispatch(SET_SELECTED_ROLE(role)); + setSelectedRoleLocal(role); + setRoleSelectionModalOpen(false); + + const rolesNeedingSubUsers = ["Steward", "KillHouse", "Guilds"]; + if (rolesNeedingSubUsers.includes(role)) { + const userKey = userProfile?.key || loginUserProfile?.key; + if (userKey && role) { + dispatch(getUserRoleInfo({ userKey, role })).catch((error) => { + console.error("Error fetching user role info:", error); + }); + } + } + } else { + setRoleSelectionModalOpen(true); + } + } + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [userRoles, selectedRole]); + + useEffect(() => { + if (selectedRole) { + const rolesNeedingSubUsers = ["Steward", "KillHouse", "Guilds"]; + if (rolesNeedingSubUsers.includes(selectedRole)) { + if (reduxSubUsers && reduxSubUsers.length > 0) { + const subUsersKeys = subUsers.map((u) => u?.key).join(","); + const reduxSubUsersKeys = reduxSubUsers.map((u) => u?.key).join(","); + if (subUsersKeys !== reduxSubUsersKeys) { + setSubUsers(reduxSubUsers); + } + + if (reduxSelectedSubUser) { + if (selectedSubUser?.key !== reduxSelectedSubUser?.key) { + setSelectedSubUser(reduxSelectedSubUser); + } + } else if (reduxSubUsers.length > 0) { + const firstSubUser = reduxSubUsers[0]; + if (selectedSubUser?.key !== firstSubUser?.key) { + setSelectedSubUser(firstSubUser); + dispatch(SET_SELECTED_SUB_USER(firstSubUser)); + } + } + setIsLoading(false); + } else { + if (subUsers.length > 0 || selectedSubUser) { + setSubUsers([]); + setSelectedSubUser(null); + } + setIsLoading(true); + } + } else { + if (subUsers.length > 0 || selectedSubUser) { + setSubUsers([]); + setSelectedSubUser(null); + dispatch(SET_SUB_USERS([])); + } + setIsLoading(false); + } + } else { + if (subUsers.length > 0 || selectedSubUser) { + setSubUsers([]); + setSelectedSubUser(null); + dispatch(SET_SUB_USERS([])); + } + setIsLoading(false); + } + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [selectedRole, reduxSubUsers, reduxSelectedSubUser]); + + const getInitialSelection = () => { + if (typeActivitySelected) { + return typeActivitySelected; + } + if (getUserTypeOfActivity(userRoles) === "LiveStock") { + return "Livestock"; + } + return "Poultry"; + }; + + const [selected] = useState(getInitialSelection()); + + const handleRoleSelection = async (role) => { + setSelectedRoleLocal(role); + dispatch(SET_SELECTED_ROLE(role)); + setRoleSelectionModalOpen(false); + + setSubUsers([]); + setSelectedSubUser(null); + dispatch(SET_SUB_USERS([])); + + const rolesNeedingSubUsers = ["Steward", "KillHouse", "Guilds"]; + if (rolesNeedingSubUsers.includes(role)) { + setIsLoading(true); + const userKey = userProfile?.key || loginUserProfile?.key; + if (userKey && role) { + try { + await dispatch(getUserRoleInfo({ userKey, role })).unwrap(); + } catch (error) { + console.error("Error fetching user role info:", error); + setIsLoading(false); + openNotif({ + vertical: "top", + horizontal: "center", + msg: "خطا در دریافت اطلاعات نقش کاربر", + severity: "error", + }); + } + } else { + setIsLoading(false); + } + } + }; + + const handleSubUserChange = (event) => { + const subUserKey = event.target.value; + const subUser = subUsers.find((u) => u.key === subUserKey); + setSelectedSubUser(subUser); + dispatch(SET_SELECTED_SUB_USER(subUser)); + + setIsLoading(true); + setTimeout(() => { + setIsLoading(false); + }, 1000); + }; + + const handleCardClick = (roleItem, role) => { + if (editModes[role]) return; + + if (roleItem?.disabled) { + openNotif({ + vertical: "top", + horizontal: "center", + msg: roleItem.disabledText || "این بخش در دست توسعه است !", + severity: "error", + }); + } else { + trackItemClick(role, roleItem.route); + navigate(roleItem.route); + } + }; + + const toggleEditMode = (role, items) => { + const isEnteringEditMode = !editModes[role]; + + if (isEnteringEditMode) { + setEditModes({ ...editModes, [role]: true }); + setDraggedItems({ ...draggedItems, [role]: items }); + } else { + saveRoleCustomOrder(role, draggedItems[role]); + setEditModes({ ...editModes, [role]: false }); + openNotif({ + vertical: "top", + horizontal: "center", + msg: "ترتیب کارت‌ها ذخیره شد", + severity: "success", + }); + } + }; + + const handleCardMouseDown = (index) => { + setDraggingCardIndex(index); + }; + + const handleCardMouseUp = () => { + setDraggingCardIndex(null); + }; + + const handleDragStart = (e, index) => { + e.dataTransfer.effectAllowed = "move"; + e.dataTransfer.setData("text/html", index); + setDraggingCardIndex(index); + }; + + const handleDragOver = (e) => { + e.preventDefault(); + e.dataTransfer.dropEffect = "move"; + }; + + const handleDrop = (e, role, dropIndex) => { + e.preventDefault(); + const dragIndex = parseInt(e.dataTransfer.getData("text/html")); + + if (dragIndex === dropIndex) return; + + const currentItems = draggedItems[role] || []; + const reorderedItems = reorderArray(currentItems, dragIndex, dropIndex); + + setDraggedItems({ ...draggedItems, [role]: reorderedItems }); + }; + + const handleDragEnd = () => { + setDraggingCardIndex(null); + }; + + const getItemsForRole = (items, role) => { + if (editModes[role] && draggedItems[role]) { + return draggedItems[role]; + } + + return applyCustomOrder(items, role); + }; + + function renderSkeletonCards(count = 6) { + return ( + + {Array.from({ length: count }).map((_, i) => ( + + + + + {Array.from({ length: 6 }).map((_, idx) => ( + + + + ))} + + + + ))} + + ); + } + + const renderContent = () => { + if (!selectedRole) { + return null; + } + + const filteredRoles = + userRoles?.filter((role) => role === selectedRole) || []; + + if (selected === "Poultry") { + return renderPoultrySection(filteredRoles); + } + if (selected === "Livestock") { + return renderLivestockSection(filteredRoles); + } + return renderBarSquareSection(filteredRoles); + }; + + const sortRolesByPriority = (roles) => { + const priorityOrder = [ + "SuperAdmin", + "AdminX", + "Admin", + "ProvinceOperator", + "ProvincialGovernment", + "Jahad", + "LiveStockProvinceJahad", + "CityJahad", + "ProvinceFinancial", + "Commerce", + "CityCommerce", + "KillHouse", + "Guilds", + "Steward", + "ColdHouseSteward", + "GuildRoom", + "CityGuild", + "VetSupervisor", + "KillHouseVet", + "VetFarm", + "CityVet", + "ParentCompany", + "ChainCompany", + "PosCompany", + "ProvinceSupervisor", + "ProvinceInspector", + "Observatory", + "CityOperator", + "CityPoultry", + "UnitWindow", + "Union", + "Cooperative", + "Rancher", + "LiveStockSupport", + "Poultry", + "PoultryScience", + "Dispenser", + "Supporter", + "Driver", + ]; + + return [...roles].sort((a, b) => { + const aIndex = priorityOrder.indexOf(a); + const bIndex = priorityOrder.indexOf(b); + if (aIndex !== -1 && bIndex !== -1) { + return aIndex - bIndex; + } + if (aIndex !== -1) return -1; + if (bIndex !== -1) return 1; + return a.localeCompare(b); + }); + }; + + const getRolePageCount = (role) => { + const roleItems = getRoleItems(role) || []; + const liveStockItems = getLiveStockItems(role) || []; + return roleItems.length + liveStockItems.length; + }; + + const availableRoles = userRoles ? sortRolesByPriority(userRoles) : []; + + return ( + <> + {availableRoles.length > 1 && ( + {}} + disableEscapeKeyDown + PaperProps={{ + sx: { + width: "670px", + maxWidth: "90vw", + }, + }} + > + انتخاب نقش کاربر + + + لطفاً نقش خود را انتخاب کنید: + + + {availableRoles.map((role) => ( + + + + + + ))} + + + + )} + + + + + + + {availableRoles.length > 1 && ( + + نقش + + + )} + + {subUsers.length > 1 && ( + + + {selectedRole === "Steward" + ? "مباشر" + : selectedRole === "Guilds" + ? "صنف" + : "کشتارگاه"} + + + + )} + + {userRoles && userRoles.includes("KillHouse") && ( + + )} + + + {renderContent()} + + + + ); + + function renderPoultrySection(filteredRoles = userRoles) { + const poultryRoles = getPoultryRoles(filteredRoles); + if (isLoading) { + return renderSkeletonCards(poultryRoles?.length || 1); + } + + if (!poultryRoles || poultryRoles.length === 0) { + return ( + + + + + هیچ دسترسی برای این نقش وجود ندارد + + + + ); + } + + return ( + + {sortRoles(poultryRoles)?.map((item, i) => ( + + + + + + toggleEditMode( + item, + getItemsForRole(getRoleItems(item), item) + ) + } + sx={{ + position: "absolute", + top: 2, + right: 0, + zIndex: 10, + backgroundColor: editModes[item] + ? "success.main" + : "primary.main", + color: "white", + "&:hover": { + backgroundColor: editModes[item] + ? "success.dark" + : "primary.dark", + }, + width: 24, + height: 24, + }} + size="small" + > + {editModes[item] ? ( + + ) : ( + + )} + + + + + + + + + + {getItemsForRole(getRoleItems(item), item)?.map( + (roleItem, index) => ( + + + editModes[item] && handleDragStart(e, index) + } + onDragEnd={handleDragEnd} + onDragOver={(e) => editModes[item] && handleDragOver(e)} + onDrop={(e) => + editModes[item] && handleDrop(e, item, index) + } + onMouseDown={() => + editModes[item] && handleCardMouseDown(index) + } + onMouseUp={handleCardMouseUp} + onTouchStart={() => + editModes[item] && handleCardMouseDown(index) + } + onTouchEnd={handleCardMouseUp} + sx={{ + width: "100%", + aspectRatio: "1/1", + borderRadius: "8px", + display: "flex", + alignItems: "center", + justifyContent: "center", + textAlign: "center", + cursor: editModes[item] ? "move" : "pointer", + transition: + "transform 0.2s ease-in-out, box-shadow 0.2s ease-in-out", + position: "relative", + backgroundSize: "cover", + backgroundPosition: "center", + color: (theme) => theme.palette.primary.main, + borderStyle: "solid", + borderWidth: "1px", + borderColor: (theme) => theme.palette.primary.main, + opacity: editModes[item] ? 0.9 : 1, + "&:hover": { + transform: editModes[item] + ? "scale(1.02)" + : "scale(1.05)", + boxShadow: "0 4px 12px rgba(0,0,0,0.15)", + backgroundColor: (theme) => + theme.palette.primary.light, + }, + }} + onClick={() => handleCardClick(roleItem, item)} + > + {editModes[item] && ( + + + + )} + + {roleItem.icon && ( + + {React.cloneElement(roleItem.icon, { + sx: { + fontSize: { + xs: "2rem", + sm: "2.5rem", + xxl: "2.8rem", + xxxl: "3.2rem", + }, + }, + })} + + )} + theme.palette.primary.dark, + }} + > + {roleItem.text} + + + + + ) + )} + + + + ))} + + ); + } + + function renderLivestockSection(filteredRoles = userRoles) { + const livestockRoles = getLiveStockRoles(filteredRoles); + if (isLoading) { + return renderSkeletonCards(livestockRoles?.length || 1); + } + + if (!livestockRoles || livestockRoles.length === 0) { + return ( + + + + + هیچ صفحه‌ای برای این نقش وجود ندارد + + + + ); + } + + return ( + + {sortRoles(livestockRoles)?.map((item, i) => ( + + + + + + toggleEditMode( + item, + getItemsForRole(getLiveStockItems(item), item) + ) + } + sx={{ + position: "absolute", + top: -8, + right: 8, + zIndex: 10, + backgroundColor: editModes[item] + ? "success.main" + : "primary.main", + color: "white", + "&:hover": { + backgroundColor: editModes[item] + ? "success.dark" + : "primary.dark", + }, + width: 32, + height: 32, + }} + size="small" + > + {editModes[item] ? ( + + ) : ( + + )} + + + + + + + + + + {getItemsForRole(getLiveStockItems(item), item)?.map( + (roleItem, index) => ( + + + editModes[item] && handleDragStart(e, index) + } + onDragEnd={handleDragEnd} + onDragOver={(e) => editModes[item] && handleDragOver(e)} + onDrop={(e) => + editModes[item] && handleDrop(e, item, index) + } + onMouseDown={() => + editModes[item] && handleCardMouseDown(index) + } + onMouseUp={handleCardMouseUp} + onTouchStart={() => + editModes[item] && handleCardMouseDown(index) + } + onTouchEnd={handleCardMouseUp} + sx={{ + width: "100%", + aspectRatio: "1/1", + borderRadius: "8px", + display: "flex", + alignItems: "center", + justifyContent: "center", + textAlign: "center", + cursor: editModes[item] ? "move" : "pointer", + transition: + "transform 0.2s ease-in-out, box-shadow 0.2s ease-in-out", + position: "relative", + backgroundSize: "cover", + backgroundPosition: "center", + color: (theme) => theme.palette.info.main, + borderStyle: "solid", + borderWidth: "1px", + borderColor: (theme) => theme.palette.primary.main, + opacity: editModes[item] ? 0.9 : 1, + "&:hover": { + transform: editModes[item] + ? "scale(1.02)" + : "scale(1.05)", + boxShadow: "0 4px 12px rgba(0,0,0,0.15)", + backgroundColor: (theme) => + theme.palette.primary.light, + }, + }} + onClick={() => handleCardClick(roleItem, item)} + > + {editModes[item] && ( + + + + )} + + {roleItem.icon && ( + + {React.cloneElement(roleItem.icon, { + sx: { + fontSize: { + xs: "2rem", + sm: "2.5rem", + }, + }, + })} + + )} + theme.palette.primary.dark, + }} + > + {roleItem.text} + + + + + ) + )} + + + + ))} + + ); + } + + function renderBarSquareSection(filteredRoles = userRoles) { + const barSquareRoles = getBarSquareRoles(filteredRoles); + if (isLoading) { + return renderSkeletonCards(barSquareRoles?.length || 1); + } + + if (!barSquareRoles || barSquareRoles.length === 0) { + return ( + + + + + هیچ صفحه‌ای برای این نقش وجود ندارد + + + + ); + } + + return ( + + {sortRoles(barSquareRoles)?.map((item, i) => ( + + + + + + toggleEditMode( + item, + getItemsForRole(getBarSquareItems(item), item) + ) + } + sx={{ + position: "absolute", + top: -8, + right: 8, + zIndex: 10, + backgroundColor: editModes[item] + ? "success.main" + : "primary.main", + color: "white", + "&:hover": { + backgroundColor: editModes[item] + ? "success.dark" + : "primary.dark", + }, + width: 32, + height: 32, + }} + size="small" + > + {editModes[item] ? ( + + ) : ( + + )} + + + + + + + + + + {getItemsForRole(getBarSquareItems(item), item)?.map( + (roleItem, index) => ( + + + editModes[item] && handleDragStart(e, index) + } + onDragEnd={handleDragEnd} + onDragOver={(e) => editModes[item] && handleDragOver(e)} + onDrop={(e) => + editModes[item] && handleDrop(e, item, index) + } + onMouseDown={() => + editModes[item] && handleCardMouseDown(index) + } + onMouseUp={handleCardMouseUp} + onTouchStart={() => + editModes[item] && handleCardMouseDown(index) + } + onTouchEnd={handleCardMouseUp} + onClick={() => handleCardClick(roleItem, item)} + sx={{ + width: "100%", + aspectRatio: "1/1", + borderRadius: "8px", + display: "flex", + alignItems: "center", + justifyContent: "center", + textAlign: "center", + cursor: editModes[item] ? "move" : "pointer", + transition: + "transform 0.2s ease-in-out, box-shadow 0.2s ease-in-out", + position: "relative", + backgroundSize: "cover", + backgroundPosition: "center", + color: "orange", + borderStyle: "solid", + borderWidth: "1px", + borderColor: (theme) => theme.palette.primary.main, + opacity: editModes[item] ? 0.9 : 1, + "&:hover": { + transform: editModes[item] + ? "scale(1.02)" + : "scale(1.05)", + boxShadow: "0 4px 12px rgba(0,0,0,0.15)", + backgroundColor: (theme) => + theme.palette.primary.light, + }, + }} + > + + {roleItem.icon && ( + + {React.cloneElement(roleItem.icon, { + sx: { + fontSize: { + xs: "2rem", + sm: "2.5rem", + lg: "3rem", + }, + }, + })} + + )} + theme.palette.primary.dark, + }} + > + {roleItem.text} + + + + + ) + )} + + + + ))} + + ); + } +}; + +export default AccessDashboardV2; diff --git a/src/pages/AdminHatchings.js b/src/pages/AdminHatchings.js new file mode 100644 index 0000000..1ce8e19 --- /dev/null +++ b/src/pages/AdminHatchings.js @@ -0,0 +1,32 @@ +import React from "react"; +import { CityManageHatchings } from "../features/city/components/city-manage-hatchings/CityManageHatchings"; +import { Grid } from "../components/grid/Grid"; +import { Box } from "@mui/material"; +import { useParams } from "react-router-dom"; +import { CityHatchingShowTableDetail } from "../features/city/components/city-hatching-show-table-detail/CityHatchingShowTableDetail"; + +const AdminHatchings = () => { + const { key } = useParams(); + + return ( + + + {key ? ( + + ) : ( + + )} + + + ); +}; +export default AdminHatchings; diff --git a/src/pages/AdminRequests.js b/src/pages/AdminRequests.js new file mode 100644 index 0000000..5a7f986 --- /dev/null +++ b/src/pages/AdminRequests.js @@ -0,0 +1,77 @@ +import { Box, Card } from "@mui/material"; +import { Grid } from "../components/grid/Grid"; +import { SPACING } from "../data/spacing"; +import { useLocation } from "react-router-dom"; +import { AvicultureNewRequest } from "../features/aviculture/components/aviculture-new-request/AvicultureNewRequest"; +import { AvicultureActiveRequests } from "../features/aviculture/components/aviculture-active-requests/AvicultureActiveRequests"; +import { useDispatch } from "react-redux"; +import { useEffect } from "react"; +import { avicultureGetRequests } from "../features/aviculture/services/aviculture-requests"; +import { AvicultureRejectedRequests } from "../features/aviculture/components/aviculture-rejected-requests/AvicultureRejectedRequests"; +import { AvicultureArchivedRequests } from "../features/aviculture/components/aviculture-archived-requests/AvicultureArchivedRequests"; +import { RequestsAwaitingPayment } from "../components/requests-awaiting-payment/RequestsAwaitingPayment"; +import { RequestsAwaitingInspections } from "../components/requests-awaiting-inspections/RequestsAwaitingInspections"; +import { + ROUTE_ADMIN_ARCHIVED_REQUESTS, + ROUTE_ADMIN_AWAITING_INSPECTION_REQUESTS, + ROUTE_ADMIN_AWAITING_PAYMENT_REQUESTS, + ROUTE_ADMIN_CREATE_NEW_REQUEST, + ROUTE_ADMIN_HATCHING, + ROUTE_ADMIN_REJECTED_REQUESTS, + ROUTE_ADMIN_REQUESTS, +} from "../routes/routes"; +import { AdminRequestsOperations } from "../features/admin/components/requests-operations/AdminRequestsOperations"; +import { AdminHatching } from "../features/admin/components/admin-hatching/AdminHatching"; + +const AdminRequests = () => { + const { pathname } = useLocation(); + const dispatch = useDispatch(); + + useEffect(() => { + dispatch(avicultureGetRequests()); + }, []); + + return ( + + + + + + + + + + {pathname === ROUTE_ADMIN_CREATE_NEW_REQUEST && ( + + )} + {pathname === ROUTE_ADMIN_HATCHING && } + {pathname === ROUTE_ADMIN_REQUESTS && } + {pathname === ROUTE_ADMIN_REJECTED_REQUESTS && ( + + )} + {pathname === ROUTE_ADMIN_ARCHIVED_REQUESTS && ( + + )} + {pathname === ROUTE_ADMIN_AWAITING_PAYMENT_REQUESTS && ( + + )} + + {pathname === ROUTE_ADMIN_AWAITING_INSPECTION_REQUESTS && ( + + )} + + + + + ); +}; + +export default AdminRequests; diff --git a/src/pages/AdminSettlement.js b/src/pages/AdminSettlement.js new file mode 100644 index 0000000..aa06be1 --- /dev/null +++ b/src/pages/AdminSettlement.js @@ -0,0 +1,60 @@ +import { Box, Typography } from "@mui/material"; +import { Grid } from "../components/grid/Grid"; + +import { + ROUTE_ADMINX_SETTLEMENTS, + ROUTE_SUPER_ADMIN_SETTLEMENTS, + ROUTE_PROVINCE_FINANCIAL_SETTLEMENT, + ROUTE_PROVINCE_SETTLEMENTS, +} from "../routes/routes"; +import { useLocation } from "react-router-dom"; +import ProvinceSettlement from "../features/province/components/province-settlement/ProvinceSettlement"; +import { BackButton } from "../components/back-button/BackButton"; +import { SPACING } from "../data/spacing"; + +const AdminSettlement = () => { + const { pathname } = useLocation(); + return ( + + + {pathname === ROUTE_PROVINCE_SETTLEMENTS || + pathname === ROUTE_PROVINCE_FINANCIAL_SETTLEMENT || + pathname === ROUTE_SUPER_ADMIN_SETTLEMENTS || + pathname === ROUTE_ADMINX_SETTLEMENTS ? ( + <> + + + + + + + ) : ( + <> + + تسویه حساب + + + + + + )} + + + ); +}; + +export default AdminSettlement; diff --git a/src/pages/AdminStatics copy.js b/src/pages/AdminStatics copy.js new file mode 100644 index 0000000..61227ac --- /dev/null +++ b/src/pages/AdminStatics copy.js @@ -0,0 +1,208 @@ +import { Box, Chip, Divider } from "@mui/material"; +import React, { useEffect, useState } from "react"; +import { useDispatch, useSelector } from "react-redux"; +import ChartBar from "../components/chart-bar/ChartBar"; +import ChartLinear from "../components/chart-linear/ChartLenear"; +import { Grid } from "../components/grid/Grid"; +import { SPACING } from "../data/spacing"; +import { adminGetCharts } from "../features/admin/services/admin-get-charts"; +import { LOADING_START, LOADING_END } from "../lib/redux/slices/appSlice"; + +import ChartPolarArea from "../components/chart-polar-area/ChartPolarArea"; +import ChartRadar from "../components/chart-radar/ChartRadar"; +import { AdminHatchingByPeriod } from "../features/admin/components/admin-hatching-by-period/AdminHatchingByPeriod"; +import AdminStaticInfoInBox from "../features/admin/components/admin-static-info-in-box/AdminStaticInfoInBox"; +import { formatJustDate } from "../utils/formatTime"; + +const AdminStatics = () => { + const [ageChickenData, setAgeChickenData] = useState({ datasets: [] }); + const [chickenPriceData, setChickenPriceData] = useState({ datasets: [] }); + const [polarData, setPolarData] = useState({ datasets: [] }); + const [radarData, setRadarData] = useState({ datasets: [] }); + + const dispatch = useDispatch(); + const { statics } = useSelector((state) => state.adminSlice); + + useEffect(() => { + dispatch(LOADING_START()); + dispatch(adminGetCharts()).then(() => { + dispatch(LOADING_END()); + }); + }, []); + + const [chickenPriceInfo, setChickenPriceInfo] = useState(); + const [chickenlist, setChickenList] = useState(); + const [infoData, setInfoData] = useState(); + useEffect(() => { + statics?.map((item) => { + if (Object.keys(item)[0] === "poultryHatching") { + setChickenList(Object.values(item)[0]); + } else if (Object.keys(item)[0] === "box") { + setInfoData(Object.values(item)[0]); + } else if (Object.keys(item)[0] === "priceList") { + setChickenPriceInfo(Object.values(item)[0]); + } + return null; + }); + }, [statics]); + + useEffect(() => { + setAgeChickenData({ + labels: chickenlist?.map((data) => data?.type?.replace("_", "-")), + datasets: [ + { + label: "تعداد", + backgroundColor: ["rgba(33, 72, 214, 0.7)"], + data: chickenlist?.map((data) => data?.quantity), + borderRadius: 5, + }, + { + label: "تلفات", + backgroundColor: ["rgba(100, 130, 160, 0.7)"], + data: chickenlist?.map((data) => data?.losses), + borderRadius: 5, + }, + { + type: "line", + label: "مقدار استاندارد", + backgroundColor: ["rgba(0, 120, 10, 0.7)"], + data: [ + 2500, 2500, 2500, 2500, 2500, 2500, 2500, 2500, 2500, 2500, 2500, + 2500, + ], + }, + ], + }); + setChickenPriceData({ + labels: chickenPriceInfo?.map((data) => formatJustDate(data?.date)), + datasets: [ + { + label: "قیمت", + backgroundColor: ["rgba(33, 72, 214, 0.7)"], + data: chickenPriceInfo?.map((data) => data?.price), + borderRadius: 5, + }, + ], + }); + setPolarData({ + labels: chickenlist?.map((data) => data?.type?.replace("_", "-")), + datasets: [ + { + backgroundColor: [ + "rgba(158, 0, 87, 0.5)", + "rgba(255, 65, 249, 0.5)", + "rgba(130, 150, 214, 0.5)", + "rgba(255, 135, 155, 0.5)", + "rgba(33, 189, 155, 0.5)", + "rgba(33, 46, 214, 0.5)", + ], + label: "تعداد", + data: chickenlist?.map((data) => data?.quantity), + }, + { + backgroundColor: [ + "rgba(255, 0, 87, 0.5)", + "rgba(255, 0, 249, 0.5)", + "rgba(33, 72, 214, 0.5)", + "rgba(255, 135, 155, 0.5)", + "rgba(33, 200, 155, 0.5)", + "rgba(33, 72, 214, 0.5)", + ], + label: "تلفات", + data: chickenlist?.map((data) => data?.losses), + }, + ], + }); + + setRadarData({ + labels: chickenlist?.map((data) => data?.type?.replace("_", "-")), + + datasets: [ + { + label: "جوجه", + data: [65, 59, 90, 81, 56, 55, 40, 56, 70, 90, 91, 88], + fill: true, + backgroundColor: "rgba(255, 99, 132, 0.2)", + borderColor: "rgb(255, 99, 132)", + pointBackgroundColor: "rgb(255, 99, 132)", + pointBorderColor: "#fff", + pointHoverBackgroundColor: "#fff", + pointHoverBorderColor: "rgb(255, 99, 132)", + }, + { + label: "تلفات", + data: [69, 75, 84, 60, 96, 95, 90, 80, 68, 75, 60, 88], + fill: true, + backgroundColor: "rgba(54, 162, 235, 0.2)", + borderColor: "rgb(54, 162, 235)", + pointBackgroundColor: "rgb(54, 162, 235)", + pointBorderColor: "#fff", + pointHoverBackgroundColor: "#fff", + pointHoverBorderColor: "rgb(54, 162, 235)", + }, + ], + }); + }, [statics, chickenlist]); + + return ( + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ); +}; + +export default AdminStatics; diff --git a/src/pages/AdminStatics.js b/src/pages/AdminStatics.js new file mode 100644 index 0000000..25993d6 --- /dev/null +++ b/src/pages/AdminStatics.js @@ -0,0 +1,272 @@ +import { Box } from "@mui/system"; +import { Grid } from "../components/grid/Grid"; +import { FarmsStats } from "../features/stats/FarmsStats"; +import { UsersStats } from "../features/stats/UserStats"; +import { HatchingStock } from "../features/stats/HatchingStock"; +import { HatchingStockAge } from "../features/stats/HatchingStockAge"; +import { HatchingStockCity } from "../features/stats/HatchingStockCity"; +import { HatchingStockCityRemain } from "../features/stats/HatchingStockCityRemain"; +import { KillRequestsStats } from "../features/stats/KillRequestsStats"; +import { NumberOfKills } from "../features/stats/NumberOfKills"; +import { SPACING } from "../data/spacing"; +import { ChickenPriceStats } from "../features/stats/ChickenPriceStats"; +import { NumberOfKillsByWeight } from "../features/stats/NumberOfKillsByWeight"; +import { KillFilesStats } from "../features/stats/KillFilesStats"; +import { KillProcessKillRequestStats } from "../features/stats/KillProcessKillRequestStats"; +import { KillProcessAllocationStats } from "../features/stats/KillProcessAllocationStats"; +import { KillProcessVetFarmStats } from "../features/stats/KillProcessVetFarmStats"; +import { KillProcessKillhouseVetStats } from "../features/stats/KillProcessKillhouseVetStats"; +import { HatchingRemainPredictionStats } from "../features/stats/HatchingRemainPredictionStats"; +import { + Button, + FormControl, + FormHelperText, + InputLabel, + MenuItem, + Select, + Typography, +} from "@mui/material"; +import { format } from "date-fns-jalali"; +import { useScreenshot } from "use-react-screenshot"; +import { createRef, useEffect } from "react"; +import DownloadIcon from "@mui/icons-material/Download"; +import { KillProcessStats } from "../features/province/components/kill-process-stats/KillProcessStats"; +import { useFormik } from "formik"; +import { getListOfProvinces } from "../utils/getListOfProvinces"; +import { getRoleFromUrl } from "../utils/getRoleFromUrl"; +import { DistributeOfCarcasses } from "../features/stats/DistributeOfCarcasses"; +import { useSelector } from "react-redux"; + +const AdminStatics = () => { + const ref = createRef(null); + const [image, takeScreenshot] = useScreenshot(); + const getImage = () => takeScreenshot(ref.current); + const userPath = useSelector((item) => item.userSlice.userPath); + + useEffect(() => { + if (image) { + const downloadLink = document.createElement("a"); + downloadLink.href = image; + downloadLink.setAttribute("download", "report.png"); + downloadLink.click(); + } + }, [image]); + + const formik = useFormik({ + initialValues: { + province: userPath, + }, + }); + + useEffect(() => { + formik.validateForm(); + }, []); + + const isMobile = window.innerWidth <= 600; + + return ( + + + + {(getRoleFromUrl() === "Observatory" || + getRoleFromUrl() === "AdminX") && ( + + + انتخاب استان + + + + {formik.touched.province && Boolean(formik.errors.province) + ? formik.errors.province + : null} + + + )} + + + + + + + {} + {} + {} + + + + + + + + + + + + + + + + + + + + + + + + + روند کشتار امروز مورخ {format(new Date(), "yyyy/MM/dd")} + + + + + + + + + + + + + + {} + + +
    + {} + {} + + {} +
    + + + + + + + + + + + + + + + + + + + + +
    +
    + ); +}; + +export default AdminStatics; diff --git a/src/pages/AdminXDashboard.js b/src/pages/AdminXDashboard.js new file mode 100644 index 0000000..c602f2d --- /dev/null +++ b/src/pages/AdminXDashboard.js @@ -0,0 +1,7 @@ +import React from "react"; + +const AdminXDashboard = () => { + return
    AdminXDashboard
    ; +}; + +export default AdminXDashboard; diff --git a/src/pages/AdminXExcelCheck.js b/src/pages/AdminXExcelCheck.js new file mode 100644 index 0000000..299f496 --- /dev/null +++ b/src/pages/AdminXExcelCheck.js @@ -0,0 +1,26 @@ +import React from "react"; +import { Grid } from "../components/grid/Grid"; +import { SPACING } from "../data/spacing"; +import { Box } from "@mui/material"; +import { AdminCExcelStatus } from "../features/admix-x/components/admin-x-excel-status/AdminCExcelStatus"; + +const AdminXExcelCheck = () => { + return ( + + + + + + ); +}; + +export default AdminXExcelCheck; diff --git a/src/pages/Auction.js b/src/pages/Auction.js new file mode 100644 index 0000000..4935a44 --- /dev/null +++ b/src/pages/Auction.js @@ -0,0 +1,35 @@ +import { Box } from "@mui/system"; +import { Grid } from "../components/grid/Grid"; +import { SPACING } from "../data/spacing"; +import { AuctionsBids } from "../features/auction/components/auction-bids/AuctionBids"; +import { AuctionsView } from "../features/auction/components/auctions-view/AuctionsView"; +import useUserProfile from "../features/authentication/hooks/useUserProfile"; +import { getRoleFromUrl } from "../utils/getRoleFromUrl"; + +const Auction = () => { + const [roles] = useUserProfile(); + return ( + + + + + + {getRoleFromUrl() === "KillHouse" && roles.includes("KillHouse") && ( + + + + )} + + + ); +}; + +export default Auction; diff --git a/src/pages/Auth.js b/src/pages/Auth.js new file mode 100644 index 0000000..5adb8c6 --- /dev/null +++ b/src/pages/Auth.js @@ -0,0 +1,640 @@ +import { Box } from "@mui/system"; +import { Grid } from "../components/grid/Grid"; +import { SPACING } from "../data/spacing"; +import { + Button, + IconButton, + InputAdornment, + TextField, + Typography, +} from "@mui/material"; +import Captcha from "../components/captcha/Captcha"; +import { + CLOSE_MODAL, + LOADING_END, + LOADING_START, + OPEN_MODAL, +} from "../lib/redux/slices/appSlice"; +import { + checkActiveUsers, + checkUserPath, + loginWithPassword, +} from "../features/authentication/services/login"; +import { Yup } from "../lib/yup/yup"; +import { useFormik } from "formik"; +import { useDispatch } from "react-redux"; +import { useContext, useEffect, useState } from "react"; +import { AppContext } from "../contexts/AppContext"; +import Visibility from "@mui/icons-material/Visibility"; +import VisibilityOff from "@mui/icons-material/VisibilityOff"; +import { getUserMovingTextsService } from "../features/authentication/services/getUserMovingTexts"; +import { slaughterGetPermisionState } from "../features/slaughter-house/services/slaughter-get-permision"; +import { getUserAnnouncement } from "../features/authentication/services/get-announcement"; +import bgImg from "../assets/images/login-rasadyar.png"; +import loginLogo from "../assets/images/login-logo.png"; +import icon from "../assets/images/logo.png"; +import { motion } from "framer-motion"; +import { getUserProfile } from "../features/authentication/services/getUserProfile"; +import { AuthPrivacyText } from "../features/authentication/components/auth-privacy-text/AuthProvacyText"; + +const modalContentStyle = { + backgroundColor: "#ffffff", + padding: "20px", + borderRadius: "4px", + outline: "none", + minWidth: "300px", + maxWidth: "600px", + textAlign: "center", +}; + +const descriptionStyle = { + marginBottom: "10px", +}; + +const buttonStyle = { + marginTop: "10px", +}; + +const containerVariants = { + hidden: { opacity: 0, scale: 0.9 }, + visible: { opacity: 1, scale: 1, transition: { duration: 0.5 } }, +}; + +const itemVariants = { + hidden: { opacity: 0, y: 20 }, + visible: { opacity: 1, y: 0, transition: { duration: 0.3 } }, +}; + +const Auth = () => { + const [activeUsers, setActiveUsers] = useState(0); + const [openNotif] = useContext(AppContext); + const [isValidCaptcha, setIsValidCaptcha] = useState(false); + const dispatch = useDispatch(); + const [isValidMobile, setIsValidMobile] = useState(false); + const [isValidMobileChecked, setIsValidMobileChecked] = useState(false); + const formik = useFormik({ + initialValues: { + mobile: "", + captcha: "", + password: "", + }, + validationSchema: Yup.object({ + mobile: Yup.number() + .required("این فیلد اجباری است!") + .typeError("لطفا اعداد انگلیسی وارد کنید!") + .test("len", "شماره تلفن باید 11 رقم باشد!", (val, context) => { + return context.originalValue && context.originalValue.length === 11; + }), + password: Yup.mixed().required("این فیلد اجباری است!"), + }), + }); + + useEffect(() => { + formik.validateForm(); + dispatch(checkActiveUsers()).then((r) => { + const currentTime = new Date(); + const hours = currentTime.getHours(); + + if (hours >= 20 || hours < 5) { + setActiveUsers(r.payload.data?.numberOfActiveUsers); + } else { + setActiveUsers(r.payload.data?.numberOfActiveUsers + 320); + } + }); + }, []); + + useEffect(() => { + if (formik.values.mobile.length === 11) { + dispatch(checkUserPath({ mobile: formik.values.mobile, state: "" })).then( + (r) => { + if (r.error) { + formik.setFieldValue("mobile", ""); + openNotif({ + vertical: "top", + horizontal: "center", + msg: "لطفا اتصال به اینترنت را چک کنید!", + severity: "error", + }); + } else { + const notValid = !!r.error; + setIsValidMobileChecked(true); + if (notValid) { + setIsValidMobile(false); + } else { + setIsValidMobile(true); + } + } + } + ); + } + }, [formik.values.mobile]); + + const getUserMovingTexts = () => { + dispatch(getUserMovingTextsService()); + }; + + const [showPassword, setShowPassword] = useState(false); + const handleClickShowPassword = () => { + setShowPassword(!showPassword); + }; + + const handleMouseDownPassword = (event) => { + event.preventDefault(); + }; + + const getSlaughterState = (role) => { + dispatch(slaughterGetPermisionState()); + dispatch(getUserAnnouncement(role)).then((r) => { + if (r.payload.data?.active) { + dispatch( + OPEN_MODAL({ + title: "اطلاعیه سیستم", + content: ( + + + {r.payload.data?.description} + + + + + + + + ), + }) + ); + } + }); + }; + + const submitForm = (e) => { + e.preventDefault(); + if (isValidMobile) { + dispatch(LOADING_START()); + dispatch( + loginWithPassword({ + mobile: formik.values.mobile, + password: formik.values.password, + }) + ).then((r) => { + dispatch(getUserProfile()); + if (r.payload?.data?.role?.includes("KillHouse")) { + getSlaughterState("KillHouse"); + } else if (r.payload?.data?.role?.includes("CityOperator")) { + getSlaughterState("CityOperator"); + } + if (r.error) { + openNotif({ + vertical: "top", + horizontal: "center", + msg: "نام کاربری یا رمز اشتباه است!", + severity: "error", + }); + } + dispatch(LOADING_END()); + }); + } else { + openNotif({ + vertical: "top", + horizontal: "center", + msg: "شماره موبایل در سامانه وجود ندارد!", + severity: "error", + }); + } + }; + + return ( + + + + + + + + + icon + + + + + + + سامانه رصدیار + + {/* + شماره موبایل تان را وارد کنید. + */} + + + + +
    + + + + + { + if ( + e.key === "Enter" && + isValidCaptcha && + isValidMobileChecked + ) { + if (isValidMobile) { + dispatch(LOADING_START()); + dispatch( + loginWithPassword({ + mobile: formik.values.mobile, + password: formik.values.password, + }) + ).then((r) => { + dispatch(getUserProfile()); + if ( + r.payload?.data?.role?.includes( + "CityOperator" + ) || + r.payload?.data?.role?.includes( + "KillHouse" + ) || + r.payload?.data?.role?.includes( + "CityJahad" + ) || + r.payload?.data?.role?.includes( + "ProvinceSupervisor" + ) || + r.payload?.data?.role?.includes( + "ProvinceOperator" + ) + ) { + getUserMovingTexts(); + } + + if ( + r.payload?.data?.role?.includes("KillHouse") + ) { + getSlaughterState("KillHouse"); + } else if ( + r.payload?.data?.role?.includes( + "CityOperator" + ) + ) { + getSlaughterState("CityOperator"); + } + if (r.error) { + openNotif({ + vertical: "top", + horizontal: "center", + msg: "رمزعبور اشتباه است!", + severity: "error", + }); + } + dispatch(LOADING_END()); + }); + } else { + openNotif({ + vertical: "top", + horizontal: "center", + msg: "شماره موبایل در سامانه وجود ندارد!", + severity: "error", + }); + } + } + }} + fullWidth + InputProps={{ + endAdornment: ( + + + {showPassword ? ( + + ) : ( + + )} + + + ), + }} + /> + + + setIsValidCaptcha(status)} + /> + + + + + + +
    +
    + + مطالعه بیانیه{" "} + + dispatch( + OPEN_MODAL({ + title: "حریم خصوصی", + content: , + }) + ) + } + > + حریم خصوصی + + +
    +
    + + {/* Logo Image */} + + + {/* Text Content */} + + سامانه رصد و پایش زنجیره تامین، تولید و توزیع کالای اساسی + + + از اینکه از سامانه برای بررسی و مدیریت کالاهای اساسی استفاده + می‌کنید، بسیار خرسندیم. امیدواریم که تجربه‌ی شما با این + سامانه، مفید و کارآمد باشد. در صورت نیاز به راهنمایی یا + پرسش‌های بیشتر، تیم پشتیبانی ما همواره آماده‌ی پاسخگویی به + شماست. + + + با تشکر از همراهی شما +
    + سامانه رصد یار +
    + + تلفن پشتیبانی : 28421237-021 + +
    + + + {/* eslint-disable-next-line react/jsx-no-target-blank */} + + icon + + +
    +
    + + + + کاربران آنلاین: {activeUsers} نفر + + + +
    +
    +
    + ); +}; + +export default Auth; diff --git a/src/pages/AvicultureDashboard.js b/src/pages/AvicultureDashboard.js new file mode 100644 index 0000000..5c462a5 --- /dev/null +++ b/src/pages/AvicultureDashboard.js @@ -0,0 +1,24 @@ +import { Box } from "@mui/system"; +import { Grid } from "../components/grid/Grid"; +import { SPACING } from "../data/spacing"; +import { ViewBankAccount } from "../features/aviculture/components/view-bank-account/ViewBankAccount"; +import { ViewProfile } from "../features/aviculture/components/view-profile/ViewProfile"; + +const AvicultureDashboard = () => { + return ( + + + + + + + + + + + + + ); +}; + +export default AvicultureDashboard; diff --git a/src/pages/AvicultureHallInspects.js b/src/pages/AvicultureHallInspects.js new file mode 100644 index 0000000..7018f92 --- /dev/null +++ b/src/pages/AvicultureHallInspects.js @@ -0,0 +1,156 @@ +import { IconButton, Typography } from "@mui/material"; +import React, { useEffect } from "react"; +import { useDispatch, useSelector } from "react-redux"; +import { useNavigate, useParams } from "react-router-dom"; +import { avicultureGetHallInspects } from "../features/aviculture/services/aviculture-get-hall-inspects"; +import { LOADING_END, LOADING_START } from "../lib/redux/slices/appSlice"; +import NavigateNextIcon from "@mui/icons-material/NavigateNext"; +import { Grid } from "../components/grid/Grid"; +import { + Timeline, + TimelineConnector, + TimelineDot, + TimelineItem, + TimelineOppositeContent, + TimelineSeparator, +} from "@mui/lab"; +import { SPACING } from "../data/spacing"; +import { SimpleTable } from "../components/simple-table/SimpleTable"; +import { formatJustDate, formatJustTime } from "../utils/formatTime"; +import { Box } from "@mui/system"; + +const AvicultureHallInspects = () => { + const { avicultureHallInspects } = useSelector( + (state) => state.avicultureSlice + ); + + const dispatch = useDispatch(); + const navigate = useNavigate(); + + const { key } = useParams(); + const { hall } = useParams(); + + useEffect(() => { + dispatch(LOADING_START()); + dispatch(avicultureGetHallInspects(key + "&hall=" + hall)).then(() => { + dispatch(LOADING_END()); + }); + }, []); + + return ( + + + + + + + navigate(-1)} + > + + بازگشت + + + + + {avicultureHallInspects?.map((item) => { + return ( + + + + + + + + + + + بازرسی مورخ {formatJustDate(item.createDate)}{" "} + ساعت {formatJustTime(item.createDate)} + + + + + + + { + return [ + + + دانلود + + , + ]; + }) + : "بدون پیوست", + ], + ]} + /> + + + + + ); + })} + {!avicultureHallInspects?.length && ( + + برای این سالن بازرسی ثبت نشده است. + + )} + + + + + + + ); +}; + +export default AvicultureHallInspects; diff --git a/src/pages/AvicultureHalls.js b/src/pages/AvicultureHalls.js new file mode 100644 index 0000000..50e3f5a --- /dev/null +++ b/src/pages/AvicultureHalls.js @@ -0,0 +1,85 @@ +import { Box, IconButton } from "@mui/material"; +import React, { useEffect, useState } from "react"; +import { Grid } from "../components/grid/Grid"; +import { SPACING } from "../data/spacing"; +import { useDispatch, useSelector } from "react-redux"; +import { avicultureGetHallsInfo } from "../features/aviculture/services/aviculture-get-halls-info"; +import { LOADING_END, LOADING_START } from "../lib/redux/slices/appSlice"; +import { ROUTE_AVICULTURE_INSPECTS } from "../routes/routes"; +import { useNavigate } from "react-router-dom"; +import { format } from "date-fns-jalali"; +import ResponsiveTable from "../components/responsive-table/ResponsiveTable"; +import TaskAltIcon from "@mui/icons-material/TaskAlt"; + +const AvicultureHalls = () => { + const dispatch = useDispatch(); + + const { avicultureHallsInfo } = useSelector((state) => state.avicultureSlice); + const [dataTable, setDataTable] = useState([]); + + const navigate = useNavigate(); + + useEffect(() => { + dispatch(LOADING_START()); + dispatch(avicultureGetHallsInfo()).then(() => { + dispatch(LOADING_END()); + }); + }, []); + + useEffect(() => { + const d = avicultureHallsInfo?.map((item) => { + return [ + item.hall, + item.hatchingState === "active" ? "دارد" : "ندارد", + format(new Date(item?.hatchingDate), "yyyy/MM/dd"), + item.inspections, + + navigate( + ROUTE_AVICULTURE_INSPECTS + item.poultryKey + "/" + item.hall + ) + } + > + + , + ]; + }); + setDataTable(d); + }, [avicultureHallsInfo]); + + return ( + + + + + + + + ); +}; + +export default AvicultureHalls; diff --git a/src/pages/AvicultureReports.js b/src/pages/AvicultureReports.js new file mode 100644 index 0000000..40a5a9a --- /dev/null +++ b/src/pages/AvicultureReports.js @@ -0,0 +1,101 @@ +import { Box, Card, IconButton } from "@mui/material"; +import React, { useEffect, useState } from "react"; +import { useDispatch, useSelector } from "react-redux"; +import { useNavigate } from "react-router-dom"; +import { AdvancedTable } from "../components/advanced-table/AdvancedTable"; +import { Grid } from "../components/grid/Grid"; +import { SPACING } from "../data/spacing"; +import { avicultureGetReports } from "../features/aviculture/services/aviculture-get-reports"; +import PlagiarismIcon from "@mui/icons-material/Plagiarism"; +import { ROUTE_AVICULTURE_FILE } from "../routes/routes"; +import { AvicultureReportsCharts } from "../features/aviculture/components/aviculture-reports-charts/AvicultureReportsCharts"; +import { format } from "date-fns-jalali"; + +const AvicultureReports = () => { + const dispatch = useDispatch(); + const { reports } = useSelector((state) => state.avicultureSlice); + const [tableData, setTableData] = useState(); + const navigate = useNavigate(); + + useEffect(() => { + dispatch(avicultureGetReports()); + }, []); + + useEffect(() => { + const d = reports?.table.map((item, i) => { + return [ + i + 1, + item.hatchingPeriod, + format(new Date(item?.hatchingDate), "yyyy/MM/dd"), + item.hatchingChickenBreed, + item.age, + item.quantity, + item.weightOfSuffering, + item.averageFee, + item.averageWeight, + item.salesPrice.toLocaleString(), + item.totalAmount.toLocaleString(), + item.paidState === "paid" + ? "پرداخت شده" + : item.paidState === "pending" + ? "در انتظار پرداخت" + : "ندارد", + navigate(ROUTE_AVICULTURE_FILE + item?.requestId)} + > + + , + ]; + }); + + setTableData(d); + }, [reports]); + return ( + + + + + + + + + + + + + + ); +}; + +export default AvicultureReports; diff --git a/src/pages/AvicultureRequests.js b/src/pages/AvicultureRequests.js new file mode 100644 index 0000000..77020fd --- /dev/null +++ b/src/pages/AvicultureRequests.js @@ -0,0 +1,84 @@ +import { Box, Typography } from "@mui/material"; +import { Grid } from "../components/grid/Grid"; +import { SPACING } from "../data/spacing"; +import { RequestsOperations } from "../features/aviculture/components/requests-operations/RequestsOperations"; +import { useLocation } from "react-router-dom"; +import { + ROUTE_AVICULTURE_ARCHIVED_REQUESTS, + ROUTE_AVICULTURE_REJECTED_REQUESTS, + ROUTE_AVICULTURE_REQUESTS, + ROUTE_AVICULTURE_HATCHING, + ROUTE_AVICULTURE_CREATE_NEW_REQUEST, + ROUTE_AVICULTURE_AWAITING_PAYMENT_REQUESTS, + ROUTE_AVICULTURE_AWAITING_INSPECTION_REQUESTS, + ROUTE_AVICULTURE_SUBMIT_REQUEST, + ROUTE_AVICULTURE_GIVE_PERMISSION, +} from "../routes/routes"; +import { AvicultureNewRequest } from "../features/aviculture/components/aviculture-new-request/AvicultureNewRequest"; +import { AvicultureActiveRequests } from "../features/aviculture/components/aviculture-active-requests/AvicultureActiveRequests"; +import { AvicultureRejectedRequests } from "../features/aviculture/components/aviculture-rejected-requests/AvicultureRejectedRequests"; +import { AvicultureArchivedRequests } from "../features/aviculture/components/aviculture-archived-requests/AvicultureArchivedRequests"; +import { AvicultureHatching } from "../features/aviculture/components/aviculture-hatching/AvicultureHatching"; +import { RequestsAwaitingPayment } from "../components/requests-awaiting-payment/RequestsAwaitingPayment"; +import { RequestsAwaitingInspections } from "../components/requests-awaiting-inspections/RequestsAwaitingInspections"; +import { BackButton } from "../components/back-button/BackButton"; +import { AvicultureGivePermission } from "../features/aviculture/components/aviculture-give-permission/AvicultureGivePermission"; + +const AvicultureRequests = () => { + const { pathname } = useLocation(); + return ( + + + {pathname === ROUTE_AVICULTURE_REQUESTS ? ( + <> + + صفحه درخواست های مرغدار + + + + + + ) : ( + + )} + + + + {pathname === ROUTE_AVICULTURE_CREATE_NEW_REQUEST && ( + + )} + {pathname === ROUTE_AVICULTURE_HATCHING && } + {pathname === ROUTE_AVICULTURE_SUBMIT_REQUEST && ( + + )} + {pathname === ROUTE_AVICULTURE_REJECTED_REQUESTS && ( + + )} + {pathname === ROUTE_AVICULTURE_ARCHIVED_REQUESTS && ( + + )} + {pathname === ROUTE_AVICULTURE_AWAITING_PAYMENT_REQUESTS && ( + + )} + {pathname === ROUTE_AVICULTURE_AWAITING_INSPECTION_REQUESTS && ( + + )} + {pathname === ROUTE_AVICULTURE_GIVE_PERMISSION && ( + + )} + + + + + ); +}; + +export default AvicultureRequests; diff --git a/src/pages/BarInfos.js b/src/pages/BarInfos.js new file mode 100644 index 0000000..3981112 --- /dev/null +++ b/src/pages/BarInfos.js @@ -0,0 +1,30 @@ +import { Box } from "@mui/material"; +import { Grid } from "../components/grid/Grid"; +import { SPACING } from "../data/spacing"; +import {} from "../routes/routes"; +import { ProvinceBarInfos } from "../features/province/components/province-bar-infos/ProvinceBarInfos"; + +const BarInfos = () => { + return ( + + + + + + + + + + ); +}; + +export default BarInfos; diff --git a/src/pages/BarSquareTransactions.js b/src/pages/BarSquareTransactions.js new file mode 100644 index 0000000..736a25e --- /dev/null +++ b/src/pages/BarSquareTransactions.js @@ -0,0 +1,117 @@ +import { Box, Button } from "@mui/material"; +import React from "react"; +import { Grid } from "../components/grid/Grid"; +import { SPACING } from "../data/spacing"; +import { BackButton } from "../components/back-button/BackButton"; +import ResponsiveTable from "../components/responsive-table/ResponsiveTable"; + +const BarSquareTransactions = () => { + const data = [ + [ + "1", + "1404/2/17", + "پرداخت شده", + "1,150,000", + , + ], + [ + "2", + "1404/2/16", + "پرداخت شده", + "830,000", + , + ], + [ + "3", + "1404/2/16", + "پرداخت شده", + "12,000,000", + , + ], + [ + "4", + "1404/2/15", + "پرداخت شده", + "120,000", + , + ], + [ + "5", + "1404/2/14", + "پرداخت شده", + "8,100,000", + , + ], + ]; + return ( + + + + + + + + + + + + + ); +}; + +export default BarSquareTransactions; diff --git a/src/pages/BroadcastManagement.js b/src/pages/BroadcastManagement.js new file mode 100644 index 0000000..fa3ee56 --- /dev/null +++ b/src/pages/BroadcastManagement.js @@ -0,0 +1,47 @@ +import { Box } from "@mui/system"; +import { Grid } from "../components/grid/Grid"; +import { SPACING } from "../data/spacing"; +import SlaughterAgentShare from "../pages/SlaughterAgentShare"; +import { BroadcastManagementOperations } from "../features/province/components/broadcast-management-operations/BroadcastManagementOperations"; +import { + ROUTE_ADMINX_BROADCAST_MANAGEMENT, + ROUTE_ADMINX_ROUTE_AGENT_SHARE, + ROUTE_PROVINCE_ROUTE_AGENT_SHARE, + ROUTE_PROVINCEـBROADCAST_MANAGEMENT, + ROUTE_SUPER_ADMIN_BROADCAST_MANAGEMENT, + ROUTE_SUPER_ADMIN_ROUTE_AGENT_SHARE, +} from "../routes/routes"; +import { useLocation } from "react-router-dom"; + +const BroadcastManagement = () => { + const { pathname } = useLocation(); + + return ( + + + {(pathname === ROUTE_PROVINCEـBROADCAST_MANAGEMENT || + pathname === ROUTE_SUPER_ADMIN_BROADCAST_MANAGEMENT || + pathname === ROUTE_ADMINX_BROADCAST_MANAGEMENT) && ( + + )} + + {(pathname === ROUTE_PROVINCE_ROUTE_AGENT_SHARE || + pathname === ROUTE_SUPER_ADMIN_ROUTE_AGENT_SHARE || + pathname === ROUTE_ADMINX_ROUTE_AGENT_SHARE) && ( + + )} + + + ); +}; + +export default BroadcastManagement; diff --git a/src/pages/CarManagement.js b/src/pages/CarManagement.js new file mode 100644 index 0000000..20c5e57 --- /dev/null +++ b/src/pages/CarManagement.js @@ -0,0 +1,34 @@ +import { Box } from "@mui/material"; +import { Grid } from "../components/grid/Grid"; +import { SPACING } from "../data/spacing"; +import { ProvinceManageCars } from "../features/province/components/province-manage-cars/ProvinceManageCars"; + +const CarManagement = () => { + return ( + + + {/* + + + + */} + + + + + + + + ); +}; + +export default CarManagement; diff --git a/src/pages/Cars.js b/src/pages/Cars.js new file mode 100644 index 0000000..be9879f --- /dev/null +++ b/src/pages/Cars.js @@ -0,0 +1,47 @@ +import { Box } from "@mui/material"; +import { Grid } from "../components/grid/Grid"; +import { SPACING } from "../data/spacing"; +import { useLocation } from "react-router-dom"; +import { + ROUTE_SLAUGHTER_ADD_CAR, + ROUTE_SLAUGHTER_CAR_MANAGEMENT, +} from "../routes/routes"; +import { SlaughterNewCar } from "../features/slaughter-house/components/slaughter-new-car/SlaughterNewCar"; +import { SlaughterManageCars } from "../features/slaughter-house/components/slaughter-manage-cars/SlaughterManageCars"; + +const Cars = () => { + const { pathname } = useLocation(); + + return ( + <> + + + {/* + + + + */} + + + {pathname === ROUTE_SLAUGHTER_ADD_CAR && } + {pathname === ROUTE_SLAUGHTER_CAR_MANAGEMENT && ( + + )} + + + + + + ); +}; + +export default Cars; diff --git a/src/pages/ChainCompany.js b/src/pages/ChainCompany.js new file mode 100644 index 0000000..b8d3e75 --- /dev/null +++ b/src/pages/ChainCompany.js @@ -0,0 +1,45 @@ +import { Box } from "@mui/material"; +import React from "react"; +import { Grid } from "../components/grid/Grid"; +import { SPACING } from "../data/spacing"; +import { ChainCompanyActiveChains } from "../features/chain-company/components/chain-company-active-chains/ChainCompanyActiveChains"; +import { useLocation } from "react-router-dom"; +import { + ROUTE_CHAIN_COMPANY_MANAGE_BARS, + ROUTE_CHAIN_COMPANY_POULTRIES, +} from "../routes/routes"; +import { ChainBarManagement } from "../features/province/components/chain-bar-management/ChainBarManagement"; + +const ChainCompany = () => { + const { pathname } = useLocation(); + return ( + <> + + + + + {pathname === ROUTE_CHAIN_COMPANY_POULTRIES && ( + + )} + + {pathname === ROUTE_CHAIN_COMPANY_MANAGE_BARS && ( + + )} + + + + + + ); +}; + +export default ChainCompany; diff --git a/src/pages/ChickenStockMarket.js b/src/pages/ChickenStockMarket.js new file mode 100644 index 0000000..31a7148 --- /dev/null +++ b/src/pages/ChickenStockMarket.js @@ -0,0 +1,76 @@ +import { + Button, + Divider, + InputAdornment, + TextField, + Typography, +} from "@mui/material"; +import { Box } from "@mui/system"; +import { Grid } from "../components/grid/Grid"; +import { SPACING } from "../data/spacing"; +import SearchIcon from "@mui/icons-material/Search"; +import StockMarketStickyOperations from "../features/chickenStockMarket/components/stock-market-sticky-operations/StockMarketStickyOperations"; +// import { StockMarketAvicultureRequests } from "../features/chickenStockMarket/components/stock-market-aviculture-requests-list/StockMarketAvicultureRequests"; +// import { StockMarketSlaughterRequests } from "../features/chickenStockMarket/components/stock-market-slaughter-requests-list/StockMarketSlaughterRequests"; + +const ChickenStockMarket = () => { + return ( + + + + پنل فروش مرغ گوشتی + + + + + + + ), + }} + /> + + تاریخ: ۱۴۰۱.۰۶.۰۲ + + + + + + درخواست کشتار مرغدار + + + قیمت میانگین : ۴۰۳.۰۰۰ ریال + + + {/* */} + + + درخواست کشتار مرغدار + + + قیمت میانگین : ۴۰۳.۰۰۰ ریال + + + {/* */} + {/* bottom Menu */} + + + + ); +}; + +export default ChickenStockMarket; diff --git a/src/pages/CityAvicultureManagement.js b/src/pages/CityAvicultureManagement.js new file mode 100644 index 0000000..b1d189b --- /dev/null +++ b/src/pages/CityAvicultureManagement.js @@ -0,0 +1,42 @@ +import { Box } from "@mui/material"; +import { Grid } from "../components/grid/Grid"; +import { SPACING } from "../data/spacing"; +import { useLocation } from "react-router-dom"; +import { ROUTE_CITY_POULTRY_FARMS } from "../routes/routes"; +import { useDispatch } from "react-redux"; +import { useEffect } from "react"; +import { avicultureGetRequests } from "../features/aviculture/services/aviculture-requests"; +import { CityPoultryFarms } from "../features/city/components/city-poultry-farms/CityPoultryFarms"; + +const CityAvicultureFarms = () => { + const { pathname } = useLocation(); + const dispatch = useDispatch(); + + useEffect(() => { + dispatch(avicultureGetRequests()); + }, []); + + return ( + <> + + + + + {pathname === ROUTE_CITY_POULTRY_FARMS && } + + + + + + ); +}; + +export default CityAvicultureFarms; diff --git a/src/pages/CityRequests.js b/src/pages/CityRequests.js new file mode 100644 index 0000000..5effdfa --- /dev/null +++ b/src/pages/CityRequests.js @@ -0,0 +1,83 @@ +import { Box, Typography } from "@mui/material"; +import { Grid } from "../components/grid/Grid"; +import { SPACING } from "../data/spacing"; +import { CityOperations } from "../features/city/components/city-operations/CityOperations"; +import { useLocation } from "react-router-dom"; +import { + ROUTE_CITY_ACTIVE_REQUESTS, + ROUTE_CITY_ARCHIVED_REQUESTS, + ROUTE_CITY_REJECTED_REQUESTS, + ROUTE_CITY_REQUESTS, + ROUTE_CITY_AWAITING_PAYMENT_REQUESTS, + ROUTE_CITY_AWAITING_INSPECTION_REQUESTS, + ROUTE_CITY_NEW_REQUESTS, + ROUTE_CITY_FREE_SALES_REQUESTS, +} from "../routes/routes"; +import { CityNewRequests } from "../features/city/components/city-new-requests/CityNewRequests"; +import { AvicultureArchivedRequests } from "../features/aviculture/components/aviculture-archived-requests/AvicultureArchivedRequests"; +import { CityActiveRequests } from "../features/city/components/city-active-requests/CityActiveRequests"; +import { CityRejectedRequests } from "../features/city/components/city-rejected-requests/CityRejectedRequests"; +import { RequestsAwaitingInspections } from "../components/requests-awaiting-inspections/RequestsAwaitingInspections"; +import { RequestsAwaitingPayment } from "../components/requests-awaiting-payment/RequestsAwaitingPayment"; +import { BackButton } from "../components/back-button/BackButton"; +import { ProvinceFreeSales } from "../features/province/components/province-free-sales/ProvinceFreeSales"; + +const CityRequests = () => { + const { pathname } = useLocation(); + + return ( + <> + + + {pathname === ROUTE_CITY_REQUESTS ? ( + + + + صفحه مدیریت درخواست ها (شهرستان) + + + + + ) : ( + + )} + + + + {pathname === ROUTE_CITY_NEW_REQUESTS && } + {pathname === ROUTE_CITY_ACTIVE_REQUESTS && ( + + )} + {pathname === ROUTE_CITY_REJECTED_REQUESTS && ( + + )} + {pathname === ROUTE_CITY_ARCHIVED_REQUESTS && ( + + )} + {pathname === ROUTE_CITY_AWAITING_PAYMENT_REQUESTS && ( + + )} + + {pathname === ROUTE_CITY_AWAITING_INSPECTION_REQUESTS && ( + + )} + {pathname === ROUTE_CITY_FREE_SALES_REQUESTS && ( + + )} + + + + + + ); +}; + +export default CityRequests; diff --git a/src/pages/CityUserFile.js b/src/pages/CityUserFile.js new file mode 100644 index 0000000..71af01b --- /dev/null +++ b/src/pages/CityUserFile.js @@ -0,0 +1,33 @@ +import { Box } from "@mui/material"; +import { Grid } from "../components/grid/Grid"; +import { SPACING } from "../data/spacing"; +import { useLocation } from "react-router-dom"; +import { ROUTE_CITY_USER_FILE } from "../routes/routes"; +import { CityUserFileInfo } from "../features/city/components/city-user-file-info/CityUserFileInfo"; + +const CityUserFile = () => { + const { pathname } = useLocation(); + + return ( + <> + + + + + {pathname.includes(ROUTE_CITY_USER_FILE) && } + + + + + + ); +}; +export default CityUserFile; diff --git a/src/pages/CityUserManagement.js b/src/pages/CityUserManagement.js new file mode 100644 index 0000000..77826a2 --- /dev/null +++ b/src/pages/CityUserManagement.js @@ -0,0 +1,34 @@ +import { Box } from "@mui/material"; +import { Grid } from "../components/grid/Grid"; +import { SPACING } from "../data/spacing"; +import { useLocation } from "react-router-dom"; +import { ROUTE_CITY_USER_MANAGEMENT } from "../routes/routes"; +import { CityUsers } from "../features/city/components/city-users/CityUsers"; + +const CityUserManagement = () => { + const { pathname } = useLocation(); + + return ( + <> + + + + + {pathname === ROUTE_CITY_USER_MANAGEMENT && } + + + + + + ); +}; + +export default CityUserManagement; diff --git a/src/pages/Commerce.js b/src/pages/Commerce.js new file mode 100644 index 0000000..0e360ba --- /dev/null +++ b/src/pages/Commerce.js @@ -0,0 +1,50 @@ +import { Box, Typography } from "@mui/material"; +import { Grid } from "../components/grid/Grid"; +import { SPACING } from "../data/spacing"; +import { + ROUTE_COMMERCE_REQUESTS, + ROUTE_PROVINCE_SUPERVISOR_REQUESTS, +} from "../routes/routes"; +import { useLocation } from "react-router-dom"; + +import { BackButton } from "../components/back-button/BackButton"; +import { CommerceOperations } from "../features/commerce/components/commerce-operations/CommerceOperations"; + +const Commerce = () => { + const { pathname } = useLocation(); + + return ( + <> + + + {pathname === ROUTE_COMMERCE_REQUESTS || + pathname === ROUTE_PROVINCE_SUPERVISOR_REQUESTS ? ( + + + + صفحه مدیریت درخواست ها (معاونت بازرگانی) + + + + + ) : ( + + )} + + + + + + + + ); +}; +export default Commerce; diff --git a/src/pages/ComponentsCatalog.js b/src/pages/ComponentsCatalog.js new file mode 100644 index 0000000..f2f992d --- /dev/null +++ b/src/pages/ComponentsCatalog.js @@ -0,0 +1,990 @@ +import { + Box, + Paper, + Typography, + Divider, + Card, + CardContent, + TextField, + Chip, + Button, +} from "@mui/material"; +import { Grid } from "../components/grid/Grid"; +import { BackButton } from "../components/back-button/BackButton"; +import { ButtonWithIcon } from "../components/button-with-icon/ButtonWithIcon"; +import { Timer } from "../components/timer/Timer"; +import { LineWithText } from "../components/line-with-text/LineWithText"; +import CustomCard from "../components/custom-card/CustomCard"; +import Captcha from "../components/captcha/Captcha"; +import { DialogAlert } from "../components/dialog-alert/DialogAlert"; +import { SimpleTable } from "../components/simple-table/SimpleTable"; +import ResponsiveTable from "../components/responsive-table/ResponsiveTable"; +import ChartBar from "../components/chart-bar/ChartBar"; +import ChartPie from "../components/chart-pie/ChartPie"; +import ChartLinear from "../components/chart-linear/ChartLenear"; +import ChartDoughnut from "../components/chart-doughnut/ChartDoughnut"; + +// Icons +import HomeIcon from "@mui/icons-material/Home"; +import AddIcon from "@mui/icons-material/Add"; +import SearchIcon from "@mui/icons-material/Search"; +import DeleteIcon from "@mui/icons-material/Delete"; +import EditIcon from "@mui/icons-material/Edit"; +import SaveIcon from "@mui/icons-material/Save"; +import SettingsIcon from "@mui/icons-material/Settings"; +import PersonIcon from "@mui/icons-material/Person"; + +import { useState, useContext } from "react"; +import { AppContext } from "../contexts/AppContext"; +import { useDispatch } from "react-redux"; +import { OPEN_MODAL } from "../lib/redux/slices/appSlice"; + +const ComponentsCatalog = () => { + const [searchTerm, setSearchTerm] = useState(""); + const [captchaValid, setCaptchaValid] = useState(false); + const [openNotif] = useContext(AppContext); + const dispatch = useDispatch(); + + // Sample data for charts + const chartBarData = { + labels: ["فروردین", "اردیبهشت", "خرداد", "تیر", "مرداد", "شهریور"], + datasets: [ + { + label: "فروش", + backgroundColor: ["rgba(33, 72, 214, 0.7)"], + data: [65, 59, 80, 81, 56, 55], + borderRadius: 5, + }, + { + label: "خرید", + backgroundColor: ["rgba(100, 130, 160, 0.7)"], + data: [45, 49, 60, 71, 46, 35], + borderRadius: 5, + }, + ], + }; + + const chartPieData = { + labels: ["فعال", "غیرفعال", "در حال بررسی", "رد شده"], + datasets: [ + { + label: "تعداد", + data: [300, 50, 100, 40], + backgroundColor: [ + "rgba(75, 192, 192, 0.7)", + "rgba(255, 99, 132, 0.7)", + "rgba(255, 205, 86, 0.7)", + "rgba(201, 203, 207, 0.7)", + ], + }, + ], + }; + + const chartLineData = { + labels: ["هفته 1", "هفته 2", "هفته 3", "هفته 4"], + datasets: [ + { + label: "روند رشد", + fill: false, + borderColor: "rgb(75, 192, 192)", + tension: 0.1, + data: [12, 19, 13, 25], + }, + ], + }; + + // Sample data for table + const tableColumns = ["ردیف", "نام", "نام خانوادگی", "شهر", "وضعیت"]; + const tableData = [ + [1, "احمد", "محمدی", "تهران", "فعال"], + [2, "فاطمه", "رضایی", "اصفهان", "فعال"], + [3, "حسین", "کریمی", "مشهد", "غیرفعال"], + [4, "مریم", "احمدی", "شیراز", "فعال"], + [5, "علی", "حسینی", "تبریز", "در حال بررسی"], + ]; + + // Sample data for responsive table + const responsiveTableColumns = [ + "ردیف", + "کد درخواست", + "نام متقاضی", + "تاریخ ثبت", + "مقدار (کیلوگرم)", + "قیمت کل (ریال)", + "وضعیت", + ]; + const responsiveTableData = [ + [ + 1, + "REQ-1001", + "احمد محمدی", + "1402/09/15", + "1,250", + "62,500,000", + "تایید شده", + ], + [ + 2, + "REQ-1002", + "فاطمه رضایی", + "1402/09/16", + "2,100", + "105,000,000", + "در انتظار", + ], + [3, "REQ-1003", "حسین کریمی", "1402/09/17", "850", "42,500,000", "رد شده"], + [ + 4, + "REQ-1004", + "مریم احمدی", + "1402/09/18", + "3,200", + "160,000,000", + "تایید شده", + ], + [ + 5, + "REQ-1005", + "علی حسینی", + "1402/09/19", + "1,750", + "87,500,000", + "در انتظار", + ], + [ + 6, + "REQ-1006", + "زهرا کاظمی", + "1402/09/20", + "950", + "47,500,000", + "تایید شده", + ], + [ + 7, + "REQ-1007", + "محمد تقی‌زاده", + "1402/09/21", + "2,450", + "122,500,000", + "تایید شده", + ], + [ + 8, + "REQ-1008", + "سارا موسوی", + "1402/09/22", + "1,100", + "55,000,000", + "در انتظار", + ], + [ + 9, + "REQ-1009", + "رضا نوری", + "1402/09/23", + "3,800", + "190,000,000", + "تایید شده", + ], + [ + 10, + "REQ-1010", + "نرگس احمدی", + "1402/09/24", + "1,450", + "72,500,000", + "رد شده", + ], + [ + 11, + "REQ-1011", + "امیر حسینی", + "1402/09/25", + "2,650", + "132,500,000", + "تایید شده", + ], + [ + 12, + "REQ-1012", + "لیلا کریمی", + "1402/09/26", + "890", + "44,500,000", + "در انتظار", + ], + ]; + + const components = [ + { + category: "🧭 Navigation", + items: [ + { + name: "BackButton", + description: "دکمه بازگشت با آیکون", + path: "components/back-button/BackButton.js", + component: , + }, + ], + }, + { + category: "🔘 Buttons & Actions", + items: [ + { + name: "ButtonWithIcon", + description: "دکمه با آیکون - انواع مختلف", + path: "components/button-with-icon/ButtonWithIcon.js", + component: ( + + alert("کلیک روی صفحه اصلی")} + /> + alert("کلیک روی افزودن")} + /> + alert("کلیک روی جستجو")} + /> + alert("کلیک روی حذف")} + /> + alert("کلیک روی ویرایش")} + /> + alert("کلیک روی ذخیره")} + /> + alert("کلیک روی تنظیمات")} + /> + alert("کلیک روی پروفایل")} + /> + + ), + }, + ], + }, + { + category: "🎴 Cards & Display", + items: [ + { + name: "CustomCard", + description: "کارت سفارشی با گرادیانت و تصویر پس‌زمینه", + path: "components/custom-card/CustomCard.js", + component: ( + + + + + + + ), + }, + ], + }, + { + category: "📐 Layout & Structure", + items: [ + { + name: "LineWithText", + description: "خط تقسیم کننده با متن و گرادیانت رنگی", + path: "components/line-with-text/LineWithText.js", + component: ( + + + + محتوای بخش اول + + + + محتوای بخش دوم + + + + ), + }, + ], + }, + { + category: "⏱️ Time & Counters", + items: [ + { + name: "Timer", + description: "تایمر شمارش معکوس با فرمت‌های مختلف", + path: "components/timer/Timer.js", + component: ( + + + + تایمر ساعتی (HH:MM:SS): + + + + + + + + تایمر روزانه (DD:HH:MM:SS): + + + + + + + ), + }, + ], + }, + { + category: "📝 Forms & Inputs", + items: [ + { + name: "Captcha", + description: "کد امنیتی (کپچا) با قابلیت تولید مجدد و پخش صوتی", + path: "components/captcha/Captcha.js", + component: ( + + setCaptchaValid(isValid)} /> + + وضعیت: {captchaValid ? "✅ معتبر" : "❌ نامعتبر"} + + + ), + }, + ], + }, + { + category: "🔔 Modals & Dialogs", + items: [ + { + name: "Modal (Global)", + description: "سیستم مودال سراسری با Redux", + path: "components/modal/Modal.js", + component: ( + + + + + + + + این کامپوننت از Redux (appSlice) استفاده می‌کند + + + ), + }, + { + name: "DialogAlert", + description: "دیالوگ با دکمه تریگر داخلی", + path: "components/dialog-alert/DialogAlert.js", + component: ( + + + پذیرفتم + , + , + ]} + /> + + این کامپوننت دکمه تریگر خود را دارد (چک‌باکس + متن) + + + ), + }, + ], + }, + { + category: "📢 Notifications", + items: [ + { + name: "Notif (Global)", + description: "سیستم نوتیفیکیشن سراسری", + path: "components/notif/Notif.js", + component: ( + + + + + + + این کامپوننت از AppContext استفاده می‌کند + + + ), + }, + ], + }, + { + category: "📊 Charts", + items: [ + { + name: "ChartBar", + description: "نمودار میله‌ای با داده‌های واقعی", + path: "components/chart-bar/ChartBar.js", + component: ( + + + + ), + }, + { + name: "ChartPie", + description: "نمودار دایره‌ای", + path: "components/chart-pie/ChartPie.js", + component: ( + + + + ), + }, + { + name: "ChartLinear", + description: "نمودار خطی", + path: "components/chart-linear/ChartLinear.js", + component: ( + + + + ), + }, + { + name: "ChartDoughnut", + description: "نمودار دونات", + path: "components/chart-doughnut/ChartDoughnut.js", + component: ( + + + + ), + }, + { + name: "Other Charts", + description: "سایر نمودارهای موجود", + path: "components/chart-*/", + component: ( + + + نمودارهای دیگر موجود: + + + {[ + "ChartRadar", + "ChartPolarArea", + "ChartBubble", + "ChartScatter", + "AdvancedChart", + ].map((name) => ( + + ))} + + + ), + }, + ], + }, + { + category: "📋 Tables", + items: [ + { + name: "SimpleTable", + description: "جدول ساده با داده‌های واقعی", + path: "components/simple-table/SimpleTable.js", + component: ( + + + + ), + }, + { + name: "ResponsiveTable", + description: "جدول پیشرفته با فیلتر، مرتب‌سازی و صفحه‌بندی", + path: "components/responsive-table/ResponsiveTable.js", + component: ( + + + + قابلیت‌ها: مرتب‌سازی کلیک روی هدر، فیلتر ستون‌ها، جستجو، + صفحه‌بندی، و محاسبه مجموع + + + ), + }, + { + name: "Other Tables", + description: "سایر جداول موجود در سیستم", + path: "components/table-*/", + component: ( + + + کامپوننت‌های جدول موجود: + + + {[ + "ModernTable", + "AdvancedTable", + "ResponsiveTable", + "MuiTable", + "MyTable", + "FlexTable", + "PageTable", + "PageTableApi", + "AdvancedTablePage", + ].map((name) => ( + + ))} + + + این کامپوننت‌ها نیاز به داده‌های جدولی دارند + + + ), + }, + ], + }, + { + category: "📤 File Upload (Documentation Only)", + items: [ + { + name: "Upload Components", + description: "کامپوننت‌های آپلود فایل", + path: "components/file-uploader/", + component: ( + + + کامپوننت‌های آپلود موجود: + + + {[ + "FileUploader", + "ImageUpload", + "ImgUploader", + "ExcelUploadButton", + ].map((name) => ( + + ))} + + + این کامپوننت‌ها برای آپلود فایل‌های مختلف استفاده می‌شوند + + + ), + }, + ], + }, + { + category: "🎯 Specialized (Documentation Only)", + items: [ + { + name: "Other Components", + description: "سایر کامپوننت‌های تخصصی سیستم", + path: "components/", + component: ( + + + کامپوننت‌های تخصصی: + + + {[ + "StateStepper", + "ChatSystem", + "TicketSummary", + "Dashboard", + "Map", + "ShowImage", + "ExcelLink", + "CheckClearanceCode", + "BoxList", + "LinkItem", + "BankCard", + "CarPelak", + "DatePicker", + "SelectCheck", + "AutocompleteSelect", + "TextInput", + "NumberFormatCustom", + "RequestsAwaitingPayment", + "RequestsAwaitingInspections", + "Drawer", + "Backdrop", + "ErrorFallback", + "TimeToLogout", + ].map((name) => ( + + ))} + + + این کامپوننت‌ها برای موارد خاص سیستم طراحی شده‌اند + + + ), + }, + ], + }, + ]; + + const filteredComponents = components + .map((category) => ({ + ...category, + items: category.items.filter( + (item) => + item.name.toLowerCase().includes(searchTerm.toLowerCase()) || + item.description.includes(searchTerm) + ), + })) + .filter((category) => category.items.length > 0); + + return ( + + + + {/* Header */} + + + 📚 کاتالوگ کامپوننت‌های سیستم رصدیار + + + نمایش زنده و تعاملی تمامی کامپوننت‌های قابل استفاده در پروژه + + + + {/* Search Box */} + setSearchTerm(e.target.value)} + InputProps={{ + startAdornment: ( + + ), + }} + /> + + {/* Stats */} + + acc + cat.items.length, + 0 + )} کامپوننت`} + color="primary" + variant="outlined" + /> + + + + + {/* Components List */} + {filteredComponents.map((category, catIndex) => ( + + + {category.category} + + + {category.items.map((component, compIndex) => ( + + + + {/* Component Info */} + + + {component.name} + + + {component.description} + + + 📁 {component.path} + + + + {/* Live Component Render */} + + + + 🎨 نمایش زنده: + + + {component.component} + + + + + + ))} + + ))} + + {filteredComponents.length === 0 && ( + + + کامپوننتی با این عبارت جستجو پیدا نشد + + + )} + + + + ); +}; + +export default ComponentsCatalog; diff --git a/src/pages/DashboardPage.js b/src/pages/DashboardPage.js new file mode 100644 index 0000000..063290a --- /dev/null +++ b/src/pages/DashboardPage.js @@ -0,0 +1,31 @@ +import { Box } from "@mui/material"; +import { Grid } from "../components/grid/Grid"; +import { useLocation } from "react-router-dom"; +import { + ROUTE_ADMINX_DASHBOARD, + ROUTE_PROVINCE_DASHBOARD, + ROUTE_PROVINCE_SUPERVISOR_DASHBOARD, + ROUTE_SUPER_ADMIN_DASHBOARD, +} from "../routes/routes"; +import { DashboardTab } from "../features/dashboard/components/dashboard-tab/DashboardTab"; +import { BackButton } from "../components/back-button/BackButton"; + +const DashboardPage = () => { + const { pathname } = useLocation(); + + return ( + + + + {(pathname.includes(ROUTE_ADMINX_DASHBOARD) || + pathname.includes(ROUTE_SUPER_ADMIN_DASHBOARD) || + pathname.includes(ROUTE_PROVINCE_DASHBOARD) || + pathname.includes(ROUTE_PROVINCE_SUPERVISOR_DASHBOARD)) && ( + + )} + + + ); +}; + +export default DashboardPage; diff --git a/src/pages/DiffrenceKillerPage.js b/src/pages/DiffrenceKillerPage.js new file mode 100644 index 0000000..5454b21 --- /dev/null +++ b/src/pages/DiffrenceKillerPage.js @@ -0,0 +1,74 @@ +import { Box } from "@mui/material"; +import { useLocation } from "react-router-dom"; +import { Grid } from "../components/grid/Grid"; +import { SPACING } from "../data/spacing"; +import { + ROUTE_ADMINX_DIFFRENCE_KILLER, + ROUTE_ADMINX_DIFFRENCE_KILLER_SLAUGHTER, + ROUTE_ADMINX_INCREASE_HATCHING, + ROUTE_CITY_DIFFRENCE_KILLER, + ROUTE_CITY_DIFFRENCE_KILLER_SLAUGHTER, + ROUTE_CITY_INCREASE_HATCHING, + ROUTE_PROVINCE_DIFFRENCE_KILLER, + ROUTE_PROVINCE_DIFFRENCE_KILLER_SLAUGHTER, + ROUTE_PROVINCE_INCREASE_HATCHING, + ROUTE_SUPER_ADMIN_DIFFRENCE_KILLER, + ROUTE_SUPER_ADMIN_DIFFRENCE_KILLER_SLAUGHTER, + ROUTE_SUPER_ADMIN_INCREASE_HATCHING, +} from "../routes/routes"; +import { CityManageDiffrenceKillerOperation } from "../features/city/components/city_manage-diffrence-killer-operation/CityManageDiffrenceKillerOperation"; +import { ProvinceBarDifference } from "../features/province/components/province-bar-difference/ProvinceBarDifference"; +import { BackButton } from "../components/back-button/BackButton"; +import { CityIncreaseHatching } from "../features/city/components/city-increase-hatching/CityIncreaseHatching"; + +const DiffrenceKillerPage = () => { + const { pathname } = useLocation(); + + return ( + <> + + + + + {pathname === ROUTE_ADMINX_DIFFRENCE_KILLER || + pathname === ROUTE_SUPER_ADMIN_DIFFRENCE_KILLER || + pathname === ROUTE_CITY_DIFFRENCE_KILLER || + pathname === ROUTE_PROVINCE_DIFFRENCE_KILLER ? ( + <> + {" "} + + + + + + ) : ( + + )} + + + + {(pathname.includes(ROUTE_ADMINX_DIFFRENCE_KILLER_SLAUGHTER) || + pathname.includes(ROUTE_SUPER_ADMIN_DIFFRENCE_KILLER_SLAUGHTER) || + pathname.includes(ROUTE_PROVINCE_DIFFRENCE_KILLER_SLAUGHTER) || + pathname.includes(ROUTE_CITY_DIFFRENCE_KILLER_SLAUGHTER)) && ( + + )} + + {(pathname.includes(ROUTE_PROVINCE_INCREASE_HATCHING) || + pathname.includes(ROUTE_ADMINX_INCREASE_HATCHING) || + pathname.includes(ROUTE_CITY_INCREASE_HATCHING) || + pathname.includes(ROUTE_SUPER_ADMIN_INCREASE_HATCHING)) && ( + + )} + + + + + + + + + ); +}; + +export default DiffrenceKillerPage; diff --git a/src/pages/DispenserDashboard.js b/src/pages/DispenserDashboard.js new file mode 100644 index 0000000..e0810f5 --- /dev/null +++ b/src/pages/DispenserDashboard.js @@ -0,0 +1,7 @@ +import React from "react"; + +const DispenserDashboard = () => { + return
    DispenserDashboard
    ; +}; + +export default DispenserDashboard; diff --git a/src/pages/DownloadReport.js b/src/pages/DownloadReport.js new file mode 100644 index 0000000..8704679 --- /dev/null +++ b/src/pages/DownloadReport.js @@ -0,0 +1,186 @@ +import React, { useEffect, useRef, useState } from "react"; +import { Box, Divider, Typography } from "@mui/material"; +import { useParams } from "react-router-dom"; +import { useReactToPrint } from "react-to-print"; +import { useDispatch } from "react-redux"; +import moment from "moment"; +import ProvinceSendLetterFactorReport from "../features/province/components/province-send-letter-factor-report/ProvinceSendLetterFactorReport"; +import { provinceGetAllocationLetterReport } from "../features/province/services/province-get-allocation-letter-report"; +import { Grid } from "../components/grid/Grid"; + +const DownloadReport = () => { + const styles = { + container: { + display: "flex", + flexDirection: "column", + alignItems: "center", + }, + box: { + border: "1px solid #ccc", + borderRadius: "4px", + padding: "10px", + marginBottom: "20px", + }, + innerBox: { + border: "1px solid #eee", + borderRadius: "4px", + padding: "5px", + marginBottom: "5px", + backgroundColor: "#fbfbea", + }, + }; + + const { name } = useParams(); + + const componentRef = useRef(); + + const [factorData, setFactorData] = useState(null); + const dispatch = useDispatch(); + + const handleDownloadFactorDailySlaughter = () => { + try { + const result = dispatch( + provinceGetAllocationLetterReport( + moment(new Date()).format("YYYY-MM-DD") + ) + ); + setFactorData(result); + } catch (error) { + console.error(error); + } + }; + + const printPDF = useReactToPrint({ + content: () => componentRef.current, + documentTitle: "گزارش کشتار روزانه", + }); + + // useEffect(() => { + // if (factorData) { + // printPDF(); + // } + // }, [factorData, printPDF]); + + useEffect(() => { + if (name === "ds") { + handleDownloadFactorDailySlaughter(); + } + }, []); + + return ( + +
    +

    { + printPDF(); + }} + > + جهت دانلود گزارش بصورت فایل پی دی اف کلیک کنید. +

    + + + + {factorData?.payload?.data?.allocation?.map((item, i) => ( + + + + ردیف: {i + 1} + + نام خریدار: {item?.name} + + تلفن: {item?.killHouseOperator?.user?.mobile} + + + شهر: {item?.killHouseOperator?.user?.city?.cityName} + + تعداد کل: {item?.totalQuantity} + + + جزئیات سفارش + + {item?.provinceKillRequest?.map((pkRequest, pkIndex) => ( + + مرغدار: {pkRequest?.poultry} + + تلفن مرغدار: {pkRequest?.poultryMobile} + + تعداد: {pkRequest?.quantity} + + میانگین وزن: {pkRequest?.IndexWeight} + + + ))} + + + ))} + {factorData?.payload?.data?.outProvince?.map((item, i) => ( + + + + ردیف: {factorData?.payload?.data?.allocation.length + i + 1} + + + فروش خارج از استان + + + + نام مرغدار: {item?.poultry?.unitName} ( + {item?.poultry?.user?.mobile}) + + + نام خریدار: {item?.buyer?.firstName} {item?.buyer?.lastName} + + تلفن: {item?.buyer?.mobile} + شهر: {item?.buyer?.city} + میانگین وزن: {item?.IndexWeight} + تعداد کل: {item?.quantity} + + نوع: {item?.freezing ? "انجماد" : "معمولی"} + + + + ))} + + +
    +
    + +
    +
    +
    +
    + ); +}; + +export default DownloadReport; diff --git a/src/pages/Driver.js b/src/pages/Driver.js new file mode 100644 index 0000000..4e034e1 --- /dev/null +++ b/src/pages/Driver.js @@ -0,0 +1,42 @@ +import { Box, Card } from "@mui/material"; +import { Grid } from "../components/grid/Grid"; +import { SPACING } from "../data/spacing"; +import { DriverOperations } from "../features/driver/components/driver-operations/DriverOperations"; +import { useLocation } from "react-router-dom"; +import { ROUTE_DRIVER_CARS, ROUTE_DRIVER_REQUESTS } from "../routes/routes"; +import { DriverRequests } from "../features/driver/components/driver-requests/DriverRequests"; +import { DriverCars } from "../features/driver/components/driver-cars/DriverCars"; + +const Driver = () => { + const { pathname } = useLocation(); + + return ( + <> + + + + + + + + + + {pathname === ROUTE_DRIVER_REQUESTS && } + {pathname === ROUTE_DRIVER_CARS && } + + + + + + ); +}; + +export default Driver; diff --git a/src/pages/File.js b/src/pages/File.js new file mode 100644 index 0000000..873c347 --- /dev/null +++ b/src/pages/File.js @@ -0,0 +1,690 @@ +import Timeline from "@mui/lab/Timeline"; +import TimelineItem from "@mui/lab/TimelineItem"; +import TimelineSeparator from "@mui/lab/TimelineSeparator"; +import TimelineConnector from "@mui/lab/TimelineConnector"; +import TimelineContent from "@mui/lab/TimelineContent"; +import TimelineDot from "@mui/lab/TimelineDot"; +import TimelineOppositeContent, { + timelineOppositeContentClasses, +} from "@mui/lab/TimelineOppositeContent"; +import { Card, IconButton, Typography } from "@mui/material"; +import { Box } from "@mui/system"; +import { SPACING } from "../data/spacing"; +import { PropTypes } from "prop-types"; +import React, { useEffect } from "react"; +import { Grid } from "../components/grid/Grid"; +import { useParams } from "react-router-dom"; +import { formatTime } from "../utils/formatTime"; +import { FileInformation } from "../features/file/components/file-information/FileInformation"; +import { CityInformation } from "../features/file/components/city-information/CityInformation"; +import CityFileOperations from "../features/file/components/city-file-operations/CityFileOperations"; +import ProvinceCheckRequest from "../features/file/components/province-check-request/ProvinceCheckRequest"; +import { ProvinceInformation } from "../features/file/components/province-information/ProvinceInformation"; +import useRequestFile from "../features/file/hooks/useRequestFile"; +import { ProvinceAllocation } from "../features/file/components/province-allocation/ProvinceAllocation"; +import SlaughterCheckRequest from "../features/file/components/slaughter-check-request/SlaughterCheckRequest"; +import SlaughterAssignCar from "../features/file/components/slaughter-assign-car/SlaughterAssignCar"; +import useGetAllocationInformation from "../features/file/hooks/useGetAllocationInformation"; +import { SlaughterEnterBarWeight } from "../features/file/components/slaughter-enter-bar-weight/SlaughterEnterBarWeight"; +// import { useSlaughterAllocatedRequests } from "../features/file/hooks/useSlaughterAllocatedRequests"; +import FinancialCheckRequestInformation from "../features/file/components/financial-check-request-information/FinancialCheckRequestInformation"; +import useUserProfile from "../features/authentication/hooks/useUserProfile"; +import { FinancialCheckRequestOperation } from "../features/file/components/financial-check-request-operation/FinancialCheckRequestOperation"; +import { getRoleFromUrl } from "../utils/getRoleFromUrl"; +import { SlaughterPayProvinceFactorForm } from "../features/file/components/slaughter-pay-province-factor-form/SlaughterPayProvinceFactorForm"; +import SlaughterPaymentFactor from "../features/file/components/slaughter-payment-factor/SlaughterPaymentFactor"; +import ProvinceFinancialSlaughterCheckRequest from "../features/file/components/province-financial-slaughter-check-request/ProvinceFinancialSlaughterCheckRequest"; +import { Factor } from "../features/province-finacial/components/factor/Factor"; +import FileAuctionStatus from "../features/file/components/file-auction-status/FileAuctionStatus"; +import { FileAuctionWinner } from "../features/file/components/file-auction-winner/FileAuctionWinner"; +import { ProvinceAllocationInformation } from "../features/file/components/province-allocation-information/ProvinceAllocationInformation"; +import { InspectorRequestOperations } from "../features/file/components/inspector-request-operations/InspectorRequestOperations"; +import { useAcceptedSlaughterRequest } from "../features/file/hooks/useAcceptedSlaughterRequest"; +import SlaughterHouseVetCheckRequest from "../features/file/components/slaughter-house-vet-check-request/SlaughterHouseVetCheckRequest"; +// import { useAcceptedSlaughterRequest } from "../features/file/hooks/useAcceptedSlaughterRequest"; +import NavigateNextIcon from "@mui/icons-material/NavigateNext"; +import { useNavigate } from "react-router-dom"; +import { useDispatch } from "react-redux"; +import { cleanFile } from "../lib/redux/slices/fileSlice"; +// import { Timer } from "../components/timer/Timer"; +// import moment from "moment"; +import { getMonthlyPercent } from "../features/file/services/get-monthly-percent"; +import { SlaughterPayPoultryFactorForm } from "../features/file/components/slaughter-pay-poultry-factor-form/SlaughterPayPoultryFactorForm"; +import { SlaughterPaymentFactorPoultry } from "../features/file/components/slaughter-payment-factor-poultry/SlaughterPaymentFactorPoultry"; + +const File = () => { + const navigate = useNavigate(); + const dispatch = useDispatch(); + const { id } = useParams(); + const myFile = useRequestFile(id); + const [roles] = useUserProfile(); + // const slaughterAllocatedRequests = useSlaughterAllocatedRequests(id); + const process = myFile?.file?.process; + const { quantity, provinceAssignments } = useGetAllocationInformation( + process?.poultry?.poultryRequestKey + ); + + useEffect(() => { + dispatch(getMonthlyPercent()); + }, []); + + const provinceKillRequests = process?.provinceKillRequests; + const acceptedSlaughterRequests = useAcceptedSlaughterRequest(id); + + const showEnterBarInfo = process?.auction + ? !!process?.auction?.filter((item) => item.barInfo === null).length + : provinceKillRequests?.some((killRequest, i) => { + const { killHouseRequests } = killRequest; + if (killHouseRequests) { + return !!killHouseRequests?.filter( + (item) => + item.barInfo === null || + item.barInfo?.killHouseAssignmentState === "rejected" + ).length; + } + return false; + }); + + const showSlaughterHouseVetCheckRequest = process?.auction + ? !!process?.auction?.filter((item) => item.barInfo === null).length + : provinceKillRequests?.some((killRequest, i) => { + const { killHouseRequests } = killRequest; + if (killHouseRequests) { + return !!killHouseRequests?.filter((item) => item.barInfo === null) + .length; + } + return false; + }); + + useEffect(() => { + return () => { + dispatch(cleanFile()); + }; + }, []); + + const sellType = process?.filePaymentType; + // const paymentPrice = "123000000"; + + // const paymentDate = moment(new Date(2022, 11, 24, 10, 33, 30, 0)); + // const currentDate = moment(); + // const diff = paymentDate.diff(currentDate); + // let paymentRemainedSeconds = moment.duration(diff).asSeconds(); + + return ( + <> + {process && ( + + + + navigate(-1)} + > + + بازگشت + + + + + + + + مشخصات پرونده با کد سفارش{" "} + {process?.poultry?.poultryOrderCode} + + + + + {!process?.poultry?.poultryAuction ? ( + + (فروش از طریق اتحادیه) + + ) : ( + + (فروش از طریق مزایده) + + )} + + + {sellType === "cash" && ( + prop.palette.warning.dark} + > + (فروش نقدی) + + )} + {sellType === "credit" && ( + prop.palette.warning.dark} + > + (فروش زمان دار - تا یک ماه) + + )} + {sellType === "cash_credit" && ( + prop.palette.warning.dark} + > + (فروش بصورت نقدی و زمان دار) + + )} + + + + + + {/* prop.palette.action.dark} + > + مبلغ قابل پرداخت ={" "} + {paymentPrice.toLocaleString() + " ریال "}× 3% ماهانه + */} + {/* + سررسید نزدیکترین قابل پرداخت + + */} + {/* + prop.palette.action.dark} + > + مبلغ قابل پرداخت ={" "} + {paymentPrice.toLocaleString() + " ریال "}× 3% ماهانه + + */} + + + + + + + + + + + + + + + مشخصات درخواست + + + + + + + + درخواست در تاریخ + + + {formatTime( + process?.poultry?.poultryRegisterDate + )} + + + ثبت شده است. + + + + + + + + + + + + + + + {(getRoleFromUrl() === "CityOperator" || + getRoleFromUrl() === "ProvinceOperator") && + process.city === null && ( + + )} + + {process.auctionsList && process?.poultry?.poultryAuction && ( + + )} + + {process.killHouseWinner && ( + + )} + + {!process.auctionsList && + !process.killHouseWinner && + process?.city && + process.city.cityState === "accept" && ( + + )} + + {!process.killHouseWinner && + getRoleFromUrl() === "ProvinceOperator" && + roles.includes("ProvinceOperator") && + process?.city && + process?.province?.provinceState !== "reject" && + process?.province?.provinceState !== "accept" && ( + + )} + + {!process.auctionsList && + getRoleFromUrl() === "ProvinceOperator" && + roles.includes("ProvinceOperator") && + process?.city && + process?.province?.provinceState === "accept" && + quantity !== 0 && } + + {!process.killHouseWinner && + provinceAssignments && + !!provinceKillRequests?.length && + provinceAssignments?.map((item, i) => { + return ( + + + + + + {!process.killHouseWinner && + getRoleFromUrl() === "KillHouse" && + roles.includes("KillHouse") && + Boolean( + provinceKillRequests?.filter( + (item) => + item.provinceKillReqState !== "accepted" + ).length + ) && + item.provinceKillRequestState === "pending" && ( + + )} + + + ); + })} + + {/* {!process.killHouseWinner && + getRoleFromUrl() === "KillHouse" && + roles.includes("KillHouse") && + Boolean( + provinceKillRequests?.filter( + (item) => item.provinceKillReqState !== "accepted" + ).length + ) && } */} + + {getRoleFromUrl() === "KillHouse" && + roles.includes("KillHouse") && + (acceptedSlaughterRequests.some( + (item) => item.quantity > 0 + ) || + (process.killHouseWinner && + process.killHouseWinner.quantity > 0)) && ( + + )} + + {showSlaughterHouseVetCheckRequest && ( + + )} + + {(getRoleFromUrl() === "KillHouse" || + getRoleFromUrl() === "Poultry" || + getRoleFromUrl() === "ProvinceFinancial") && + (roles.includes("KillHouse") || + roles.includes("Poultry") || + roles.includes("ProvinceFinancial")) && + !!showEnterBarInfo && ( + + )} + + {!process.killHouseWinner && + provinceKillRequests?.map((killRequest, i) => { + const { killHouseRequests } = killRequest; + const d = killHouseRequests + ?.filter((item) => item.barInfo !== null) + .map((item, i) => { + const showSlaughterFactorForm = + (item.barInfo && + item.provinceFactorToKillHouse && + (!item.killHouseFactorToProvince || + item.killHouseFactorToProvince.factorState === + "rejected")) || + (item.provinceFactorToKillHouseForPoultry && + !item.killHouseFactorToPoultry) || + item.killHouseFactorToPoultry?.factorState === + "rejected"; + + const data = [ + [ + item.barcod, + `${item.killHouseName} (${item.killHouseUserProvince}/${item.killHouseUserCity})`, + item.quantity + " قطعه", + item.car?.driverName + + ` (${item.car?.driverMobile})`, + `${item.car?.typeCar} با پلاک ${item.car?.pelak}`, + item.barInfo.killHouseNetWeight + " کیلوگرم", + item.fee + " ریال", + + بدون بار + , + + بدون بار + , + ], + ]; + return ( + + + {getRoleFromUrl() === "ProvinceFinancial" && + roles.includes("ProvinceFinancial") && + !item.provinceFactorToKillHouse && + item.barInfo.killHouseAssignmentState === + "pending" && ( + + )} + + {(getRoleFromUrl() === "KillHouse" || + getRoleFromUrl() === "ProvinceFinancial") && + (roles.includes("KillHouse") || + roles.includes("ProvinceFinancial")) && + showSlaughterFactorForm && ( + <> + {!item.killHouseFactorToProvince && ( + + )} + {item.provinceFactorToKillHouseForPoultry && + !item.killHouseFactorToPoultry && ( + + )} + + )} + + ); + }); + return d; + })} + + {process.killHouseWinner && + process.auction + ?.filter((item) => item.barInfo !== null) + .map((item, i) => { + return ( + + + {getRoleFromUrl() === "ProvinceFinancial" && + roles.includes("ProvinceFinancial") && + !item.provinceFactorToKillHouse && ( + + )} + + ); + })} + + {process.killHouseWinner && + process.auction && + process.auction + ?.filter( + (item) => + item.barInfo && + !item.killHouseFactorToProvince && + item.provinceFactorToKillHouse + ) + .map((item, i) => { + return ( + <> + + {getRoleFromUrl() === "KillHouse" && + roles.includes("KillHouse") && ( + + )} + + ); + })} + + {provinceKillRequests?.map((killRequest, i) => { + const { killHouseRequests } = killRequest; + return killHouseRequests + ?.filter( + (item) => + item.barInfo && + (item.killHouseFactorToProvince || + item.killHouseFactorToPoultry) + ) + .map((item, i) => { + return ( + <> + {item?.killHouseFactorToProvince && ( + + )} + + {getRoleFromUrl() === "ProvinceFinancial" && + roles.includes("ProvinceFinancial") && + item?.killHouseFactorToProvince && + item.killHouseFactorToProvince.factorState === + "pending" && ( + <> + + + )} + + {item?.killHouseFactorToPoultry && ( + + )} + + {item?.killHouseFactorToPoultry && + getRoleFromUrl() === "ProvinceFinancial" && + roles.includes("ProvinceFinancial") && + item.killHouseFactorToPoultry.factorState === + "pending" && ( + + )} + + ); + }); + })} + + {process.killHouseWinner && + process.auction + ?.filter( + (item) => item.barInfo && item.killHouseFactorToProvince + ) + .map((item, i) => { + return ( + <> + + {getRoleFromUrl() === "ProvinceFinancial" && + roles.includes("ProvinceFinancial") && + item.killHouseFactorToProvince.factorState === + "pending" && ( + + )} + + ); + })} + + {process.allocation && ( + + + + )} + {getRoleFromUrl() === "ProvinceInspector" && + roles.includes("ProvinceInspector") && + process.allocation && + process?.poultry?.poultryRequestFinalState === "archive" && ( + + + + + + )} + + + + + )} + + ); +}; + +File.propTypes = { + id: PropTypes.number, +}; +export default File; diff --git a/src/pages/FilesState.js b/src/pages/FilesState.js new file mode 100644 index 0000000..10deb0b --- /dev/null +++ b/src/pages/FilesState.js @@ -0,0 +1,30 @@ +import { Box } from "@mui/material"; +import { Grid } from "../components/grid/Grid"; +import { SPACING } from "../data/spacing"; +import { ProvinceFilesState } from "../features/province/components/province-files-state/ProvinceFilesState"; + +const FilesState = () => { + return ( + <> + + + + + + + + + + + ); +}; + +export default FilesState; diff --git a/src/pages/GeneralDashboard.js b/src/pages/GeneralDashboard.js new file mode 100644 index 0000000..e89c5a5 --- /dev/null +++ b/src/pages/GeneralDashboard.js @@ -0,0 +1,299 @@ +import { Card } from "@mui/material"; +import { Box } from "@mui/system"; +import { useLocation } from "react-router-dom"; +import { Grid } from "../components/grid/Grid"; +import { SPACING } from "../data/spacing"; +import { BasicProfileInformation } from "../features/authentication/components/basic-profile-information/BasicProfileInformation"; +import { GeneralDashboardOperations } from "../features/authentication/components/general-dashboard-operations/GeneralDashboardOperations"; +import { + ROUTE_AVICULTURE_USER_PROFILE, + ROUTE_CITY_USER_PROFILE, + ROUTE_GENERAL_USER_PROFILE, + ROUTE_PROVINCE_USER_PROFILE, + ROUTE_SLAUGHTER_USER_PROFILE, + ROUTE_INSPECTOR_USER_PROFILE, + ROUTE_VETFARM_USER_PROFILE, + DRIVER_USER_PROFILE, + ROUTE_PROVINCE_FINANCIAL_USER_PROFILE, + ROUTE_SLAUGHTER_HOUSE_VET_USER_PROFILE, + ROUTE_STEWARD_USER_PROFILE, + ROUTE_CITYVET_USER_PROFILE, + ROUTE_LIVE_STOCK_USER_PROFILE, + ROUTE_CHAIN_COMPANY_USER_PROFILE, +} from "../routes/routes"; +import useUserProfile from "../features/authentication/hooks/useUserProfile"; +import { CityProfile } from "../features/city/components/city-profile/CityProfile"; +import { ProvinceProfile } from "../features/province/components/province-profile/ProvinceProfile"; +import { VetFarmProfile } from "../features/vet-farm/components/ver-farm-profile/VetFarmProfile"; +import { AvicultureProfile } from "../features/aviculture/components/aviculture-profile/AvicultureProfile"; +import { DriverProfile } from "../features/driver/components/driver-profile/DriverProfile"; +import { InspectorProfile } from "../features/inspector/components/inspector-profile/InspectorProfile"; +import { SlaughterProfile } from "../features/slaughter-house/components/slaughter-profile/SlaughterProfile"; +import { ProvinceFinancialProfile } from "../features/province-finacial/components/province-financial-profile/ProvinceFinancialProfile"; +import { SlaughterHouseVetProfile } from "../features/slaughter-house-vet/components/slaughter-house-vet-profile/SlaughterHouseVetProfile"; +import { GuildProfile } from "../features/guild/components/GuildProfile"; +import { CityVetProfile } from "../features/city-vet/components/CityVetProfile"; +import LiveStockProfile from "../features/live-stock-support/components/live-stock-profile/LiveStockProfile"; +import { ChainCompanyProfile } from "../features/chain-company/components/chain-company-profile/ChainCompanyProfile"; +import { BackButton } from "../components/back-button/BackButton"; +import AccessDashboardV2 from "./AcessDashboardV2"; + +const GeneralDashboard = () => { + const { pathname } = useLocation(); + const [roles] = useUserProfile(); + + return ( + <> + + + {pathname === ROUTE_GENERAL_USER_PROFILE && ( + + + + + + )} + {pathname === ROUTE_GENERAL_USER_PROFILE && ( + + + + + {/* + + */} + + )} + {pathname === "/" ? ( + + + + ) : ( + + {window.location.pathname !== "/dashboard/profile" && ( + + )} + + {roles.map((role, i) => { + switch (role) { + case "CityOperator": + return ( + pathname === ROUTE_CITY_USER_PROFILE && ( + + + + + + ) + ); + case "Poultry": + return ( + pathname === ROUTE_AVICULTURE_USER_PROFILE && ( + + + + + + ) + ); + case "ProvinceOperator": + return ( + pathname === ROUTE_PROVINCE_USER_PROFILE && ( + + + + + + ) + ); + case "ProvinceFinancial": + return ( + pathname === ROUTE_PROVINCE_FINANCIAL_USER_PROFILE && ( + + + + + + ) + ); + case "ProvinceInspector": + return ( + pathname === ROUTE_INSPECTOR_USER_PROFILE && ( + + + + + + ) + ); + case "KillHouse": + return ( + pathname === ROUTE_SLAUGHTER_USER_PROFILE && ( + + + + + + ) + ); + case "KillHouseVet": + return ( + pathname === ROUTE_SLAUGHTER_HOUSE_VET_USER_PROFILE && ( + + + + + + ) + ); + case "VetFarm": + return ( + pathname === ROUTE_VETFARM_USER_PROFILE && ( + + + + + + ) + ); + case "Driver": + return ( + pathname === DRIVER_USER_PROFILE && ( + + + + + + ) + ); + case "Guilds": + return ( + pathname === ROUTE_STEWARD_USER_PROFILE && ( + + + + + + ) + ); + case "CityVet": + return ( + pathname === ROUTE_CITYVET_USER_PROFILE && ( + + + + + + ) + ); + case "ChainCompany": + return ( + pathname === ROUTE_CHAIN_COMPANY_USER_PROFILE && ( + + + + + + ) + ); + case "LiveStockSupport": + return ( + pathname === ROUTE_LIVE_STOCK_USER_PROFILE && ( + + + + + + ) + ); + default: + return null; + } + })} + + + )} + + + + ); +}; + +export default GeneralDashboard; diff --git a/src/pages/GuildManageGuildsPage.js b/src/pages/GuildManageGuildsPage.js new file mode 100644 index 0000000..04aea97 --- /dev/null +++ b/src/pages/GuildManageGuildsPage.js @@ -0,0 +1,36 @@ +import { Box } from "@mui/material"; +import { Grid } from "../components/grid/Grid"; +import { SPACING } from "../data/spacing"; +import { useLocation } from "react-router-dom"; +import GuildMaangeGuilds from "../features/guild/components/GuildManageGuilds"; +import { ROUTE_STEWARD_MANAGE_GUILDS } from "../routes/routes"; + +const GuildManageGuildsPage = () => { + const { pathname } = useLocation(); + + return ( + <> + + + + + {pathname === ROUTE_STEWARD_MANAGE_GUILDS && ( + + )} + + + + + + ); +}; + +export default GuildManageGuildsPage; diff --git a/src/pages/Guilds.js b/src/pages/Guilds.js new file mode 100644 index 0000000..5eacd18 --- /dev/null +++ b/src/pages/Guilds.js @@ -0,0 +1,259 @@ +import { Box } from "@mui/material"; +import { Grid } from "../components/grid/Grid"; +import { SPACING } from "../data/spacing"; +import { useLocation } from "react-router-dom"; +import { + ROUTE_ADMINX_ROUTE_GUILDS, + ROUTE_ADMINX_ROUTE_IN_PROVINCE_GUILDS_DISTRIBUTIONS, + ROUTE_ADMINX_ROUTE_IN_PROVINCE_GUILDS_REQUESTS, + ROUTE_ADMINX_ROUTE_GUILDS_SETTINGS, + ROUTE_ADMINX_ROUTE_IN_PROVINCE_GUILDS, + ROUTE_ADMINX_ROUTE_MANAGE_GUILDS, + ROUTE_ADMINX_ROUTE_OUT_PROVINCE_GUILDS, + ROUTE_ADMINX_ROUTE_IN_PROVINCE_STEWARDS, + ROUTE_CITY_JIHAD_ROUTE_GUILDS, + ROUTE_CITY_JIHAD_ROUTE_MANAGE_GUILDS, + ROUTE_CITY_JIHAD_ROUTE_STEWARDS, + ROUTE_CITY_POULTRY_ROUTE_GUILDS, + ROUTE_CITY_POULTRY_ROUTE_MANAGE_GUILDS, + ROUTE_CITY_POULTRY_ROUTE_STEWARDS, + ROUTE_COMMERCE_ROUTE_GUILDS, + ROUTE_COMMERCE_ROUTE_GUILDS_SETTINGS, + ROUTE_COMMERCE_ROUTE_MANAGE_GUILDS, + ROUTE_COMMERCE_ROUTE_STEWARDS, + ROUTE_GUILD_ROOM_ROUTE_GUILDS, + ROUTE_GUILD_ROOM_ROUTE_GUILDS_REQUESTS, + ROUTE_GUILD_ROOM_ROUTE_MANAGE_GUILDS, + ROUTE_GUILD_ROOM_ROUTE_STEWARDS, + ROUTE_PROVINCE_ROUTE_GUILDS, + ROUTE_PROVINCE_ROUTE_IN_PROVINCE_GUILDS_REQUESTS, + ROUTE_PROVINCE_ROUTE_GUILDS_SETTINGS, + ROUTE_PROVINCE_ROUTE_IN_PROVINCE_GUILDS, + ROUTE_PROVINCE_ROUTE_MANAGE_GUILDS, + ROUTE_PROVINCE_ROUTE_OUT_PROVINCE_GUILDS, + ROUTE_PROVINCE_ROUTE_IN_PROVINCE_STEWARDS, + ROUTE_PROVINCE_SUPERVISOR_ROUTE_GUILDS, + ROUTE_PROVINCE_SUPERVISOR_ROUTE_GUILDS_SETTINGS, + ROUTE_PROVINCE_SUPERVISOR_ROUTE_MANAGE_GUILDS, + ROUTE_PROVINCE_SUPERVISOR_ROUTE_STEWARDS, + ROUTE_SUPER_ADMIN_ROUTE_GUILDS, + ROUTE_SUPER_ADMIN_ROUTE_IN_PROVINCE_GUILDS_DISTRIBUTIONS, + ROUTE_SUPER_ADMIN_ROUTE_IN_PROVINCE_GUILDS_REQUESTS, + ROUTE_SUPER_ADMIN_ROUTE_GUILDS_SETTINGS, + ROUTE_SUPER_ADMIN_ROUTE_IN_PROVINCE_GUILDS, + ROUTE_SUPER_ADMIN_ROUTE_MANAGE_GUILDS, + ROUTE_SUPER_ADMIN_ROUTE_OUT_PROVINCE_GUILDS, + ROUTE_SUPER_ADMIN_ROUTE_IN_PROVINCE_STEWARDS, + ROUTE_SUPER_ADMIN_ROUTE_IN_PROVINCE_TRUE_GUILDS, + ROUTE_ADMINX_ROUTE_IN_PROVINCE_TRUE_GUILDS, + ROUTE_PROVINCE_ROUTE_IN_PROVINCE_TRUE_GUILDS, + ROUTE_SUPER_ADMIN_ROUTE_OUT_PROVINCE_TRUE_GUILDS, + ROUTE_ADMINX_ROUTE_OUT_PROVINCE_TRUE_GUILDS, + ROUTE_PROVINCE_ROUTE_OUT_PROVINCE_TRUE_GUILDS, + ROUTE_SUPER_ADMIN_ROUTE_IN_PROVINCE_LEGAL_GUILDS, + ROUTE_ADMINX_ROUTE_IN_PROVINCE_LEGAL_GUILDS, + ROUTE_PROVINCE_ROUTE_IN_PROVINCE_LEGAL_GUILDS, + ROUTE_SUPER_ADMIN_ROUTE_OUT_PROVINCE_LEGAL_GUILDS, + ROUTE_ADMINX_ROUTE_OUT_PROVINCE_LEGAL_GUILDS, + ROUTE_PROVINCE_ROUTE_OUT_PROVINCE_LEGAL_GUILDS, +} from "../routes/routes"; +import { BackButton } from "../components/back-button/BackButton"; +import { GuildsOperations } from "../features/province/components/guilds-operations/GuildsOperations"; +import { ManageStewards } from "../features/province/components/manage-stewards/ManageStewards"; +import { GuildsSettings } from "../features/province/components/guilds-settings/GuildsSettings"; +import { GuildsOperationsCommerce } from "../features/commerce/components/guilds-operations-commerce/GuildsOperationsCommerce"; +import { getRoleFromUrl } from "../utils/getRoleFromUrl"; +import { ManageGuildsRequests } from "../features/province/components/manage-guilds-requests/ManageGuildsRequests"; +import { GuildsOperationsCityJihad } from "../features/city-jihad/components/guilds-operations-city-jihad/GuildsOperationsCityJihad"; +import { GuildRoomOperations } from "../features/guild-room/components/guild-room-operations/GuildRoomOperations"; +import { ManageTab } from "../features/province/components/manage-tab/ManageTab"; +import { ManageGuildDistributions } from "../features/province/components/manage-guild-distributions/ManageGuildDistributions"; +import { ProvinceTrueGuildsOutProvince } from "../features/province/components/province-true-guilds-out-province/ProvinceTrueGuildsOutProvince"; +import { ProvinceLegalGuildsInProvince } from "../features/province/components/province-legal-guilds-in-province/ProvinceLegalGuildsInProvince"; +import { ProvinceLegalGuildsOutProvince } from "../features/province/components/province-legal-guilds-out-province/ProvinceLegalGuildsOutProvince"; + +const MANAGE_ROUTES = [ + ROUTE_PROVINCE_ROUTE_MANAGE_GUILDS, + ROUTE_COMMERCE_ROUTE_MANAGE_GUILDS, + ROUTE_PROVINCE_SUPERVISOR_ROUTE_MANAGE_GUILDS, + ROUTE_GUILD_ROOM_ROUTE_MANAGE_GUILDS, + ROUTE_CITY_JIHAD_ROUTE_MANAGE_GUILDS, + ROUTE_CITY_POULTRY_ROUTE_MANAGE_GUILDS, + ROUTE_SUPER_ADMIN_ROUTE_MANAGE_GUILDS, + ROUTE_ADMINX_ROUTE_MANAGE_GUILDS, + ROUTE_SUPER_ADMIN_ROUTE_IN_PROVINCE_GUILDS, + ROUTE_ADMINX_ROUTE_IN_PROVINCE_GUILDS, + ROUTE_PROVINCE_ROUTE_IN_PROVINCE_GUILDS, + ROUTE_SUPER_ADMIN_ROUTE_OUT_PROVINCE_GUILDS, + ROUTE_ADMINX_ROUTE_OUT_PROVINCE_GUILDS, + ROUTE_PROVINCE_ROUTE_OUT_PROVINCE_GUILDS, +]; + +const GUILDS_OPERATIONS_ROUTES = [ + ROUTE_PROVINCE_ROUTE_MANAGE_GUILDS, + ROUTE_SUPER_ADMIN_ROUTE_MANAGE_GUILDS, + ROUTE_ADMINX_ROUTE_MANAGE_GUILDS, + ROUTE_SUPER_ADMIN_ROUTE_IN_PROVINCE_GUILDS, + ROUTE_ADMINX_ROUTE_IN_PROVINCE_GUILDS, + ROUTE_PROVINCE_ROUTE_IN_PROVINCE_GUILDS, + ROUTE_SUPER_ADMIN_ROUTE_OUT_PROVINCE_GUILDS, + ROUTE_ADMINX_ROUTE_OUT_PROVINCE_GUILDS, + ROUTE_PROVINCE_ROUTE_OUT_PROVINCE_GUILDS, +]; + +const GUILDS_OPERATIONS_COMMERCE_ROUTES = [ + ROUTE_COMMERCE_ROUTE_MANAGE_GUILDS, + ROUTE_PROVINCE_SUPERVISOR_ROUTE_MANAGE_GUILDS, +]; + +const GUILDS_OPERATIONS_CITY_JIHAD_ROUTES = [ + ROUTE_CITY_JIHAD_ROUTE_MANAGE_GUILDS, + ROUTE_CITY_POULTRY_ROUTE_MANAGE_GUILDS, +]; + +const MANAGE_TAB_ROUTES = [ + ROUTE_PROVINCE_ROUTE_GUILDS, + ROUTE_SUPER_ADMIN_ROUTE_GUILDS, + ROUTE_ADMINX_ROUTE_GUILDS, + ROUTE_COMMERCE_ROUTE_GUILDS, + ROUTE_GUILD_ROOM_ROUTE_GUILDS, + ROUTE_PROVINCE_SUPERVISOR_ROUTE_GUILDS, + ROUTE_CITY_JIHAD_ROUTE_GUILDS, + ROUTE_CITY_POULTRY_ROUTE_GUILDS, + ROUTE_PROVINCE_ROUTE_IN_PROVINCE_TRUE_GUILDS, + ROUTE_ADMINX_ROUTE_IN_PROVINCE_TRUE_GUILDS, + ROUTE_SUPER_ADMIN_ROUTE_IN_PROVINCE_TRUE_GUILDS, +]; + +const STEWARDS_ROUTES = [ + ROUTE_PROVINCE_ROUTE_IN_PROVINCE_STEWARDS, + ROUTE_SUPER_ADMIN_ROUTE_IN_PROVINCE_STEWARDS, + ROUTE_ADMINX_ROUTE_IN_PROVINCE_STEWARDS, + ROUTE_COMMERCE_ROUTE_STEWARDS, + ROUTE_GUILD_ROOM_ROUTE_STEWARDS, + ROUTE_PROVINCE_SUPERVISOR_ROUTE_STEWARDS, + ROUTE_CITY_POULTRY_ROUTE_STEWARDS, + ROUTE_CITY_JIHAD_ROUTE_STEWARDS, +]; + +const GUILDS_SETTINGS_ROUTES = [ + ROUTE_PROVINCE_ROUTE_GUILDS_SETTINGS, + ROUTE_SUPER_ADMIN_ROUTE_GUILDS_SETTINGS, + ROUTE_ADMINX_ROUTE_GUILDS_SETTINGS, + ROUTE_PROVINCE_SUPERVISOR_ROUTE_GUILDS_SETTINGS, + ROUTE_COMMERCE_ROUTE_GUILDS_SETTINGS, +]; + +const GUILDS_REQUESTS_ROUTES = [ + ROUTE_PROVINCE_ROUTE_IN_PROVINCE_GUILDS_REQUESTS, + ROUTE_SUPER_ADMIN_ROUTE_IN_PROVINCE_GUILDS_REQUESTS, + ROUTE_ADMINX_ROUTE_IN_PROVINCE_GUILDS_REQUESTS, + ROUTE_GUILD_ROOM_ROUTE_GUILDS_REQUESTS, +]; + +const GUILDS_DISTRIBUTIONS_ROUTES = [ + ROUTE_SUPER_ADMIN_ROUTE_IN_PROVINCE_GUILDS_DISTRIBUTIONS, + ROUTE_ADMINX_ROUTE_IN_PROVINCE_GUILDS_DISTRIBUTIONS, +]; + +const TRUE_GUILDS_OUT_PROVINCE_ROUTES = [ + ROUTE_SUPER_ADMIN_ROUTE_OUT_PROVINCE_TRUE_GUILDS, + ROUTE_ADMINX_ROUTE_OUT_PROVINCE_TRUE_GUILDS, + ROUTE_PROVINCE_ROUTE_OUT_PROVINCE_TRUE_GUILDS, +]; + +const LEGAL_GUILDS_IN_PROVINCE_ROUTES = [ + ROUTE_SUPER_ADMIN_ROUTE_IN_PROVINCE_LEGAL_GUILDS, + ROUTE_ADMINX_ROUTE_IN_PROVINCE_LEGAL_GUILDS, + ROUTE_PROVINCE_ROUTE_IN_PROVINCE_LEGAL_GUILDS, +]; + +const LEGAL_GUILDS_OUT_PROVINCE_ROUTES = [ + ROUTE_SUPER_ADMIN_ROUTE_OUT_PROVINCE_LEGAL_GUILDS, + ROUTE_ADMINX_ROUTE_OUT_PROVINCE_LEGAL_GUILDS, + ROUTE_PROVINCE_ROUTE_OUT_PROVINCE_LEGAL_GUILDS, +]; + +const isPathnameIn = (pathname, routes) => routes.includes(pathname); + +const isPathnameIncludes = (pathname, routes) => + routes.some((route) => pathname.includes(route)); + +const Guilds = () => { + const { pathname } = useLocation(); + const role = getRoleFromUrl(); + const isKillHouse = role === "KillHouse"; + + return ( + <> + + + {isPathnameIn(pathname, MANAGE_ROUTES) ? ( + + {isPathnameIn(pathname, GUILDS_OPERATIONS_ROUTES) && ( + + )} + {isPathnameIn(pathname, GUILDS_OPERATIONS_COMMERCE_ROUTES) && ( + + )} + {isPathnameIn(pathname, GUILDS_OPERATIONS_CITY_JIHAD_ROUTES) && ( + + )} + {pathname === ROUTE_GUILD_ROOM_ROUTE_MANAGE_GUILDS && ( + + )} + + ) : ( + + )} + + + + {(isPathnameIn(pathname, MANAGE_TAB_ROUTES) || isKillHouse) && ( + + )} + + {isPathnameIncludes(pathname, STEWARDS_ROUTES) && ( + + )} + + {isPathnameIn(pathname, GUILDS_SETTINGS_ROUTES) && ( + + )} + + {isPathnameIn(pathname, GUILDS_REQUESTS_ROUTES) && ( + + )} + + {isPathnameIn(pathname, GUILDS_DISTRIBUTIONS_ROUTES) && ( + + )} + + {isPathnameIn(pathname, TRUE_GUILDS_OUT_PROVINCE_ROUTES) && ( + + )} + + {isPathnameIn(pathname, LEGAL_GUILDS_IN_PROVINCE_ROUTES) && ( + + )} + + {isPathnameIn(pathname, LEGAL_GUILDS_OUT_PROVINCE_ROUTES) && ( + + )} + + + + + + ); +}; + +export default Guilds; diff --git a/src/pages/Hatching.js b/src/pages/Hatching.js new file mode 100644 index 0000000..eddcf7f --- /dev/null +++ b/src/pages/Hatching.js @@ -0,0 +1,32 @@ +import { Box } from "@mui/material"; +import { Grid } from "../components/grid/Grid"; +import { SPACING } from "../data/spacing"; +import { BackButton } from "../components/back-button/BackButton"; +import { HatchingDetails } from "../features/commerce/components/hatching-details/HatchingDetails"; + +const HatchingPage = () => { + return ( + <> + + + + + + + + + + + + ); +}; + +export default HatchingPage; diff --git a/src/pages/Inspection.js b/src/pages/Inspection.js new file mode 100644 index 0000000..6487bf8 --- /dev/null +++ b/src/pages/Inspection.js @@ -0,0 +1,240 @@ +import { useContext, useEffect, useState } from "react"; +import { useDispatch } from "react-redux"; +import moment from "moment"; +import { Button, TextField, Tooltip, IconButton, Box } from "@mui/material"; +import { DatePicker } from "@mui/x-date-pickers"; +import { RiSearchLine, RiFileExcel2Fill } from "react-icons/ri"; +import axios from "axios"; +import { AppContext } from "../contexts/AppContext"; +import { + LOADING_END, + LOADING_START, + OPEN_MODAL, +} from "../lib/redux/slices/appSlice"; +import { Grid } from "../components/grid/Grid"; +import { SPACING } from "../data/spacing"; +import ResponsiveTable from "../components/responsive-table/ResponsiveTable"; +import { BackButton } from "../components/back-button/BackButton"; +import { inspectorGetPoultryScienceReport } from "../features/inspector/services/inspector-get-poultry-science-report"; +import { InspectionDetailsModal } from "../components/inspection-details-modal/InspectionDetailsModal"; +import VisibilityIcon from "@mui/icons-material/Visibility"; +import { formatJustDate } from "../utils/formatTime"; + +const Inspection = () => { + const dispatch = useDispatch(); + const [textValue, setTextValue] = useState(""); + const [totalRows, setTotalRows] = useState(0); + const [perPage, setPerPage] = useState(10); + const [data, setData] = useState([]); + const [tableData, setTableData] = useState([]); + const [page, setPage] = useState(1); + + const [, , selectedDate1, setSelectedDate1, selectedDate2, setSelectedDate2] = + useContext(AppContext); + const [openNotif] = useContext(AppContext); + + useEffect(() => { + const currentDate = moment(new Date()).format("YYYY-MM-DD"); + setSelectedDate1(currentDate); + setSelectedDate2(currentDate); + }, []); + + const handleTextChange = (event) => { + setTextValue(event.target.value); + }; + + const fetchApiData = async (page) => { + dispatch(LOADING_START()); + try { + const response = await inspectorGetPoultryScienceReport(page, perPage); + setData(response.results || []); + setTotalRows(response.count || 0); + } catch (error) { + console.error("Error fetching inspection data:", error); + setData([]); + setTotalRows(0); + } + dispatch(LOADING_END()); + }; + + const handlePageChange = (page) => { + fetchApiData(page); + setPage(page); + }; + + const handlePerRowsChange = (perRows) => { + setPerPage(perRows); + setPage(1); + fetchApiData(1); + }; + + const handleSubmit = async (event) => { + event.preventDefault(); + setPage(1); + fetchApiData(1); + }; + + const handleViewDetails = (item) => { + dispatch( + OPEN_MODAL({ + title: "جزئیات", + size: 1280, + content: , + }) + ); + }; + + const getInspectionStatus = (item) => { + if (item?.state === "pending") { + return "در انتظار تایید"; + } else if (item?.state === "accepted") { + return "تایید شده"; + } else if (item?.state === "rejected") { + return "رد شده"; + } + }; + + useEffect(() => { + const d = data?.map((item, i) => { + return [ + page === 1 ? i + 1 : i + perPage * (page - 1) + 1, + formatJustDate(item?.date) || "-", + item?.reportId || "-", + item?.hatching?.poultry?.unitName || "-", + item?.hatching?.poultry?.breedingUniqueId || "-", + item?.hatching?.licenceNumber || "-", + item?.hatching?.poultry?.user?.city?.name || "-", + formatJustDate(item?.hatching?.date) || "-", + item?.hatching?.quantity?.toLocaleString() || "-", + getInspectionStatus(item) || "-", + + handleViewDetails(item)} + size="small" + > + + + , + ]; + }); + setTableData(d || []); + }, [data, page, perPage]); + + useEffect(() => { + fetchApiData(1); + }, [selectedDate1, selectedDate2, perPage]); + + return ( + + + + + +
    + + + } + value={selectedDate1} + onChange={(e) => { + setSelectedDate1(moment(e).format("YYYY-MM-DD")); + }} + /> + + + } + value={selectedDate2} + onChange={(e) => { + setSelectedDate2(moment(e).format("YYYY-MM-DD")); + }} + /> + + + + + { + openNotif({ + vertical: "top", + horizontal: "center", + msg: "فایل اکسل در حال دانلود می باشد، این عملیات ممکن است زمان بر باشد لطفا صبر کنید.", + severity: "success", + }); + // TODO: Replace with actual Excel export endpoint + const link = `${axios.defaults.baseURL}inspection_excel/?date1=${selectedDate1}&date2=${selectedDate2}&search=filter&value=${textValue}`; + window.location.href = link; + }} + > + + + + +
    +
    + + +
    +
    + ); +}; + +export default Inspection; diff --git a/src/pages/Inspector.js b/src/pages/Inspector.js new file mode 100644 index 0000000..27cd113 --- /dev/null +++ b/src/pages/Inspector.js @@ -0,0 +1,77 @@ +import { Box, Typography } from "@mui/material"; +import { Grid } from "../components/grid/Grid"; +import { SPACING } from "../data/spacing"; +import { + ROUTE_INSPECTOR_ARCHIVED_REQUESTS, + ROUTE_INSPECTOR_REJECTED_REQUESTS, + ROUTE_INSPECTOR_REQUESTS, + ROUTE_INSPECTOR_REQUESTS_NEW_REQUESTS, + ROUTE_PROVINCE_INSPECTOR_AWAITING_INSPECTION_REQUESTS, + ROUTE_PROVINCE_INSPECTOR_AWAITING_PAYMENT_REQUESTS, +} from "../routes/routes"; +import { useLocation } from "react-router-dom"; +import { InspectorNewRequests } from "../features/inspector/components/inspector-new-requests/InspectorNewRequests"; +import { InspectorOperations } from "../features/inspector/components/inspector-operations/InspectorOperations"; +import { InspectorRejectedRequests } from "../features/inspector/components/inspector-rejected-requests/InspectorRejectedRequests"; +import { InspectorArchivedRequests } from "../features/inspector/components/inspector-archived-requests/InspectorArchivedRequests"; +import { RequestsAwaitingPayment } from "../components/requests-awaiting-payment/RequestsAwaitingPayment"; +import { RequestsAwaitingInspections } from "../components/requests-awaiting-inspections/RequestsAwaitingInspections"; +import { BackButton } from "../components/back-button/BackButton"; + +const Inspector = () => { + const { pathname } = useLocation(); + + return ( + <> + + + {pathname === ROUTE_INSPECTOR_REQUESTS ? ( + + + + صفحه مدیریت درخواست ها (بازرس) + + + + + ) : ( + + )} + + + + {pathname === ROUTE_INSPECTOR_REQUESTS_NEW_REQUESTS && ( + + )} + {pathname === ROUTE_INSPECTOR_REJECTED_REQUESTS && ( + + )} + {pathname === ROUTE_INSPECTOR_ARCHIVED_REQUESTS && ( + + )} + + {pathname === + ROUTE_PROVINCE_INSPECTOR_AWAITING_PAYMENT_REQUESTS && ( + + )} + + {pathname === + ROUTE_PROVINCE_INSPECTOR_AWAITING_INSPECTION_REQUESTS && ( + + )} + + + + + + ); +}; +export default Inspector; diff --git a/src/pages/InspectorReporting.js b/src/pages/InspectorReporting.js new file mode 100644 index 0000000..2431b20 --- /dev/null +++ b/src/pages/InspectorReporting.js @@ -0,0 +1,765 @@ +import { + Accordion, + AccordionDetails, + AccordionSummary, + Box, + Button, + Divider, + FormControl, + FormHelperText, + InputLabel, + MenuItem, + Select, + TextField, + Typography, +} from "@mui/material"; +import { Grid } from "../components/grid/Grid"; +import { SPACING } from "../data/spacing"; +import ExpandMoreIcon from "@mui/icons-material/ExpandMore"; +import { useFormik } from "formik"; +import { Yup } from "../lib/yup/yup"; +import { useContext, useEffect, useState } from "react"; +import { useDispatch } from "react-redux"; +import { inspectorGetReporting } from "../features/inspector/services/inspector-get-reporting"; +import { LOADING_END, LOADING_START } from "../lib/redux/slices/appSlice"; +import AddIcon from "@mui/icons-material/Add"; +import RemoveIcon from "@mui/icons-material/Remove"; +import SearchIcon from "@mui/icons-material/Search"; +import { AdvancedTable } from "../components/advanced-table/AdvancedTable"; +import { AppContext } from "../contexts/AppContext"; +import { DatePicker } from "@mui/x-date-pickers"; +import moment from "moment"; +import { format } from "date-fns-jalali"; + +const InspectorReporting = () => { + const [reportData, setReportData] = useState(); + const [tableData, setTableData] = useState(); + const dispatch = useDispatch(); + const [openNotif] = useContext(AppContext); + + const formik = useFormik({ + initialValues: { + mobile: "", + fname: "", + lname: "", + nationalCode: "", + nationalId: "", + address: "", + unitName: "", + gisCode: "", + operationNumber: "", + halls: "", + economicCode: "", + systemCode: "", + epidemiologicalCode: "", + capacity: "", + licenseNumber: "", + healthCode: "", + orderCode: "", + race: "", + }, + validationSchema: Yup.object({ + mobile: Yup.number().typeError("لطفا عدد وارد کنید!"), + fname: Yup.string().typeError("فیلد را به درستی وارد کنید!"), + lname: Yup.string().typeError("فیلد را به درستی وارد کنید!"), + nationalCode: Yup.number().typeError("لطفا عدد وارد کنید!"), + nationalId: Yup.number().typeError("لطفا عدد وارد کنید!"), + address: Yup.string().typeError("فیلد را به درستی وارد کنید!"), + unitName: Yup.string().typeError("فیلد را به درستی وارد کنید!"), + race: Yup.string().typeError("فیلد را به درستی وارد کنید!"), + gisCode: Yup.number().typeError("لطفا عدد وارد کنید!"), + operationNumber: Yup.number().typeError("لطفا عدد وارد کنید!"), + halls: Yup.number().typeError("لطفا عدد وارد کنید!"), + economicCode: Yup.number().typeError("لطفا عدد وارد کنید!"), + systemCode: Yup.number().typeError("لطفا عدد وارد کنید!"), + epidemiologicalCode: Yup.number().typeError("لطفا عدد وارد کنید!"), + capacity: Yup.number().typeError("لطفا عدد وارد کنید!"), + licenseNumber: Yup.number().typeError("لطفا عدد وارد کنید!"), + healthCode: Yup.number().typeError("لطفا عدد وارد کنید!"), + orderCode: Yup.number().typeError("لطفا عدد وارد کنید!"), + }), + }); + + const formikHatching = useFormik({ + initialValues: { + hatchingDateFrom: "", + hatchingDateTo: "", + }, + validationSchema: Yup.object({ + hatchingDateFrom: Yup.string().typeError("فیلد را به درستی وارد کنید!"), + hatchingDateTo: Yup.string().typeError("فیلد را به درستی وارد کنید!"), + }), + }); + + useEffect(() => { + formik.validateForm(); + formikHatching.validateForm(); + }, []); + + const handleValidForm = () => { + if (formik.isValid && formikHatching.isValid) { + if ( + Object.values(formik.values).filter((item) => item.length > 0) + .length === 0 && + Object.values(formikHatching.values).filter((item) => item.length > 0) + .length !== 2 + ) { + return true; + } else { + return false; + } + } else { + return true; + } + }; + + const [expanded, setExpanded] = useState(true); + const handleChange = () => { + setExpanded(!expanded); + }; + + const handleClick = () => { + let values = Object.values(formik.values).filter((item) => item.length > 0); + let finalValue = ""; + + for (let index = 0; index < values.length; index++) { + finalValue = finalValue + values[index] + ","; + } + finalValue = finalValue.substring(0, finalValue.length - 1); + + if (formikHatching.values.hatchingDateFrom) { + finalValue = + finalValue + + "&double_hatching_date=" + + formikHatching.values.hatchingDateFrom + + "," + + formikHatching.values.hatchingDateTo; + } + + if (formik.values) dispatch(LOADING_START()); + dispatch(inspectorGetReporting(finalValue)).then((r) => { + dispatch(LOADING_END()); + if (r.error) { + openNotif({ + vertical: "top", + horizontal: "center", + msg: "مشکلی پیش آمده است!", + severity: "error", + }); + } else { + setReportData(r?.payload.data); + } + }); + }; + + useEffect(() => { + if (reportData) { + const d = reportData.map((item, i) => { + return [ + i + 1, + item.unitName, + item.userprofile?.fullName, + item.breedingUniqueId, + item.numberOfHalls, + item.totalCapacity, + item.userprofile?.mobile, + item.userprofile?.province, + item.userprofile?.city, + item.hatching?.length, + item.numberOfParty, + format(new Date(item?.lastPartyDate), "yyyy/MM/dd"), + item.gisCode, + item.economicCode, + item.samasatUserCode, + item.unitStatus, + ]; + }); + + setTableData(d); + } + }, [reportData]); + + const [addFilter, setAddFilter] = useState(false); + + return ( + <> + + + + } + aria-controls="panel1a-content" + id="panel1a-header" + > + جستجو + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + نژاد مرغ + + + + {formik.touched.race && Boolean(formik.errors.race) + ? formik.errors.race + : null} + + + + + {addFilter && ( + <> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ( + + )} + value={formikHatching.values.hatchingDateFrom} + error={ + formikHatching.touched.hatchingDateFrom + ? Boolean(formikHatching.errors.hatchingDateFrom) + : null + } + onChange={(e) => { + formikHatching.setFieldValue( + "hatchingDateFrom", + moment(e).format("YYYY-MM-DD") + ); + }} + onBlur={formikHatching.handleBlur} + helperText={ + formikHatching.touched.hatchingDateFrom && + Boolean(formikHatching.errors.hatchingDateFrom) + ? formikHatching.errors.hatchingDateFrom + : null + } + /> + + + ( + + )} + value={formikHatching.values.hatchingDateTo} + error={ + formikHatching.touched.hatchingDateTo + ? Boolean(formikHatching.errors.hatchingDateTo) + : null + } + onChange={(e) => { + formikHatching.setFieldValue( + "hatchingDateTo", + moment(e).format("YYYY-MM-DD") + ); + }} + onBlur={formikHatching.handleBlur} + helperText={ + formikHatching.touched.hatchingDateTo && + Boolean(formikHatching.errors.hatchingDateTo) + ? formikHatching.errors.hatchingDateTo + : null + } + /> + + + )} + + + + + + + + + + + + + + + + + + + + + + + ); +}; +export default InspectorReporting; diff --git a/src/pages/JahadIllegalKilling.js b/src/pages/JahadIllegalKilling.js new file mode 100644 index 0000000..178102f --- /dev/null +++ b/src/pages/JahadIllegalKilling.js @@ -0,0 +1,30 @@ +import { Box } from "@mui/material"; +import { Grid } from "../components/grid/Grid"; +import { SPACING } from "../data/spacing"; +import { JahadIllegalKillingComponent } from "../features/jahad/components/jahad-illegal-killing/JahadIllegalKillingComponent"; + +const JahadIllegalKilling = () => { + return ( + <> + + + + + + + + + + + ); +}; + +export default JahadIllegalKilling; diff --git a/src/pages/JahadKillStats.js b/src/pages/JahadKillStats.js new file mode 100644 index 0000000..a244573 --- /dev/null +++ b/src/pages/JahadKillStats.js @@ -0,0 +1,30 @@ +import { Box } from "@mui/material"; +import { Grid } from "../components/grid/Grid"; +import { SPACING } from "../data/spacing"; +import { JahadKillStatsComponent } from "../features/jahad/components/jahad-kill-stats/JahadKillStatsComponent"; + +const JahadKillStats = () => { + return ( + <> + + + + + + + + + + + ); +}; + +export default JahadKillStats; diff --git a/src/pages/KillerManagment.js b/src/pages/KillerManagment.js new file mode 100644 index 0000000..17bb0be --- /dev/null +++ b/src/pages/KillerManagment.js @@ -0,0 +1,30 @@ +import { Box } from "@mui/material"; +import { Grid } from "../components/grid/Grid"; +import { SPACING } from "../data/spacing"; +import { ProvinceKillerManagment } from "../features/province/components/province-killer-managment/ProvinceKillerManagment"; + +const KillerManagment = () => { + return ( + <> + + + + + + + + + + + ); +}; + +export default KillerManagment; diff --git a/src/pages/LiveStockColdHouse.js b/src/pages/LiveStockColdHouse.js new file mode 100644 index 0000000..9394283 --- /dev/null +++ b/src/pages/LiveStockColdHouse.js @@ -0,0 +1,34 @@ +import { Box } from "@mui/material"; +import React from "react"; +import { Grid } from "../components/grid/Grid"; +import { SPACING } from "../data/spacing"; +import { LiveStockColdHouseComponent } from "../features/live-stock-support/components/live-stock-cold-house/LiveStockColdHouse"; + +const LiveStockColdHouse = () => { + return ( + + + + + + + + + + ); +}; + +export default LiveStockColdHouse; diff --git a/src/pages/LiveStockFreezingRequests.js b/src/pages/LiveStockFreezingRequests.js new file mode 100644 index 0000000..b362e47 --- /dev/null +++ b/src/pages/LiveStockFreezingRequests.js @@ -0,0 +1,34 @@ +import { Box } from "@mui/material"; +import React from "react"; +import { Grid } from "../components/grid/Grid"; +import { SPACING } from "../data/spacing"; +import { LiveStockAllFreezingRequests } from "../features/live-stock-support/components/live-stock-all-freezing-requests/LiveStockAllFreezingRequests"; + +const LiveStockFreezingRequests = () => { + return ( + + + + + + + + + + ); +}; + +export default LiveStockFreezingRequests; diff --git a/src/pages/LiveStockSupportCases.js b/src/pages/LiveStockSupportCases.js new file mode 100644 index 0000000..37cec13 --- /dev/null +++ b/src/pages/LiveStockSupportCases.js @@ -0,0 +1,34 @@ +import React from "react"; +import { ProvinceCases } from "../features/province/components/province-cases/ProvinceCases"; +import { Grid } from "../components/grid/Grid"; +import { SPACING } from "../data/spacing"; +import { Box } from "@mui/material"; + +const LiveStockSupportCases = () => { + return ( + + + + + + + + + + ); +}; + +export default LiveStockSupportCases; diff --git a/src/pages/LiveStockSupportManageBars.js b/src/pages/LiveStockSupportManageBars.js new file mode 100644 index 0000000..6ffc940 --- /dev/null +++ b/src/pages/LiveStockSupportManageBars.js @@ -0,0 +1,8 @@ +import React from "react"; +import { VetFarmOperation } from "../features/vet-farm/components/vet-farm-operation/VetFarmOperation"; + +const LiveStockSupportManageBars = () => { + return ; +}; + +export default LiveStockSupportManageBars; diff --git a/src/pages/ManageFarm.js b/src/pages/ManageFarm.js new file mode 100644 index 0000000..dd61296 --- /dev/null +++ b/src/pages/ManageFarm.js @@ -0,0 +1,30 @@ +import { Box } from "@mui/material"; +import { Grid } from "../components/grid/Grid"; +import { SPACING } from "../data/spacing"; +import { ManageFarmComponent } from "../features/inspector/components/manage-farm-component/ManageFarmComponent"; + +const ManageFarm = () => { + return ( + <> + + + + + + + + + + + ); +}; + +export default ManageFarm; diff --git a/src/pages/ManageProcess.js b/src/pages/ManageProcess.js new file mode 100644 index 0000000..c7ee728 --- /dev/null +++ b/src/pages/ManageProcess.js @@ -0,0 +1,164 @@ +import { Box, Typography } from "@mui/material"; +import { useLocation } from "react-router-dom"; +import { BackButton } from "../components/back-button/BackButton"; +import { Grid } from "../components/grid/Grid"; +import { SPACING } from "../data/spacing"; +import { ProvinceManageBuyReq } from "../features/province/components/province-manage-buy-req/ProvinceManageBuyReq"; +import { ProvinceManageProcessOperation } from "../features/province/components/province-manage-process-operation/ProvinceManageProcessOperation"; +import { ProvinceManageSlaughterKillplace } from "../features/province/components/province-manage-slaughter-killplace/ProvinceManageSlaughterKillplace"; +import { ProvinceManageSlaughters } from "../features/province/components/province-manage-slaughters/ProvinceManageSlaughters"; +import { ProvincePolicyCouncil } from "../features/province/components/province-policy-council/ProvincePolicyCouncil"; +import { + ROUTE_ADMINX_ROUTE_ACCOUNTS, + ROUTE_ADMINX_ROUTE_CRONJOB, + ROUTE_ADMINX_ROUTE_Sms_Submission_Management, + ROUTE_ADMINX_ROUTE_MANAGE_PROCESS, + ROUTE_ADMINX_ROUTE_MANAGE_PROCESS_BUY_REQ, + ROUTE_ADMINX_ROUTE_MANAGE_PROCESS_DOCUMENT_STATES, + ROUTE_ADMINX_ROUTE_MANAGE_PROCESS_KILLPLACE, + ROUTE_ADMINX_ROUTE_MANAGE_PROCESS_POLICY_COUNCIL, + ROUTE_ADMINX_ROUTE_MANAGE_PROCESS_SLAUGHTER, + ROUTE_ADMINX_ROUTE_TICKET_PERMISSION, + ROUTE_PROVINCE_ROUTE_MANAGE_PROCESS, + ROUTE_PROVINCE_ROUTE_MANAGE_PROCESS_BUY_REQ, + ROUTE_PROVINCE_ROUTE_MANAGE_PROCESS_KILLPLACE, + ROUTE_PROVINCE_ROUTE_MANAGE_PROCESS_POLICY_COUNCIL, + ROUTE_PROVINCE_ROUTE_MANAGE_PROCESS_SLAUGHTER, + ROUTE_SUPER_ADMIN_ROUTE_MANAGE_PROCESS, + ROUTE_SUPER_ADMIN_ROUTE_MANAGE_PROCESS_BUY_REQ, + ROUTE_SUPER_ADMIN_ROUTE_MANAGE_PROCESS_DOCUMENT_STATES, + ROUTE_SUPER_ADMIN_ROUTE_MANAGE_PROCESS_KILLPLACE, + ROUTE_SUPER_ADMIN_ROUTE_MANAGE_PROCESS_POLICY_COUNCIL, + ROUTE_SUPER_ADMIN_ROUTE_MANAGE_PROCESS_SLAUGHTER, + ROUTE_SUPER_ADMIN_ROUTE_TICKET_PERMISSION, + ROUTE_SUPER_ADMIN_ROUTE_SLAUGHTER_TRADE_PANEL, + ROUTE_ADMINX_ROUTE_SLAUGHTER_TRADE_PANEL, + ROUTE_ADMINX_ROUTE_WEIGHT_RANGE, + ROUTE_ADMINX_ROUTE_WEIGHT_CATEGORY, + ROUTE_SUPER_ADMIN_ROUTE_WEIGHT_CATEGORY, + ROUTE_SUPER_ADMIN_ROUTE_WEIGHT_RANGE, + ROUTE_SUPER_ADMIN_ROUTE_PENALTY, + ROUTE_ADMINX_ROUTE_PENALTY, + ROUTE_ADMINX_ROUTE_MANAGE_DISTRIBUTIONS, + ROUTE_SUPER_ADMIN_ROUTE_MANAGE_DISTRIBUTIONS, + ROUTE_ADMINX_ROUTE_RESTRICTION_OF_CARCASS_DISTRIBUTION, + ROUTE_SUPER_ADMIN_ROUTE_RESTRICTION_OF_CARCASS_DISTRIBUTION, +} from "../routes/routes"; +import { ProvincePolicyDocumentStates } from "../features/province/components/province-policy-document-states/ProvincePolicyDocumentStates"; +import { ProvincePolicyAccounts } from "../features/province/components/province-policy-accounts/ProvincePolicyAccounts"; +import { ProvincePolicyTicketPermission } from "../features/province/components/province-policy-ticket-permission/ProvincePolicyTicketPermission"; +import ProcincePolicyKronjob from "../features/province/components/province-policey-kronjon/ProcincePolicyKronjob"; +import { ProvinceSmsSubmissionManagement } from "../features/province/components/province-sms-submission-management/provinceSmsSubmissionManagement"; +import { ProvinceManageTrades } from "../features/province/components/province-manage-trades/ProvinceManageTrades"; +import { ProvincePolicyManageWeightRange } from "../features/province/components/province-policy-manage-weight-range/ProvincePolicyManageWeightRange"; +import { ProvincePolicyManageWeightCategory } from "../features/province/components/province-policy-manage-weight-category/ProvincePolicyManageWeightCategory"; +import { ProvincePolicyManagePenalty } from "../features/province/components/province-policy-manage-penalty/provincePolicyManagePenalty"; +import { ProvinceManageDistributions } from "../features/province/components/province-manage-distributions/ProvinceManageDistributions"; +import { ProvinceRestrictionCarcassDistribution } from "../features/province/components/province-restriction-carcass-distribution/ProvinceRestrictionCarcassDistribution"; + +const ManageProcess = () => { + const { pathname } = useLocation(); + return ( + <> + + + {pathname === ROUTE_PROVINCE_ROUTE_MANAGE_PROCESS || + pathname === ROUTE_SUPER_ADMIN_ROUTE_MANAGE_PROCESS || + pathname === ROUTE_ADMINX_ROUTE_MANAGE_PROCESS ? ( + + + مدیریت فرآیند + + + + ) : ( + + )} + + + + {(pathname === + ROUTE_PROVINCE_ROUTE_MANAGE_PROCESS_POLICY_COUNCIL || + pathname === + ROUTE_SUPER_ADMIN_ROUTE_MANAGE_PROCESS_POLICY_COUNCIL || + pathname === + ROUTE_ADMINX_ROUTE_MANAGE_PROCESS_POLICY_COUNCIL) && ( + + )} + {(pathname === ROUTE_SUPER_ADMIN_ROUTE_SLAUGHTER_TRADE_PANEL || + pathname === ROUTE_ADMINX_ROUTE_SLAUGHTER_TRADE_PANEL) && ( + + )} + {(pathname === ROUTE_ADMINX_ROUTE_MANAGE_DISTRIBUTIONS || + pathname === ROUTE_SUPER_ADMIN_ROUTE_MANAGE_DISTRIBUTIONS) && ( + + )} + {(pathname === ROUTE_PROVINCE_ROUTE_MANAGE_PROCESS_SLAUGHTER || + pathname === ROUTE_SUPER_ADMIN_ROUTE_MANAGE_PROCESS_SLAUGHTER || + pathname === ROUTE_ADMINX_ROUTE_MANAGE_PROCESS_SLAUGHTER) && ( + + )} + {(pathname === ROUTE_PROVINCE_ROUTE_MANAGE_PROCESS_KILLPLACE || + pathname === ROUTE_SUPER_ADMIN_ROUTE_MANAGE_PROCESS_KILLPLACE || + pathname === ROUTE_ADMINX_ROUTE_MANAGE_PROCESS_KILLPLACE) && ( + + )} + {(pathname === ROUTE_PROVINCE_ROUTE_MANAGE_PROCESS_BUY_REQ || + pathname === ROUTE_SUPER_ADMIN_ROUTE_MANAGE_PROCESS_BUY_REQ || + pathname === ROUTE_ADMINX_ROUTE_MANAGE_PROCESS_BUY_REQ) && ( + + )} + {(pathname === + ROUTE_SUPER_ADMIN_ROUTE_MANAGE_PROCESS_DOCUMENT_STATES || + pathname === + ROUTE_ADMINX_ROUTE_MANAGE_PROCESS_DOCUMENT_STATES) && ( + + )} + {pathname === ROUTE_ADMINX_ROUTE_ACCOUNTS && ( + + )} + {(pathname === ROUTE_ADMINX_ROUTE_TICKET_PERMISSION || + pathname === ROUTE_SUPER_ADMIN_ROUTE_TICKET_PERMISSION) && ( + + )} + {pathname === ROUTE_ADMINX_ROUTE_CRONJOB && ( + + )} + {pathname === ROUTE_ADMINX_ROUTE_Sms_Submission_Management && ( + + )} + {(pathname === ROUTE_ADMINX_ROUTE_WEIGHT_RANGE || + pathname === ROUTE_SUPER_ADMIN_ROUTE_WEIGHT_RANGE) && ( + + )} + {(pathname === ROUTE_ADMINX_ROUTE_WEIGHT_CATEGORY || + pathname === ROUTE_SUPER_ADMIN_ROUTE_WEIGHT_CATEGORY) && ( + + )} + {(pathname === ROUTE_ADMINX_ROUTE_PENALTY || + pathname === ROUTE_SUPER_ADMIN_ROUTE_PENALTY) && ( + + )} + {(pathname === + ROUTE_ADMINX_ROUTE_RESTRICTION_OF_CARCASS_DISTRIBUTION || + pathname === + ROUTE_SUPER_ADMIN_ROUTE_RESTRICTION_OF_CARCASS_DISTRIBUTION) && ( + + )} + + + + + + ); +}; + +export default ManageProcess; diff --git a/src/pages/ManageProcessWageFractions.js b/src/pages/ManageProcessWageFractions.js new file mode 100644 index 0000000..5f8ac28 --- /dev/null +++ b/src/pages/ManageProcessWageFractions.js @@ -0,0 +1,33 @@ +import { Box } from "@mui/material"; +import { BackButton } from "../components/back-button/BackButton"; +import { Grid } from "../components/grid/Grid"; +import { SPACING } from "../data/spacing"; +import ProvincePolicyWagesSetup from "../features/province/components/province-policy-wage-setup/ProvincePolicyWagesSetup"; + +const ManageProcessWageFractions = () => { + return ( + <> + + + + + + + + + + + + + ); +}; + +export default ManageProcessWageFractions; diff --git a/src/pages/Messages.js b/src/pages/Messages.js new file mode 100644 index 0000000..69d06f1 --- /dev/null +++ b/src/pages/Messages.js @@ -0,0 +1,97 @@ +import { Box, Chip, Divider, Typography } from "@mui/material"; +import { useEffect } from "react"; +import { useDispatch, useSelector } from "react-redux"; +import { Grid } from "../components/grid/Grid"; +import { SPACING } from "../data/spacing"; +import MessagesRecivers from "../features/messages/components/messages-recivers/MessagesRecivers"; +import MessagesSenders from "../features/messages/components/messages-senders/MessagesSenders"; +import { messagesGetReciverMessages } from "../features/messages/services/messages-get-reciver-messages"; +import { messagesGetSenderMessages } from "../features/messages/services/messages-get-sender-messages"; + +const Messages = () => { + const { senderMessages } = useSelector((state) => state.messageSlice); + const { reciverMessages } = useSelector((state) => state.messageSlice); + const dispatch = useDispatch(); + + useEffect(() => { + dispatch(messagesGetSenderMessages()); + dispatch(messagesGetReciverMessages()); + }, []); + + return ( + <> + + + + {!senderMessages?.length && !reciverMessages?.length && ( + + در حال حاضر پیامی جهت نمایش وجود ندارد! + + )} + {senderMessages?.length ? ( + + + + ) : ( + "" + )} + + + {senderMessages?.map((item, i) => { + return ( + + ); + })} + + + + + {reciverMessages?.length ? ( + + + + ) : ( + "" + )} + + + {reciverMessages?.map((item, i) => { + return ( + + ); + })} + + + + + + ); +}; + +export default Messages; diff --git a/src/pages/NationalInfo.js b/src/pages/NationalInfo.js new file mode 100644 index 0000000..36f4628 --- /dev/null +++ b/src/pages/NationalInfo.js @@ -0,0 +1,53 @@ +import { Box } from "@mui/material"; +import React from "react"; +import { Grid } from "../components/grid/Grid"; +import { NationalInfo } from "../features/city/components/national-info/NationalInfo"; +import { useLocation, useParams } from "react-router-dom"; +import { NationalInfoHatchingDetails } from "../features/city/components/national-info-hatching-details/NationalInfoHatchingDetails"; +import { + ROUTE_ADMINX_ROUTE_NATIONAL_INFO_SLAUGHTER, + ROUTE_PROVINCE_SUPERVISOR_ROUTE_NATIONAL_INFO_SLAUGHTER, + ROUTE_SUPER_ADMIN_ROUTE_NATIONAL_INFO_SLAUGHTER, +} from "../routes/routes"; +import { NationalInfoTransports } from "../features/city/components/national-info-bars/NationalInfoTransports"; +import { ProvinceChickenDistributionsAndSalesDetails } from "../features/province/components/province-chicken-distribution-and-sales-details/ProvinceChickenDistributionsAndSalesDetails"; + +const NationalInfoPage = () => { + const { key, name, type } = useParams(); + const { pathname } = useLocation(); + const isSlaughterDetailsRoute = + pathname.includes(ROUTE_ADMINX_ROUTE_NATIONAL_INFO_SLAUGHTER) || + pathname.includes( + ROUTE_PROVINCE_SUPERVISOR_ROUTE_NATIONAL_INFO_SLAUGHTER + ) || + pathname.includes(ROUTE_SUPER_ADMIN_ROUTE_NATIONAL_INFO_SLAUGHTER); + + return ( + <> + + + {type ? ( + + ) : isSlaughterDetailsRoute ? ( + + ) : key || name ? ( + + ) : ( + + )} + + + + ); +}; + +export default NationalInfoPage; diff --git a/src/pages/NewFile.js b/src/pages/NewFile.js new file mode 100644 index 0000000..e3fd23c --- /dev/null +++ b/src/pages/NewFile.js @@ -0,0 +1,1439 @@ +import Timeline from "@mui/lab/Timeline"; +import TimelineContent from "@mui/lab/TimelineContent"; +import TimelineOppositeContent, { + timelineOppositeContentClasses, +} from "@mui/lab/TimelineOppositeContent"; +import { + // Button, + Card, + IconButton, + // Paper, + // Step, + // StepContent, + // StepLabel, + // Stepper, + // ToggleButton, + // ToggleButtonGroup, + Typography, +} from "@mui/material"; +import { Box } from "@mui/system"; +import { SPACING } from "../data/spacing"; +import { PropTypes } from "prop-types"; +import React, { useEffect } from "react"; +import { Grid } from "../components/grid/Grid"; +import { useParams } from "react-router-dom"; +import { formatTime } from "../utils/formatTime"; +import { FileInformation } from "../features/file/components/file-information/FileInformation"; +import { CityInformation } from "../features/file/components/city-information/CityInformation"; +// import CityFileOperations from "../features/file/components/city-file-operations/CityFileOperations"; +// import ProvinceCheckRequest from "../features/file/components/province-check-request/ProvinceCheckRequest"; +import { ProvinceInformation } from "../features/file/components/province-information/ProvinceInformation"; +import useRequestFile from "../features/file/hooks/useRequestFile"; +// import { ProvinceAllocation } from "../features/file/components/province-allocation/ProvinceAllocation"; +// import SlaughterCheckRequest from "../features/file/components/slaughter-check-request/SlaughterCheckRequest"; +// import SlaughterAssignCar from "../features/file/components/slaughter-assign-car/SlaughterAssignCar"; +import useGetAllocationInformation from "../features/file/hooks/useGetAllocationInformation"; +// import { SlaughterEnterBarWeight } from "../features/file/components/slaughter-enter-bar-weight/SlaughterEnterBarWeight"; +// import { useSlaughterAllocatedRequests } from "../features/file/hooks/useSlaughterAllocatedRequests"; +import FinancialCheckRequestInformation from "../features/file/components/financial-check-request-information/FinancialCheckRequestInformation"; +import useUserProfile from "../features/authentication/hooks/useUserProfile"; +import { FinancialCheckRequestOperation } from "../features/file/components/financial-check-request-operation/FinancialCheckRequestOperation"; +import { getRoleFromUrl } from "../utils/getRoleFromUrl"; +import { SlaughterPayProvinceFactorForm } from "../features/file/components/slaughter-pay-province-factor-form/SlaughterPayProvinceFactorForm"; +import SlaughterPaymentFactor from "../features/file/components/slaughter-payment-factor/SlaughterPaymentFactor"; +// import ProvinceFinancialSlaughterCheckRequest from "../features/file/components/province-financial-slaughter-check-request/ProvinceFinancialSlaughterCheckRequest"; +import { Factor } from "../features/province-finacial/components/factor/Factor"; +import { ProvinceAllocationInformation } from "../features/file/components/province-allocation-information/ProvinceAllocationInformation"; +// import { InspectorRequestOperations } from "../features/file/components/inspector-request-operations/InspectorRequestOperations"; +// import { useAcceptedSlaughterRequest } from "../features/file/hooks/useAcceptedSlaughterRequest"; +// import SlaughterHouseVetCheckRequest from "../features/file/components/slaughter-house-vet-check-request/SlaughterHouseVetCheckRequest"; +// import { useAcceptedSlaughterRequest } from "../features/file/hooks/useAcceptedSlaughterRequest"; +import NavigateNextIcon from "@mui/icons-material/NavigateNext"; +import { useNavigate } from "react-router-dom"; +import { useDispatch } from "react-redux"; +import { cleanFile } from "../lib/redux/slices/fileSlice"; +// import { Timer } from "../components/timer/Timer"; +// import moment from "moment"; +import { getMonthlyPercent } from "../features/file/services/get-monthly-percent"; +// import { SlaughterPayPoultryFactorForm } from "../features/file/components/slaughter-pay-poultry-factor-form/SlaughterPayPoultryFactorForm"; +import { SlaughterPaymentFactorPoultry } from "../features/file/components/slaughter-payment-factor-poultry/SlaughterPaymentFactorPoultry"; +// import { CityInformationTitle } from "../features/file/components/city-information/CityInformationTitle"; +// import { CityInformationContent } from "../features/file/components/city-information/CityInformationContent"; +// import { ProvinceInformationTitle } from "../features/file/components/province-information/ProvinceInformationTitle"; +// import { ProvinceInformationContent } from "../features/file/components/province-information/ProvinceInformationContent"; +// import { ProvinceAllocationTitle } from "../features/file/components/province-allocation/ProvinceAllocationTitle"; +// import { ProvinceAllocationContent } from "../features/file/components/province-allocation/ProvinceAllocationContent"; +// import { ProvinceAllocationInformationContent } from "../features/file/components/province-allocation-information/ProvinceAllocationInformationContent"; +// import FinancialCheckRequestInformationContent from "../features/file/components/financial-check-request-information/FinancialCheckRequestInformationContent"; +// import { StateStepper } from "../components/state-stepper/StateStepper"; +// import { SlaghterCheckRequestTitle } from "../features/file/components/slaghter-check-request-title/SlaghterCheckRequestTitle"; +// import { SlaghterAssignCarTitle } from "../features/file/components/slaughter-assign-car-title/SlaughterAssignCarTitle"; +// import { FinancialCreateFactorTitle } from "../features/file/components/financial-create-factor-title/FinancialCreateFactorTitle"; +// import { FinancialCheckRequestTitle } from "../features/file/components/financial-check-request-title/FinancialCheckRequestTitle"; +// import { FinalFactorTitle } from "../features/file/components/final-factor-title/FinalFactorTitle"; +// import { InspectorCheckRequestTitle } from "../features/file/components/inspector-check-request-title/InspectorCheckRequestTitle"; +// import CloseFileFinancialInfo from "../features/file/components/close-file-financial-info/CloseFileFinancialInfo"; +import { InspectorInformation } from "../features/file/components/inspector-information/InspectorInformation"; +import { FileOperatorCheckComplaint } from "../features/file/components/file-operator-check-complaint/FileOperatorCheckComplaint"; +import { + TimelineConnector, + TimelineDot, + TimelineItem, + TimelineSeparator, +} from "@mui/lab"; +import { FileComplaint } from "../features/file/components/file-complaint/FileComplaint"; + +const NewFile = () => { + // vertical steppere + // const [activeStep, setActiveStep] = React.useState(0); + + // const handleReset = () => { + // setActiveStep(0); + // }; + + const navigate = useNavigate(); + const dispatch = useDispatch(); + const { id } = useParams(); + const myFile = useRequestFile(id); + const [roles] = useUserProfile(); + + // const slaughterAllocatedRequests = useSlaughterAllocatedRequests(id); + const process = myFile?.file?.process; + const { quantity, provinceAssignments } = useGetAllocationInformation( + process?.poultry?.poultryRequestKey + ); + useEffect(() => { + dispatch(getMonthlyPercent()); + }, []); + + const provinceKillRequests = process?.provinceKillRequests; + // const acceptedSlaughterRequests = useAcceptedSlaughterRequest(id); + + // const showEnterBarInfo = process?.auction + // ? !!process?.auction?.filter((item) => item.barInfo === null).length + // : provinceKillRequests?.some((killRequest, i) => { + // const { killHouseRequests } = killRequest; + // if (killHouseRequests) { + // return !!killHouseRequests?.filter( + // (item) => + // item.barInfo === null || + // item.barInfo?.killHouseAssignmentState === "rejected" + // ).length; + // } + // return false; + // }); + + // const showSlaughterHouseVetCheckRequest = process?.auction + // ? !!process?.auction?.filter((item) => item.barInfo === null).length + // : provinceKillRequests?.some((killRequest, i) => { + // const { killHouseRequests } = killRequest; + // if (killHouseRequests) { + // return !!killHouseRequests?.filter((item) => item.barInfo === null) + // .length; + // } + // return false; + // }); + + useEffect(() => { + return () => { + dispatch(cleanFile()); + }; + }, []); + + // const requestInformation = "completed"; + // const city = process?.city === null; + // const province = + // process?.city && + // process?.province?.provinceState !== "reject" && + // process?.province?.provinceState !== "accept"; + + // const provinceAllocation = + // process?.city && + // process?.province?.provinceState === "accept" && + // quantity !== 0; + + // const slaghterCheckRequestLoop = + // provinceAssignments && + // !!provinceKillRequests?.length && + // Boolean( + // provinceKillRequests?.filter( + // (item) => item.provinceKillReqState !== "accepted" + // ).length + // ); + + // const slaughterAllocation = + // acceptedSlaughterRequests.some((item) => item.quantity > 0) || + // (process?.killHouseWinner && process?.killHouseWinner.quantity > 0); + + // const financialCreateAndPayFactor = !!provinceKillRequests?.filter( + // (killRequest, i) => { + // const { killHouseRequests } = killRequest; + // const d = killHouseRequests + // ?.filter((item) => item.barInfo !== null) + // .filter((item, i) => { + // const showSlaughterFactorForm = + // (item.barInfo && + // item.provinceFactorToKillHouse && + // (!item.killHouseFactorToProvince || + // item.killHouseFactorToProvince.factorState === "rejected")) || + // (item.provinceFactorToKillHouseForPoultry && + // !item.killHouseFactorToPoultry) || + // item.killHouseFactorToPoultry?.factorState === "rejected"; + // return showSlaughterFactorForm; + // }); + // return !!d?.length; + // } + // ).length; + + // const financialFactorCheck = !!provinceKillRequests?.filter( + // (killRequest, i) => { + // const { killHouseRequests } = killRequest; + // return !!killHouseRequests + // ?.filter( + // (item) => + // item?.barInfo && + // (item.killHouseFactorToProvince || item?.killHouseFactorToPoultry) + // ) + // .filter((item) => { + // return ( + // item?.killHouseFactorToPoultry && + // item?.killHouseFactorToPoultry?.factorState === "pending" + // ); + // }) + // .filter((item) => { + // return ( + // item?.killHouseFactorToProvince && + // item.killHouseFactorToProvince.factorState === "pending" + // ); + // }).length; + // } + // )?.length; + + // const finalFactor = process?.allocation; + + // const inspectorCheckRequest = + // process?.allocation && + // process?.poultry?.poultryRequestFinalState === "archive"; + + // let cityState, + // provinceState, + // provinceAllocationState, + // slaghterCheckRequestState, + // slaghterAllocationState, + // financialCreateAndPayFactorState, + // financialFactorCheckState, + // finalFactorState, + // inspectorCheckRequestState; + + // cityState = city ? "pending" : "completed"; + + // provinceState = province ? "pending" : "completed"; + // if (cityState === "pending") { + // provinceState = "locked"; + // } + + // provinceAllocationState = provinceAllocation ? "pending" : "completed"; + // if (provinceState === "pending" || provinceState === "locked") { + // provinceAllocationState = "locked"; + // } + + // slaghterCheckRequestState = slaghterCheckRequestLoop + // ? "pending" + // : "completed"; + // if ( + // provinceAllocationState === "pending" || + // provinceAllocationState === "locked" + // ) { + // slaghterCheckRequestState = "locked"; + // } + + // slaghterAllocationState = + // slaughterAllocation || showEnterBarInfo ? "pending" : "completed"; + // if ( + // slaghterCheckRequestState === "pending" || + // slaghterCheckRequestState === "locked" + // ) { + // slaghterAllocationState = "locked"; + // } + + // financialCreateAndPayFactorState = financialCreateAndPayFactor + // ? "pending" + // : "completed"; + // if ( + // slaghterAllocationState === "pending" || + // slaghterAllocationState === "locked" + // ) { + // financialCreateAndPayFactorState = "locked"; + // } + + // financialFactorCheckState = financialFactorCheck ? "pending" : "completed"; + // if ( + // financialCreateAndPayFactorState === "pending" || + // financialCreateAndPayFactorState === "locked" + // ) { + // financialFactorCheckState = "locked"; + // } + + // finalFactorState = finalFactor ? "pending" : "completed"; + // if ( + // financialFactorCheckState === "pending" || + // financialFactorCheckState === "locked" + // ) { + // finalFactorState = "locked"; + // } + + // inspectorCheckRequestState = inspectorCheckRequest ? "completed" : "pending"; + // if (!finalFactorState === "completed") { + // inspectorCheckRequestState = "locked"; + // } + + // const getStepState = (step) => { + // const stepStates = { + // 0: requestInformation, + // 1: cityState, + // 2: provinceState, + // 3: provinceAllocationState, + // 4: slaghterCheckRequestState, + // 5: slaghterAllocationState, + // 6: financialCreateAndPayFactorState, + // 7: financialFactorCheckState, + // 8: finalFactorState, + // 9: inspectorCheckRequestState, + // }; + // return stepStates[step] ? stepStates[step] : "locked"; + // }; + + const sellType = process?.filePaymentType; + // const paymentPrice = "123000000"; + + // const paymentDate = moment(new Date(2022, 11, 24, 10, 33, 30, 0)); + // const currentDate = moment(); + // const diff = paymentDate.diff(currentDate); + // let paymentRemainedSeconds = moment.duration(diff).asSeconds(); + + // let steps = []; + if (process) { + // steps = [ + // { + // label: ( + // + // + // + // + // مشخصات درخواست + // + // + // + // + // + // + // + // درخواست در تاریخ + // + // + // {formatTime(process?.poultry?.poultryRegisterDate)} + // + // + // ثبت شده است. + // + // + // + // + // + // ), + // description: , + // }, + // { + // label: , + // description: ( + // <> + // + // {(getRoleFromUrl() === "CityOperator" || + // getRoleFromUrl() === "ProvinceOperator") && + // process.city === null && } + // + // ), + // }, + // { + // label: , + // description: ( + // <> + // + // {!process.killHouseWinner && + // getRoleFromUrl() === "ProvinceOperator" && + // roles.includes("ProvinceOperator") && + // process?.city && + // process?.province?.provinceState !== "reject" && + // process?.province?.provinceState !== "accept" && ( + // + // )} + // + // ), + // }, + // { + // label: , + // description: ( + // <> + // {!process.killHouseWinner && + // provinceAssignments && + // !!provinceKillRequests?.length && + // provinceAssignments?.map((item, i) => { + // return ( + // + // + // + // ); + // })} + // {!process.auctionsList && + // getRoleFromUrl() === "ProvinceOperator" && + // roles.includes("ProvinceOperator") && + // process?.city && + // process?.province?.provinceState === "accept" && + // quantity !== 0 && } + // + // ), + // }, + // { + // label: , + // description: ( + // <> + // {!process.killHouseWinner && + // provinceAssignments && + // !!provinceKillRequests?.length && + // provinceAssignments?.map((item, i) => { + // return ( + // + // + // + // + // + // {!process.killHouseWinner && + // getRoleFromUrl() === "KillHouse" && + // roles.includes("KillHouse") && + // Boolean( + // provinceKillRequests?.filter( + // (item) => item.provinceKillReqState !== "accepted" + // ).length + // ) && + // item.provinceKillRequestState === "pending" && ( + // + // )} + // + // + // ); + // })} + // + // ), + // }, + // { + // label: , + // description: ( + // <> + // {!process.killHouseWinner && + // provinceAssignments && + // !!provinceKillRequests?.length && + // provinceAssignments?.map((item, i) => { + // return ( + // + // + // + // + // + // {!process.killHouseWinner && + // getRoleFromUrl() === "KillHouse" && + // roles.includes("KillHouse") && + // Boolean( + // provinceKillRequests?.filter( + // (item) => item.provinceKillReqState !== "accepted" + // ).length + // ) && + // item.provinceKillRequestState === "pending" && ( + // + // )} + // + // + // ); + // })} + // {getRoleFromUrl() === "KillHouse" && + // roles.includes("KillHouse") && + // (acceptedSlaughterRequests.some((item) => item.quantity > 0) || + // (process.killHouseWinner && + // process.killHouseWinner.quantity > 0)) && ( + // + // )} + // {(getRoleFromUrl() === "KillHouse" || + // getRoleFromUrl() === "Poultry" || + // getRoleFromUrl() === "ProvinceFinancial") && + // (roles.includes("KillHouse") || + // roles.includes("Poultry") || + // roles.includes("ProvinceFinancial")) && + // !!showEnterBarInfo && } + // + // ), + // }, + // { + // label: , + // description: ( + // <> + // {!process.killHouseWinner && + // provinceKillRequests?.map((killRequest, i) => { + // const { killHouseRequests } = killRequest; + // const d = killHouseRequests + // ?.filter((item) => item.barInfo !== null) + // .map((item, i) => { + // const showSlaughterFactorForm = + // (item.barInfo && + // item.provinceFactorToKillHouse && + // (!item.killHouseFactorToProvince || + // item.killHouseFactorToProvince.factorState === + // "rejected")) || + // (item.provinceFactorToKillHouseForPoultry && + // !item.killHouseFactorToPoultry) || + // item.killHouseFactorToPoultry?.factorState === "rejected"; + // const data = [ + // [ + // item.barcod, + // `${item.killHouseName} (${item.killHouseUserProvince}/${item.killHouseUserCity})`, + // item.quantity + " قطعه", + // item.car?.driverName + ` (${item.car?.driverMobile})`, + // `${item.car?.typeCar} با پلاک ${item.car?.pelak}`, + // item.barInfo.killHouseNetWeight + " کیلوگرم", + // item.fee + " ریال", + // + // بدون بار + // , + // + // بدون بار + // , + // ], + // ]; + // return ( + // + // + // {getRoleFromUrl() === "ProvinceFinancial" && + // roles.includes("ProvinceFinancial") && + // !item.provinceFactorToKillHouse && + // item.barInfo.killHouseAssignmentState === + // "pending" && ( + // + // )} + // {(getRoleFromUrl() === "KillHouse" || + // getRoleFromUrl() === "ProvinceFinancial") && + // (roles.includes("KillHouse") || + // roles.includes("ProvinceFinancial")) && + // showSlaughterFactorForm && ( + // <> + // {item.provinceFactorToKillHouse && + // (!item.killHouseFactorToProvince || + // item.killHouseFactorToProvince + // ?.factorState === "rejected") && ( + // <> + // + // + // )} + // {!!item.provinceFactorToKillHouseForPoultry && + // (!item.killHouseFactorToPoultry || + // item.killHouseFactorToPoultry?.factorState === + // "rejected") && ( + // + // )} + // + // )} + // + // ); + // }); + // return d; + // })} + // + // ), + // }, + // { + // label: , + // description: ( + // <> + // {provinceKillRequests?.map((killRequest, i) => { + // const { killHouseRequests } = killRequest; + // return killHouseRequests + // ?.filter( + // (item) => + // item.barInfo && + // (item.killHouseFactorToProvince || + // item.killHouseFactorToPoultry) + // ) + // .map((item, i) => { + // return ( + // <> + // {item?.killHouseFactorToProvince && ( + // + // )} + // {getRoleFromUrl() === "ProvinceFinancial" && + // roles.includes("ProvinceFinancial") && + // item?.killHouseFactorToProvince && + // item.killHouseFactorToProvince.factorState === + // "pending" && ( + // <> + // + // + // )} + // {item?.killHouseFactorToPoultry && ( + // + // )} + // {item?.killHouseFactorToPoultry && + // getRoleFromUrl() === "ProvinceFinancial" && + // roles.includes("ProvinceFinancial") && + // item.killHouseFactorToPoultry.factorState === + // "pending" && ( + // + // )} + // + // ); + // }); + // })} + // + // ), + // }, + // { + // label: , + // description: ( + // <> + // {process.allocation && ( + // + // + // + // )} + // + // ), + // }, + // { + // label: , + // description: ( + // <> + // {getRoleFromUrl() === "ProvinceInspector" && + // roles.includes("ProvinceInspector") && + // process.allocation && + // process?.poultry?.poultryRequestFinalState === "pending" && ( + // + // + // + // + // + // )} + // {process.provinceIncpector.acceptRejectDate && ( + // + // )} + // + // ), + // }, + // ]; + } + + // const [viewType, setViewType] = React.useState("file"); + + // const handleChangeViewType = (event, newAlignment) => { + // setViewType(newAlignment); + // }; + + // const control = { + // value: viewType, + // onChange: handleChangeViewType, + // exclusive: true, + // }; + + return ( + <> + {process && ( + + + + + navigate(-1)} + > + + بازگشت + + + {/* + + + نمایش بصورت مرحله ای + + + نمایش بصورت پرونده + + + */} + + + + + + + + مشخصات پرونده با کد سفارش + {process?.poultry?.poultryOrderCode} + + + + + {!process?.poultry?.poultryAuction ? ( + + (فروش از طریق اتحادیه) + + ) : ( + + (فروش از طریق مزایده) + + )} + + + {sellType === "cash" && ( + prop.palette.warning.dark} + > + (فروش نقدی) + + )} + {sellType === "credit" && ( + prop.palette.warning.dark} + > + (فروش زمان دار - تا یک ماه) + + )} + {sellType === "cash_credit" && ( + prop.palette.warning.dark} + > + (فروش بصورت نقدی و زمان دار) + + )} + + + + + + {/* show file items */} + + + + + + + + + + + + + مشخصات درخواست + + + + + + + + درخواست در تاریخ + + + {formatTime( + process?.poultry?.poultryRegisterDate + )} + + + ثبت شده است. + + + + + + + + + + {/* City Level */} + + {/* {(getRoleFromUrl() === "CityOperator" || + getRoleFromUrl() === "ProvinceOperator") && + process.city === null && ( + + )} */} + + {/* {process.auctionsList && process?.poultry?.poultryAuction && ( + + )} */} + + {/* {process.killHouseWinner && ( + + )} */} + + {/* Province Level */} + {!process.auctionsList && + !process.killHouseWinner && + process?.city && + process.city.cityState === "accept" && ( + + )} + + {/* Province Level */} + {/* {!process.killHouseWinner && + getRoleFromUrl() === "ProvinceOperator" && + roles.includes("ProvinceOperator") && + process?.city && + process?.province?.provinceState !== "reject" && + process?.province?.provinceState !== "accept" && ( + + )} */} + {/* + {!process.auctionsList && + getRoleFromUrl() === "ProvinceOperator" && + roles.includes("ProvinceOperator") && + process?.city && + process?.province?.provinceState === "accept" && + quantity !== 0 && } */} + {/* {!process.auctionsList && + getRoleFromUrl() === "ProvinceOperator" && + roles.includes("ProvinceOperator") && + process?.city && + process?.province?.provinceState === "accept" && ( + + )} */} + + {!process.killHouseWinner && + provinceAssignments && + !!provinceKillRequests?.length && + provinceAssignments?.map((item, i) => { + return ( + + + + + {/* + {!process.killHouseWinner && + (getRoleFromUrl() === "KillHouse" || + getRoleFromUrl() === "ProvinceOperator") && + (roles.includes("KillHouse") || + roles.includes("ProvinceOperator")) && + Boolean( + provinceKillRequests?.filter( + (item) => + item.provinceKillReqState !== "accepted" + ).length + ) && + item.provinceKillRequestState === "pending" && ( + + )} + */} + + ); + })} + + {/* {!process.killHouseWinner && + getRoleFromUrl() === "KillHouse" && + roles.includes("KillHouse") && + Boolean( + provinceKillRequests?.filter( + (item) => item.provinceKillReqState !== "accepted" + ).length + ) && } */} + + {/* {(getRoleFromUrl() === "KillHouse" || + getRoleFromUrl() === "ProvinceOperator") && + (roles.includes("KillHouse") || + roles.includes("ProvinceOperator")) && + (acceptedSlaughterRequests.some( + (item) => item.quantity > 0 + ) || + (process.killHouseWinner && + process.killHouseWinner.quantity > 0)) && + provinceAssignments?.map((assignment, i) => { + return ( + + ); + })} */} + + {/* {showSlaughterHouseVetCheckRequest && ( + + )} */} + + {/* Submit Bar Weight Level */} + {/* {(getRoleFromUrl() === "KillHouse" || + getRoleFromUrl() === "Poultry" || + getRoleFromUrl() === "KillHouseVet" || + getRoleFromUrl() === "ProvinceFinancial") && + (roles.includes("KillHouse") || + roles.includes("Poultry") || + roles.includes("KillHouseVet") || + roles.includes("ProvinceFinancial")) && + !!showEnterBarInfo && ( + + )} */} + + {!process.killHouseWinner && + provinceKillRequests?.map((killRequest) => { + const { killHouseRequests } = killRequest; + const d = killHouseRequests + ?.filter((item) => item.barInfo !== null) + .map((item, i) => { + const showSlaughterFactorForm = + (item.barInfo && + item.provinceFactorToKillHouse && + (!item.killHouseFactorToProvince || + item.killHouseFactorToProvince.factorState === + "rejected")) || + (item.provinceFactorToKillHouseForPoultry && + !item.killHouseFactorToPoultry) || + item.killHouseFactorToPoultry?.factorState === + "rejected"; + + const data = [ + [ + item.barcod, + `${item.killHouseName} (${item.killHouseUserProvince}/${item.killHouseUserCity})`, + item.quantity + " قطعه", + item.car?.driverName + + ` (${item.car?.driverMobile})`, + `${item.car?.typeCar} با پلاک ${item.car?.pelak}`, + item.barInfo.killHouseNetWeight + " کیلوگرم", + item.fee + " ریال", + + بدون بار + , + + بدون بار + , + ], + ]; + return ( + + + + {item.complaint && ( + + + + + + + + + + )} + + {/* !!item?.complaint && item.complaint?.state === "pending" */} + + {(getRoleFromUrl() === "ProvinceFinancial" || + getRoleFromUrl() === "ProvinceInspector") && + item.complaint?.state === "pending" && ( + + )} + + {/* {getRoleFromUrl() === "ProvinceFinancial" && + roles.includes("ProvinceFinancial") && + !item.provinceFactorToKillHouse && + item.barInfo.killHouseAssignmentState === + "pending" && + item.complaint?.state !== "pending" && ( + + )} */} + + {(getRoleFromUrl() === "KillHouse" || + getRoleFromUrl() === "ProvinceFinancial") && + (roles.includes("KillHouse") || + roles.includes("ProvinceFinancial")) && + showSlaughterFactorForm && ( + <> + {/* {item.provinceFactorToKillHouse && + (!item.killHouseFactorToProvince || + item.killHouseFactorToProvince + ?.factorState === "rejected") && ( + + )} */} + + {/* {!!item.provinceFactorToKillHouseForPoultry && + (!item.killHouseFactorToPoultry || + item.killHouseFactorToPoultry + ?.factorState === "rejected") && ( + + )} */} + + )} + + ); + }); + return d; + })} + + {process.killHouseWinner && + process.auction + ?.filter((item) => item.barInfo !== null) + .map((item, i) => { + return ( + + + {getRoleFromUrl() === "ProvinceFinancial" && + roles.includes("ProvinceFinancial") && + !item.provinceFactorToKillHouse && ( + + )} + + ); + })} + + {process.killHouseWinner && + process.auction && + process.auction + ?.filter( + (item) => + item.barInfo && + !item.killHouseFactorToProvince && + item.provinceFactorToKillHouse + ) + .map((item, i) => { + return ( + <> + + {getRoleFromUrl() === "KillHouse" && + roles.includes("KillHouse") && ( + + )} + + ); + })} + + {provinceKillRequests?.map((killRequest) => { + const { killHouseRequests } = killRequest; + return killHouseRequests + ?.filter( + (item) => + item.barInfo && + (item.killHouseFactorToProvince || + item.killHouseFactorToPoultry) + ) + .map((item, i) => { + return ( + <> + {item?.killHouseFactorToProvince && ( + + )} + + {/* {getRoleFromUrl() === "ProvinceFinancial" && + roles.includes("ProvinceFinancial") && + item?.killHouseFactorToProvince && + item.killHouseFactorToProvince.factorState === + "pending" && ( + <> + + + )} */} + + {item?.killHouseFactorToPoultry && ( + + )} + + {/* {item?.killHouseFactorToPoultry && + getRoleFromUrl() === "ProvinceFinancial" && + roles.includes("ProvinceFinancial") && + item.killHouseFactorToPoultry.factorState === + "pending" && ( + + )} */} + + ); + }); + })} + + {process.killHouseWinner && + process.auction + ?.filter( + (item) => item.barInfo && item.killHouseFactorToProvince + ) + .map((item, i) => { + return ( + <> + + {/* {getRoleFromUrl() === "ProvinceFinancial" && + roles.includes("ProvinceFinancial") && + item.killHouseFactorToProvince.factorState === + "pending" && ( + + )} */} + + ); + })} + + {process.allocation && ( + + + + )} + {/* {getRoleFromUrl() === "ProvinceInspector" && + roles.includes("ProvinceInspector") && + process.allocation && + process?.poultry?.poultryRequestFinalState === + "pending" && ( + + + + + + )} */} + + {process.provinceIncpector.acceptRejectDate && ( + + )} + + + {/* end show file items */} + {/* show closefile items */} + {/* {viewType === "closefile" && ( + <> + {!process.killHouseWinner && + provinceKillRequests?.map((killRequest, i) => { + const { killHouseRequests } = killRequest; + const d = killHouseRequests + ?.filter((item) => item.barInfo !== null) + .map((item, i) => { + const data = [ + [ + item.barcod, + `${item.killHouseName} (${item.killHouseUserProvince}/${item.killHouseUserCity})`, + item.quantity + " قطعه", + item.car?.driverName + + ` (${item.car?.driverMobile})`, + `${item.car?.typeCar} با پلاک ${item.car?.pelak}`, + item.barInfo.killHouseNetWeight + " کیلوگرم", + item.fee + " ریال", + + بدون بار + , + + بدون بار + , + ], + ]; + return ( + + + + ); + }); + return d; + })} + + )} */} + + + + )} + + ); +}; + +NewFile.propTypes = { + id: PropTypes.number, +}; +export default NewFile; diff --git a/src/pages/OperatorNewHatching.js b/src/pages/OperatorNewHatching.js new file mode 100644 index 0000000..979d2c6 --- /dev/null +++ b/src/pages/OperatorNewHatching.js @@ -0,0 +1,91 @@ +import { Box } from "@mui/material"; +import { useLocation } from "react-router-dom"; +import { Grid } from "../components/grid/Grid"; +import { SPACING } from "../data/spacing"; +import { CityHatching } from "../features/city/components/city-new-hatching/CityHatching"; +import { CityNewRequest } from "../features/city/components/city-new-request/CityNewRequest"; +import { + ROUTE_ADMINX_HATCHING, + ROUTE_ADMINX_NEW_REQUEST, + ROUTE_ADMINX_ROUTE_NATIONAL_INFO, + ROUTE_ADMINX_ROUTE_NATIONAL_INFO_FARM, + ROUTE_CITY_HATCHING, + ROUTE_CITY_NEW_REQUEST, + ROUTE_CITY_POULTRY_HATCHING, + ROUTE_PROVINCE_HATCHING, + ROUTE_PROVINCE_NEW_REQUEST, + ROUTE_PROVINCE_SUPERVISOR_ROUTE_NATIONAL_INFO, + ROUTE_PROVINCE_SUPERVISOR_ROUTE_NATIONAL_INFO_FARM, + ROUTE_SUPER_ADMIN_HATCHING, + ROUTE_SUPER_ADMIN_NEW_REQUEST, + ROUTE_SUPER_ADMIN_ROUTE_NATIONAL_INFO, + ROUTE_SUPER_ADMIN_ROUTE_NATIONAL_INFO_FARM, + ROUTE_VETFARM_ROUTE_HATCHING, +} from "../routes/routes"; +import { ProvinceNationalInfo } from "../features/province/components/province-national-info/ProvinceNationalInfo"; +import { ProvinceNationalInfoFarm } from "../features/province/components/province-national-info-farm/ProvinceNationalInfoFarm"; + +const OperatorNewHatching = () => { + const { pathname } = useLocation(); + // console.log( + // "fdloklofd", + // pathname.includes(ROUTE_CITY_VISOR_STATICSـHATCHINGS_DETAILS) + // ); + return ( + <> + + + {/* + + + + */} + + + {(pathname === ROUTE_CITY_HATCHING || + pathname === ROUTE_PROVINCE_HATCHING || + pathname === ROUTE_VETFARM_ROUTE_HATCHING || + pathname === ROUTE_ADMINX_HATCHING || + pathname === ROUTE_CITY_POULTRY_HATCHING || + pathname === ROUTE_SUPER_ADMIN_HATCHING) && } + + {(pathname === ROUTE_CITY_NEW_REQUEST || + pathname === ROUTE_PROVINCE_NEW_REQUEST || + pathname === ROUTE_ADMINX_NEW_REQUEST || + pathname === ROUTE_SUPER_ADMIN_NEW_REQUEST) && ( + + )} + + {(pathname.includes(ROUTE_ADMINX_ROUTE_NATIONAL_INFO) || + pathname.includes(ROUTE_SUPER_ADMIN_ROUTE_NATIONAL_INFO) || + pathname.includes( + ROUTE_PROVINCE_SUPERVISOR_ROUTE_NATIONAL_INFO + )) && } + + {(pathname.includes(ROUTE_ADMINX_ROUTE_NATIONAL_INFO_FARM) || + pathname.includes(ROUTE_SUPER_ADMIN_ROUTE_NATIONAL_INFO_FARM) || + pathname.includes( + ROUTE_PROVINCE_SUPERVISOR_ROUTE_NATIONAL_INFO_FARM + )) && } + + + + + + ); +}; + +export default OperatorNewHatching; diff --git a/src/pages/ParentCompany.js b/src/pages/ParentCompany.js new file mode 100644 index 0000000..4608269 --- /dev/null +++ b/src/pages/ParentCompany.js @@ -0,0 +1,73 @@ +import React, { useState } from "react"; +import { Box, FormControl, MenuItem, Select, Grid } from "@mui/material"; +import { BackButton } from "../components/back-button/BackButton"; +import { SPACING } from "../data/spacing"; +import { useLocation } from "react-router-dom"; +import { + ROUTE_PARENT_COMPANY_ALLOCATIONS, + ROUTE_PARENT_COMPANY_PAYING_FEES_REQUESTS, +} from "../routes/routes"; +import { ParentCompanyPaymentByWeightOverviewTable } from "../features/province/components/parent-company-payment-by-weight-overview/ParentCompanyPaymentByWeightOverview"; +import { ParentCompanyVetFarmOperation } from "../features/vet-farm/components/parent-company-vet-farm-operation/ParentCompanyVetFarmOperation"; + +const PROVINCES = [ + { label: "استان مرکزی", value: "https://mabackend.rasadyar.com/" }, + { label: "استان همدان", value: "https://habackend.rasadyar.com/" }, + { label: "استان بوشهر", value: "https://bubackend.rasadyar.com/" }, +]; + +const ParentCompany = () => { + const [province, setProvince] = useState("https://mabackend.rasadyar.com/"); + const { pathname } = useLocation(); + + const handleChange = (event) => setProvince(event.target.value); + + const renderContent = () => { + if (pathname.includes(ROUTE_PARENT_COMPANY_PAYING_FEES_REQUESTS)) { + return ; + } + if (pathname.includes(ROUTE_PARENT_COMPANY_ALLOCATIONS)) { + return ; + } + return null; + }; + + return ( + + + + + + + + + + + + + + {renderContent()} + + + + ); +}; + +export default ParentCompany; diff --git a/src/pages/Payment.js b/src/pages/Payment.js new file mode 100644 index 0000000..02f86af --- /dev/null +++ b/src/pages/Payment.js @@ -0,0 +1,25 @@ +import { Box } from "@mui/system"; +import { Grid } from "../components/grid/Grid"; +import { SPACING } from "../data/spacing"; +import { PaymentResult } from "../features/payment/components/PaymentResult"; + +const Payment = () => { + return ( + + + + + + ); +}; + +export default Payment; diff --git a/src/pages/PaymentOfFees.js b/src/pages/PaymentOfFees.js new file mode 100644 index 0000000..79fedaa --- /dev/null +++ b/src/pages/PaymentOfFees.js @@ -0,0 +1,79 @@ +import { Box, Tab, Tabs } from "@mui/material"; +import { BackButton } from "../components/back-button/BackButton"; +import { Grid } from "../components/grid/Grid"; +import { SPACING } from "../data/spacing"; +import { SLaughterPaymentOverview } from "../features/slaughter-house/components/slaughter-payment-overview/SLaughterPaymentOverview"; +import { useState } from "react"; +import { TabContext, TabPanel } from "@mui/lab"; +import { SlaughterPaymentByWeight } from "../features/slaughter-house/components/slaughter-payment-by-weight/SlaughterPaymentByWeight"; +import { SlaughterPayingFees } from "../features/slaughter-house/components/slaughter-paying-fees/SlaughterPayingFees"; + +const PaymentOfFees = () => { + const [tabValue, setTabValue] = useState("1"); + + const handleTabChange = (event, newValue) => { + setTabValue(newValue); + }; + return ( + <> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ); +}; + +export default PaymentOfFees; diff --git a/src/pages/PolicyCouncil.js b/src/pages/PolicyCouncil.js new file mode 100644 index 0000000..b32909b --- /dev/null +++ b/src/pages/PolicyCouncil.js @@ -0,0 +1,68 @@ +import { Box } from "@mui/material"; +import { useLocation } from "react-router-dom"; +import { Grid } from "../components/grid/Grid"; +import { SPACING } from "../data/spacing"; +import { PolicyKillhouseDirectBuy } from "../features/province/components/policy-killhouse-direct-buy/PolicyKillhouseDirectBuy"; +import { PolicyKillhouseGuilds } from "../features/province/components/policy-killhouse-guilds/PolicyKillhouseGuilds"; +import { PolicyPoultryChooseSlaughter } from "../features/province/components/policy-poultry-choose-slaughter/PolicyPoultryChooseSlaughter"; +import { PolicyPoultryFreeSale } from "../features/province/components/policy-poultry-free-sale/PolicyPoultryFreeSale"; +import { + ROUTE_ADMINX_ROUTE_POLICY_COUNCIL_DIRECT_BUY, + ROUTE_ADMINX_ROUTE_POLICY_COUNCIL_FREE_SALE, + ROUTE_ADMINX_ROUTE_POLICY_COUNCIL_KILLHOUSE_GUILDS, + ROUTE_PROVINCE_ROUTE_POLICY_COUNCIL_DIRECT_BUY, + ROUTE_PROVINCE_ROUTE_POLICY_COUNCIL_FREE_SALE, + ROUTE_PROVINCE_ROUTE_POLICY_COUNCIL_KILLHOUSE_GUILDS, + ROUTE_PROVINCE_ROUTE_POLICY_COUNCIL_POULTRY_CHOOSE_SLAUGHTER, + ROUTE_SUPER_ADMIN_ROUTE_POLICY_COUNCIL_DIRECT_BUY, + ROUTE_SUPER_ADMIN_ROUTE_POLICY_COUNCIL_FREE_SALE, + ROUTE_SUPER_ADMIN_ROUTE_POLICY_COUNCIL_KILLHOUSE_GUILDS, +} from "../routes/routes"; + +const PolicyCouncil = () => { + const { pathname } = useLocation(); + return ( + <> + + + + + {pathname === + ROUTE_PROVINCE_ROUTE_POLICY_COUNCIL_POULTRY_CHOOSE_SLAUGHTER && ( + + )} + {(pathname === ROUTE_PROVINCE_ROUTE_POLICY_COUNCIL_FREE_SALE || + pathname === ROUTE_SUPER_ADMIN_ROUTE_POLICY_COUNCIL_FREE_SALE || + pathname === ROUTE_ADMINX_ROUTE_POLICY_COUNCIL_FREE_SALE) && ( + + )} + {(pathname === ROUTE_PROVINCE_ROUTE_POLICY_COUNCIL_DIRECT_BUY || + ROUTE_SUPER_ADMIN_ROUTE_POLICY_COUNCIL_DIRECT_BUY || + ROUTE_ADMINX_ROUTE_POLICY_COUNCIL_DIRECT_BUY) && ( + + )} + {(pathname === + ROUTE_PROVINCE_ROUTE_POLICY_COUNCIL_KILLHOUSE_GUILDS || + pathname === + ROUTE_SUPER_ADMIN_ROUTE_POLICY_COUNCIL_KILLHOUSE_GUILDS || + pathname === + ROUTE_ADMINX_ROUTE_POLICY_COUNCIL_KILLHOUSE_GUILDS) && ( + + )} + + + + + + ); +}; + +export default PolicyCouncil; diff --git a/src/pages/Poultries.js b/src/pages/Poultries.js new file mode 100644 index 0000000..d344fb5 --- /dev/null +++ b/src/pages/Poultries.js @@ -0,0 +1,20 @@ +import { Grid } from "../components/grid/Grid"; +import { ManagePoultries } from "../features/province/components/manage-poultries/ManagePoultries"; +// import { VetFarmOperations } from "../features/vet-farm/components/vet-farm-operations/VetFarmOperations"; + +const Poultries = () => { + return ( + <> + + + + + ); +}; +export default Poultries; diff --git a/src/pages/PoultriesDetailsPage.js b/src/pages/PoultriesDetailsPage.js new file mode 100644 index 0000000..642df57 --- /dev/null +++ b/src/pages/PoultriesDetailsPage.js @@ -0,0 +1,18 @@ +import { Box } from "@mui/material"; +import { Grid } from "../components/grid/Grid"; +import { PoultriesDetails } from "../features/province/components/poultries-details/PoultriesDetails"; +import { BackButton } from "../components/back-button/BackButton"; + +const PoultriesDetailsPage = () => { + return ( + + + + + + + + + ); +}; +export default PoultriesDetailsPage; diff --git a/src/pages/PoultryScienceExperts.js b/src/pages/PoultryScienceExperts.js new file mode 100644 index 0000000..50c85e2 --- /dev/null +++ b/src/pages/PoultryScienceExperts.js @@ -0,0 +1,36 @@ +import { Box } from "@mui/material"; +import React from "react"; +import { Grid } from "../components/grid/Grid"; +import { SPACING } from "../data/spacing"; +import { ProvincePoultryScienceExperts } from "../features/province/components/province-poultry-science-experts/ProvincePoultryScienceExperts"; + +const PoultryScienceExperts = () => { + return ( + <> + + + + + + + + + + + ); +}; + +export default PoultryScienceExperts; diff --git a/src/pages/ProvinceCaseStatus.js b/src/pages/ProvinceCaseStatus.js new file mode 100644 index 0000000..140db6d --- /dev/null +++ b/src/pages/ProvinceCaseStatus.js @@ -0,0 +1,40 @@ +import { Box } from "@mui/material"; +import { Grid } from "../components/grid/Grid"; +import { SPACING } from "../data/spacing"; +import { ProvinceCaseStatusComponent } from "../features/province/components/province-case-status/ProvinceCaseStatusComponent"; + +const ProvinceCaseStatus = () => { + return ( + <> + + + {/* + + + + */} + + + + + + + + + ); +}; + +export default ProvinceCaseStatus; diff --git a/src/pages/ProvinceColdHousesPage.js b/src/pages/ProvinceColdHousesPage.js new file mode 100644 index 0000000..db6700c --- /dev/null +++ b/src/pages/ProvinceColdHousesPage.js @@ -0,0 +1,60 @@ +import React from "react"; +import { + ROUTE_ADMINX_COLD_HOUSES, + ROUTE_ADMINX_COLD_HOUSES_MANAGEMENT, + ROUTE_PROVINCE_COLD_HOUSES, + ROUTE_PROVINCE_COLD_HOUSES_MANAGEMENT, + ROUTE_SUPER_ADMIN_COLD_HOUSES, + ROUTE_SUPER_ADMIN_COLD_HOUSES_MANAGEMENT, +} from "../routes/routes"; +import { SPACING } from "../data/spacing"; +import { Grid } from "../components/grid/Grid"; +import { Box, Typography } from "@mui/material"; +import { useLocation, useParams } from "react-router-dom"; +import { BackButton } from "../components/back-button/BackButton"; +import { ProvinceColdHousesOperations } from "../features/province/components/province-cold-houses-operations/ProvinceColdHousesOperations"; +import { ProvinceColdHousesList } from "../features/province/components/province-cold-houses-list/ProvinceColdHousesList"; +import { ProvinceStewardShowColdHousesList } from "../features/province/components/province-steward-show-cold-houses-list/ProvinceStewardShowColdHousesList"; + +const ProvinceColdHousesPage = () => { + const { pathname } = useLocation(); + const { key } = useParams(); + return ( + <> + + + {pathname === ROUTE_PROVINCE_COLD_HOUSES || + pathname === ROUTE_ADMINX_COLD_HOUSES || + pathname === ROUTE_SUPER_ADMIN_COLD_HOUSES ? ( + + + داشبورد مدیریت سردخانه ها + + + + ) : ( + + )} + + {(pathname === ROUTE_PROVINCE_COLD_HOUSES_MANAGEMENT || + pathname === ROUTE_ADMINX_COLD_HOUSES_MANAGEMENT || + pathname === ROUTE_SUPER_ADMIN_COLD_HOUSES_MANAGEMENT) && ( + + )} + + {key && } + + + + ); +}; + +export default ProvinceColdHousesPage; diff --git a/src/pages/ProvinceFees.js b/src/pages/ProvinceFees.js new file mode 100644 index 0000000..9ff8234 --- /dev/null +++ b/src/pages/ProvinceFees.js @@ -0,0 +1,112 @@ +import { Box } from "@mui/material"; +import { useParams } from "react-router-dom"; +import { BackButton } from "../components/back-button/BackButton"; +import { Grid } from "../components/grid/Grid"; +import { SPACING } from "../data/spacing"; +import { ProvinceKillhousePaidFee } from "../features/province/components/province-killhouse-paid-fee/ProvinceKillhousePaidFee"; +import { ProvincePaymentByWeight } from "../features/province/components/province-payment-by-weight/ProvincePaymentByWeight"; +import { ProvinceKillhouseFee } from "../features/province/components/province-killhouse-fee/ProvinceKillhouseFee"; +import { ProvinceDailyBarsDetails } from "../features/province/components/province-daily-bars-details/ProvinceDailyBarsDetails"; +import { ProvincePaymentLiveChickenDetails } from "../features/province/components/province-payment-live-chicken-detail/ProvincePaymentLiveChickenDetails"; +import { ProvincePaymentChainDetails } from "../features/province/components/province-payment-chain-detail/ProvincePaymentChainDetails"; + +const ProvinceFees = () => { + const params = useParams(); + + const getDetailComponent = () => { + let component; + switch (params.type) { + case "unpaid": + component = ; + break; + case "kill_house_key": + component = ( + + ); + break; + case "chain_company_key": + component = ( + + ); + break; + case "daily_bar": + component = ( + + ); + break; + case "live_chicken": + component = ( + + ); + break; + case "carcassess": + component = ( + + ); + break; + case "chain": + component = ; + break; + + default: + component = ( + + ); + break; + } + + return component; + }; + + return ( + <> + + + + + {params.type ? ( + <>{getDetailComponent()} + ) : ( + + + + )} + + + + + ); +}; + +export default ProvinceFees; diff --git a/src/pages/ProvinceFinancial.js b/src/pages/ProvinceFinancial.js new file mode 100644 index 0000000..8595847 --- /dev/null +++ b/src/pages/ProvinceFinancial.js @@ -0,0 +1,97 @@ +import { Box, Typography } from "@mui/material"; +import { Grid } from "../components/grid/Grid"; +import { SPACING } from "../data/spacing"; +import { useLocation } from "react-router-dom"; +import { + ROUTE_PROVINCE_FINANCIAL_ACTIVE_REQUESTS, + ROUTE_PROVINCE_FINANCIAL_ARCHIVED_REQUESTS, + ROUTE_PROVINCE_FINANCIAL_AWAITING_INSPECTION_REQUESTS, + ROUTE_PROVINCE_FINANCIAL_AWAITING_PAYMENT_REQUESTS, + ROUTE_PROVINCE_FINANCIAL_CHECK_PAYED_FACTOR_REQUESTS, + ROUTE_PROVINCE_FINANCIAL_FINAL_FACTORS_REQUESTS, + ROUTE_PROVINCE_FINANCIAL_NEW_REQUESTS, + ROUTE_PROVINCE_FINANCIAL_PENDING_REQUESTS, + ROUTE_PROVINCE_FINANCIAL_REQUESTS, +} from "../routes/routes"; +import { ProvinceFinancialOperations } from "../features/province-finacial/components/province-financial-operations/ProvinceFinancialOperations"; +import { ProvinceFinancialActiveRequests } from "../features/province-finacial/components/province-financial-active-requests/ProvinceFinancialActiveRequests"; +import { AvicultureArchivedRequests } from "../features/aviculture/components/aviculture-archived-requests/AvicultureArchivedRequests"; +import { ProvinceFinancialNewRequests } from "../features/province-finacial/components/province-financial-new-requests/ProvinceFinancialNewRequests"; +import { RequestsAwaitingPayment } from "../components/requests-awaiting-payment/RequestsAwaitingPayment"; +import { RequestsAwaitingInspections } from "../components/requests-awaiting-inspections/RequestsAwaitingInspections"; +import { ProvinceFinancialPendingRequests } from "../features/province-finacial/components/province-financial-pending-requests/ProvinceFinancialPendingRequests"; +import { ProvinceFinancialCheckPayedFactorRequests } from "../features/province-finacial/components/province-financial-check-payed-factor-requests/ProvinceFinancialCheckPayedFactorRequests"; +import { FinalFactorsRequests } from "../features/province-finacial/components/final-factors-requests/FinalFactorsRequests"; +import { BackButton } from "../components/back-button/BackButton"; + +const ProvinceFinancial = () => { + const { pathname } = useLocation(); + + return ( + <> + + + {pathname === ROUTE_PROVINCE_FINANCIAL_REQUESTS ? ( + + + + صفحه مدیریت درخواست ها (اپراتور مالی) + + + + + ) : ( + + )} + + + + {pathname === ROUTE_PROVINCE_FINANCIAL_PENDING_REQUESTS && ( + + )} + {pathname === ROUTE_PROVINCE_FINANCIAL_ACTIVE_REQUESTS && ( + + )} + {pathname === ROUTE_PROVINCE_FINANCIAL_ARCHIVED_REQUESTS && ( + + )} + + {pathname === ROUTE_PROVINCE_FINANCIAL_NEW_REQUESTS && ( + + )} + + {pathname === + ROUTE_PROVINCE_FINANCIAL_AWAITING_PAYMENT_REQUESTS && ( + + )} + + {pathname === + ROUTE_PROVINCE_FINANCIAL_AWAITING_INSPECTION_REQUESTS && ( + + )} + + {pathname === + ROUTE_PROVINCE_FINANCIAL_CHECK_PAYED_FACTOR_REQUESTS && ( + + )} + + {pathname === ROUTE_PROVINCE_FINANCIAL_FINAL_FACTORS_REQUESTS && ( + + )} + + + + + + ); +}; + +export default ProvinceFinancial; diff --git a/src/pages/ProvinceFinancialComplaints.js b/src/pages/ProvinceFinancialComplaints.js new file mode 100644 index 0000000..ffb1aa2 --- /dev/null +++ b/src/pages/ProvinceFinancialComplaints.js @@ -0,0 +1,93 @@ +import { IconButton } from "@mui/material"; +import { Box } from "@mui/system"; +import React, { useEffect, useState } from "react"; +import { useDispatch, useSelector } from "react-redux"; +import { useNavigate } from "react-router-dom"; +import { Grid } from "../components/grid/Grid"; +import { SimpleTable } from "../components/simple-table/SimpleTable"; +import { SPACING } from "../data/spacing"; +import { provinceFinancialGetRegisteredComplaints } from "../features/province-finacial/services/province-financial-get-registered-compaints"; +import { LOADING_END, LOADING_START } from "../lib/redux/slices/appSlice"; +import { ROUTE_PROVINCE_FINANCIAL_FILE } from "../routes/routes"; +import PlagiarismIcon from "@mui/icons-material/Plagiarism"; +import { formatJustDate } from "../utils/formatTime"; + +const ProvinceFinancialComplaints = () => { + const [dataTable, setDataTable] = useState(); + const navigate = useNavigate(); + + const dispatch = useDispatch(); + + const { registeredComplaints } = useSelector( + (state) => state.provinceFinancialSlice + ); + + useEffect(() => { + dispatch(LOADING_START()); + dispatch(provinceFinancialGetRegisteredComplaints()).then((r) => { + dispatch(LOADING_END()); + }); + }, []); + + useEffect(() => { + const d = registeredComplaints?.map((item, i) => { + return [ + item.title, + item.description, + formatJustDate(item?.createDate), + item.state === "pending" + ? "در حال بررسی" + : item.state === "accepted" + ? "تایید شده" + : "رد شده", + + navigate(ROUTE_PROVINCE_FINANCIAL_FILE + item.poultryRequestId) + } + > + + , + ]; + }); + setDataTable(d); + }, []); + return ( + <> + + + + + + + + + + + + + ); +}; + +export default ProvinceFinancialComplaints; diff --git a/src/pages/ProvinceFinancialDebts.js b/src/pages/ProvinceFinancialDebts.js new file mode 100644 index 0000000..ec1cc84 --- /dev/null +++ b/src/pages/ProvinceFinancialDebts.js @@ -0,0 +1,66 @@ +import { Box, Button } from "@mui/material"; +import React from "react"; +import { useDispatch } from "react-redux"; +import { Grid } from "../components/grid/Grid"; +import { SPACING } from "../data/spacing"; +import { DRAWER } from "../lib/redux/slices/appSlice"; +import AttachMoneyIcon from "@mui/icons-material/AttachMoney"; +import { SimpleTable } from "../components/simple-table/SimpleTable"; +import { ProvinceFinancialRegisterDebt } from "../features/province-finacial/components/province-financial-register-debt/ProvinceFinancialRegisterDebt"; + +const ProvinceFinancialDebts = () => { + const dispatch = useDispatch(); + return ( + <> + + + + + + + + + + + + + + + + ); +}; + +export default ProvinceFinancialDebts; diff --git a/src/pages/ProvinceFinancialDocumentRegister.js b/src/pages/ProvinceFinancialDocumentRegister.js new file mode 100644 index 0000000..537098f --- /dev/null +++ b/src/pages/ProvinceFinancialDocumentRegister.js @@ -0,0 +1,43 @@ +import { Box } from "@mui/material"; +import { Grid } from "../components/grid/Grid"; +import { SPACING } from "../data/spacing"; +import { useLocation } from "react-router-dom"; +import { + ROUTE_PROVINCE_FINANCIAL_DOCUMENT_REGISTRATION, + ROUTE_PROVINCE__FINANCIAL_USER_FINACIAL_FILE, +} from "../routes/routes"; +import { ProvinceFinancialDocumentRegistration } from "../features/province-finacial/components/province-financial-document-register/ProvinceFinancialDocumentRegister"; +import ProvinceFinancialUserFinancial from "../features/province-finacial/components/province-financial-user-financial/ProvinceFinancialUserFinancial"; + +const ProvinceFinancialDocumentRegister = () => { + const { pathname } = useLocation(); + + return ( + <> + + + + + {pathname.includes( + ROUTE_PROVINCE_FINANCIAL_DOCUMENT_REGISTRATION + ) && } + + {pathname.includes( + ROUTE_PROVINCE__FINANCIAL_USER_FINACIAL_FILE + ) && } + + + + + + ); +}; +export default ProvinceFinancialDocumentRegister; diff --git a/src/pages/ProvinceGuildsTransactions.js b/src/pages/ProvinceGuildsTransactions.js new file mode 100644 index 0000000..79d64ac --- /dev/null +++ b/src/pages/ProvinceGuildsTransactions.js @@ -0,0 +1,74 @@ +import { Box, IconButton } from "@mui/material"; +import React, { useEffect, useState } from "react"; +import { Grid } from "../components/grid/Grid"; +import { useDispatch } from "react-redux"; +import { getStewards } from "../features/province/services/provinceGetStewards"; +import { AdvancedTable } from "../components/advanced-table/AdvancedTable"; +import ReceiptIcon from "@mui/icons-material/Receipt"; +import { DRAWER } from "../lib/redux/slices/appSlice"; +import MainPlaceFullInfo from "../features/province/components/province-place-full-info/MainPlaceInfo"; +import { useProvinceName } from "../utils/getProvinceName"; + +const ProvinceGuildsTransactions = () => { + const dispatch = useDispatch(); + const [transactions, setTransactions] = useState(); + const [tableData, settableData] = useState(); + const provinceName = useProvinceName(); + + useEffect(() => { + dispatch(getStewards(provinceName)).then((r) => { + setTransactions(r.payload.data); + }); + }, []); + + useEffect(() => { + const d = transactions?.map((item, i) => { + return [ + i + 1, + item?.guild_info.fullname, + item?.guild_info.mobile, + item?.ware_house_info.quantity.toLocaleString(), + { + dispatch( + DRAWER({ + title: "مشخصات کامل محل", + right: false, + bottom: true, + content: , + }) + ); + }} + > + + , + ]; + }); + settableData(d); + }, [transactions]); + return ( + + + {" "} + + + + ); +}; + +export default ProvinceGuildsTransactions; diff --git a/src/pages/ProvinceJahadRequests.js b/src/pages/ProvinceJahadRequests.js new file mode 100644 index 0000000..fbaca2a --- /dev/null +++ b/src/pages/ProvinceJahadRequests.js @@ -0,0 +1,141 @@ +import { Box } from "@mui/material"; +import React, { useState, useEffect } from "react"; +import { Grid } from "../components/grid/Grid"; +import { SPACING } from "../data/spacing"; +import { useLocation } from "react-router-dom"; +import { + ROUTE_COOPERATIVE_PRODUCT_DISTRIBUTION, + ROUTE_COOPERATIVE_PRODUCT_DISTRIBUTION_ALLOCATION, + ROUTE_COOPERATIVE_PRODUCT_DISTRIBUTION_POLICY, + ROUTE_COOPERATIVE_PRODUCT_TRANSACTIONS, + ROUTE_COOPERATIVE_HERDS, + ROUTE_COOPERATIVE_RANCHERS, + ROUTE_COOPERATIVE_USERS, + ROUTE_PROVINCE_JAHAD_PRODUCT_DISTRIBUTION, + ROUTE_PROVINCE_JAHAD_PRODUCT_DISTRIBUTION_ALLOCATION, + ROUTE_PROVINCE_JAHAD_PRODUCT_DISTRIBUTION_POLICY, + ROUTE_PROVINCE_JAHAD_PRODUCT_SHARES, + ROUTE_PROVINCE_JAHAD_PRODUCT_TRANSACTIONS, + ROUTE_PROVINCE_JAHAD_COOPERATIVES, + ROUTE_PROVINCE_JAHAD_HERDS, + ROUTE_PROVINCE_JAHAD_RANCHERS, + ROUTE_PROVINCE_JAHAD_SELL_REPORT, + ROUTE_PROVINCE_JAHAD_UNIONS, + ROUTE_PROVINCE_JAHAD_USERS, + ROUTE_UNION_PRODUCT_DISTRIBUTION, + ROUTE_UNION_PRODUCT_DISTRIBUTION_ALLOCATION, + ROUTE_UNION_PRODUCT_DISTRIBUTION_POLICY, + ROUTE_UNION_PRODUCT_TRANSACTIONS, + ROUTE_UNION_COOPERATIVES, + ROUTE_UNION_HERDS, + ROUTE_UNION_RANCHERS, + ROUTE_UNION_SELL_REPORT, + ROUTE_UNION_USERS, +} from "../routes/routes"; +import { ProvinceJahadUnions } from "../features/province-jahad/components/province-jahad-unions/ProvinceJahadUnions"; +import { ProvinceJahadCooperatives } from "../features/province-jahad/components/province-jahad-cooperatives/ProvinceJahadCooperatives"; +import { ProvinceJahadHerds } from "../features/province-jahad/components/province-jahad-herds/ProvinceJahadHerds"; +import { ProvinceJahadRanchers } from "../features/province-jahad/components/province-jahad-ranchers/ProvinceJahadRanchers"; +import { ProvinceJahadUsers } from "../features/province-jahad/components/province-jahad-users/ProvinceJahadUsers"; +import { ProvinceJahadBranDistributions } from "../features/province-jahad/components/province-jahad-bran-distributions/ProvinceJahadBranDistributions"; +import { BackButton } from "../components/back-button/BackButton"; +import { ProvinceJahadBranDistributionsAllocation } from "../features/province-jahad/components/province-jahad-bran-distributions-allocation/ProvinceJahadBranDistributionsAllocation"; +import { ProvinceJahadBranDistributionsPolicy } from "../features/province-jahad/components/province-jahad-bran-distributions-policy/ProvinceJahadBranDistributionsPolicy"; +import { ProvinceJahadShares } from "../features/province-jahad/components/province-jahad-shares/ProvinceJahadShares"; +import { ProvinceJahadTransactions } from "../features/province-jahad/components/province-jahad-transactions/ProvinceJahadTransactions"; +import { ProvinceJahadSellReport } from "../features/province-jahad/components/province-jahad-sell-report/ProvinceJahadSellReport"; +import ProductSelector from "../features/province-jahad/components/product-selector/ProductSelector"; + +const LOCAL_STORAGE_KEY = "selectedProduct"; + +const ProvinceJahadRequests = () => { + const { pathname } = useLocation(); + + const saved = localStorage.getItem(LOCAL_STORAGE_KEY); + let initialProduct; + try { + initialProduct = saved ? JSON.parse(saved) : { key: "bran", label: "سبوس" }; + } catch { + initialProduct = { key: "bran", label: "سبوس" }; + } + + const [selectedProduct, setSelectedProduct] = useState(initialProduct); + + useEffect(() => { + localStorage.setItem(LOCAL_STORAGE_KEY, JSON.stringify(selectedProduct)); + }, [selectedProduct]); + + return ( + + + + + {pathname === ROUTE_PROVINCE_JAHAD_UNIONS && } + + {(pathname === ROUTE_PROVINCE_JAHAD_COOPERATIVES || + pathname === ROUTE_UNION_COOPERATIVES) && ( + + )} + + {(pathname === ROUTE_PROVINCE_JAHAD_RANCHERS || + pathname === ROUTE_UNION_RANCHERS || + pathname === ROUTE_COOPERATIVE_RANCHERS) && } + + {(pathname === ROUTE_PROVINCE_JAHAD_HERDS || + pathname === ROUTE_UNION_HERDS || + pathname === ROUTE_COOPERATIVE_HERDS) && } + + {(pathname === ROUTE_PROVINCE_JAHAD_USERS || + pathname === ROUTE_UNION_USERS || + pathname === ROUTE_COOPERATIVE_USERS) && } + + {(pathname === ROUTE_PROVINCE_JAHAD_PRODUCT_DISTRIBUTION || + pathname === ROUTE_UNION_PRODUCT_DISTRIBUTION || + pathname === ROUTE_COOPERATIVE_PRODUCT_DISTRIBUTION) && ( + <> + setSelectedProduct(p)} /> + + + )} + + {(pathname === ROUTE_PROVINCE_JAHAD_PRODUCT_DISTRIBUTION_ALLOCATION || + pathname === ROUTE_UNION_PRODUCT_DISTRIBUTION_ALLOCATION || + pathname === ROUTE_COOPERATIVE_PRODUCT_DISTRIBUTION_ALLOCATION) && ( + + )} + + {(pathname === ROUTE_PROVINCE_JAHAD_PRODUCT_DISTRIBUTION_POLICY || + pathname === ROUTE_UNION_PRODUCT_DISTRIBUTION_POLICY || + pathname === ROUTE_COOPERATIVE_PRODUCT_DISTRIBUTION_POLICY) && ( + + )} + + {(pathname === ROUTE_PROVINCE_JAHAD_PRODUCT_TRANSACTIONS || + pathname === ROUTE_UNION_PRODUCT_TRANSACTIONS || + pathname === ROUTE_COOPERATIVE_PRODUCT_TRANSACTIONS) && ( + + )} + + {pathname === ROUTE_PROVINCE_JAHAD_PRODUCT_SHARES && ( + + )} + + {(pathname === ROUTE_UNION_SELL_REPORT || + pathname === ROUTE_PROVINCE_JAHAD_SELL_REPORT) && ( + + )} + + + ); +}; + +export default ProvinceJahadRequests; diff --git a/src/pages/ProvinceKillersWages.js b/src/pages/ProvinceKillersWages.js new file mode 100644 index 0000000..f71e98f --- /dev/null +++ b/src/pages/ProvinceKillersWages.js @@ -0,0 +1,245 @@ +import React, { useEffect, useState } from "react"; +import { Grid } from "../components/grid/Grid"; +import { BackButton } from "../components/back-button/BackButton"; +import { Box, Button } from "@mui/material"; +import { useParams } from "react-router-dom"; +import { useDispatch, useSelector } from "react-redux"; +import { provincePaymentGetKillersOfKillhousesInfo } from "../features/province/services/province-payment-get-killers-of-killhouses-info"; +import ResponsiveTable from "../components/responsive-table/ResponsiveTable"; +import { OPEN_MODAL } from "../lib/redux/slices/appSlice"; +import { SimpleTable } from "../components/simple-table/SimpleTable"; + +const ProvinceKillersWages = () => { + const { key } = useParams(); + const [tableData, setTableData] = useState(); + + const dispatch = useDispatch(); + + useEffect(() => { + dispatch( + provincePaymentGetKillersOfKillhousesInfo({ kill_house_key: key }) + ); + }, []); + const { provincePaymentByWeightOverview } = useSelector( + (item) => item.provinceSlice + ); + const { provincePaymentKillersOfKillhouses } = useSelector( + (item) => item.provinceSlice + ); + + const getKillHouseShares = (shares, name) => { + // if (!shares || shares.length === 0) { + // return ( + // + // ); + // } + + const shareData = shares.map((share, i) => [ + i + 1, + share?.name, + share?.provinceKillRequestWage?.toLocaleString() || "0", + share?.freeSellCarcassesWage?.toLocaleString() || "0", + share?.freeBuyingCarcassesWage?.toLocaleString() || "0", + share?.freeBuyingLiveWage?.toLocaleString() || "0", + ( + (share?.provinceKillRequestWage || 0) + + (share?.freeSellCarcassesWage || 0) + + (share?.freeBuyingCarcassesWage || 0) + + (share?.freeBuyingLiveWage || 0) + )?.toLocaleString(), + share?.totalPaidWage?.toLocaleString() || "0", + share?.totalUnpaidWage?.toLocaleString() || "0", + ]); + + return ( + + ); + }; + + useEffect(() => { + if (provincePaymentByWeightOverview) { + const d = provincePaymentKillersOfKillhouses?.map((item, i) => { + if ( + provincePaymentByWeightOverview?.wageInfo?.wageCountingType === "live" + ) { + return [ + item?.name, + Math.ceil(item?.wageInfo?.totalWage)?.toLocaleString(), + Math.ceil(item?.wageInfo?.totalPaidWage)?.toLocaleString(), + Math.ceil(item?.wageInfo?.off)?.toLocaleString(), + Math.ceil(item?.wageInfo?.totalUnpaidWage)?.toLocaleString(), + + Math.ceil( + item?.wageInfo?.totalProvinceLiveWeight + )?.toLocaleString(), + Math.ceil( + item?.wageInfo?.provinceKillRequestsTotalWage + )?.toLocaleString(), + Math.ceil( + item?.wageInfo?.freeBarsOutProvinceCarcasesTotalWeight + )?.toLocaleString(), + Math.ceil( + item?.wageInfo?.freeBarsOutProvinceCarcasesTotalWage + )?.toLocaleString(), + Math.ceil( + item?.wageInfo?.freeBarsCarcasesTotalWeight + )?.toLocaleString(), + Math.ceil( + item?.wageInfo?.freeBarsCarcasesTotalWage + )?.toLocaleString(), + Math.ceil( + item?.wageInfo?.freeBarsLiveTotalWeight + )?.toLocaleString(), + Math.ceil(item?.wageInfo?.freeBarsLiveTotalWage)?.toLocaleString(), + getKillHouseShares(item?.wageInfo?.shares, item?.name), + ]; + } else { + return [ + item?.name, + Math.ceil(item?.wageInfo?.totalWage)?.toLocaleString(), + Math.ceil(item?.wageInfo?.totalPaidWage)?.toLocaleString(), + Math.ceil(item?.wageInfo?.off)?.toLocaleString(), + Math.ceil(item?.wageInfo?.totalUnpaidWage)?.toLocaleString(), + + Math.ceil( + item?.wageInfo?.totalProvinceLiveWeight + )?.toLocaleString(), + Math.ceil( + item?.wageInfo?.totalProvinceCarcassesWeight + )?.toLocaleString(), + Math.ceil( + item?.wageInfo?.provinceKillRequestsTotalWeight + )?.toLocaleString(), + Math.ceil( + item?.wageInfo?.provinceKillRequestsTotalWage + )?.toLocaleString(), + Math.ceil( + item?.wageInfo?.freeBarsOutProvinceCarcasesTotalWeight + )?.toLocaleString(), + Math.ceil( + item?.wageInfo?.freeBarsOutProvinceCarcasesTotalWage + )?.toLocaleString(), + Math.ceil( + item?.wageInfo?.freeBarsCarcasesTotalWeight + )?.toLocaleString(), + Math.ceil( + item?.wageInfo?.freeBarsCarcasesTotalWage + )?.toLocaleString(), + Math.ceil( + item?.wageInfo?.freeBarsLiveTotalWeight + )?.toLocaleString(), + Math.ceil(item?.wageInfo?.freeBarsLiveTotalWage)?.toLocaleString(), + getKillHouseShares(item?.wageInfo?.shares, item?.name), + ]; + } + }); + + setTableData(d); + } + }, [provincePaymentKillersOfKillhouses, provincePaymentByWeightOverview]); + + return ( + <> + + + + + + + + + + + + ); +}; + +export default ProvinceKillersWages; diff --git a/src/pages/ProvinceManagePricing.js b/src/pages/ProvinceManagePricing.js new file mode 100644 index 0000000..1099539 --- /dev/null +++ b/src/pages/ProvinceManagePricing.js @@ -0,0 +1,41 @@ +import { Box } from "@mui/material"; +import { Grid } from "../components/grid/Grid"; +import { SPACING } from "../data/spacing"; +// import { ProvincePricingOperations } from "../features/province/components/province-pricing-operations/ProvincePricingOperations"; +import { ProvincePricing } from "../features/province/components/province-pricing/ProvincePricing"; + +const ProvinceManagePricing = () => { + return ( + <> + + + {/* + + + + */} + + + + + + + + + ); +}; + +export default ProvinceManagePricing; diff --git a/src/pages/ProvinceManageStewards.js b/src/pages/ProvinceManageStewards.js new file mode 100644 index 0000000..ce75e00 --- /dev/null +++ b/src/pages/ProvinceManageStewards.js @@ -0,0 +1,92 @@ +import { SPACING } from "../data/spacing"; +import { NavLink } from "../components/nav-link/NavLink"; +import { useLocation } from "react-router-dom"; + +import LinkItem from "../components/link-item/LinkItem"; +import { MdCorporateFare } from "react-icons/md"; +import { BackButton } from "../components/back-button/BackButton"; +import { Grid } from "../components/grid/Grid"; +import { + ROUTE_ADMINX_ROUTE_MANAGE_STEWARDS, + ROUTE_PROVINCE_SUPERVISOR_ROUTE_MANAGE_STEWARDS, + ROUTE_SUPER_ADMIN_ROUTE_MANAGE_STEWARDS, +} from "../routes/routes"; + +const ProvinceManageStewards = () => { + const { pathname } = useLocation(); + + return ( + <> + {["reza"].includes(pathname) && } + + + {(ROUTE_ADMINX_ROUTE_MANAGE_STEWARDS === pathname || + ROUTE_SUPER_ADMIN_ROUTE_MANAGE_STEWARDS === pathname || + ROUTE_PROVINCE_SUPERVISOR_ROUTE_MANAGE_STEWARDS === pathname) && ( + <> + + } + title="مباشرین داخل استان" + /> + + + } + title="مباشرین خارج استان" + /> + + + )} + {["reza"].includes(pathname) && ( + <> + + } + title="درخواست های ثبت صنف" + /> + + + } + title="اصناف حقیقی" + /> + + + } + title="اصناف حقوقی" + /> + + + )} + + {["reza"].includes(pathname) && ( + <> + + } + title="اصناف حقیقی" + /> + + + } + title="اصناف حقوقی" + /> + + + )} + + + ); +}; + +export default ProvinceManageStewards; diff --git a/src/pages/ProvinceProducts.js b/src/pages/ProvinceProducts.js new file mode 100644 index 0000000..ff96eb8 --- /dev/null +++ b/src/pages/ProvinceProducts.js @@ -0,0 +1,199 @@ +import { Box, Button, Switch, Typography } from "@mui/material"; +import { Grid } from "../components/grid/Grid"; +import { SPACING } from "../data/spacing"; +import { useContext, useEffect, useState } from "react"; +import { useDispatch, useSelector } from "react-redux"; +import { provinceGetProducts } from "../features/province/services/province-get-producrs"; +import { SimpleTable } from "../components/simple-table/SimpleTable"; +import { OPEN_MODAL } from "../lib/redux/slices/appSlice"; +import { ProvinceSubmitProductPrice } from "../features/province/components/province-submit-product-price/ProvinceSubmitProductPrice"; +import { provinceSubmitProductPrice } from "../features/province/services/province-submit-product-price"; +import { AppContext } from "../contexts/AppContext"; + +const ProvinceProducts = () => { + const [openNotif] = useContext(AppContext); + + const dispatch = useDispatch(); + useEffect(() => { + dispatch(provinceGetProducts()); + }, []); + + const handleRespose = (r) => { + if (r.error) { + openNotif({ + vertical: "top", + horizontal: "center", + msg: "مشکلی پیش آمده است!", + severity: "error", + }); + } else { + openNotif({ + vertical: "top", + horizontal: "center", + msg: "عملیات با موفقیت انجام شد.", + severity: "success", + }); + dispatch(provinceGetProducts()); + } + }; + + const { provinceProductList } = useSelector((item) => item.provinceSlice); + + const [tableData, setTableData] = useState([]); + + useEffect(() => { + const d = provinceProductList?.map((item, i) => [ + i + 1, + item?.name, + { + dispatch( + provinceSubmitProductPrice({ + product_key: item?.key, + selling_free_price: item?.sellingFreePrice, + selling_approved_price: + item?.sellingApprovedPrice === true ? false : true, + selling_more_than_inventory: item?.sellingMoreThanInventory, + selling_other_products: item?.sellingOtherProducts, + price: item?.price, + }) + ).then((r) => { + handleRespose(r); + }); + }} + />, + { + dispatch( + provinceSubmitProductPrice({ + product_key: item?.key, + selling_free_price: + item?.sellingFreePrice === true ? false : true, + selling_approved_price: item?.sellingApprovedPrice, + selling_more_than_inventory: item?.sellingMoreThanInventory, + selling_other_products: item?.sellingOtherProducts, + price: item?.price, + }) + ).then((r) => { + handleRespose(r); + }); + }} + />, + { + dispatch( + provinceSubmitProductPrice({ + product_key: item?.key, + selling_free_price: item?.sellingFreePrice, + selling_approved_price: item?.sellingApprovedPrice, + selling_more_than_inventory: + item?.sellingMoreThanInventory === true ? false : true, + selling_other_products: item?.sellingOtherProducts, + price: item?.price, + }) + ).then((r) => { + handleRespose(r); + }); + }} + />, + { + dispatch( + provinceSubmitProductPrice({ + product_key: item?.key, + selling_free_price: item?.sellingFreePrice, + selling_approved_price: item?.sellingApprovedPrice, + selling_more_than_inventory: item?.sellingMoreThanInventory, + selling_other_products: + item?.sellingOtherProducts === true ? false : true, + price: item?.price, + }) + ).then((r) => { + handleRespose(r); + }); + }} + />, + + بدون بار + , + + {item?.price} + + , + ]); + + setTableData(d); + }, [provinceProductList]); + + return ( + <> + + + + + + محصولات + + + + + + + + ); +}; + +export default ProvinceProducts; diff --git a/src/pages/ProvinceReports.js b/src/pages/ProvinceReports.js new file mode 100644 index 0000000..9a7107e --- /dev/null +++ b/src/pages/ProvinceReports.js @@ -0,0 +1,354 @@ +import { Box, TextField, Typography } from "@mui/material"; +import { Grid } from "../components/grid/Grid"; +import { SPACING } from "../data/spacing"; +import { BackButton } from "../components/back-button/BackButton"; +import { useContext, useState } from "react"; +import { AppContext } from "../contexts/AppContext"; +import { DatePicker } from "@mui/x-date-pickers"; +import moment from "moment"; +import axios from "axios"; +import { getRoleFromUrl } from "../utils/getRoleFromUrl"; +import { useSelector } from "react-redux"; +import { RiFileExcel2Fill, RiTicket2Line } from "react-icons/ri"; +import { ImFilePdf } from "react-icons/im"; + +import { motion } from "framer-motion"; + +const ProvinceRequests = () => { + const [, , selectedDate1, setSelectedDate1, selectedDate2, setSelectedDate2] = + useContext(AppContext); + useContext(AppContext); + const [openNotif] = useContext(AppContext); + + const authToken = useSelector((state) => state.userSlice.authToken); + const userInfo = useSelector((state) => state.userSlice); + const [textValue, setTextValue] = useState(""); + + const handleDownload = (link, isTicket = false) => { + if (!isTicket) { + openNotif({ + vertical: "top", + horizontal: "center", + msg: "فایل در حال دانلود می باشد، این عملیات ممکن است زمان بر باشد لطفا صبر کنید.", + severity: "success", + }); + window.location.href = link; + } + }; + + const handleTicketClick = async (link) => { + try { + const response = await axios.get(link); + if (response.status === 200) { + openNotif({ + vertical: "top", + horizontal: "center", + msg: "تیکت با موفقیت ارسال شد", + severity: "success", + }); + } + } catch (error) { + openNotif({ + vertical: "top", + horizontal: "center", + msg: "خطا در ارسال تیکت", + severity: "error", + }); + } + }; + + const reportList = [ + { + title: "گزارش تحلیلی", + description: "گزارش تحلیلی از زنجیره مرغ گوشتی در استان", + link: `${axios.defaults.baseURL}management_all_poultry_and_warehouse_pdf/?date1=${selectedDate1}&date2=${selectedDate2}`, + icon: , + }, + { + title: "تیکت وضعیت سند بار ها", + description: "تیکت وضعیت سند بار ها", + link: `${axios.defaults.baseURL}send_bar_info_from_ticket/?key=${userInfo?.userProfile?.key}&date1=${selectedDate1}&date2=${selectedDate2}`, + icon: , + isTicket: true, + }, + { + title: "مغایرت قرنطینه", + description: "مغایرت قرنطینه", + link: `${axios.defaults.baseURL}send_clearance_code_to_rsi/?date1=${selectedDate1}&date2=${selectedDate2}`, + }, + { + title: "گزارش جامع کشتار", + description: "اطلاعات کلی از کشتار تا صنف", + link: `${ + axios.defaults.baseURL + }detail_of_killing_excel/?date1=${selectedDate1}&date2=${selectedDate2}&role=${getRoleFromUrl()}&key=${ + userInfo?.userProfile?.key + }`, + }, + { + title: "گزارش پایش کشتارگاه ها", + description: "پایش کلی کشتارگاه ها", + link: `${axios.defaults.baseURL}comprehensive_report_of_the_slaughterhouse_excel/?date1=${selectedDate1}&date2=${selectedDate2}`, + }, + { + title: "اطلاعات بارها", + description: "جزئیات بارهای ایجاد شده", + link: `${ + axios.defaults.baseURL + }bar_excel/?start=${selectedDate1}&end=${selectedDate2}&key=${ + userInfo?.userProfile?.key + }&role=${getRoleFromUrl()}`, + }, + { + title: "گزارش پایش تعاونی ها", + description: "جزئیات جوجه ریزی و کشتار تعاونی ها", + link: `${ + axios.defaults.baseURL + }general_city_operator/?date1=${selectedDate1}&date2=${selectedDate2}&key=${ + userInfo?.userProfile?.key + }&role=${getRoleFromUrl()}`, + }, + { + title: "گزارش کلی خریداران", + description: "گزارش تخصیص و پخش خریداران", + link: `${axios.defaults.baseURL}kill_house_user_excel/?date1=${selectedDate1}&date2=${selectedDate2}`, + }, + + { + title: "درخواست مرغداران", + description: "درخواست های کتشار ثبت شده توسط مرغداران", + link: `${ + axios.defaults.baseURL + }poultry_kill_request_excel/?start=${selectedDate1}&end=${selectedDate1}&role=${getRoleFromUrl()}&token=${authToken}`, + }, + { + title: "اعلام نیاز خریداران", + description: "اعلام نیاز کشتار از طرف خریداران", + link: `${axios.defaults.baseURL}kill_house_excel/?start=${selectedDate1}&end=${selectedDate2}`, + }, + { + title: "جوجه ریزی های فعال", + description: "اطلاعات تکمیلی جوجه ریزی", + link: `${axios.defaults.baseURL}0/hatching_excel`, + }, + { + title: "جوجه ریزی های بایگانی شده", + description: "اطلاعات تکمیلی جوجه ریزی", + link: `${axios.defaults.baseURL}archive_hatching_excel/?key=${userInfo?.userProfile?.key}`, + }, + { + title: "درخواست های کشتار", + description: "جزئیات درخواست مرغداران تا تحویلی کشتارگاه", + link: `${axios.defaults.baseURL}poultry_request_report_excel/?start=${selectedDate1}&end=${selectedDate2}&key=${userInfo?.userProfile?.key}`, + }, + { + title: "اصناف", + description: "اطلاعات اصناف ثبت شده", + link: `${axios.defaults.baseURL}guilds_excel/?key=${userInfo?.userProfile?.key}`, + }, + { + title: "کاربران", + description: "اطلاعات کاربران ثبت شده", + link: `${axios.defaults.baseURL}get_all_user_excel/`, + }, + { + title: "تخصیصات", + description: "جزئیات تخصیص به خریداران", + link: `${axios.defaults.baseURL}allocated_excel/?start=${selectedDate1}&end=${selectedDate2}`, + }, + { + title: "گزارش پخش روزانه", + description: "کشتارگاه به مباشر/صنف", + link: `${axios.defaults.baseURL}all_inventory_excel/?date1=${selectedDate1}&date2=${selectedDate2}`, + }, + { + title: "گزارش پخش روزانه", + description: "مباشر به صنف", + link: `${axios.defaults.baseURL}steward_ware_house_total_report_daily_excel/?date1=${selectedDate1}&date2=${selectedDate2}`, + }, + { + title: "آمار جوجه ریزی", + description: "جزئیات جوجه ریزی", + link: `${axios.defaults.baseURL}hatching_date_range_excel/?date1=${selectedDate1}&date2=${selectedDate2}`, + }, + { + title: "بارهای تکمیل شده", + description: "جزئیات بارهای تکمیل شده", + link: `${axios.defaults.baseURL}bar-management-kill-house-excel/?key=${userInfo?.userProfile?.key}&date1=${selectedDate1}&date2=${selectedDate2}`, + }, + ]; + + return ( + + + + + + + + + + تاریخ گزارش: + + + + + ( + + )} + value={selectedDate1} + onChange={(newValue) => { + setSelectedDate1(moment(newValue).format("YYYY-MM-DD")); + }} + /> + + ( + + )} + value={selectedDate2} + onChange={(newValue) => { + setSelectedDate2(moment(newValue).format("YYYY-MM-DD")); + }} + /> + + + { + setTextValue(e.target.value); + }} + /> + + + + + + {reportList + ?.filter((option) => option?.title.includes(textValue)) + ?.map((item, i) => ( + + { + if (item.isTicket) { + e.preventDefault(); + handleTicketClick(item.link); + } else { + e.preventDefault(); + handleDownload(item.link, item.isTicket); + } + }} + > + + + + {item.icon || ( + + )} + + + {item?.title} + + + {item?.description} + + + + + + ))} + + + + + ); +}; + +export default ProvinceRequests; diff --git a/src/pages/ProvinceRequests.js b/src/pages/ProvinceRequests.js new file mode 100644 index 0000000..5b398ec --- /dev/null +++ b/src/pages/ProvinceRequests.js @@ -0,0 +1,196 @@ +import { Box, Typography } from "@mui/material"; +import { Grid } from "../components/grid/Grid"; +import { SPACING } from "../data/spacing"; +import { useLocation } from "react-router-dom"; +import { ProvinceRequestsOperations } from "../features/province/components/province-requests-operations/ProvinceRequestsOperations"; +import { ProvinceNewRequests } from "../features/province/components/province-new-requests/ProvinceNewRequests"; +import { + ROUTE_ADMINX_REQUESTS, + ROUTE_ADMINX_CITY_NEW_REQUESTS, + ROUTE_ADMINX_STATEMENTـOFـNEED_REQUESTS, + ROUTE_ADMINX_ALLOCATION_REQUESTS, + ROUTE_ADMINX_FREE_SALES_REQUESTS, + ROUTE_ADMINX_AWAITING_PAYMENT_REQUESTS, + ROUTE_ADMINX_AWAITING_INSPECTION_REQUESTS, + ROUTE_ADMINX_AUTO_ALLOCATION_REQUESTS, + ROUTE_ADMINX_CHAINS, + ROUTE_ADMINX_ALLOCATED_REQUESTS, + ROUTE_ADMINX_ISSUANCE_OF_LETTER, + ROUTE_ADMINX_EXPORT, + ROUTE_PROVINCE_ACTIVE_REQUESTS, + ROUTE_PROVINCE_ALLOCATED_REQUESTS, + ROUTE_PROVINCE_ALLOCATION_REQUESTS, + ROUTE_PROVINCE_ARCHIVED_REQUESTS, + ROUTE_PROVINCE_AUTO_ALLOCATION_REQUESTS, + ROUTE_PROVINCE_AWAITING_INSPECTION_REQUESTS, + ROUTE_PROVINCE_AWAITING_PAYMENT_REQUESTS, + ROUTE_PROVINCE_CHAINS, + ROUTE_PROVINCE_CITY_NEW_REQUESTS, + ROUTE_PROVINCE_FREE_SALES_REQUESTS, + ROUTE_PROVINCE_ISSUANCE_OF_LETTER, + ROUTE_PROVINCE_NEW_REQUESTS, + ROUTE_PROVINCE_REJECTED_REQUESTS, + ROUTE_PROVINCE_REQUESTS, + ROUTE_PROVINCE_STATEMENTـOFـNEED_REQUESTS, + ROUTE_PROVINCEـEXPORT, + ROUTE_PROVINCEـFREE_BUY, + ROUTE_SUPER_ADMIN_ACTIVE_REQUESTS, + ROUTE_SUPER_ADMIN_ALLOCATED_REQUESTS, + ROUTE_SUPER_ADMIN_ALLOCATION_REQUESTS, + ROUTE_SUPER_ADMIN_ARCHIVED_REQUESTS, + ROUTE_SUPER_ADMIN_AUTO_ALLOCATION_REQUESTS, + ROUTE_SUPER_ADMIN_AWAITING_INSPECTION_REQUESTS, + ROUTE_SUPER_ADMIN_AWAITING_PAYMENT_REQUESTS, + ROUTE_SUPER_ADMIN_CHAINS, + ROUTE_SUPER_ADMIN_CITY_NEW_REQUESTS, + ROUTE_SUPER_ADMIN_EXPORT, + ROUTE_SUPER_ADMIN_FREE_SALES_REQUESTS, + ROUTE_SUPER_ADMIN_ISSUANCE_OF_LETTER, + ROUTE_SUPER_ADMIN_REJECTED_REQUESTS, + ROUTE_SUPER_ADMIN_REQUESTS, + ROUTE_SUPER_ADMIN_STATEMENTـOFـNEED_REQUESTS, + ROUT_SUPER_ADMIN_FREE_BUY, + ROUTE_ADMINX_ARCHIVED_REQUESTS, + ROUTE_ADMINX_ACTIVE_REQUESTS, + ROUT_ADMINX_FREE_BUY, +} from "../routes/routes"; +import { ProvinceRejectedRequests } from "../features/province/components/province-rejected-requests/ProvinceRejectedRequests"; +import { AvicultureArchivedRequests } from "../features/aviculture/components/aviculture-archived-requests/AvicultureArchivedRequests"; +import { ProvinceCityNewRequests } from "../features/province/components/province-city-new-requests/ProvinceCityNewRequests"; +import { RequestsAwaitingPayment } from "../components/requests-awaiting-payment/RequestsAwaitingPayment"; +import { RequestsAwaitingInspections } from "../components/requests-awaiting-inspections/RequestsAwaitingInspections"; +import { BackButton } from "../components/back-button/BackButton"; +import { ProvinceNeedRequests } from "../features/province/components/province-need-requests/ProvinceNeedRequests"; +import { ProvinceAllocateRequests } from "../features/province/components/province-allocate-requests/ProvinceAllocateRequests"; +import { ProvinceActiveRequests } from "../features/province/components/province-active-requests/ProvinceActiveRequests"; +import { ProvinceFreeSales } from "../features/province/components/province-free-sales/ProvinceFreeSales"; +import { ProvinceAutoAllocation } from "../features/province/components/province-auto-allocation/ProvinceAutoAllocation"; +import { ProvinceAllocatedRequests } from "../features/province/components/province-allocated-requests/ProvinceAllocatedRequests"; +import { SlaughterFreeBuy } from "../features/slaughter-house/components/slaughter-free-buy/SlaughterFreeBuy"; +import { ProvinceSendLetter } from "../features/province/components/province-send-letter/ProvinceSendLetter"; +import { getRoleFromUrl } from "../utils/getRoleFromUrl"; +import { SuperAdminRequestsOperations } from "../features/super-admin/components/super-admin-requests-operations/SuperAdminRequestsOperations"; +import { ProvinceChains } from "../features/province/components/chains/ProvinceChains"; +import { ProvinceExport } from "../features/province/components/province-export/ProvinceExport"; + +const ProvinceRequests = () => { + const { pathname } = useLocation(); + + return ( + + + {pathname === ROUTE_PROVINCE_REQUESTS || + pathname === ROUTE_SUPER_ADMIN_REQUESTS || + pathname === ROUTE_ADMINX_REQUESTS ? ( + + {getRoleFromUrl() === "SuperAdmin" || + getRoleFromUrl() === "AdminX" ? ( + <> + + {getRoleFromUrl() === "SuperAdmin" ? ( + + داشبورد ادمین کل + + ) : ( + + داشبورد ادمین ایکس + + )} + + + + ) : ( + <> + + + داشبورد تخصیص استان + + + + + )} + + ) : ( + + )} + + + {(pathname === ROUTE_PROVINCE_CITY_NEW_REQUESTS || + pathname === ROUTE_SUPER_ADMIN_CITY_NEW_REQUESTS || + pathname === ROUTE_ADMINX_CITY_NEW_REQUESTS) && ( + + )} + {(pathname === ROUTE_PROVINCE_STATEMENTـOFـNEED_REQUESTS || + pathname === ROUTE_SUPER_ADMIN_STATEMENTـOFـNEED_REQUESTS || + pathname === ROUTE_ADMINX_STATEMENTـOFـNEED_REQUESTS) && ( + + )} + {pathname === ROUTE_PROVINCE_NEW_REQUESTS && } + {(pathname === ROUTE_PROVINCE_ALLOCATION_REQUESTS || + pathname === ROUTE_SUPER_ADMIN_ALLOCATION_REQUESTS || + pathname === ROUTE_ADMINX_ALLOCATION_REQUESTS) && ( + + )} + {(pathname === ROUTE_PROVINCE_ACTIVE_REQUESTS || + pathname === ROUTE_SUPER_ADMIN_ACTIVE_REQUESTS || + pathname === ROUTE_ADMINX_ACTIVE_REQUESTS) && ( + + )} + {(pathname === ROUTE_PROVINCE_FREE_SALES_REQUESTS || + pathname === ROUTE_SUPER_ADMIN_FREE_SALES_REQUESTS || + pathname === ROUTE_ADMINX_FREE_SALES_REQUESTS) && ( + + )} + {(pathname === ROUTE_PROVINCE_REJECTED_REQUESTS || + pathname === ROUTE_SUPER_ADMIN_REJECTED_REQUESTS || + pathname === ROUTE_PROVINCE_REJECTED_REQUESTS) && ( + + )} + {(pathname === ROUTE_PROVINCE_ARCHIVED_REQUESTS || + pathname === ROUTE_SUPER_ADMIN_ARCHIVED_REQUESTS || + pathname === ROUTE_ADMINX_ARCHIVED_REQUESTS) && ( + + )} + {(pathname === ROUTE_PROVINCE_AWAITING_PAYMENT_REQUESTS || + pathname === ROUTE_SUPER_ADMIN_AWAITING_PAYMENT_REQUESTS || + pathname === ROUTE_ADMINX_AWAITING_PAYMENT_REQUESTS) && ( + + )} + {(pathname === ROUTE_PROVINCE_AWAITING_INSPECTION_REQUESTS || + pathname === ROUTE_SUPER_ADMIN_AWAITING_INSPECTION_REQUESTS || + pathname === ROUTE_ADMINX_AWAITING_INSPECTION_REQUESTS) && ( + + )} + {(pathname === ROUTE_PROVINCE_AUTO_ALLOCATION_REQUESTS || + pathname === ROUTE_SUPER_ADMIN_AUTO_ALLOCATION_REQUESTS || + pathname === ROUTE_ADMINX_AUTO_ALLOCATION_REQUESTS) && ( + + )} + {(pathname === ROUTE_PROVINCE_CHAINS || + pathname === ROUTE_SUPER_ADMIN_CHAINS || + pathname === ROUTE_ADMINX_CHAINS) && } + + {(pathname === ROUTE_PROVINCE_ALLOCATED_REQUESTS || + pathname === ROUTE_SUPER_ADMIN_ALLOCATED_REQUESTS || + pathname === ROUTE_ADMINX_ALLOCATED_REQUESTS) && ( + + )} + {(pathname === ROUTE_PROVINCEـFREE_BUY || + pathname === ROUT_SUPER_ADMIN_FREE_BUY || + pathname === ROUT_ADMINX_FREE_BUY) && } + + {(pathname === ROUTE_PROVINCE_ISSUANCE_OF_LETTER || + pathname === ROUTE_SUPER_ADMIN_ISSUANCE_OF_LETTER || + pathname === ROUTE_ADMINX_ISSUANCE_OF_LETTER) && ( + + )} + {(pathname === ROUTE_SUPER_ADMIN_EXPORT || + pathname === ROUTE_PROVINCEـEXPORT || + pathname === ROUTE_ADMINX_EXPORT) && } + + + + ); +}; + +export default ProvinceRequests; diff --git a/src/pages/ProvinceSendMessage.js b/src/pages/ProvinceSendMessage.js new file mode 100644 index 0000000..de6a899 --- /dev/null +++ b/src/pages/ProvinceSendMessage.js @@ -0,0 +1,93 @@ +import { Box, Button, Chip, Divider, Typography } from "@mui/material"; +import { Grid } from "../components/grid/Grid"; +import { SPACING } from "../data/spacing"; + +import * as React from "react"; + +import { DRAWER } from "../lib/redux/slices/appSlice"; + +import ProvinceSubmitMessage from "../features/province/components/province-submit-message/ProvinceSubmitMessage"; +import { useDispatch, useSelector } from "react-redux"; +import { messagesGetSenderMessages } from "../features/messages/services/messages-get-sender-messages"; +import { useEffect } from "react"; +import MessagesSenders from "../features/messages/components/messages-senders/MessagesSenders"; +import { provinceGetUserProfiles } from "../features/province/services/province-get-user-profiles"; +// import { useState } from "react"; + +const ProvinceSendMessage = () => { + const dispatch = useDispatch(); + + const { senderMessages } = useSelector((state) => state.messageSlice); + + useEffect(() => { + dispatch(messagesGetSenderMessages()); + dispatch(provinceGetUserProfiles()); + }, []); + + return ( + <> + + + + + + + + + + + {!senderMessages?.length && ( + + + در حال حاضر پیامی جهت نمایش وجود ندارد! + + + )} + + + {senderMessages?.map((item, i) => { + return [ + , + ]; + })} + + + + + ); +}; + +export default ProvinceSendMessage; diff --git a/src/pages/ProvinceSettlementPage.js b/src/pages/ProvinceSettlementPage.js new file mode 100644 index 0000000..96dbde1 --- /dev/null +++ b/src/pages/ProvinceSettlementPage.js @@ -0,0 +1,33 @@ +import { Box } from "@mui/material"; +import { Grid } from "../components/grid/Grid"; +import { SPACING } from "../data/spacing"; +import { ProvinceFinancialSettlementSlaughter } from "../features/province-finacial/components/province-financial-settlement-slaughter/ProvinceFinancialSettlementSlaughter"; +import { ROUTE_PROVINCE_FINANCIAL_SETTLEMENT } from "../routes/routes"; + +const ProvinceSettlementPage = () => { + return ( + <> + + + + + {ROUTE_PROVINCE_FINANCIAL_SETTLEMENT && ( + + )} + + + + + + ); +}; + +export default ProvinceSettlementPage; diff --git a/src/pages/ProvinceUserFile.js b/src/pages/ProvinceUserFile.js new file mode 100644 index 0000000..3492476 --- /dev/null +++ b/src/pages/ProvinceUserFile.js @@ -0,0 +1,29 @@ +import { Box } from "@mui/material"; +import { Grid } from "../components/grid/Grid"; +import { SPACING } from "../data/spacing"; +import { ProvinceUserFileInfo } from "../features/inspector/components/province-user-file-info/ProvinceUserFileInfo"; + +const ProvinceUserFile = () => { + return ( + <> + + + + + + + + + + + ); +}; +export default ProvinceUserFile; diff --git a/src/pages/ProvinceUserManagement.js b/src/pages/ProvinceUserManagement.js new file mode 100644 index 0000000..f54d73b --- /dev/null +++ b/src/pages/ProvinceUserManagement.js @@ -0,0 +1,30 @@ +import { Box } from "@mui/material"; +import { Grid } from "../components/grid/Grid"; +import { SPACING } from "../data/spacing"; +import { ProvinceUsers } from "../features/inspector/components/province-users/ProvinceUsers"; + +const ProvinceUserManagement = () => { + return ( + <> + + + + + + + + + + + ); +}; + +export default ProvinceUserManagement; diff --git a/src/pages/PspCompany.js b/src/pages/PspCompany.js new file mode 100644 index 0000000..8c6a87b --- /dev/null +++ b/src/pages/PspCompany.js @@ -0,0 +1,76 @@ +import { Box } from "@mui/material"; +import { Grid } from "../components/grid/Grid"; +import { SPACING } from "../data/spacing"; +import { useLocation } from "react-router-dom"; +import { + ROUTE_PSP_COMPANY_ROUTE_ACTIVE_SESSION, + ROUTE_PSP_COMPANY_ROUTE_GUILDS, + ROUTE_PSP_COMPANY_ROUTE_DEVICES, + ROUTE_SUPER_ADMIN_COMPANY_ROUTE_GUILDS, + ROUTE_ADMINX_COMPANY_ROUTE_GUILDS, + ROUTE_SUPER_ADMIN_COMPANY_ROUTE_ACTIVE_SESSION, + ROUTE_ADMINX_COMPANY_ROUTE_ACTIVE_SESSION, + ROUTE_SUPER_ADMIN_COMPANY_ROUTE_DEVICES, + ROUTE_ADMINX_COMPANY_ROUTE_DEVICES, + ROUTE_ADMINX_ROUTE_PSP_COMPANIES, + ROUTE_SUPER_ADMIN_ROUTE_PSP_COMPANIES, + ROUTE_PSP_ROUTE_COMPANY_PSP_COMPANIES, +} from "../routes/routes"; +import { BackButton } from "../components/back-button/BackButton"; +import { PspOperations } from "../features/psp-company/components/psp-operations/PspOperations"; +import { PspManageGuilds } from "../features/psp-company/components/psp-manage-guilds/PspManageGuilds"; +import { PspActiveSession } from "../features/psp-company/components/psp-active-session/PspActiveSession"; +import { PspDevices } from "../features/psp-company/components/psp-devices/PspDevices"; +const PspCompanyManagement = () => { + const { pathname } = useLocation(); + + return ( + <> + + + {[ + ROUTE_PSP_ROUTE_COMPANY_PSP_COMPANIES, + ROUTE_SUPER_ADMIN_ROUTE_PSP_COMPANIES, + ROUTE_ADMINX_ROUTE_PSP_COMPANIES, + ].includes(pathname) ? ( + + + + ) : ( + + )} + + + + {[ + ROUTE_PSP_COMPANY_ROUTE_GUILDS, + ROUTE_SUPER_ADMIN_COMPANY_ROUTE_GUILDS, + ROUTE_ADMINX_COMPANY_ROUTE_GUILDS, + ].includes(pathname) && } + {[ + ROUTE_PSP_COMPANY_ROUTE_ACTIVE_SESSION, + ROUTE_SUPER_ADMIN_COMPANY_ROUTE_ACTIVE_SESSION, + ROUTE_ADMINX_COMPANY_ROUTE_ACTIVE_SESSION, + ].includes(pathname) && } + {[ + ROUTE_PSP_COMPANY_ROUTE_DEVICES, + ROUTE_SUPER_ADMIN_COMPANY_ROUTE_DEVICES, + ROUTE_ADMINX_COMPANY_ROUTE_DEVICES, + ].includes(pathname) && } + + + + + + ); +}; + +export default PspCompanyManagement; diff --git a/src/pages/ReturnPurchases.js b/src/pages/ReturnPurchases.js new file mode 100644 index 0000000..071a164 --- /dev/null +++ b/src/pages/ReturnPurchases.js @@ -0,0 +1,33 @@ +import { Box } from "@mui/material"; +import { Grid } from "../components/grid/Grid"; +import { SPACING } from "../data/spacing"; +import { BackButton } from "../components/back-button/BackButton"; + +import { ProvinceReturnPurchases } from "../features/province/components/province-return-purchases/ProvinceReturnPurchases"; +const ProvinceRequests = () => { + return ( + <> + + + + + + + + + + + + + ); +}; + +export default ProvinceRequests; diff --git a/src/pages/SendMassage.js b/src/pages/SendMassage.js new file mode 100644 index 0000000..f476695 --- /dev/null +++ b/src/pages/SendMassage.js @@ -0,0 +1,284 @@ +import { Box, Typography } from "@mui/material"; +import { Grid } from "../components/grid/Grid"; +import LinkItem from "../components/link-item/LinkItem"; +import { SPACING } from "../data/spacing"; +import { ProvinceSmsComponent } from "../features/province/components/province-sms/province-sms-component"; +import { FaComments, FaEnvelope, FaNewspaper, FaSms } from "react-icons/fa"; +import { NavLink, useLocation } from "react-router-dom"; + +import { + ROUTE_ADMINX_DASHBOARD_NEWS, + ROUTE_ADMINX_ROUTE_AGE_MESSAGE, + ROUTE_ADMINX_ROUTE_MANAGE_PROCESS_MOBILE_MESSAGE, + ROUTE_ADMINX_ROUTE_SMS, + ROUTE_ADMINX_ROUTE_SMS_MANAGE, + ROUTE_ADMINX_ROUTE_SMS_SEND, + ROUTE_ADMINX_SEND_ANNOUNCEMENT, + ROUTE_ADMINX_SEND_MESSAGE, + ROUTE_ADMINX_SEND_REPORT, + ROUTE_PROVINCE_DASHBOARD_NEWS, + ROUTE_PROVINCE_ROUTE_SMS, + ROUTE_PROVINCE_ROUTE_SMS_MANAGE, + ROUTE_PROVINCE_ROUTE_SMS_SEND, + ROUTE_PROVINCE_SEND_ANNOUNCEMENT, + ROUTE_PROVINCE_SEND_MESSAGE, + ROUTE_PROVINCE_SEND_REPORT, + ROUTE_SUPER_ADMIN_DASHBOARD_NEWS, + ROUTE_SUPER_ADMIN_ROUTE_AGE_MESSAGE, + ROUTE_SUPER_ADMIN_ROUTE_MANAGE_PROCESS_MOBILE_MESSAGE, + ROUTE_SUPER_ADMIN_ROUTE_SMS, + ROUTE_SUPER_ADMIN_ROUTE_SMS_MANAGE, + ROUTE_SUPER_ADMIN_ROUTE_SMS_SEND, + ROUTE_SUPER_ADMIN_SEND_ANNOUNCEMENT, + ROUTE_SUPER_ADMIN_SEND_MESSAGE, + ROUTE_SUPER_ADMIN_SEND_REPORT, +} from "../routes/routes"; +import { BackButton } from "../components/back-button/BackButton"; +import { ProvinceSmsManageComponent } from "../features/province/components/province-sms-manage/ProvinceSmsManage"; +import { ProvinceSmsAnnouncement } from "../features/province/components/province-sms-announcement/ProvinceSmsAnnouncement"; +import { getRoleFromUrl } from "../utils/getRoleFromUrl"; +import { ProvinceSendReport } from "../features/province/components/province-send-report/ProvinceSendReport"; +import { ProvincePolicyMobileMessage } from "../features/province/components/province-policy-mobile-message/ProvincePolicyMobileMessage"; +import { ProvinceAgeMessage } from "../features/province/components/province-age-message/ProvinceAgeMessage"; +import { ProvinceDashboardNews } from "../features/province/components/province-dashboard-news/ProvinceDashboardNews"; +const SendMassage = () => { + const { pathname } = useLocation(); + + return ( + <> + + + {pathname === ROUTE_PROVINCE_ROUTE_SMS || + pathname === ROUTE_SUPER_ADMIN_ROUTE_SMS || + pathname === ROUTE_ADMINX_ROUTE_SMS ? ( + + + + پیامک ها + + + + + } + title="ارسال پیامک" + description="ارسال پیامک برای نقش ها و کاربران مختلف" + /> + + + } + title="مدیریت پیامک اطلاع رسانی" + description="تعیین گزینه های اطلاع رسانی برای نقش ها و مراحل مختلف" + /> + + + } + title="مدیریت پیام های سیستمی" + description="تعیین گزینه های اطلاع رسانی برای نقش ها و مراحل مختلف" + /> + + + } + title="اعلانات" + description="تعیین گزینه های اطلاع رسانی برای نقش ها و مراحل مختلف" + /> + + {getRoleFromUrl() === "SuperAdmin" && ( + + } + title="گزارش دهی" + description="تعیین گزینه های اطلاع رسانی برای نقش ها و مراحل مختلف" + /> + + )} + {(getRoleFromUrl() === "SuperAdmin" || + getRoleFromUrl() === "AdminX") && ( + + } + title="پیغام متحرک" + /> + + )} + + {(getRoleFromUrl() === "SuperAdmin" || + getRoleFromUrl() === "AdminX") && ( + + } + title="پیغام بازه سنی" + /> + + )} + + {(getRoleFromUrl() === "SuperAdmin" || + getRoleFromUrl() === "AdminX") && ( + + } + title="اطلاعیه داشبورد" + /> + + )} + + + ) : ( + + )} + {(pathname === ROUTE_PROVINCE_ROUTE_SMS_SEND || + pathname === ROUTE_SUPER_ADMIN_ROUTE_SMS_SEND || + pathname === ROUTE_ADMINX_ROUTE_SMS_SEND) && ( + + )} + {(pathname === ROUTE_PROVINCE_ROUTE_SMS_MANAGE || + pathname === ROUTE_SUPER_ADMIN_ROUTE_SMS_MANAGE || + pathname === ROUTE_ADMINX_ROUTE_SMS_MANAGE) && ( + + )} + {(pathname === ROUTE_PROVINCE_SEND_ANNOUNCEMENT || + pathname === ROUTE_SUPER_ADMIN_SEND_ANNOUNCEMENT || + pathname === ROUTE_ADMINX_SEND_ANNOUNCEMENT) && ( + + )} + {(pathname === ROUTE_PROVINCE_SEND_REPORT || + pathname === ROUTE_SUPER_ADMIN_SEND_REPORT || + pathname === ROUTE_ADMINX_SEND_REPORT) && } + + {(pathname === + ROUTE_SUPER_ADMIN_ROUTE_MANAGE_PROCESS_MOBILE_MESSAGE || + pathname === ROUTE_ADMINX_ROUTE_MANAGE_PROCESS_MOBILE_MESSAGE) && ( + + )} + + {(pathname === ROUTE_SUPER_ADMIN_ROUTE_AGE_MESSAGE || + pathname === ROUTE_ADMINX_ROUTE_AGE_MESSAGE) && ( + + )} + + {(pathname === ROUTE_SUPER_ADMIN_DASHBOARD_NEWS || + pathname === ROUTE_ADMINX_DASHBOARD_NEWS || + pathname === ROUTE_PROVINCE_DASHBOARD_NEWS) && ( + + )} + + + + ); +}; +export default SendMassage; diff --git a/src/pages/SenfInventoryPage.js b/src/pages/SenfInventoryPage.js new file mode 100644 index 0000000..e946b90 --- /dev/null +++ b/src/pages/SenfInventoryPage.js @@ -0,0 +1,55 @@ +import { Box } from "@mui/material"; +import { Grid } from "../components/grid/Grid"; +import { SPACING } from "../data/spacing"; +import { useLocation } from "react-router-dom"; +import { BackButton } from "../components/back-button/BackButton"; +import { SenfInventoryOperation } from "../features/senf/components/SenfInventoryOperation"; +import { + ROUTE_SENF_INVENTORY, + ROUTE_SENF_INVENTORY_ENTER, + ROUTE_SENF_INVENTORY_SEGMENTATION, + ROUTE_SENF_INVENTORY_STOCK, +} from "../routes/routes"; +import { SenfStock } from "../features/senf/components/SenfStock"; +import { SenfSegmentaion } from "../features/senf/components/SenfSegmentaion"; +import { SenfEnterToWarehouse } from "../features/senf/components/SenfEnterToWarehouse"; + +const SenfInventoryPage = () => { + const { pathname } = useLocation(); + + return ( + + + + {pathname === ROUTE_SENF_INVENTORY && ( + + + + )} + {pathname.includes(ROUTE_SENF_INVENTORY_STOCK) && } + {pathname.includes(ROUTE_SENF_INVENTORY_SEGMENTATION) && ( + + )} + {pathname.includes(ROUTE_SENF_INVENTORY_ENTER) && ( + + )} + + + ); +}; + +export default SenfInventoryPage; diff --git a/src/pages/SlaughterAgentShare.js b/src/pages/SlaughterAgentShare.js new file mode 100644 index 0000000..81841a5 --- /dev/null +++ b/src/pages/SlaughterAgentShare.js @@ -0,0 +1,44 @@ +import { Box } from "@mui/material"; +import React from "react"; +import { Grid } from "../components/grid/Grid"; +import { useLocation, useParams } from "react-router-dom"; +import { ProvinceBuyersAllocations } from "../features/province/components/province-buyers-allocations/ProvinceBuyersAllocations"; +import { ProvinceBuyerStewardAllocation } from "../features/province/components/province-buyer-steward-allocation/ProvinceBuyerStewardAllocation"; +import { SPACING } from "../data/spacing"; +import { BackButton } from "../components/back-button/BackButton"; +import { ROUTE_PROVINCE_ROUTE_STEWARD_SHARE } from "../routes/routes"; +import { ProvinceGuildAllocation } from "../features/province/components/province-guild-allocation.js/ProvinceGuildAllocation"; + +const SlaughterAgentShare = () => { + const params = useParams(); + const buyerId = params?.id; + const { pathname } = useLocation(); + + return ( + + + + + {pathname === ROUTE_PROVINCE_ROUTE_STEWARD_SHARE ? ( + + ) : ( + <> + {!buyerId && } + {buyerId && } + + )} + + + ); +}; + +export default SlaughterAgentShare; diff --git a/src/pages/SlaughterComplaints.js b/src/pages/SlaughterComplaints.js new file mode 100644 index 0000000..d253e30 --- /dev/null +++ b/src/pages/SlaughterComplaints.js @@ -0,0 +1,427 @@ +import { + Accordion, + AccordionDetails, + AccordionSummary, + Box, + Button, + Chip, + Divider, + Typography, +} from "@mui/material"; +import ExpandMoreIcon from "@mui/icons-material/ExpandMore"; +import { useEffect, useState } from "react"; +import { useDispatch, useSelector } from "react-redux"; +import { Grid } from "../components/grid/Grid"; +import { SimpleTable } from "../components/simple-table/SimpleTable"; +import { Timer } from "../components/timer/Timer"; +import { SPACING } from "../data/spacing"; +import { SlaughterHouseNewComplaint } from "../features/slaughter-house/components/slaughter-house-new-conmplaint/SlaughterHouseNewComplaint"; +import { slaughterGetComplaints } from "../features/slaughter-house/services/slaughter-get-complaints"; +import { slaughterGetRegisteredComplaints } from "../features/slaughter-house/services/slaughter-get-registered-complaints"; +import { + DRAWER, + LOADING_END, + LOADING_START, +} from "../lib/redux/slices/appSlice"; +import { getRemainedSeconds } from "../utils/getRemainedSeconds"; +import { getRoleFromUrl } from "../utils/getRoleFromUrl"; +import { AdvancedTable } from "../components/advanced-table/AdvancedTable"; +import { formatJustDate } from "../utils/formatTime"; + +const SlaughterComplaints = () => { + const [dataTable, setDataTable] = useState(); + const [expanded, setExpanded] = useState(false); + const handleChange = () => { + setExpanded(!expanded); + }; + const dispatch = useDispatch(); + const { slaughterHouseComplaints } = useSelector( + (state) => state.slaughterSlice + ); + + const role = getRoleFromUrl(); + + const { slaughterHouseRegisteredComplaints } = useSelector( + (state) => state.slaughterSlice + ); + + useEffect(() => { + dispatch(LOADING_START()); + dispatch(slaughterGetComplaints()); + dispatch(slaughterGetRegisteredComplaints()).then((r) => { + dispatch(LOADING_END()); + }); + }, []); + + useEffect(() => { + const d = slaughterHouseRegisteredComplaints?.map((item, i) => { + return [ + item.title, + item.description ? item.description : "بدون توضیحات", + formatJustDate(item?.createDate), + item.state === "pending" + ? "در حال بررسی" + : item.state === "accepted" + ? "تایید شده" + : "رد شده", + item.percent, + item.image?.length + ? item.image?.map((item, i) => { + return [ + + + دانلود + + , + ]; + }) + : "بدون پیوست", + ]; + }); + setDataTable(d); + }, [slaughterHouseRegisteredComplaints]); + + const [filteredAvalableCompaints, setFilteredAvalableCompaints] = useState( + [] + ); + + const [filteredArchievedCompaints, setFilteredArchievedCompaints] = useState( + [] + ); + useEffect(() => { + setFilteredAvalableCompaints( + slaughterHouseComplaints?.filter( + (item) => getRemainedSeconds(item.protestTime) > 0 + ) + ); + + setFilteredArchievedCompaints( + slaughterHouseComplaints?.filter( + (item) => getRemainedSeconds(item.protestTime) < 1 + ) + ); + }, [slaughterHouseComplaints]); + + return ( + <> + + + + + + } + aria-controls="panel1a-content" + id="panel1a-header" + > + شکایات ثبت شده + + + + + + + + + {filteredAvalableCompaints?.length > 0 && ( + + + + )} + {filteredAvalableCompaints?.map((item, i) => { + let remainedSeconds = getRemainedSeconds(item.protestTime); + const requestedSellTypeCash = item.cellType?.cash + ? "نقدی" + : null; + const requestedSellTypeCredit = item?.cellType?.credit + ? "زمان دار" + : null; + const requestedSellType = [ + requestedSellTypeCash, + requestedSellTypeCredit, + ] + .filter((item) => item) + .join(" یا "); + return ( + <> + + + + بدون بار + , + + بدون بار + , + item.killHouseRequestQuantity, + item.killHouseNetWeight, + Math.round( + (item.killHouseNetWeight / + item.killHouseRequestQuantity) * + 100 + ) / 100, + , + , + item.averageWeight, + ], + ]} + /> + + ); + })} + + + + + {filteredArchievedCompaints?.length > 0 && ( + + + + )} + {filteredArchievedCompaints?.map((item, i) => { + const requestedSellTypeCash = item.cellType?.cash + ? "نقدی" + : null; + const requestedSellTypeCredit = item?.cellType?.credit + ? "زمان دار" + : null; + const requestedSellType = [ + requestedSellTypeCash, + requestedSellTypeCredit, + ] + .filter((item) => item) + .join(" یا "); + return ( + <> + + + + بدون بار + , + + بدون بار + , + item.killHouseRequestQuantity, + item.killHouseNetWeight, + Math.round( + (item.killHouseNetWeight / + item.killHouseRequestQuantity) * + 100 + ) / 100, + ], + ]} + /> + + ); + })} + + + + + + ); +}; +export default SlaughterComplaints; diff --git a/src/pages/SlaughterFreeBuy.js b/src/pages/SlaughterFreeBuy.js new file mode 100644 index 0000000..f6d064e --- /dev/null +++ b/src/pages/SlaughterFreeBuy.js @@ -0,0 +1,38 @@ +import { Box } from "@mui/material"; +import React from "react"; +import { Grid } from "../components/grid/Grid"; +import { useLocation } from "react-router-dom"; +import { BackButton } from "../components/back-button/BackButton"; +import { + ROUTE_SLAUGHTER_HOUSE_VET_FREE_BUY_ROUTE, + ROUTE_SLAUGHTER_OUT_PROVINCE_BUY, +} from "../routes/routes"; +import { SlaughterFreeBuyBars } from "../features/slaughter-house/components/slaughter-free-buy-bars/SlaughterFreeBuyBars"; + +const SlaughterFreeBuy = () => { + const { pathname } = useLocation(); + + return ( + <> + + + + {(pathname === ROUTE_SLAUGHTER_OUT_PROVINCE_BUY || + pathname === ROUTE_SLAUGHTER_HOUSE_VET_FREE_BUY_ROUTE) && ( + + )} + + + + ); +}; + +export default SlaughterFreeBuy; diff --git a/src/pages/SlaughterHouseDispenserDashboard.js b/src/pages/SlaughterHouseDispenserDashboard.js new file mode 100644 index 0000000..892d969 --- /dev/null +++ b/src/pages/SlaughterHouseDispenserDashboard.js @@ -0,0 +1,214 @@ +import { Box, Typography } from "@mui/material"; +import React from "react"; +import { Grid } from "../components/grid/Grid"; +import { useLocation, useParams } from "react-router-dom"; +import { + ROUTE_ADMINX_DELEGATES_MANAGEMENT, + ROUTE_ADMINX_DISPENSERS, + ROUTE_ADMINX_DISPENSERS_INVENTORY, + ROUTE_ADMINX_DISPENSERS_KILLHOUSES, + ROUTE_ADMINX_DISPENSERS_MANAGEMENT, + ROUTE_ADMINX_DISPENSERS_MANAGEMENT_V2, + ROUTE_ADMINX_DISPENSERS_SELL_CARCASS, + ROUTE_ADMINX_DISPENSERS_STEWARDS, + ROUTE_ADMINX_DISPENSER_DETAILS, + ROUTE_ADMINX_SALE_DESTRIBUTION_DETAILS, + ROUTE_CITY_DISPENSERS, + ROUTE_CITY_DISPENSERS_INVENTORY, + ROUTE_CITY_JIHAD_DISPENSERS, + ROUTE_CITY_JIHAD_DISPENSERS_INVENTORY, + ROUTE_CITY_JIHAD_DISPENSERS_KILLHOUSES, + ROUTE_CITY_JIHAD_DISPENSERS_MANAGEMENT, + ROUTE_CITY_JIHAD_DISPENSERS_SELL_CARCASS, + ROUTE_CITY_JIHAD_DISPENSERS_STEWARDS, + ROUTE_CITY_JIHAD_DISPENSER_DETAILS_VIEW, + ROUTE_CITY_JIHAD_SALE_DESTRIBUTION_DETAILS, + ROUTE_CITY_REQUEST_DISTRIBUTION, + // ROUTE_ADMINX_SALE_DESTRIBUTION_DETAILS, + ROUTE_PROVINCE_DISPENSERS, + ROUTE_PROVINCE_DISPENSERS_INVENTORY, + ROUTE_PROVINCE_DISPENSERS_KILLHOUSES, + ROUTE_PROVINCE_DISPENSERS_MANAGEMENT, + ROUTE_PROVINCE_DISPENSERS_SELL_CARCASS, + ROUTE_PROVINCE_DISPENSERS_STEWARDS, + ROUTE_PROVINCE_DISPENSER_DETAILS, + ROUTE_PROVINCE_SALE_DESTRIBUTION_DETAILS, + ROUTE_PROVINCE_SUPERVISOR_DISPENSERS, + ROUTE_PROVINCE_SUPERVISOR_DISPENSERS_INVENTORY, + ROUTE_PROVINCE_SUPERVISOR_DISPENSERS_KILLHOUSES, + ROUTE_PROVINCE_SUPERVISOR_DISPENSERS_MANAGEMENT, + ROUTE_PROVINCE_SUPERVISOR_DISPENSERS_SELL_CARCASS, + ROUTE_PROVINCE_SUPERVISOR_DISPENSERS_STEWARDS, + ROUTE_PROVINCE_SUPERVISOR_DISPENSER_DETAILS_VIEW, + ROUTE_PROVINCE_SUPERVISOR_REQUEST_DISTRIBUTION, + ROUTE_PROVINCE_SUPERVISOR_SALE_DESTRIBUTION_DETAILS, + // ROUTE_PROVINCE_SALE_DESTRIBUTION_DETAILS, + ROUTE_SLAUGHTER_DISPENSERS, + ROUTE_SLAUGHTER_DISPENSERS_KILLHOUSES, + ROUTE_SLAUGHTER_DISPENSERS_MANAGEMENT, + ROUTE_SLAUGHTER_DISPENSERS_STEWARDS, + ROUTE_SLAUGHTER_DISPENSER_DETAILS, + ROUTE_SUPER_ADMIN_DESTRIBUTION_DETAILS, + // ROUTE_SUPER_ADMIN_DESTRIBUTION_DETAILS, + ROUTE_SUPER_ADMIN_DISPENSERS, + ROUTE_SUPER_ADMIN_DISPENSERS_INVENTORY, + ROUTE_SUPER_ADMIN_DISPENSERS_KILLHOUSES, + ROUTE_SUPER_ADMIN_DISPENSERS_MANAGEMENT, + ROUTE_SUPER_ADMIN_DISPENSERS_SELL_CARCASS, + ROUTE_SUPER_ADMIN_DISPENSERS_STEWARDS, + ROUTE_SUPER_ADMIN_DISPENSER_DETAILS, +} from "../routes/routes"; +import { SPACING } from "../data/spacing"; +import { SlaughterHouseDispensersOperations } from "../features/slaughter-house/components/slaughter-house-dispensers-operations/SlaughterHouseDispensersOperations"; +import { BackButton } from "../components/back-button/BackButton"; +import { SlaughterHouseDispensers } from "../features/slaughter-house/components/slaughter-house-dispensers/SlaughterHouseDispensers"; +import { SlaughterHouseDispenserDetails } from "../features/slaughter-house/components/slaughter-house-dispenser-details/SlaughterHouseDispenserDetails"; +import { ProvinceDispenserStewards } from "../features/province/components/province-dispenser-stewards/ProvinceDispenserStewards"; +import { ProvinceDispenserKillhouses } from "../features/province/components/province-dispenser-killhouses/ProvinceDispenserKillhouses"; +import { ProvinceDispensersSellCarcass } from "../features/province/components/province-dispensers-sell-carcass/ProvinceDispensersSellCarcass"; +import { ProvinceDispensersKillhouses } from "../features/province/components/province-dispensers-killhouses/ProvinceDispensersKillhouses"; +import { ProvinceDispensersViewKillHouse } from "../features/province/components/province-dispensers-view-killhouse/ProvinceDispensersViewKillHouse"; +import { ProvinceDispencerSaleDistribution } from "../features/province/components/province-dispencer-sale-distribution/ProvinceDispencerSaleDistribution"; +import { SlaughterHouseDispensersV2 } from "../features/slaughter-house/components/slaughter-house-dispensers-v2/SlaughterHouseDispensers"; +import { SlaughterHouseDelegates } from "../features/slaughter-house/components/slaughter-house-delegates/SlaughterHouseDelegates"; +// import { ProvinceDispencerSaleDistribution } from "../features/province/components/province-dispencer-sale-distribution/ProvinceDispencerSaleDistribution"; + +const DashboardTitle = () => ( + + + داشبورد مدیریت توزیع + + +); + +const renderComponentBasedOnPath = (pathname) => { + const managementRoutes = [ + ROUTE_SLAUGHTER_DISPENSERS_MANAGEMENT, + ROUTE_ADMINX_DISPENSERS_MANAGEMENT, + ROUTE_PROVINCE_DISPENSERS_MANAGEMENT, + ROUTE_SUPER_ADMIN_DISPENSERS_MANAGEMENT, + ROUTE_CITY_JIHAD_DISPENSERS_MANAGEMENT, + ROUTE_PROVINCE_SUPERVISOR_DISPENSERS_MANAGEMENT, + ]; + + const detailsRoutes = [ + ROUTE_ADMINX_DISPENSER_DETAILS, + ROUTE_SLAUGHTER_DISPENSER_DETAILS, + ROUTE_PROVINCE_DISPENSER_DETAILS, + ROUTE_SUPER_ADMIN_DISPENSER_DETAILS, + ROUTE_CITY_JIHAD_DISPENSER_DETAILS_VIEW, + ROUTE_PROVINCE_SUPERVISOR_DISPENSER_DETAILS_VIEW, + ]; + + const stewardsRoutes = [ + ROUTE_SLAUGHTER_DISPENSERS_STEWARDS, + ROUTE_ADMINX_DISPENSERS_STEWARDS, + ROUTE_SUPER_ADMIN_DISPENSERS_STEWARDS, + ROUTE_PROVINCE_DISPENSERS_STEWARDS, + ROUTE_CITY_JIHAD_DISPENSERS_STEWARDS, + ROUTE_PROVINCE_SUPERVISOR_DISPENSERS_STEWARDS, + ]; + + const killhousesRoutes = [ + ROUTE_SLAUGHTER_DISPENSERS_KILLHOUSES, + ROUTE_ADMINX_DISPENSERS_KILLHOUSES, + ROUTE_SUPER_ADMIN_DISPENSERS_KILLHOUSES, + ROUTE_PROVINCE_DISPENSERS_KILLHOUSES, + ROUTE_CITY_JIHAD_DISPENSERS_KILLHOUSES, + ROUTE_PROVINCE_SUPERVISOR_DISPENSERS_KILLHOUSES, + ]; + + const sellCarcassRoutes = [ + ROUTE_PROVINCE_DISPENSERS_SELL_CARCASS, + ROUTE_SUPER_ADMIN_DISPENSERS_SELL_CARCASS, + ROUTE_ADMINX_DISPENSERS_SELL_CARCASS, + ROUTE_CITY_JIHAD_DISPENSERS_SELL_CARCASS, + ROUTE_PROVINCE_SUPERVISOR_DISPENSERS_SELL_CARCASS, + ]; + + const inventoryRoutes = [ + ROUTE_ADMINX_DISPENSERS_INVENTORY, + ROUTE_SUPER_ADMIN_DISPENSERS_INVENTORY, + ROUTE_PROVINCE_DISPENSERS_INVENTORY, + ROUTE_CITY_DISPENSERS_INVENTORY, + ROUTE_CITY_JIHAD_DISPENSERS_INVENTORY, + ROUTE_PROVINCE_SUPERVISOR_DISPENSERS_INVENTORY, + ]; + + const distribution = [ + ROUTE_ADMINX_SALE_DESTRIBUTION_DETAILS, + ROUTE_SUPER_ADMIN_DESTRIBUTION_DETAILS, + ROUTE_PROVINCE_SALE_DESTRIBUTION_DETAILS, + ROUTE_CITY_REQUEST_DISTRIBUTION, + ROUTE_CITY_JIHAD_SALE_DESTRIBUTION_DETAILS, + ROUTE_PROVINCE_SUPERVISOR_SALE_DESTRIBUTION_DETAILS, + ROUTE_PROVINCE_SUPERVISOR_REQUEST_DISTRIBUTION, + ]; + + const managementRoutesV2 = [ROUTE_ADMINX_DISPENSERS_MANAGEMENT_V2]; + + const managementRoutesDelegates = [ROUTE_ADMINX_DELEGATES_MANAGEMENT]; + + if (managementRoutes.includes(pathname)) return ; + if (managementRoutesV2.includes(pathname)) + return ; + if (managementRoutesDelegates.includes(pathname)) + return ; + if (distribution.includes(pathname)) + return ; + if (detailsRoutes.some((route) => pathname.includes(route))) + return ; + if (stewardsRoutes.some((route) => pathname.includes(route))) + return ; + if (killhousesRoutes.some((route) => pathname.includes(route))) + return ; + if (sellCarcassRoutes.some((route) => pathname.includes(route))) + return ; + if (inventoryRoutes.some((route) => pathname.includes(route))) + return ; + + return null; +}; + +const SlaughterHouseDispenserDashboard = () => { + const { pathname } = useLocation(); + const { key, name } = useParams(); + + const isDashboardRoute = [ + ROUTE_SLAUGHTER_DISPENSERS, + ROUTE_ADMINX_DISPENSERS, + ROUTE_SUPER_ADMIN_DISPENSERS, + ROUTE_PROVINCE_DISPENSERS, + ROUTE_CITY_DISPENSERS, + ROUTE_CITY_JIHAD_DISPENSERS, + ROUTE_PROVINCE_SUPERVISOR_DISPENSERS, + ].includes(pathname); + + return ( + + + {isDashboardRoute ? ( + <> + + + + ) : ( + + )} + + {!key && renderComponentBasedOnPath(pathname)} + {key && } + + + ); +}; + +export default React.memo(SlaughterHouseDispenserDashboard); diff --git a/src/pages/SlaughterHouseVet.js b/src/pages/SlaughterHouseVet.js new file mode 100644 index 0000000..e88ff8f --- /dev/null +++ b/src/pages/SlaughterHouseVet.js @@ -0,0 +1,67 @@ +import { Box, Typography } from "@mui/material"; +import { Grid } from "../components/grid/Grid"; +import { SPACING } from "../data/spacing"; +import { + // ROUTE_SLAUGHTER_HOUSE_VET_ARCHIVED_REQUESTS, + ROUTE_SLAUGHTER_HOUSE_VET_COMPLAINTS, + ROUTE_SLAUGHTER_HOUSE_VET_ENTER_BAR_INFO, + ROUTE_SLAUGHTER_HOUSE_VET_NEW_REQUESTS, + ROUTE_SLAUGHTER_HOUSE_VET_REQUESTS, +} from "../routes/routes"; +import { useLocation } from "react-router-dom"; +import { SlaughterHouseVetOperations } from "../features/slaughter-house-vet/components/slaughter-house-vet-operations/SlaughterHouseVetOperations"; +import { SlaughterHouseVetNewRequests } from "../features/slaughter-house-vet/components/slaughter-house-vet-new-requests/SlaughterHouseVetNewRequests"; +// import { AvicultureArchivedRequests } from "../features/aviculture/components/aviculture-archived-requests/AvicultureArchivedRequests"; +import { BackButton } from "../components/back-button/BackButton"; +import { SlaughterHouseVetComplaints } from "../pages/SlaughterHouseVetComplaints"; +import { SalughterEnterBarInfo } from "../features/slaughter-house/components/slaughter-enter-bar-info/SlaghterEnterBarInfo"; +const SlaughterHouseVet = () => { + const { pathname } = useLocation(); + + return ( + <> + + + {pathname === ROUTE_SLAUGHTER_HOUSE_VET_REQUESTS ? ( + + + داشبورد (دامپزشک کشتارگاه) + + + + ) : ( + + )} + + + {pathname === ROUTE_SLAUGHTER_HOUSE_VET_NEW_REQUESTS && ( + + )} + + {pathname === ROUTE_SLAUGHTER_HOUSE_VET_ENTER_BAR_INFO && ( + + )} + + {/* {pathname === ROUTE_SLAUGHTER_HOUSE_VET_ARCHIVED_REQUESTS && ( + + )} */} + + {pathname === ROUTE_SLAUGHTER_HOUSE_VET_COMPLAINTS && ( + + )} + + + + + + ); +}; +export default SlaughterHouseVet; diff --git a/src/pages/SlaughterHouseVetComplaints.js b/src/pages/SlaughterHouseVetComplaints.js new file mode 100644 index 0000000..a7664b2 --- /dev/null +++ b/src/pages/SlaughterHouseVetComplaints.js @@ -0,0 +1,429 @@ +import { + Accordion, + AccordionDetails, + AccordionSummary, + Box, + Button, + Chip, + Divider, + Typography, +} from "@mui/material"; +import ExpandMoreIcon from "@mui/icons-material/ExpandMore"; +import { useEffect, useState } from "react"; +import { useDispatch, useSelector } from "react-redux"; +import { Grid } from "../components/grid/Grid"; +import { SimpleTable } from "../components/simple-table/SimpleTable"; +import { Timer } from "../components/timer/Timer"; +import { SPACING } from "../data/spacing"; +import { SlaughterHouseNewComplaint } from "../features/slaughter-house/components/slaughter-house-new-conmplaint/SlaughterHouseNewComplaint"; +import { slaughterGetComplaints } from "../features/slaughter-house/services/slaughter-get-complaints"; +import { slaughterGetRegisteredComplaints } from "../features/slaughter-house/services/slaughter-get-registered-complaints"; +import { + DRAWER, + LOADING_END, + LOADING_START, +} from "../lib/redux/slices/appSlice"; +import { getRemainedSeconds } from "../utils/getRemainedSeconds"; +import { getRoleFromUrl } from "../utils/getRoleFromUrl"; +import { AdvancedTable } from "../components/advanced-table/AdvancedTable"; +import { format } from "date-fns-jalali"; +import { formatJustDate } from "../utils/formatTime"; + +export const SlaughterHouseVetComplaints = () => { + const [dataTable, setDataTable] = useState(); + const [expanded, setExpanded] = useState(false); + const handleChange = () => { + setExpanded(!expanded); + }; + const dispatch = useDispatch(); + const { slaughterHouseComplaints } = useSelector( + (state) => state.slaughterSlice + ); + + const role = getRoleFromUrl(); + + const { slaughterHouseRegisteredComplaints } = useSelector( + (state) => state.slaughterSlice + ); + + useEffect(() => { + dispatch(LOADING_START()); + dispatch(slaughterGetComplaints()); + dispatch(slaughterGetRegisteredComplaints()).then((r) => { + dispatch(LOADING_END()); + }); + }, []); + + useEffect(() => { + const d = slaughterHouseRegisteredComplaints?.map((item, i) => { + return [ + item.title, + item.description ? item.description : "بدون توضیحات", + formatJustDate(item?.createDate), + item.state === "pending" + ? "در حال بررسی" + : item.state === "accepted" + ? "تایید شده" + : "رد شده", + item.percent, + item.image?.length + ? item.image?.map((item, i) => { + return [ + + + دانلود + + , + ]; + }) + : "بدون پیوست", + ]; + }); + setDataTable(d); + }, [slaughterHouseRegisteredComplaints]); + + const [filteredAvalableCompaints, setFilteredAvalableCompaints] = useState( + [] + ); + + const [filteredArchievedCompaints, setFilteredArchievedCompaints] = useState( + [] + ); + useEffect(() => { + setFilteredAvalableCompaints( + slaughterHouseComplaints?.filter( + (item) => getRemainedSeconds(item.protestTime) > 0 + ) + ); + + setFilteredArchievedCompaints( + slaughterHouseComplaints?.filter( + (item) => getRemainedSeconds(item.protestTime) < 1 + ) + ); + }, [slaughterHouseComplaints]); + + return ( + <> + + + + + + } + aria-controls="panel1a-content" + id="panel1a-header" + > + شکایات ثبت شده + + + + + + + + + {filteredAvalableCompaints?.length > 0 && ( + + + + )} + {filteredAvalableCompaints?.map((item, i) => { + let remainedSeconds = getRemainedSeconds(item.protestTime); + const requestedSellTypeCash = item.cellType?.cash + ? "نقدی" + : null; + const requestedSellTypeCredit = item?.cellType?.credit + ? "زمان دار" + : null; + const requestedSellType = [ + requestedSellTypeCash, + requestedSellTypeCredit, + ] + .filter((item) => item) + .join(" یا "); + return ( + <> + + + + بدون بار + , + + بدون بار + , + item.killHouseRequestQuantity, + item.killHouseNetWeight, + Math.round( + (item.killHouseNetWeight / + item.killHouseRequestQuantity) * + 100 + ) / 100, + , + , + item.averageWeight, + ], + ]} + /> + + ); + })} + + + + + {filteredArchievedCompaints?.length > 0 && ( + + + + )} + {filteredArchievedCompaints?.map((item, i) => { + // let remainedSeconds = getRemainedSeconds(item.protestTime); + + const requestedSellTypeCash = item.cellType?.cash + ? "نقدی" + : null; + const requestedSellTypeCredit = item?.cellType?.credit + ? "زمان دار" + : null; + const requestedSellType = [ + requestedSellTypeCash, + requestedSellTypeCredit, + ] + .filter((item) => item) + .join(" یا "); + return ( + <> + + + + بدون بار + , + + بدون بار + , + item.killHouseRequestQuantity, + item.killHouseNetWeight, + Math.round( + (item.killHouseNetWeight / + item.killHouseRequestQuantity) * + 100 + ) / 100, + ], + ]} + /> + + ); + })} + + + + + + ); +}; diff --git a/src/pages/SlaughterInventoryPage.js b/src/pages/SlaughterInventoryPage.js new file mode 100644 index 0000000..66b436a --- /dev/null +++ b/src/pages/SlaughterInventoryPage.js @@ -0,0 +1,289 @@ +import { Box } from "@mui/material"; +import { Grid } from "../components/grid/Grid"; +import { useLocation } from "react-router-dom"; +import { + ROUTE_STEWARD_INVENTORY, + ROUTE_SLAUGHTER_INVENTORY, + ROUTE_SLAUGHTER_INVENTORY_SELL_CARCASS_IN_PROVINCE, + ROUTE_SLAUGHTER_INVENTORY_SELL_CARCASS_OUT_PROVINCE, + ROUTE_SLAUGHTER_INVENTORY_STOCK, + ROUTE_SLAUGHTER_DAILY_LIST, + ROUTE_SLAUGHTER_SEGMENTATION, + ROUTE_SLAUGHTER_ORDERS, + ROUTE_SLAUGHTER_OUT_PROVINCE_BUY, +} from "../routes/routes"; +import { BackButton } from "../components/back-button/BackButton"; +import { SlaughterStockWrapper } from "../features/slaughter-house/components/slaughter-stock-wrapper/SlaughterStockWrapper"; +import { SlaughterSellCarcass } from "../features/slaughter-house/components/slaughter-sell-carcass/SlaughterSellCarcass"; +import { SlaughterSellCarcassOutProvincePage } from "../features/slaughter-house/components/slaughter-sell-carcass-out-province/SlaughterSellCarcassOutProvince"; +import { useDispatch, useSelector } from "react-redux"; +import { useEffect } from "react"; +import { SlaughterDailyList } from "../features/slaughter-house/components/slaughter-daily-list/SlaughterDailyList"; +import { SlaughterSegmentation } from "../features/slaughter-house/components/slaughter-segmentation/SlaughterSegmentation"; +import { SlaughterOrders } from "../features/slaughter-house/components/slaughter-orders/SlaughterOrders"; +import { SlaughterInventorySummary } from "../features/slaughter-house/components/slaughter-inventory-summary/SlaughterInventorySummary"; +import { fetchSlaughterBroadcastAndProducts } from "../features/slaughter-house/services/handle-fetch-slaughter-products"; +import { getKillhouseApprovedPriceState } from "../features/province/services/get-approved-price-state"; +import { SPACING } from "../data/spacing"; +import { NavLink } from "../components/nav-link/NavLink"; +import LinkItem from "../components/link-item/LinkItem"; +import WarehouseIcon from "@mui/icons-material/Warehouse"; +import StoreIcon from "@mui/icons-material/Store"; +import PublicIcon from "@mui/icons-material/Public"; +import ContentCutIcon from "@mui/icons-material/ContentCut"; +import { SlaughterFreeBuyBars } from "../features/slaughter-house/components/slaughter-free-buy-bars/SlaughterFreeBuyBars"; +import { checkPathStartsWith } from "../utils/checkPathStartsWith"; +// import { Grading } from "@mui/icons-material"; + +const SlaughterInventoryPage = () => { + const { pathname } = useLocation(); + const dispatch = useDispatch(); + const { distributionInfo, priceInfo } = useSelector( + (state) => state.slaughterSlice + ); + const selectedSubUser = useSelector( + (state) => state.userSlice.selectedSubUser + ); + + useEffect(() => { + if ( + [ + ROUTE_SLAUGHTER_INVENTORY, + ROUTE_SLAUGHTER_INVENTORY_SELL_CARCASS_OUT_PROVINCE, + ].includes(pathname) + ) { + dispatch( + fetchSlaughterBroadcastAndProducts({ + role_key: checkPathStartsWith("slaughter") + ? selectedSubUser?.key || "" + : "", + }) + ); + dispatch( + getKillhouseApprovedPriceState({ + role_key: checkPathStartsWith("slaughter") + ? selectedSubUser?.key || "" + : "", + }) + ); + } + }, [pathname, selectedSubUser?.key]); + + return ( + <> + + {pathname === ROUTE_SLAUGHTER_INVENTORY && ( + + + + + )} + + {/* )} */} + {(pathname === ROUTE_SLAUGHTER_INVENTORY || + pathname === ROUTE_STEWARD_INVENTORY) && ( + + {/* + } + title="خلاصه انبار" + /> + */} + + + } + title="ورود به انبار" + /> + + + + } + title="فروش داخل استان" + /> + + + + } + title="فروش به خارج استان" + /> + + + } + title="خرید خارج از استان" + /> + + + + } + title="قطعه بندی" + /> + + + {/* + } + title="لیست روزانه" + /> + */} + + {/* + } + title="سفارشات" + /> + */} + + )} + + {/* {pathname.includes(ROUTE_SLAUGHTER_INVENTORY_SUMMARY) && ( */} + + {pathname.includes(ROUTE_SLAUGHTER_INVENTORY_STOCK) && ( + + + + + + + )} + + {pathname.includes( + ROUTE_SLAUGHTER_INVENTORY_SELL_CARCASS_OUT_PROVINCE + ) && ( + + + + + + + )} + + {pathname.includes(ROUTE_SLAUGHTER_DAILY_LIST) && ( + + + + + + + )} + + {pathname.includes( + ROUTE_SLAUGHTER_INVENTORY_SELL_CARCASS_IN_PROVINCE + ) && ( + + + + + + + )} + + {pathname.includes(ROUTE_SLAUGHTER_SEGMENTATION) && ( + + + + + + + )} + + {pathname.includes(ROUTE_SLAUGHTER_ORDERS) && ( + + + + + + + )} + + {pathname.includes(ROUTE_SLAUGHTER_OUT_PROVINCE_BUY) && ( + + + + + + + )} + + ); +}; + +export default SlaughterInventoryPage; diff --git a/src/pages/SlaughterManageBars.js b/src/pages/SlaughterManageBars.js new file mode 100644 index 0000000..3747d31 --- /dev/null +++ b/src/pages/SlaughterManageBars.js @@ -0,0 +1,25 @@ +import { Box } from "@mui/material"; +import { Grid } from "../components/grid/Grid"; +import { SlaughterBars } from "../features/slaughter-house/components/slaughter-bars/SlaughterBars"; + +const SlaughterManageBars = () => { + return ( + <> + + + + + + + ); +}; + +export default SlaughterManageBars; diff --git a/src/pages/SlaughterMorgue.js b/src/pages/SlaughterMorgue.js new file mode 100644 index 0000000..8929c93 --- /dev/null +++ b/src/pages/SlaughterMorgue.js @@ -0,0 +1,131 @@ +import React, { useEffect, useState } from "react"; +import { Grid } from "../components/grid/Grid"; +import { Box, IconButton } from "@mui/material"; +import ResponsiveTable from "../components/responsive-table/ResponsiveTable"; +import { useDispatch, useSelector } from "react-redux"; +import { + slaughterGetMorgueDashboardService, + slaughterGetMorguesService, +} from "../features/slaughter-house/services/slaughetr-morgue-services"; +import { useNavigate, useParams } from "react-router-dom"; +import { SlaughterMorgueView } from "../features/slaughter-house/components/slaughter-morgue-view/SlaughterMorgueView"; +import { ROUTE_SLAUGHTER_MORGUE } from "../routes/routes"; +import { BackButton } from "../components/back-button/BackButton"; +import VisibilityIcon from "@mui/icons-material/Visibility"; +import { checkPathStartsWith } from "../utils/checkPathStartsWith"; + +const SlaughterMorgue = () => { + const dispatch = useDispatch(); + const [dashboardData, setDashboardData] = useState([]); + const [tableData, setTableData] = useState([]); + const selectedSubUser = useSelector( + (state) => state.userSlice.selectedSubUser + ); + const navigate = useNavigate(); + + const { key } = useParams(); + + useEffect(() => { + if (!key) { + dispatch( + slaughterGetMorgueDashboardService({ + role_key: checkPathStartsWith("slaughter") + ? selectedSubUser?.key || "" + : "", + }) + ).then((r) => { + setDashboardData(r.payload.data); + }); + dispatch(slaughterGetMorguesService()).then((r) => { + const d = r.payload.data?.coldHouses?.map((item, i) => { + return [ + i + 1, + item?.name, + item?.totalInputWeight?.toLocaleString(), + item?.totalAllocatedWeight?.toLocaleString(), + item?.totalRemainWeight?.toLocaleString(), + { + navigate(ROUTE_SLAUGHTER_MORGUE + "/" + item?.key); + }} + > + + , + ]; + }); + setTableData(d); + }); + } + }, [dispatch, key, selectedSubUser?.key]); + + return ( + <> + + + + {!key ? ( + + + + + + + + + ) : ( + + + + )} + + + + ); +}; + +export default SlaughterMorgue; diff --git a/src/pages/SlaughterRequestsPage.js b/src/pages/SlaughterRequestsPage.js new file mode 100644 index 0000000..7a12936 --- /dev/null +++ b/src/pages/SlaughterRequestsPage.js @@ -0,0 +1,131 @@ +import { Box, Typography } from "@mui/material"; +import { Grid } from "../components/grid/Grid"; +import { SPACING } from "../data/spacing"; +import { useLocation } from "react-router-dom"; +import { + ROUTE_SLAUGHTER_ACTIVE_REQUESTS, + ROUTE_SLAUGHTER_ALLOCATE_CAR_REQUESTS, + ROUTE_SLAUGHTER_ALLOCATION_REQUESTS, + ROUTE_SLAUGHTER_ARCHIVED_REQUESTS, + ROUTE_SLAUGHTER_ENTER_BAR_INFO, + ROUTE_SLAUGHTER_FACTORS, + ROUTE_SLAUGHTER_FINAL_FACTORS, + ROUTE_SLAUGHTER_NEW_REQUESTS, + ROUTE_SLAUGHTER_PAY_FACTORS_REQUESTS, + ROUTE_SLAUGHTER_PENDING_REQUESTS, + ROUTE_SLAUGHTER_REJECTED_REQUESTS, + ROUTE_SLAUGHTER_REQUESTS, + ROUTE_SLAUGHTER_SELL_CARCASS, + ROUTE_SLAUGHTERـEXPORT, + ROUTE_SLAUGHTERـFREE_BUY, +} from "../routes/routes"; +import { SlaughterRequests } from "../features/slaughter-house/components/slaughter-requests/SlaughterRequests"; +import { SlaughterRequestsOperations } from "../features/slaughter-house/components/slaughter-requests-operations/SlaughterRequestsOperations"; +import { SlaughterActiveRequests } from "../features/slaughter-house/components/slaughter-active-requests/SlaughterActiveRequests"; +import { SlaughterRejectedRequests } from "../features/slaughter-house/components/slaughter-rejected-requests/SlaughterRejectedRequests"; +import { SlaughterArchivedRequests } from "../features/slaughter-house/components/slaughter-archived-requests/SlaughterArchivedRequests"; +import { TourProvider } from "@reactour/tour"; +import { slaughterRequestsTourSteps } from "../features/slaughter-house/components/slaughter-requests/tour"; +import { SlaughterAllocatedCheckRequests } from "../features/slaughter-house/components/slaughter-allocated-check-requests/SlaughterAllocatedCheckRequests"; +import { SlaughterAllocateCarToRequests } from "../features/slaughter-house/components/slaughter-allocate-car-to-requests/SlaughterAllocateCarToRequests"; +import { SalughterEnterBarInfo } from "../features/slaughter-house/components/slaughter-enter-bar-info/SlaghterEnterBarInfo"; +import { SlaughterPayFactorRequests } from "../features/slaughter-house/components/slaughter-pay-factor-requests/SlaughterPayFactorRequests"; +import { BackButton } from "../components/back-button/BackButton"; +import { SlaughterFactorsComponent } from "../features/slaughter-house/components/slaughter-factors/SlaughterFactors"; +import { SlaughterFinalFactorsComponent } from "../features/slaughter-house/components/slaughter-final-factors/SlaughterFinalFactors"; +import { SlaughterFreeBuy } from "../features/slaughter-house/components/slaughter-free-buy/SlaughterFreeBuy"; +import { useSelector } from "react-redux"; +import { SlaughterExport } from "../features/slaughter-house/components/slaughter-export/SlaughterExport"; +import { ProvinceAllocatedRequests } from "../features/province/components/province-allocated-requests/ProvinceAllocatedRequests"; +import { SlaughterSellCarcass } from "../features/slaughter-house/components/slaughter-sell-carcass/SlaughterSellCarcass"; + +const SlaughterRequestsPage = () => { + const { pathname } = useLocation(); + + const { slaughterPermissionState } = useSelector( + (item) => item.slaughterSlice + ); + + return ( + <> + + + {pathname === ROUTE_SLAUGHTER_REQUESTS ? ( + + + + صفحه مدیریت درخواست های کشتارگاه + + + + + ) : ( + + )} + + + + {pathname === ROUTE_SLAUGHTER_NEW_REQUESTS && ( + + + + )} + {pathname === ROUTE_SLAUGHTER_ACTIVE_REQUESTS && ( + + )} + {pathname === ROUTE_SLAUGHTER_PENDING_REQUESTS && ( + + )} + {pathname === ROUTE_SLAUGHTER_ALLOCATE_CAR_REQUESTS && ( + + )} + {pathname === ROUTE_SLAUGHTER_REJECTED_REQUESTS && ( + + )}{" "} + {pathname === ROUTE_SLAUGHTER_ARCHIVED_REQUESTS && ( + + )} + {pathname === ROUTE_SLAUGHTER_ENTER_BAR_INFO && ( + + )} + {pathname === ROUTE_SLAUGHTER_SELL_CARCASS && ( + + )} + {pathname === ROUTE_SLAUGHTER_PAY_FACTORS_REQUESTS && ( + + )} + {pathname === ROUTE_SLAUGHTER_FACTORS && ( + + )} + {pathname === ROUTE_SLAUGHTER_FINAL_FACTORS && ( + + )} + {pathname === ROUTE_SLAUGHTERـFREE_BUY && } + {pathname === ROUTE_SLAUGHTERـEXPORT && } + + + {pathname === ROUTE_SLAUGHTER_ALLOCATION_REQUESTS && ( + + )} + + + + + ); +}; + +export default SlaughterRequestsPage; diff --git a/src/pages/SlaughterSubUnits.js b/src/pages/SlaughterSubUnits.js new file mode 100644 index 0000000..38402b8 --- /dev/null +++ b/src/pages/SlaughterSubUnits.js @@ -0,0 +1,66 @@ +import { Box, Grid } from "@mui/material"; +import { BackButton } from "../components/back-button/BackButton"; +import { NavLink } from "../components/nav-link/NavLink"; +import LinkItem from "../components/link-item/LinkItem"; +import { SPACING } from "../data/spacing"; +import { + ROUTE_SLAUGHTER_ROUTE_MANAGE_DISPENSERS, + ROUTE_SLAUGHTER_ROUTE_MANAGE_DELEGATES, + ROUTE_STEWARD_ROUTE_MANAGE_DELEGATES, + ROUTE_STEWARD_ROUTE_MANAGE_DISPENSERS, +} from "../routes/routes"; +import { VscPerson } from "react-icons/vsc"; +import BadgeIcon from "@mui/icons-material/Badge"; +import { getRoleFromUrl } from "../utils/getRoleFromUrl"; + +const SlaughterSubUnits = () => { + return ( + <> + + + + + + } + title="نمایندگان" + description="مدیریت نمایندگان" + /> + + + } + title="توزیع کنندگان" + description="مدیریت توزیع کنندگان" + /> + + + + + + ); +}; + +export default SlaughterSubUnits; diff --git a/src/pages/Slaughters.js b/src/pages/Slaughters.js new file mode 100644 index 0000000..93c235f --- /dev/null +++ b/src/pages/Slaughters.js @@ -0,0 +1,69 @@ +import { Box, Typography } from "@mui/material"; +import { Grid } from "../components/grid/Grid"; +import { SPACING } from "../data/spacing"; +import { useLocation } from "react-router-dom"; +import { + ROUTE_ADMINX_SLAUGHTERS, + ROUTE_ADMINX_SLAUGHTERS_MANAGE, + ROUTE_ADMINX_SLAUGHTERS_MONITORING_BUYERS, + ROUTE_PROVINCE_SLAUGHTERS, + ROUTE_PROVINCE_SLAUGHTERS_MANAGE, + ROUTE_PROVINCE_SLAUGHTERS_MONITORING_BUYERS, + ROUTE_SUPER_ADMIN_SLAUGHTERS, + ROUTE_SUPER_ADMIN_SLAUGHTERS_MANAGE, + ROUTE_SUPER_ADMIN_SLAUGHTERS_MONITORING_BUYERS, +} from "../routes/routes"; +import { SlaughterActiveRequests } from "../features/slaughter-house/components/slaughter-active-requests/SlaughterActiveRequests"; +import { BackButton } from "../components/back-button/BackButton"; +import { ProvinceSlaughterOperations } from "../features/province/components/province-slaughter-operations/ProvinceSlaughterOperations"; +import { MonitoringBuyers } from "../features/province/components/monitoring-buyers/MonitoringBuyers"; + +const Slaughters = () => { + const { pathname } = useLocation(); + + return ( + <> + + + {pathname === ROUTE_PROVINCE_SLAUGHTERS || + pathname === ROUTE_SUPER_ADMIN_SLAUGHTERS || + pathname === ROUTE_ADMINX_SLAUGHTERS ? ( + + + مدیریت خریداران + + + + ) : ( + + )} + + + + {(pathname === ROUTE_PROVINCE_SLAUGHTERS_MANAGE || + pathname === ROUTE_SUPER_ADMIN_SLAUGHTERS_MANAGE || + pathname === ROUTE_ADMINX_SLAUGHTERS_MANAGE) && ( + + )} + {(pathname === ROUTE_PROVINCE_SLAUGHTERS_MONITORING_BUYERS || + pathname === ROUTE_SUPER_ADMIN_SLAUGHTERS_MONITORING_BUYERS || + pathname === ROUTE_ADMINX_SLAUGHTERS_MONITORING_BUYERS) && ( + + )} + + + + + + ); +}; + +export default Slaughters; diff --git a/src/pages/StewardInventoryPage.js b/src/pages/StewardInventoryPage.js new file mode 100644 index 0000000..27c120d --- /dev/null +++ b/src/pages/StewardInventoryPage.js @@ -0,0 +1,186 @@ +import { Box } from "@mui/material"; +import { Grid } from "../components/grid/Grid"; +import { SPACING } from "../data/spacing"; +import { useLocation } from "react-router-dom"; +import { + ROUTE_STEWARD_INVENTORY, + ROUTE_STEWARD_SALE_IN_PROVINCE, + ROUTE_STEWARD_INVENTORY_STOCK, + ROUTE_STEWARD_DAILY_LIST, + ROUTE_STEWARD_PURCHASE_OUT_PROVINCE, + ROUTE_STEWARD_SALE_OUT_PROVINCE, + ROUTE_STEWARD_SEGMENT, +} from "../routes/routes"; +import { BackButton } from "../components/back-button/BackButton"; +import { useEffect } from "react"; +import { useDispatch, useSelector } from "react-redux"; +import { GuildInventoryOperation } from "../features/guild/components/GuildInventoryOperation"; +import ResponsiveTable from "../components/responsive-table/ResponsiveTable"; +import { StewardDailyList } from "../features/guild/components/StewardDailyList"; +import { StewardSegmant } from "../features/guild/components/StewardSegmant"; +import { StewardShowProducts } from "../features/steward/components/steward-show-products/StewardShowProducts"; +import { fetchStewardBroadcastAndProducts } from "../features/steward/services/handle-fetch-steward-products"; +import { StewardStock } from "../features/steward/components/steward-stock/StewardStock"; +import { StewardPurchaseOutProvince } from "../features/steward/components/steward-purchase-out-province/StewardPurchaseOutProvince"; +import { StewardSellOutOfProvince } from "../features/steward/components/steward-sell-out-of-province/StewardSellOutOfProvince"; +import { StewardSellInProvince } from "../features/steward/components/steward-sell-in-province/StewardSellInProvince"; +import { checkPathStartsWith } from "../utils/checkPathStartsWith"; + +const StewardInventoryPage = () => { + const { pathname } = useLocation(); + const dispatch = useDispatch(); + const selectedSubUser = useSelector( + (state) => state.userSlice.selectedSubUser + ); + const { distributionInfo } = useSelector((state) => state.stewardSlice); + + useEffect(() => { + if ( + [ + ROUTE_STEWARD_PURCHASE_OUT_PROVINCE, + ROUTE_STEWARD_INVENTORY, + ROUTE_STEWARD_SALE_OUT_PROVINCE, + ].includes(pathname) + ) { + dispatch( + fetchStewardBroadcastAndProducts({ + role_key: checkPathStartsWith("steward") ? selectedSubUser?.key : "", + }) + ); + } + }, [dispatch, pathname, selectedSubUser?.key]); + + return ( + <> + + + + {pathname === ROUTE_STEWARD_INVENTORY ? ( + + + + + + + + + + ) : null} + {pathname.includes(ROUTE_STEWARD_INVENTORY_STOCK) && } + {pathname.includes(ROUTE_STEWARD_SALE_IN_PROVINCE) && ( + + )} + {pathname.includes(ROUTE_STEWARD_PURCHASE_OUT_PROVINCE) && ( + + )} + {pathname.includes(ROUTE_STEWARD_DAILY_LIST) && } + {pathname.includes(ROUTE_STEWARD_SALE_OUT_PROVINCE) && ( + + )} + {pathname.includes(ROUTE_STEWARD_SEGMENT) && } + + + + ); +}; + +export default StewardInventoryPage; diff --git a/src/pages/SubSectorWage.js b/src/pages/SubSectorWage.js new file mode 100644 index 0000000..aec5e31 --- /dev/null +++ b/src/pages/SubSectorWage.js @@ -0,0 +1,89 @@ +import React from "react"; +import { Grid } from "../components/grid/Grid"; +import { Box, Typography } from "@mui/material"; +import { BackButton } from "../components/back-button/BackButton"; +import { useLocation } from "react-router-dom"; +import { + ROUTE_ADMINX_SUB_SECTORS_WAGE, + ROUTE_ADMINX_SUB_SECTORS_STEWARD_SHARES, + ROUTE_ADMINX_SUB_SECTORS_CITY_SHARES, + ROUTE_ADMINX_SUB_SECTORS_VET_FARM_SHARES, + ROUTE_PROVINCE_FINANCIAL_SUB_SECTORS_WAGE, + ROUTE_PROVINCE_FINANCIAL_SUB_SECTORS_STEWARD_SHARES, + ROUTE_PROVINCE_FINANCIAL_SUB_SECTORS_CITY_SHARES, + ROUTE_PROVINCE_FINANCIAL_SUB_SECTORS_VET_FARM_SHARES, + ROUTE_PROVINCE_SUB_SECTORS_WAGE, + ROUTE_PROVINCE_SUB_SECTORS_STEWARD_SHARES, + ROUTE_PROVINCE_SUB_SECTORS_CITY_SHARES, + ROUTE_PROVINCE_SUB_SECTORS_VET_FARM_SHARES, + ROUTE_SUPER_ADMIN_SUB_SECTORS_WAGE, + ROUTE_SUPER_ADMIN_SUB_SECTORS_STEWARD_SHARES, + ROUTE_SUPER_ADMIN_SUB_SECTORS_CITY_SHARES, + ROUTE_SUPER_ADMIN_SUB_SECTORS_VET_FARM_SHARES, +} from "../routes/routes"; +import { SPACING } from "../data/spacing"; +import { ProvinceSubSectorWageOperations } from "../features/province/components/province-sub-sector-wage-operations/ProvinceSubSectorWageOperations"; +import { ProvinceSubSectorCityShares } from "../features/province/components/province-sub-sector-city-shares/ProvinceSubSectorCityShares"; +import { ProvinceSubSectorWageDeposits } from "../features/province/components/province-sub-sector-wage-deposits/ProvinceSubSectorWageDeposits"; +import { ProvinceSubSectorVetFarmShares } from "../features/province/components/province-sub-sector-vet-farm-shares/ProvinceSubSectorVetFarmShares"; + +const SubSectorWage = () => { + const { pathname } = useLocation(); + return ( + <> + + + {pathname === ROUTE_PROVINCE_SUB_SECTORS_WAGE || + pathname === ROUTE_PROVINCE_FINANCIAL_SUB_SECTORS_WAGE || + pathname === ROUTE_SUPER_ADMIN_SUB_SECTORS_WAGE || + pathname === ROUTE_ADMINX_SUB_SECTORS_WAGE ? ( + + + تعرفه زیربخش ها + + + + ) : ( + + )} + + + {(pathname === ROUTE_PROVINCE_SUB_SECTORS_CITY_SHARES || + pathname === ROUTE_PROVINCE_FINANCIAL_SUB_SECTORS_CITY_SHARES || + pathname === ROUTE_SUPER_ADMIN_SUB_SECTORS_CITY_SHARES || + pathname === ROUTE_ADMINX_SUB_SECTORS_CITY_SHARES) && ( + + )} + + {(pathname === ROUTE_PROVINCE_SUB_SECTORS_VET_FARM_SHARES || + pathname === + ROUTE_PROVINCE_FINANCIAL_SUB_SECTORS_VET_FARM_SHARES || + pathname === ROUTE_SUPER_ADMIN_SUB_SECTORS_VET_FARM_SHARES || + pathname === ROUTE_ADMINX_SUB_SECTORS_VET_FARM_SHARES) && ( + + )} + + {(pathname === ROUTE_PROVINCE_SUB_SECTORS_STEWARD_SHARES || + pathname === + ROUTE_PROVINCE_FINANCIAL_SUB_SECTORS_STEWARD_SHARES || + pathname === ROUTE_SUPER_ADMIN_SUB_SECTORS_STEWARD_SHARES || + pathname === ROUTE_ADMINX_SUB_SECTORS_STEWARD_SHARES) && ( + + )} + + + + + + ); +}; + +export default SubSectorWage; diff --git a/src/pages/Support.js b/src/pages/Support.js new file mode 100644 index 0000000..fbb0f46 --- /dev/null +++ b/src/pages/Support.js @@ -0,0 +1,126 @@ +import { Button, Card, CardMedia, Typography } from "@mui/material"; +import { Box } from "@mui/system"; +import { Grid } from "../components/grid/Grid"; +import { SPACING } from "../data/spacing"; +// import WhatsAppIcon from "@mui/icons-material/WhatsApp"; +import PhoneIcon from "@mui/icons-material/Phone"; +import { motion } from "framer-motion"; +import eita from "../assets/images/eita.png"; + +const Support = () => { + // const MotionWhatsapp = motion(WhatsAppIcon); + const MotionPhone = motion(PhoneIcon); + + return ( + + + + + + برای تماس با پشتیبانی می توانید از طریق شماره زیر ارتباط برقرار + کنید. + + + {/* + + + + + 09011110919 + + + + */} + + + + + + + 021-28421237 + + + + + + + + + + + + + + + + پیشتیبانی سامانه رصدیار + + + + + + + + + + + + + + + ); +}; + +export default Support; diff --git a/src/pages/Ticket.js b/src/pages/Ticket.js new file mode 100644 index 0000000..943a061 --- /dev/null +++ b/src/pages/Ticket.js @@ -0,0 +1,94 @@ +import React, { useState } from "react"; +import { + Box, + Button, + TextField, + Stack, + Typography, + CircularProgress, +} from "@mui/material"; +import { useFormik } from "formik"; +import * as Yup from "yup"; + +const TicketSchema = Yup.object().shape({ + title: Yup.string().required("عنوان تیکت الزامی است"), + description: Yup.string().required("متن تیکت الزامی است"), +}); + +const Ticket = () => { + const [isSubmitting, setIsSubmitting] = useState(false); + + const formik = useFormik({ + initialValues: { title: "", description: "" }, + validationSchema: TicketSchema, + onSubmit: async (values) => { + setIsSubmitting(true); + try { + // Simulate a submission + await new Promise((resolve) => setTimeout(resolve, 2000)); + // console.log(values); + } finally { + setIsSubmitting(false); + } + }, + }); + + return ( + + + + ارسال پیام + +
    + + + + + +
    +
    +
    + ); +}; + +export default Ticket; diff --git a/src/pages/TicketList.js b/src/pages/TicketList.js new file mode 100644 index 0000000..aea4177 --- /dev/null +++ b/src/pages/TicketList.js @@ -0,0 +1,599 @@ +import React, { useContext, useEffect, useState } from "react"; +import { + Box, + Button, + IconButton, + TextField, + Tooltip, + Typography, +} from "@mui/material"; +import { useDispatch } from "react-redux"; +import axios from "axios"; +import { Grid } from "../components/grid/Grid"; +import { + CLOSE_MODAL, + LOADING_END, + LOADING_START, + OPEN_MODAL, +} from "../lib/redux/slices/appSlice"; +import ResponsiveTable from "../components/responsive-table/ResponsiveTable"; +import { getFaUserRole } from "../utils/getFaUserRole"; +import { useNavigate } from "react-router-dom"; +import persianDate from "persian-date"; +import useUserProfile from "../features/authentication/hooks/useUserProfile"; +import CommentsDisabledIcon from "@mui/icons-material/CommentsDisabled"; +import { AppContext } from "../contexts/AppContext"; +import { CloseTicketService } from "../features/ticket/services/create-ticket"; + +import personalTicketImage from "../../src/assets/images/Ticket1.png"; +import publicTicketImage from "../../src/assets/images/ticket2.png"; +import ClosedTicketImage from "../../src/assets/images/ClosedTicketImage.png"; +const TicketList = () => { + const navigate = useNavigate(); + const handleTextChange = (event) => { + setTextValue(event.target.value); + }; + + const [role] = useUserProfile(); + + const isAdmin = () => { + if ( + role.includes("CityOperator") || + role.includes("ProvinceOperator") || + role.includes("AdminX") || + role.includes("Supporter") || + role.includes("SuperAdmin") + ) { + return true; + } else { + return false; + } + }; + + const [data, setData] = useState([]); + const [totalRows, setTotalRows] = useState(0); + const [perPage, setPerPage] = useState(10); + const [textValue, setTextValue] = useState(""); + const [page, setPage] = useState(1); + const [tableData, setTableData] = useState([]); + const [openNotif] = useContext(AppContext); + const [value, setValue] = useState("0"); + const [selectedTicket, setSelectedTicket] = useState("0"); + const [unreadMessages, setUnredMessages] = useState([]); + // const [ticketCounts, setTicketCounts] = useState({ + // personal: 0, + // public: 0, + // closed: 0, + // }); + + // const handleChange = (event, newValue) => { + // setValue(newValue); + // }; + + const fetchApiData = async (page) => { + let response; + try { + dispatch(LOADING_START()); + + let query = `ticket/?search=filter&value=${textValue}&page=${page}&page_size=${perPage}`; + + if (value === "0") query += `&type=single&status=open`; + else if (value === "1") query += `&type=public&status=open`; + else if (value === "2") query += `&status=closed`; + + response = await axios.get(query); + dispatch(LOADING_END()); + setData(response.data.results); + setTotalRows(response.data.count); + } catch { + dispatch(LOADING_END()); + } + }; + + const dispatch = useDispatch(); + + const handlePageChange = (page) => { + fetchApiData(page); + setPage(page); + }; + + const handlePerRowsChange = (perRows) => { + setPerPage(perRows); + setPage(1); + }; + + const updateTable = () => { + fetchApiData(page !== 0 ? page : 1); + }; + + useEffect(() => { + fetchApiData(1); + }, [dispatch, perPage, value]); + + useEffect(() => { + let unread = []; + const d = data?.map((item, i) => { + if (item?.unreadMessage) { + unread[i] = true; + } else { + unread[i] = false; + } + return [ + page === 1 ? i + 1 : i + (perPage * page) / 2 + 1, + item?.ticketId, + item.typeTicket === "single" ? "شخصی" : "همگانی", + `${item?.role ? getFaUserRole(item?.role) : ""} (${ + item?.user?.fullname + })`, + item?.title, + `${ + item?.status === "open" + ? `باز${item?.readOnly === true ? " (فقط خواندنی)" : ""}` + : item?.status === "answered" + ? "پاسخ داده شده" + : "بسته" + }`, + item.toUser.length + ? item?.toUser?.map( + (option, index) => + `${option?.fullname} ${ + index + 1 !== item?.toUser?.length ? " - " : "" + }` + ) + : item?.toRole?.map( + (option, index) => + `${getFaUserRole(option.name)} ${ + index + 1 !== item?.toRole?.length ? " - " : "" + }` + ), + `${new persianDate(new Date(item?.createDate)).format( + "dddd DD MMMM" + )} (${new Date(item?.createDate).toLocaleTimeString([], { + hour: "2-digit", + minute: "2-digit", + hour12: false, + })})`, + + + {isAdmin() && ( + + { + dispatch( + OPEN_MODAL({ + title: "از بستن تیکت اطمینان دارید؟", + content: ( + + + در صورت بستن تیکت امکان باز کردن مجدد آن وجود ندارد! + + + + + + + ), + }) + ); + }} + > + + + + )} + , + ]; + }); + + setTableData(d); + setUnredMessages(unread); + }, [data]); + + const handleSubmit = async (event) => { + event.preventDefault(); + dispatch(LOADING_START()); + + try { + let query = `ticket/?search=filter&value=${textValue}&page=1&page_size=${perPage}`; + + if (value === "0") query += `&type=single`; + else if (value === "1") query += `&type=public`; + else if (value === "2") query += `&status=closed`; + + const response = await axios.get(query); + setData(response.data.results); + setTotalRows(response.data.count); + dispatch(LOADING_END()); + } catch (error) { + console.error("Error fetching data:", error); + } + }; + + const handleTicketTypeSelect = (type) => { + setValue(type); + setSelectedTicket(type); + }; + + return ( + <> + + + + + تیکت های من + + + + + + + {/* + + + */} + + + + handleTicketTypeSelect("0")} + gap={1} + > + + Personal Tickets + + + + تیکت های شخصی + + + + handleTicketTypeSelect("1")} + gap={1} + > + + Public Tickets + + + + تیکت های همگانی + + + + handleTicketTypeSelect("2")} + gap={1} + > + + Closed Tickets + + + تیکت‌های بایگانی + + + + {/* + Closed Tickets + + تیکت های بسته شده: {ticketCounts.closed} + + */} + + + {value === "0" && ( + + +
    + + + +
    + + + + +
    + )} + + {value === "1" && ( + + + +
    + + + +
    + + + + +
    + )} + + {value === "2" && ( + + +
    + + + +
    + + + + +
    + )} +
    +
    + + ); +}; + +export default TicketList; diff --git a/src/pages/Tickets.js b/src/pages/Tickets.js new file mode 100644 index 0000000..6f6d880 --- /dev/null +++ b/src/pages/Tickets.js @@ -0,0 +1,63 @@ +import { Box } from "@mui/material"; +import { Grid } from "../components/grid/Grid"; +import { SPACING } from "../data/spacing"; +import { + ROUTE_ADMINX_TICKET, + ROUTE_AVICULTURE_TICKET, + ROUTE_CITY_TICKET, + ROUTE_GENERAL_TICKET_LIST, + ROUTE_PROVINCE_FINANCIAL_TICKET, + ROUTE_PROVINCE_INSPECTOR_TICKET, + ROUTE_PROVINCE_TICKET, + ROUTE_SLAUGHTER_TICKET, + ROUTE_SUPER_ADMIN_TICKET, +} from "../routes/routes"; +import { useLocation, useParams } from "react-router-dom"; +// import { VetFarmOperations } from "../features/vet-farm/components/vet-farm-operations/VetFarmOperations"; +import { TicketView } from "../features/ticket/components/ticket-view/TicketView"; +import TicketList from "./TicketList"; + +const Tickets = () => { + const { pathname } = useLocation(); + + const { id } = useParams(); + + return ( + + + {/* + + + + */} + + + + {(!id && pathname === ROUTE_AVICULTURE_TICKET) || + pathname === ROUTE_PROVINCE_FINANCIAL_TICKET || + pathname === ROUTE_PROVINCE_TICKET || + pathname === ROUTE_SLAUGHTER_TICKET || + pathname === ROUTE_SUPER_ADMIN_TICKET || + pathname === ROUTE_ADMINX_TICKET || + pathname === ROUTE_PROVINCE_INSPECTOR_TICKET || + pathname === ROUTE_CITY_TICKET || + pathname === ROUTE_GENERAL_TICKET_LIST ? ( + + ) : ( + + )} + + + + + ); +}; +export default Tickets; diff --git a/src/pages/TokenLogin.js b/src/pages/TokenLogin.js new file mode 100644 index 0000000..11ff17c --- /dev/null +++ b/src/pages/TokenLogin.js @@ -0,0 +1,25 @@ +import { Box } from "@mui/system"; +import { useEffect } from "react"; +import { useDispatch } from "react-redux"; +import { useLocation } from "react-router-dom"; +import { AUTO_SIGN_IN } from "../lib/redux/slices/userSlice"; + +const TokenLogin = () => { + const loc = useLocation(); + const data = loc.pathname.slice(1); + const decodedStringAtoB = atob(data); + const dispatch = useDispatch(); + + useEffect(() => { + dispatch(AUTO_SIGN_IN(JSON.parse(decodedStringAtoB))); + // localStorage.setItem("persist:root", decodedStringAtoB); + }, []); + + return ( + +

    در حال لاگین

    +
    + ); +}; + +export default TokenLogin; diff --git a/src/pages/TradePanel.js b/src/pages/TradePanel.js new file mode 100644 index 0000000..f341822 --- /dev/null +++ b/src/pages/TradePanel.js @@ -0,0 +1,38 @@ +import { Grid } from "../components/grid/Grid"; +import { Box } from "@mui/material"; +import { useLocation } from "react-router-dom"; +import { + ROUTE_PROVINCE_TRADING_PANEL, + ROUTE_SLAUGHTER_TRADING_PANEL, + ROUTE_ADMINX_TRADING_PANEL, + ROUTE_SUPER_ADMIN_TRADING_PANEL, +} from "../routes/routes"; +import { BackButton } from "../components/back-button/BackButton"; +import { ProvinceTradePanel } from "../features/province/components/province-trade-panel/ProvinceTradePanel"; +const TradePanel = () => { + const { pathname } = useLocation(); + + return ( + + + + {(pathname === ROUTE_SLAUGHTER_TRADING_PANEL || + pathname === ROUTE_PROVINCE_TRADING_PANEL || + pathname === ROUTE_ADMINX_TRADING_PANEL || + pathname === ROUTE_SUPER_ADMIN_TRADING_PANEL) && ( + + )} + + + ); +}; + +export default TradePanel; diff --git a/src/pages/Training.js b/src/pages/Training.js new file mode 100644 index 0000000..ac4c3e3 --- /dev/null +++ b/src/pages/Training.js @@ -0,0 +1,61 @@ +import { Typography, Box } from "@mui/material"; +import { motion } from "framer-motion"; +import { SPACING } from "../data/spacing"; +import useUserProfile from "../features/authentication/hooks/useUserProfile"; + +const Training = () => { + const [roles] = useUserProfile(); + + return ( + + + آموزش + + + {roles.includes("KillHouse") && ( + + + + Your browser does not support the video tag. + + + )} + + ); +}; + +export default Training; diff --git a/src/pages/Transactions.js b/src/pages/Transactions.js new file mode 100644 index 0000000..1c75242 --- /dev/null +++ b/src/pages/Transactions.js @@ -0,0 +1,40 @@ +import { Box } from "@mui/material"; +import { Grid } from "../components/grid/Grid"; +import { SPACING } from "../data/spacing"; +import { Transactions } from "../features/province/components/transactions/Transactions"; +import { BackButton } from "../components/back-button/BackButton"; +import { useParams } from "react-router-dom"; +import { ProvinceShowStewardsTransactions } from "../features/province/components/province-show-stewards-transactions/ProvinceShowStewardsTransactions"; + +const TransactionsPage = () => { + const { key, name } = useParams(); + + return ( + <> + + + + + + {key ? ( + + ) : ( + + )} + + + + + + ); +}; + +export default TransactionsPage; diff --git a/src/pages/Users.js b/src/pages/Users.js new file mode 100644 index 0000000..9c2c49e --- /dev/null +++ b/src/pages/Users.js @@ -0,0 +1,30 @@ +import { Box } from "@mui/material"; +import { Grid } from "../components/grid/Grid"; +import { SPACING } from "../data/spacing"; +import { ProvinceManageUsers } from "../features/province/components/province-manage-users/ProvinceManageUsers"; +// import { VetFarmOperations } from "../features/vet-farm/components/vet-farm-operations/VetFarmOperations"; + +const Users = () => { + return ( + <> + + + + + + + + + + + ); +}; +export default Users; diff --git a/src/pages/VetFarm.js b/src/pages/VetFarm.js new file mode 100644 index 0000000..a78184f --- /dev/null +++ b/src/pages/VetFarm.js @@ -0,0 +1,45 @@ +import { Box } from "@mui/material"; +import { Grid } from "../components/grid/Grid"; +import { SPACING } from "../data/spacing"; +import { + ROUTE_CITYVET_REGISTER_INFO, + ROUTE_VETFARM_REGISTER_INFO, +} from "../routes/routes"; +import { useLocation } from "react-router-dom"; +// import { VetFarmOperations } from "../features/vet-farm/components/vet-farm-operations/VetFarmOperations"; +import { VetFarmSubmitFarmInfo } from "../features/vet-farm/components/vet-farm-submit-farm-info/VetFarmSubmitFarmInfo"; + +const VetFarm = () => { + const { pathname } = useLocation(); + + return ( + <> + + + {/* + + + + */} + + + {(pathname === ROUTE_VETFARM_REGISTER_INFO || + pathname === ROUTE_CITYVET_REGISTER_INFO) && ( + + )} + + + + + + ); +}; +export default VetFarm; diff --git a/src/pages/VetFarmAllocations.js b/src/pages/VetFarmAllocations.js new file mode 100644 index 0000000..5a6e03e --- /dev/null +++ b/src/pages/VetFarmAllocations.js @@ -0,0 +1,32 @@ +import { Box } from "@mui/material"; +import { Grid } from "../components/grid/Grid"; +import { SPACING } from "../data/spacing"; +import { VetFarmOperation } from "../features/vet-farm/components/vet-farm-operation/VetFarmOperation"; + +const VetFarmAllocations = () => { + return ( + + + + + + + + + + ); +}; +export default VetFarmAllocations; diff --git a/src/pages/VetFarmInspections.js b/src/pages/VetFarmInspections.js new file mode 100644 index 0000000..879a6cc --- /dev/null +++ b/src/pages/VetFarmInspections.js @@ -0,0 +1,35 @@ +import { Box } from "@mui/material"; +import { Grid } from "../components/grid/Grid"; +import { SPACING } from "../data/spacing"; +import { ROUTE_VETFARM_INSPECTIONS } from "../routes/routes"; +import { useLocation } from "react-router-dom"; +import { VetFarmInspectionHistory } from "../features/vet-farm/components/vet-farm-inspection-history/VetFarmInspectionHistory"; + +const VetFarmInspections = () => { + const { pathname } = useLocation(); + + return ( + <> + + + + + {pathname.includes(ROUTE_VETFARM_INSPECTIONS) && ( + + )} + + + + + + ); +}; +export default VetFarmInspections; diff --git a/src/pages/VetSupervisor.js b/src/pages/VetSupervisor.js new file mode 100644 index 0000000..4aca4d8 --- /dev/null +++ b/src/pages/VetSupervisor.js @@ -0,0 +1,45 @@ +import { Box } from "@mui/material"; +import { Grid } from "../components/grid/Grid"; +import { SPACING } from "../data/spacing"; +// import { ROUTE_VETFARM_REGISTER_INFO } from "../routes/routes"; +// import { useLocation } from "react-router-dom"; +// import { VetFarmOperations } from "../features/vet-farm/components/vet-farm-operations/VetFarmOperations"; +// import { VetFarmSubmitFarmInfo } from "../features/vet-farm/components/vet-farm-submit-farm-info/VetFarmSubmitFarmInfo"; +import { CityHatching } from "../features/city/components/city-new-hatching/CityHatching"; + +const VetSupervisor = () => { + // const { pathname } = useLocation(); + + return ( + <> + + + {/* + + + + */} + + + + + + + + + ); +}; +export default VetSupervisor; diff --git a/src/pages/VisorStatics.js b/src/pages/VisorStatics.js new file mode 100644 index 0000000..dc2b1c7 --- /dev/null +++ b/src/pages/VisorStatics.js @@ -0,0 +1,132 @@ +import React from "react"; +import { Grid } from "../components/grid/Grid"; +import { Box, Typography } from "@mui/material"; +import { VisorsStaticsMainPage } from "../features/visors/components/visors-statics-main-page/VisorsStaticsMainPage"; +import { SPACING } from "../data/spacing"; +import { useLocation, useParams } from "react-router-dom"; +import { + ROUTE_ADMINX_VISOR_STATICS, + ROUTE_CITY_VISOR_STATICS, + ROUTE_PROVINCEـVISOR_STATICS, + ROUTE_VETـSUPERVISOR_STATICS, + ROUTE_COMMERCE_VISOR_STATICS, + ROUTE_PROVINCE_SUPERVISOR_STATICS, + ROUTE_OBSERVATORY_VISOR_STATICS, + ROUTE_SUPER_ADMIN_VISOR_STATICS, + ROUTE_ADMINX_VISOR_STATICS_CHARTS, + ROUTE_CITY_VISOR_STATICS_CHARTS, + ROUTE_PROVINCEـVISOR_STATICS_CHARTS, + ROUTE_VETـSUPERVISOR_STATICS_CHARTS, + ROUTE_COMMERCE_VISOR_STATICS_CHARTS, + ROUTE_PROVINCE_SUPERVISOR_STATICS_CHARTS, + ROUTE_OBSERVATORY_VISOR_STATICS_CHARTS, + ROUTE_SUPER_ADMIN_VISOR_STATICS_CHARTS, + ROUTE_ADMINX_VISOR_STATICS_PREDICTION, + ROUTE_CITY_VISOR_STATICS_PREDICTION, + ROUTE_PROVINCEـVISOR_STATICS_PREDICTION, + ROUTE_VETـSUPERVISOR_STATICS_PREDICTION, + ROUTE_COMMERCE_VISOR_STATICS_PREDICTION, + ROUTE_PROVINCE_SUPERVISOR_STATICS_PREDICTION, + ROUTE_OBSERVATORY_VISOR_STATICS_PREDICTION, + ROUTE_SUPER_ADMIN_VISOR_STATICS_PREDICTION, + ROUTE_ADMINX_NATIONAL_STATICS, + ROUTE_SUPER_ADMIN_NATIONAL_STATICS, + ROUTE_ADMIN_NATIONAL_STATICS, + ROUTE_PROVINCE_NATIONAL_STATICS, +} from "../routes/routes"; +import { VisorsStaticsOperations } from "../features/visors/components/visors-statics-operations/VisorsStaticsOperations"; +import { BackButton } from "../components/back-button/BackButton"; +import { VisorStaticsPrediction } from "../features/visors/components/visor-statics-prediction/VisorStaticsPrediction"; +import { VisorStaticsPredictionDetails } from "../features/visors/components/visor-statics-prediction-details/VisorStaticsPredictionDetails"; +import { VisorStaticsNationalInfo } from "../features/visors/components/visor-statics-national-info/VisorStaticsNationalInfo"; + +const VisorStatics = () => { + const { key } = useParams(); + const renderComponentBasedOnPath = (pathname) => { + const chartsRoutes = [ + ROUTE_ADMINX_VISOR_STATICS_CHARTS, + ROUTE_CITY_VISOR_STATICS_CHARTS, + ROUTE_PROVINCEـVISOR_STATICS_CHARTS, + ROUTE_VETـSUPERVISOR_STATICS_CHARTS, + ROUTE_COMMERCE_VISOR_STATICS_CHARTS, + ROUTE_PROVINCE_SUPERVISOR_STATICS_CHARTS, + ROUTE_OBSERVATORY_VISOR_STATICS_CHARTS, + ROUTE_SUPER_ADMIN_VISOR_STATICS_CHARTS, + ]; + + const predictionRoutes = [ + ROUTE_ADMINX_VISOR_STATICS_PREDICTION, + ROUTE_CITY_VISOR_STATICS_PREDICTION, + ROUTE_PROVINCEـVISOR_STATICS_PREDICTION, + ROUTE_VETـSUPERVISOR_STATICS_PREDICTION, + ROUTE_COMMERCE_VISOR_STATICS_PREDICTION, + ROUTE_PROVINCE_SUPERVISOR_STATICS_PREDICTION, + ROUTE_OBSERVATORY_VISOR_STATICS_PREDICTION, + ROUTE_SUPER_ADMIN_VISOR_STATICS_PREDICTION, + ]; + + const nationalInfoRoutes = [ + ROUTE_ADMINX_NATIONAL_STATICS, + ROUTE_SUPER_ADMIN_NATIONAL_STATICS, + ROUTE_ADMIN_NATIONAL_STATICS, + ROUTE_PROVINCE_NATIONAL_STATICS, + ]; + + if (chartsRoutes.includes(pathname)) return ; + if (nationalInfoRoutes.includes(pathname)) + return ; + if (predictionRoutes.some((route) => pathname.includes(route))) + return ; + + return null; + }; + + const DashboardTitle = () => ( + + + داشبورد پایش آماری + + + ); + + const { pathname } = useLocation(); + + const isDashboardRoute = [ + ROUTE_ADMINX_VISOR_STATICS, + ROUTE_CITY_VISOR_STATICS, + ROUTE_PROVINCEـVISOR_STATICS, + ROUTE_VETـSUPERVISOR_STATICS, + ROUTE_COMMERCE_VISOR_STATICS, + ROUTE_PROVINCE_SUPERVISOR_STATICS, + ROUTE_OBSERVATORY_VISOR_STATICS, + ROUTE_SUPER_ADMIN_VISOR_STATICS, + ].includes(pathname); + + return ( + + + {isDashboardRoute && !key ? ( + <> + + + + ) : ( + !key && + )} + + {!key && renderComponentBasedOnPath(pathname)} + {key && } + + + ); +}; + +export default VisorStatics; diff --git a/src/pages/WagePayment.js b/src/pages/WagePayment.js new file mode 100644 index 0000000..4cafc41 --- /dev/null +++ b/src/pages/WagePayment.js @@ -0,0 +1,326 @@ +import React, { useEffect, useState } from "react"; +import { useParams } from "react-router-dom"; +import { Grid } from "../components/grid/Grid"; +import { + Accordion, + AccordionDetails, + AccordionSummary, + Button, + Divider, + InputAdornment, + TextField, + Typography, +} from "@mui/material"; +import ExpandMoreIcon from "@mui/icons-material/ExpandMore"; + +import logo from "../assets/images/logo.png"; +import { useFormik } from "formik"; +import { Yup } from "../lib/yup/yup"; +import Num2persian from "num2persian"; +import { useDispatch } from "react-redux"; +import { wagePaymentGetUserInfo } from "../features/authentication/services/wage-payment-get-user-info"; +import { OPEN_MODAL } from "../lib/redux/slices/appSlice"; +import { SlaughterPayFeesGateway } from "../features/slaughter-house/components/slaughter-pay-fees-gateway/SlaughterPayFeesGateway"; +import { SimpleTable } from "../components/simple-table/SimpleTable"; + +const WagePayment = () => { + const { key, province } = useParams(); + + const [userInfo, setUserInfo] = useState(); + + const dispatch = useDispatch(); + + const formik = useFormik({ + initialValues: { + offer: 0, + }, + validationSchema: Yup.object({ + offer: Yup.number() + .required("این فیلد اجباری است!") + .typeError("لطفا عدد وارد کنید!") + .min(200000, "حداقل بیست هزار تومان وارد کنید"), + // .max( + // 2000000000, + // "در هر بار پرداخت، حداکثر مبلغ 200 میلیون تومان میتوانید پرداخت کنید!" + // ), + }), + }); + + useEffect(() => { + if (key) { + dispatch( + wagePaymentGetUserInfo({ province, key: `user_gate_way_id=${key}` }) + ).then((r) => { + setUserInfo(r.payload.data); + if (r.payload?.data?.totalAmount > 2000000000) { + formik.setFieldValue("offer", 2000000000); + } else { + formik.setFieldValue( + "offer", + parseInt(Math.ceil(r.payload.data.totalAmount / 10000) * 10000) + ); + } + }); + } + }, []); + + useEffect(() => { + formik.validateForm(); + }, []); + + const [tableData, setTableData] = useState([]); + + useEffect(() => { + if (userInfo?.role === "Poultry" || userInfo?.role === "buyer") { + const d = userInfo?.orderCode?.map((item, i) => { + return [i + 1, item]; + }); + + setTableData(d); + } + }, [userInfo]); + + return ( + + + + logo + + + سامانه رصدیار + + + پنل پرداخت تعرفه + + + + + + + نام و نام خانوادگی: + + + + + {userInfo?.fullname} + {/* {userInfo?.role === "Poultry" + ? `${userInfo?.fullname}` + : userInfo?.role === "Buyer" + ? `${userInfo?.fullname}` + : `${userInfo?.fullname} (${userInfo?.name})`} */} + + + + {userInfo?.mobile} + + + + + + {userInfo?.role === "Poultry" && ( + <> + {userInfo?.orderCode && ( + + + کد سفارش: + + + + {userInfo?.orderCode?.toLocaleString()} + + + )} + + + تعداد سفارشات: + + + + {userInfo?.numberOfRequests?.toLocaleString()} + + + + + حجم سفارشات: + + + + {userInfo?.totalQuantity?.toLocaleString()} قطعه + + + + + + وزن سفارشات: + + + + {userInfo?.totalWeight?.toLocaleString()} کیلوگرم + + + + )} + + {(userInfo?.role === "Poultry" || userInfo?.role === "buyer") && ( + + } + aria-controls="panel1a-content" + sx={{ + backgroundColor: "#fff", + }} + > + + مشاهده سفارشات + + + + + + + + + )} + + + + جمع بدهی: + + + + {parseInt( + Math.ceil(userInfo?.totalAmount / 10000) * 10000 + ).toLocaleString()}{" "} + ریال + + + + + + + + مبلغ تراکنش: + + + + {parseInt( + Math.ceil(formik.values.offer / 10000) * 10000 + ).toLocaleString()}{" "} + ریال + + + + + + + ریال + ), + readOnly: + userInfo?.role === "Poultry" || userInfo?.role === "Buyer", + }} + variant="outlined" + sx={{ width: "100%" }} + value={formik.values.offer} + error={formik.touched.offer ? Boolean(formik.errors.offer) : null} + onChange={formik.handleChange} + onBlur={formik.handleBlur} + helperText={ + formik.touched.offer && Boolean(formik.errors.offer) + ? formik.errors.offer + : null + } + /> + + + معادل {Num2persian(formik.values.offer / 10)} تومان + + {/* + + توجه: در هر تراکنش حداکثر مبلغ 200 میلیون تومان میتوانید پرداخت + کنید! + + */} + + + + + ); +}; + +export default WagePayment; diff --git a/src/pages/Wallet.js b/src/pages/Wallet.js new file mode 100644 index 0000000..1c6b1ee --- /dev/null +++ b/src/pages/Wallet.js @@ -0,0 +1,424 @@ +import React, { useContext, useEffect, useState } from "react"; +import { + Box, + Button, + Typography, + TextField, + InputAdornment, + Pagination, + Tooltip, + FormControl, + InputLabel, + Select, + MenuItem, +} from "@mui/material"; +import { AiOutlineArrowUp } from "react-icons/ai"; +import { Grid } from "../components/grid/Grid"; +import { motion } from "framer-motion"; +import { useFormik } from "formik"; +import { Yup } from "../lib/yup/yup"; +import { useDispatch, useSelector } from "react-redux"; +import { slaughterGetWalletBalance } from "../features/slaughter-house/services/get-wallet-balance"; +import { BackButton } from "../components/back-button/BackButton"; +import { OPEN_MODAL } from "../lib/redux/slices/appSlice"; +import { SlaughterPayFeesGateway } from "../features/slaughter-house/components/slaughter-pay-fees-gateway/SlaughterPayFeesGateway"; +import { slaughterGetProfile } from "../features/slaughter-house/services/slaughter-get-profile"; +import Num2persian from "num2persian"; +import { AppContext } from "../contexts/AppContext"; +import moment from "moment"; +import axios from "axios"; +import { SimpleTable } from "../components/simple-table/SimpleTable"; +import { getRoleFromUrl } from "../utils/getRoleFromUrl"; +import { DatePicker } from "@mui/x-date-pickers"; +import { SPACING } from "../data/spacing"; +import { format } from "date-fns-jalali"; +import { RiFileExcel2Fill, RiSearchLine } from "react-icons/ri"; + +const Wallet = () => { + const [showInput, setShowInput] = useState(false); + const [balance, setBalance] = useState(0); + const [dataTableM, setDataTableM] = useState([]); + const dispatch = useDispatch(); + const [data, setData] = useState([]); + const [totalRows, setTotalRows] = useState(0); + const [textValue, setTextValue] = useState(""); + const [type, setType] = useState("completed"); + + const handleChange = (event) => { + setType(event.target.value); + }; + + const handleTextChange = (event) => { + setTextValue(event.target.value); + }; + const userInfo = useSelector((state) => state.userSlice); + + const handleDepositClick = () => { + setShowInput(true); + }; + + const [, , selectedDate1, setSelectedDate1, selectedDate2, setSelectedDate2] = + useContext(AppContext); + + useEffect(() => { + const currentDate = moment(new Date()).format("YYYY-MM-DD"); + setSelectedDate1(currentDate); + setSelectedDate2(currentDate); + }, []); + + const fetchApiData = async (page, textValue) => { + const response = await axios.get( + `transactions/?search=filter&value=${textValue}&page=${page}&type=wallet&page_size=${10}&date1=${selectedDate1}&date2=${selectedDate2}&state=${type}&role=${getRoleFromUrl()}` + ); + setData(response.data.results); + setTotalRows(response.data.count); + }; + + useEffect(() => { + fetchApiData(1); + }, [selectedDate1, selectedDate2, type]); + + const handleSubmit = async (event) => { + event.preventDefault(); + try { + const response = await axios.get( + `transactions/?search=filter&value=${textValue}&type=wallet&date1=${selectedDate1}&date2=${selectedDate2}&state=${type}&role=${getRoleFromUrl()}` + ); + setData(response.data.results); + setTotalRows(response.data.count); + } catch (error) { + console.error("Error fetching data:", error); + } + }; + + const [page, setPage] = useState(0); + const handleChangePageM = (event, newPage) => { + setPage(newPage); + fetchApiData(newPage + 1, textValue); + }; + + useEffect(() => { + dispatch(slaughterGetWalletBalance()).then((r) => { + setBalance(r.payload.data?.balance); + }); + dispatch(slaughterGetProfile()); + }, []); + + useEffect(() => { + const d = data?.map((item, i) => { + return [ + i + 1, + format(new Date(item.createDate), "yyyy/MM/dd hh:mm:ss"), + item.payer, + item.orderId, + item.saleReferenceId, + item.orderId, + item.cardHolderPan, + item?.amount?.toLocaleString() + " ﷼", + item.message?.split("_")?.join(" "), + ]; + }); + + setDataTableM(d); + }, [data]); + + const { inventorySelectedKillHouse } = useSelector( + (state) => state.slaughterSlice + ); + + const formik = useFormik({ + initialValues: { + amount: "", + }, + validationSchema: Yup.object({ + amount: Yup.number() + .required("این فیلد اجباری است!") + .min(1000000, "حداقل مبلغ صد هزار تومان است!") + .max( + 1818180000, + "جمع مبلغ کل و مالیات نباید از دویست میلیون تومان بیشتر شود!" + ) + .typeError("لطفا مبلغ را به درستی وارد کنید!"), + }), + }); + + useEffect(() => { + formik.validateForm(); + }, []); + + const getValueWIthTax = (value) => { + return Number(value / 10) + Number(value); + }; + + return ( + + + + + + + + + + کیف پول + + + موجودی کیف پول: {balance?.toLocaleString()} ریال + + {!showInput ? ( + + ) : ( + + ریال + ), + }} + helperText={ + formik.touched.amount && Boolean(formik.errors.amount) + ? formik.errors.amount + : null + } + autoComplete="current-password" + variant="outlined" + /> + + + {formik.values.amount > 0 && ( + + {Num2persian(formik.values.amount)} ریال + + )} + + + {formik.values.amount > 0 && ( + + با احتساب ده درصد ارزش افزوده:{" "} + {getValueWIthTax( + formik.values.amount + ).toLocaleString()}{" "} + ریال + + )} + + + + + + )} + + + + + + + تراکنش ها + + + + + نوع تراکنش + + + + + + ( + + )} + value={selectedDate1} + onChange={(e) => { + setSelectedDate1(moment(e).format("YYYY-MM-DD")); + }} + /> + + + ( + + )} + value={selectedDate2} + onChange={(e) => { + setSelectedDate2(moment(e).format("YYYY-MM-DD")); + }} + /> + + +
    + + + + + + + + +
    +
    + + + + { + handleChangePageM(event, newPage - 1); + }} + /> + + +
    +
    +
    + ); +}; + +export default Wallet; diff --git a/src/reportWebVitals.js b/src/reportWebVitals.js new file mode 100644 index 0000000..9ecd33f --- /dev/null +++ b/src/reportWebVitals.js @@ -0,0 +1,13 @@ +const reportWebVitals = (onPerfEntry) => { + if (onPerfEntry && onPerfEntry instanceof Function) { + import("web-vitals").then(({ getCLS, getFID, getFCP, getLCP, getTTFB }) => { + getCLS(onPerfEntry); + getFID(onPerfEntry); + getFCP(onPerfEntry); + getLCP(onPerfEntry); + getTTFB(onPerfEntry); + }); + } +}; + +export default reportWebVitals; diff --git a/src/routes/LiveStockProvinceJahadRouting.js b/src/routes/LiveStockProvinceJahadRouting.js new file mode 100644 index 0000000..eff335b --- /dev/null +++ b/src/routes/LiveStockProvinceJahadRouting.js @@ -0,0 +1,40 @@ +import { lazy } from "react"; +import { lazyRetry } from "../utils/lazyRetry"; +import { + ROUTE_PROVINCE_JAHAD_PRODUCT_DISTRIBUTION, + ROUTE_PROVINCE_JAHAD_PRODUCT_DISTRIBUTION_ALLOCATION, + ROUTE_PROVINCE_JAHAD_PRODUCT_DISTRIBUTION_POLICY, + ROUTE_PROVINCE_JAHAD_PRODUCT_SHARES, + ROUTE_PROVINCE_JAHAD_PRODUCT_TRANSACTIONS, + ROUTE_PROVINCE_JAHAD_COOPERATIVES, + ROUTE_PROVINCE_JAHAD_HERDS, + ROUTE_PROVINCE_JAHAD_RANCHERS, + ROUTE_PROVINCE_JAHAD_SELL_REPORT, + ROUTE_PROVINCE_JAHAD_UNIONS, + ROUTE_PROVINCE_JAHAD_USERS, +} from "./routes"; + +const RequestsPage = lazy(() => + lazyRetry(() => import("../pages/ProvinceJahadRequests")) +); + +export const liveStockProvinceJahadRouting = [ + { + path: [ + ROUTE_PROVINCE_JAHAD_UNIONS, + ROUTE_PROVINCE_JAHAD_COOPERATIVES, + ROUTE_PROVINCE_JAHAD_RANCHERS, + ROUTE_PROVINCE_JAHAD_HERDS, + ROUTE_PROVINCE_JAHAD_USERS, + ROUTE_PROVINCE_JAHAD_PRODUCT_DISTRIBUTION, + ROUTE_PROVINCE_JAHAD_PRODUCT_DISTRIBUTION_ALLOCATION, + ROUTE_PROVINCE_JAHAD_PRODUCT_DISTRIBUTION_POLICY, + ROUTE_PROVINCE_JAHAD_PRODUCT_SHARES, + ROUTE_PROVINCE_JAHAD_PRODUCT_TRANSACTIONS, + ROUTE_PROVINCE_JAHAD_SELL_REPORT, + ], + Page: RequestsPage, + exact: false, + props: {}, + }, +]; diff --git a/src/routes/adminRouting.js b/src/routes/adminRouting.js new file mode 100644 index 0000000..054374d --- /dev/null +++ b/src/routes/adminRouting.js @@ -0,0 +1,62 @@ +import { lazy } from "react"; +import { lazyRetry } from "../utils/lazyRetry"; +import { + ROUTE_ADMIN_REQUESTS, + ROUTE_ADMIN_CREATE_NEW_REQUEST, + ROUTE_ADMIN_HATCHING, + ROUTE_ADMIN_NEW_REQUESTS, + ROUTE_ADMIN_REJECTED_REQUESTS, + ROUTE_ADMIN_AWAITING_PAYMENT_REQUESTS, + ROUTE_ADMIN_AWAITING_INSPECTION_REQUESTS, + ROUTE_ADMIN_ARCHIVED_REQUESTS, + ROUTE_ADMIN_ACTIVE_REQUESTS, + ROUTE_ADMIN_STATICS, + ROUTE_ADMIN_VISOR_STATICS, + ROUTE_ADMIN_VISOR_STATICS_CHARTS, + ROUTE_ADMIN_VISOR_STATICS_PREDICTION, +} from "./routes"; + +const Requests = lazy(() => lazyRetry(() => import("../pages/AdminRequests"))); + +const Statics = lazy(() => lazyRetry(() => import("../pages/AdminStatics"))); +const VisorStatics = lazy(() => + lazyRetry(() => import("../pages/VisorStatics")) +); + +// const Requests = lazy(() => import("../pages/AdminRequests")); +// const Statics = lazy(() => import("../pages/AdminStatics")); + +export const adminRouting = [ + { + path: [ + ROUTE_ADMIN_REQUESTS, + ROUTE_ADMIN_CREATE_NEW_REQUEST, + ROUTE_ADMIN_HATCHING, + ROUTE_ADMIN_NEW_REQUESTS, + ROUTE_ADMIN_REJECTED_REQUESTS, + ROUTE_ADMIN_AWAITING_PAYMENT_REQUESTS, + ROUTE_ADMIN_AWAITING_INSPECTION_REQUESTS, + ROUTE_ADMIN_ARCHIVED_REQUESTS, + ROUTE_ADMIN_ACTIVE_REQUESTS, + ], + Page: Requests, + exact: false, + props: {}, + }, + { + path: [ROUTE_ADMIN_STATICS], + Page: Statics, + exact: false, + props: {}, + }, + { + path: [ + ROUTE_ADMIN_VISOR_STATICS, + ROUTE_ADMIN_VISOR_STATICS_PREDICTION, + ROUTE_ADMIN_VISOR_STATICS_CHARTS, + ], + Page: VisorStatics, + exact: false, + props: {}, + }, +]; diff --git a/src/routes/avicultureRouting.js b/src/routes/avicultureRouting.js new file mode 100644 index 0000000..06ea96f --- /dev/null +++ b/src/routes/avicultureRouting.js @@ -0,0 +1,109 @@ +import { lazy } from "react"; +import { lazyRetry } from "../utils/lazyRetry"; +import { + ROUTE_AVICULTURE_ARCHIVED_REQUESTS, + ROUTE_AVICULTURE_AUCTION, + ROUTE_AVICULTURE_CREATE_NEW_REQUEST, + ROUTE_AVICULTURE_FILE_ROUTE, + ROUTE_AVICULTURE_HATCHING, + ROUTE_AVICULTURE_REJECTED_REQUESTS, + ROUTE_AVICULTURE_REQUESTS, + ROUTE_AVICULTURE_ROUTE_HALLS, + ROUTE_AVICULTURE_TICKET, + ROUTE_AVICULTURE_VIEW_TICKET, + ROUTE_AVICULTURE_INSPECTS_ROUTE, + ROUTE_AVICULTURE_AWAITING_PAYMENT_REQUESTS, + ROUTE_AVICULTURE_AWAITING_INSPECTION_REQUESTS, + ROUTE_AVICULTURE_REPORTS, + ROUTE_AVICULTURE_PRICING, + ROUTE_AVICULTURE_SUBMIT_REQUEST, + ROUTE_AVICULTURE_GIVE_PERMISSION, +} from "./routes"; + +// const AvicultureRequests = lazy(() => import("../pages/AvicultureRequests")); +// const NewFile = lazy(() => import("../pages/NewFile")); +// const Inspects = lazy(() => import("../pages/AvicultureHallInspects")); +// const Auction = lazy(() => import("../pages/Auction")); +// const Tickets = lazy(() => import("../pages/Tickets")); +// const Halls = lazy(() => import("../pages/AvicultureHalls")); + +export const avicultureRoutingDefault = "/dashboard/profile"; + +const AvicultureRequests = lazy(() => + lazyRetry(() => import("../pages/AvicultureRequests")) +); +const NewFile = lazy(() => lazyRetry(() => import("../pages/NewFile"))); +const Inspects = lazy(() => + lazyRetry(() => import("../pages/AvicultureHallInspects")) +); +const Auction = lazy(() => lazyRetry(() => import("../pages/Auction"))); +const Tickets = lazy(() => lazyRetry(() => import("../pages/Tickets"))); +const Halls = lazy(() => lazyRetry(() => import("../pages/AvicultureHalls"))); +const Reports = lazy(() => + lazyRetry(() => import("../pages/AvicultureReports")) +); +const AviculturePricing = lazy(() => + lazyRetry(() => import("../pages/ProvinceManagePricing")) +); + +export const avicultureRouting = [ + // requests routes + { + path: [ + ROUTE_AVICULTURE_REQUESTS, + ROUTE_AVICULTURE_HATCHING, + ROUTE_AVICULTURE_CREATE_NEW_REQUEST, + ROUTE_AVICULTURE_REJECTED_REQUESTS, + ROUTE_AVICULTURE_ARCHIVED_REQUESTS, + ROUTE_AVICULTURE_AWAITING_PAYMENT_REQUESTS, + ROUTE_AVICULTURE_AWAITING_INSPECTION_REQUESTS, + ROUTE_AVICULTURE_SUBMIT_REQUEST, + ROUTE_AVICULTURE_GIVE_PERMISSION, + ], + Page: AvicultureRequests, + exact: false, + props: {}, + }, + { + path: [ROUTE_AVICULTURE_AUCTION], + Page: Auction, + exact: false, + props: {}, + }, + { + path: [ROUTE_AVICULTURE_FILE_ROUTE], + Page: NewFile, + exact: false, + props: {}, + }, + { + path: [ROUTE_AVICULTURE_VIEW_TICKET, ROUTE_AVICULTURE_TICKET], + Page: Tickets, + exact: false, + props: {}, + }, + { + path: [ROUTE_AVICULTURE_ROUTE_HALLS], + Page: Halls, + exact: false, + props: {}, + }, + { + path: [ROUTE_AVICULTURE_INSPECTS_ROUTE], + Page: Inspects, + exact: false, + props: {}, + }, + { + path: [ROUTE_AVICULTURE_REPORTS], + Page: Reports, + exact: false, + props: {}, + }, + { + path: [ROUTE_AVICULTURE_PRICING], + Page: AviculturePricing, + exact: false, + props: {}, + }, +]; diff --git a/src/routes/barSquareRouting.js b/src/routes/barSquareRouting.js new file mode 100644 index 0000000..0dd953a --- /dev/null +++ b/src/routes/barSquareRouting.js @@ -0,0 +1,16 @@ +import { lazy } from "react"; +import { lazyRetry } from "../utils/lazyRetry"; +import { ROUTE_BAR_SQUARE_TRANSACTIONS } from "./routes"; + +const SlaughterMorguePage = lazy(() => + lazyRetry(() => import("../pages/BarSquareTransactions")) +); + +export const barSquareRouting = [ + { + path: [ROUTE_BAR_SQUARE_TRANSACTIONS], + Page: SlaughterMorguePage, + exact: false, + props: {}, + }, +]; diff --git a/src/routes/chainCompanyRouting.js b/src/routes/chainCompanyRouting.js new file mode 100644 index 0000000..7526484 --- /dev/null +++ b/src/routes/chainCompanyRouting.js @@ -0,0 +1,37 @@ +import { lazy } from "react"; +import { lazyRetry } from "../utils/lazyRetry"; +import { + ROUTE_CHAIN_COMPANY_MANAGE_BARS, + ROUTE_CHAIN_COMPANY_MANAGE_FEES, + ROUTE_CHAIN_COMPANY_POULTRIES, + ROUTE_CHAIN_COMPANY_POULTRIES_DETAILS, +} from "./routes"; + +const Poultries = lazy(() => lazyRetry(() => import("../pages/ChainCompany"))); + +const Fees = lazy(() => lazyRetry(() => import("../pages/ProvinceFees"))); + +const PoultriesDetails = lazy(() => + lazyRetry(() => import("../pages/PoultriesDetailsPage")) +); + +export const chainCompanyRouting = [ + { + path: [ROUTE_CHAIN_COMPANY_POULTRIES, ROUTE_CHAIN_COMPANY_MANAGE_BARS], + Page: Poultries, + exact: false, + props: {}, + }, + { + path: [ROUTE_CHAIN_COMPANY_MANAGE_FEES], + Page: Fees, + exact: false, + props: {}, + }, + { + path: [ROUTE_CHAIN_COMPANY_POULTRIES_DETAILS], + Page: PoultriesDetails, + exact: false, + props: {}, + }, +]; diff --git a/src/routes/cityCommerceRouting.js b/src/routes/cityCommerceRouting.js new file mode 100644 index 0000000..bd83dc1 --- /dev/null +++ b/src/routes/cityCommerceRouting.js @@ -0,0 +1,42 @@ +import { lazy } from "react"; +import { lazyRetry } from "../utils/lazyRetry"; +import { + ROUTE_CITY_COMMERCE_ROUTE_ALLOCATIONS, + ROUTE_CITY_COMMERCE_ROUTE_FILES_STATE, + ROUTE_CITY_COMMERCE_ROUTE_GUILDS, + ROUTE_CITY_COMMERCE_ROUTE_GUILDS_SETTINGS, + ROUTE_CITY_COMMERCE_ROUTE_MANAGE_GUILDS, + ROUTE_CITY_COMMERCE_ROUTE_STEWARDS, +} from "./routes"; + +const Guilds = lazy(() => lazyRetry(() => import("../pages/Guilds"))); +const FilesState = lazy(() => lazyRetry(() => import("../pages/FilesState"))); +const VetFarmAllocations = lazy(() => + lazyRetry(() => import("../pages/VetFarmAllocations")) +); + +export const cityCommerceRouting = [ + { + path: [ + ROUTE_CITY_COMMERCE_ROUTE_MANAGE_GUILDS, + ROUTE_CITY_COMMERCE_ROUTE_GUILDS, + ROUTE_CITY_COMMERCE_ROUTE_STEWARDS, + ROUTE_CITY_COMMERCE_ROUTE_GUILDS_SETTINGS, + ], + Page: Guilds, + exact: false, + props: {}, + }, + { + path: [ROUTE_CITY_COMMERCE_ROUTE_FILES_STATE], + Page: FilesState, + exact: false, + props: {}, + }, + { + path: [ROUTE_CITY_COMMERCE_ROUTE_ALLOCATIONS], + Page: VetFarmAllocations, + exact: false, + props: {}, + }, +]; diff --git a/src/routes/cityGuildRouting.js b/src/routes/cityGuildRouting.js new file mode 100644 index 0000000..8f02fe2 --- /dev/null +++ b/src/routes/cityGuildRouting.js @@ -0,0 +1,16 @@ +import { lazy } from "react"; +import { lazyRetry } from "../utils/lazyRetry"; +import { ROUTE_SENF_INVENTORY, ROUTE_SENF_INVENTORY_STOCK } from "./routes"; + +const SenfInventoryPage = lazy(() => + lazyRetry(() => import("../pages/SenfInventoryPage")) +); + +export const cityGuildRouting = [ + { + path: [ROUTE_SENF_INVENTORY, ROUTE_SENF_INVENTORY_STOCK], + Page: SenfInventoryPage, + exact: false, + props: {}, + }, +]; diff --git a/src/routes/cityJihadRouting.js b/src/routes/cityJihadRouting.js new file mode 100644 index 0000000..bb67c5e --- /dev/null +++ b/src/routes/cityJihadRouting.js @@ -0,0 +1,79 @@ +import { lazy } from "react"; +import { lazyRetry } from "../utils/lazyRetry"; +import { + ROUTE_CITY_JIHAD_DISPENSER_DETAILS_VIEW, + ROUTE_CITY_JIHAD_DISPENSERS, + ROUTE_CITY_JIHAD_DISPENSERS_INVENTORY, + ROUTE_CITY_JIHAD_DISPENSERS_KILLHOUSES, + ROUTE_CITY_JIHAD_DISPENSERS_MANAGEMENT, + ROUTE_CITY_JIHAD_DISPENSERS_SELL_CARCASS, + ROUTE_CITY_JIHAD_DISPENSERS_STEWARDS, + ROUTE_CITY_JIHAD_HATCHINGS_DETAILS, + ROUTE_CITY_JIHAD_ROUTE_ALLOCATIONS, + ROUTE_CITY_JIHAD_ROUTE_FILES_STATE, + // ROUTE_CITY_JIHAD_ROUTE_GUILDS, + // ROUTE_CITY_JIHAD_ROUTE_GUILDS_SETTINGS, + // ROUTE_CITY_JIHAD_ROUTE_MANAGE_GUILDS, + // ROUTE_CITY_JIHAD_ROUTE_STEWARDS, + ROUTE_CITY_JIHAD_SALE_DESTRIBUTION_DETAILS, + ROUTE_CITY_JIHAD_STATICS, + ROUTE_CITY_JIHADـHATCHINGS, +} from "./routes"; + +const Statics = lazy(() => lazyRetry(() => import("../pages/AdminStatics"))); +const FilesState = lazy(() => lazyRetry(() => import("../pages/FilesState"))); +const VetFarmAllocations = lazy(() => + lazyRetry(() => import("../pages/VetFarmAllocations")) +); +const Dispensers = lazy(() => + lazyRetry(() => import("../pages/SlaughterHouseDispenserDashboard")) +); + +const AllHatchings = lazy(() => + lazyRetry(() => import("../pages/AdminHatchings")) +); + +export const cityJihadRouting = [ + { + path: [ROUTE_CITY_JIHAD_STATICS], + Page: Statics, + exact: false, + props: {}, + }, + { + path: [ROUTE_CITY_JIHAD_ROUTE_FILES_STATE], + Page: FilesState, + exact: false, + props: {}, + }, + { + path: [ROUTE_CITY_JIHAD_ROUTE_ALLOCATIONS], + Page: VetFarmAllocations, + exact: false, + props: {}, + }, + { + path: [ + ROUTE_CITY_JIHAD_DISPENSERS, + ROUTE_CITY_JIHAD_DISPENSERS_MANAGEMENT, + ROUTE_CITY_JIHAD_DISPENSER_DETAILS_VIEW, + ROUTE_CITY_JIHAD_DISPENSER_DETAILS_VIEW, + ROUTE_CITY_JIHAD_DISPENSERS_STEWARDS, + ROUTE_CITY_JIHAD_DISPENSERS_KILLHOUSES, + ROUTE_CITY_JIHAD_DISPENSER_DETAILS_VIEW, + ROUTE_CITY_JIHAD_DISPENSERS_SELL_CARCASS, + ROUTE_CITY_JIHAD_DISPENSERS_INVENTORY, + ROUTE_CITY_JIHAD_SALE_DESTRIBUTION_DETAILS, + ], + Page: Dispensers, + exact: false, + props: {}, + }, + { + path: [ROUTE_CITY_JIHADـHATCHINGS, ROUTE_CITY_JIHAD_HATCHINGS_DETAILS], + Page: AllHatchings, + + exact: false, + props: {}, + }, +]; diff --git a/src/routes/cityPoultryRouting.js b/src/routes/cityPoultryRouting.js new file mode 100644 index 0000000..a5d4ac3 --- /dev/null +++ b/src/routes/cityPoultryRouting.js @@ -0,0 +1,116 @@ +import { lazy } from "react"; +import { lazyRetry } from "../utils/lazyRetry"; +import { + ROUTE_CITY_DISPENSERS, + ROUTE_CITY_DISPENSERS_INVENTORY, + ROUTE_CITY_POULTRY_HATCHING, + ROUTE_CITY_POULTRY_ROUTE_ALLOCATIONS, + ROUTE_CITY_POULTRY_ROUTE_FILES_STATE, + ROUTE_CITY_POULTRY_ROUTE_GUILDS, + ROUTE_CITY_POULTRY_ROUTE_GUILDS_SETTINGS, + ROUTE_CITY_POULTRY_ROUTE_MANAGE_GUILDS, + ROUTE_CITY_POULTRY_ROUTE_STEWARDS, + ROUTE_CITY_POULTRY_STATICS, + ROUTE_CITY_POULTRYـHATCHINGS, + ROUTE_CITY_POULTRYـHATCHINGS_DETAILS, + ROUTE_CITY_REQUEST_DISTRIBUTION, + ROUTE_CITY_REQUEST_TRANSACTION_DETAILS, + ROUTE_CITY_REQUEST_TRANSACTIONS, +} from "./routes"; + +const Statics = lazy(() => lazyRetry(() => import("../pages/AdminStatics"))); +const FilesState = lazy(() => lazyRetry(() => import("../pages/FilesState"))); +const VetFarmAllocations = lazy(() => + lazyRetry(() => import("../pages/VetFarmAllocations")) +); +const Guilds = lazy(() => lazyRetry(() => import("../pages/Guilds"))); + +const Hatching = lazy(() => + lazyRetry(() => import("../pages/OperatorNewHatching")) +); + +const AllHatchings = lazy(() => + lazyRetry(() => import("../pages/AdminHatchings")) +); + +const TransactionsPage = lazy(() => + lazyRetry(() => import("../pages/Transactions")) +); + +const SlaughterHouseDispenserDashboard = lazy(() => + lazyRetry(() => import("../pages/SlaughterHouseDispenserDashboard")) +); + +export const cityPoultryRouting = [ + { + path: [ROUTE_CITY_POULTRY_STATICS], + Page: Statics, + exact: false, + props: {}, + }, + { + path: [ROUTE_CITY_POULTRY_ROUTE_FILES_STATE], + Page: FilesState, + exact: false, + props: {}, + }, + { + path: [ROUTE_CITY_POULTRY_ROUTE_ALLOCATIONS], + Page: VetFarmAllocations, + exact: false, + props: {}, + }, + { + path: [ + ROUTE_CITY_POULTRY_ROUTE_MANAGE_GUILDS, + ROUTE_CITY_POULTRY_ROUTE_GUILDS, + ROUTE_CITY_POULTRY_ROUTE_STEWARDS, + ROUTE_CITY_POULTRY_ROUTE_GUILDS_SETTINGS, + ], + Page: Guilds, + exact: false, + props: {}, + }, + { + path: [ROUTE_CITY_POULTRY_HATCHING], + Page: Hatching, + exact: false, + props: {}, + }, + { + path: [ROUTE_CITY_POULTRYـHATCHINGS, ROUTE_CITY_POULTRYـHATCHINGS_DETAILS], + Page: AllHatchings, + exact: false, + props: {}, + }, + { + path: [ROUTE_CITY_REQUEST_TRANSACTIONS], + Page: TransactionsPage, + exact: false, + props: {}, + }, + { + path: [ROUTE_CITY_DISPENSERS_INVENTORY], + Page: SlaughterHouseDispenserDashboard, + exact: false, + props: {}, + }, + { + path: [ROUTE_CITY_REQUEST_DISTRIBUTION], + Page: SlaughterHouseDispenserDashboard, + exact: false, + props: {}, + }, + { + path: [ROUTE_CITY_DISPENSERS], + Page: SlaughterHouseDispenserDashboard, + exact: false, + props: {}, + }, + { + path: [ROUTE_CITY_REQUEST_TRANSACTION_DETAILS], + Page: TransactionsPage, + exact: false, + props: {}, + }, +]; diff --git a/src/routes/cityRouting.js b/src/routes/cityRouting.js new file mode 100644 index 0000000..8c8d0fa --- /dev/null +++ b/src/routes/cityRouting.js @@ -0,0 +1,202 @@ +import { lazy } from "react"; +import { lazyRetry } from "../utils/lazyRetry"; +import { + ROUTE_CITY_ACTIVE_REQUESTS, + ROUTE_CITY_ARCHIVED_REQUESTS, + ROUTE_CITY_REJECTED_REQUESTS, + ROUTE_CITY_REQUESTS, + ROUTE_CITY_POULTRY_FARMS, + ROUTE_CITY_FILE_ROUTE, + ROUTE_CITY_VIEW_TICKET, + ROUTE_CITY_TICKET, + ROUTE_CITY_USER_MANAGEMENT, + ROUTE_CITY_USER_FILE_ROUTE, + ROUTE_CITY_AWAITING_PAYMENT_REQUESTS, + ROUTE_CITY_AWAITING_INSPECTION_REQUESTS, + ROUTE_CITY_STATICS, + ROUTE_CITY_HATCHING, + ROUTE_CITY_NEW_REQUEST, + ROUTE_CITY_PRICING, + ROUTE_CITY_NEW_REQUESTS, + ROUTE_CITY_ROUTE_ALLOCATIONS, + ROUTE_CITY_ROUTE_FILES_STATE, + ROUTE_CITY_POULTRIES, + ROUTE_CITY_FREE_SALES_REQUESTS, + ROUTE_CITY_VISOR_STATICS, + ROUTE_CITYـHATCHINGS, + ROUTE_CITY_VISOR_STATICS_CHARTS, + ROUTE_CITY_VISOR_STATICS_PREDICTION, + ROUTE_CITY_VISOR_STATICS_PREDICTION_VIEW, + ROUTE_CITY_DIFFRENCE_KILLER_SLAUGHTER, + ROUTE_CITY_DIFFRENCE_KILLER, + ROUTE_CITY_INCREASE_HATCHING, + ROUTE_CITY_VISOR_STATICSـHATCHINGS_DETAILS, + ROUTE_CITY_POULTRIES_DETAILS, +} from "./routes"; + +const CityRequests = lazy(() => + lazyRetry(() => import("../pages/CityRequests")) +); +const CityAvicultureManagement = lazy(() => + lazyRetry(() => import("../pages/CityAvicultureManagement")) +); +// const File = lazy(() => import("../pages/File")); +const NewFile = lazy(() => lazyRetry(() => import("../pages/NewFile"))); +const Tickets = lazy(() => lazyRetry(() => import("../pages/Tickets"))); +const UserManagement = lazy(() => + lazyRetry(() => import("../pages/CityUserManagement")) +); +const UserFile = lazy(() => lazyRetry(() => import("../pages/CityUserFile"))); +const Poultries = lazy(() => lazyRetry(() => import("../pages/Poultries"))); +const Statics = lazy(() => lazyRetry(() => import("../pages/AdminStatics"))); + +const Hatching = lazy(() => + lazyRetry(() => import("../pages/OperatorNewHatching")) +); + +const CityPricing = lazy(() => + lazyRetry(() => import("../pages/ProvinceManagePricing")) +); + +const VetFarmAllocations = lazy(() => + lazyRetry(() => import("../pages/VetFarmAllocations")) +); + +const FilesState = lazy(() => lazyRetry(() => import("../pages/FilesState"))); + +const VisorStatics = lazy(() => + lazyRetry(() => import("../pages/VisorStatics")) +); + +const AllHatchings = lazy(() => + lazyRetry(() => import("../pages/AdminHatchings")) +); +const DiffrenceKiller = lazy(() => + lazyRetry(() => import("../pages/DiffrenceKillerPage")) +); +const PoultriesDetails = lazy(() => + lazyRetry(() => import("../pages/PoultriesDetailsPage")) +); + +export const cityRouting = [ + { + path: [ + ROUTE_CITY_REQUESTS, + ROUTE_CITY_ACTIVE_REQUESTS, + ROUTE_CITY_REJECTED_REQUESTS, + ROUTE_CITY_ARCHIVED_REQUESTS, + ROUTE_CITY_AWAITING_PAYMENT_REQUESTS, + ROUTE_CITY_AWAITING_INSPECTION_REQUESTS, + ROUTE_CITY_NEW_REQUESTS, + ROUTE_CITY_FREE_SALES_REQUESTS, + ], + Page: CityRequests, + exact: false, + props: {}, + }, + { + path: [ROUTE_CITYـHATCHINGS, ROUTE_CITY_VISOR_STATICSـHATCHINGS_DETAILS], + Page: AllHatchings, + exact: false, + props: {}, + }, + { + path: [ROUTE_CITY_FILE_ROUTE], + Page: NewFile, + exact: false, + props: {}, + }, + { + path: [ROUTE_CITY_POULTRY_FARMS], + Page: CityAvicultureManagement, + exact: false, + props: {}, + }, + { + path: [ROUTE_CITY_VIEW_TICKET, ROUTE_CITY_TICKET], + Page: Tickets, + exact: false, + props: {}, + }, + { + path: [ROUTE_CITY_VIEW_TICKET, ROUTE_CITY_TICKET], + Page: Tickets, + exact: false, + props: {}, + }, + { + path: [ROUTE_CITY_USER_MANAGEMENT], + Page: UserManagement, + exact: false, + props: {}, + }, + { + path: [ROUTE_CITY_USER_FILE_ROUTE], + Page: UserFile, + exact: false, + props: {}, + }, + { + path: [ROUTE_CITY_STATICS], + Page: Statics, + exact: false, + props: {}, + }, + { + path: [ROUTE_CITY_POULTRIES], + Page: Poultries, + exact: false, + props: {}, + }, + { + path: [ROUTE_CITY_HATCHING, ROUTE_CITY_NEW_REQUEST], + Page: Hatching, + exact: false, + props: {}, + }, + { + path: [ROUTE_CITY_PRICING], + Page: CityPricing, + exact: false, + props: {}, + }, + { + path: [ROUTE_CITY_ROUTE_ALLOCATIONS], + Page: VetFarmAllocations, + exact: false, + props: {}, + }, + { + path: [ROUTE_CITY_ROUTE_FILES_STATE], + Page: FilesState, + exact: false, + props: {}, + }, + { + path: [ + ROUTE_CITY_VISOR_STATICS, + ROUTE_CITY_VISOR_STATICS_CHARTS, + ROUTE_CITY_VISOR_STATICS_PREDICTION, + ROUTE_CITY_VISOR_STATICS_PREDICTION_VIEW, + ], + Page: VisorStatics, + exact: false, + props: {}, + }, + { + path: [ + ROUTE_CITY_DIFFRENCE_KILLER, + ROUTE_CITY_DIFFRENCE_KILLER_SLAUGHTER, + ROUTE_CITY_INCREASE_HATCHING, + ], + Page: DiffrenceKiller, + exact: false, + props: {}, + }, + { + path: [ROUTE_CITY_POULTRIES_DETAILS], + Page: PoultriesDetails, + exact: false, + props: {}, + }, +]; diff --git a/src/routes/cityVetRouting.js b/src/routes/cityVetRouting.js new file mode 100644 index 0000000..85bed40 --- /dev/null +++ b/src/routes/cityVetRouting.js @@ -0,0 +1,65 @@ +import { lazy } from "react"; +import { lazyRetry } from "../utils/lazyRetry"; +import { + ROUTE_CITYVET_HATCHING, + ROUTE_CITYVET_REGISTER_INFO, + ROUTE_CITYVET_ROUTE_ALLOCATIONS, + ROUTE_STEWARD_INVENTORY, + ROUTE_STEWARD_SALE_IN_PROVINCE, + ROUTE_STEWARD_INVENTORY_STOCK, + ROUTE_JAHAD_FILES_STATE, + ROUTE_STEWARD_PURCHASE_OUT_PROVINCE, + ROUTE_STEWARD_SALE_OUT_PROVINCE, + ROUTE_STEWARD_SEGMENT, +} from "./routes"; +const FilesState = lazy(() => lazyRetry(() => import("../pages/FilesState"))); + +const StewardInventoryPage = lazy(() => + lazyRetry(() => import("../pages/StewardInventoryPage")) +); +const VetFarmAllocations = lazy(() => + lazyRetry(() => import("../pages/VetFarmAllocations")) +); +const Hatching = lazy(() => lazyRetry(() => import("../pages/Hatching"))); + +const VetFarm = lazy(() => lazyRetry(() => import("../pages/VetFarm"))); + +export const cityVetRouting = [ + { + path: [ROUTE_CITYVET_HATCHING], + Page: Hatching, + exact: false, + props: {}, + }, + { + path: [ROUTE_CITYVET_REGISTER_INFO], + Page: VetFarm, + exact: false, + props: {}, + }, + { + path: [ROUTE_JAHAD_FILES_STATE], + Page: FilesState, + exact: false, + props: {}, + }, + { + path: [ + ROUTE_STEWARD_INVENTORY, + ROUTE_STEWARD_SALE_IN_PROVINCE, + ROUTE_STEWARD_INVENTORY_STOCK, + ROUTE_STEWARD_SALE_OUT_PROVINCE, + ROUTE_STEWARD_PURCHASE_OUT_PROVINCE, + ROUTE_STEWARD_SEGMENT, + ], + Page: StewardInventoryPage, + exact: false, + props: {}, + }, + { + path: [ROUTE_CITYVET_ROUTE_ALLOCATIONS], + Page: VetFarmAllocations, + exact: false, + props: {}, + }, +]; diff --git a/src/routes/coldHouseStewardRouting.js b/src/routes/coldHouseStewardRouting.js new file mode 100644 index 0000000..6fc74b4 --- /dev/null +++ b/src/routes/coldHouseStewardRouting.js @@ -0,0 +1,16 @@ +import { lazy } from "react"; +import { lazyRetry } from "../utils/lazyRetry"; +import { ROUTE_COLD_HOUSE_STEWARD_MORGUE } from "./routes"; + +const SlaughterMorguePage = lazy(() => + lazyRetry(() => import("../pages/SlaughterMorgue")) +); + +export const coldHouseStewardRouting = [ + { + path: [ROUTE_COLD_HOUSE_STEWARD_MORGUE], + Page: SlaughterMorguePage, + exact: false, + props: {}, + }, +]; diff --git a/src/routes/commerceRouting.js b/src/routes/commerceRouting.js new file mode 100644 index 0000000..2af2dba --- /dev/null +++ b/src/routes/commerceRouting.js @@ -0,0 +1,87 @@ +import { lazy } from "react"; +import { lazyRetry } from "../utils/lazyRetry"; +import { + ROUTE_COMMERCE_ROUTE_ALLOCATIONS, + ROUTE_COMMERCE_ROUTE_FILES_STATE, + ROUTE_COMMERCE_ROUTE_GUILDS, + ROUTE_COMMERCE_ROUTE_GUILDS_SETTINGS, + ROUTE_COMMERCE_ROUTE_MANAGE_GUILDS, + ROUTE_COMMERCE_ROUTE_STEWARDS, + ROUTE_COMMERCE_STATICS, + ROUTE_COMMERCE_REQUESTS, + ROUTE_COMMERCE_HATCHING, + ROUTE_COMMERCE_VISOR_STATICS, + ROUTE_COMMERCE_VISOR_STATICS_CHARTS, + ROUTE_COMMERCE_VISOR_STATICS_PREDICTION, + ROUTE_COMMERCE_VISOR_STATICS_PREDICTION_VIEW, +} from "./routes"; + +const Guilds = lazy(() => lazyRetry(() => import("../pages/Guilds"))); +const FilesState = lazy(() => lazyRetry(() => import("../pages/FilesState"))); +const VetFarmAllocations = lazy(() => + lazyRetry(() => import("../pages/VetFarmAllocations")) +); +const Statics = lazy(() => lazyRetry(() => import("../pages/AdminStatics"))); + +const Commerce = lazy(() => lazyRetry(() => import("../pages/Commerce"))); + +const Hatching = lazy(() => lazyRetry(() => import("../pages/Hatching"))); + +const VisorStatics = lazy(() => + lazyRetry(() => import("../pages/VisorStatics")) +); + +export const commerceRouting = [ + { + path: [ROUTE_COMMERCE_REQUESTS], + Page: Commerce, + exact: false, + props: {}, + }, + { + path: [ + ROUTE_COMMERCE_ROUTE_MANAGE_GUILDS, + ROUTE_COMMERCE_ROUTE_GUILDS, + ROUTE_COMMERCE_ROUTE_STEWARDS, + ROUTE_COMMERCE_ROUTE_GUILDS_SETTINGS, + ], + Page: Guilds, + exact: false, + props: {}, + }, + { + path: [ROUTE_COMMERCE_ROUTE_FILES_STATE], + Page: FilesState, + exact: false, + props: {}, + }, + { + path: [ROUTE_COMMERCE_ROUTE_ALLOCATIONS], + Page: VetFarmAllocations, + exact: false, + props: {}, + }, + { + path: [ROUTE_COMMERCE_STATICS], + Page: Statics, + exact: false, + props: {}, + }, + { + path: [ROUTE_COMMERCE_HATCHING], + Page: Hatching, + exact: false, + props: {}, + }, + { + path: [ + ROUTE_COMMERCE_VISOR_STATICS, + ROUTE_COMMERCE_VISOR_STATICS_PREDICTION, + ROUTE_COMMERCE_VISOR_STATICS_PREDICTION_VIEW, + ROUTE_COMMERCE_VISOR_STATICS_CHARTS, + ], + Page: VisorStatics, + exact: false, + props: {}, + }, +]; diff --git a/src/routes/cooperativeRouting.js b/src/routes/cooperativeRouting.js new file mode 100644 index 0000000..2b5c570 --- /dev/null +++ b/src/routes/cooperativeRouting.js @@ -0,0 +1,32 @@ +import { lazy } from "react"; +import { lazyRetry } from "../utils/lazyRetry"; +import { + ROUTE_COOPERATIVE_PRODUCT_DISTRIBUTION, + ROUTE_COOPERATIVE_PRODUCT_DISTRIBUTION_ALLOCATION, + ROUTE_COOPERATIVE_PRODUCT_DISTRIBUTION_POLICY, + ROUTE_COOPERATIVE_PRODUCT_TRANSACTIONS, + ROUTE_COOPERATIVE_HERDS, + ROUTE_COOPERATIVE_RANCHERS, + ROUTE_COOPERATIVE_USERS, +} from "./routes"; + +const RequestsPage = lazy(() => + lazyRetry(() => import("../pages/ProvinceJahadRequests")) +); + +export const cooperativeRouting = [ + { + path: [ + ROUTE_COOPERATIVE_RANCHERS, + ROUTE_COOPERATIVE_HERDS, + ROUTE_COOPERATIVE_USERS, + ROUTE_COOPERATIVE_PRODUCT_DISTRIBUTION, + ROUTE_COOPERATIVE_PRODUCT_DISTRIBUTION_ALLOCATION, + ROUTE_COOPERATIVE_PRODUCT_DISTRIBUTION_POLICY, + ROUTE_COOPERATIVE_PRODUCT_TRANSACTIONS, + ], + Page: RequestsPage, + exact: false, + props: {}, + }, +]; diff --git a/src/routes/dispenserRouting.js b/src/routes/dispenserRouting.js new file mode 100644 index 0000000..6fb0070 --- /dev/null +++ b/src/routes/dispenserRouting.js @@ -0,0 +1,16 @@ +import { lazy } from "react"; +import { lazyRetry } from "../utils/lazyRetry"; +import { ROUTE_DISPENSER_DASHBOARD } from "./routes"; + +const Dashboard = lazy(() => + lazyRetry(() => import("../pages/DispenserDashboard")) +); + +export const dispenserRouting = [ + { + path: [ROUTE_DISPENSER_DASHBOARD], + Page: Dashboard, + exact: false, + props: {}, + }, +]; diff --git a/src/routes/driverRouting.js b/src/routes/driverRouting.js new file mode 100644 index 0000000..e5ab627 --- /dev/null +++ b/src/routes/driverRouting.js @@ -0,0 +1,14 @@ +import { lazy } from "react"; +import { lazyRetry } from "../utils/lazyRetry"; +import { ROUTE_DRIVER_CARS, ROUTE_DRIVER_REQUESTS } from "./routes"; + +const Driver = lazy(() => lazyRetry(() => import("../pages/Driver"))); + +export const driverRouting = [ + { + path: [ROUTE_DRIVER_REQUESTS, ROUTE_DRIVER_CARS], + Page: Driver, + exact: false, + props: {}, + }, +]; diff --git a/src/routes/generalRouting.js b/src/routes/generalRouting.js new file mode 100644 index 0000000..7a5a6aa --- /dev/null +++ b/src/routes/generalRouting.js @@ -0,0 +1,117 @@ +import { PropTypes } from "prop-types"; +import { lazy } from "react"; +import { lazyRetry } from "../utils/lazyRetry"; +import { + ROUTE_AVICULTURE_USER_PROFILE, + ROUTE_CITY_USER_PROFILE, + ROUTE_GENERAL_SUPPORT, + ROUTE_GENERAL_USER_PROFILE, + ROUTE_PROVINCE_USER_PROFILE, + ROUTE_SLAUGHTER_USER_PROFILE, + ROUTE_VETFARM_USER_PROFILE, + DRIVER_USER_PROFILE, + ROUTE_GENERAL_MESSAGES, + ROUTE_INSPECTOR_USER_PROFILE, + ROUTE_PROVINCE_FINANCIAL_USER_PROFILE, + ROUTE_SLAUGHTER_HOUSE_VET_USER_PROFILE, + ROUTE_GENERAL_TRAINING, + ROUTE_STEWARD_USER_PROFILE, + ROUTE_CITYVET_USER_PROFILE, + ROUTE_LIVE_STOCK_USER_PROFILE, + ROUTE_GENERAL_PAYMENT, + ROUTE_CHAIN_COMPANY_USER_PROFILE, + ROUTE_GENERAL_WAGE_PAYMENT, + ROUTE_GENERAL_DOWNLOAD_REPORT, + ROUTE_GENERAL_TICKET_LIST, + ROUTE_GENERAL_TICKET, +} from "./routes"; + +const Test = ({ testProp }) => { + return

    home {testProp}

    ; +}; + +Test.propTypes = { + testProp: PropTypes.any, + // testProp: PropTypes.func, +}; + +// use lazy for import components +const Support = lazy(() => lazyRetry(() => import("../pages/Support"))); +const GeneralDashboard = lazy(() => + lazyRetry(() => import("../pages/GeneralDashboard")) +); +const Messages = lazy(() => import("../pages/Messages")); +const Training = lazy(() => import("../pages/Training")); +const Payment = lazy(() => import("../pages/Payment")); +const WagePayment = lazy(() => lazyRetry(() => import("../pages/WagePayment"))); +const DownloadReport = lazy(() => + lazyRetry(() => import("../pages/DownloadReport")) +); +const Ticket = lazy(() => import("../pages/Tickets")); + +export const generalRouting = [ + { + path: [ + ROUTE_GENERAL_USER_PROFILE, + ROUTE_AVICULTURE_USER_PROFILE, + ROUTE_CITY_USER_PROFILE, + ROUTE_SLAUGHTER_USER_PROFILE, + ROUTE_PROVINCE_USER_PROFILE, + ROUTE_INSPECTOR_USER_PROFILE, + ROUTE_VETFARM_USER_PROFILE, + ROUTE_PROVINCE_FINANCIAL_USER_PROFILE, + ROUTE_SLAUGHTER_HOUSE_VET_USER_PROFILE, + ROUTE_STEWARD_USER_PROFILE, + DRIVER_USER_PROFILE, + ROUTE_CITYVET_USER_PROFILE, + ROUTE_LIVE_STOCK_USER_PROFILE, + ROUTE_CHAIN_COMPANY_USER_PROFILE, + "/", + ], + Page: GeneralDashboard, + exact: false, + props: {}, + }, + { + path: [ROUTE_GENERAL_TICKET_LIST, ROUTE_GENERAL_TICKET], + Page: Ticket, + exact: false, + props: {}, + }, + { + path: [ROUTE_GENERAL_SUPPORT], + Page: Support, + exact: false, + props: {}, + }, + { + path: [ROUTE_GENERAL_MESSAGES], + Page: Messages, + exact: false, + props: {}, + }, + { + path: [ROUTE_GENERAL_TRAINING], + Page: Training, + exact: false, + props: {}, + }, + { + path: [ROUTE_GENERAL_PAYMENT], + Page: Payment, + exact: false, + props: {}, + }, + { + path: [ROUTE_GENERAL_WAGE_PAYMENT], + Page: WagePayment, + exact: false, + props: {}, + }, + { + path: [ROUTE_GENERAL_DOWNLOAD_REPORT], + Page: DownloadReport, + exact: false, + props: {}, + }, +]; diff --git a/src/routes/guestRouting.js b/src/routes/guestRouting.js new file mode 100644 index 0000000..442c4e3 --- /dev/null +++ b/src/routes/guestRouting.js @@ -0,0 +1,51 @@ +// import { Login } from "../features/authentication/components/login/Login"; +import { lazy } from "react"; +import { lazyRetry } from "../utils/lazyRetry"; +import { + ROUTE_GENERAL_DOWNLOAD_REPORT, + ROUTE_GENERAL_SUPPORT, + ROUTE_GENERAL_WAGE_PAYMENT, +} from "./routes"; + +const Auth = lazy(() => lazyRetry(() => import("../pages/Auth"))); +// const TokenLogin = lazy(() => lazyRetry(() => import("../pages/TokenLogin"))); +const Support = lazy(() => lazyRetry(() => import("../pages/Support"))); +const WagePayment = lazy(() => lazyRetry(() => import("../pages/WagePayment"))); +const DownloadReport = lazy(() => + lazyRetry(() => import("../pages/DownloadReport")) +); + +// use lazy for import components + +export const guestRouting = [ + { + path: ["/"], + Page: Auth, + exact: false, + props: {}, + }, + // { + // path: ["/:token"], + // Page: TokenLogin, + // exact: false, + // props: {}, + // }, + { + path: [ROUTE_GENERAL_SUPPORT], + Page: Support, + exact: false, + props: {}, + }, + { + path: [ROUTE_GENERAL_WAGE_PAYMENT], + Page: WagePayment, + exact: false, + props: {}, + }, + { + path: [ROUTE_GENERAL_DOWNLOAD_REPORT], + Page: DownloadReport, + exact: false, + props: {}, + }, +]; diff --git a/src/routes/guildRoomRouting.js b/src/routes/guildRoomRouting.js new file mode 100644 index 0000000..fc692a7 --- /dev/null +++ b/src/routes/guildRoomRouting.js @@ -0,0 +1,26 @@ +import { lazy } from "react"; +import { lazyRetry } from "../utils/lazyRetry"; +import { + ROUTE_GUILD_ROOM_ROUTE_MANAGE_GUILDS, + ROUTE_GUILD_ROOM_ROUTE_GUILDS_REQUESTS, + ROUTE_GUILD_ROOM_ROUTE_GUILDS, + ROUTE_GUILD_ROOM_ROUTE_STEWARDS, + // ROUTE_GUILD_ROOM_ROUTE_GUILDS_SETTINGS, +} from "./routes"; + +const ManageGuilds = lazy(() => lazyRetry(() => import("../pages/Guilds"))); + +export const guildRoomRouting = [ + { + path: [ + ROUTE_GUILD_ROOM_ROUTE_MANAGE_GUILDS, + ROUTE_GUILD_ROOM_ROUTE_GUILDS_REQUESTS, + ROUTE_GUILD_ROOM_ROUTE_GUILDS, + ROUTE_GUILD_ROOM_ROUTE_STEWARDS, + // ROUTE_GUILD_ROOM_ROUTE_GUILDS_SETTINGS, + ], + Page: ManageGuilds, + exact: false, + props: {}, + }, +]; diff --git a/src/routes/inspectorRouting.js b/src/routes/inspectorRouting.js new file mode 100644 index 0000000..de8bec3 --- /dev/null +++ b/src/routes/inspectorRouting.js @@ -0,0 +1,117 @@ +import { lazy } from "react"; +import { lazyRetry } from "../utils/lazyRetry"; +import { + ROUTE_INSPECTOR_ARCHIVED_REQUESTS, + ROUTE_INSPECTOR_FILE_ROUTE, + ROUTE_INSPECTOR_REJECTED_REQUESTS, + ROUTE_INSPECTOR_REQUESTS, + ROUTE_INSPECTOR_REQUESTS_NEW_REQUESTS, + ROUTE_PROVINCE_CAR_MANAGEMENT, + ROUTE_PROVINCE_INSPECTOR_REPORTING, + ROUTE_PROVINCE_INSPECTOR_TICKET, + ROUTE_PROVINCE_INSPECTOR_VIEW_TICKET, + ROUTE_PROVINCE_USER_FILE_ROUTE, + ROUTE_PROVINCE_USER_MANAGEMENT, + ROUTE_PROVINCE_INSPECTOR_AWAITING_PAYMENT_REQUESTS, + ROUTE_PROVINCE_INSPECTOR_AWAITING_INSPECTION_REQUESTS, + ROUTE_INSPECTOR_STATICS, + ROUTE_PROVINCE_INSPECTOR_PRICING, + ROUTE_INSPECTOR_ASSIGN_VET_FARM, +} from "./routes"; + +const Inspector = lazy(() => lazyRetry(() => import("../pages/Inspector"))); +// const File = lazy(() => import("../pages/File")); +const NewFile = lazy(() => lazyRetry(() => import("../pages/NewFile"))); +const CarManagement = lazy(() => + lazyRetry(() => import("../pages/CarManagement")) +); +const UserManagement = lazy(() => + lazyRetry(() => import("../pages/ProvinceUserManagement")) +); +const UserFile = lazy(() => + lazyRetry(() => import("../pages/ProvinceUserFile")) +); +const Tickets = lazy(() => lazyRetry(() => import("../pages/Tickets"))); +const Reporting = lazy(() => + lazyRetry(() => import("../pages/InspectorReporting")) +); +const Statics = lazy(() => lazyRetry(() => import("../pages/AdminStatics"))); + +const InspectorPricing = lazy(() => + lazyRetry(() => import("../pages/ProvinceManagePricing")) +); +const ManageFarm = lazy(() => lazyRetry(() => import("../pages/ManageFarm"))); + +export const inspectorRouting = [ + { + path: [ + ROUTE_INSPECTOR_REQUESTS, + ROUTE_INSPECTOR_REJECTED_REQUESTS, + ROUTE_INSPECTOR_REQUESTS_NEW_REQUESTS, + ROUTE_INSPECTOR_ARCHIVED_REQUESTS, + ROUTE_PROVINCE_INSPECTOR_AWAITING_PAYMENT_REQUESTS, + ROUTE_PROVINCE_INSPECTOR_AWAITING_INSPECTION_REQUESTS, + ], + Page: Inspector, + exact: false, + props: {}, + }, + { + path: [ROUTE_INSPECTOR_FILE_ROUTE], + Page: NewFile, + exact: false, + props: {}, + }, + { + path: [ROUTE_PROVINCE_CAR_MANAGEMENT], + Page: CarManagement, + exact: false, + props: {}, + }, + + { + path: [ROUTE_PROVINCE_USER_MANAGEMENT], + Page: UserManagement, + exact: false, + props: {}, + }, + { + path: [ROUTE_INSPECTOR_ASSIGN_VET_FARM], + Page: ManageFarm, + exact: false, + props: {}, + }, + { + path: [ROUTE_PROVINCE_USER_FILE_ROUTE], + Page: UserFile, + exact: false, + props: {}, + }, + { + path: [ + ROUTE_PROVINCE_INSPECTOR_VIEW_TICKET, + ROUTE_PROVINCE_INSPECTOR_TICKET, + ], + Page: Tickets, + exact: false, + props: {}, + }, + { + path: [ROUTE_PROVINCE_INSPECTOR_REPORTING], + Page: Reporting, + exact: false, + props: {}, + }, + { + path: [ROUTE_INSPECTOR_STATICS], + Page: Statics, + exact: false, + props: {}, + }, + { + path: [ROUTE_PROVINCE_INSPECTOR_PRICING], + Page: InspectorPricing, + exact: false, + props: {}, + }, +]; diff --git a/src/routes/jahadRouting.js b/src/routes/jahadRouting.js new file mode 100644 index 0000000..0b42cf7 --- /dev/null +++ b/src/routes/jahadRouting.js @@ -0,0 +1,47 @@ +import { lazy } from "react"; +import { lazyRetry } from "../utils/lazyRetry"; +import { + ROUTE_JAHAD_FILES_STATE, + ROUTE_JAHAD_ILLEGALـKILLING, + ROUTE_JAHAD_KILLS_STATS, + ROUTE_JAHAD_PRICING, +} from "./routes"; + +const JahadKillStats = lazy(() => + lazyRetry(() => import("../pages/JahadKillStats")) +); + +const JahadIllegalKilling = lazy(() => + lazyRetry(() => import("../pages/JahadIllegalKilling")) +); +const InspectorPricing = lazy(() => + lazyRetry(() => import("../pages/ProvinceManagePricing")) +); +const FilesState = lazy(() => lazyRetry(() => import("../pages/FilesState"))); + +export const jahadRouting = [ + { + path: [ROUTE_JAHAD_KILLS_STATS], + Page: JahadKillStats, + exact: false, + props: {}, + }, + { + path: [ROUTE_JAHAD_ILLEGALـKILLING], + Page: JahadIllegalKilling, + exact: false, + props: {}, + }, + { + path: [ROUTE_JAHAD_PRICING], + Page: InspectorPricing, + exact: false, + props: {}, + }, + { + path: [ROUTE_JAHAD_FILES_STATE], + Page: FilesState, + exact: false, + props: {}, + }, +]; diff --git a/src/routes/liveStockSupportRouting.js b/src/routes/liveStockSupportRouting.js new file mode 100644 index 0000000..db625a3 --- /dev/null +++ b/src/routes/liveStockSupportRouting.js @@ -0,0 +1,51 @@ +import { lazy } from "react"; +import { lazyRetry } from "../utils/lazyRetry"; +import { + ROUTE_LIVE_STOCK_COLD_HOUSE, + ROUTE_LIVE_STOCK_FREEZING_REQUESTS, + ROUTE_LIVE_STOCK_SUPPORT_MANAGE_BARS, + ROUTE_LIVE_STOCK_SUPPORT_ROUTE_FILES_STATE, +} from "./routes"; + +const Bars = lazy(() => + lazyRetry(() => import("../pages/LiveStockSupportManageBars")) +); + +const Cases = lazy(() => + lazyRetry(() => import("../pages/LiveStockSupportCases")) +); + +const Freezing = lazy(() => + lazyRetry(() => import("../pages/LiveStockFreezingRequests")) +); + +const ColdHouse = lazy(() => + lazyRetry(() => import("../pages/LiveStockColdHouse")) +); + +export const liveStockSupportRouting = [ + { + path: [ROUTE_LIVE_STOCK_SUPPORT_MANAGE_BARS], + Page: Bars, + exact: false, + props: {}, + }, + { + path: [ROUTE_LIVE_STOCK_SUPPORT_ROUTE_FILES_STATE], + Page: Cases, + exact: false, + props: {}, + }, + { + path: [ROUTE_LIVE_STOCK_FREEZING_REQUESTS], + Page: Freezing, + exact: false, + props: {}, + }, + { + path: [ROUTE_LIVE_STOCK_COLD_HOUSE], + Page: ColdHouse, + exact: false, + props: {}, + }, +]; diff --git a/src/routes/managerRouting.js b/src/routes/managerRouting.js new file mode 100644 index 0000000..d771085 --- /dev/null +++ b/src/routes/managerRouting.js @@ -0,0 +1,1047 @@ +import { lazy } from "react"; +import { lazyRetry } from "../utils/lazyRetry"; +import * as ROUTES from "../routes/routes"; + +const ProvinceRequests = lazy(() => + lazyRetry(() => import("../pages/ProvinceRequests")) +); + +const ProvinceManagePricing = lazy(() => + lazyRetry(() => import("../pages/ProvinceManagePricing")) +); + +const ProvinceProducts = lazy(() => + lazyRetry(() => import("../pages/ProvinceProducts")) +); + +const CarManagement = lazy(() => + lazyRetry(() => import("../pages/CarManagement")) +); + +const UserManagement = lazy(() => + lazyRetry(() => import("../pages/ProvinceUserManagement")) +); + +const Guilds = lazy(() => lazyRetry(() => import("../pages/Guilds"))); + +const AgentShare = lazy(() => + lazyRetry(() => import("../pages/SlaughterAgentShare")) +); + +const Hatching = lazy(() => + lazyRetry(() => import("../pages/OperatorNewHatching")) +); + +const NationalInfo = lazy(() => + lazyRetry(() => import("../pages/NationalInfo")) +); + +const VetFarmAllocations = lazy(() => + lazyRetry(() => import("../pages/VetFarmAllocations")) +); + +const SendMassage = lazy(() => lazyRetry(() => import("../pages/SendMassage"))); + +const ManageProcess = lazy(() => + lazyRetry(() => import("../pages/ManageProcess")) +); + +const ManageProcessWages = lazy(() => + lazyRetry(() => import("../pages/ManageProcessWageFractions")) +); + +const ManageFarm = lazy(() => lazyRetry(() => import("../pages/ManageFarm"))); + +const PolicyCouncil = lazy(() => + lazyRetry(() => import("../pages/PolicyCouncil")) +); + +const FilesState = lazy(() => lazyRetry(() => import("../pages/FilesState"))); + +const BarInfos = lazy(() => lazyRetry(() => import("../pages/BarInfos"))); + +const Slaughters = lazy(() => lazyRetry(() => import("../pages/Slaughters"))); + +const UserFile = lazy(() => + lazyRetry(() => import("../pages/ProvinceUserFile")) +); + +const Users = lazy(() => lazyRetry(() => import("../pages/Users"))); + +const Poultries = lazy(() => lazyRetry(() => import("../pages/Poultries"))); + +const ProvinceFees = lazy(() => + lazyRetry(() => import("../pages/ProvinceFees")) +); + +const BroadcastManagement = lazy(() => + lazyRetry(() => import("../pages/BroadcastManagement")) +); + +const Reports = lazy(() => lazyRetry(() => import("../pages/ProvinceReports"))); + +const TransactionsPage = lazy(() => + lazyRetry(() => import("../pages/Transactions")) +); + +const GuildTransactions = lazy(() => + lazyRetry(() => import("../pages/ProvinceGuildsTransactions")) +); + +const VisorStatics = lazy(() => + lazyRetry(() => import("../pages/VisorStatics")) +); + +const TradePanel = lazy(() => lazyRetry(() => import("../pages/TradePanel"))); + +const Dispensers = lazy(() => + lazyRetry(() => import("../pages/SlaughterHouseDispenserDashboard")) +); + +const AllHatchings = lazy(() => + lazyRetry(() => import("../pages/AdminHatchings")) +); + +const ColdHouses = lazy(() => + lazyRetry(() => import("../pages/ProvinceColdHousesPage")) +); + +const SubSectorWage = lazy(() => + lazyRetry(() => import("../pages/SubSectorWage")) +); + +const KillersWages = lazy(() => + lazyRetry(() => import("../pages/ProvinceKillersWages")) +); + +const DiffrenceKiller = lazy(() => + lazyRetry(() => import("../pages/DiffrenceKillerPage")) +); + +const DashboardPage = lazy(() => + lazyRetry(() => import("../pages/DashboardPage")) +); + +const SettlementPage = lazy(() => + lazyRetry(() => import("../pages/AdminSettlement")) +); + +const PoultryScienceExpertsPage = lazy(() => + lazyRetry(() => import("../pages/PoultryScienceExperts")) +); + +const ReturnPurchases = lazy(() => + lazyRetry(() => import("../pages/ReturnPurchases")) +); + +const ComponentsCatalog = lazy(() => + lazyRetry(() => import("../pages/ComponentsCatalog")) +); + +const ExcelCheck = lazy(() => + lazyRetry(() => import("../pages/AdminXExcelCheck")) +); + +const AdminXDashboard = lazy(() => + lazyRetry(() => import("../pages/AdminXDashboard")) +); + +const Statics = lazy(() => lazyRetry(() => import("../pages/AdminStatics"))); + +const Tickets = lazy(() => lazyRetry(() => import("../pages/Tickets"))); + +const Message = lazy(() => + lazyRetry(() => import("../pages/ProvinceSendMessage")) +); + +const NewFile = lazy(() => lazyRetry(() => import("../pages/NewFile"))); + +const DispensersStock = lazy(() => + lazyRetry(() => + import( + "../features/province/components/province-dispensers-stock/ProvinceDispensersStock" + ) + ) +); + +const ProvinceDispensersStockSlug = lazy(() => + lazyRetry(() => + import( + "../features/province/components/province-dispensers-stock-slug/ProvinceDispensersStockSlug" + ) + ) +); + +const PoultriesDetails = lazy(() => + lazyRetry(() => import("../pages/PoultriesDetailsPage")) +); + +const AccessDashboardV2 = lazy(() => + lazyRetry(() => import("../pages/AcessDashboardV2")) +); + +const Inspection = lazy(() => lazyRetry(() => import("../pages/Inspection"))); + +const PspCompany = lazy(() => lazyRetry(() => import("../pages/PspCompany"))); + +const ManageStewards = lazy(() => + lazyRetry(() => import("../pages/ProvinceManageStewards")) +); + +const consolidatedRouting = [ + { + path: [ROUTES.ROUTE_ADMINX_BASE_NEW_HOME], + Page: AccessDashboardV2, + exact: false, + props: {}, + }, + { + path: [ROUTES.ROUTE_ADMINX_PROVINCE_SWITCH], + Page: AdminXDashboard, + exact: false, + props: {}, + }, + + { + path: [ + ROUTES.ROUTE_ADMINX_STATICS, + ROUTES.ROUTE_PROVINCE_STATICS, + ROUTES.ROUTE_SUPER_ADMIN_STATICS, + ], + Page: Statics, + exact: false, + props: {}, + }, + + { + path: [ + ROUTES.ROUTE_ADMINX_TICKET, + ROUTES.ROUTE_ADMINX_VIEW_TICKET, + ROUTES.ROUTE_PROVINCE_TICKET, + ROUTES.ROUTE_PROVINCE_VIEW_TICKET, + ROUTES.ROUTE_SUPER_ADMIN_TICKET, + ROUTES.ROUTE_SUPER_ADMIN_VIEW_TICKET, + ], + Page: Tickets, + exact: false, + props: {}, + }, + + { + path: [ + ROUTES.ROUTE_ADMINX_SEND_MESSAGE, + ROUTES.ROUTE_PROVINCE_SEND_MESSAGE, + ROUTES.ROUTE_SUPER_ADMIN_SEND_MESSAGE, + ], + Page: Message, + exact: false, + props: {}, + }, + + { + path: [ + ROUTES.ROUTE_ADMINX_FILE_ROUTE, + ROUTES.ROUTE_PROVINCE_FILE_ROUTE, + ROUTES.ROUTE_SUPER_ADMIN_FILE_ROUTE, + ], + Page: NewFile, + exact: false, + props: {}, + }, + + { + path: [ + ROUTES.ROUTE_ADMINX_USERS, + ROUTES.ROUTE_PROVINCE_USERS, + ROUTES.ROUTE_SUPER_ADMIN_USERS, + ], + Page: UserManagement, + exact: false, + props: {}, + }, + { + path: [ + ROUTES.ROUTE_ADMINX_REQUESTS, + ROUTES.ROUTE_ADMINX_CITY_NEW_REQUESTS, + ROUTES.ROUTE_ADMINX_NEW_REQUESTS, + ROUTES.ROUTE_ADMINX_REJECTED_REQUESTS, + ROUTES.ROUTE_ADMINX_ARCHIVED_REQUESTS, + ROUTES.ROUTE_ADMINX_ISSUANCE_OF_LETTER, + ROUTES.ROUTE_ADMINX_AWAITING_PAYMENT_REQUESTS, + ROUTES.ROUTE_ADMINX_AWAITING_INSPECTION_REQUESTS, + ROUTES.ROUTE_ADMINX_ACTIVE_REQUESTS, + ROUTES.ROUTE_ADMINX_STATEMENTـOFـNEED_REQUESTS, + ROUTES.ROUTE_ADMINX_ALLOCATION_REQUESTS, + ROUTES.ROUTE_ADMINX_FREE_SALES_REQUESTS, + ROUTES.ROUTE_ADMINX_AUTO_ALLOCATION_REQUESTS, + ROUTES.ROUTE_ADMINX_ALLOCATED_REQUESTS, + ROUTES.ROUTE_ADMINX_CHAINS, + ROUTES.ROUTE_ADMINX_EXPORT, + ROUTES.ROUT_ADMINX_FREE_BUY, + + ROUTES.ROUTE_PROVINCE_REQUESTS, + ROUTES.ROUTE_PROVINCE_CITY_NEW_REQUESTS, + ROUTES.ROUTE_PROVINCE_NEW_REQUESTS, + ROUTES.ROUTE_PROVINCE_REJECTED_REQUESTS, + ROUTES.ROUTE_PROVINCE_ARCHIVED_REQUESTS, + ROUTES.ROUTE_PROVINCE_ISSUANCE_OF_LETTER, + ROUTES.ROUTE_PROVINCE_AWAITING_PAYMENT_REQUESTS, + ROUTES.ROUTE_PROVINCE_AWAITING_INSPECTION_REQUESTS, + ROUTES.ROUTE_PROVINCE_ACTIVE_REQUESTS, + ROUTES.ROUTE_PROVINCE_STATEMENTـOFـNEED_REQUESTS, + ROUTES.ROUTE_PROVINCE_ALLOCATION_REQUESTS, + ROUTES.ROUTE_PROVINCE_FREE_SALES_REQUESTS, + ROUTES.ROUTE_PROVINCE_AUTO_ALLOCATION_REQUESTS, + ROUTES.ROUTE_PROVINCE_ALLOCATED_REQUESTS, + ROUTES.ROUTE_PROVINCEـFREE_BUY, + ROUTES.ROUTE_PROVINCE_CHAINS, + ROUTES.ROUTE_PROVINCEـEXPORT, + + ROUTES.ROUTE_SUPER_ADMIN_REQUESTS, + ROUTES.ROUTE_SUPER_ADMIN_CITY_NEW_REQUESTS, + ROUTES.ROUTE_SUPER_ADMIN_NEW_REQUESTS, + ROUTES.ROUTE_SUPER_ADMIN_REJECTED_REQUESTS, + ROUTES.ROUTE_SUPER_ADMIN_ARCHIVED_REQUESTS, + ROUTES.ROUTE_SUPER_ADMIN_ISSUANCE_OF_LETTER, + ROUTES.ROUTE_SUPER_ADMIN_AWAITING_PAYMENT_REQUESTS, + ROUTES.ROUTE_SUPER_ADMIN_AWAITING_INSPECTION_REQUESTS, + ROUTES.ROUTE_SUPER_ADMIN_ACTIVE_REQUESTS, + ROUTES.ROUTE_SUPER_ADMIN_STATEMENTـOFـNEED_REQUESTS, + ROUTES.ROUTE_SUPER_ADMIN_ALLOCATION_REQUESTS, + ROUTES.ROUTE_SUPER_ADMIN_FREE_SALES_REQUESTS, + ROUTES.ROUTE_SUPER_ADMIN_AUTO_ALLOCATION_REQUESTS, + ROUTES.ROUTE_SUPER_ADMIN_ALLOCATED_REQUESTS, + ROUTES.ROUTE_SUPER_ADMIN_CHAINS, + ROUTES.ROUTE_SUPER_ADMIN_EXPORT, + ROUTES.ROUT_SUPER_ADMIN_FREE_BUY, + ], + Page: ProvinceRequests, + exact: false, + props: {}, + }, + + { + path: [ + ROUTES.ROUTE_ADMINX_BROADCAST_MANAGEMENT, + ROUTES.ROUTE_PROVINCEـBROADCAST_MANAGEMENT, + ROUTES.ROUTE_SUPER_ADMIN_BROADCAST_MANAGEMENT, + ], + Page: BroadcastManagement, + exact: false, + props: {}, + }, + + { + path: [ + ROUTES.ROUTE_ADMINX_REPORT, + ROUTES.ROUTE_PROVINCE_REPORT, + ROUTES.ROUTE_SUPER_ADMIN_REPORT, + ], + Page: Reports, + exact: false, + props: {}, + }, + + { + path: [ + ROUTES.ROUTE_ADMINX_PRODUCTS, + ROUTES.ROUTE_PROVINCE_PRODUCTS, + ROUTES.ROUTE_SUPER_ADMIN_PRODUCTS, + ], + Page: ProvinceProducts, + exact: false, + props: {}, + }, + + { + path: [ + ROUTES.ROUTE_ADMINX_TRANSACTIONS, + ROUTES.ROUTE_ADMINX_TRANSACTIONS_VIEW, + ROUTES.ROUTE_PROVINCE_TRANSACTIONS, + ROUTES.ROUTE_PROVINCE_TRANSACTIONS_VIEW, + ROUTES.ROUTE_SUPER_ADMIN_TRANSACTIONS, + ROUTES.ROUTE_SUPER_ADMIN_TRANSACTIONS_VIEW, + ], + Page: TransactionsPage, + exact: false, + props: {}, + }, + + { + path: [ + ROUTES.ROUTE_ADMINX_GUILD_TRANSACTIONS, + ROUTES.ROUTE_PROVINCE_GUILD_TRANSACTIONS, + ROUTES.ROUTE_SUPER_ADMIN_GUILD_TRANSACTIONS, + ], + Page: GuildTransactions, + exact: false, + props: {}, + }, + + { + path: [ + ROUTES.ROUTE_ADMINX_PAYING_FEES_REQUESTS, + ROUTES.ROUTE_ADMINX_PAYING_FEES_REQUESTS_VIEW, + ROUTES.ROUTE_PROVINCE_PAYING_FEES_REQUESTS, + ROUTES.ROUTE_PROVINCE_PAYING_FEES_REQUESTS_VIEW, + ROUTES.ROUTE_SUPER_ADMIN_PAYING_FEES_REQUESTS, + ROUTES.ROUTE_SUPER_ADMIN_PAYING_FEES_REQUESTS_VIEW, + ], + Page: ProvinceFees, + exact: false, + props: {}, + }, + + { + path: [ + ROUTES.ROUTE_ADMINX_ROUTE_AGENT_SHARE, + ROUTES.ROUTE_ADMINX_ROUTE_AGENT_SHARE_ID, + ROUTES.ROUTE_ADMINX_ROUTE_STEWARD_SHARE, + ROUTES.ROUTE_PROVINCE_ROUTE_AGENT_SHARE, + ROUTES.ROUTE_PROVINCE_ROUTE_AGENT_SHARE_ID, + ROUTES.ROUTE_PROVINCE_ROUTE_STEWARD_SHARE, + ROUTES.ROUTE_SUPER_ADMIN_ROUTE_AGENT_SHARE, + ROUTES.ROUTE_SUPER_ADMIN_ROUTE_AGENT_SHARE_ID, + ROUTES.ROUTE_SUPER_ADMIN_ROUTE_STEWARD_SHARE, + ], + Page: AgentShare, + exact: false, + props: {}, + }, + + { + path: [ + ROUTES.ROUTE_ADMINX_ROUTE_MANAGE_GUILDS, + ROUTES.ROUTE_ADMINX_ROUTE_GUILDS, + ROUTES.ROUTE_ADMINX_ROUTE_IN_PROVINCE_STEWARDS, + ROUTES.ROUTE_ADMINX_ROUTE_GUILDS_SETTINGS, + ROUTES.ROUTE_ADMINX_ROUTE_IN_PROVINCE_GUILDS_REQUESTS, + ROUTES.ROUTE_ADMINX_ROUTE_IN_PROVINCE_GUILDS_DISTRIBUTIONS, + ROUTES.ROUTE_PROVINCE_ROUTE_MANAGE_GUILDS, + ROUTES.ROUTE_PROVINCE_ROUTE_GUILDS, + ROUTES.ROUTE_PROVINCE_ROUTE_IN_PROVINCE_STEWARDS, + ROUTES.ROUTE_PROVINCE_ROUTE_GUILDS_SETTINGS, + ROUTES.ROUTE_PROVINCE_ROUTE_IN_PROVINCE_GUILDS_REQUESTS, + ROUTES.ROUTE_SUPER_ADMIN_ROUTE_MANAGE_GUILDS, + ROUTES.ROUTE_SUPER_ADMIN_ROUTE_GUILDS, + ROUTES.ROUTE_SUPER_ADMIN_ROUTE_IN_PROVINCE_STEWARDS, + ROUTES.ROUTE_SUPER_ADMIN_ROUTE_GUILDS_SETTINGS, + ROUTES.ROUTE_SUPER_ADMIN_ROUTE_IN_PROVINCE_GUILDS_REQUESTS, + ROUTES.ROUTE_SUPER_ADMIN_ROUTE_IN_PROVINCE_GUILDS_DISTRIBUTIONS, + ROUTES.ROUTE_SUPER_ADMIN_ROUTE_OUT_PROVINCE_GUILDS, + ROUTES.ROUTE_ADMINX_ROUTE_OUT_PROVINCE_GUILDS, + ROUTES.ROUTE_PROVINCE_ROUTE_OUT_PROVINCE_GUILDS, + ROUTES.ROUTE_ADMINX_ROUTE_IN_PROVINCE_GUILDS, + ROUTES.ROUTE_PROVINCE_ROUTE_IN_PROVINCE_GUILDS, + ROUTES.ROUTE_SUPER_ADMIN_ROUTE_IN_PROVINCE_GUILDS, + ROUTES.ROUTE_SUPER_ADMIN_ROUTE_IN_PROVINCE_TRUE_GUILDS, + ROUTES.ROUTE_ADMINX_ROUTE_IN_PROVINCE_TRUE_GUILDS, + ROUTES.ROUTE_PROVINCE_ROUTE_IN_PROVINCE_TRUE_GUILDS, + ROUTES.ROUTE_SUPER_ADMIN_ROUTE_OUT_PROVINCE_TRUE_GUILDS, + ROUTES.ROUTE_ADMINX_ROUTE_OUT_PROVINCE_TRUE_GUILDS, + ROUTES.ROUTE_PROVINCE_ROUTE_OUT_PROVINCE_TRUE_GUILDS, + ROUTES.ROUTE_SUPER_ADMIN_ROUTE_IN_PROVINCE_LEGAL_GUILDS, + ROUTES.ROUTE_ADMINX_ROUTE_IN_PROVINCE_LEGAL_GUILDS, + ROUTES.ROUTE_PROVINCE_ROUTE_IN_PROVINCE_LEGAL_GUILDS, + ROUTES.ROUTE_SUPER_ADMIN_ROUTE_OUT_PROVINCE_LEGAL_GUILDS, + ROUTES.ROUTE_ADMINX_ROUTE_OUT_PROVINCE_LEGAL_GUILDS, + ROUTES.ROUTE_PROVINCE_ROUTE_OUT_PROVINCE_LEGAL_GUILDS, + ], + Page: Guilds, + exact: false, + props: {}, + }, + + { + path: [ + ROUTES.ROUTE_ADMINX_SLAUGHTERS, + ROUTES.ROUTE_SLAUGHTER_ACTIVE_REQUESTS, + ROUTES.ROUTE_PROVINCE_SLAUGHTERS, + ROUTES.ROUTE_SUPER_ADMIN_SLAUGHTERS, + ROUTES.ROUTE_ADMINX_SLAUGHTERS_MONITORING_BUYERS, + ROUTES.ROUTE_PROVINCE_SLAUGHTERS_MONITORING_BUYERS, + ROUTES.ROUTE_SUPER_ADMIN_SLAUGHTERS_MONITORING_BUYERS, + ], + Page: Slaughters, + exact: false, + props: {}, + }, + + { + path: [ + ROUTES.ROUTE_ADMINX_POULTRIES, + ROUTES.ROUTE_PROVINCE_POULTRIES, + ROUTES.ROUTE_SUPER_ADMIN_POULTRIES, + ], + Page: Poultries, + exact: false, + props: {}, + }, + + { + path: [ + ROUTES.ROUTE_ADMINX_USERS, + ROUTES.ROUTE_PROVINCE_USERS, + ROUTES.ROUTE_SUPER_ADMIN_USERS, + ], + Page: Users, + exact: false, + props: {}, + }, + + { + path: [ + ROUTES.ROUTE_ADMINX_CARS, + ROUTES.ROUTE_PROVINCE_CARS, + ROUTES.ROUTE_SUPER_ADMIN_CARS, + ], + Page: CarManagement, + exact: false, + props: {}, + }, + + { + path: [ + ROUTES.ROUTE_ADMINX_ASSIGN_VET_FARM, + ROUTES.ROUTE_PROVINCE_ASSIGN_VET_FARM, + ROUTES.ROUTE_SUPER_ADMIN_ASSIGN_VET_FARM, + ], + Page: ManageFarm, + exact: false, + props: {}, + }, + + { + path: [ + ROUTES.ROUTE_ADMINX_ROUTE_ALLOCATIONS, + ROUTES.ROUTE_PROVINCE_ROUTE_ALLOCATIONS, + ROUTES.ROUTE_SUPER_ADMIN_ROUTE_ALLOCATIONS, + ], + Page: VetFarmAllocations, + exact: false, + props: {}, + }, + + { + path: [ + ROUTES.ROUTE_ADMINX_ROUTE_MANAGE_PROCESS, + ROUTES.ROUTE_ADMINX_ROUTE_MANAGE_PROCESS_POLICY_COUNCIL, + ROUTES.ROUTE_ADMINX_ROUTE_MANAGE_PROCESS_SLAUGHTER, + ROUTES.ROUTE_ADMINX_ROUTE_SLAUGHTER_TRADE_PANEL, + ROUTES.ROUTE_ADMINX_ROUTE_MANAGE_DISTRIBUTIONS, + ROUTES.ROUTE_ADMINX_ROUTE_MANAGE_PROCESS_KILLPLACE, + ROUTES.ROUTE_ADMINX_ROUTE_MANAGE_PROCESS_BUY_REQ, + ROUTES.ROUTE_ADMINX_ROUTE_MANAGE_PROCESS_DOCUMENT_STATES, + ROUTES.ROUTE_ADMINX_ROUTE_ACCOUNTS, + ROUTES.ROUTE_ADMINX_ROUTE_TICKET_PERMISSION, + ROUTES.ROUTE_ADMINX_ROUTE_CRONJOB, + ROUTES.ROUTE_ADMINX_ROUTE_Sms_Submission_Management, + ROUTES.ROUTE_ADMINX_ROUTE_WEIGHT_RANGE, + ROUTES.ROUTE_ADMINX_ROUTE_WEIGHT_CATEGORY, + ROUTES.ROUTE_ADMINX_ROUTE_PENALTY, + ROUTES.ROUTE_ADMINX_ROUTE_RESTRICTION_OF_CARCASS_DISTRIBUTION, + ROUTES.ROUTE_PROVINCE_ROUTE_MANAGE_PROCESS, + ROUTES.ROUTE_PROVINCE_ROUTE_MANAGE_PROCESS_POLICY_COUNCIL, + ROUTES.ROUTE_PROVINCE_ROUTE_MANAGE_PROCESS_SLAUGHTER, + ROUTES.ROUTE_PROVINCE_ROUTE_MANAGE_PROCESS_KILLPLACE, + ROUTES.ROUTE_PROVINCE_ROUTE_MANAGE_PROCESS_BUY_REQ, + ROUTES.ROUTE_SUPER_ADMIN_ROUTE_MANAGE_PROCESS, + ROUTES.ROUTE_SUPER_ADMIN_ROUTE_MANAGE_PROCESS_POLICY_COUNCIL, + ROUTES.ROUTE_SUPER_ADMIN_ROUTE_MANAGE_PROCESS_SLAUGHTER, + ROUTES.ROUTE_SUPER_ADMIN_ROUTE_SLAUGHTER_TRADE_PANEL, + ROUTES.ROUTE_SUPER_ADMIN_ROUTE_MANAGE_DISTRIBUTIONS, + ROUTES.ROUTE_SUPER_ADMIN_ROUTE_MANAGE_PROCESS_KILLPLACE, + ROUTES.ROUTE_SUPER_ADMIN_ROUTE_MANAGE_PROCESS_BUY_REQ, + ROUTES.ROUTE_SUPER_ADMIN_ROUTE_MANAGE_PROCESS_DOCUMENT_STATES, + ROUTES.ROUTE_SUPER_ADMIN_ROUTE_TICKET_PERMISSION, + ROUTES.ROUTE_SUPER_ADMIN_ROUTE_WEIGHT_CATEGORY, + ROUTES.ROUTE_SUPER_ADMIN_ROUTE_WEIGHT_RANGE, + ROUTES.ROUTE_SUPER_ADMIN_ROUTE_PENALTY, + ROUTES.ROUTE_SUPER_ADMIN_ROUTE_RESTRICTION_OF_CARCASS_DISTRIBUTION, + ], + Page: ManageProcess, + exact: false, + props: {}, + }, + + { + path: [ + ROUTES.ROUTE_ADMINX_ROUTE_POLICY_COUNCIL_POULTRY_CHOOSE_SLAUGHTER, + ROUTES.ROUTE_ADMINX_ROUTE_POLICY_COUNCIL_FREE_SALE, + ROUTES.ROUTE_ADMINX_ROUTE_POLICY_COUNCIL_DIRECT_BUY, + ROUTES.ROUTE_ADMINX_ROUTE_POLICY_COUNCIL_KILLHOUSE_GUILDS, + ROUTES.ROUTE_PROVINCE_ROUTE_POLICY_COUNCIL_POULTRY_CHOOSE_SLAUGHTER, + ROUTES.ROUTE_PROVINCE_ROUTE_POLICY_COUNCIL_FREE_SALE, + ROUTES.ROUTE_PROVINCE_ROUTE_POLICY_COUNCIL_DIRECT_BUY, + ROUTES.ROUTE_PROVINCE_ROUTE_POLICY_COUNCIL_KILLHOUSE_GUILDS, + ROUTES.ROUTE_SUPER_ADMIN_ROUTE_POLICY_COUNCIL_POULTRY_CHOOSE_SLAUGHTER, + ROUTES.ROUTE_SUPER_ADMIN_ROUTE_POLICY_COUNCIL_FREE_SALE, + ROUTES.ROUTE_SUPER_ADMIN_ROUTE_POLICY_COUNCIL_DIRECT_BUY, + ROUTES.ROUTE_SUPER_ADMIN_ROUTE_POLICY_COUNCIL_KILLHOUSE_GUILDS, + ], + Page: PolicyCouncil, + exact: false, + props: {}, + }, + + { + path: [ + ROUTES.ROUTE_ADMINX_ROUTE_FILES_STATE, + ROUTES.ROUTE_PROVINCE_ROUTE_FILES_STATE, + ROUTES.ROUTE_SUPER_ADMIN_ROUTE_FILES_STATE, + ], + Page: FilesState, + exact: false, + props: {}, + }, + + { + path: [ + ROUTES.ROUTE_ADMINX_BARS, + ROUTES.ROUTE_PROVINCE_BARS, + ROUTES.ROUTE_SUPER_ADMIN_BARS, + ], + Page: BarInfos, + exact: false, + props: {}, + }, + + { + path: [ + ROUTES.ROUTE_ADMINX_USER_FILE_ROUTE, + ROUTES.ROUTE_PROVINCE_USER_FILE_ROUTE, + ROUTES.ROUTE_SUPER_ADMIN_USER_FILE_ROUTE, + ], + Page: UserFile, + exact: false, + props: {}, + }, + + { + path: [ + ROUTES.ROUTE_ADMINX_MANAGE_USERS, + ROUTES.ROUTE_PROVINCE_MANAGE_USERS, + ROUTES.ROUTE_SUPER_ADMIN_MANAGE_USERS, + ], + Page: UserManagement, + exact: false, + props: {}, + }, + + { + path: [ + ROUTES.ROUTE_ADMINX_PRICING3, + ROUTES.ROUTE_PROVINCE_PRICING3, + ROUTES.ROUTE_SUPER_ADMIN_PRICING3, + ], + Page: ProvinceManagePricing, + exact: false, + props: {}, + }, + + { + path: [ + ROUTES.ROUTE_ADMINX_VISOR_STATICS, + ROUTES.ROUTE_ADMINX_VISOR_STATICS_CHARTS, + ROUTES.ROUTE_ADMINX_VISOR_STATICS_PREDICTION, + ROUTES.ROUTE_ADMINX_VISOR_STATICS_PREDICTION_VIEW, + ROUTES.ROUTE_ADMINX_NATIONAL_STATICS, + ROUTES.ROUTE_PROVINCEـVISOR_STATICS, + ROUTES.ROUTE_PROVINCEـVISOR_STATICS_CHARTS, + ROUTES.ROUTE_PROVINCEـVISOR_STATICS_PREDICTION, + ROUTES.ROUTE_PROVINCEـVISOR_STATICS_PREDICTION_VIEW, + ROUTES.ROUTE_SUPER_ADMIN_VISOR_STATICS, + ROUTES.ROUTE_SUPER_ADMIN_VISOR_STATICS_CHARTS, + ROUTES.ROUTE_SUPER_ADMIN_VISOR_STATICS_PREDICTION, + ROUTES.ROUTE_SUPER_ADMIN_VISOR_STATICS_PREDICTION_VIEW, + ROUTES.ROUTE_SUPER_ADMIN_NATIONAL_STATICS, + ], + Page: VisorStatics, + exact: false, + props: {}, + }, + + { + path: [ + ROUTES.ROUTE_ADMINX_TRADING_PANEL, + ROUTES.ROUTE_ADMINX_TRADING_PANEL_DASHBOARD, + ROUTES.ROUTE_PROVINCE_TRADING_PANEL, + ROUTES.ROUTE_SUPER_ADMIN_TRADING_PANEL, + ], + Page: TradePanel, + exact: false, + props: {}, + }, + + { + path: [ + ROUTES.ROUTE_ADMINX_DISPENSERS, + ROUTES.ROUTE_ADMINX_DISPENSERS_MANAGEMENT, + ROUTES.ROUTE_ADMINX_DISPENSERS_MANAGEMENT_V2, + ROUTES.ROUTE_ADMINX_DELEGATES_MANAGEMENT, + ROUTES.ROUTE_ADMINX_DISPENSER_DETAILS, + ROUTES.ROUTE_ADMINX_DISPENSER_DETAILS_VIEW, + ROUTES.ROUTE_ADMINX_DISPENSERS_STEWARDS, + ROUTES.ROUTE_ADMINX_DISPENSERS_KILLHOUSES, + ROUTES.ROUTE_ADMINX_DISPENSERS_KILLHOUSES_VIEW, + ROUTES.ROUTE_ADMINX_DISPENSERS_SELL_CARCASS, + ROUTES.ROUTE_ADMINX_DISPENSERS_INVENTORY, + ROUTES.ROUTE_ADMINX_SALE_DESTRIBUTION_DETAILS, + ROUTES.ROUTE_PROVINCE_DISPENSERS, + ROUTES.ROUTE_PROVINCE_DISPENSERS_MANAGEMENT, + ROUTES.ROUTE_PROVINCE_DISPENSER_DETAILS, + ROUTES.ROUTE_PROVINCE_DISPENSER_DETAILS_VIEW, + ROUTES.ROUTE_PROVINCE_DISPENSERS_STEWARDS, + ROUTES.ROUTE_PROVINCE_DISPENSERS_KILLHOUSES, + ROUTES.ROUTE_PROVINCE_DISPENSERS_KILLHOUSES_VIEW, + ROUTES.ROUTE_PROVINCE_DISPENSERS_SELL_CARCASS, + ROUTES.ROUTE_PROVINCE_DISPENSERS_INVENTORY, + ROUTES.ROUTE_PROVINCE_SALE_DESTRIBUTION_DETAILS, + ROUTES.ROUTE_SUPER_ADMIN_DISPENSERS, + ROUTES.ROUTE_SUPER_ADMIN_DISPENSERS_MANAGEMENT, + ROUTES.ROUTE_SUPER_ADMIN_DISPENSER_DETAILS, + ROUTES.ROUTE_SUPER_ADMIN_DISPENSER_DETAILS_VIEW, + ROUTES.ROUTE_SUPER_ADMIN_DISPENSERS_STEWARDS, + ROUTES.ROUTE_SUPER_ADMIN_DISPENSERS_KILLHOUSES, + ROUTES.ROUTE_SUPER_ADMIN_DISPENSERS_KILLHOUSES_VIEW, + ROUTES.ROUTE_SUPER_ADMIN_DISPENSERS_SELL_CARCASS, + ROUTES.ROUTE_SUPER_ADMIN_DISPENSERS_INVENTORY, + ROUTES.ROUTE_SUPER_ADMIN_DESTRIBUTION_DETAILS, + ], + Page: Dispensers, + exact: false, + props: {}, + }, + { + path: [ + ROUTES.ROUTE_ADMINX_DISPENSERS_STOCK, + ROUTES.ROUTE_SUPER_ADMIN_DISPENSERS_STOCK, + ], + Page: DispensersStock, + exact: false, + props: {}, + }, + { + path: [ + ROUTES.ROUTE_ADMINX_DISPENSERS_STOCK_KILLHOUSE, + ROUTES.ROUTE_ADMINX_DISPENSERS_STOCK_STEWARD, + ROUTES.ROUTE_ADMINX_DISPENSERS_STOCK_GUILD, + ROUTES.ROUTE_SUPER_ADMIN_DISPENSERS_STOCK_KILLHOUSE, + ROUTES.ROUTE_SUPER_ADMIN_DISPENSERS_STOCK_STEWARD, + ROUTES.ROUTE_SUPER_ADMIN_DISPENSERS_STOCK_GUILD, + ], + Page: ProvinceDispensersStockSlug, + exact: false, + props: {}, + }, + { + path: [ + ROUTES.ROUTE_ADMINXـHATCHINGS, + ROUTES.ROUTE_ADMINXـHATCHINGS_DETAILS, + ROUTES.ROUTE_PROVINCEـHATCHINGS, + ROUTES.ROUTE_PROVINCEـHATCHINGS_DETAILS, + ROUTES.ROUTE_SUPER_ADMINـHATCHINGS, + ROUTES.ROUTE_SUPER_ADMINـHATCHINGS_DETAILS, + ], + Page: AllHatchings, + exact: false, + props: {}, + }, + { + path: [ + ROUTES.ROUTE_ADMINX_COLD_HOUSES, + ROUTES.ROUTE_ADMINX_COLD_HOUSES_MANAGEMENT, + ROUTES.ROUTE_ADMINX_COLD_HOUSES_MANAGEMENT_VIEW, + ROUTES.ROUTE_PROVINCE_COLD_HOUSES, + ROUTES.ROUTE_PROVINCE_COLD_HOUSES_MANAGEMENT, + ROUTES.ROUTE_PROVINCE_COLD_HOUSES_MANAGEMENT_VIEW, + ROUTES.ROUTE_SUPER_ADMIN_COLD_HOUSES, + ROUTES.ROUTE_SUPER_ADMIN_COLD_HOUSES_MANAGEMENT, + ROUTES.ROUTE_SUPER_ADMIN_COLD_HOUSES_MANAGEMENT_VIEW, + ], + Page: ColdHouses, + exact: false, + props: {}, + }, + + { + path: [ + ROUTES.ROUTE_ADMINX_SUB_SECTORS_WAGE, + ROUTES.ROUTE_ADMINX_SUB_SECTORS_CITY_SHARES, + ROUTES.ROUTE_ADMINX_SUB_SECTORS_STEWARD_SHARES, + ROUTES.ROUTE_ADMINX_SUB_SECTORS_VET_FARM_SHARES, + ROUTES.ROUTE_PROVINCE_SUB_SECTORS_WAGE, + ROUTES.ROUTE_PROVINCE_SUB_SECTORS_CITY_SHARES, + ROUTES.ROUTE_PROVINCE_SUB_SECTORS_STEWARD_SHARES, + ROUTES.ROUTE_PROVINCE_SUB_SECTORS_VET_FARM_SHARES, + ROUTES.ROUTE_SUPER_ADMIN_SUB_SECTORS_WAGE, + ROUTES.ROUTE_SUPER_ADMIN_SUB_SECTORS_CITY_SHARES, + ROUTES.ROUTE_SUPER_ADMIN_SUB_SECTORS_STEWARD_SHARES, + ROUTES.ROUTE_SUPER_ADMIN_SUB_SECTORS_VET_FARM_SHARES, + ], + Page: SubSectorWage, + exact: false, + props: {}, + }, + + { + path: [ + ROUTES.ROUTE_ADMINX_ROUTE_KILLERS_WAGES, + ROUTES.ROUTE_ADMINX_ROUTE_KILLERS_WAGES_DETAILS, + ROUTES.ROUTE_PROVINCE_ROUTE_KILLERS_WAGES, + ROUTES.ROUTE_PROVINCE_ROUTE_KILLERS_WAGES_DETAILS, + ROUTES.ROUTE_SUPER_ADMIN_ROUTE_KILLERS_WAGES, + ROUTES.ROUTE_SUPER_ADMIN_ROUTE_KILLERS_WAGES_DETAILS, + ], + Page: KillersWages, + exact: false, + props: {}, + }, + + { + path: [ + ROUTES.ROUTE_ADMINX_DIFFRENCE_KILLER, + ROUTES.ROUTE_ADMINX_DIFFRENCE_KILLER_SLAUGHTER, + ROUTES.ROUTE_ADMINX_INCREASE_HATCHING, + ROUTES.ROUTE_PROVINCE_DIFFRENCE_KILLER, + ROUTES.ROUTE_PROVINCE_DIFFRENCE_KILLER_SLAUGHTER, + ROUTES.ROUTE_PROVINCE_INCREASE_HATCHING, + ROUTES.ROUTE_SUPER_ADMIN_DIFFRENCE_KILLER, + ROUTES.ROUTE_SUPER_ADMIN_DIFFRENCE_KILLER_SLAUGHTER, + ROUTES.ROUTE_SUPER_ADMIN_INCREASE_HATCHING, + ], + Page: DiffrenceKiller, + exact: false, + props: {}, + }, + + { + path: [ + ROUTES.ROUTE_ADMINX_DASHBOARD, + ROUTES.ROUTE_PROVINCE_DASHBOARD, + ROUTES.ROUTE_SUPER_ADMIN_DASHBOARD, + ], + Page: DashboardPage, + exact: false, + props: {}, + }, + + { + path: [ + ROUTES.ROUTE_ADMINX_SETTLEMENTS, + ROUTES.ROUTE_PROVINCE_SETTLEMENTS, + ROUTES.ROUTE_SUPER_ADMIN_SETTLEMENTS, + ], + Page: SettlementPage, + exact: false, + props: {}, + }, + + { + path: [ + ROUTES.ROUTE_ADMINX_POULTRY_LIVESTOCK_EXPERTS, + ROUTES.ROUTE_PROVINCE_POULTRY_LIVESTOCK_EXPERTS, + ROUTES.ROUTE_SUPER_ADMIN_POULTRY_LIVESTOCK_EXPERTS, + ], + Page: PoultryScienceExpertsPage, + exact: false, + props: {}, + }, + + { + path: [ + ROUTES.ROUTE_ADMINX_RETURN_PURCHASES, + ROUTES.ROUTE_PROVINCE_RETURN_PURCHASES, + ROUTES.ROUTE_SUPER_ADMIN_RETURN_PURCHASES, + ], + Page: ReturnPurchases, + exact: false, + props: {}, + }, + + { + path: [ + ROUTES.ROUTE_ADMINX_ROUTE_NATIONAL_INFO, + ROUTES.ROUTE_ADMINX_ROUTE_NATIONAL_INFO_DETAILS, + ROUTES.ROUTE_ADMINX_ROUTE_NATIONAL_INFO_FARM, + ROUTES.ROUTE_ADMINX_ROUTE_NATIONAL_INFO_FARM_DETAILS, + ROUTES.ROUTE_ADMINX_ROUTE_NATIONAL_INFO_HATCHING_DETAILS, + ROUTES.ROUTE_ADMINX_ROUTE_NATIONAL_INFO_SLAUGHTER, + ROUTES.ROUTE_ADMINX_ROUTE_NATIONAL_INFO_SLAUGHTER_DETAILS, + ROUTES.ROUTE_ADMINX_ROUTE_NATIONAL_INFO_DISTRIBUTION_DETAILS, + ROUTES.ROUTE_SUPER_ADMIN_ROUTE_NATIONAL_INFO, + ROUTES.ROUTE_SUPER_ADMIN_ROUTE_NATIONAL_INFO_DETAILS, + ROUTES.ROUTE_SUPER_ADMIN_ROUTE_NATIONAL_INFO_FARM, + ROUTES.ROUTE_SUPER_ADMIN_ROUTE_NATIONAL_INFO_FARM_DETAILS, + ROUTES.ROUTE_SUPER_ADMIN_ROUTE_NATIONAL_INFO_HATCHING_DETAILS, + ROUTES.ROUTE_SUPER_ADMIN_ROUTE_NATIONAL_INFO_SLAUGHTER, + ROUTES.ROUTE_SUPER_ADMIN_ROUTE_NATIONAL_INFO_SLAUGHTER_DETAILS, + ROUTES.ROUTE_SUPER_ADMIN_ROUTE_NATIONAL_INFO_DISTRIBUTION_DETAILS, + ], + Page: NationalInfo, + exact: false, + props: {}, + }, + + { + path: [ + ROUTES.ROUTE_ADMINX_HATCHING, + ROUTES.ROUTE_ADMINX_NEW_REQUEST, + ROUTES.ROUTE_ADMINX_ROUTE_NATIONAL_INFO_DETAILS, + ROUTES.ROUTE_ADMINX_ROUTE_NATIONAL_INFO_FARM, + ROUTES.ROUTE_ADMINX_ROUTE_NATIONAL_INFO_FARM_DETAILS, + ROUTES.ROUTE_PROVINCE_HATCHING, + ROUTES.ROUTE_PROVINCE_NEW_REQUEST, + ROUTES.ROUTE_SUPER_ADMIN_HATCHING, + ROUTES.ROUTE_SUPER_ADMIN_NEW_REQUEST, + ROUTES.ROUTE_SUPER_ADMIN_ROUTE_NATIONAL_INFO_DETAILS, + ROUTES.ROUTE_SUPER_ADMIN_ROUTE_NATIONAL_INFO_FARM, + ROUTES.ROUTE_SUPER_ADMIN_ROUTE_NATIONAL_INFO_FARM_DETAILS, + ], + Page: Hatching, + exact: false, + props: {}, + }, + + { + path: [ + ROUTES.ROUTE_ADMINX_ROUTE_SMS, + ROUTES.ROUTE_ADMINX_ROUTE_SMS_MANAGE, + ROUTES.ROUTE_ADMINX_ROUTE_SMS_SEND, + ROUTES.ROUTE_ADMINX_SEND_ANNOUNCEMENT, + ROUTES.ROUTE_ADMINX_SEND_REPORT, + ROUTES.ROUTE_ADMINX_ROUTE_MANAGE_PROCESS_MOBILE_MESSAGE, + ROUTES.ROUTE_ADMINX_ROUTE_AGE_MESSAGE, + ROUTES.ROUTE_ADMINX_DASHBOARD_NEWS, + ROUTES.ROUTE_PROVINCE_ROUTE_SMS, + ROUTES.ROUTE_PROVINCE_ROUTE_SMS_MANAGE, + ROUTES.ROUTE_PROVINCE_ROUTE_SMS_SEND, + ROUTES.ROUTE_PROVINCE_SEND_ANNOUNCEMENT, + ROUTES.ROUTE_PROVINCE_SEND_REPORT, + ROUTES.ROUTE_PROVINCE_DASHBOARD_NEWS, + ROUTES.ROUTE_SUPER_ADMIN_ROUTE_SMS, + ROUTES.ROUTE_SUPER_ADMIN_ROUTE_SMS_MANAGE, + ROUTES.ROUTE_SUPER_ADMIN_ROUTE_SMS_SEND, + ROUTES.ROUTE_SUPER_ADMIN_SEND_ANNOUNCEMENT, + ROUTES.ROUTE_SUPER_ADMIN_SEND_REPORT, + ROUTES.ROUTE_SUPER_ADMIN_ROUTE_MANAGE_PROCESS_MOBILE_MESSAGE, + ROUTES.ROUTE_SUPER_ADMIN_ROUTE_AGE_MESSAGE, + ROUTES.ROUTE_SUPER_ADMIN_DASHBOARD_NEWS, + ], + Page: SendMassage, + exact: false, + props: {}, + }, + + { + path: [ + ROUTES.ROUTE_ADMINX_ROUTE_MANAGE_PROCESS_WAGE_FRACTIONS, + ROUTES.ROUTE_SUPER_ADMIN_ROUTE_MANAGE_PROCESS_WAGE_FRACTIONS, + ], + Page: ManageProcessWages, + exact: false, + props: {}, + }, + + { + path: [ROUTES.ROUTE_ADMINX_COMPONENTS_CATALOG], + Page: ComponentsCatalog, + exact: false, + props: {}, + }, + + { + path: [ROUTES.ROUTE_ADMINX_EXCEL_CHECK], + Page: ExcelCheck, + exact: false, + props: {}, + }, + + // export const ROUTE_SUPER_ADMIN_ROUTE_COMPANY_MANAGE_STEWARDS = + // ROUTE_SUPER_ADMIN_BASE + "/manage-stewards"; + // export const ROUTE_SUPER_ADMIN_COMPANY_ROUTE_GUILDS = + // ROUTE_SUPER_ADMIN_BASE + "/manage-guilds/guilds"; + // export const ROUTE_SUPER_ADMIN_COMPANY_ROUTE_ACTIVE_SESSION = + // ROUTE_SUPER_ADMIN_BASE + "/active-session/session"; + // export const ROUTE_SUPER_ADMIN_COMPANY_ROUTE_DEVICES = + // ROUTE_SUPER_ADMIN_BASE + "/devices"; + { + path: [ + ROUTES.ROUTE_SUPER_ADMIN_ROUTE_PSP_COMPANIES, + ROUTES.ROUTE_SUPER_ADMIN_COMPANY_ROUTE_GUILDS, + ROUTES.ROUTE_SUPER_ADMIN_COMPANY_ROUTE_ACTIVE_SESSION, + ROUTES.ROUTE_SUPER_ADMIN_COMPANY_ROUTE_DEVICES, + ROUTES.ROUTE_ADMINX_ROUTE_PSP_COMPANIES, + ROUTES.ROUTE_ADMINX_COMPANY_ROUTE_GUILDS, + ROUTES.ROUTE_ADMINX_COMPANY_ROUTE_ACTIVE_SESSION, + ROUTES.ROUTE_ADMINX_COMPANY_ROUTE_DEVICES, + ], + Page: PspCompany, + exact: false, + props: {}, + }, + { + path: [ + ROUTES.ROUTE_ADMINX_POULTRIES_DETAILS, + ROUTES.ROUTE_PROVINCE_POULTRIES_DETAILS, + ROUTES.ROUTE_SUPER_ADMIN_POULTRIES_DETAILS, + ], + Page: PoultriesDetails, + exact: false, + props: {}, + }, + { + path: [ + ROUTES.ROUTE_ADMINX_ROUTE_INSPECTION, + ROUTES.ROUTE_SUPER_ADMIN_ROUTE_INSPECTION, + ], + Page: Inspection, + exact: false, + props: {}, + }, + { + path: [ + ROUTES.ROUTE_ADMINX_ROUTE_MANAGE_STEWARDS, + ROUTES.ROUTE_SUPER_ADMIN_ROUTE_MANAGE_STEWARDS, + ROUTES.ROUTE_PROVINCE_SUPERVISOR_ROUTE_MANAGE_STEWARDS, + ], + Page: ManageStewards, + exact: false, + props: {}, + }, +]; + +export const getManagerRouting = (role) => { + if (!role) { + return consolidatedRouting; + } + + const routePrefixes = { + AdminX: "/adminx", + provinceOperator: "/province", + SuperAdmin: "/superadmin", + }; + + const rolePrefix = routePrefixes[role]; + + if (!rolePrefix) { + return consolidatedRouting; + } + + return consolidatedRouting + .map((routeConfig) => { + const rolePaths = routeConfig.path.filter((path) => + path.startsWith(rolePrefix) + ); + + if (rolePaths.length > 0) { + return { + ...routeConfig, + path: rolePaths, + }; + } + + return null; + }) + .filter((routeConfig) => routeConfig !== null); +}; diff --git a/src/routes/observatoryRouting.js b/src/routes/observatoryRouting.js new file mode 100644 index 0000000..0a07857 --- /dev/null +++ b/src/routes/observatoryRouting.js @@ -0,0 +1,35 @@ +import { lazy } from "react"; +import { lazyRetry } from "../utils/lazyRetry"; +import { + ROUTE_OBSERVATORY_STATICS, + ROUTE_OBSERVATORY_VISOR_STATICS, + ROUTE_OBSERVATORY_VISOR_STATICS_CHARTS, + ROUTE_OBSERVATORY_VISOR_STATICS_PREDICTION, + ROUTE_OBSERVATORY_VISOR_STATICS_PREDICTION_VIEW, +} from "./routes"; + +const Statics = lazy(() => lazyRetry(() => import("../pages/AdminStatics"))); + +const VisorStatics = lazy(() => + lazyRetry(() => import("../pages/VisorStatics")) +); + +export const observatoryRouting = [ + { + path: [ROUTE_OBSERVATORY_STATICS], + Page: Statics, + exact: false, + props: {}, + }, + { + path: [ + ROUTE_OBSERVATORY_VISOR_STATICS, + ROUTE_OBSERVATORY_VISOR_STATICS_PREDICTION, + ROUTE_OBSERVATORY_VISOR_STATICS_PREDICTION_VIEW, + ROUTE_OBSERVATORY_VISOR_STATICS_CHARTS, + ], + Page: VisorStatics, + exact: false, + props: {}, + }, +]; diff --git a/src/routes/parentCompanyRouting.js b/src/routes/parentCompanyRouting.js new file mode 100644 index 0000000..2f5d5c1 --- /dev/null +++ b/src/routes/parentCompanyRouting.js @@ -0,0 +1,24 @@ +import { lazy } from "react"; +import { lazyRetry } from "../utils/lazyRetry"; +import { + ROUTE_PARENT_COMPANY_ALLOCATIONS, + ROUTE_PARENT_COMPANY_PAYING_FEES_REQUESTS, + ROUTE_PARENT_COMPANY_PAYING_FEES_VIEW, +} from "./routes"; + +const ParentCompanyRequests = lazy(() => + lazyRetry(() => import("../pages/ParentCompany")) +); + +export const parentCompanyRouting = [ + { + path: [ + ROUTE_PARENT_COMPANY_PAYING_FEES_VIEW, + ROUTE_PARENT_COMPANY_PAYING_FEES_REQUESTS, + ROUTE_PARENT_COMPANY_ALLOCATIONS, + ], + Page: ParentCompanyRequests, + exact: false, + props: {}, + }, +]; diff --git a/src/routes/posCompanyRouting.js b/src/routes/posCompanyRouting.js new file mode 100644 index 0000000..404d346 --- /dev/null +++ b/src/routes/posCompanyRouting.js @@ -0,0 +1,48 @@ +import { lazy } from "react"; +import { lazyRetry } from "../utils/lazyRetry"; +import { + ROUTE_PSP_COMPANY_ROUTE_ACTIVE_SESSION, + ROUTE_PSP_COMPANY_ROUTE_DEVICES, + ROUTE_PSP_COMPANY_ROUTE_DEVICES_V2, + ROUTE_PSP_COMPANY_ROUTE_GUILDS, + ROUTE_PSP_ROUTE_COMPANY_PSP_COMPANIES, +} from "./routes"; + +const Stewards = lazy(() => lazyRetry(() => import("../pages/PspCompany"))); + +const PspDevicesV2 = lazy(() => + lazyRetry(() => + import("../features/psp-company/components/psp-devices-v2/PspDevicesV2") + ) +); + +// export const ROUTE_PSP_ROUTE_COMPANY_MANAGE_STEWARDS = +// ROUTE_PSP_COMPANY_BASE + "/manage-stewards"; + +// export const ROUTE_PSP_COMPANY_ROUTE_GUILDS = +// ROUTE_PSP_COMPANY_BASE + "/manage-guilds/guilds"; + +// export const ROUTE_PSP_COMPANY_ROUTE_ACTIVE_SESSION = +// ROUTE_PSP_COMPANY_BASE + "/active-session/session"; + +// export const ROUTE_PSP_COMPANY_ROUTE_DEVICES = +// ROUTE_PSP_COMPANY_BASE + "/devices"; +export const posCompanyRouting = [ + { + path: [ + ROUTE_PSP_ROUTE_COMPANY_PSP_COMPANIES, + ROUTE_PSP_COMPANY_ROUTE_GUILDS, + ROUTE_PSP_COMPANY_ROUTE_ACTIVE_SESSION, + ROUTE_PSP_COMPANY_ROUTE_DEVICES, + ], + Page: Stewards, + exact: false, + props: {}, + }, + { + path: [ROUTE_PSP_COMPANY_ROUTE_DEVICES_V2], + Page: PspDevicesV2, + exact: false, + props: {}, + }, +]; diff --git a/src/routes/provinceFinancialRouting.js b/src/routes/provinceFinancialRouting.js new file mode 100644 index 0000000..4941b0c --- /dev/null +++ b/src/routes/provinceFinancialRouting.js @@ -0,0 +1,167 @@ +import { lazy } from "react"; +import { lazyRetry } from "../utils/lazyRetry"; +import { + ROUTE_PROVINCE_FINANCIAL_ARCHIVED_REQUESTS, + ROUTE_PROVINCE_FINANCIAL_FILE_ROUTE, + ROUTE_PROVINCE_FINANCIAL_NEW_REQUESTS, + ROUTE_PROVINCE_FINANCIAL_REJECTED_REQUESTS, + ROUTE_PROVINCE_FINANCIAL_REQUESTS, + ROUTE_PROVINCE_FINANCIAL_TICKET, + ROUTE_PROVINCE_FINANCIAL_VIEW_TICKET, + ROUTE_PROVINCE_PRICING, + ROUTE_PROVINCE_FINANCIAL_ROUTE_DEBT, + ROUTE_PROVINCE_FINANCIAL_COMPLAINTS, + ROUTE_PROVINCE_FINANCIAL_DOCUMENT_REGISTRATION, + ROUTE_PROVINCE__FINANCIAL_USER_FINACIAL_FILE_ROUTE, + ROUTE_PROVINCE_FINANCIAL_AWAITING_PAYMENT_REQUESTS, + ROUTE_PROVINCE_FINANCIAL_AWAITING_INSPECTION_REQUESTS, + ROUTE_PROVINCE_FINANCIAL_STATICS, + ROUTE_PROVINCE_PRICING3, + ROUTE_PROVINCE_FINANCIAL_PENDING_REQUESTS, + ROUTE_PROVINCE_FINANCIAL_CHECK_PAYED_FACTOR_REQUESTS, + ROUTE_PROVINCE_FINANCIAL_FINAL_FACTORS_REQUESTS, + ROUTE_PROVINCE_FINANCIAL_SETTLEMENT, + ROUTE_PROVINCE_FINANCIAL_ACTIVE_REQUESTS, + ROUTE_PROVINCE_FINANCIAL_TRANSACTIONS, + ROUTE_PROVINCE_FINANCIAL_SUB_SECTORS_WAGE, + ROUTE_PROVINCE_FINANCIAL_SUB_SECTORS_CITY_SHARES, + ROUTE_PROVINCE_FINANCIAL_SUB_SECTORS_STEWARD_SHARES, + ROUTE_PROVINCE_FINANCIAL_SUB_SECTORS_VET_FARM_SHARES, + ROUTE_PROVINCE_FINANCIAL_TRANSACTIONS_VIEW, +} from "./routes"; + +const ProvinceFinancial = lazy(() => + lazyRetry(() => import("../pages/ProvinceFinancial")) +); +// const File = lazy(() => lazyRetry(() => import("../pages/File"))); +const NewFile = lazy(() => lazyRetry(() => import("../pages/NewFile"))); +const ProvinceManagePricing = lazy(() => + lazyRetry(() => import("../pages/ProvinceManagePricing")) +); +const Tickets = lazy(() => lazyRetry(() => import("../pages/Tickets"))); +const Debts = lazy(() => + lazyRetry(() => import("../pages/ProvinceFinancialDebts")) +); +const Complaints = lazy(() => + lazyRetry(() => import("../pages/ProvinceFinancialComplaints")) +); +const DoucumentRegister = lazy(() => + lazyRetry(() => import("../pages/ProvinceFinancialDocumentRegister")) +); +const Statics = lazy(() => lazyRetry(() => import("../pages/AdminStatics"))); + +const ProvinceSettlementPage = lazy(() => + lazyRetry(() => import("../pages/ProvinceSettlementPage")) +); + +const TransactionsPage = lazy(() => + lazyRetry(() => import("../pages/Transactions")) +); + +const ProvincePricing = lazy(() => + lazyRetry(() => import("../pages/ProvinceManagePricing")) +); + +const SubSectorWage = lazy(() => + lazyRetry(() => import("../pages/SubSectorWage")) +); + +export const provinceFinancialRouting = [ + { + path: [ + ROUTE_PROVINCE_FINANCIAL_REQUESTS, + ROUTE_PROVINCE_FINANCIAL_REJECTED_REQUESTS, + ROUTE_PROVINCE_FINANCIAL_ARCHIVED_REQUESTS, + ROUTE_PROVINCE_FINANCIAL_NEW_REQUESTS, + ROUTE_PROVINCE_FINANCIAL_AWAITING_PAYMENT_REQUESTS, + ROUTE_PROVINCE_FINANCIAL_AWAITING_INSPECTION_REQUESTS, + ROUTE_PROVINCE_FINANCIAL_PENDING_REQUESTS, + ROUTE_PROVINCE_FINANCIAL_CHECK_PAYED_FACTOR_REQUESTS, + ROUTE_PROVINCE_FINANCIAL_FINAL_FACTORS_REQUESTS, + ROUTE_PROVINCE_FINANCIAL_ACTIVE_REQUESTS, + ], + Page: ProvinceFinancial, + exact: false, + props: {}, + }, + { + path: [ + ROUTE_PROVINCE_FINANCIAL_SUB_SECTORS_WAGE, + ROUTE_PROVINCE_FINANCIAL_SUB_SECTORS_CITY_SHARES, + ROUTE_PROVINCE_FINANCIAL_SUB_SECTORS_STEWARD_SHARES, + ROUTE_PROVINCE_FINANCIAL_SUB_SECTORS_VET_FARM_SHARES, + ], + Page: SubSectorWage, + exact: false, + props: {}, + }, + { + path: [ROUTE_PROVINCE_FINANCIAL_FILE_ROUTE], + Page: NewFile, + exact: false, + props: {}, + }, + { + path: [ROUTE_PROVINCE_PRICING], + Page: ProvinceManagePricing, + exact: false, + props: {}, + }, + { + path: [ + ROUTE_PROVINCE_FINANCIAL_VIEW_TICKET, + ROUTE_PROVINCE_FINANCIAL_TICKET, + ], + Page: Tickets, + exact: false, + props: {}, + }, + { + path: [ROUTE_PROVINCE_FINANCIAL_ROUTE_DEBT], + Page: Debts, + exact: false, + props: {}, + }, + { + path: [ROUTE_PROVINCE_FINANCIAL_COMPLAINTS], + Page: Complaints, + exact: false, + props: {}, + }, + { + path: [ + ROUTE_PROVINCE_FINANCIAL_DOCUMENT_REGISTRATION, + ROUTE_PROVINCE__FINANCIAL_USER_FINACIAL_FILE_ROUTE, + ], + Page: DoucumentRegister, + exact: false, + props: {}, + }, + { + path: [ROUTE_PROVINCE_FINANCIAL_STATICS], + Page: Statics, + exact: false, + props: {}, + }, + { + path: [ROUTE_PROVINCE_PRICING3], + Page: ProvincePricing, + exact: false, + props: {}, + }, + { + path: [ROUTE_PROVINCE_FINANCIAL_SETTLEMENT], + Page: ProvinceSettlementPage, + exact: false, + props: {}, + }, + { + path: [ + ROUTE_PROVINCE_FINANCIAL_TRANSACTIONS, + ROUTE_PROVINCE_FINANCIAL_TRANSACTIONS_VIEW, + ], + Page: TransactionsPage, + exact: false, + props: {}, + }, +]; diff --git a/src/routes/provinceSupervisorRouting.js b/src/routes/provinceSupervisorRouting.js new file mode 100644 index 0000000..a42b3a9 --- /dev/null +++ b/src/routes/provinceSupervisorRouting.js @@ -0,0 +1,238 @@ +import { lazy } from "react"; +import { lazyRetry } from "../utils/lazyRetry"; +import { + ROUTE_PROVINCE_SUPERVISOR_ROUTE_ALLOCATIONS, + ROUTE_PROVINCE_SUPERVISOR_ROUTE_FILES_STATE, + ROUTE_PROVINCE_SUPERVISOR_ROUTE_GUILDS, + ROUTE_PROVINCE_SUPERVISOR_ROUTE_GUILDS_SETTINGS, + ROUTE_PROVINCE_SUPERVISOR_ROUTE_MANAGE_GUILDS, + ROUTE_PROVINCE_SUPERVISOR_ROUTE_STEWARDS, + ROUTE_PROVINCE_SUPERVISOR_STATICS, + ROUTE_PROVINCE_SUPERVISOR_REQUESTS, + ROUTE_PROVINCE_SUPERVISOR_HATCHING, + ROUTE_PROVINCE_SUPERVISOR_REPORTING, + ROUTE_PROVINCE_SUPERVISORـHATCHINGS, + ROUTE_PROVINCE_SUPERVISOR_STATICS_CHARTS, + ROUTE_PROVINCE_SUPERVISOR_STATICS_PREDICTION, + ROUTE_PROVINCE_SUPERVISOR_STATICS_PREDICTION_VIEW, + ROUTE_PROVINCE_SUPERVISOR_DASHBOARD, + ROUTE_PROVINCE_SUPERVISORـHATCHINGS_DETAILS, + ROUTE_PROVINCE_SUPERVISOR_PRICING, + ROUTE_PROVINCE_SUPERVISOR_ROUTE_NATIONAL_INFO_DETAILS, + ROUTE_PROVINCE_SUPERVISOR_ROUTE_NATIONAL_INFO_FARM, + ROUTE_PROVINCE_SUPERVISOR_ROUTE_NATIONAL_INFO_FARM_DETAILS, + ROUTE_PROVINCE_SUPERVISOR_ROUTE_NATIONAL_INFO, + ROUTE_PROVINCE_SUPERVISOR_ROUTE_NATIONAL_INFO_HATCHING_DETAILS, + ROUTE_PROVINCE_SUPERVISOR_ROUTE_NATIONAL_INFO_SLAUGHTER, + ROUTE_PROVINCE_SUPERVISOR_ROUTE_NATIONAL_INFO_SLAUGHTER_DETAILS, + ROUTE_PROVINCE_SUPERVISOR_DISPENSERS, + ROUTE_PROVINCE_SUPERVISOR_DISPENSERS_MANAGEMENT, + ROUTE_PROVINCE_SUPERVISOR_DISPENSER_DETAILS_VIEW, + ROUTE_PROVINCE_SUPERVISOR_DISPENSERS_STEWARDS, + ROUTE_PROVINCE_SUPERVISOR_DISPENSERS_KILLHOUSES, + ROUTE_PROVINCE_SUPERVISOR_DISPENSERS_SELL_CARCASS, + ROUTE_PROVINCE_SUPERVISOR_DISPENSERS_INVENTORY, + ROUTE_PROVINCE_SUPERVISOR_SALE_DESTRIBUTION_DETAILS, + ROUTE_PROVINCE_SUPERVISOR_DISPENSERS_STOCK_KILLHOUSE, + ROUTE_PROVINCE_SUPERVISOR_DISPENSERS_STOCK_STEWARD, + ROUTE_PROVINCE_SUPERVISOR_DISPENSERS_STOCK_GUILD, + ROUTE_PROVINCE_SUPERVISOR_DISPENSERS_STOCK, + ROUTE_PROVINCE_SUPERVISOR_REQUEST_DISTRIBUTION, + ROUTE_PROVINCE_SUPERVISOR_REQUEST_TRANSACTIONS, +} from "./routes"; + +const Dispensers = lazy(() => + lazyRetry(() => import("../pages/SlaughterHouseDispenserDashboard")) +); + +const Guilds = lazy(() => lazyRetry(() => import("../pages/Guilds"))); +const FilesState = lazy(() => lazyRetry(() => import("../pages/FilesState"))); +const VetFarmAllocations = lazy(() => + lazyRetry(() => import("../pages/VetFarmAllocations")) +); +const Statics = lazy(() => lazyRetry(() => import("../pages/AdminStatics"))); + +const Commerce = lazy(() => lazyRetry(() => import("../pages/Commerce"))); +const Hatching = lazy(() => lazyRetry(() => import("../pages/Hatching"))); +const Reports = lazy(() => lazyRetry(() => import("../pages/ProvinceReports"))); + +const OperatorHatching = lazy(() => + lazyRetry(() => import("../pages/OperatorNewHatching")) +); + +const AllHatchings = lazy(() => + lazyRetry(() => import("../pages/AdminHatchings")) +); +const DashboardPage = lazy(() => + lazyRetry(() => import("../pages/DashboardPage")) +); + +const ProvinceManagePricing = lazy(() => + lazyRetry(() => import("../pages/ProvinceManagePricing")) +); + +const NationalInfo = lazy(() => + lazyRetry(() => import("../pages/NationalInfo")) +); + +const ProvinceDispensersStockSlug = lazy(() => + lazyRetry(() => + import( + "../features/province/components/province-dispensers-stock-slug/ProvinceDispensersStockSlug" + ) + ) +); + +const DispensersStock = lazy(() => + lazyRetry(() => + import( + "../features/province/components/province-dispensers-stock/ProvinceDispensersStock" + ) + ) +); + +const TransactionsPage = lazy(() => + lazyRetry(() => import("../pages/Transactions")) +); + +export const provinceSupervisorRouting = [ + { + path: [ROUTE_PROVINCE_SUPERVISOR_REQUESTS], + Page: Commerce, + exact: false, + props: {}, + }, + { + path: [ + ROUTE_PROVINCE_SUPERVISOR_ROUTE_MANAGE_GUILDS, + ROUTE_PROVINCE_SUPERVISOR_ROUTE_GUILDS, + ROUTE_PROVINCE_SUPERVISOR_ROUTE_STEWARDS, + ROUTE_PROVINCE_SUPERVISOR_ROUTE_GUILDS_SETTINGS, + ], + Page: Guilds, + exact: false, + props: {}, + }, + { + path: [ROUTE_PROVINCE_SUPERVISOR_PRICING], + Page: ProvinceManagePricing, + exact: false, + props: {}, + }, + { + path: [ + ROUTE_PROVINCE_SUPERVISOR_ROUTE_NATIONAL_INFO_DETAILS, + ROUTE_PROVINCE_SUPERVISOR_ROUTE_NATIONAL_INFO_FARM, + ROUTE_PROVINCE_SUPERVISOR_ROUTE_NATIONAL_INFO_FARM_DETAILS, + ], + Page: OperatorHatching, + exact: false, + props: {}, + }, + { + path: [ + ROUTE_PROVINCE_SUPERVISOR_ROUTE_NATIONAL_INFO, + ROUTE_PROVINCE_SUPERVISOR_ROUTE_NATIONAL_INFO_HATCHING_DETAILS, + ROUTE_PROVINCE_SUPERVISOR_ROUTE_NATIONAL_INFO_SLAUGHTER, + ROUTE_PROVINCE_SUPERVISOR_ROUTE_NATIONAL_INFO_SLAUGHTER_DETAILS, + ], + Page: NationalInfo, + exact: false, + props: {}, + }, + + { + path: [ROUTE_PROVINCE_SUPERVISOR_ROUTE_FILES_STATE], + Page: FilesState, + exact: false, + props: {}, + }, + { + path: [ROUTE_PROVINCE_SUPERVISOR_ROUTE_ALLOCATIONS], + Page: VetFarmAllocations, + exact: false, + props: {}, + }, + { + path: [ + ROUTE_PROVINCE_SUPERVISOR_STATICS, + ROUTE_PROVINCE_SUPERVISOR_STATICS_PREDICTION, + ROUTE_PROVINCE_SUPERVISOR_STATICS_PREDICTION_VIEW, + ROUTE_PROVINCE_SUPERVISOR_STATICS_CHARTS, + ], + Page: Statics, + exact: false, + props: {}, + }, + { + path: [ROUTE_PROVINCE_SUPERVISOR_HATCHING], + Page: Hatching, + exact: false, + props: {}, + }, + { + path: [ROUTE_PROVINCE_SUPERVISOR_REPORTING], + Page: Reports, + exact: false, + props: {}, + }, + { + path: [ + ROUTE_PROVINCE_SUPERVISORـHATCHINGS, + ROUTE_PROVINCE_SUPERVISORـHATCHINGS_DETAILS, + ], + Page: AllHatchings, + exact: false, + props: {}, + }, + { + path: [ROUTE_PROVINCE_SUPERVISOR_DASHBOARD], + Page: DashboardPage, + exact: false, + props: {}, + }, + { + path: [ + ROUTE_PROVINCE_SUPERVISOR_DISPENSERS, + ROUTE_PROVINCE_SUPERVISOR_DISPENSERS_MANAGEMENT, + ROUTE_PROVINCE_SUPERVISOR_DISPENSER_DETAILS_VIEW, + ROUTE_PROVINCE_SUPERVISOR_DISPENSERS_STEWARDS, + ROUTE_PROVINCE_SUPERVISOR_DISPENSERS_KILLHOUSES, + ROUTE_PROVINCE_SUPERVISOR_DISPENSERS_SELL_CARCASS, + ROUTE_PROVINCE_SUPERVISOR_DISPENSERS_INVENTORY, + ROUTE_PROVINCE_SUPERVISOR_SALE_DESTRIBUTION_DETAILS, + ROUTE_PROVINCE_SUPERVISOR_REQUEST_DISTRIBUTION, + ], + Page: Dispensers, + exact: false, + props: {}, + }, + { + path: [ROUTE_PROVINCE_SUPERVISOR_DISPENSERS_STOCK], + Page: DispensersStock, + exact: false, + props: {}, + }, + { + path: [ + ROUTE_PROVINCE_SUPERVISOR_DISPENSERS_STOCK_KILLHOUSE, + ROUTE_PROVINCE_SUPERVISOR_DISPENSERS_STOCK_STEWARD, + ROUTE_PROVINCE_SUPERVISOR_DISPENSERS_STOCK_GUILD, + ], + Page: ProvinceDispensersStockSlug, + exact: false, + props: {}, + }, + { + path: [ROUTE_PROVINCE_SUPERVISOR_REQUEST_TRANSACTIONS], + Page: TransactionsPage, + exact: false, + props: {}, + }, + // { + // path: [ROUTE_PROVINCE_SUPERVISOR_DISPENSERS_INVENTORY], + // Page: SlaughterHouseDispenserDashboard, + // exact: false, + // props: {}, + // }, +]; diff --git a/src/routes/rancherRouting.js b/src/routes/rancherRouting.js new file mode 100644 index 0000000..ae500c6 --- /dev/null +++ b/src/routes/rancherRouting.js @@ -0,0 +1,30 @@ +import { lazy } from "react"; +import { lazyRetry } from "../utils/lazyRetry"; +import { + ROUTE_COOPERATIVE_PRODUCT_DISTRIBUTION, + ROUTE_COOPERATIVE_PRODUCT_DISTRIBUTION_ALLOCATION, + ROUTE_COOPERATIVE_PRODUCT_DISTRIBUTION_POLICY, + ROUTE_COOPERATIVE_HERDS, + ROUTE_COOPERATIVE_RANCHERS, + ROUTE_COOPERATIVE_USERS, +} from "./routes"; + +const RequestsPage = lazy(() => + lazyRetry(() => import("../pages/ProvinceJahadRequests")) +); + +export const rancherRouting = [ + { + path: [ + ROUTE_COOPERATIVE_RANCHERS, + ROUTE_COOPERATIVE_HERDS, + ROUTE_COOPERATIVE_USERS, + ROUTE_COOPERATIVE_PRODUCT_DISTRIBUTION, + ROUTE_COOPERATIVE_PRODUCT_DISTRIBUTION_ALLOCATION, + ROUTE_COOPERATIVE_PRODUCT_DISTRIBUTION_POLICY, + ], + Page: RequestsPage, + exact: false, + props: {}, + }, +]; diff --git a/src/routes/routes.js b/src/routes/routes.js new file mode 100644 index 0000000..91d364a --- /dev/null +++ b/src/routes/routes.js @@ -0,0 +1,1732 @@ +// BASES +export const ROUTE_AVICULTURE_BASE = "/aviculture"; +export const ROUTE_CITY_BASE = "/city"; +export const ROUTE_SLAUGHTER_BASE = "/slaughter"; +export const ROUTE_PROVINCE_BASE = "/province"; +export const ROUTE_VETFARM_BASE = "/vetfarm"; +export const ROUTE_AUCTION_BASE = "/auction"; +export const ROUTE_DRIVER_BASE = "/driver"; +export const ROUTE_VETـSUPERVISOR_BASE = "/vet-supervisor"; +export const ROUTE_PROVINCE_FINANCIAL_BASE = "/financial"; +export const ROUTE_PROVINCE_INSPECTOR_BASE = "/inspector"; +export const ROUTE_SLAUGHTER_HOUSE_VET_BASE = "/slaughter-house-vet"; +export const ROUTE_ADMIN_BASE = "/admin"; +export const ROUTE_JAHAD_BASE = "/jahad"; +export const ROUTE_STEWARD_BASE = "/steward"; +export const ROUTE_CITYVET_BASE = "/city-vet"; +export const ROUTE_COMMERCE_BASE = "/commerce"; +export const ROUTE_PROVINCE_SUPERVISOR_BASE = "/province-supervisor"; +export const ROUTE_CITY_COMMERCE_BASE = "/city-commerce"; +export const ROUTE_CITY_JAHAD_BASE = "/city-jahad"; +export const ROUTE_CITY_POULTRY_BASE = "/citypoultry"; +export const ROUTE_OBSERVATORY_BASE = "/observatory"; +export const ROUTE_SENF_BASE = "/senf"; +export const ROUTE_GUILD_ROOM_BASE = "/guild-room"; +export const ROUTE_PSP_COMPANY_BASE = "/psp-company"; +export const ROUTE_LIVE_STOCK_SUPPORT_BASE = "/livestock"; +export const ROUTE_SUPER_ADMIN_BASE = "/superadmin"; +export const ROUTE_CHAIN_COMPANY_BASE = "/chaincompany"; +export const ROUTE_CITY_GUILD_BASE = "/city-guild"; +export const ROUTE_ADMINX_BASE = "/adminx"; +export const ROUTE_SUPPORTER_BASE = "/supporter"; +export const ROUTE_DISPENSER_BASE = "/dispenser"; +export const ROUTE_PARENT_COMPANY_BASE = "/parent-company"; +export const ROUTE_COLD_HOUSE_STEWARD_BASE = "/cold-house-steward"; +export const ROUTE_PROVINCE_JAHAD_BASE = "/province-jahad"; +export const ROUTE_UNION_BASE = "/union"; +export const ROUTE_COOPERATIVE_BASE = "/cooperative"; +export const ROUTE_BAR_SQUARE_BASE = "/bar-square"; + +// GENERAL +export const ROUTE_GENERAL_USER_PROFILE = "/dashboard/profile"; +export const ROUTE_GENERAL_USER_CHANGE_PASSWORD = "/dashboard/change-password"; +export const ROUTE_GENERAL_USER_CHANGE_PROFILE_PICTURE = + "/dashboard/change-profile-picture"; +export const ROUTE_GENERAL_USER_CHANGE_PROFILE_INFO = + "/dashboard/change-profile-info"; +export const ROUTE_GENERAL_USER_CHANGE_BANK_ACCOUNT = + "/dashboard/change-bank-account"; +export const ROUTE_GENERAL_FILE_PARAM = "/file/:id"; +export const ROUTE_GENERAL_FILE = "/file/"; +export const ROUTE_GENERAL_SUPPORT = "/support/"; +export const ROUTE_GENERAL_MESSAGES = "/messages/"; +export const ROUTE_GENERAL_TRAINING = "/training/"; +export const ROUTE_GENERAL_PAYMENT = "/payment/"; +export const ROUTE_GENERAL_WAGE_PAYMENT = "/pay/:province/:key"; +export const ROUTE_GENERAL_DOWNLOAD_REPORT = "/reports/:name"; +export const ROUTE_GENERAL_TICKET_LIST = "/ticket/"; +export const ROUTE_GENERAL_TICKET = "/ticket/:id/:create"; + +// AVICULTURE +export const ROUTE_AVICULTURE_USER_PROFILE = + "/dashboard/profile" + ROUTE_AVICULTURE_BASE; +export const ROUTE_AVICULTURE_REQUESTS = ROUTE_AVICULTURE_BASE + "/requests"; +export const ROUTE_AVICULTURE_CREATE_NEW_REQUEST = + ROUTE_AVICULTURE_BASE + "/requests/create"; +export const ROUTE_AVICULTURE_HATCHING = + ROUTE_AVICULTURE_BASE + "/requests/hatching"; +export const ROUTE_AVICULTURE_NEW_REQUESTS = + ROUTE_AVICULTURE_BASE + "/requests/new"; +export const ROUTE_AVICULTURE_SUBMIT_REQUEST = + ROUTE_AVICULTURE_BASE + "/requests/submit"; +export const ROUTE_AVICULTURE_REJECTED_REQUESTS = + ROUTE_AVICULTURE_BASE + "/requests/rejected"; + +export const ROUTE_AVICULTURE_AWAITING_PAYMENT_REQUESTS = + ROUTE_AVICULTURE_BASE + "/requests/awaitpayment"; + +export const ROUTE_AVICULTURE_AWAITING_INSPECTION_REQUESTS = + ROUTE_AVICULTURE_BASE + "/requests/awaitinspection"; +export const ROUTE_AVICULTURE_GIVE_PERMISSION = + ROUTE_AVICULTURE_BASE + "/requests/permission"; + +export const ROUTE_AVICULTURE_ARCHIVED_REQUESTS = + ROUTE_AVICULTURE_BASE + "/requests/archived"; +export const ROUTE_AVICULTURE_ACTIVE_REQUESTS = + ROUTE_AVICULTURE_BASE + "/requests/active"; +export const ROUTE_AVICULTURE_FILE = ROUTE_AVICULTURE_BASE + "/file/"; +export const ROUTE_AVICULTURE_FILE_ROUTE = ROUTE_AVICULTURE_BASE + "/file/:id"; +export const ROUTE_AVICULTURE_INSPECTS = ROUTE_AVICULTURE_BASE + "/inspects/"; +export const ROUTE_AVICULTURE_INSPECTS_ROUTE = + ROUTE_AVICULTURE_BASE + "/inspects/:key/:hall"; +export const ROUTE_AVICULTURE_AUCTION = + ROUTE_AVICULTURE_BASE + ROUTE_AUCTION_BASE; +export const ROUTE_AVICULTURE_TICKET = ROUTE_AVICULTURE_BASE + "/ticket/"; +export const ROUTE_AVICULTURE_VIEW_TICKET = + ROUTE_AVICULTURE_BASE + "/ticket/:id/:create"; +export const ROUTE_AVICULTURE_ROUTE_TICKET = ROUTE_AVICULTURE_BASE + "/ticket/"; +export const ROUTE_AVICULTURE_ROUTE_HALLS = ROUTE_AVICULTURE_BASE + "/halls/"; +export const ROUTE_AVICULTURE_REPORTS = ROUTE_AVICULTURE_BASE + "/reports/"; + +export const ROUTE_AVICULTURE_PRICING = ROUTE_AVICULTURE_BASE + "/pricing/"; + +// CITY +export const ROUTE_CITY_USER_PROFILE = "/dashboard/profile" + ROUTE_CITY_BASE; +export const ROUTE_CITY_REQUESTS = ROUTE_CITY_BASE + "/requests"; +export const ROUTE_CITY_ACTIVE_REQUESTS = ROUTE_CITY_BASE + "/requests/active"; +export const ROUTE_CITY_NEW_REQUESTS = ROUTE_CITY_BASE + "/requests/new"; +export const ROUTE_CITY_REJECTED_REQUESTS = + ROUTE_CITY_BASE + "/requests/rejected"; +export const ROUTE_CITY_ARCHIVED_REQUESTS = + ROUTE_CITY_BASE + "/requests/archived"; +export const ROUTE_CITY_POULTRY_FARMS = ROUTE_CITY_BASE + "/poultryfarms"; +export const ROUTE_CITY_FILE = ROUTE_CITY_BASE + "/file/"; +export const ROUTE_CITY_FILE_ROUTE = ROUTE_CITY_BASE + "/file/:id"; +export const ROUTE_CITY_AUCTION = ROUTE_CITY_BASE + ROUTE_AUCTION_BASE; +export const ROUTE_CITY_TICKET = ROUTE_CITY_BASE + "/ticket/"; +export const ROUTE_CITY_VIEW_TICKET = ROUTE_CITY_BASE + "/ticket/:id/:create"; +export const ROUTE_CITY_ROUTE_TICKET = ROUTE_CITY_BASE + "/ticket/"; +export const ROUTE_CITY_USER_MANAGEMENT = ROUTE_CITY_BASE + "/users"; +export const ROUTE_CITY_USER_FILE_ROUTE = ROUTE_CITY_BASE + "/userfile/:userid"; +export const ROUTE_CITY_USER_FILE = ROUTE_CITY_BASE + "/userfile/"; +export const ROUTE_CITY_AWAITING_PAYMENT_REQUESTS = + ROUTE_CITY_BASE + "/requests/awaitpayment"; +export const ROUTE_CITY_AWAITING_INSPECTION_REQUESTS = + ROUTE_CITY_BASE + "/requests/awaitinspection"; +export const ROUTE_CITY_STATICS = ROUTE_CITY_BASE + "/statics"; +export const ROUTE_CITY_HATCHING = ROUTE_CITY_BASE + "/hatching"; +export const ROUTE_CITY_NEW_REQUEST = ROUTE_CITY_BASE + "/request"; +export const ROUTE_CITY_ROUTE_FILES_STATE = ROUTE_CITY_BASE + "/files-state/"; +export const ROUTE_CITY_ROUTE_ALLOCATIONS = ROUTE_CITY_BASE + "/allocations/"; +export const ROUTE_CITY_PRICING = ROUTE_CITY_BASE + "/pricing"; +export const ROUTE_CITY_POULTRIES = ROUTE_CITY_BASE + "/poultries/"; +export const ROUTE_CITY_POULTRIES_DETAILS = ROUTE_CITY_BASE + "/poultries/:key"; +export const ROUTE_CITY_FREE_SALES_REQUESTS = + ROUTE_CITY_BASE + "/requests/free-sale"; +export const ROUTE_CITY_VISOR_STATICS = ROUTE_CITY_BASE + "/visor-statics"; +export const ROUTE_CITY_VISOR_STATICS_CHARTS = + ROUTE_CITY_BASE + "/visor-statics/charts"; +export const ROUTE_CITY_VISOR_STATICS_PREDICTION = + ROUTE_CITY_BASE + "/visor-statics/prediction/"; +export const ROUTE_CITY_VISOR_STATICS_PREDICTION_VIEW = + ROUTE_CITY_BASE + "/visor-statics/prediction/:key/:date"; +export const ROUTE_CITYـHATCHINGS = ROUTE_CITY_BASE + "/manage-hatchings"; +export const ROUTE_CITY_VISOR_STATICSـHATCHINGS_DETAILS = + ROUTE_CITYـHATCHINGS + "/manage-hatchings/:key"; +export const ROUTE_CITY_DIFFRENCE_KILLER = + ROUTE_CITY_BASE + "/manage-hatchings/diffrence-killer"; +export const ROUTE_CITY_DIFFRENCE_KILLER_SLAUGHTER = + ROUTE_CITY_BASE + "/manage-hatchings/diffrence-killer-slaughter"; +export const ROUTE_CITY_INCREASE_HATCHING = + ROUTE_CITY_BASE + "/hatching/increase-hatching"; +export const ROUTE_CITY_ROUTE_INSPECTION = ROUTE_CITY_BASE + "/inspection"; +// SLAUGHTER +export const ROUTE_SLAUGHTER_USER_PROFILE = + "/dashboard/profile" + ROUTE_SLAUGHTER_BASE; +export const ROUTE_SLAUGHTER_HOUSE_CARS = ROUTE_SLAUGHTER_BASE + "/cars"; +export const ROUTE_SLAUGHTER_ADD_CAR = ROUTE_SLAUGHTER_BASE + "/cars/add"; +export const ROUTE_SLAUGHTER_CAR_MANAGEMENT = + ROUTE_SLAUGHTER_BASE + "/cars/management"; +export const ROUTE_SLAUGHTER_REQUESTS = ROUTE_SLAUGHTER_BASE + "/requests"; +export const ROUTE_SLAUGHTER_NEW_REQUESTS = + ROUTE_SLAUGHTER_BASE + "/requests/new"; +export const ROUTE_SLAUGHTERـFREE_BUY = + ROUTE_SLAUGHTER_BASE + "/requests/free-buy"; + +export const ROUTE_SLAUGHTERـEXPORT = ROUTE_SLAUGHTER_BASE + "/requests/export"; +export const ROUTE_SLAUGHTER_PENDING_REQUESTS = + ROUTE_SLAUGHTER_BASE + "/requests/pending"; +export const ROUTE_SLAUGHTER_ACTIVE_REQUESTS = + ROUTE_SLAUGHTER_BASE + "/requests/active"; +export const ROUTE_SLAUGHTER_ALLOCATE_CAR_REQUESTS = + ROUTE_SLAUGHTER_BASE + "/requests/allocate-car"; +export const ROUTE_SLAUGHTER_ENTER_BAR_INFO = + ROUTE_SLAUGHTER_BASE + "/requests/bar-info"; +export const ROUTE_SLAUGHTER_SELL_CARCASS = + ROUTE_SLAUGHTER_BASE + "/requests/sell-carcass"; +export const ROUTE_SLAUGHTER_OUT_PROVINCE_BUY = + ROUTE_SLAUGHTER_BASE + "/inventory/buy-out-province"; +export const ROUTE_SLAUGHTER_SEGMENTATION = + ROUTE_SLAUGHTER_BASE + "/inventory/segmentation"; +export const ROUTE_SLAUGHTER_ORDERS = + ROUTE_SLAUGHTER_BASE + "/inventory/orders"; +export const ROUTE_SLAUGHTER_PAY_FACTORS_REQUESTS = + ROUTE_SLAUGHTER_BASE + "/requests/pay-factors"; +export const ROUTE_SLAUGHTER_PAYING_FEES_REQUESTS = + ROUTE_SLAUGHTER_BASE + "/requests/payment-of-fees"; +export const ROUTE_SLAUGHTER_WALLET = ROUTE_SLAUGHTER_BASE + "/wallet"; +export const ROUTE_SLAUGHTER_REJECTED_REQUESTS = + ROUTE_SLAUGHTER_BASE + "/requests/rejected"; +export const ROUTE_SLAUGHTER_ARCHIVED_REQUESTS = + ROUTE_SLAUGHTER_BASE + "/requests/archived"; +export const ROUTE_SLAUGHTER_FILE = ROUTE_SLAUGHTER_BASE + "/file/"; +export const ROUTE_SLAUGHTER_FILE_ROUTE = ROUTE_SLAUGHTER_BASE + "/file/:id"; +export const ROUTE_SLAUGHTER_AUCTION = + ROUTE_SLAUGHTER_BASE + ROUTE_AUCTION_BASE; +export const ROUTE_SLAUGHTER_TICKET = ROUTE_SLAUGHTER_BASE + "/ticket/"; +export const ROUTE_SLAUGHTER_VIEW_TICKET = + ROUTE_SLAUGHTER_BASE + "/ticket/:id/:create"; +export const ROUTE_SLAUGHTER_ROUTE_TICKET = ROUTE_SLAUGHTER_BASE + "/ticket/"; +export const ROUTE_SLAUGHTER_COMPLAINTS = ROUTE_SLAUGHTER_BASE + "/complaints"; +export const ROUTE_SLAUGHTER_INVENTORY = ROUTE_SLAUGHTER_BASE + "/inventory"; +export const ROUTE_SLAUGHTER_INVENTORY_SUMMARY = + ROUTE_SLAUGHTER_BASE + "/inventory/summary"; +export const ROUTE_SLAUGHTER_AGENT_SHARE = + ROUTE_SLAUGHTER_BASE + "/agent-share"; +export const ROUTE_SLAUGHTER_AGENT_SHARE_ID = + ROUTE_SLAUGHTER_BASE + "/agent-share/:id/:date"; +export const ROUTE_SLAUGHTER_ALLOCATION_REQUESTS = + ROUTE_SLAUGHTER_BASE + "/requests/allocated"; +export const ROUTE_SLAUGHTER_INVENTORY_STOCK = + ROUTE_SLAUGHTER_BASE + "/inventory/stock"; +export const ROUTE_SLAUGHTER_INVENTORY_SELL_CARCASS_OUT_PROVINCE = + ROUTE_SLAUGHTER_BASE + "/inventory/sell-carcass-out-province"; +export const ROUTE_SLAUGHTER_INVENTORY_SELL_CARCASS_IN_PROVINCE = + ROUTE_SLAUGHTER_BASE + "/inventory/sell-carcass-in-province"; +export const ROUTE_SLAUGHTER_FACTORS = + ROUTE_SLAUGHTER_BASE + "/requests/factors"; +export const ROUTE_SLAUGHTER_FINAL_FACTORS = + ROUTE_SLAUGHTER_BASE + "/requests/final-factors"; +export const ROUTE_SLAUGHTER_ROUTE_MANAGE_GUILDS = + ROUTE_SLAUGHTER_BASE + "/manage-guilds/"; +export const ROUTE_SLAUGHTER_ROUTE_MANAGE_STEWARDS = + ROUTE_SLAUGHTER_BASE + "/manage-stewards/"; +export const ROUTE_SLAUGHTER_ROUTE_MANAGE_BARS = + ROUTE_SLAUGHTER_BASE + "/manage-bars/"; +export const ROUTE_SLAUGHTER_FINANCIAL_TRANSACTIONS = + ROUTE_SLAUGHTER_BASE + "/requests/transactions"; +export const ROUTE_SLAUGHTER_PRICING = ROUTE_SLAUGHTER_BASE + "/pricing"; +export const ROUTE_SLAUGHTER_MORGUE = ROUTE_SLAUGHTER_BASE + "/morgue"; +export const ROUTE_SLAUGHTER_MORGUE_VIEW = + ROUTE_SLAUGHTER_BASE + "/morgue/:key"; +export const ROUTE_SLAUGHTER_MORGUE_STOCK = + ROUTE_SLAUGHTER_BASE + "/morgue/stock"; +export const ROUTE_SLAUGHTER_MORGUE_BROADCAST_MANAGEMENT = + ROUTE_SLAUGHTER_BASE + "/morgue/management"; +export const ROUTE_SLAUGHTER_DISPENSERS = ROUTE_SLAUGHTER_BASE + "/dispensers"; +export const ROUTE_SLAUGHTER_DISPENSERS_MANAGEMENT = + ROUTE_SLAUGHTER_BASE + "/dispensers-management"; +export const ROUTE_SLAUGHTER_DISPENSER_DETAILS = + ROUTE_SLAUGHTER_BASE + "/dispenser-data"; +export const ROUTE_SLAUGHTER_DISPENSER_DETAILS_VIEW = + ROUTE_SLAUGHTER_BASE + "/dispenser-data/:key"; +export const ROUTE_SLAUGHTER_DISPENSERS_STEWARDS = + ROUTE_SLAUGHTER_BASE + "/dispensers-stewards"; +export const ROUTE_SLAUGHTER_DISPENSERS_KILLHOUSES = + ROUTE_SLAUGHTER_BASE + "/dispensers-killhouses"; +export const ROUTE_SLAUGHTER_DAILY_LIST = ROUTE_SLAUGHTER_BASE + "/dailylist"; +export const ROUTE_SLAUGHTER_SETTLEMENTS = + ROUTE_SLAUGHTER_BASE + "/settlements"; +export const ROUTE_SLAUGHTER_RETURN_PURCHASES = + ROUTE_SLAUGHTER_BASE + "/return-purchases"; +export const ROUTE_SLAUGHTER_TRADING_PANEL = + ROUTE_SLAUGHTER_BASE + "/requests/trade-panel"; +export const ROUTE_SLAUGHTER_ROUTE_SUB_UNITS = + ROUTE_SLAUGHTER_BASE + "/sub-unit"; +export const ROUTE_SLAUGHTER_ROUTE_MANAGE_DISPENSERS = + ROUTE_SLAUGHTER_BASE + "/manage-dispensers"; +export const ROUTE_SLAUGHTER_ROUTE_MANAGE_DELEGATES = + ROUTE_SLAUGHTER_BASE + "/manage-delegates"; + +export const ROUTE_SLAUGHTER_ROUTE_DEVICES = ROUTE_SLAUGHTER_BASE + "/devices"; +// PROVINCE + +export const ROUTE_PROVINCE_TRADING_PANEL = + ROUTE_PROVINCE_BASE + "/requests/trade-panel"; + +export const ROUTE_PROVINCE_USER_PROFILE = + "/dashboard/profile" + ROUTE_PROVINCE_BASE; +export const ROUTE_PROVINCE_REQUESTS = ROUTE_PROVINCE_BASE + "/requests"; +export const ROUTE_PROVINCE_ACTIVE_REQUESTS = + ROUTE_PROVINCE_BASE + "/requests/active"; +export const ROUTE_PROVINCE_ALLOCATION_REQUESTS = + ROUTE_PROVINCE_BASE + "/requests/allocation"; +export const ROUTE_PROVINCE_ALLOCATED_REQUESTS = + ROUTE_PROVINCE_BASE + "/requests/allocated"; +export const ROUTE_PROVINCE_AUTO_ALLOCATION_REQUESTS = + ROUTE_PROVINCE_BASE + "/requests/auto-allocation"; +export const ROUTE_PROVINCE_CHAINS = ROUTE_PROVINCE_BASE + "/chains"; +export const ROUTE_PROVINCE_CITY_NEW_REQUESTS = + ROUTE_PROVINCE_BASE + "/requests/city"; +export const ROUTE_PROVINCE_NEW_REQUESTS = + ROUTE_PROVINCE_BASE + "/requests/new"; +export const ROUTE_PROVINCE_STATEMENTـOFـNEED_REQUESTS = + ROUTE_PROVINCE_BASE + "/requests/statement-of-need"; +export const ROUTE_PROVINCE_REJECTED_REQUESTS = + ROUTE_PROVINCE_BASE + "/requests/rejected"; +export const ROUTE_PROVINCE_ARCHIVED_REQUESTS = + ROUTE_PROVINCE_BASE + "/requests/archived"; +export const ROUTE_PROVINCE_ISSUANCE_OF_LETTER = + ROUTE_PROVINCE_BASE + "/requests/issuance-of-letter"; +export const ROUTE_PROVINCE_FREE_SALES_REQUESTS = + ROUTE_PROVINCE_BASE + "/requests/free-sale"; +export const ROUTE_PROVINCE_FILE = ROUTE_PROVINCE_BASE + "/file/"; +export const ROUTE_PROVINCE_FILE_ROUTE = ROUTE_PROVINCE_BASE + "/file/:id"; +export const ROUTE_PROVINCE_AUCTION = ROUTE_PROVINCE_BASE + ROUTE_AUCTION_BASE; +export const ROUTE_PROVINCE_SEND_MESSAGE = ROUTE_PROVINCE_BASE + "/sendmessage"; +export const ROUTE_PROVINCE_SEND_ANNOUNCEMENT = + ROUTE_PROVINCE_BASE + "/announcement"; +export const ROUTE_PROVINCE_SEND_REPORT = ROUTE_PROVINCE_BASE + "/sendreport"; +export const ROUTE_PROVINCE_TICKET = ROUTE_PROVINCE_BASE + "/ticket/"; +export const ROUTE_PROVINCE_VIEW_TICKET = + ROUTE_PROVINCE_BASE + "/ticket/:id/:create"; +export const ROUTE_PROVINCE_ROUTE_TICKET = ROUTE_PROVINCE_BASE + "/ticket/"; +export const ROUTE_PROVINCE_AWAITING_PAYMENT_REQUESTS = + ROUTE_PROVINCE_BASE + "/requests/awaitpayment"; +export const ROUTE_PROVINCE_AWAITING_INSPECTION_REQUESTS = + ROUTE_PROVINCE_BASE + "/requests/awaitinspection"; +export const ROUTE_PROVINCE_STATICS = ROUTE_PROVINCE_BASE + "/statics"; +export const ROUTE_PROVINCE_NATIONAL_STATICS = + ROUTE_PROVINCE_BASE + "/national-statics"; +export const ROUTE_PROVINCE_HATCHING = ROUTE_PROVINCE_BASE + "/hatching"; +export const ROUTE_PROVINCE_NEW_REQUEST = ROUTE_PROVINCE_BASE + "/request"; +export const ROUTE_PROVINCE_KILLER_MANAGMENT = + ROUTE_PROVINCE_BASE + "/killer-managment"; +export const ROUTE_PROVINCE_ROUTE_ALLOCATIONS = + ROUTE_PROVINCE_BASE + "/allocations/"; +export const ROUTE_PROVINCE_ROUTE_MANAGE_GUILDS = + ROUTE_PROVINCE_BASE + "/manage-guilds/"; +export const ROUTE_PROVINCE_ROUTE_MANAGE_STEWARDS = + ROUTE_PROVINCE_BASE + "/manage-stewards/"; +export const ROUTE_PROVINCE_ROUTE_IN_PROVINCE_GUILDS = + ROUTE_PROVINCE_BASE + "/manage-guilds/in-province"; +export const ROUTE_PROVINCE_ROUTE_OUT_PROVINCE_GUILDS = + ROUTE_PROVINCE_BASE + "/manage-guilds/out-province"; +export const ROUTE_PROVINCE_ROUTE_OUT_PROVINCE_LEGAL_GUILDS = + ROUTE_PROVINCE_BASE + "/manage-guilds/out-province/legal-guilds"; +export const ROUTE_PROVINCE_ROUTE_OUT_PROVINCE_TRUE_GUILDS = + ROUTE_PROVINCE_BASE + "/manage-guilds/out-province/true-guilds"; +export const ROUTE_PROVINCE_ROUTE_IN_PROVINCE_LEGAL_GUILDS = + ROUTE_PROVINCE_BASE + "/manage-guilds/in-province/legal-guilds"; +export const ROUTE_PROVINCE_ROUTE_IN_PROVINCE_TRUE_GUILDS = + ROUTE_PROVINCE_BASE + "/manage-guilds/in-province/true-guilds"; +export const ROUTE_PROVINCE_ROUTE_GUILDS = + ROUTE_PROVINCE_BASE + "/manage-guilds/guilds"; +export const ROUTE_PROVINCE_ROUTE_IN_PROVINCE_STEWARDS = + ROUTE_PROVINCE_BASE + "/manage-guilds/in-province/stewards"; +export const ROUTE_PROVINCE_ROUTE_GUILDS_SETTINGS = + ROUTE_PROVINCE_BASE + "/manage-guilds/settings"; +export const ROUTE_PROVINCE_ROUTE_AGENT_SHARE = + ROUTE_PROVINCE_BASE + "/agent-share"; +export const ROUTE_PROVINCE_ROUTE_STEWARD_SHARE = + ROUTE_PROVINCE_BASE + "/steward-share"; +export const ROUTE_PROVINCE_ROUTE_AGENT_SHARE_ID = + ROUTE_PROVINCE_BASE + "/agent-share/:id/:date"; +export const ROUTE_PROVINCE_ROUTE_IN_PROVINCE_GUILDS_REQUESTS = + ROUTE_PROVINCE_BASE + "/manage-guilds/in-province/guilds-requests"; +export const ROUTE_PROVINCE_ROUTE_MANAGE_PROCESS = + ROUTE_PROVINCE_BASE + "/manage-process/"; +export const ROUTE_PROVINCE_ROUTE_MANAGE_PROCESS_SLAUGHTER = + ROUTE_PROVINCE_BASE + "/manage-process/slaughter"; +export const ROUTE_PROVINCE_ROUTE_MANAGE_PROCESS_KILLPLACE = + ROUTE_PROVINCE_BASE + "/manage-process/killplace"; +export const ROUTE_PROVINCE_ROUTE_MANAGE_PROCESS_BUY_REQ = + ROUTE_PROVINCE_BASE + "/manage-process/buy-req"; +export const ROUTE_PROVINCE_ROUTE_MANAGE_PROCESS_POLICY_COUNCIL = + ROUTE_PROVINCE_BASE + "/manage-process/policy-council"; +export const ROUTE_PROVINCE_ROUTE_POLICY_COUNCIL_POULTRY_CHOOSE_SLAUGHTER = + ROUTE_PROVINCE_BASE + "/policy-council/poultry-choose-slaughter"; +export const ROUTE_PROVINCE_ROUTE_POLICY_COUNCIL_FREE_SALE = + ROUTE_PROVINCE_BASE + "/policy-council/free-sale"; +export const ROUTE_PROVINCE_ROUTE_POLICY_COUNCIL_DIRECT_BUY = + ROUTE_PROVINCE_BASE + "/policy-council/direct-buy"; +export const ROUTE_PROVINCE_ROUTE_POLICY_COUNCIL_KILLHOUSE_GUILDS = + ROUTE_PROVINCE_BASE + "/policy-council/killhouse-guilds"; +export const ROUTE_PROVINCE_ROUTE_CASE_STATUS = + ROUTE_PROVINCE_BASE + "/case-status/"; +export const ROUTE_PROVINCE_ROUTE_FILES_STATE = + ROUTE_PROVINCE_BASE + "/files-state/"; +export const ROUTE_PROVINCE_ASSIGN_VET_FARM = + ROUTE_PROVINCE_BASE + "/assign-farm/"; +export const ROUTE_PROVINCE_CARS = ROUTE_PROVINCE_BASE + "/cars/"; +export const ROUTE_PROVINCE_USERS = ROUTE_PROVINCE_BASE + "/users/"; +export const ROUTE_PROVINCE_POULTRIES = ROUTE_PROVINCE_BASE + "/poultries/"; +export const ROUTE_PROVINCE_POULTRIES_DETAILS = + ROUTE_PROVINCE_BASE + "/poultries/:key"; +export const ROUTE_PROVINCE_GUILD_TRANSACTIONS = + ROUTE_PROVINCE_BASE + "/transactions/"; +export const ROUTE_PROVINCE_SLAUGHTERS = + ROUTE_PROVINCE_BASE + "/slaugter-houses/"; +export const ROUTE_PROVINCE_SLAUGHTERS_MONITORING_BUYERS = + ROUTE_PROVINCE_BASE + "/slaugter-houses/monitoring-buyers"; +export const ROUTE_PROVINCE_SLAUGHTERS_MANAGE = + ROUTE_PROVINCE_BASE + "/slaugter-houses/manage"; +export const ROUTE_PROVINCE_ROUTE_SMS = ROUTE_PROVINCE_BASE + "/sms"; +export const ROUTE_PROVINCE_ROUTE_SMS_SEND = ROUTE_PROVINCE_BASE + "/sms/send"; +export const ROUTE_PROVINCE_ROUTE_SMS_MANAGE = + ROUTE_PROVINCE_BASE + "/sms/manage"; +export const ROUTE_PROVINCE_PRICING3 = ROUTE_PROVINCE_BASE + "/pricing"; +export const ROUTE_PROVINCE_BARS = ROUTE_PROVINCE_BASE + "/bars"; +export const ROUTE_PROVINCE_OPERATOR_USER_FILE_ROUTE = + ROUTE_PROVINCE_BASE + "/userfile/:userid"; +export const ROUTE_PROVINCE_OPERATOR_USER_FILE = + ROUTE_PROVINCE_BASE + "/userfile/"; +export const ROUTE_PROVINCE_MANAGE_USERS = + ROUTE_PROVINCE_BASE + "/manage-users/"; +export const ROUTE_PROVINCE_PAYING_FEES_REQUESTS = + ROUTE_PROVINCE_BASE + "/requests/payment-of-fees"; +export const ROUTE_PROVINCE_PAYING_FEES_REQUESTS_VIEW = + ROUTE_PROVINCE_BASE + "/requests/payment-of-fees/:type/:key"; +export const ROUTE_PROVINCEـFREE_BUY = + ROUTE_PROVINCE_BASE + "/requests/free-buy"; +export const ROUTE_PROVINCE_ROUTE_NATIONAL_INFO_DISTRIBUTION_DETAILS = + ROUTE_PROVINCE_BASE + "/national-slaughter-info/:unitkey/:name/:type"; +export const ROUTE_PROVINCEـBROADCAST_MANAGEMENT = + ROUTE_PROVINCE_BASE + "/broadcast-management"; +export const ROUTE_PROVINCE_REPORT = ROUTE_PROVINCE_BASE + "/report"; +export const ROUTE_PROVINCE_PRODUCTS = ROUTE_PROVINCE_BASE + "/products"; +export const ROUTE_PROVINCE_TRANSACTIONS = + ROUTE_PROVINCE_BASE + "/requests/transactions"; +export const ROUTE_PROVINCE_TRANSACTIONS_VIEW = + ROUTE_PROVINCE_BASE + "/requests/transactions/:key/:name"; +export const ROUTE_PROVINCEـEXPORT = ROUTE_PROVINCE_BASE + "/requests/export"; +export const ROUTE_PROVINCEـVISOR_STATICS = + ROUTE_PROVINCE_BASE + "/visor-statics"; +export const ROUTE_PROVINCEـVISOR_STATICS_CHARTS = + ROUTE_PROVINCE_BASE + "/visor-statics/charts"; +export const ROUTE_PROVINCEـVISOR_STATICS_PREDICTION = + ROUTE_PROVINCE_BASE + "/visor-statics/prediction/"; +export const ROUTE_PROVINCEـVISOR_STATICS_PREDICTION_VIEW = + ROUTE_PROVINCE_BASE + "/visor-statics/prediction/:key/:date"; +export const ROUTE_PROVINCEـHATCHINGS = + ROUTE_PROVINCE_BASE + "/manage-hatchings"; +export const ROUTE_PROVINCEـHATCHINGS_DETAILS = + ROUTE_PROVINCE_BASE + "/manage-hatchings/:key"; +export const ROUTE_PROVINCE_DISPENSERS = ROUTE_PROVINCE_BASE + "/dispensers"; +export const ROUTE_PROVINCE_COLD_HOUSES = + ROUTE_PROVINCE_BASE + "/cold-house-management"; +export const ROUTE_PROVINCE_COLD_HOUSES_MANAGEMENT = + ROUTE_PROVINCE_BASE + "/cold-houses-management"; +export const ROUTE_PROVINCE_COLD_HOUSES_MANAGEMENT_VIEW = + ROUTE_PROVINCE_BASE + "/cold-houses-management/:key/:name/:type"; +export const ROUTE_PROVINCE_DISPENSERS_MANAGEMENT = + ROUTE_PROVINCE_BASE + "/dispensers-management"; +export const ROUTE_PROVINCE_DISPENSER_DETAILS = + ROUTE_PROVINCE_BASE + "/dispenser-data"; +export const ROUTE_PROVINCE_DISPENSER_DETAILS_VIEW = + ROUTE_PROVINCE_BASE + "/dispenser-data/:key"; +export const ROUTE_PROVINCE_DISPENSERS_STEWARDS = + ROUTE_PROVINCE_BASE + "/dispensers-stewards"; +export const ROUTE_PROVINCE_DISPENSERS_KILLHOUSES = + ROUTE_PROVINCE_BASE + "/dispensers-killhouses"; +export const ROUTE_PROVINCE_DISPENSERS_KILLHOUSES_VIEW = + ROUTE_PROVINCE_BASE + "/dispensers-killhouses/:key/:name"; +export const ROUTE_PROVINCE_DISPENSERS_INVENTORY = + ROUTE_PROVINCE_BASE + "/dispensers-inventory"; +export const ROUTE_PROVINCE_DISPENSERS_SELL_CARCASS = + ROUTE_PROVINCE_BASE + "/dispensers-sell-carcass"; +export const ROUTE_PROVINCE_SUB_SECTORS_WAGE = + ROUTE_PROVINCE_BASE + "/subsectors-wage"; +export const ROUTE_PROVINCE_SUB_SECTORS_CITY_SHARES = + ROUTE_PROVINCE_BASE + "/subsectors-city-shares"; +export const ROUTE_PROVINCE_SUB_SECTORS_STEWARD_SHARES = + ROUTE_PROVINCE_BASE + "/subsectors-steward-shares"; +export const ROUTE_PROVINCE_SUB_SECTORS_VET_FARM_SHARES = + ROUTE_PROVINCE_BASE + "/subsectors-vet-farm-shares"; +export const ROUTE_PROVINCE_SETTLEMENTS = ROUTE_PROVINCE_BASE + "/settlements"; +export const ROUTE_PROVINCE_ROUTE_KILLERS_WAGES = + ROUTE_PROVINCE_BASE + "/requests/payment-of-fees-killers"; +export const ROUTE_PROVINCE_ROUTE_KILLERS_WAGES_DETAILS = + ROUTE_PROVINCE_BASE + "/requests/payment-of-fees-killers/:key"; +export const ROUTE_PROVINCE_DIFFRENCE_KILLER = + ROUTE_PROVINCE_BASE + "/manage-hatchings/diffrence-killer"; +export const ROUTE_PROVINCE_DIFFRENCE_KILLER_SLAUGHTER = + ROUTE_PROVINCE_BASE + "/manage-hatchings/diffrence-killer-slaughter"; +export const ROUTE_PROVINCE_INCREASE_HATCHING = + ROUTE_PROVINCE_BASE + "/hatching/increase-hatching"; +export const ROUTE_PROVINCE_DASHBOARD = ROUTE_PROVINCE_BASE + "/dashbord"; +export const ROUTE_PROVINCE_SALE_DESTRIBUTION_DETAILS = + ROUTE_PROVINCE_BASE + "/requests/distribution"; +export const ROUTE_PROVINCE_DASHBOARD_NEWS = + ROUTE_PROVINCE_BASE + "/dashboard/news"; +export const ROUTE_PROVINCE_POULTRY_LIVESTOCK_EXPERTS = + ROUTE_PROVINCE_BASE + "/livestock-experts"; +export const ROUTE_PROVINCE_RETURN_PURCHASES = + ROUTE_PROVINCE_BASE + "/return-purchases"; + +// VETFARM +export const ROUTE_VETFARM_USER_PROFILE = + "/dashboard/profile" + ROUTE_VETFARM_BASE; +export const ROUTE_VETFARM_REGISTER_INFO = ROUTE_VETFARM_BASE + "/farminfo"; +export const ROUTE_VETFARM_INSPECTIONS_ROUTE = + ROUTE_VETFARM_BASE + "/inspections/:inspectionid"; +export const ROUTE_VETFARM_INSPECTIONS = ROUTE_VETFARM_BASE + "/inspections/"; +export const ROUTE_VETFARM_FILE = ROUTE_VETFARM_BASE + "/file/"; +export const ROUTE_VETFARM_FILE_ROUTE = ROUTE_VETFARM_BASE + "/file/:id"; +export const ROUTE_VETFARM_TICKET = ROUTE_VETFARM_BASE + "/ticket/"; +export const ROUTE_VETFARM_VIEW_TICKET = ROUTE_VETFARM_BASE + "/ticket/:id"; +export const ROUTE_VETFARM_ROUTE_TICKET = ROUTE_VETFARM_BASE + "/ticket/"; +export const ROUTE_VETFARM_ROUTE_HATCHING = ROUTE_VETFARM_BASE + "/hatching/"; +export const ROUTE_VETFARM_ROUTE_ALLOCATIONS = + ROUTE_VETFARM_BASE + "/allocations/"; +export const ROUTE_VETFARM_HATCHING = ROUTE_VETFARM_BASE + "/hatchings"; +export const ROUTE_VETFARM_ROUTE_INSPECTION = + ROUTE_VETFARM_BASE + "/inspection"; + +// Vet supervisor +export const VETـSUPERVISOR_USER_PROFILE = + "/dashboard/profile/" + ROUTE_VETـSUPERVISOR_BASE; +export const ROUTE_VETـSUPERVISOR_HATCHING = + ROUTE_VETـSUPERVISOR_BASE + "/hatching"; +export const ROUTE_VETـSUPERVISOR_ALLOCATIONS = + ROUTE_VETـSUPERVISOR_BASE + "/allocations"; +export const ROUTE_VETـSUPERVISOR_ILLEGALـKILLING = + ROUTE_VETـSUPERVISOR_BASE + "/illegal-killing"; +export const ROUTE_VETـSUPERVISOR_KILLS_STATS = + ROUTE_VETـSUPERVISOR_BASE + "/kill-stats"; +export const ROUTE_VETـSUPERVISOR_STATICS = + ROUTE_VETـSUPERVISOR_BASE + "/visor-statics"; +export const ROUTE_VETـSUPERVISOR_STATICS_CHARTS = + ROUTE_VETـSUPERVISOR_BASE + "/visor-statics/charts"; +export const ROUTE_VETـSUPERVISOR_STATICS_PREDICTION = + ROUTE_VETـSUPERVISOR_BASE + "/visor-statics/prediction/"; +export const ROUTE_VETـSUPERVISOR_STATICS_PREDICTION_VIEW = + ROUTE_VETـSUPERVISOR_BASE + "/visor-statics/prediction/:key/:date"; +export const ROUTE_VETـSUPERVISOR_ROUTE_ALLOCATIONS = + ROUTE_VETـSUPERVISOR_BASE + "/allocations/"; +export const ROUTE_VETـSUPERVISOR_ROUTE_FILES_STATE = + ROUTE_VETـSUPERVISOR_BASE + "/files-state/"; +export const ROUTE_VETـSUPERVISOR_REPORTING = + ROUTE_VETـSUPERVISOR_BASE + "/reporting"; +export const ROUTEـVET_SUPERVISOR_POULTRIES = + ROUTE_VETـSUPERVISOR_BASE + "/poultries/"; +export const ROUTEـVET_SUPERVISOR_POULTRIES_DETAILS = + ROUTE_VETـSUPERVISOR_BASE + "/poultries/:key"; + +//DRIVER +export const DRIVER_USER_PROFILE = "/dashboard/profile/" + ROUTE_DRIVER_BASE; +export const ROUTE_DRIVER_REQUESTS = ROUTE_DRIVER_BASE + "/requests"; +export const ROUTE_DRIVER_CARS = ROUTE_DRIVER_BASE + "/cars"; + +//INSPECTOR +export const ROUTE_INSPECTOR_USER_PROFILE = + "/dashboard/profile" + ROUTE_PROVINCE_INSPECTOR_BASE; +export const ROUTE_INSPECTOR_REQUESTS = + ROUTE_PROVINCE_INSPECTOR_BASE + "/requests"; +export const ROUTE_INSPECTOR_REQUESTS_NEW_REQUESTS = + ROUTE_PROVINCE_INSPECTOR_BASE + "/requests/new"; +export const ROUTE_INSPECTOR_REJECTED_REQUESTS = + ROUTE_PROVINCE_INSPECTOR_BASE + "/requests/rejected"; +export const ROUTE_INSPECTOR_ARCHIVED_REQUESTS = + ROUTE_PROVINCE_INSPECTOR_BASE + "/requests/archived"; +export const ROUTE_INSPECTOR_FILE = ROUTE_PROVINCE_INSPECTOR_BASE + "/file/"; +export const ROUTE_INSPECTOR_FILE_ROUTE = + ROUTE_PROVINCE_INSPECTOR_BASE + "/file/:id"; +export const ROUTE_PROVINCE_USER_MANAGEMENT = + ROUTE_PROVINCE_INSPECTOR_BASE + "/users"; +export const ROUTE_PROVINCE_CAR_MANAGEMENT = + ROUTE_PROVINCE_INSPECTOR_BASE + "/cars"; +export const ROUTE_PROVINCE_INSPECTOR_PRICING = + ROUTE_PROVINCE_INSPECTOR_BASE + "/pricing"; + +export const ROUTE_PROVINCE_USER_FILE_ROUTE = + ROUTE_PROVINCE_INSPECTOR_BASE + "/userfile/:userid"; +export const ROUTE_PROVINCE_USER_FILE = + ROUTE_PROVINCE_INSPECTOR_BASE + "/userfile/"; +export const ROUTE_PROVINCE_INSPECTOR_TICKET = + ROUTE_PROVINCE_INSPECTOR_BASE + "/ticket/"; +export const ROUTE_PROVINCE_INSPECTOR_VIEW_TICKET = + ROUTE_PROVINCE_INSPECTOR_BASE + "/ticket/:id/:create"; +export const ROUTE_PROVINCE_INSPECTOR_ROUTE_TICKET = + ROUTE_PROVINCE_INSPECTOR_BASE + "/ticket/"; +export const ROUTE_PROVINCE_INSPECTOR_REPORTING = + ROUTE_PROVINCE_INSPECTOR_BASE + "/reporting"; +export const ROUTE_PROVINCE_INSPECTOR_AWAITING_PAYMENT_REQUESTS = + ROUTE_PROVINCE_INSPECTOR_BASE + "/requests/awaitpayment"; +export const ROUTE_PROVINCE_INSPECTOR_AWAITING_INSPECTION_REQUESTS = + ROUTE_PROVINCE_INSPECTOR_BASE + "/requests/awaitinspection"; +export const ROUTE_INSPECTOR_STATICS = + ROUTE_PROVINCE_INSPECTOR_BASE + "/statics"; +export const ROUTE_INSPECTOR_ASSIGN_VET_FARM = + ROUTE_PROVINCE_INSPECTOR_BASE + "/assgin-vet-farm"; + +// export const CHICKEN_STOCK_MARKET = "/exchange"; + +//PROVINCE FINANCIAL +export const ROUTE_PROVINCE_FINANCIAL_PENDING_REQUESTS = + ROUTE_PROVINCE_FINANCIAL_BASE + "/requests/pending"; +export const ROUTE_PROVINCE_FINANCIAL_CHECK_PAYED_FACTOR_REQUESTS = + ROUTE_PROVINCE_FINANCIAL_BASE + "/requests/check-payed-factors"; +export const ROUTE_PROVINCE_FINANCIAL_TRANSACTIONS = + ROUTE_PROVINCE_FINANCIAL_BASE + "/requests/transactions"; +export const ROUTE_PROVINCE_FINANCIAL_TRANSACTIONS_VIEW = + ROUTE_PROVINCE_FINANCIAL_BASE + "/requests/transactions/:key/:name"; +export const ROUTE_PROVINCE_FINANCIAL_FINAL_FACTORS_REQUESTS = + ROUTE_PROVINCE_FINANCIAL_BASE + "/requests/final-factors"; +export const ROUTE_PROVINCE_FINANCIAL_REQUESTS = + ROUTE_PROVINCE_FINANCIAL_BASE + "/requests"; +export const ROUTE_PROVINCE_FINANCIAL_ACTIVE_REQUESTS = + ROUTE_PROVINCE_FINANCIAL_BASE + "/requests/active"; +export const ROUTE_PROVINCE_FINANCIAL_SETTLEMENT = + ROUTE_PROVINCE_FINANCIAL_BASE + "/settlement"; +export const ROUTE_PROVINCE_FINANCIAL_USER_PROFILE = + "/dashboard/profile" + ROUTE_PROVINCE_FINANCIAL_BASE; +export const ROUTE_PROVINCE_FINANCIAL_REJECTED_REQUESTS = + ROUTE_PROVINCE_FINANCIAL_BASE + "/requests/rejected"; +export const ROUTE_PROVINCE_FINANCIAL_NEW_REQUESTS = + ROUTE_PROVINCE_FINANCIAL_BASE + "/requests/new"; +export const ROUTE_PROVINCE_FINANCIAL_ARCHIVED_REQUESTS = + ROUTE_PROVINCE_FINANCIAL_BASE + "/requests/archived"; +export const ROUTE_PROVINCE_FINANCIAL_FILE_ROUTE = + ROUTE_PROVINCE_FINANCIAL_BASE + "/file/:id"; +export const ROUTE_PROVINCE_FINANCIAL_FILE = + ROUTE_PROVINCE_FINANCIAL_BASE + "/file/"; +export const ROUTE_PROVINCE_PRICING = + ROUTE_PROVINCE_FINANCIAL_BASE + "/pricing"; +export const ROUTE_PROVINCE_FINANCIAL_TICKET = + ROUTE_PROVINCE_FINANCIAL_BASE + "/ticket/"; +export const ROUTE_PROVINCE_FINANCIAL_VIEW_TICKET = + ROUTE_PROVINCE_FINANCIAL_BASE + "/ticket/:id/:create"; +export const ROUTE_PROVINCE_FINANCIAL_ROUTE_TICKET = + ROUTE_PROVINCE_FINANCIAL_BASE + "/ticket/"; +export const ROUTE_PROVINCE_FINANCIAL_ROUTE_DEBT = + ROUTE_PROVINCE_FINANCIAL_BASE + "/debt/"; +export const ROUTE_PROVINCE_FINANCIAL_COMPLAINTS = + ROUTE_PROVINCE_FINANCIAL_BASE + "/complaints"; +export const ROUTE_PROVINCE_FINANCIAL_DOCUMENT_REGISTRATION = + ROUTE_PROVINCE_FINANCIAL_BASE + "/documentregister"; +export const ROUTE_PROVINCE__FINANCIAL_USER_FINACIAL_FILE_ROUTE = + ROUTE_PROVINCE_FINANCIAL_BASE + "/userfile/:userid/:profileid"; +export const ROUTE_PROVINCE__FINANCIAL_USER_FINACIAL_FILE = + ROUTE_PROVINCE_FINANCIAL_BASE + "/userfile/"; +export const ROUTE_PROVINCE_FINANCIAL_AWAITING_PAYMENT_REQUESTS = + ROUTE_PROVINCE_FINANCIAL_BASE + "/requests/awaitpayment"; +export const ROUTE_PROVINCE_FINANCIAL_AWAITING_INSPECTION_REQUESTS = + ROUTE_PROVINCE_FINANCIAL_BASE + "/requests/awaitinspection"; +export const ROUTE_PROVINCE_FINANCIAL_STATICS = + ROUTE_PROVINCE_FINANCIAL_BASE + "/statics"; +export const ROUTE_PROVINCE_FINANCIAL_SUB_SECTORS_WAGE = + ROUTE_PROVINCE_FINANCIAL_BASE + "/subsectors-wage"; +export const ROUTE_PROVINCE_FINANCIAL_SUB_SECTORS_CITY_SHARES = + ROUTE_PROVINCE_FINANCIAL_BASE + "/subsectors-city-shares"; +export const ROUTE_PROVINCE_FINANCIAL_SUB_SECTORS_STEWARD_SHARES = + ROUTE_PROVINCE_FINANCIAL_BASE + "/subsectors-steward-shares"; +export const ROUTE_PROVINCE_FINANCIAL_SUB_SECTORS_VET_FARM_SHARES = + ROUTE_PROVINCE_FINANCIAL_BASE + "/subsectors-vet-farm-shares"; + +//SLAUGHTER HOUSE VET +export const ROUTE_SLAUGHTER_HOUSE_VET_REQUESTS = + ROUTE_SLAUGHTER_HOUSE_VET_BASE + "/requests"; +export const ROUTE_SLAUGHTER_HOUSE_VET_USER_PROFILE = + "/dashboard/profile" + ROUTE_SLAUGHTER_HOUSE_VET_BASE; +export const ROUTE_SLAUGHTER_HOUSE_VET_ENTER_BAR_INFO = + ROUTE_SLAUGHTER_HOUSE_VET_BASE + "/requests/bar-info"; +export const ROUTE_SLAUGHTER_HOUSE_VET_NEW_REQUESTS = + ROUTE_SLAUGHTER_HOUSE_VET_BASE + "/requests/new"; +export const ROUTE_SLAUGHTER_HOUSE_VET_ACTIVE_REQUESTS = + ROUTE_SLAUGHTER_HOUSE_VET_BASE + "/requests/active"; +export const ROUTE_SLAUGHTER_HOUSE_VET_REJECTED_REQUESTS = + ROUTE_SLAUGHTER_HOUSE_VET_BASE + "/requests/rejected"; +export const ROUTE_SLAUGHTER_HOUSE_VET_ARCHIVED_REQUESTS = + ROUTE_SLAUGHTER_HOUSE_VET_BASE + "/requests/archived"; +export const ROUTE_SLAUGHTER_HOUSE_VET_FILE_ROUTE = + ROUTE_SLAUGHTER_HOUSE_VET_BASE + "/file/:id"; +export const ROUTE_SLAUGHTER_HOUSE_VET_FREE_BUY_ROUTE = + ROUTE_SLAUGHTER_HOUSE_VET_BASE + "/requests/out-province"; +export const ROUTE_SLAUGHTER_HOUSE_VET_FILE = + ROUTE_SLAUGHTER_HOUSE_VET_BASE + "/file/"; +export const ROUTE_SLAUGHTER_HOUSE_VET_COMPLAINTS = + ROUTE_SLAUGHTER_HOUSE_VET_BASE + "/requests/complaints"; + +//Admin +export const ROUTE_ADMIN_REQUESTS = ROUTE_ADMIN_BASE + "/requests"; +export const ROUTE_ADMIN_VISOR_STATICS = ROUTE_ADMIN_BASE + "/visor-statics"; +export const ROUTE_ADMIN_VISOR_STATICS_CHARTS = + ROUTE_ADMIN_BASE + "/visor-statics/charts"; +export const ROUTE_ADMIN_VISOR_STATICS_PREDICTION = + ROUTE_ADMIN_BASE + "/visor-statics/prediction/"; +export const ROUTE_ADMIN_CREATE_NEW_REQUEST = + ROUTE_ADMIN_BASE + "/requests/create"; +export const ROUTE_ADMIN_HATCHING = ROUTE_ADMIN_BASE + "/requests/hatching"; +export const ROUTE_ADMIN_NEW_REQUESTS = ROUTE_ADMIN_BASE + "/requests/new"; +export const ROUTE_ADMIN_REJECTED_REQUESTS = ROUTE_ADMIN_BASE + "/requests/new"; + +export const ROUTE_ADMIN_AWAITING_PAYMENT_REQUESTS = + ROUTE_ADMIN_BASE + "/requests/awaitpayment"; + +export const ROUTE_ADMIN_AWAITING_INSPECTION_REQUESTS = + ROUTE_ADMIN_BASE + "/requests/awaitinspection"; + +export const ROUTE_ADMIN_ARCHIVED_REQUESTS = + ROUTE_ADMIN_BASE + "/requests/archived"; +export const ROUTE_ADMIN_ACTIVE_REQUESTS = + ROUTE_ADMIN_BASE + "/requests/active"; +export const ROUTE_ADMIN_FILE = ROUTE_ADMIN_BASE + "/file/"; +export const ROUTE_ADMIN_FILE_ROUTE = ROUTE_ADMIN_BASE + "/file/:id"; + +export const ROUTE_ADMIN_STATICS = ROUTE_ADMIN_BASE + "/statics"; +export const ROUTE_ADMIN_NATIONAL_STATICS = + ROUTE_ADMIN_BASE + "/national-statics"; + +//Jahad +export const ROUTE_JAHAD_USER_PROFILE = "/dashboard/profile" + ROUTE_JAHAD_BASE; +export const ROUTE_JAHAD_REQUESTS = ROUTE_JAHAD_BASE + "/requests"; +export const ROUTE_JAHAD_KILLS_STATS = ROUTE_JAHAD_BASE + "/kill-stats"; +export const ROUTE_JAHAD_ILLEGALـKILLING = + ROUTE_JAHAD_BASE + "/illegal-killing"; +export const ROUTE_JAHAD_PRICING = ROUTE_JAHAD_BASE + "/pricing"; +export const ROUTE_JAHAD_FILES_STATE = ROUTE_JAHAD_BASE + "/files-state"; + +// steward + +export const ROUTE_STEWARD_USER_PROFILE = + "/dashboard/profile" + ROUTE_STEWARD_BASE; +export const ROUTE_STEWARD_INVENTORY = ROUTE_STEWARD_BASE + "/inventory"; +export const ROUTE_STEWARD_INVENTORY_STOCK = + ROUTE_STEWARD_BASE + "/inventory/stock"; +export const ROUTE_STEWARD_SALE_IN_PROVINCE = + ROUTE_STEWARD_BASE + "/inventory/in/sale"; +export const ROUTE_STEWARD_PURCHASE_OUT_PROVINCE = + ROUTE_STEWARD_BASE + "/inventory/out/purchase"; +export const ROUTE_STEWARD_SALE_OUT_PROVINCE = + ROUTE_STEWARD_BASE + "/inventory/out/sale"; +export const ROUTE_STEWARD_MANAGE_GUILDS = + ROUTE_STEWARD_BASE + "/manage-guilds"; +export const ROUTE_STEWARD_DAILY_LIST = ROUTE_STEWARD_BASE + "/dailylist"; +export const ROUTE_STEWARD_SEGMENT = ROUTE_STEWARD_BASE + "/segment"; +export const ROUTE_STEWARD_ROUTE_SUB_UNITS = ROUTE_STEWARD_BASE + "/sub-units"; +export const ROUTE_STEWARD_ROUTE_MANAGE_DISPENSERS = + ROUTE_STEWARD_BASE + "/manage-dispensers"; +export const ROUTE_STEWARD_ROUTE_MANAGE_DELEGATES = + ROUTE_STEWARD_BASE + "/manage-delegates"; +export const ROUTE_STEWARD_ROUTE_DEVICES = ROUTE_STEWARD_BASE + "/devices"; + +// Commerce +export const ROUTE_COMMERCE_REQUESTS = ROUTE_COMMERCE_BASE + "/requests"; +export const ROUTE_COMMERCE_ROUTE_MANAGE_GUILDS = + ROUTE_COMMERCE_BASE + "/manage-guilds/"; +export const ROUTE_COMMERCE_ROUTE_MANAGE_STEWARDS = + ROUTE_COMMERCE_BASE + "/manage-stewards/"; +export const ROUTE_COMMERCE_ROUTE_GUILDS = + ROUTE_COMMERCE_BASE + "/manage-guilds/guilds"; +export const ROUTE_COMMERCE_ROUTE_STEWARDS = + ROUTE_COMMERCE_BASE + "/manage-guilds/stewards"; +export const ROUTE_COMMERCE_ROUTE_GUILDS_SETTINGS = + ROUTE_COMMERCE_BASE + "/manage-guilds/settings"; +export const ROUTE_COMMERCE_ROUTE_FILES_STATE = + ROUTE_COMMERCE_BASE + "/files-state/"; +export const ROUTE_COMMERCE_ROUTE_ALLOCATIONS = + ROUTE_COMMERCE_BASE + "/allocations/"; +export const ROUTE_COMMERCE_STATICS = ROUTE_COMMERCE_BASE + "/statics"; +export const ROUTE_COMMERCE_HATCHING = ROUTE_COMMERCE_BASE + "/hatching"; +export const ROUTE_COMMERCE_PAYING_FEES_REQUESTS = + ROUTE_COMMERCE_BASE + "/requests/payment-of-fees"; +export const ROUTE_COMMERCE_VISOR_STATICS = + ROUTE_COMMERCE_BASE + "/visor-statics"; +export const ROUTE_COMMERCE_VISOR_STATICS_CHARTS = + ROUTE_COMMERCE_BASE + "/visor-statics/charts"; +export const ROUTE_COMMERCE_VISOR_STATICS_PREDICTION = + ROUTE_COMMERCE_BASE + "/visor-statics/prediction/"; +export const ROUTE_COMMERCE_VISOR_STATICS_PREDICTION_VIEW = + ROUTE_COMMERCE_BASE + "/visor-statics/prediction/:key/:date"; +export const ROUTE_COMMERCEـHATCHINGS = + ROUTE_COMMERCE_BASE + "/manage-hatchings"; +export const ROUTE_COMMERCEـHATCHINGS_DETAILS = + ROUTE_COMMERCE_BASE + "/manage-hatchings/:key"; + +// ProvinceSupervisor +export const ROUTE_PROVINCE_SUPERVISOR_REQUESTS = + ROUTE_PROVINCE_SUPERVISOR_BASE + "/requests"; +export const ROUTE_PROVINCE_SUPERVISOR_ROUTE_MANAGE_GUILDS = + ROUTE_PROVINCE_SUPERVISOR_BASE + "/manage-guilds/"; +export const ROUTE_PROVINCE_SUPERVISOR_ROUTE_MANAGE_STEWARDS = + ROUTE_PROVINCE_SUPERVISOR_BASE + "/manage-stewards/"; +export const ROUTE_PROVINCE_SUPERVISOR_ROUTE_GUILDS = + ROUTE_PROVINCE_SUPERVISOR_BASE + "/manage-guilds/guilds"; +export const ROUTE_PROVINCE_SUPERVISOR_ROUTE_STEWARDS = + ROUTE_PROVINCE_SUPERVISOR_BASE + "/manage-guilds/stewards"; +export const ROUTE_PROVINCE_SUPERVISOR_ROUTE_GUILDS_SETTINGS = + ROUTE_PROVINCE_SUPERVISOR_BASE + "/manage-guilds/settings"; +export const ROUTE_PROVINCE_SUPERVISOR_ROUTE_FILES_STATE = + ROUTE_PROVINCE_SUPERVISOR_BASE + "/files-state/"; +export const ROUTE_PROVINCE_SUPERVISOR_ROUTE_ALLOCATIONS = + ROUTE_PROVINCE_SUPERVISOR_BASE + "/allocations/"; +export const ROUTE_PROVINCE_SUPERVISOR_STATICS = + ROUTE_PROVINCE_SUPERVISOR_BASE + "/visor-statics"; +export const ROUTE_PROVINCE_SUPERVISOR_STATICS_CHARTS = + ROUTE_PROVINCE_SUPERVISOR_BASE + "/visor-statics/charts"; +export const ROUTE_PROVINCE_SUPERVISOR_STATICS_PREDICTION = + ROUTE_PROVINCE_SUPERVISOR_BASE + "/visor-statics/prediction/"; +export const ROUTE_PROVINCE_SUPERVISOR_STATICS_PREDICTION_VIEW = + ROUTE_PROVINCE_SUPERVISOR_BASE + "/visor-statics/prediction/:key/:date"; +export const ROUTE_PROVINCE_SUPERVISOR_HATCHING = + ROUTE_PROVINCE_SUPERVISOR_BASE + "/hatching"; +export const ROUTE_PROVINCE_SUPERVISOR_REPORTING = + ROUTE_PROVINCE_SUPERVISOR_BASE + "/reporting"; +export const ROUTE_PROVINCE_SUPERVISORـHATCHINGS = + ROUTE_PROVINCE_SUPERVISOR_BASE + "/manage-hatchings"; +export const ROUTE_PROVINCE_SUPERVISORـHATCHINGS_DETAILS = + ROUTE_PROVINCE_SUPERVISOR_BASE + "/manage-hatchings/:key"; +export const ROUTE_PROVINCE_SUPERVISOR_DASHBOARD = + ROUTE_PROVINCE_SUPERVISOR_BASE + "/dashbord"; + +export const ROUTE_PROVINCE_SUPERVISOR_PRICING = + ROUTE_PROVINCE_SUPERVISOR_BASE + "/pricing"; + +export const ROUTE_PROVINCE_SUPERVISOR_ROUTE_NATIONAL_INFO = + ROUTE_PROVINCE_SUPERVISOR_BASE + "/national-info"; + +export const ROUTE_PROVINCE_SUPERVISOR_ROUTE_NATIONAL_INFO_DETAILS = + ROUTE_PROVINCE_SUPERVISOR_BASE + "/national-info/:key"; + +export const ROUTE_PROVINCE_SUPERVISOR_ROUTE_NATIONAL_INFO_FARM = + ROUTE_PROVINCE_SUPERVISOR_BASE + "/national-farm-info"; + +export const ROUTE_PROVINCE_SUPERVISOR_ROUTE_NATIONAL_INFO_FARM_DETAILS = + ROUTE_PROVINCE_SUPERVISOR_BASE + "/national-farm-info/:key/:name"; + +export const ROUTE_PROVINCE_SUPERVISOR_ROUTE_NATIONAL_INFO_HATCHING_DETAILS = + ROUTE_PROVINCE_SUPERVISOR_BASE + "/national-info/:key/:name"; + +export const ROUTE_PROVINCE_SUPERVISOR_ROUTE_NATIONAL_INFO_SLAUGHTER = + ROUTE_PROVINCE_SUPERVISOR_BASE + "/national-slaughter-info"; + +export const ROUTE_PROVINCE_SUPERVISOR_ROUTE_NATIONAL_INFO_SLAUGHTER_DETAILS = + ROUTE_PROVINCE_SUPERVISOR_BASE + "/national-slaughter-info/:unitkey/:name"; + +export const ROUTE_PROVINCE_SUPERVISOR_DISPENSERS = + ROUTE_PROVINCE_SUPERVISOR_BASE + "/dispensers"; +export const ROUTE_PROVINCE_SUPERVISOR_DISPENSERS_MANAGEMENT = + ROUTE_PROVINCE_SUPERVISOR_BASE + "/dispensers/management"; +export const ROUTE_PROVINCE_SUPERVISOR_DISPENSER_DETAILS_VIEW = + ROUTE_PROVINCE_SUPERVISOR_BASE + "/dispensers/details/:key"; +export const ROUTE_PROVINCE_SUPERVISOR_DISPENSERS_STEWARDS = + ROUTE_PROVINCE_SUPERVISOR_BASE + "/dispensers/stewards"; +export const ROUTE_PROVINCE_SUPERVISOR_DISPENSERS_KILLHOUSES = + ROUTE_PROVINCE_SUPERVISOR_BASE + "/dispensers/killhouses"; +export const ROUTE_PROVINCE_SUPERVISOR_DISPENSERS_SELL_CARCASS = + ROUTE_PROVINCE_SUPERVISOR_BASE + "/dispensers/sell-carcass"; +export const ROUTE_PROVINCE_SUPERVISOR_DISPENSERS_INVENTORY = + ROUTE_PROVINCE_SUPERVISOR_BASE + "/dispensers/inventory"; +export const ROUTE_PROVINCE_SUPERVISOR_SALE_DESTRIBUTION_DETAILS = + ROUTE_PROVINCE_SUPERVISOR_BASE + "/dispensers/sale-distribution/:key"; +export const ROUTE_PROVINCE_SUPERVISOR_DISPENSERS_STOCK = + ROUTE_PROVINCE_SUPERVISOR_BASE + "/dispensers/stock"; +export const ROUTE_PROVINCE_SUPERVISOR_DISPENSERS_STOCK_KILLHOUSE = + ROUTE_PROVINCE_SUPERVISOR_BASE + "/dispensers/stock/killhouse"; +export const ROUTE_PROVINCE_SUPERVISOR_DISPENSERS_STOCK_GUILD = + ROUTE_PROVINCE_SUPERVISOR_BASE + "/dispensers/stock/guild"; +export const ROUTE_PROVINCE_SUPERVISOR_DISPENSERS_STOCK_STEWARD = + ROUTE_PROVINCE_SUPERVISOR_BASE + "/dispensers/stock/steward"; +export const ROUTE_PROVINCE_SUPERVISOR_REQUEST_DISTRIBUTION = + ROUTE_PROVINCE_SUPERVISOR_BASE + "/requests/distribution"; +export const ROUTE_PROVINCE_SUPERVISOR_REQUEST_TRANSACTIONS = + ROUTE_PROVINCE_SUPERVISOR_BASE + "/requests/transactions"; +export const ROUTE_PROVINCE_SUPERVISOR_ROUTE_INSPECTION = + ROUTE_PROVINCE_SUPERVISOR_BASE + "/inspection"; +// CityCommerce +export const ROUTE_CITY_COMMERCE_ROUTE_MANAGE_GUILDS = + ROUTE_CITY_COMMERCE_BASE + "/manage-guilds/"; +export const ROUTE_CITY_COMMERCE_ROUTE_MANAGE_STEWARDS = + ROUTE_CITY_COMMERCE_BASE + "/manage-stewards/"; +export const ROUTE_CITY_COMMERCE_ROUTE_GUILDS = + ROUTE_CITY_COMMERCE_BASE + "/manage-guilds/guilds"; +export const ROUTE_CITY_COMMERCE_ROUTE_STEWARDS = + ROUTE_CITY_COMMERCE_BASE + "/manage-guilds/stewards"; +export const ROUTE_CITY_COMMERCE_ROUTE_GUILDS_SETTINGS = + ROUTE_CITY_COMMERCE_BASE + "/manage-guilds/settings"; +export const ROUTE_CITY_COMMERCE_ROUTE_FILES_STATE = + ROUTE_CITY_COMMERCE_BASE + "/files-state/"; +export const ROUTE_CITY_COMMERCE_ROUTE_ALLOCATIONS = + ROUTE_CITY_COMMERCE_BASE + "/allocations/"; + +// CityVet +export const ROUTE_CITYVET_USER_PROFILE = + "/dashboard/profile" + ROUTE_CITYVET_BASE; +export const ROUTE_CITYVET_ROUTE_ALLOCATIONS = + ROUTE_CITYVET_BASE + "/allocations/"; +export const ROUTE_CITYVET_REGISTER_INFO = ROUTE_CITYVET_BASE + "/farminfo"; +export const ROUTE_CITYVET_HATCHING = ROUTE_CITYVET_BASE + "/hatching"; + +// CityJihad +export const ROUTE_CITY_JIHAD_STATICS = ROUTE_CITY_JAHAD_BASE + "/statics"; +export const ROUTE_CITY_JIHAD_ROUTE_FILES_STATE = + ROUTE_CITY_JAHAD_BASE + "/files-state/"; +export const ROUTE_CITY_JIHAD_ROUTE_ALLOCATIONS = + ROUTE_CITY_JAHAD_BASE + "/allocations/"; +export const ROUTE_CITY_JIHAD_ROUTE_MANAGE_GUILDS = + ROUTE_CITY_JAHAD_BASE + "/manage-guilds/"; +export const ROUTE_CITY_JIHAD_ROUTE_MANAGE_STEWARDS = + ROUTE_CITY_JAHAD_BASE + "/manage-stewards/"; +export const ROUTE_CITY_JIHAD_ROUTE_GUILDS = + ROUTE_CITY_JAHAD_BASE + "/manage-guilds/guilds"; +export const ROUTE_CITY_JIHAD_ROUTE_STEWARDS = + ROUTE_CITY_JAHAD_BASE + "/manage-guilds/stewards"; +export const ROUTE_CITY_JIHAD_ROUTE_GUILDS_SETTINGS = + ROUTE_CITY_JAHAD_BASE + "/manage-guilds/settings"; +export const ROUTE_CITY_JIHAD_DISPENSERS = + ROUTE_CITY_JAHAD_BASE + "/dispensers"; +export const ROUTE_CITY_JIHAD_DISPENSERS_MANAGEMENT = + ROUTE_CITY_JAHAD_BASE + "/dispensers/management"; +export const ROUTE_CITY_JIHAD_DISPENSER_DETAILS_VIEW = + ROUTE_CITY_JAHAD_BASE + "/dispensers/details/:key"; +export const ROUTE_CITY_JIHAD_DISPENSERS_STEWARDS = + ROUTE_CITY_JAHAD_BASE + "/dispensers/stewards"; +export const ROUTE_CITY_JIHAD_DISPENSERS_KILLHOUSES = + ROUTE_CITY_JAHAD_BASE + "/dispensers/killhouses"; +export const ROUTE_CITY_JIHAD_DISPENSERS_SELL_CARCASS = + ROUTE_CITY_JAHAD_BASE + "/dispensers/sell-carcass"; +export const ROUTE_CITY_JIHAD_DISPENSERS_INVENTORY = + ROUTE_CITY_JAHAD_BASE + "/dispensers/inventory"; +export const ROUTE_CITY_JIHAD_SALE_DESTRIBUTION_DETAILS = + ROUTE_CITY_JAHAD_BASE + "/dispensers/sale-distribution/:key"; +export const ROUTE_CITY_JIHADـHATCHINGS = + ROUTE_CITY_JAHAD_BASE + "/manage-hatchings"; +export const ROUTE_CITY_JIHAD_HATCHINGS_DETAILS = + ROUTE_CITY_JAHAD_BASE + "/manage-hatchings/:key"; + +// CityPoultry +export const ROUTE_CITY_POULTRY_STATICS = ROUTE_CITY_POULTRY_BASE + "/statics"; +export const ROUTE_CITY_POULTRY_ROUTE_FILES_STATE = + ROUTE_CITY_POULTRY_BASE + "/files-state/"; +export const ROUTE_CITY_POULTRY_ROUTE_ALLOCATIONS = + ROUTE_CITY_POULTRY_BASE + "/allocations/"; +export const ROUTE_CITY_POULTRY_ROUTE_MANAGE_GUILDS = + ROUTE_CITY_POULTRY_BASE + "/manage-guilds/"; +export const ROUTE_CITY_POULTRY_ROUTE_MANAGE_STEWARDS = + ROUTE_CITY_POULTRY_BASE + "/manage-stewards/"; +export const ROUTE_CITY_POULTRY_ROUTE_GUILDS = + ROUTE_CITY_POULTRY_BASE + "/manage-guilds/guilds"; +export const ROUTE_CITY_POULTRY_ROUTE_STEWARDS = + ROUTE_CITY_POULTRY_BASE + "/manage-guilds/stewards"; +export const ROUTE_CITY_POULTRY_ROUTE_GUILDS_SETTINGS = + ROUTE_CITY_POULTRY_BASE + "/manage-guilds/settings"; +export const ROUTE_CITY_POULTRY_HATCHING = + ROUTE_CITY_POULTRY_BASE + "/hatching"; +export const ROUTE_CITY_POULTRYـHATCHINGS = + ROUTE_CITY_POULTRY_BASE + "/manage-hatchings"; +export const ROUTE_CITY_POULTRYـHATCHINGS_DETAILS = + ROUTE_CITY_POULTRY_BASE + "/manage-hatchings/:key"; +export const ROUTE_CITY_DISPENSERS = ROUTE_CITY_POULTRY_BASE + "/dispensers"; +export const ROUTE_CITY_DISPENSERS_INVENTORY = + ROUTE_CITY_POULTRY_BASE + "/dispensers/inventory"; +export const ROUTE_CITY_REQUEST_DISTRIBUTION = + ROUTE_CITY_POULTRY_BASE + "/request-distribution"; +export const ROUTE_CITY_REQUEST_TRANSACTIONS = + ROUTE_CITY_POULTRY_BASE + "/requests/transactions"; +export const ROUTE_CITY_REQUEST_TRANSACTION_DETAILS = + ROUTE_CITY_POULTRY_BASE + "/requests/transactions/:key/:name"; +// Observatory +export const ROUTE_OBSERVATORY_STATICS = ROUTE_OBSERVATORY_BASE + "/statics"; +export const ROUTE_OBSERVATORY_HATCHING = ROUTE_OBSERVATORY_BASE + "/hatching"; +export const ROUTE_OBSERVATORY_VISOR_STATICS = + ROUTE_OBSERVATORY_BASE + "/visor-statics"; +export const ROUTE_OBSERVATORY_VISOR_STATICS_CHARTS = + ROUTE_OBSERVATORY_BASE + "/visor-statics/charts"; +export const ROUTE_OBSERVATORY_VISOR_STATICS_PREDICTION = + ROUTE_OBSERVATORY_BASE + "/visor-statics/prediction/"; +export const ROUTE_OBSERVATORY_VISOR_STATICS_PREDICTION_VIEW = + ROUTE_OBSERVATORY_BASE + "/visor-statics/prediction/:key/:date"; +export const ROUTE_OBSERVATORYـHATCHINGS = + ROUTE_OBSERVATORY_BASE + "/manage-hatchings"; +export const ROUTE_OBSERVATORYـHATCHINGS_DETAILS = + ROUTE_OBSERVATORY_BASE + "/manage-hatchings/:key"; + +// Senf +export const ROUTE_SENF_INVENTORY = ROUTE_SENF_BASE + "/inventory"; +export const ROUTE_SENF_INVENTORY_STOCK = ROUTE_SENF_BASE + "/inventory/stock"; +export const ROUTE_SENF_INVENTORY_SEGMENTATION = + ROUTE_SENF_BASE + "/inventory/segmentaion"; +export const ROUTE_SENF_INVENTORY_ENTER = ROUTE_SENF_BASE + "/inventory/enter"; +export const ROUTE_GUILD_ROUTE_DEVICES = ROUTE_SENF_BASE + "/devices"; + +//Guild Room + +export const ROUTE_GUILD_ROOM_ROUTE_MANAGE_GUILDS = + ROUTE_GUILD_ROOM_BASE + "/manage-guilds/"; + +export const ROUTE_GUILD_ROOM_ROUTE_GUILDS_REQUESTS = + ROUTE_GUILD_ROOM_BASE + "/manage-guilds/guilds-requests"; + +export const ROUTE_GUILD_ROOM_ROUTE_GUILDS = + ROUTE_GUILD_ROOM_BASE + "/manage-guilds/guilds"; + +export const ROUTE_GUILD_ROOM_ROUTE_STEWARDS = + ROUTE_GUILD_ROOM_BASE + "/manage-guilds/stewards"; + +// export const ROUTE_GUILD_ROOM_ROUTE_GUILDS_SETTINGS = +// ROUTE_GUILD_ROOM_BASE + "/manage-guilds/settings"; + +//PSP Company + +export const ROUTE_PSP_ROUTE_COMPANY_MANAGE_STEWARDS = + ROUTE_PSP_COMPANY_BASE + "/manage-stewards"; +export const ROUTE_PSP_ROUTE_COMPANY_PSP_COMPANIES = + ROUTE_PSP_COMPANY_BASE + "/psp-companies"; +export const ROUTE_PSP_COMPANY_ROUTE_GUILDS = + ROUTE_PSP_COMPANY_BASE + "/manage-guilds/guilds"; + +export const ROUTE_PSP_COMPANY_ROUTE_ACTIVE_SESSION = + ROUTE_PSP_COMPANY_BASE + "/active-session/session"; + +export const ROUTE_PSP_COMPANY_ROUTE_DEVICES = + ROUTE_PSP_COMPANY_BASE + "/devices"; +export const ROUTE_PSP_COMPANY_ROUTE_DEVICES_V2 = + ROUTE_PSP_COMPANY_BASE + "/devices-v2"; + +//LIVE STOCK SUPPORT + +export const ROUTE_LIVE_STOCK_SUPPORT_MANAGE_BARS = + ROUTE_LIVE_STOCK_SUPPORT_BASE + "/manage-bars"; + +export const ROUTE_LIVE_STOCK_USER_PROFILE = + "/dashboard/profile" + ROUTE_LIVE_STOCK_SUPPORT_BASE; + +export const ROUTE_LIVE_STOCK_SUPPORT_ROUTE_FILES_STATE = + ROUTE_LIVE_STOCK_SUPPORT_BASE + "/files-state/"; + +export const ROUTE_LIVE_STOCK_FREEZING_REQUESTS = + ROUTE_LIVE_STOCK_SUPPORT_BASE + "/freezing/"; + +export const ROUTE_LIVE_STOCK_COLD_HOUSE = + ROUTE_LIVE_STOCK_SUPPORT_BASE + "/coldhouse/"; + +// SUPER ADMIN +export const ROUTE_SUPER_ADMIN_USER_PROFILE = + "/dashboard/profile" + ROUTE_SUPER_ADMIN_BASE; +export const ROUTE_SUPER_ADMIN_REQUESTS = ROUTE_SUPER_ADMIN_BASE + "/requests"; +export const ROUTE_SUPER_ADMIN_SETTLEMENTS = + ROUTE_SUPER_ADMIN_BASE + "/settlements"; + +export const ROUTE_SUPER_ADMIN_ACTIVE_REQUESTS = + ROUTE_SUPER_ADMIN_BASE + "/requests/active"; +export const ROUTE_SUPER_ADMIN_ALLOCATION_REQUESTS = + ROUTE_SUPER_ADMIN_BASE + "/requests/allocation"; +export const ROUTE_SUPER_ADMIN_ALLOCATED_REQUESTS = + ROUTE_SUPER_ADMIN_BASE + "/requests/allocated"; +export const ROUTE_SUPER_ADMIN_AUTO_ALLOCATION_REQUESTS = + ROUTE_SUPER_ADMIN_BASE + "/requests/auto-allocation"; +export const ROUTE_SUPER_ADMIN_CITY_NEW_REQUESTS = + ROUTE_SUPER_ADMIN_BASE + "/requests/city"; +export const ROUTE_SUPER_ADMIN_NEW_REQUESTS = + ROUTE_SUPER_ADMIN_BASE + "/requests/new"; +export const ROUTE_SUPER_ADMIN_STATEMENTـOFـNEED_REQUESTS = + ROUTE_SUPER_ADMIN_BASE + "/requests/statement-of-need"; +export const ROUTE_SUPER_ADMIN_REJECTED_REQUESTS = + ROUTE_SUPER_ADMIN_BASE + "/requests/rejected"; +export const ROUTE_SUPER_ADMIN_ARCHIVED_REQUESTS = + ROUTE_SUPER_ADMIN_BASE + "/requests/archived"; +export const ROUTE_SUPER_ADMIN_ISSUANCE_OF_LETTER = + ROUTE_SUPER_ADMIN_BASE + "/requests/issuance-of-letter"; +export const ROUTE_SUPER_ADMIN_FREE_SALES_REQUESTS = + ROUTE_SUPER_ADMIN_BASE + "/requests/free-sale"; +export const ROUTE_SUPER_ADMIN_FILE = ROUTE_SUPER_ADMIN_BASE + "/file/"; +export const ROUTE_SUPER_ADMIN_FILE_ROUTE = + ROUTE_SUPER_ADMIN_BASE + "/file/:id"; +export const ROUTE_SUPER_ADMIN_AUCTION = + ROUTE_SUPER_ADMIN_BASE + ROUTE_AUCTION_BASE; +export const ROUTE_SUPER_ADMIN_SEND_MESSAGE = + ROUTE_SUPER_ADMIN_BASE + "/sendmessage"; +export const ROUTE_SUPER_ADMIN_SEND_ANNOUNCEMENT = + ROUTE_SUPER_ADMIN_BASE + "/announcement"; +export const ROUTE_SUPER_ADMIN_SEND_REPORT = + ROUTE_SUPER_ADMIN_BASE + "/sendreport"; +export const ROUTE_SUPER_ADMIN_TICKET = ROUTE_SUPER_ADMIN_BASE + "/ticket/"; +export const ROUTE_SUPER_ADMIN_VIEW_TICKET = + ROUTE_SUPER_ADMIN_BASE + "/ticket/:id/:create"; +export const ROUTE_SUPER_ADMIN_ROUTE_TICKET = + ROUTE_SUPER_ADMIN_BASE + "/ticket/"; +export const ROUTE_SUPER_ADMIN_AWAITING_PAYMENT_REQUESTS = + ROUTE_SUPER_ADMIN_BASE + "/requests/awaitpayment"; +export const ROUTE_SUPER_ADMIN_AWAITING_INSPECTION_REQUESTS = + ROUTE_SUPER_ADMIN_BASE + "/requests/awaitinspection"; +export const ROUTE_SUPER_ADMIN_STATICS = ROUTE_SUPER_ADMIN_BASE + "/statics"; +export const ROUTE_SUPER_ADMIN_NATIONAL_STATICS = + ROUTE_SUPER_ADMIN_BASE + "/national-statics"; +export const ROUTE_SUPER_ADMIN_HATCHING = ROUTE_SUPER_ADMIN_BASE + "/hatching"; +export const ROUTE_SUPER_ADMINـHATCHINGS = + ROUTE_SUPER_ADMIN_BASE + "/manage-hatchings"; +export const ROUTE_SUPER_ADMINـHATCHINGS_DETAILS = + ROUTE_SUPER_ADMIN_BASE + "/manage-hatchings/:key"; +export const ROUTE_SUPER_ADMIN_NEW_REQUEST = + ROUTE_SUPER_ADMIN_BASE + "/request"; +export const ROUTE_SUPER_ADMIN_KILLER_MANAGMENT = + ROUTE_SUPER_ADMIN_BASE + "/killer-managment"; +export const ROUTE_SUPER_ADMIN_ROUTE_ALLOCATIONS = + ROUTE_SUPER_ADMIN_BASE + "/allocations/"; +export const ROUTE_SUPER_ADMIN_ROUTE_MANAGE_GUILDS = + ROUTE_SUPER_ADMIN_BASE + "/manage-guilds/"; +export const ROUTE_SUPER_ADMIN_ROUTE_MANAGE_STEWARDS = + ROUTE_SUPER_ADMIN_BASE + "/manage-stewards/"; +export const ROUTE_SUPER_ADMIN_ROUTE_IN_PROVINCE_GUILDS = + ROUTE_SUPER_ADMIN_BASE + "/manage-guilds/in-province"; +export const ROUTE_SUPER_ADMIN_ROUTE_OUT_PROVINCE_GUILDS = + ROUTE_SUPER_ADMIN_BASE + "/manage-guilds/out-province"; +export const ROUTE_SUPER_ADMIN_ROUTE_OUT_PROVINCE_LEGAL_GUILDS = + ROUTE_SUPER_ADMIN_BASE + "/manage-guilds/out-province/legal-guilds"; +export const ROUTE_SUPER_ADMIN_ROUTE_OUT_PROVINCE_TRUE_GUILDS = + ROUTE_SUPER_ADMIN_BASE + "/manage-guilds/out-province/true-guilds"; +export const ROUTE_SUPER_ADMIN_ROUTE_IN_PROVINCE_LEGAL_GUILDS = + ROUTE_SUPER_ADMIN_BASE + "/manage-guilds/in-province/legal-guilds"; +export const ROUTE_SUPER_ADMIN_ROUTE_IN_PROVINCE_TRUE_GUILDS = + ROUTE_SUPER_ADMIN_BASE + "/manage-guilds/in-province/true-guilds"; +export const ROUTE_SUPER_ADMIN_ROUTE_GUILDS = + ROUTE_SUPER_ADMIN_BASE + "/manage-guilds/guilds"; +export const ROUTE_SUPER_ADMIN_ROUTE_IN_PROVINCE_STEWARDS = + ROUTE_SUPER_ADMIN_BASE + "/manage-guilds/in-province/stewards"; +export const ROUTE_SUPER_ADMIN_ROUTE_GUILDS_SETTINGS = + ROUTE_SUPER_ADMIN_BASE + "/manage-guilds/settings"; +export const ROUTE_SUPER_ADMIN_ROUTE_AGENT_SHARE = + ROUTE_SUPER_ADMIN_BASE + "/agent-share"; +export const ROUTE_SUPER_ADMIN_ROUTE_STEWARD_SHARE = + ROUTE_SUPER_ADMIN_BASE + "/steward-share"; +export const ROUTE_SUPER_ADMIN_ROUTE_AGENT_SHARE_ID = + ROUTE_SUPER_ADMIN_BASE + "/agent-share/:id/:date"; +export const ROUTE_SUPER_ADMIN_ROUTE_IN_PROVINCE_GUILDS_REQUESTS = + ROUTE_SUPER_ADMIN_BASE + "/manage-guilds/in-province/guilds-requests"; +export const ROUTE_SUPER_ADMIN_ROUTE_IN_PROVINCE_GUILDS_DISTRIBUTIONS = + ROUTE_SUPER_ADMIN_BASE + "/manage-guilds/guilds-distributions"; +export const ROUTE_SUPER_ADMIN_RETURN_PURCHASES = + ROUTE_SUPER_ADMIN_BASE + "/return-purchases"; + +export const ROUTE_SUPER_ADMIN_ROUTE_WEIGHT_RANGE = + ROUTE_SUPER_ADMIN_BASE + "/manage-process/weight-range"; +export const ROUTE_SUPER_ADMIN_ROUTE_MANAGE_PROCESS = + ROUTE_SUPER_ADMIN_BASE + "/manage-process/"; +export const ROUTE_SUPER_ADMIN_ROUTE_RESTRICTION_OF_CARCASS_DISTRIBUTION = + ROUTE_SUPER_ADMIN_BASE + + "/manage-process/restriction-of-carcass-distribution"; +export const ROUTE_SUPER_ADMIN_ROUTE_MANAGE_PROCESS_SLAUGHTER = + ROUTE_SUPER_ADMIN_BASE + "/manage-process/slaughter"; +export const ROUTE_SUPER_ADMIN_ROUTE_SLAUGHTER_TRADE_PANEL = + ROUTE_SUPER_ADMIN_BASE + "/manage-process/slaughter-trade-panel"; +export const ROUTE_SUPER_ADMIN_ROUTE_MANAGE_DISTRIBUTIONS = + ROUTE_SUPER_ADMIN_BASE + "/manage-process/manage-distributions"; +export const ROUTE_SUPER_ADMIN_ROUTE_MANAGE_PROCESS_KILLPLACE = + ROUTE_SUPER_ADMIN_BASE + "/manage-process/killplace"; +export const ROUTE_SUPER_ADMIN_ROUTE_MANAGE_PROCESS_BUY_REQ = + ROUTE_SUPER_ADMIN_BASE + "/manage-process/buy-req"; +export const ROUTE_SUPER_ADMIN_ROUTE_MANAGE_PROCESS_POLICY_COUNCIL = + ROUTE_SUPER_ADMIN_BASE + "/manage-process/policy-council"; +export const ROUTE_SUPER_ADMIN_ROUTE_MANAGE_PROCESS_DOCUMENT_STATES = + ROUTE_SUPER_ADMIN_BASE + "/manage-process/document-states"; +export const ROUTE_SUPER_ADMIN_ROUTE_TICKET_PERMISSION = + ROUTE_SUPER_ADMIN_BASE + "/manage-process/ticket-permission"; +export const ROUTE_SUPER_ADMIN_ROUTE_MANAGE_PROCESS_WAGE_FRACTIONS = + ROUTE_SUPER_ADMIN_BASE + "/manage-process/wage-fractions"; +export const ROUTE_SUPER_ADMIN_ROUTE_POLICY_COUNCIL_POULTRY_CHOOSE_SLAUGHTER = + ROUTE_SUPER_ADMIN_BASE + "/policy-council/poultry-choose-slaughter"; +export const ROUTE_SUPER_ADMIN_ROUTE_POLICY_COUNCIL_FREE_SALE = + ROUTE_SUPER_ADMIN_BASE + "/policy-council/free-sale"; +export const ROUTE_SUPER_ADMIN_ROUTE_POLICY_COUNCIL_DIRECT_BUY = + ROUTE_SUPER_ADMIN_BASE + "/policy-council/direct-buy"; +export const ROUTE_SUPER_ADMIN_ROUTE_POLICY_COUNCIL_KILLHOUSE_GUILDS = + ROUTE_SUPER_ADMIN_BASE + "/policy-council/killhouse-guilds"; +export const ROUTE_SUPER_ADMIN_ROUTE_CASE_STATUS = + ROUTE_SUPER_ADMIN_BASE + "/case-status/"; +export const ROUTE_SUPER_ADMIN_ROUTE_FILES_STATE = + ROUTE_SUPER_ADMIN_BASE + "/files-state/"; +export const ROUTE_SUPER_ADMIN_ROUTE_WEIGHT_CATEGORY = + ROUTE_SUPER_ADMIN_BASE + "/manage-process/weight-category"; +export const ROUTE_SUPER_ADMIN_ROUTE_PENALTY = + ROUTE_SUPER_ADMIN_BASE + "/manage-process/penalty"; +export const ROUTE_SUPER_ADMIN_ASSIGN_VET_FARM = + ROUTE_SUPER_ADMIN_BASE + "/assign-farm/"; +export const ROUTE_SUPER_ADMIN_CARS = ROUTE_SUPER_ADMIN_BASE + "/cars/"; +export const ROUTE_SUPER_ADMIN_USERS = ROUTE_SUPER_ADMIN_BASE + "/users/"; +export const ROUTE_SUPER_ADMIN_POULTRIES = + ROUTE_SUPER_ADMIN_BASE + "/poultries/"; +export const ROUTE_SUPER_ADMIN_POULTRIES_DETAILS = + ROUTE_SUPER_ADMIN_BASE + "/poultries/:key"; +export const ROUTE_SUPER_ADMIN_GUILD_TRANSACTIONS = + ROUTE_SUPER_ADMIN_BASE + "/transactions/"; +export const ROUTE_SUPER_ADMIN_SLAUGHTERS = + ROUTE_SUPER_ADMIN_BASE + "/slaugter-houses/"; +export const ROUTE_SUPER_ADMIN_SLAUGHTERS_MONITORING_BUYERS = + ROUTE_SUPER_ADMIN_BASE + "/slaugter-houses/monitoring-buyers"; +export const ROUTE_SUPER_ADMIN_SLAUGHTERS_MANAGE = + ROUTE_SUPER_ADMIN_BASE + "/slaugter-houses/manage"; +export const ROUTE_SUPER_ADMIN_ROUTE_SMS = ROUTE_SUPER_ADMIN_BASE + "/sms"; +export const ROUTE_SUPER_ADMIN_ROUTE_SMS_SEND = + ROUTE_SUPER_ADMIN_BASE + "/sms/send"; +export const ROUTE_SUPER_ADMIN_ROUTE_SMS_MANAGE = + ROUTE_SUPER_ADMIN_BASE + "/sms/manage"; +export const ROUTE_SUPER_ADMIN_ROUTE_MANAGE_PROCESS_MOBILE_MESSAGE = + ROUTE_SUPER_ADMIN_BASE + "/sms/mobile-message"; +export const ROUTE_SUPER_ADMIN_ROUTE_AGE_MESSAGE = + ROUTE_SUPER_ADMIN_BASE + "/sms/age-message"; +export const ROUTE_SUPER_ADMIN_PRICING3 = ROUTE_SUPER_ADMIN_BASE + "/pricing"; +export const ROUTE_SUPER_ADMIN_BARS = ROUTE_SUPER_ADMIN_BASE + "/bars"; +export const ROUTE_SUPER_ADMIN_USER_FILE_ROUTE = + ROUTE_SUPER_ADMIN_BASE + "/userfile/:userid"; +export const ROUTE_SUPER_ADMIN_OPERATOR_USER_FILE = + ROUTE_SUPER_ADMIN_BASE + "/userfile/"; +export const ROUTE_SUPER_ADMIN_MANAGE_USERS = + ROUTE_SUPER_ADMIN_BASE + "/manage-users/"; +export const ROUTE_SUPER_ADMIN_PAYING_FEES_REQUESTS = + ROUTE_SUPER_ADMIN_BASE + "/requests/payment-of-fees"; +export const ROUTE_SUPER_ADMIN_PAYING_FEES_REQUESTS_VIEW = + ROUTE_SUPER_ADMIN_BASE + "/requests/payment-of-fees/:type/:key"; +export const ROUT_SUPER_ADMIN_FREE_BUY = + ROUTE_SUPER_ADMIN_BASE + "/requests/free-buy"; +export const ROUTE_SUPER_ADMIN_BROADCAST_MANAGEMENT = + ROUTE_SUPER_ADMIN_BASE + "/broadcast-management"; +export const ROUTE_SUPER_ADMIN_REPORT = ROUTE_SUPER_ADMIN_BASE + "/report"; +export const ROUTE_SUPER_ADMIN_PRODUCTS = ROUTE_SUPER_ADMIN_BASE + "/products"; +export const ROUTE_SUPER_ADMIN_TRANSACTIONS = + ROUTE_SUPER_ADMIN_BASE + "/requests/transactions"; +export const ROUTE_SUPER_ADMIN_DESTRIBUTION_DETAILS = + ROUTE_SUPER_ADMIN_BASE + "/requests/distribution"; +export const ROUTE_SUPER_ADMIN_TRANSACTIONS_VIEW = + ROUTE_SUPER_ADMIN_BASE + "/requests/transactions/:key/:name"; +export const ROUTE_SUPER_ADMIN_CHAINS = ROUTE_SUPER_ADMIN_BASE + "/chains"; +export const ROUTE_SUPER_ADMIN_EXPORT = + ROUTE_SUPER_ADMIN_BASE + "/requests/export"; +export const ROUTE_SUPER_ADMIN_VISOR_STATICS = + ROUTE_SUPER_ADMIN_BASE + "/visor-statics"; +export const ROUTE_SUPER_ADMIN_VISOR_STATICS_CHARTS = + ROUTE_SUPER_ADMIN_BASE + "/visor-statics/charts"; +export const ROUTE_SUPER_ADMIN_VISOR_STATICS_PREDICTION = + ROUTE_SUPER_ADMIN_BASE + "/visor-statics/prediction/"; +export const ROUTE_SUPER_ADMIN_VISOR_STATICS_PREDICTION_VIEW = + ROUTE_SUPER_ADMIN_BASE + "/visor-statics/prediction/:key/:date"; +export const ROUTE_SUPER_ADMIN_DISPENSERS = + ROUTE_SUPER_ADMIN_BASE + "/dispensers"; +export const ROUTE_SUPER_ADMIN_DISPENSERS_MANAGEMENT = + ROUTE_SUPER_ADMIN_BASE + "/dispensers-management"; +export const ROUTE_SUPER_ADMIN_DISPENSER_DETAILS = + ROUTE_SUPER_ADMIN_BASE + "/dispenser-data"; +export const ROUTE_SUPER_ADMIN_DISPENSER_DETAILS_VIEW = + ROUTE_SUPER_ADMIN_BASE + "/dispenser-data/:key"; +export const ROUTE_SUPER_ADMIN_DISPENSERS_STEWARDS = + ROUTE_SUPER_ADMIN_BASE + "/dispensers-stewards"; +export const ROUTE_SUPER_ADMIN_DISPENSERS_KILLHOUSES = + ROUTE_SUPER_ADMIN_BASE + "/dispensers-killhouses"; +export const ROUTE_SUPER_ADMIN_DISPENSERS_KILLHOUSES_VIEW = + ROUTE_SUPER_ADMIN_BASE + "/dispensers-killhouses/:key/:name"; +export const ROUTE_SUPER_ADMIN_DISPENSERS_INVENTORY = + ROUTE_SUPER_ADMIN_BASE + "/dispensers-inventory"; +export const ROUTE_SUPER_ADMIN_DISPENSERS_SELL_CARCASS = + ROUTE_SUPER_ADMIN_BASE + "/dispensers-sell-carcass"; +export const ROUTE_SUPER_ADMIN_DISPENSERS_STOCK = + ROUTE_SUPER_ADMIN_BASE + "/dispensers/stock"; +export const ROUTE_SUPER_ADMIN_DISPENSERS_STOCK_KILLHOUSE = + ROUTE_SUPER_ADMIN_BASE + "/dispensers/stock/killhouse"; +export const ROUTE_SUPER_ADMIN_DISPENSERS_STOCK_GUILD = + ROUTE_SUPER_ADMIN_BASE + "/dispensers/stock/guild"; +export const ROUTE_SUPER_ADMIN_DISPENSERS_STOCK_STEWARD = + ROUTE_SUPER_ADMIN_BASE + "/dispensers/stock/steward"; +export const ROUTE_SUPER_ADMIN_COLD_HOUSES = + ROUTE_SUPER_ADMIN_BASE + "/cold-house-management"; +export const ROUTE_SUPER_ADMIN_COLD_HOUSES_MANAGEMENT = + ROUTE_SUPER_ADMIN_BASE + "/cold-houses-management"; +export const ROUTE_SUPER_ADMIN_COLD_HOUSES_MANAGEMENT_VIEW = + ROUTE_SUPER_ADMIN_BASE + "/cold-houses-management/:key/:name/:type"; +export const ROUTE_SUPER_ADMIN_SUB_SECTORS_WAGE = + ROUTE_SUPER_ADMIN_BASE + "/subsectors-wage"; +export const ROUTE_SUPER_ADMIN_SUB_SECTORS_CITY_SHARES = + ROUTE_SUPER_ADMIN_BASE + "/subsectors-city-shares"; +export const ROUTE_SUPER_ADMIN_SUB_SECTORS_STEWARD_SHARES = + ROUTE_SUPER_ADMIN_BASE + "/subsectors-steward-shares"; +export const ROUTE_SUPER_ADMIN_SUB_SECTORS_VET_FARM_SHARES = + ROUTE_SUPER_ADMIN_BASE + "/subsectors-vet-farm-shares"; + +export const ROUTE_SUPER_ADMIN_ROUTE_NATIONAL_INFO = + ROUTE_SUPER_ADMIN_BASE + "/national-info"; + +export const ROUTE_SUPER_ADMIN_ROUTE_NATIONAL_INFO_DETAILS = + ROUTE_SUPER_ADMIN_BASE + "/national-info/:key"; + +export const ROUTE_SUPER_ADMIN_ROUTE_NATIONAL_INFO_FARM = + ROUTE_SUPER_ADMIN_BASE + "/national-farm-info"; + +export const ROUTE_SUPER_ADMIN_ROUTE_NATIONAL_INFO_FARM_DETAILS = + ROUTE_SUPER_ADMIN_BASE + "/national-farm-info/:key/:name"; + +export const ROUTE_SUPER_ADMIN_ROUTE_NATIONAL_INFO_HATCHING_DETAILS = + ROUTE_SUPER_ADMIN_BASE + "/national-info/:key/:name"; + +export const ROUTE_SUPER_ADMIN_ROUTE_NATIONAL_INFO_SLAUGHTER = + ROUTE_SUPER_ADMIN_BASE + "/national-slaughter-info"; + +export const ROUTE_SUPER_ADMIN_ROUTE_NATIONAL_INFO_SLAUGHTER_DETAILS = + ROUTE_SUPER_ADMIN_BASE + "/national-slaughter-info/:unitkey/:name"; + +export const ROUTE_SUPER_ADMIN_ROUTE_NATIONAL_INFO_DISTRIBUTION_DETAILS = + ROUTE_SUPER_ADMIN_BASE + "/national-slaughter-info/:unitkey/:name/:type"; + +export const ROUTE_SUPER_ADMIN_ROUTE_KILLERS_WAGES = + ROUTE_SUPER_ADMIN_BASE + "/requests/payment-of-fees-killers"; + +export const ROUTE_SUPER_ADMIN_ROUTE_KILLERS_WAGES_DETAILS = + ROUTE_SUPER_ADMIN_BASE + "/requests/payment-of-fees-killers/:key"; + +export const ROUTE_SUPER_ADMIN_DIFFRENCE_KILLER = + ROUTE_SUPER_ADMIN_BASE + "/manage-hatchings/diffrence-killer"; +export const ROUTE_SUPER_ADMIN_DIFFRENCE_KILLER_SLAUGHTER = + ROUTE_SUPER_ADMIN_BASE + "/manage-hatchings/diffrence-killer-slaughter"; +export const ROUTE_SUPER_ADMIN_INCREASE_HATCHING = + ROUTE_SUPER_ADMIN_BASE + "/hatching/increase-hatching"; + +export const ROUTE_SUPER_ADMIN_DASHBOARD = ROUTE_SUPER_ADMIN_BASE + "/dashbord"; +export const ROUTE_SUPER_ADMIN_DASHBOARD_NEWS = + ROUTE_SUPER_ADMIN_BASE + "/dashboard/news"; +export const ROUTE_SUPER_ADMIN_POULTRY_LIVESTOCK_EXPERTS = + ROUTE_SUPER_ADMIN_BASE + "/livestock-experts"; + +export const ROUTE_SUPER_ADMIN_ROUTE_MANAGE_DEVICES = + ROUTE_SUPER_ADMIN_BASE + "/manage-devices/"; + +export const ROUTE_SUPER_ADMIN_ROUTE_COMPANY_MANAGE_STEWARDS = + ROUTE_SUPER_ADMIN_BASE + "/manage-stewards"; +export const ROUTE_SUPER_ADMIN_ROUTE_PSP_COMPANIES = + ROUTE_SUPER_ADMIN_BASE + "/psp-companies"; +export const ROUTE_SUPER_ADMIN_COMPANY_ROUTE_GUILDS = + ROUTE_SUPER_ADMIN_BASE + "/manage-guilds/guilds"; +export const ROUTE_SUPER_ADMIN_COMPANY_ROUTE_ACTIVE_SESSION = + ROUTE_SUPER_ADMIN_BASE + "/active-session/session"; +export const ROUTE_SUPER_ADMIN_COMPANY_ROUTE_DEVICES = + ROUTE_SUPER_ADMIN_BASE + "/devices"; + +export const ROUTE_SUPER_ADMIN_ROUTE_INSPECTION = + ROUTE_SUPER_ADMIN_BASE + "/inspection"; + +// CHAIN_COMPANY + +export const ROUTE_SUPER_ADMIN_TRADING_PANEL = + ROUTE_SUPER_ADMIN_BASE + "/requests/trade-panel"; + +export const ROUTE_SUPER_ADMIN_TRADING_PANEL_FREE_BUY = + ROUTE_SUPER_ADMIN_BASE + "/requests/trade-panel/free-buy"; + +export const ROUTE_SUPER_ADMIN_TRADING_PANEL_DASHBOARD = + ROUTE_SUPER_ADMIN_BASE + "/requests/trade-panel/dashboard"; + +export const ROUTE_CHAIN_COMPANY_USER_PROFILE = + "/dashboard/profile" + ROUTE_CHAIN_COMPANY_BASE; +export const ROUTE_CHAIN_COMPANY_POULTRIES = + ROUTE_CHAIN_COMPANY_BASE + "/poultries/"; +export const ROUTE_CHAIN_COMPANY_POULTRIES_DETAILS = + ROUTE_CHAIN_COMPANY_BASE + "/poultries/:key"; +export const ROUTE_CHAIN_COMPANY_MANAGE_BARS = + ROUTE_CHAIN_COMPANY_BASE + "/bars/"; +export const ROUTE_CHAIN_COMPANY_MANAGE_FEES = + ROUTE_CHAIN_COMPANY_BASE + "/manage-fee/"; + +// ADMIN X +export const ROUTE_ADMINX_BASE_NEW_HOME = ROUTE_ADMINX_BASE + "/home"; +export const ROUTE_ADMINX_USER_PROFILE = + "/dashboard/profile" + ROUTE_ADMINX_BASE; +export const ROUTE_ADMINX_REQUESTS = ROUTE_ADMINX_BASE + "/requests"; +export const ROUTE_ADMINX_SETTLEMENTS = ROUTE_ADMINX_BASE + "/settlements"; +export const ROUTE_ADMINX_ACTIVE_REQUESTS = + ROUTE_ADMINX_BASE + "/requests/active"; +export const ROUTE_ADMINX_ALLOCATION_REQUESTS = + ROUTE_ADMINX_BASE + "/requests/allocation"; +export const ROUTE_ADMINX_ALLOCATED_REQUESTS = + ROUTE_ADMINX_BASE + "/requests/allocated"; +export const ROUTE_ADMINX_AUTO_ALLOCATION_REQUESTS = + ROUTE_ADMINX_BASE + "/requests/auto-allocation"; +export const ROUTE_ADMINX_CITY_NEW_REQUESTS = + ROUTE_ADMINX_BASE + "/requests/city"; +export const ROUTE_ADMINX_NEW_REQUESTS = ROUTE_ADMINX_BASE + "/requests/new"; +export const ROUTE_ADMINX_STATEMENTـOFـNEED_REQUESTS = + ROUTE_ADMINX_BASE + "/requests/statement-of-need"; +export const ROUTE_ADMINX_REJECTED_REQUESTS = + ROUTE_ADMINX_BASE + "/requests/rejected"; +export const ROUTE_ADMINX_ARCHIVED_REQUESTS = + ROUTE_ADMINX_BASE + "/requests/archived"; +export const ROUTE_ADMINX_ISSUANCE_OF_LETTER = + ROUTE_ADMINX_BASE + "/requests/issuance-of-letter"; +export const ROUTE_ADMINX_FREE_SALES_REQUESTS = + ROUTE_ADMINX_BASE + "/requests/free-sale"; +export const ROUTE_ADMINX_FILE = ROUTE_ADMINX_BASE + "/file/"; +export const ROUTE_ADMINX_FILE_ROUTE = ROUTE_ADMINX_BASE + "/file/:id"; +export const ROUTE_ADMINX_AUCTION = ROUTE_ADMINX_BASE + ROUTE_AUCTION_BASE; +export const ROUTE_ADMINX_SEND_MESSAGE = ROUTE_ADMINX_BASE + "/sendmessage"; +export const ROUTE_ADMINX_SEND_ANNOUNCEMENT = + ROUTE_ADMINX_BASE + "/announcement"; +export const ROUTE_ADMINX_SEND_REPORT = ROUTE_ADMINX_BASE + "/sendreport"; +export const ROUTE_ADMINX_TICKET = ROUTE_ADMINX_BASE + "/ticket/"; +export const ROUTE_ADMINX_VIEW_TICKET = + ROUTE_ADMINX_BASE + "/ticket/:id/:create"; +export const ROUTE_ADMINX_ROUTE_TICKET = ROUTE_ADMINX_BASE + "/ticket/"; +export const ROUTE_ADMINX_AWAITING_PAYMENT_REQUESTS = + ROUTE_ADMINX_BASE + "/requests/awaitpayment"; +export const ROUTE_ADMINX_AWAITING_INSPECTION_REQUESTS = + ROUTE_ADMINX_BASE + "/requests/awaitinspection"; +export const ROUTE_ADMINX_STATICS = ROUTE_ADMINX_BASE + "/statics"; +export const ROUTE_ADMINX_NATIONAL_STATICS = + ROUTE_ADMINX_BASE + "/national-statics"; +export const ROUTE_ADMINX_HATCHING = ROUTE_ADMINX_BASE + "/hatching"; +export const ROUTE_ADMINXـHATCHINGS = ROUTE_ADMINX_BASE + "/manage-hatchings"; +export const ROUTE_ADMINXـHATCHINGS_DETAILS = + ROUTE_ADMINX_BASE + "/manage-hatchings/:key"; +export const ROUTE_ADMINX_NEW_REQUEST = ROUTE_ADMINX_BASE + "/request"; +export const ROUTE_ADMINX_KILLER_MANAGMENT = + ROUTE_ADMINX_BASE + "/killer-managment"; +export const ROUTE_ADMINX_ROUTE_ALLOCATIONS = + ROUTE_ADMINX_BASE + "/allocations/"; +export const ROUTE_ADMINX_ROUTE_MANAGE_GUILDS = + ROUTE_ADMINX_BASE + "/manage-guilds/"; +export const ROUTE_ADMINX_ROUTE_MANAGE_STEWARDS = + ROUTE_ADMINX_BASE + "/manage-stewards/"; +export const ROUTE_ADMINX_ROUTE_IN_PROVINCE_GUILDS = + ROUTE_ADMINX_BASE + "/manage-guilds/in-province"; +export const ROUTE_ADMINX_ROUTE_OUT_PROVINCE_GUILDS = + ROUTE_ADMINX_BASE + "/manage-guilds/out-province"; +export const ROUTE_ADMINX_ROUTE_OUT_PROVINCE_LEGAL_GUILDS = + ROUTE_ADMINX_BASE + "/manage-guilds/out-province/legal-guilds"; +export const ROUTE_ADMINX_ROUTE_OUT_PROVINCE_TRUE_GUILDS = + ROUTE_ADMINX_BASE + "/manage-guilds/out-province/true-guilds"; +export const ROUTE_ADMINX_ROUTE_IN_PROVINCE_LEGAL_GUILDS = + ROUTE_ADMINX_BASE + "/manage-guilds/in-province/legal-guilds"; +export const ROUTE_ADMINX_ROUTE_IN_PROVINCE_TRUE_GUILDS = + ROUTE_ADMINX_BASE + "/manage-guilds/in-province/true-guilds"; +export const ROUTE_ADMINX_ROUTE_GUILDS = + ROUTE_ADMINX_BASE + "/manage-guilds/guilds"; +export const ROUTE_ADMINX_ROUTE_IN_PROVINCE_STEWARDS = + ROUTE_ADMINX_BASE + "/manage-guilds/in-province/stewards"; +export const ROUTE_ADMINX_ROUTE_GUILDS_SETTINGS = + ROUTE_ADMINX_BASE + "/manage-guilds/settings"; +export const ROUTE_ADMINX_ROUTE_AGENT_SHARE = + ROUTE_ADMINX_BASE + "/agent-share"; +export const ROUTE_ADMINX_ROUTE_STEWARD_SHARE = + ROUTE_ADMINX_BASE + "/steward-share"; +export const ROUTE_ADMINX_ROUTE_AGENT_SHARE_ID = + ROUTE_ADMINX_BASE + "/agent-share/:id/:date"; +export const ROUTE_ADMINX_ROUTE_IN_PROVINCE_GUILDS_REQUESTS = + ROUTE_ADMINX_BASE + "/manage-guilds/in-province/guilds-requests"; +export const ROUTE_ADMINX_ROUTE_IN_PROVINCE_GUILDS_DISTRIBUTIONS = + ROUTE_ADMINX_BASE + "/manage-guilds/in-province/guilds-distributions"; +export const ROUTE_ADMINX_ROUTE_MANAGE_PROCESS = + ROUTE_ADMINX_BASE + "/manage-process/"; +export const ROUTE_ADMINX_ROUTE_MANAGE_PROCESS_SLAUGHTER = + ROUTE_ADMINX_BASE + "/manage-process/slaughter"; +export const ROUTE_ADMINX_ROUTE_SLAUGHTER_TRADE_PANEL = + ROUTE_ADMINX_BASE + "/manage-process/slaughter-trade-panel"; +export const ROUTE_ADMINX_ROUTE_MANAGE_DISTRIBUTIONS = + ROUTE_ADMINX_BASE + "/manage-process/manage-distributions"; +export const ROUTE_ADMINX_ROUTE_MANAGE_PROCESS_KILLPLACE = + ROUTE_ADMINX_BASE + "/manage-process/killplace"; +export const ROUTE_ADMINX_ROUTE_MANAGE_PROCESS_BUY_REQ = + ROUTE_ADMINX_BASE + "/manage-process/buy-req"; +export const ROUTE_ADMINX_ROUTE_MANAGE_PROCESS_POLICY_COUNCIL = + ROUTE_ADMINX_BASE + "/manage-process/policy-council"; +export const ROUTE_ADMINX_ROUTE_MANAGE_PROCESS_DOCUMENT_STATES = + ROUTE_ADMINX_BASE + "/manage-process/document-states"; +export const ROUTE_ADMINX_COLD_HOUSES = + ROUTE_ADMINX_BASE + "/cold-house-management"; +export const ROUTE_ADMINX_COLD_HOUSES_MANAGEMENT = + ROUTE_ADMINX_BASE + "/cold-houses-management"; +export const ROUTE_ADMINX_COLD_HOUSES_MANAGEMENT_VIEW = + ROUTE_ADMINX_BASE + "/cold-houses-management/:key/:name/:type"; +export const ROUTE_ADMINX_ROUTE_MANAGE_PROCESS_WAGE_FRACTIONS = + ROUTE_ADMINX_BASE + "/manage-process/wage-fractions"; +export const ROUTE_ADMINX_ROUTE_POLICY_COUNCIL_POULTRY_CHOOSE_SLAUGHTER = + ROUTE_ADMINX_BASE + "/policy-council/poultry-choose-slaughter"; +export const ROUTE_ADMINX_ROUTE_POLICY_COUNCIL_FREE_SALE = + ROUTE_ADMINX_BASE + "/policy-council/free-sale"; +export const ROUTE_ADMINX_ROUTE_POLICY_COUNCIL_DIRECT_BUY = + ROUTE_ADMINX_BASE + "/policy-council/direct-buy"; +export const ROUTE_ADMINX_ROUTE_POLICY_COUNCIL_KILLHOUSE_GUILDS = + ROUTE_ADMINX_BASE + "/policy-council/killhouse-guilds"; +export const ROUTE_ADMINX_ROUTE_CASE_STATUS = + ROUTE_ADMINX_BASE + "/case-status/"; +export const ROUTE_ADMINX_ROUTE_FILES_STATE = + ROUTE_ADMINX_BASE + "/files-state/"; +export const ROUTE_ADMINX_ASSIGN_VET_FARM = ROUTE_ADMINX_BASE + "/assign-farm/"; +export const ROUTE_ADMINX_CARS = ROUTE_ADMINX_BASE + "/cars/"; +export const ROUTE_ADMINX_USERS = ROUTE_ADMINX_BASE + "/users/"; +export const ROUTE_ADMINX_POULTRIES = ROUTE_ADMINX_BASE + "/poultries/"; +export const ROUTE_ADMINX_POULTRIES_DETAILS = + ROUTE_ADMINX_BASE + "/poultries/:key"; +export const ROUTE_ADMINX_GUILD_TRANSACTIONS = + ROUTE_ADMINX_BASE + "/transactions/"; +export const ROUTE_ADMINX_SLAUGHTERS = ROUTE_ADMINX_BASE + "/slaugter-houses/"; +export const ROUTE_ADMINX_SLAUGHTERS_MONITORING_BUYERS = + ROUTE_ADMINX_BASE + "/slaugter-houses/monitoring-buyers"; +export const ROUTE_ADMINX_SLAUGHTERS_MANAGE = + ROUTE_ADMINX_BASE + "/slaugter-houses/manage"; +export const ROUTE_ADMINX_ROUTE_SMS = ROUTE_ADMINX_BASE + "/sms"; +export const ROUTE_ADMINX_ROUTE_SMS_SEND = ROUTE_ADMINX_BASE + "/sms/send"; +export const ROUTE_ADMINX_ROUTE_SMS_MANAGE = ROUTE_ADMINX_BASE + "/sms/manage"; +export const ROUTE_ADMINX_ROUTE_MANAGE_PROCESS_MOBILE_MESSAGE = + ROUTE_ADMINX_BASE + "/sms/mobile-message"; +export const ROUTE_ADMINX_ROUTE_AGE_MESSAGE = + ROUTE_ADMINX_BASE + "/sms/age-message"; +export const ROUTE_ADMINX_PRICING3 = ROUTE_ADMINX_BASE + "/pricing"; +export const ROUTE_ADMINX_BARS = ROUTE_ADMINX_BASE + "/bars"; +export const ROUTE_ADMINX_USER_FILE_ROUTE = + ROUTE_ADMINX_BASE + "/userfile/:userid"; +export const ROUTE_ADMINX_OPERATOR_USER_FILE = ROUTE_ADMINX_BASE + "/userfile/"; +export const ROUTE_ADMINX_MANAGE_USERS = ROUTE_ADMINX_BASE + "/manage-users/"; +export const ROUTE_ADMINX_PAYING_FEES_REQUESTS = + ROUTE_ADMINX_BASE + "/requests/payment-of-fees"; +export const ROUTE_ADMINX_PAYING_FEES_REQUESTS_VIEW = + ROUTE_ADMINX_BASE + "/requests/payment-of-fees/:type/:key"; +export const ROUT_ADMINX_FREE_BUY = ROUTE_ADMINX_BASE + "/requests/free-buy"; + +export const ROUTE_ADMINX_BROADCAST_MANAGEMENT = + ROUTE_ADMINX_BASE + "/broadcast-management"; +export const ROUTE_ADMINX_REPORT = ROUTE_ADMINX_BASE + "/report"; +export const ROUTE_ADMINX_PRODUCTS = ROUTE_ADMINX_BASE + "/products"; +export const ROUTE_ADMINX_TRANSACTIONS = + ROUTE_ADMINX_BASE + "/requests/transactions"; +export const ROUTE_ADMINX_SALE_DESTRIBUTION_DETAILS = + ROUTE_ADMINX_BASE + "/requests/distribution"; +export const ROUTE_ADMINX_TRANSACTIONS_VIEW = + ROUTE_ADMINX_BASE + "/requests/transactions/:key/:name"; +export const ROUTE_ADMINX_CHAINS = ROUTE_ADMINX_BASE + "/chains"; +export const ROUTE_ADMINX_EXPORT = ROUTE_ADMINX_BASE + "/requests/export"; +export const ROUTE_ADMINX_ROUTE_ACCOUNTS = + ROUTE_ADMINX_BASE + "/manage-process/accounts"; +export const ROUTE_ADMINX_PROVINCE_SWITCH = + ROUTE_ADMINX_BASE + "/province-switch/"; +export const ROUTE_ADMINX_TRADING_PANEL = + ROUTE_ADMINX_BASE + "/requests/trade-panel"; + +export const ROUTE_ADMINX_TRADING_PANEL_FREE_BUY = + ROUTE_ADMINX_BASE + "/requests/trade-panel/free-buy"; +export const ROUTE_ADMINX_TRADING_PANEL_DASHBOARD = + ROUTE_ADMINX_BASE + "/requests/trade-panel/dashboard"; + +export const ROUTE_ADMINX_VISOR_STATICS = ROUTE_ADMINX_BASE + "/visor-statics"; +export const ROUTE_ADMINX_VISOR_STATICS_CHARTS = + ROUTE_ADMINX_BASE + "/visor-statics/charts"; +export const ROUTE_ADMINX_VISOR_STATICS_PREDICTION = + ROUTE_ADMINX_BASE + "/visor-statics/prediction/"; +export const ROUTE_ADMINX_VISOR_STATICS_PREDICTION_VIEW = + ROUTE_ADMINX_BASE + "/visor-statics/prediction/:key/:date"; +export const ROUTE_ADMINX_EXCEL_CHECK = ROUTE_ADMINX_BASE + "/excel-check"; +export const ROUTE_ADMINX_DISPENSERS = ROUTE_ADMINX_BASE + "/dispensers"; +export const ROUTE_ADMINX_DISPENSERS_MANAGEMENT = + ROUTE_ADMINX_BASE + "/dispensers-management"; +export const ROUTE_ADMINX_DISPENSERS_MANAGEMENT_V2 = + ROUTE_ADMINX_BASE + "/dispensers-management-v2"; +export const ROUTE_ADMINX_DELEGATES_MANAGEMENT = + ROUTE_ADMINX_BASE + "/delegates-management"; +export const ROUTE_ADMINX_DISPENSER_DETAILS = + ROUTE_ADMINX_BASE + "/dispenser-data"; +export const ROUTE_ADMINX_DISPENSER_DETAILS_VIEW = + ROUTE_ADMINX_BASE + "/dispenser-data/:key"; +export const ROUTE_ADMINX_DISPENSERS_STEWARDS = + ROUTE_ADMINX_BASE + "/dispensers-stewards"; +export const ROUTE_ADMINX_DISPENSERS_KILLHOUSES = + ROUTE_ADMINX_BASE + "/dispensers-killhouses"; +export const ROUTE_ADMINX_DISPENSERS_KILLHOUSES_VIEW = + ROUTE_ADMINX_BASE + "/dispensers-killhouses/:key/:name"; +export const ROUTE_ADMINX_DISPENSERS_INVENTORY = + ROUTE_ADMINX_BASE + "/dispensers-inventory"; +export const ROUTE_ADMINX_DISPENSERS_SELL_CARCASS = + ROUTE_ADMINX_BASE + "/dispensers-sell-carcass"; +export const ROUTE_ADMINX_DISPENSERS_STOCK = + ROUTE_ADMINX_BASE + "/dispensers/stock"; +export const ROUTE_ADMINX_DISPENSERS_STOCK_KILLHOUSE = + ROUTE_ADMINX_BASE + "/dispensers/stock/killhouse"; +export const ROUTE_ADMINX_DISPENSERS_STOCK_GUILD = + ROUTE_ADMINX_BASE + "/dispensers/stock/guild"; +export const ROUTE_ADMINX_DISPENSERS_STOCK_STEWARD = + ROUTE_ADMINX_BASE + "/dispensers/stock/steward"; +export const ROUTE_ADMINX_SUB_SECTORS_WAGE = + ROUTE_ADMINX_BASE + "/subsectors-wage"; +export const ROUTE_ADMINX_SUB_SECTORS_CITY_SHARES = + ROUTE_ADMINX_BASE + "/subsectors-city-shares"; +export const ROUTE_ADMINX_SUB_SECTORS_STEWARD_SHARES = + ROUTE_ADMINX_BASE + "/subsectors-steward-shares"; +export const ROUTE_ADMINX_SUB_SECTORS_VET_FARM_SHARES = + ROUTE_ADMINX_BASE + "/subsectors-vet-farm-shares"; +export const ROUTE_ADMINX_ROUTE_TICKET_PERMISSION = + ROUTE_ADMINX_BASE + "/manage-process/ticket-permission"; +export const ROUTE_ADMINX_ROUTE_CRONJOB = ROUTE_ADMINX_BASE + "/cronjob"; +export const ROUTE_ADMINX_ROUTE_Sms_Submission_Management = + ROUTE_ADMINX_BASE + "/sms-submission-management"; +export const ROUTE_ADMINX_ROUTE_WEIGHT_RANGE = + ROUTE_ADMINX_BASE + "/manage-process/weight-range"; +export const ROUTE_ADMINX_ROUTE_PENALTY = + ROUTE_ADMINX_BASE + "/manage-process/penalty"; +export const ROUTE_ADMINX_ROUTE_WEIGHT_CATEGORY = + ROUTE_ADMINX_BASE + "/manage-process/weight-category"; +export const ROUTE_ADMINX_ROUTE_RESTRICTION_OF_CARCASS_DISTRIBUTION = + ROUTE_ADMINX_BASE + "/manage-process/restriction-of-carcass-distribution"; +export const ROUTE_ADMINX_ROUTE_NATIONAL_INFO = + ROUTE_ADMINX_BASE + "/national-info"; +export const ROUTE_ADMINX_ROUTE_NATIONAL_INFO_DETAILS = + ROUTE_ADMINX_BASE + "/national-info/:key"; +export const ROUTE_ADMINX_ROUTE_NATIONAL_INFO_FARM = + ROUTE_ADMINX_BASE + "/national-farm-info"; +export const ROUTE_ADMINX_ROUTE_NATIONAL_INFO_FARM_DETAILS = + ROUTE_ADMINX_BASE + "/national-farm-info/:key/:name"; +export const ROUTE_ADMINX_ROUTE_NATIONAL_INFO_HATCHING_DETAILS = + ROUTE_ADMINX_BASE + "/national-info/:key/:name"; +export const ROUTE_ADMINX_ROUTE_NATIONAL_INFO_SLAUGHTER = + ROUTE_ADMINX_BASE + "/national-slaughter-info"; +export const ROUTE_ADMINX_ROUTE_NATIONAL_INFO_SLAUGHTER_DETAILS = + ROUTE_ADMINX_BASE + "/national-slaughter-info/:unitkey/:name"; +export const ROUTE_ADMINX_ROUTE_NATIONAL_INFO_DISTRIBUTION_DETAILS = + ROUTE_ADMINX_BASE + "/national-slaughter-info/:unitkey/:name/:type"; +export const ROUTE_ADMINX_ROUTE_KILLERS_WAGES = + ROUTE_ADMINX_BASE + "/requests/payment-of-fees-killers"; +export const ROUTE_ADMINX_ROUTE_KILLERS_WAGES_DETAILS = + ROUTE_ADMINX_BASE + "/requests/payment-of-fees-killers/:key"; +export const ROUTE_ADMINX_DIFFRENCE_KILLER = + ROUTE_ADMINX_BASE + "/manage-hatchings/diffrence-killer"; +export const ROUTE_ADMINX_DIFFRENCE_KILLER_SLAUGHTER = + ROUTE_ADMINX_BASE + "/manage-hatchings/diffrence-killer-slaughter"; +export const ROUTE_ADMINX_INCREASE_HATCHING = + ROUTE_ADMINX_BASE + "/hatching/increase-hatching"; +export const ROUTE_ADMINX_DASHBOARD = ROUTE_ADMINX_BASE + "/dashbord"; +export const ROUTE_ADMINX_DASHBOARD_NEWS = + ROUTE_ADMINX_BASE + "/dashboard/news"; +export const ROUTE_ADMINX_POULTRY_LIVESTOCK_EXPERTS = + ROUTE_ADMINX_BASE + "/livestock-experts"; +export const ROUTE_ADMINX_COMPONENTS_CATALOG = + ROUTE_ADMINX_BASE + "/components-catalog"; +export const ROUTE_ADMINX_RETURN_PURCHASES = + ROUTE_ADMINX_BASE + "/return-purchases"; + +export const ROUTE_ADMINX_ROUTE_COMPANY_MANAGE_STEWARDS = + ROUTE_ADMINX_BASE + "/manage-stewards"; +export const ROUTE_ADMINX_ROUTE_PSP_COMPANIES = + ROUTE_ADMINX_BASE + "/psp-companies"; +export const ROUTE_ADMINX_COMPANY_ROUTE_GUILDS = + ROUTE_ADMINX_BASE + "/manage-guilds/guilds"; +export const ROUTE_ADMINX_COMPANY_ROUTE_ACTIVE_SESSION = + ROUTE_ADMINX_BASE + "/active-session/session"; +export const ROUTE_ADMINX_COMPANY_ROUTE_DEVICES = + ROUTE_ADMINX_BASE + "/devices"; + +export const ROUTE_ADMINX_ROUTE_INSPECTION = ROUTE_ADMINX_BASE + "/inspection"; + +// Supporter +export const ROUTE_SUPPORTER_ROUTE_ALLOCATIONS = + ROUTE_SUPPORTER_BASE + "/allocations/"; +export const ROUTE_SUPPORTERـHATCHINGS = + ROUTE_SUPPORTER_BASE + "/manage-hatchings"; +export const ROUTE_SUPPORTERـHATCHINGS_DETAILS = + ROUTE_SUPPORTER_BASE + "/manage-hatchings/:key"; + +// Dispenser +export const ROUTE_DISPENSER_DASHBOARD = ROUTE_DISPENSER_BASE + "/dashboard/"; + +// Parent Company +export const ROUTE_PARENT_COMPANY_PAYING_FEES_REQUESTS = + ROUTE_PARENT_COMPANY_BASE + "/requests/payment-of-fees"; + +export const ROUTE_PARENT_COMPANY_PAYING_FEES_VIEW = + ROUTE_PARENT_COMPANY_BASE + "/requests/payment-of-fees/:type/:key"; +export const ROUTE_PARENT_COMPANY_ALLOCATIONS = + ROUTE_PARENT_COMPANY_BASE + "/allocations/"; + +// cold house steward + +export const ROUTE_COLD_HOUSE_STEWARD_USER_PROFILE = + "/dashboard/profile" + ROUTE_COLD_HOUSE_STEWARD_BASE; +export const ROUTE_COLD_HOUSE_STEWARD_MORGUE = + ROUTE_COLD_HOUSE_STEWARD_BASE + "/morgue"; + +// province jahad + +export const ROUTE_PROVINCE_JAHAD_UNIONS = + ROUTE_PROVINCE_JAHAD_BASE + "/unions"; + +export const ROUTE_PROVINCE_JAHAD_COOPERATIVES = + ROUTE_PROVINCE_JAHAD_BASE + "/cooperatives"; + +export const ROUTE_PROVINCE_JAHAD_RANCHERS = + ROUTE_PROVINCE_JAHAD_BASE + "/ranchers"; + +export const ROUTE_PROVINCE_JAHAD_HERDS = ROUTE_PROVINCE_JAHAD_BASE + "/herds"; + +export const ROUTE_PROVINCE_JAHAD_USERS = ROUTE_PROVINCE_JAHAD_BASE + "/users"; + +export const ROUTE_PROVINCE_JAHAD_PRODUCT_DISTRIBUTION = + ROUTE_PROVINCE_JAHAD_BASE + "/product-distributions"; + +export const ROUTE_PROVINCE_JAHAD_PRODUCT_TRANSACTIONS = + ROUTE_PROVINCE_JAHAD_BASE + "/product-transactions"; + +export const ROUTE_PROVINCE_JAHAD_PRODUCT_DISTRIBUTION_ALLOCATION = + ROUTE_PROVINCE_JAHAD_BASE + "/product-distributions/allocation"; + +export const ROUTE_PROVINCE_JAHAD_PRODUCT_DISTRIBUTION_POLICY = + ROUTE_PROVINCE_JAHAD_BASE + "/product-distributions/policy"; + +export const ROUTE_PROVINCE_JAHAD_PRODUCT_SHARES = + ROUTE_PROVINCE_JAHAD_BASE + "/product-distributions/shares"; + +export const ROUTE_PROVINCE_JAHAD_SELL_REPORT = + ROUTE_PROVINCE_JAHAD_BASE + "/sell-reports"; + +export const ROUTE_PROVINCE_JAHAD_ROUTE_INSPECTION = + ROUTE_PROVINCE_JAHAD_BASE + "/inspection"; + +// unions + +export const ROUTE_UNION_COOPERATIVES = ROUTE_UNION_BASE + "/cooperatives"; + +export const ROUTE_UNION_RANCHERS = ROUTE_UNION_BASE + "/ranchers"; + +export const ROUTE_UNION_HERDS = ROUTE_UNION_BASE + "/herds"; + +export const ROUTE_UNION_USERS = ROUTE_UNION_BASE + "/users"; + +export const ROUTE_UNION_PRODUCT_DISTRIBUTION = + ROUTE_UNION_BASE + "/product-distributions"; + +export const ROUTE_UNION_PRODUCT_TRANSACTIONS = + ROUTE_UNION_BASE + "/product-transactions"; + +export const ROUTE_UNION_PRODUCT_DISTRIBUTION_ALLOCATION = + ROUTE_UNION_BASE + "/product-distributions/allocation"; + +export const ROUTE_UNION_PRODUCT_DISTRIBUTION_POLICY = + ROUTE_UNION_BASE + "/product-distributions/policy"; + +export const ROUTE_UNION_SELL_REPORT = ROUTE_UNION_BASE + "/sell-reports"; + +export const ROUTE_UNION_ROUTE_INSPECTION = ROUTE_UNION_BASE + "/inspection"; +// cooperatives + +export const ROUTE_COOPERATIVE_RANCHERS = ROUTE_COOPERATIVE_BASE + "/ranchers"; + +export const ROUTE_COOPERATIVE_HERDS = ROUTE_COOPERATIVE_BASE + "/herds"; + +export const ROUTE_COOPERATIVE_USERS = ROUTE_COOPERATIVE_BASE + "/users"; + +export const ROUTE_COOPERATIVE_PRODUCT_DISTRIBUTION = + ROUTE_COOPERATIVE_BASE + "/product-distributions"; + +export const ROUTE_COOPERATIVE_PRODUCT_TRANSACTIONS = + ROUTE_COOPERATIVE_BASE + "/product-transactions"; + +export const ROUTE_COOPERATIVE_PRODUCT_DISTRIBUTION_ALLOCATION = + ROUTE_COOPERATIVE_BASE + "/product-distributions/allocation"; + +export const ROUTE_COOPERATIVE_PRODUCT_DISTRIBUTION_POLICY = + ROUTE_COOPERATIVE_BASE + "/product-distributions/policy"; + +// bar square + +export const ROUTE_BAR_SQUARE_TRANSACTIONS = + ROUTE_BAR_SQUARE_BASE + "/transactions"; diff --git a/src/routes/senfRouting.js b/src/routes/senfRouting.js new file mode 100644 index 0000000..93e6d6c --- /dev/null +++ b/src/routes/senfRouting.js @@ -0,0 +1,39 @@ +import { lazy } from "react"; +import { lazyRetry } from "../utils/lazyRetry"; +import { + ROUTE_GUILD_ROUTE_DEVICES, + ROUTE_SENF_INVENTORY, + ROUTE_SENF_INVENTORY_ENTER, + ROUTE_SENF_INVENTORY_SEGMENTATION, + ROUTE_SENF_INVENTORY_STOCK, +} from "./routes"; + +const SenfInventoryPage = lazy(() => + lazyRetry(() => import("../pages/SenfInventoryPage")) +); + +const GuildPspDevices = lazy(() => + lazyRetry(() => + import("../features/guild/components/guild-psp-devices/GuildPspDevices") + ) +); + +export const senfRouting = [ + { + path: [ + ROUTE_SENF_INVENTORY, + ROUTE_SENF_INVENTORY_STOCK, + ROUTE_SENF_INVENTORY_SEGMENTATION, + ROUTE_SENF_INVENTORY_ENTER, + ], + Page: SenfInventoryPage, + exact: false, + props: {}, + }, + { + path: [ROUTE_GUILD_ROUTE_DEVICES], + Page: GuildPspDevices, + exact: false, + props: {}, + }, +]; diff --git a/src/routes/slaughterHouseVet.js b/src/routes/slaughterHouseVet.js new file mode 100644 index 0000000..ac49968 --- /dev/null +++ b/src/routes/slaughterHouseVet.js @@ -0,0 +1,64 @@ +import { lazy } from "react"; +import { lazyRetry } from "../utils/lazyRetry"; +import { + ROUTE_SLAUGHTER_HOUSE_VET_ACTIVE_REQUESTS, + ROUTE_SLAUGHTER_HOUSE_VET_ARCHIVED_REQUESTS, + ROUTE_SLAUGHTER_HOUSE_VET_FILE_ROUTE, + ROUTE_SLAUGHTER_HOUSE_VET_NEW_REQUESTS, + ROUTE_SLAUGHTER_HOUSE_VET_REJECTED_REQUESTS, + ROUTE_SLAUGHTER_HOUSE_VET_REQUESTS, + ROUTE_SLAUGHTER_HOUSE_VET_COMPLAINTS, + ROUTE_SLAUGHTER_PRICING, + ROUTE_SLAUGHTER_HOUSE_VET_ENTER_BAR_INFO, + ROUTE_SLAUGHTER_HOUSE_VET_FREE_BUY_ROUTE, +} from "./routes"; + +const SlaughterHouseVetPage = lazy(() => + lazyRetry(() => import("../pages/SlaughterHouseVet")) +); +// const File = lazy(() => lazyRetry(() => import("../pages/File"))); +const NewFile = lazy(() => lazyRetry(() => import("../pages/NewFile"))); + +const SlaughterPricing = lazy(() => + lazyRetry(() => import("../pages/ProvinceManagePricing")) +); + +const FreeBuy = lazy(() => + lazyRetry(() => import("../pages/SlaughterFreeBuy")) +); + +export const slaughterHouseVetRouting = [ + //requests + { + path: [ + ROUTE_SLAUGHTER_HOUSE_VET_REQUESTS, + ROUTE_SLAUGHTER_HOUSE_VET_NEW_REQUESTS, + ROUTE_SLAUGHTER_HOUSE_VET_ACTIVE_REQUESTS, + ROUTE_SLAUGHTER_HOUSE_VET_REJECTED_REQUESTS, + ROUTE_SLAUGHTER_HOUSE_VET_ARCHIVED_REQUESTS, + ROUTE_SLAUGHTER_HOUSE_VET_ENTER_BAR_INFO, + ROUTE_SLAUGHTER_HOUSE_VET_COMPLAINTS, + ], + Page: SlaughterHouseVetPage, + exact: false, + props: {}, + }, + { + path: [ROUTE_SLAUGHTER_HOUSE_VET_FILE_ROUTE], + Page: NewFile, + exact: false, + props: {}, + }, + { + path: [ROUTE_SLAUGHTER_PRICING], + Page: SlaughterPricing, + exact: false, + props: {}, + }, + { + path: [ROUTE_SLAUGHTER_HOUSE_VET_FREE_BUY_ROUTE], + Page: FreeBuy, + exact: false, + props: {}, + }, +]; diff --git a/src/routes/slaughterRouting.js b/src/routes/slaughterRouting.js new file mode 100644 index 0000000..cfd4ad8 --- /dev/null +++ b/src/routes/slaughterRouting.js @@ -0,0 +1,339 @@ +import { lazy } from "react"; +import { lazyRetry } from "../utils/lazyRetry"; +import { + ROUTE_SLAUGHTER_ACTIVE_REQUESTS, + ROUTE_SLAUGHTER_ADD_CAR, + ROUTE_SLAUGHTER_ARCHIVED_REQUESTS, + ROUTE_SLAUGHTER_AUCTION, + ROUTE_SLAUGHTER_CAR_MANAGEMENT, + ROUTE_SLAUGHTER_FILE_ROUTE, + ROUTE_SLAUGHTER_REJECTED_REQUESTS, + ROUTE_SLAUGHTER_REQUESTS, + ROUTE_SLAUGHTER_TICKET, + ROUTE_SLAUGHTER_VIEW_TICKET, + ROUTE_SLAUGHTER_COMPLAINTS, + ROUTE_SLAUGHTER_INVENTORY, + ROUTE_SLAUGHTER_FACTORS, + ROUTE_SLAUGHTER_PENDING_REQUESTS, + ROUTE_SLAUGHTER_ALLOCATE_CAR_REQUESTS, + ROUTE_SLAUGHTER_ENTER_BAR_INFO, + ROUTE_SLAUGHTER_PAY_FACTORS_REQUESTS, + ROUTE_SLAUGHTER_NEW_REQUESTS, + ROUTE_SLAUGHTER_PRICING, + ROUTE_SLAUGHTER_FINAL_FACTORS, + ROUTE_SLAUGHTER_INVENTORY_SELL_CARCASS_OUT_PROVINCE, + ROUTE_SLAUGHTER_INVENTORY_SELL_CARCASS_IN_PROVINCE, + ROUTE_SLAUGHTER_INVENTORY_STOCK, + ROUTE_SLAUGHTER_PAYING_FEES_REQUESTS, + ROUTE_SLAUGHTERـFREE_BUY, + ROUTE_SLAUGHTER_TRADING_PANEL, + ROUTE_SLAUGHTER_ROUTE_MANAGE_GUILDS, + ROUTE_SLAUGHTER_FINANCIAL_TRANSACTIONS, + ROUTE_SLAUGHTER_AGENT_SHARE, + ROUTE_SLAUGHTER_AGENT_SHARE_ID, + ROUTE_SLAUGHTER_MORGUE, + ROUTE_SLAUGHTER_MORGUE_STOCK, + ROUTE_SLAUGHTER_MORGUE_BROADCAST_MANAGEMENT, + ROUTE_SLAUGHTER_ROUTE_MANAGE_BARS, + ROUTE_SLAUGHTER_WALLET, + ROUTE_SLAUGHTERـEXPORT, + ROUTE_SLAUGHTER_OUT_PROVINCE_BUY, + ROUTE_SLAUGHTER_DISPENSERS, + ROUTE_SLAUGHTER_DISPENSERS_MANAGEMENT, + ROUTE_SLAUGHTER_DISPENSER_DETAILS, + ROUTE_SLAUGHTER_DISPENSER_DETAILS_VIEW, + ROUTE_SLAUGHTER_ALLOCATION_REQUESTS, + ROUTE_SLAUGHTER_SELL_CARCASS, + ROUTE_SLAUGHTER_DISPENSERS_STEWARDS, + ROUTE_SLAUGHTER_DISPENSERS_KILLHOUSES, + ROUTE_SLAUGHTER_MORGUE_VIEW, + ROUTE_SLAUGHTER_DAILY_LIST, + ROUTE_SLAUGHTER_SETTLEMENTS, + ROUTE_SLAUGHTER_SEGMENTATION, + ROUTE_SLAUGHTER_RETURN_PURCHASES, + ROUTE_SLAUGHTER_INVENTORY_SUMMARY, + ROUTE_SLAUGHTER_ORDERS, + ROUTE_SLAUGHTER_ROUTE_MANAGE_DISPENSERS, + ROUTE_SLAUGHTER_ROUTE_MANAGE_DELEGATES, + ROUTE_SLAUGHTER_ROUTE_DEVICES, + ROUTE_SLAUGHTER_ROUTE_SUB_UNITS, +} from "./routes"; + +const TradePanel = lazy(() => lazyRetry(() => import("../pages/TradePanel"))); + +const Cars = lazy(() => lazyRetry(() => import("../pages/CarManagement"))); +const SlaughterRequestsPage = lazy(() => + lazyRetry(() => import("../pages/SlaughterRequestsPage")) +); +// const File = lazy(() => lazyRetry(() => import("../pages/File"))); +const NewFile = lazy(() => lazyRetry(() => import("../pages/NewFile"))); +const Auction = lazy(() => lazyRetry(() => import("../pages/Auction"))); +const Tickets = lazy(() => lazyRetry(() => import("../pages/Tickets"))); +const AgentShare = lazy(() => + lazyRetry(() => import("../pages/SlaughterAgentShare")) +); +const SlaughterInventoryPage = lazy(() => + lazyRetry(() => import("../pages/SlaughterInventoryPage")) +); + +const SlaughterMorguePage = lazy(() => + lazyRetry(() => import("../pages/SlaughterMorgue")) +); + +const SlaughterManageBars = lazy(() => + lazyRetry(() => import("../pages/SlaughterManageBars")) +); + +const Complaints = lazy(() => + lazyRetry(() => import("../pages/SlaughterComplaints")) +); + +const SlaughterPricing = lazy(() => + lazyRetry(() => import("../pages/ProvinceManagePricing")) +); +const Payment = lazy(() => lazyRetry(() => import("../pages/ProvinceFees"))); +const Wallet = lazy(() => lazyRetry(() => import("../pages/Wallet"))); + +const Guilds = lazy(() => lazyRetry(() => import("../pages/Guilds"))); + +const TransactionsPage = lazy(() => + lazyRetry(() => import("../pages/Transactions")) +); + +const FreeBuy = lazy(() => + lazyRetry(() => import("../pages/SlaughterFreeBuy")) +); + +const Dispensers = lazy(() => + lazyRetry(() => import("../pages/SlaughterHouseDispenserDashboard")) +); + +const SettlementPage = lazy(() => + lazyRetry(() => import("../pages/AdminSettlement")) +); + +const ReturnPurchases = lazy(() => + lazyRetry(() => import("../pages/ReturnPurchases")) +); + +const ManageDispensers = lazy(() => + lazyRetry(() => + import( + "../features/slaughter-house/components/slaughter-manage-dispensers/SlaughterManageDispensers" + ) + ) +); + +const ManageDelegates = lazy(() => + lazyRetry(() => + import( + "../features/slaughter-house/components/slaughter-manage-delegates/SlaughterManageDelegates" + ) + ) +); + +const PspDevices = lazy(() => + lazyRetry(() => + import("../features/guild/components/guild-psp-devices/GuildPspDevices") + ) +); + +const SlaughterSubUnits = lazy(() => + lazyRetry(() => import("../pages/SlaughterSubUnits")) +); + +export const slaughterRouting = [ + //cars section slaughter + { + path: [ROUTE_SLAUGHTER_ADD_CAR, ROUTE_SLAUGHTER_CAR_MANAGEMENT], + Page: Cars, + exact: false, + props: {}, + }, + //requests + { + path: [ + ROUTE_SLAUGHTER_REQUESTS, + ROUTE_SLAUGHTERـFREE_BUY, + ROUTE_SLAUGHTER_ACTIVE_REQUESTS, + ROUTE_SLAUGHTER_REJECTED_REQUESTS, + ROUTE_SLAUGHTER_ARCHIVED_REQUESTS, + ROUTE_SLAUGHTER_PENDING_REQUESTS, + ROUTE_SLAUGHTER_ALLOCATE_CAR_REQUESTS, + ROUTE_SLAUGHTER_ENTER_BAR_INFO, + ROUTE_SLAUGHTER_SELL_CARCASS, + ROUTE_SLAUGHTER_PAY_FACTORS_REQUESTS, + ROUTE_SLAUGHTER_NEW_REQUESTS, + ROUTE_SLAUGHTER_FACTORS, + ROUTE_SLAUGHTER_FINAL_FACTORS, + ROUTE_SLAUGHTERـEXPORT, + ROUTE_SLAUGHTER_ALLOCATION_REQUESTS, + ], + Page: SlaughterRequestsPage, + exact: false, + props: {}, + }, + { + path: [ROUTE_SLAUGHTER_TRADING_PANEL], + Page: TradePanel, + exact: false, + props: {}, + }, + { + path: [ROUTE_SLAUGHTER_SETTLEMENTS], + Page: SettlementPage, + exact: false, + props: {}, + }, + { + path: [ROUTE_SLAUGHTER_AUCTION], + Page: Auction, + exact: false, + props: {}, + }, + { + path: [ + ROUTE_SLAUGHTER_DISPENSERS, + ROUTE_SLAUGHTER_DISPENSERS_MANAGEMENT, + ROUTE_SLAUGHTER_DISPENSER_DETAILS, + ROUTE_SLAUGHTER_DISPENSER_DETAILS_VIEW, + ROUTE_SLAUGHTER_DISPENSERS_STEWARDS, + ROUTE_SLAUGHTER_DISPENSERS_KILLHOUSES, + ], + Page: Dispensers, + exact: false, + props: {}, + }, + { + path: [ROUTE_SLAUGHTER_FILE_ROUTE], + Page: NewFile, + exact: false, + props: {}, + }, + { + path: [ROUTE_SLAUGHTER_VIEW_TICKET, ROUTE_SLAUGHTER_TICKET], + Page: Tickets, + exact: false, + props: {}, + }, + { + path: [ROUTE_SLAUGHTER_COMPLAINTS], + Page: Complaints, + exact: false, + props: {}, + }, + { + path: [ + ROUTE_SLAUGHTER_INVENTORY, + ROUTE_SLAUGHTER_INVENTORY_SELL_CARCASS_OUT_PROVINCE, + ROUTE_SLAUGHTER_INVENTORY_STOCK, + ROUTE_SLAUGHTER_INVENTORY_SELL_CARCASS_IN_PROVINCE, + ROUTE_SLAUGHTER_DAILY_LIST, + ROUTE_SLAUGHTER_SEGMENTATION, + ], + Page: SlaughterInventoryPage, + exact: false, + props: {}, + }, + { + path: [ROUTE_SLAUGHTER_PRICING], + Page: SlaughterPricing, + exact: false, + props: {}, + }, + { + path: [ROUTE_SLAUGHTER_PAYING_FEES_REQUESTS], + Page: Payment, + exact: false, + props: {}, + }, + { + path: [ROUTE_SLAUGHTER_WALLET], + Page: Wallet, + exact: false, + props: {}, + }, + { + path: [ROUTE_SLAUGHTER_ROUTE_MANAGE_GUILDS], + Page: Guilds, + exact: false, + props: {}, + }, + { + path: [ROUTE_SLAUGHTER_FINANCIAL_TRANSACTIONS], + Page: TransactionsPage, + exact: false, + props: {}, + }, + { + path: [ROUTE_SLAUGHTER_AGENT_SHARE, ROUTE_SLAUGHTER_AGENT_SHARE_ID], + Page: AgentShare, + exact: false, + props: {}, + }, + { + path: [ + ROUTE_SLAUGHTER_MORGUE, + ROUTE_SLAUGHTER_MORGUE_STOCK, + ROUTE_SLAUGHTER_MORGUE_BROADCAST_MANAGEMENT, + ROUTE_SLAUGHTER_MORGUE_VIEW, + ], + Page: SlaughterMorguePage, + exact: false, + props: {}, + }, + { + path: [ROUTE_SLAUGHTER_ROUTE_MANAGE_BARS], + Page: SlaughterManageBars, + exact: false, + props: {}, + }, + { + path: [ROUTE_SLAUGHTER_OUT_PROVINCE_BUY], + Page: FreeBuy, + exact: false, + props: {}, + }, + { + path: [ROUTE_SLAUGHTER_RETURN_PURCHASES], + Page: ReturnPurchases, + exact: false, + props: {}, + }, + { + path: [ROUTE_SLAUGHTER_INVENTORY_SUMMARY], + Page: SlaughterInventoryPage, + exact: false, + props: {}, + }, + { + path: [ROUTE_SLAUGHTER_ORDERS], + Page: SlaughterInventoryPage, + exact: false, + props: {}, + }, + { + path: [ROUTE_SLAUGHTER_ROUTE_SUB_UNITS], + Page: SlaughterSubUnits, + exact: false, + props: {}, + }, + { + path: [ROUTE_SLAUGHTER_ROUTE_MANAGE_DISPENSERS], + Page: ManageDispensers, + exact: false, + props: {}, + }, + { + path: [ROUTE_SLAUGHTER_ROUTE_MANAGE_DELEGATES], + Page: ManageDelegates, + exact: false, + props: {}, + }, + { + path: [ROUTE_SLAUGHTER_ROUTE_DEVICES], + Page: PspDevices, + exact: false, + props: {}, + }, +]; diff --git a/src/routes/stewardRouting.js b/src/routes/stewardRouting.js new file mode 100644 index 0000000..3035d86 --- /dev/null +++ b/src/routes/stewardRouting.js @@ -0,0 +1,105 @@ +import { lazy } from "react"; +import { lazyRetry } from "../utils/lazyRetry"; +import { + ROUTE_STEWARD_INVENTORY, + ROUTE_STEWARD_SALE_IN_PROVINCE, + ROUTE_STEWARD_INVENTORY_STOCK, + ROUTE_JAHAD_FILES_STATE, + ROUTE_STEWARD_MANAGE_GUILDS, + ROUTE_STEWARD_DAILY_LIST, + ROUTE_STEWARD_PURCHASE_OUT_PROVINCE, + ROUTE_STEWARD_SALE_OUT_PROVINCE, + ROUTE_STEWARD_SEGMENT, + ROUTE_STEWARD_ROUTE_MANAGE_DISPENSERS, + ROUTE_STEWARD_ROUTE_MANAGE_DELEGATES, + ROUTE_STEWARD_ROUTE_DEVICES, + ROUTE_STEWARD_ROUTE_SUB_UNITS, +} from "./routes"; +const FilesState = lazy(() => lazyRetry(() => import("../pages/FilesState"))); + +const StewardInventoryPage = lazy(() => + lazyRetry(() => import("../pages/StewardInventoryPage")) +); + +const ManageGuilds = lazy(() => + lazyRetry(() => import("../pages/GuildManageGuildsPage")) +); + +const ManageDispensers = lazy(() => + lazyRetry(() => + import( + "../features/slaughter-house/components/slaughter-manage-dispensers/SlaughterManageDispensers" + ) + ) +); + +const ManageDelegates = lazy(() => + lazyRetry(() => + import( + "../features/slaughter-house/components/slaughter-manage-delegates/SlaughterManageDelegates" + ) + ) +); + +const PspDevices = lazy(() => + lazyRetry(() => + import("../features/guild/components/guild-psp-devices/GuildPspDevices") + ) +); + +const SubUnits = lazy(() => + lazyRetry(() => import("../pages/SlaughterSubUnits")) +); + +export const stewardRouting = [ + { + path: [ROUTE_JAHAD_FILES_STATE], + Page: FilesState, + exact: false, + props: {}, + }, + { + path: [ROUTE_STEWARD_MANAGE_GUILDS], + Page: ManageGuilds, + exact: false, + props: {}, + }, + { + path: [ + ROUTE_STEWARD_INVENTORY, + ROUTE_STEWARD_SALE_IN_PROVINCE, + ROUTE_STEWARD_INVENTORY_STOCK, + ROUTE_STEWARD_PURCHASE_OUT_PROVINCE, + ROUTE_STEWARD_SALE_OUT_PROVINCE, + ROUTE_STEWARD_DAILY_LIST, + ROUTE_STEWARD_SEGMENT, + ], + Page: StewardInventoryPage, + exact: false, + props: {}, + }, + { + path: [ROUTE_STEWARD_ROUTE_SUB_UNITS], + Page: SubUnits, + exact: false, + props: {}, + }, + { + path: [ROUTE_STEWARD_ROUTE_MANAGE_DISPENSERS], + Page: ManageDispensers, + exact: false, + props: {}, + }, + { + path: [ROUTE_STEWARD_ROUTE_MANAGE_DELEGATES], + Page: ManageDelegates, + exact: false, + props: {}, + }, + { + path: [ROUTE_STEWARD_ROUTE_DEVICES], + Page: PspDevices, + exact: false, + props: {}, + }, +]; diff --git a/src/routes/supporterRouting.js b/src/routes/supporterRouting.js new file mode 100644 index 0000000..f99644c --- /dev/null +++ b/src/routes/supporterRouting.js @@ -0,0 +1,31 @@ +import { lazy } from "react"; +import { lazyRetry } from "../utils/lazyRetry"; +import { + ROUTE_SUPPORTER_ROUTE_ALLOCATIONS, + ROUTE_SUPPORTERـHATCHINGS, + ROUTE_SUPPORTERـHATCHINGS_DETAILS, +} from "./routes"; + +const VetFarmAllocations = lazy(() => + lazyRetry(() => import("../pages/VetFarmAllocations")) +); + +const AllHatchings = lazy(() => + lazyRetry(() => import("../pages/AdminHatchings")) +); + +export const supporterRouting = [ + { + path: [ROUTE_SUPPORTER_ROUTE_ALLOCATIONS], + Page: VetFarmAllocations, + exact: false, + props: {}, + }, + + { + path: [ROUTE_SUPPORTERـHATCHINGS, ROUTE_SUPPORTERـHATCHINGS_DETAILS], + Page: AllHatchings, + exact: false, + props: {}, + }, +]; diff --git a/src/routes/unionRouting.js b/src/routes/unionRouting.js new file mode 100644 index 0000000..bdfb666 --- /dev/null +++ b/src/routes/unionRouting.js @@ -0,0 +1,36 @@ +import { lazy } from "react"; +import { lazyRetry } from "../utils/lazyRetry"; +import { + ROUTE_UNION_PRODUCT_DISTRIBUTION, + ROUTE_UNION_PRODUCT_DISTRIBUTION_ALLOCATION, + ROUTE_UNION_PRODUCT_DISTRIBUTION_POLICY, + ROUTE_UNION_PRODUCT_TRANSACTIONS, + ROUTE_UNION_COOPERATIVES, + ROUTE_UNION_HERDS, + ROUTE_UNION_RANCHERS, + ROUTE_UNION_SELL_REPORT, + ROUTE_UNION_USERS, +} from "./routes"; + +const RequestsPage = lazy(() => + lazyRetry(() => import("../pages/ProvinceJahadRequests")) +); + +export const unionRouting = [ + { + path: [ + ROUTE_UNION_COOPERATIVES, + ROUTE_UNION_RANCHERS, + ROUTE_UNION_HERDS, + ROUTE_UNION_USERS, + ROUTE_UNION_PRODUCT_DISTRIBUTION, + ROUTE_UNION_PRODUCT_DISTRIBUTION_ALLOCATION, + ROUTE_UNION_PRODUCT_DISTRIBUTION_POLICY, + ROUTE_UNION_PRODUCT_TRANSACTIONS, + ROUTE_UNION_SELL_REPORT, + ], + Page: RequestsPage, + exact: false, + props: {}, + }, +]; diff --git a/src/routes/vetFarmRouting.js b/src/routes/vetFarmRouting.js new file mode 100644 index 0000000..f9734b4 --- /dev/null +++ b/src/routes/vetFarmRouting.js @@ -0,0 +1,56 @@ +import { lazy } from "react"; +import { lazyRetry } from "../utils/lazyRetry"; +import { + ROUTE_VETFARM_HATCHING, + ROUTE_VETFARM_INSPECTIONS_ROUTE, + ROUTE_VETFARM_REGISTER_INFO, + ROUTE_VETFARM_ROUTE_ALLOCATIONS, + ROUTE_VETFARM_ROUTE_HATCHING, +} from "./routes"; + +const VetFarm = lazy(() => lazyRetry(() => import("../pages/VetFarm"))); +const VetFarmAllocations = lazy(() => + lazyRetry(() => import("../pages/VetFarmAllocations")) +); +const VetFarmInspections = lazy(() => + lazyRetry(() => import("../pages/VetFarmInspections")) +); +const Hatching = lazy(() => + lazyRetry(() => import("../pages/OperatorNewHatching")) +); +const ChickenHatching = lazy(() => + lazyRetry(() => import("../pages/Hatching")) +); + +export const vetFarmRouting = [ + { + path: [ROUTE_VETFARM_HATCHING], + Page: ChickenHatching, + exact: false, + props: {}, + }, + { + path: [ROUTE_VETFARM_REGISTER_INFO], + Page: VetFarm, + exact: false, + props: {}, + }, + { + path: [ROUTE_VETFARM_INSPECTIONS_ROUTE], + Page: VetFarmInspections, + exact: false, + props: {}, + }, + { + path: [ROUTE_VETFARM_ROUTE_HATCHING], + Page: Hatching, + exact: false, + props: {}, + }, + { + path: [ROUTE_VETFARM_ROUTE_ALLOCATIONS], + Page: VetFarmAllocations, + exact: false, + props: {}, + }, +]; diff --git a/src/routes/vetSupervisorRouting.js b/src/routes/vetSupervisorRouting.js new file mode 100644 index 0000000..d572496 --- /dev/null +++ b/src/routes/vetSupervisorRouting.js @@ -0,0 +1,107 @@ +import { lazy } from "react"; +import { lazyRetry } from "../utils/lazyRetry"; +import { + ROUTE_VETـSUPERVISOR_ALLOCATIONS, + ROUTE_VETـSUPERVISOR_HATCHING, + ROUTE_VETـSUPERVISOR_ILLEGALـKILLING, + ROUTE_VETـSUPERVISOR_KILLS_STATS, + ROUTE_VETـSUPERVISOR_REPORTING, + ROUTE_VETـSUPERVISOR_ROUTE_FILES_STATE, + ROUTE_VETـSUPERVISOR_STATICS, + ROUTE_VETـSUPERVISOR_STATICS_CHARTS, + ROUTE_VETـSUPERVISOR_STATICS_PREDICTION, + ROUTE_VETـSUPERVISOR_STATICS_PREDICTION_VIEW, + ROUTEـVET_SUPERVISOR_POULTRIES, + ROUTEـVET_SUPERVISOR_POULTRIES_DETAILS, +} from "./routes"; + +const Statics = lazy(() => lazyRetry(() => import("../pages/AdminStatics"))); + +// const Reporting = lazy(() => +// lazyRetry(() => import("../pages/InspectorReporting")) +// ); + +const Reports = lazy(() => lazyRetry(() => import("../pages/ProvinceReports"))); + +const VetFarmAllocations = lazy(() => + lazyRetry(() => import("../pages/VetFarmAllocations")) +); + +const JahadKillStats = lazy(() => + lazyRetry(() => import("../pages/JahadKillStats")) +); + +const Poultries = lazy(() => lazyRetry(() => import("../pages/Poultries"))); + +const JahadIllegalKilling = lazy(() => + lazyRetry(() => import("../pages/JahadIllegalKilling")) +); +const FilesState = lazy(() => lazyRetry(() => import("../pages/FilesState"))); + +const Hatching = lazy(() => lazyRetry(() => import("../pages/Hatching"))); + +const PoultriesDetails = lazy(() => + lazyRetry(() => import("../pages/PoultriesDetailsPage")) +); + +export const vetSupervisorRouting = [ + { + path: [ROUTE_VETـSUPERVISOR_HATCHING], + Page: Hatching, + exact: false, + props: {}, + }, + { + path: [ROUTEـVET_SUPERVISOR_POULTRIES], + Page: Poultries, + exact: false, + props: {}, + }, + { + path: [ROUTE_VETـSUPERVISOR_ALLOCATIONS], + Page: VetFarmAllocations, + exact: false, + props: {}, + }, + { + path: [ROUTE_VETـSUPERVISOR_ILLEGALـKILLING], + Page: JahadIllegalKilling, + exact: false, + props: {}, + }, + { + path: [ROUTE_VETـSUPERVISOR_KILLS_STATS], + Page: JahadKillStats, + exact: false, + props: {}, + }, + { + path: [ + ROUTE_VETـSUPERVISOR_STATICS, + ROUTE_VETـSUPERVISOR_STATICS_PREDICTION, + ROUTE_VETـSUPERVISOR_STATICS_PREDICTION_VIEW, + ROUTE_VETـSUPERVISOR_STATICS_CHARTS, + ], + Page: Statics, + exact: false, + props: {}, + }, + { + path: [ROUTE_VETـSUPERVISOR_ROUTE_FILES_STATE], + Page: FilesState, + exact: false, + props: {}, + }, + { + path: [ROUTE_VETـSUPERVISOR_REPORTING], + Page: Reports, + exact: false, + props: {}, + }, + { + path: [ROUTEـVET_SUPERVISOR_POULTRIES_DETAILS], + Page: PoultriesDetails, + exact: false, + props: {}, + }, +]; diff --git a/src/service-worker.js b/src/service-worker.js new file mode 100644 index 0000000..a0d2c5e --- /dev/null +++ b/src/service-worker.js @@ -0,0 +1,73 @@ +/* eslint-disable no-restricted-globals */ + +// This service worker can be customized! +// See https://developers.google.com/web/tools/workbox/modules +// for the list of available Workbox modules, or add any other +// code you'd like. +// You can also remove this file if you'd prefer not to use a +// service worker, and the Workbox build step will be skipped. + +import { clientsClaim } from "workbox-core"; +import { ExpirationPlugin } from "workbox-expiration"; +import { precacheAndRoute, createHandlerBoundToURL } from "workbox-precaching"; +import { registerRoute } from "workbox-routing"; +import { StaleWhileRevalidate } from "workbox-strategies"; + +clientsClaim(); + +// Precache all of the assets generated by your build process. +// Their URLs are injected into the manifest variable below. +// This variable must be present somewhere in your service worker file, +// even if you decide not to use precaching. See https://cra.link/PWA +precacheAndRoute(self.__WB_MANIFEST); + +// Set up App Shell-style routing, so that all navigation requests +// are fulfilled with your index.html shell. Learn more at +// https://developers.google.com/web/fundamentals/architecture/app-shell +const fileExtensionRegexp = new RegExp("/[^/?]+\\.[^/]+$"); +registerRoute( + // Return false to exempt requests from being fulfilled by index.html. + ({ request, url }) => { + // If this isn't a navigation, skip. + if (request.mode !== "navigate") { + return false; + } // If this is a URL that starts with /_, skip. + + if (url.pathname.startsWith("/_")) { + return false; + } // If this looks like a URL for a resource, because it contains // a file extension, skip. + + if (url.pathname.match(fileExtensionRegexp)) { + return false; + } // Return true to signal that we want to use the handler. + + return true; + }, + createHandlerBoundToURL(process.env.PUBLIC_URL + "/index.html") +); + +// An example runtime caching route for requests that aren't handled by the +// precache, in this case same-origin .png requests like those from in public/ +registerRoute( + // Add in any other file extensions or routing criteria as needed. + ({ url }) => + url.origin === self.location.origin && url.pathname.endsWith(".png"), // Customize this strategy as needed, e.g., by changing to CacheFirst. + new StaleWhileRevalidate({ + cacheName: "images", + plugins: [ + // Ensure that once this runtime cache reaches a maximum size the + // least-recently used images are removed. + new ExpirationPlugin({ maxEntries: 50 }), + ], + }) +); + +// This allows the web app to trigger skipWaiting via +// registration.waiting.postMessage({type: 'SKIP_WAITING'}) +self.addEventListener("message", (event) => { + if (event.data && event.data.type === "SKIP_WAITING") { + self.skipWaiting(); + } +}); + +// Any other custom service worker logic can go here. diff --git a/src/serviceWorkerRegistration.js b/src/serviceWorkerRegistration.js new file mode 100644 index 0000000..fd0e8c5 --- /dev/null +++ b/src/serviceWorkerRegistration.js @@ -0,0 +1,141 @@ +// This optional code is used to register a service worker. +// register() is not called by default. + +// This lets the app load faster on subsequent visits in production, and gives +// it offline capabilities. However, it also means that developers (and users) +// will only see deployed updates on subsequent visits to a page, after all the +// existing tabs open on the page have been closed, since previously cached +// resources are updated in the background. + +// To learn more about the benefits of this model and instructions on how to +// opt-in, read https://cra.link/PWA + +const isLocalhost = Boolean( + window.location.hostname === "localhost" || + // [::1] is the IPv6 localhost address. + window.location.hostname === "[::1]" || + // 127.0.0.0/8 are considered localhost for IPv4. + window.location.hostname.match( + /^127(?:\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}$/ + ) +); + +export function register(config) { + if (process.env.NODE_ENV === "production" && "serviceWorker" in navigator) { + // The URL constructor is available in all browsers that support SW. + const publicUrl = new URL(process.env.PUBLIC_URL, window.location.href); + if (publicUrl.origin !== window.location.origin) { + // Our service worker won't work if PUBLIC_URL is on a different origin + // from what our page is served on. This might happen if a CDN is used to + // serve assets; see https://github.com/facebook/create-react-app/issues/2374 + return; + } + + window.addEventListener("load", () => { + const swUrl = `${process.env.PUBLIC_URL}/service-worker.js`; + + if (isLocalhost) { + // This is running on localhost. Let's check if a service worker still exists or not. + checkValidServiceWorker(swUrl, config); + + // Add some additional logging to localhost, pointing developers to the + // service worker/PWA documentation. + navigator.serviceWorker.ready.then(() => { + console.log( + "This web app is being served cache-first by a service " + + "worker. To learn more, visit https://cra.link/PWA" + ); + }); + } else { + // Is not localhost. Just register service worker + registerValidSW(swUrl, config); + } + }); + } +} + +function registerValidSW(swUrl, config) { + navigator.serviceWorker + .register(swUrl) + .then((registration) => { + registration.onupdatefound = () => { + const installingWorker = registration.installing; + if (installingWorker == null) { + return; + } + installingWorker.onstatechange = () => { + if (installingWorker.state === "installed") { + if (navigator.serviceWorker.controller) { + // At this point, the updated precached content has been fetched, + // but the previous service worker will still serve the older + // content until all client tabs are closed. + console.log( + "New content is available and will be used when all " + + "tabs for this page are closed. See https://cra.link/PWA." + ); + + // Execute callback + if (config && config.onUpdate) { + config.onUpdate(registration); + } + } else { + // At this point, everything has been precached. + // It's the perfect time to display a + // "Content is cached for offline use." message. + console.log("Content is cached for offline use."); + + // Execute callback + if (config && config.onSuccess) { + config.onSuccess(registration); + } + } + } + }; + }; + }) + .catch((error) => { + console.error("Error during service worker registration:", error); + }); +} + +function checkValidServiceWorker(swUrl, config) { + // Check if the service worker can be found. If it can't reload the page. + fetch(swUrl, { + headers: { "Service-Worker": "script" }, + }) + .then((response) => { + // Ensure service worker exists, and that we really are getting a JS file. + const contentType = response.headers.get("content-type"); + if ( + response.status === 404 || + (contentType != null && contentType.indexOf("javascript") === -1) + ) { + // No service worker found. Probably a different app. Reload the page. + navigator.serviceWorker.ready.then((registration) => { + registration.unregister().then(() => { + window.location.reload(); + }); + }); + } else { + // Service worker found. Proceed as normal. + registerValidSW(swUrl, config); + } + }) + .catch(() => { + console.log( + "No internet connection found. App is running in offline mode." + ); + }); +} + +export function unregister() { + if ("serviceWorker" in navigator) { + navigator.serviceWorker.ready + .then((registration) => { + registration.unregister(); + }) + .catch((error) => { + console.error(error.message); + }); + } +} diff --git a/src/setupTests.js b/src/setupTests.js new file mode 100644 index 0000000..1dd407a --- /dev/null +++ b/src/setupTests.js @@ -0,0 +1,5 @@ +// jest-dom adds custom jest matchers for asserting on DOM nodes. +// allows you to do things like: +// expect(element).toHaveTextContent(/react/i) +// learn more: https://github.com/testing-library/jest-dom +import "@testing-library/jest-dom"; diff --git a/src/utils/address.js b/src/utils/address.js new file mode 100644 index 0000000..6e8ab12 --- /dev/null +++ b/src/utils/address.js @@ -0,0 +1,29 @@ +export const extractProvinceFromAddress = (address, provinceData) => { + if ( + !address || + typeof address !== "string" || + !provinceData || + provinceData.length === 0 + ) { + return ""; + } + + const normalized = address + .replace(/\u200c/g, " ") + .replace(/\s+/g, " ") + .trim(); + + const words = normalized.split(/\s+/).slice(0, 2); + const firstTwoWords = words.join(" "); + + const matchedProvince = provinceData.find((province) => { + const provinceName = province.name || ""; + return ( + provinceName.includes(firstTwoWords) || + firstTwoWords.includes(provinceName) || + normalized.includes(provinceName) + ); + }); + + return matchedProvince ? matchedProvince.name : ""; +}; diff --git a/src/utils/checkPathStartsWith.js b/src/utils/checkPathStartsWith.js new file mode 100644 index 0000000..009e815 --- /dev/null +++ b/src/utils/checkPathStartsWith.js @@ -0,0 +1,7 @@ +export const checkPathStartsWith = (str) => { + const path = window.location.pathname; + if (path.startsWith("/" + str)) { + return true; + } + return false; +}; diff --git a/src/utils/dashboardCustomization.js b/src/utils/dashboardCustomization.js new file mode 100644 index 0000000..090d141 --- /dev/null +++ b/src/utils/dashboardCustomization.js @@ -0,0 +1,84 @@ +const STORAGE_KEY = "dashboard_custom_order"; + +export const getCustomOrders = () => { + try { + const orders = localStorage.getItem(STORAGE_KEY); + return orders ? JSON.parse(orders) : {}; + } catch (error) { + console.error("Error reading custom orders:", error); + return {}; + } +}; + +const saveCustomOrders = (orders) => { + try { + localStorage.setItem(STORAGE_KEY, JSON.stringify(orders)); + } catch (error) { + console.error("Error saving custom orders:", error); + } +}; + +export const getRoleCustomOrder = (role) => { + const orders = getCustomOrders(); + return orders[role] || null; +}; + +export const saveRoleCustomOrder = (role, items) => { + const orders = getCustomOrders(); + + const routeOrder = items.map((item) => item.route); + + orders[role] = routeOrder; + saveCustomOrders(orders); +}; + +export const applyCustomOrder = (items, role) => { + if (!items || !Array.isArray(items)) return items; + + const customOrder = getRoleCustomOrder(role); + + if (!customOrder || customOrder.length === 0) return items; + + const orderedItems = []; + const remainingItems = [...items]; + + for (const route of customOrder) { + const index = remainingItems.findIndex((item) => item.route === route); + if (index !== -1) { + orderedItems.push(remainingItems[index]); + remainingItems.splice(index, 1); + } + } + + orderedItems.push(...remainingItems); + + return orderedItems; +}; + +export const clearRoleCustomOrder = (role) => { + const orders = getCustomOrders(); + if (orders[role]) { + delete orders[role]; + saveCustomOrders(orders); + } +}; + +export const clearAllCustomOrders = () => { + try { + localStorage.removeItem(STORAGE_KEY); + } catch (error) { + console.error("Error clearing custom orders:", error); + } +}; + +export const hasCustomOrder = (role) => { + const customOrder = getRoleCustomOrder(role); + return customOrder !== null && customOrder.length > 0; +}; + +export const reorderArray = (list, startIndex, endIndex) => { + const result = Array.from(list); + const [removed] = result.splice(startIndex, 1); + result.splice(endIndex, 0, removed); + return result; +}; diff --git a/src/utils/formatTime.js b/src/utils/formatTime.js new file mode 100644 index 0000000..3d0fdf6 --- /dev/null +++ b/src/utils/formatTime.js @@ -0,0 +1,135 @@ +import { format } from "date-fns-jalali"; +import { enUS } from "date-fns/locale"; +import PersianDate from "persian-date"; + +const persianLocale = { + ...enUS, + localize: { + ...enUS.localize, + month: (n) => + [ + "فروردین", + "اردیبهشت", + "خرداد", + "تیر", + "مرداد", + "شهریور", + "مهر", + "آبان", + "آذر", + "دی", + "بهمن", + "اسفند", + ][n], + }, + formatLong: { + ...enUS.formatLong, + date: () => "d MMMM yyyy", + }, +}; + +export const formatTime = (time) => { + const date = new Date(time); + const hours = date.getHours().toString().padStart(2, "0"); + const minutes = date.getMinutes().toString().padStart(2, "0"); + + return format(new Date(time), "yyyy/MM/dd ") + `(${hours}:${minutes})`; +}; + +export const formatTimeFull = (time) => { + const date = new Date(time); + const hours = date.getHours().toString().padStart(2, "0"); + const minutes = date.getMinutes().toString().padStart(2, "0"); + const seconds = date.getSeconds().toString().padStart(2, "0"); + + return ( + format(new Date(time), "yyyy/MM/dd ") + `(${hours}:${minutes}:${seconds})` + ); +}; + +export const formatJustDate = (time) => { + if (time) { + return format(new Date(time), "yyyy/MM/dd"); + } else { + return null; + } +}; + +export const formatJustTime = (time) => { + return format(new Date(time), "HH:MM"); +}; + +export const formatJustDateGregorian = (time) => { + const timePortion = time.getTime() % (3600 * 1000 * 24); + return new Date(time - timePortion); +}; + +export function formatTimeStampDate(timestamp) { + const date = new Date(timestamp); + const year = date.getFullYear(); + const month = String(date.getMonth() + 1).padStart(2, "0"); + const day = String(date.getDate()).padStart(2, "0"); + return `${year}/${month}/${day}`; +} + +export function convertToIranianTime(dateString) { + const gregorianDate = new Date(dateString); + const iranianDate = new PersianDate(gregorianDate); + const iranianDateString = iranianDate.format("YYYY/MM/DD"); + + const asciiIranianDateString = iranianDateString.replace( + /[۰-۹]/g, + function (digit) { + return String.fromCharCode(digit.charCodeAt(0) - 1728); + } + ); + + return asciiIranianDateString; +} + +export function getPersianMonth(dateString) { + const date = new Date(dateString); + const persianMonth = format(date, "MMMM", { locale: persianLocale }); + return persianMonth + " " + format(new Date(date), "yyyy"); +} + +export function convertDaysToYMD(days) { + const daysInYear = 365; + const daysInMonth = 30; + + const years = Math.floor(days / daysInYear); + days = days % daysInYear; + + const months = Math.floor(days / daysInMonth); + days = days % daysInMonth; + + const remainingDays = days; + + const result = []; + if (years > 0) result.push(`${years} سال`); + if (months > 0) result.push(`${months} ماه`); + if (remainingDays > 0) result.push(`${remainingDays} روز`); + + return result.join(" و "); +} + +export function convertPersianToEnglishNumerals(text) { + if (!text || typeof text !== "string") { + return text; + } + + const persianToEnglish = { + "۰": "0", + "۱": "1", + "۲": "2", + "۳": "3", + "۴": "4", + "۵": "5", + "۶": "6", + "۷": "7", + "۸": "8", + "۹": "9", + }; + + return text.replace(/[۰-۹]/g, (char) => persianToEnglish[char] || char); +} diff --git a/src/utils/getAllocationType.js b/src/utils/getAllocationType.js new file mode 100644 index 0000000..821619a --- /dev/null +++ b/src/utils/getAllocationType.js @@ -0,0 +1,15 @@ +export const getAllocationType = (item) => { + if (!item?.allocationType) return "-"; + + const types = { + killhouse_steward: "کشتارگاه به مباشر", + killhouse_guild: "کشتارگاه به صنف", + killhouse_coldhouse: "کشتارگاه به سردخانه", + steward_steward: "مباشر به مباشر", + steward_guild: "مباشر به صنف", + ColdHouse: "کشتارگاه به سردخانه", + guild_killhouse: "صنف به کشتارگاه", + }; + + return types[item.allocationType] || "-"; +}; diff --git a/src/utils/getBarSquareItems.js b/src/utils/getBarSquareItems.js new file mode 100644 index 0000000..e3267af --- /dev/null +++ b/src/utils/getBarSquareItems.js @@ -0,0 +1,40 @@ +import React from "react"; +import * as ROUTES from "../routes/routes"; +import CorporateFareIcon from "@mui/icons-material/CorporateFare"; +import ApartmentIcon from "@mui/icons-material/Apartment"; +import PeopleIcon from "@mui/icons-material/People"; +import CompareArrowsIcon from "@mui/icons-material/CompareArrows"; + +export const getBarSquareItems = (role) => { + switch (role) { + case "BarSquareProvinceJahad": + return [ + { + text: "دسترسی ها", + icon: , + route: ROUTES.ROUTE_PROVINCE_JAHAD_UNIONS, + disabled: true, + }, + { + text: "بنک دارها", + icon: , + route: ROUTES.ROUTE_PROVINCE_JAHAD_COOPERATIVES, + disabled: true, + }, + { + text: "تراکنش ها", + icon: , + route: ROUTES.ROUTE_BAR_SQUARE_TRANSACTIONS, + }, + { + text: "صنوف", + icon: , + route: ROUTES.ROUTE_PROVINCE_JAHAD_USERS, + disabled: true, + }, + ]; + + default: + return []; + } +}; diff --git a/src/utils/getCeoAddress.js b/src/utils/getCeoAddress.js new file mode 100644 index 0000000..4981444 --- /dev/null +++ b/src/utils/getCeoAddress.js @@ -0,0 +1,26 @@ +import { useSelector } from "react-redux"; + +export const useCeoAddress = () => { + const userPath = useSelector((state) => state.userSlice.userPath); + + if ( + userPath === "https://check.rasadyaar.ir" || + userPath.includes("localhost") + ) { + return "خرم آباد، مطهری، شرکت آرتامهر آرتان"; + } else if (userPath === "https://mabackend.rasadyar.com/") { + return "مرودشت، رو به روی شبکه دامپزشکی شهرستان اراک، اتحادیه مرغداران استان مرکزی"; + } else if (userPath === "https://arbackend.rasadyar.com/") { + return "آدرس : اردبیل، شهرک کارشناسان ،جنب ساختمان نظام مهندسی، ساختمان فرهنگ، طبقه دوم تلفن : 33749254 تلفاکس : 33749253 "; + } else if (userPath === "https://habackend.rasadyar.com/") { + return "همدان، بلوار آیت اله مدنی، کوچه امامزاده یحیی یک تلفن: 081 32523689 "; + } else if (userPath === "https://shabackend.rasadyar.com/") { + return "تبریز خیابان راه آهن نبش کوی اشکان ساختمان ۱۴ طبقه دوم تلفن: 041 34502363"; + } else if (userPath === "https://ghabackend.rasadyar.com/") { + return "آدرس استان آذربایجان غربی"; + } else if (userPath === "https://bubackend.rasadyar.com/") { + return "بوشهر، خيابان امام خمينی، جنب مديريت برق، ساختمان رضايي، طبقه 3"; + } else { + return "آدرس تست"; + } +}; diff --git a/src/utils/getCeoName.js b/src/utils/getCeoName.js new file mode 100644 index 0000000..0d71d2d --- /dev/null +++ b/src/utils/getCeoName.js @@ -0,0 +1,26 @@ +import { useSelector } from "react-redux"; + +export const useCeoName = () => { + const userPath = useSelector((state) => state.userSlice.userPath); + + if ( + userPath === "https://check.rasadyaar.ir" || + userPath.includes("localhost") + ) { + return "محمد میرانی"; + } else if (userPath === "https://mabackend.rasadyar.com/") { + return "علی حیدری"; + } else if (userPath === "https://arbackend.rasadyar.com/") { + return "علیرضا سقایی"; + } else if (userPath === "https://habackend.rasadyar.com/") { + return "داوود شعبانلو"; + } else if (userPath === "https://shabackend.rasadyar.com/") { + return "جواد سلطانی مجد"; + } else if (userPath === "https://ghabackend.rasadyar.com/") { + return "آقای/خانم"; + } else if (userPath === "https://bubackend.rasadyar.com/") { + return "حسین تمجیدی پور"; + } else { + return "محمد میرانی"; + } +}; diff --git a/src/utils/getDayOfWeek.js b/src/utils/getDayOfWeek.js new file mode 100644 index 0000000..60480e0 --- /dev/null +++ b/src/utils/getDayOfWeek.js @@ -0,0 +1,22 @@ +export const getDayOfWeek = (inputdate) => { + let x = new Date(inputdate); + let dayofweek = x.getDay(); + switch (dayofweek) { + case 1: + return "دوشنبه"; + case 2: + return "سه شنبه"; + case 3: + return "چهارشنبه"; + case 4: + return "پنج شنبه"; + case 5: + return "جمعه"; + case 6: + return "شنبه"; + case 7: + return "یکشنبه"; + default: + return "نامشخص"; + } +}; diff --git a/src/utils/getEnRoleFromFa.js b/src/utils/getEnRoleFromFa.js new file mode 100644 index 0000000..525e98a --- /dev/null +++ b/src/utils/getEnRoleFromFa.js @@ -0,0 +1,35 @@ +export function getEnRoleFromFa(name) { + let itemVal; + switch (name) { + case "شهرستان": + itemVal = "CityOperator"; + break; + case "مرغدار": + itemVal = "Poultry"; + break; + case "دامپزشک": + itemVal = "VetFarm"; + break; + case "راننده": + itemVal = "Driver"; + break; + case "کشتارگاه": + itemVal = "KillHouse"; + break; + case "پشتیبانی امور دام": + itemVal = "LiveStockSupport"; + break; + case "مالی": + itemVal = "ProvinceFinancial"; + break; + case "ادمین کل": + itemVal = "SuperAdmin"; + break; + case "پخش کننده": + itemVal = "Dispenser"; + break; + default: + break; + } + return itemVal; +} diff --git a/src/utils/getFaUserRole.js b/src/utils/getFaUserRole.js new file mode 100644 index 0000000..3da9150 --- /dev/null +++ b/src/utils/getFaUserRole.js @@ -0,0 +1,88 @@ +export function getFaUserRole(role) { + switch (role) { + case "Admin": + return "ادمین استان"; + case "CityOperator": + return "تعاونی"; + case "Poultry": + return "مرغدار"; + case "ProvinceOperator": + return "مدیر اجرایی"; + case "ProvinceFinancial": + return "مالی اتحادیه"; + case "KillHouse": + return "کشتارگاه"; + case "KillHouseVet": + return "دامپزشک کشتارگاه"; + case "VetFarm": + return "دامپزشک فارم"; + case "Driver": + return "راننده"; + case "ProvinceInspector": + return "بازرس اتحادیه "; + case "VetSupervisor": + return "دامپزشک کل"; + case "Jahad": + return "جهاد کشاورزی استان"; + case "CityJahad": + return "جهاد کشاورزی شهرستان"; + case "ProvincialGovernment": + return "استانداری"; + case "Guilds": + return "صنف"; + case "Steward": + return "مباشر"; + case "Commerce": + return "معاونت بازرگانی استان"; + case "CityCommerce": + return "بازرگانی شهرستان"; + case "UnitWindow": + return "پنجره واحد"; + case "CityVet": + return "دامپزشک شهرستان"; + case "Observatory": + return "رصدخانه"; + case "ProvinceSupervisor": + return "ناظر استان"; + case "GuildRoom": + return "اتاق اصناف"; + case "PosCompany": + return "شرکت psp"; + case "LiveStockSupport": + return "پشتیبانی امور دام"; + case "SuperAdmin": + return "ادمین کل"; + case "ChainCompany": + return "شرکت زنجیره"; + case "AdminX": + return "ادمین ایکس"; + case "Supporter": + return "پشتیبان سامانه"; + case "Dispenser": + return "پخش کننده"; + case "CityPoultry": + return "طیور شهرستان"; + case "ParentCompany": + return "شرکت مادر"; + case "ColdHouseSteward": + return "مباشر سردخانه"; + case "CityGuild": + return "اتحادیه پروتئینی"; + case "LiveStockProvinceJahad": + return "جهاد استان"; + case "Union": + return "اتحادیه دامداران"; + case "Cooperative": + return "تعاونی دامداران"; + case "Rancher": + return "دامدار"; + case "BarSquareProvinceJahad": + return "جهاد میدان بار"; + case "PoultryScience": + return "کارشناس علوم دامی"; + case "ProteinGuild": + return "گویهای پروتئین"; + default: + return ""; + } +} diff --git a/src/utils/getListOfProvinces.js b/src/utils/getListOfProvinces.js new file mode 100644 index 0000000..e8b117e --- /dev/null +++ b/src/utils/getListOfProvinces.js @@ -0,0 +1,24 @@ +export const getListOfProvinces = () => { + return [ + { + name: "همدان", + link: "https://habackend.rasadyar.com/", + }, + { + name: "مرکزی", + link: "https://mabackend.rasadyar.com/", + }, + { + name: "بوشهر", + link: "https://bubackend.rasadyar.com/", + }, + // { + // name: "آذربایجان شرقی", + // link: "https://shabackend.rasadyar.com/", + // }, + // { + // name: "اردبیل", + // link: "https://arbackend.rasadyar.com/", + // }, + ]; +}; diff --git a/src/utils/getLivestock.js b/src/utils/getLivestock.js new file mode 100644 index 0000000..9aef037 --- /dev/null +++ b/src/utils/getLivestock.js @@ -0,0 +1,121 @@ +import React from "react"; +import * as ROUTES from "../routes/routes"; +import CorporateFareIcon from "@mui/icons-material/CorporateFare"; +import ApartmentIcon from "@mui/icons-material/Apartment"; +import ListAltIcon from "@mui/icons-material/ListAlt"; +import PeopleIcon from "@mui/icons-material/People"; +import Face5Icon from "@mui/icons-material/Face5"; +import BlurOnIcon from "@mui/icons-material/BlurOn"; +import CompareArrowsIcon from "@mui/icons-material/CompareArrows"; + +export const getLiveStockItems = (role) => { + switch (role) { + case "LiveStockProvinceJahad": + return [ + { + text: "اتحادیه ها", + icon: , + route: ROUTES.ROUTE_PROVINCE_JAHAD_UNIONS, + }, + { + text: "تعاونی ها", + icon: , + route: ROUTES.ROUTE_PROVINCE_JAHAD_COOPERATIVES, + }, + { + text: "دامداران", + icon: , + route: ROUTES.ROUTE_PROVINCE_JAHAD_RANCHERS, + }, + { + text: "گله ها", + icon: , + route: ROUTES.ROUTE_PROVINCE_JAHAD_HERDS, + }, + { + text: "محصولات", + icon: , + route: ROUTES.ROUTE_PROVINCE_JAHAD_PRODUCT_DISTRIBUTION, + }, + { + text: "تراکنش ها", + icon: , + route: ROUTES.ROUTE_PROVINCE_JAHAD_PRODUCT_TRANSACTIONS, + }, + { + text: "کاربران", + icon: , + route: ROUTES.ROUTE_PROVINCE_JAHAD_USERS, + }, + ]; + case "Union": + return [ + { + text: "تعاونی ها", + icon: , + route: ROUTES.ROUTE_UNION_COOPERATIVES, + }, + { + text: "دامداران", + icon: , + route: ROUTES.ROUTE_UNION_RANCHERS, + }, + { + text: "گله ها", + icon: , + route: ROUTES.ROUTE_UNION_HERDS, + }, + { + text: "محصولات", + icon: , + route: ROUTES.ROUTE_UNION_PRODUCT_DISTRIBUTION, + }, + { + text: "تراکنش ها", + icon: , + route: ROUTES.ROUTE_UNION_PRODUCT_TRANSACTIONS, + }, + { + text: "کاربران", + icon: , + route: ROUTES.ROUTE_UNION_USERS, + disabled: true, + }, + ]; + case "Cooperative": + return [ + { + text: "دامداران", + icon: , + route: ROUTES.ROUTE_COOPERATIVE_RANCHERS, + disabled: true, + disabledText: "شما مجوز دسترسی به این بخش را ندارید!", + }, + { + text: "گله ها", + icon: , + route: ROUTES.ROUTE_COOPERATIVE_HERDS, + disabled: true, + disabledText: "شما مجوز دسترسی به این بخش را ندارید!", + }, + { + text: "محصولات", + icon: , + route: ROUTES.ROUTE_COOPERATIVE_PRODUCT_DISTRIBUTION, + }, + { + text: "تراکنش ها", + icon: , + route: ROUTES.ROUTE_COOPERATIVE_PRODUCT_TRANSACTIONS, + }, + { + text: "کاربران", + icon: , + route: ROUTES.ROUTE_COOPERATIVE_USERS, + disabled: true, + }, + ]; + default: + return []; + } +}; diff --git a/src/utils/getPosProviderName.js b/src/utils/getPosProviderName.js new file mode 100644 index 0000000..352bac5 --- /dev/null +++ b/src/utils/getPosProviderName.js @@ -0,0 +1,18 @@ +export const getPosProviderName = (provider) => { + switch (provider) { + case "SEP": + return "سامان کیش"; + case "asanpardakht": + return "آسان پرداخت"; + case "irkish": + return "ایران کیش"; + case "sepehr": + return "سپهر"; + case "mellat": + return "ملت"; + case "pec": + return "پارسیان"; + default: + return "نامشخص"; + } +}; diff --git a/src/utils/getProductItems.js b/src/utils/getProductItems.js new file mode 100644 index 0000000..5630731 --- /dev/null +++ b/src/utils/getProductItems.js @@ -0,0 +1,57 @@ +import React from "react"; +import RiceBowlIcon from "@mui/icons-material/RiceBowl"; +import AcUnitIcon from "@mui/icons-material/AcUnit"; +import LocalDiningIcon from "@mui/icons-material/LocalDining"; +import IcecreamIcon from "@mui/icons-material/Icecream"; +import FastfoodIcon from "@mui/icons-material/Fastfood"; +import KitchenIcon from "@mui/icons-material/Kitchen"; +import SetMealIcon from "@mui/icons-material/SetMeal"; +import RestaurantIcon from "@mui/icons-material/Restaurant"; +import LocalGroceryStoreIcon from "@mui/icons-material/LocalGroceryStore"; + +const getEssentialGoodsMenuItems = () => { + return [ + { + text: "برنج", + icon: , + }, + { + text: "شکر", + icon: , + }, + { + text: "قند", + icon: , + }, + { + text: "گوشت قرمز (منجمد)", + icon: , + }, + { + text: "گوشت قرمز (گرم)", + icon: , + }, + { + text: "روغن خوراکی", + icon: , + }, + { + text: "حبوبات", + icon: , + }, + { + text: "مرغ (منجمد)", + icon: , + }, + { + text: "مرغ (گرم)", + icon: , + }, + { + text: "ماهی", + icon: , + }, + ]; +}; + +export default getEssentialGoodsMenuItems; diff --git a/src/utils/getProvinceName.js b/src/utils/getProvinceName.js new file mode 100644 index 0000000..07ab1da --- /dev/null +++ b/src/utils/getProvinceName.js @@ -0,0 +1,22 @@ +import { useSelector } from "react-redux"; + +export const useProvinceName = () => { + const userPath = useSelector((state) => state.userSlice.userPath); + + let province; + if (userPath === "https://testbackend.rasadyar.com/") { + province = "test"; + } else if (userPath === "https://mabackend.rasadyar.com/") { + province = "markazi"; + } else if (userPath === "https://arbackend.rasadyar.com/") { + province = "ardabil"; + } else if (userPath === "https://habackend.rasadyar.com/") { + province = "hamedan"; + } else if (userPath === "https://bubackend.rasadyar.com/") { + province = "bushehr"; + } else { + province = "hamedan"; + } + + return province; +}; diff --git a/src/utils/getRemainedSeconds.js b/src/utils/getRemainedSeconds.js new file mode 100644 index 0000000..541d6fa --- /dev/null +++ b/src/utils/getRemainedSeconds.js @@ -0,0 +1,9 @@ +import moment from "moment"; +export const getRemainedSeconds = (item) => { + const finishDate = moment(new Date(item)); + const currentDate = moment(); + const diff = finishDate.diff(currentDate); + let remainedSeconds = moment.duration(diff).asSeconds(); + + return remainedSeconds; +}; diff --git a/src/utils/getRoleFromUrl.js b/src/utils/getRoleFromUrl.js new file mode 100644 index 0000000..bd70927 --- /dev/null +++ b/src/utils/getRoleFromUrl.js @@ -0,0 +1,98 @@ +export const getRoleFromUrl = () => { + switch (window.location.pathname.split("/")[1]) { + case "city": + return "CityOperator"; + case "aviculture": + return "Poultry"; + case "province": + return "ProvinceOperator"; + case "slaughter": + return "KillHouse"; + case "slaughter-house-vet": + return "KillHouseVet"; + case "vetfarm": + return "VetFarm"; + case "financial": + return "ProvinceFinancial"; + case "inspector": + return "ProvinceInspector"; + case "vet-supervisor": + return "VetSupervisor"; + case "commerce": + return "Commerce"; + case "city-commerce": + return "CityCommerce"; + case "city-vet": + return "CityVet"; + case "city-jahad": + return "CityJahad"; + case "observatory": + return "Observatory"; + case "province-supervisor": + return "ProvinceSupervisor"; + case "guild": + return "Guilds"; + case "senf": + return "Guilds"; + case "steward": + return "Steward"; + case "guild-room": + return "GuildRoom"; + case "livestock": + return "LiveStockSupport"; + case "superadmin": + return "SuperAdmin"; + case "chaincompany": + return "ChainCompany"; + case "adminx": + return "AdminX"; + case "supporter": + return "Supporter"; + case "dispenser": + return "Dispenser"; + case "citypoultry": + return "CityPoultry"; + case "driver": + return "Driver"; + case "parent-company": + return "ParentCompany"; + case "cold-house-steward": + return "ColdHouseSteward"; + case "city-guild": + return "CityGuild"; + case "province-jahad": + return "LiveStockProvinceJahad"; + case "union": + return "Union"; + case "cooperative": + return "Cooperative"; + case "rancher": + return "Rancher"; + case "psp-company": + return "PosCompany"; + case "poultry-science": + return "PoultryScience"; + default: + return null; + } +}; + +export const getActualRoleFromRole = (role) => { + switch (role) { + case "city": + return "CityOperator"; + case "aviculture": + return "Poultry"; + case "province": + return "ProvinceOperator"; + case "slaughter": + return "KillHouse"; + case "slaughter-house-vet": + case "vetfarm": + return "Vet"; + case "financial": + return "ProvinceFinancial"; + default: + return null; + } +}; diff --git a/src/utils/getRoleIcon.js b/src/utils/getRoleIcon.js new file mode 100644 index 0000000..5529bcc --- /dev/null +++ b/src/utils/getRoleIcon.js @@ -0,0 +1,114 @@ +import ReduceCapacityIcon from "@mui/icons-material/ReduceCapacity"; +import EggIcon from "@mui/icons-material/Egg"; +import FactoryIcon from "@mui/icons-material/Factory"; +import HdrStrongIcon from "@mui/icons-material/HdrStrong"; +import VaccinesIcon from "@mui/icons-material/Vaccines"; +import StoreIcon from "@mui/icons-material/Store"; +import RemoveRedEyeIcon from "@mui/icons-material/RemoveRedEye"; +import SupportIcon from "@mui/icons-material/Support"; +import WindowIcon from "@mui/icons-material/Window"; +import PaymentIcon from "@mui/icons-material/Payment"; +import AnimationIcon from "@mui/icons-material/Animation"; +import CoPresentIcon from "@mui/icons-material/CoPresent"; +import Diversity3Icon from "@mui/icons-material/Diversity3"; +import BrightnessLowIcon from "@mui/icons-material/BrightnessLow"; +import MedicalInformationIcon from "@mui/icons-material/MedicalInformation"; +import MonetizationOnIcon from "@mui/icons-material/MonetizationOn"; +import PolicyIcon from "@mui/icons-material/Policy"; +import LocalTaxiIcon from "@mui/icons-material/LocalTaxi"; +import AdminPanelSettingsIcon from "@mui/icons-material/AdminPanelSettings"; +import AgricultureIcon from "@mui/icons-material/Agriculture"; +import StorefrontIcon from "@mui/icons-material/Storefront"; +import CurrencyExchangeIcon from "@mui/icons-material/CurrencyExchange"; +import LocalAtmIcon from "@mui/icons-material/LocalAtm"; +import PreviewIcon from "@mui/icons-material/Preview"; +import DomainIcon from "@mui/icons-material/Domain"; +import AcUnitIcon from "@mui/icons-material/AcUnit"; +import FoodBankIcon from "@mui/icons-material/FoodBank"; +import { CorporateFare } from "@mui/icons-material"; +import HowToRegIcon from "@mui/icons-material/HowToReg"; + +export function getIconUserRole(role) { + switch (role) { + case "Admin": + return ; + case "CityOperator": + return ; + case "Poultry": + return ; + case "ProvinceOperator": + return ; + case "ProvinceFinancial": + return ; + case "KillHouse": + return ; + case "KillHouseVet": + return ; + case "VetFarm": + return ; + case "Driver": + return ; + case "ProvinceInspector": + return ; + case "VetSupervisor": + return ; + case "Jahad": + return ; + case "CityJahad": + return ; + case "ProvincialGovernment": + return ; + case "Guilds": + return ; + case "Steward": + return ; + case "Commerce": + return ; + case "CityCommerce": + return ; + case "UnitWindow": + return ; + case "CityVet": + return ; + case "Observatory": + return ; + case "ProvinceSupervisor": + return ; + case "GuildRoom": + return ; + case "PosCompany": + return ; + case "LiveStockSupport": + return ; + case "SuperAdmin": + return ; + case "AdminX": + return ; + case "ChainCompany": + return ; + case "Supporter": + return ; + case "Dispenser": + return ; + case "CityPoultry": + return ; + case "ParentCompany": + return ; + case "ColdHouseSteward": + return ; + case "CityGuild": + return ; + case "LiveStockProvinceJahad": + return ; + case "Union": + return ; + case "Cooperative": + return ; + case "ranRanchercher": + return ; + case "PoultryScience": + return ; + default: + return ; + } +} diff --git a/src/utils/getRoleList.js b/src/utils/getRoleList.js new file mode 100644 index 0000000..a1ce7c0 --- /dev/null +++ b/src/utils/getRoleList.js @@ -0,0 +1,42 @@ +import { getFaUserRole } from "./getFaUserRole"; + +export const getRoleList = () => { + const roles = [ + "CityOperator", + "Poultry", + "ProvinceOperator", + "KillHouse", + "KillHouseVet", + "VetFarm", + "ProvinceFinancial", + "ProvinceInspector", + "VetSupervisor", + "Commerce", + "CityCommerce", + "CityVet", + "CityJahad", + "Observatory", + "ProvinceSupervisor", + "Guilds", + "GuildRoom", + "LiveStockSupport", + "SuperAdmin", + "ChainCompany", + "AdminX", + "Supporter", + "Dispenser", + "CityPoultry", + "ParentCompany", + "ColdHouseSteward", + "CityGuild", + "LiveStockProvinceJahad", + "Union", + "Cooperative", + "Rancher", + ]; + + return roles.map((role) => ({ + role, + translation: getFaUserRole(role), + })); +}; diff --git a/src/utils/getRolesItems.js b/src/utils/getRolesItems.js new file mode 100644 index 0000000..13d2f30 --- /dev/null +++ b/src/utils/getRolesItems.js @@ -0,0 +1,1675 @@ +import * as ROUTES from "../routes/routes"; +import WarehouseIcon from "@mui/icons-material/Warehouse"; +import EggIcon from "@mui/icons-material/Egg"; +import LocalShippingIcon from "@mui/icons-material/LocalShipping"; +import AttachMoneyIcon from "@mui/icons-material/AttachMoney"; +import AssignmentIcon from "@mui/icons-material/Assignment"; +import AssignmentTurnedInIcon from "@mui/icons-material/AssignmentTurnedIn"; +import ArchiveIcon from "@mui/icons-material/Archive"; +import FolderOpenIcon from "@mui/icons-material/FolderOpen"; +import NewReleasesIcon from "@mui/icons-material/NewReleases"; +import TaskAltIcon from "@mui/icons-material/TaskAlt"; +import AttachFileIcon from "@mui/icons-material/AttachFile"; +import MeetingRoomIcon from "@mui/icons-material/MeetingRoom"; +import PendingActionsIcon from "@mui/icons-material/PendingActions"; +import PaidIcon from "@mui/icons-material/Paid"; +import FlightTakeoffIcon from "@mui/icons-material/FlightTakeoff"; +import AcUnitIcon from "@mui/icons-material/AcUnit"; +import { + AddBox, + AddCircleOutline, + AssignmentReturn, + AssignmentTurnedIn, + DirectionsCarFilled, + DriveEta, + Engineering, + Home, + Lan, + Payment, + PriceChange, + SettingsApplications, + ShoppingBasket, + Storefront, + TravelExplore, + UploadFile, +} from "@mui/icons-material"; +import { Folder } from "@mui/icons-material"; +import SettingsSuggestIcon from "@mui/icons-material/SettingsSuggest"; +import VaccinesIcon from "@mui/icons-material/Vaccines"; +import ErrorIcon from "@mui/icons-material/Error"; +import { FileCopy } from "@mui/icons-material"; +import { Archive } from "@mui/icons-material"; +import { Warning } from "@mui/icons-material"; +import KitchenIcon from "@mui/icons-material/Kitchen"; +import SpaceDashboardIcon from "@mui/icons-material/SpaceDashboard"; +import ManageAccountsIcon from "@mui/icons-material/ManageAccounts"; +import ReportProblemIcon from "@mui/icons-material/ReportProblem"; +import CampaignIcon from "@mui/icons-material/Campaign"; +import AccountBalanceWalletIcon from "@mui/icons-material/AccountBalanceWallet"; +import DeviceHubIcon from "@mui/icons-material/DeviceHub"; +import PublicIcon from "@mui/icons-material/Public"; +import MoneyIcon from "@mui/icons-material/Money"; +import FolderIcon from "@mui/icons-material/Folder"; +import InventoryIcon from "@mui/icons-material/Inventory"; +import AssignmentIndIcon from "@mui/icons-material/AssignmentInd"; +import AutorenewIcon from "@mui/icons-material/Autorenew"; +import MarkEmailReadIcon from "@mui/icons-material/MarkEmailRead"; +import LocationOnIcon from "@mui/icons-material/LocationOn"; +import QueryStatsIcon from "@mui/icons-material/QueryStats"; +import PriceCheckIcon from "@mui/icons-material/PriceCheck"; +import AssessmentIcon from "@mui/icons-material/Assessment"; +import ManageSearchIcon from "@mui/icons-material/ManageSearch"; +import StoreIcon from "@mui/icons-material/Store"; +import PeopleIcon from "@mui/icons-material/People"; +import FactCheckIcon from "@mui/icons-material/FactCheck"; +import ShoppingBagIcon from "@mui/icons-material/ShoppingBag"; +import CategoryIcon from "@mui/icons-material/Category"; +import MedicalServicesIcon from "@mui/icons-material/MedicalServices"; +import NotificationsIcon from "@mui/icons-material/Notifications"; +import TableChartIcon from "@mui/icons-material/TableChart"; +import { FaFax } from "react-icons/fa"; +import BadgeIcon from "@mui/icons-material/Badge"; + +export const getRoleItems = (role) => { + switch (role) { + case "AdminX": + return [ + { + text: "داشبورد", + route: ROUTES.ROUTE_ADMINX_DASHBOARD, + icon: , + }, + { + text: "درخواست های کشتار", + route: ROUTES.ROUTE_ADMINX_CITY_NEW_REQUESTS, + icon: , + }, + + { + text: "تخصیص", + route: ROUTES.ROUTE_ADMINX_ALLOCATION_REQUESTS, + icon: , + }, + { + text: "مدیریت کشتار", + route: ROUTES.ROUTE_ADMINX_HATCHING, + icon: , + }, + { + text: "مدیریت جوجه ریزی", + route: ROUTES.ROUTE_ADMINXـHATCHINGS, + icon: , + }, + { + text: "اختلاف کشتار", + route: ROUTES.ROUTE_ADMINX_DIFFRENCE_KILLER, + icon: , + }, + { + text: "اعلام نیاز خریداران", + route: ROUTES.ROUTE_ADMINX_STATEMENTـOFـNEED_REQUESTS, + icon: , + }, + { + text: "خرید مستقیم", + route: ROUTES.ROUT_ADMINX_FREE_BUY, + icon: , + }, + { + text: "پنل معاملات", + route: ROUTES.ROUTE_ADMINX_TRADING_PANEL, + icon: , + }, + { + text: "فروش به خارج استان", + route: ROUTES.ROUTE_ADMINX_FREE_SALES_REQUESTS, + icon: , + }, + { + text: "زنجیره ها", + route: ROUTES.ROUTE_ADMINX_CHAINS, + icon: , + }, + { + text: "تعرفه ها", + route: ROUTES.ROUTE_ADMINX_PAYING_FEES_REQUESTS, + icon: , + }, + { + text: "پایش کشوری", + route: ROUTES.ROUTE_ADMINX_ROUTE_NATIONAL_INFO, + icon: , + }, + { + text: "تعرفه زیربخش ها", + route: ROUTES.ROUTE_ADMINX_SUB_SECTORS_WAGE, + icon: , + }, + { + text: "تسویه حساب", + route: ROUTES.ROUTE_ADMINX_SETTLEMENTS, + icon: , + }, + { + text: "پرونده های کشتار", + route: ROUTES.ROUTE_ADMINX_ROUTE_FILES_STATE, + icon: , + }, + { + text: "مدیریت بازرسی", + route: ROUTES.ROUTE_ADMINX_ROUTE_INSPECTION, + icon: , + }, + { + text: "مدیریت بارها", + route: ROUTES.ROUTE_ADMINX_ROUTE_ALLOCATIONS, + icon: , + }, + { + text: "صادرات", + route: ROUTES.ROUTE_ADMINX_EXPORT, + icon: , + }, + + { + text: "مدیریت تخصیصات", + route: ROUTES.ROUTE_ADMINX_ALLOCATED_REQUESTS, + icon: , + }, + { + text: "تخصیصات خودکار", + route: ROUTES.ROUTE_ADMINX_AUTO_ALLOCATION_REQUESTS, + icon: , + }, + { + text: "صدور نامه", + route: ROUTES.ROUTE_ADMINX_ISSUANCE_OF_LETTER, + icon: , + }, + // { + // text: "تراکنش ها", + // route: ROUTES.ROUTE_ADMINX_TRANSACTIONS, + // icon: , + // }, + { + text: "انتخاب استان", + route: ROUTES.ROUTE_ADMINX_PROVINCE_SWITCH, + icon: , + }, + { + text: "تحلیل داده", + route: ROUTES.ROUTE_ADMINX_VISOR_STATICS, + icon: , + }, + { + text: "کارشناسان علوم دام", + route: ROUTES.ROUTE_ADMINX_POULTRY_LIVESTOCK_EXPERTS, + icon: , + }, + { + text: "قیمت روز", + route: ROUTES.ROUTE_ADMINX_PRICING3, + icon: , + }, + // { + // text: "آمار و اطلاعات", + // route: ROUTES.ROUTE_ADMINX_STATICS, + // icon: , + // }, + // { + // text: "گزارش روزانه", + // route: null, // Opens modal instead of navigating + // icon: , + // }, + { + text: "گزارشات", + route: ROUTES.ROUTE_ADMINX_REPORT, + icon: , + }, + + { + text: "مدیریت توزیع", + route: ROUTES.ROUTE_ADMINX_DISPENSERS, + icon: , + }, + { + text: "مدیریت اصناف", + route: ROUTES.ROUTE_ADMINX_ROUTE_MANAGE_GUILDS, + icon: , + }, + { + text: "مدیریت مباشرین", + route: ROUTES.ROUTE_ADMINX_ROUTE_MANAGE_STEWARDS, + icon: , + }, + { + text: "مدیریت سردخانه ها", + icon: , + route: ROUTES.ROUTE_ADMINX_COLD_HOUSES, + }, + { + text: "شرکت‌های پرداخت الکترونیک", + route: ROUTES.ROUTE_ADMINX_ROUTE_PSP_COMPANIES, + icon: , + }, + { + text: "خودروها", + route: ROUTES.ROUTE_ADMINX_CARS, + icon: , + }, + { + text: "کاربران", + route: ROUTES.ROUTE_ADMINX_USERS, + icon: , + }, + // { + // text: "مدیریت تراکنش ها", + // route: ROUTES.ROUTE_ADMINX_GUILD_TRANSACTIONS, + // icon: , + // }, + { + text: "مدیریت فارم ها", + route: ROUTES.ROUTE_ADMINX_POULTRIES, + icon: , + }, + { + text: "خریداران", + route: ROUTES.ROUTE_ADMINX_SLAUGHTERS, + icon: , + }, + { + text: "خریدهای بازگشتی", + route: ROUTES.ROUTE_ADMINX_RETURN_PURCHASES, + icon: , + }, + { + text: "محصولات", + route: ROUTES.ROUTE_ADMINX_PRODUCTS, + icon: , + }, + { + text: "دامپزشکان", + route: ROUTES.ROUTE_ADMINX_ASSIGN_VET_FARM, + icon: , + }, + { + text: "پنل اطلاع رسانی", + route: ROUTES.ROUTE_ADMINX_ROUTE_SMS, + icon: , + }, + { + text: "مدیریت فرآیند", + route: ROUTES.ROUTE_ADMINX_ROUTE_MANAGE_PROCESS, + icon: , + }, + // { + // text: "مدیریت تیکت ها", + + // route: ROUTES.ROUTE_ADMINX_TICKET, + // icon: , + // }, + { + text: "بررسی اکسل", + route: ROUTES.ROUTE_ADMINX_EXCEL_CHECK, + icon: , + }, + { + text: "خانه", + route: ROUTES.ROUTE_ADMINX_BASE_NEW_HOME, + icon: , + }, + ]; + case "Admin": + return [ + { + text: "تحلیل داده", + route: ROUTES.ROUTE_ADMIN_VISOR_STATICS, + icon: , + }, + // { + // text: "آمار و اطلاعات", + // route: ROUTES.ROUTE_ADMIN_STATICS, + // icon: , + // }, + ]; + case "CityOperator": + return [ + { + route: ROUTES.ROUTE_CITY_NEW_REQUESTS, + icon: , + text: "درخواست های کشتار", + }, + { + route: ROUTES.ROUTE_CITY_ACTIVE_REQUESTS, + icon: , + text: "درخواست های فعال", + }, + // { + // route: ROUTES.ROUTE_CITY_AWAITING_PAYMENT_REQUESTS, + // icon: , + // text: "در انتظار پرداخت", + // }, + // { + // route: ROUTES.ROUTE_CITY_AWAITING_INSPECTION_REQUESTS, + // icon: , + // text: "در انتظار بازرسی", + // }, + // { + // route: ROUTES.ROUTE_CITY_REJECTED_REQUESTS, + // icon: , + // text: "درخواست های رد شده", + // }, + { + route: ROUTES.ROUTE_CITY_FREE_SALES_REQUESTS, + icon: , + text: "فروش به خارج استان", + }, + // { + // route: ROUTES.ROUTE_CITY_ARCHIVED_REQUESTS, + // icon: , + // text: "بایگانی", + // }, + { + route: ROUTES.ROUTE_CITY_VISOR_STATICS, + icon: , + text: "تحلیل داده", + }, + { + route: ROUTES.ROUTE_CITY_HATCHING, + icon: , + text: "مدیریت کشتار", + }, + // { + // route: ROUTES.ROUTE_CITY_ROUTE_FILES_STATE, + // icon: , + // text: "پرونده های کشتار", + // }, + { + route: ROUTES.ROUTE_CITYـHATCHINGS, + icon: , + text: "مدیریت جوجه ریزی", + }, + { + text: "اختلاف کشتار", + route: ROUTES.ROUTE_CITY_DIFFRENCE_KILLER, + icon: , + }, + { + route: ROUTES.ROUTE_CITY_ROUTE_ALLOCATIONS, + icon: , + text: "مدیریت بارها", + }, + { + route: ROUTES.ROUTE_CITY_ROUTE_INSPECTION, + icon: , + text: "مدیریت بازرسی", + }, + { + route: ROUTES.ROUTE_CITY_PRICING, + icon: , + text: "قیمت روز", + }, + { + route: ROUTES.ROUTE_CITY_POULTRIES, + icon: , + text: "مدیریت فارم ها", + }, + { + route: ROUTES.ROUTE_CITY_POULTRY_FARMS, + icon: , + text: "مرغداران", + }, + // { + // route: ROUTES.ROUTE_CITY_STATICS, + // icon: , + // text: "آمار و اطلاعات", + // }, + { + route: ROUTES.ROUTE_CITY_USER_MANAGEMENT, + icon: , + text: "کاربران", + }, + // { + // route: ROUTES.ROUTE_CITY_TICKET, + // icon: , + // text: "مدیریت تیکت ها", + // }, + ]; + case "Poultry": + return [ + { + route: ROUTES.ROUTE_AVICULTURE_HATCHING, + icon: , + text: "جوجه ریزی", + }, + { + route: ROUTES.ROUTE_AVICULTURE_SUBMIT_REQUEST, + icon: , + text: "درخواست های کشتار", + }, + // { + // route: ROUTES.ROUTE_AVICULTURE_AWAITING_PAYMENT_REQUESTS, + // icon: , + // text: "در انتظار پرداخت", + // }, + // { + // route: ROUTES.ROUTE_AVICULTURE_AWAITING_INSPECTION_REQUESTS, + // icon: , + // text: "در انتظار بازرسی", + // }, + // { + // route: ROUTES.ROUTE_AVICULTURE_REJECTED_REQUESTS, + // icon: , + // text: "درخواست های رد شده", + // }, + // { + // route: ROUTES.ROUTE_AVICULTURE_ARCHIVED_REQUESTS, + // icon: , + // text: "بایگانی", + // }, + // { + // route: ROUTES.ROUTE_AVICULTURE_GIVE_PERMISSION, + // icon: , + // text: "وکالت", + // }, + { + route: ROUTES.ROUTE_AVICULTURE_PRICING, + icon: , + text: "قیمت روز", + }, + { + route: ROUTES.ROUTE_AVICULTURE_ROUTE_HALLS, + icon: , + text: "سالن ها", + }, + // { + // route: ROUTES.ROUTE_AVICULTURE_TICKET, + // icon: , + // text: "مدیریت تیکت ها", + // }, + ]; + case "ProvinceOperator": + return [ + { + text: "داشبورد", + route: ROUTES.ROUTE_PROVINCE_DASHBOARD, + icon: , + }, + { + text: "درخواست های کشتار", + route: ROUTES.ROUTE_PROVINCE_CITY_NEW_REQUESTS, + icon: , + }, + { + text: "تخصیص", + route: ROUTES.ROUTE_PROVINCE_ALLOCATION_REQUESTS, + icon: , + }, + { + text: "مدیریت کشتار", + icon: , + route: ROUTES.ROUTE_PROVINCE_HATCHING, + }, + { + text: "مدیریت جوجه ریزی", + icon: , + route: ROUTES.ROUTE_PROVINCEـHATCHINGS, + }, + { + text: "اختلاف کشتار", + route: ROUTES.ROUTE_PROVINCE_DIFFRENCE_KILLER, + icon: , + }, + { + text: "اعلام نیاز خریداران", + route: ROUTES.ROUTE_PROVINCE_STATEMENTـOFـNEED_REQUESTS, + icon: , + }, + { + text: "خرید مستقیم", + route: ROUTES.ROUTE_PROVINCEـFREE_BUY, + icon: , + }, + { + text: "پنل معاملات", + route: ROUTES.ROUTE_PROVINCE_TRADING_PANEL, + icon: , + }, + { + text: "فروش به خارج استان", + route: ROUTES.ROUTE_PROVINCE_FREE_SALES_REQUESTS, + icon: , + }, + { + text: "زنجیره ها", + route: ROUTES.ROUTE_PROVINCE_CHAINS, + icon: , + }, + { + text: "مدیریت تخصیصات", + route: ROUTES.ROUTE_PROVINCE_ALLOCATED_REQUESTS, + icon: , + }, + { + text: "تعرفه ها", + route: ROUTES.ROUTE_PROVINCE_PAYING_FEES_REQUESTS, + icon: , + }, + { + text: "تعرفه زیربخش ها", + + route: ROUTES.ROUTE_PROVINCE_SUB_SECTORS_WAGE, + icon: , + }, + { + text: "تسویه حساب", + route: ROUTES.ROUTE_PROVINCE_SETTLEMENTS, + icon: , + }, + { + text: "صادرات", + route: ROUTES.ROUTE_PROVINCEـEXPORT, + icon: , + }, + { + text: "گزارشات", + icon: , + route: ROUTES.ROUTE_PROVINCE_REPORT, + }, + + // { + // text: "پرونده های کشتار", + // icon: , + // route: ROUTES.ROUTE_PROVINCE_ROUTE_FILES_STATE, + // }, + { + text: "مدیریت بارها", + icon: , + route: ROUTES.ROUTE_PROVINCE_ROUTE_ALLOCATIONS, + }, + + // { + // text: "تخصیصات خودکار", + // route: ROUTES.ROUTE_PROVINCE_AUTO_ALLOCATION_REQUESTS, + // icon: , + // }, + // { + // text: "صدور نامه", + // route: ROUTES.ROUTE_PROVINCE_ISSUANCE_OF_LETTER, + // icon: , + // }, + // { + // text: "تراکنش ها", + // route: ROUTES.ROUTE_PROVINCE_TRANSACTIONS, + // icon: , + // }, + // { + // text: "گزارش روزانه", + // icon: , + // onClick: () => dispatch(OPEN_MODAL({ text: "اطلاعات گزارش", content: })) + // }, + { + text: "تحلیل داده", + icon: , + tooltip: "آمار", + route: ROUTES.ROUTE_PROVINCEـVISOR_STATICS, + }, + { + text: "کارشناسان علوم دام", + route: ROUTES.ROUTE_PROVINCE_POULTRY_LIVESTOCK_EXPERTS, + icon: , + }, + // { + // text: "قیمت روز", + // icon: , + // route: ROUTES.ROUTE_PROVINCE_PRICING3, + // }, + // { + // text: "آمار و اطلاعات", + // icon: , + // route: ROUTES.ROUTE_PROVINCE_STATICS, + // }, + { + text: "مدیریت توزیع", + icon: , + route: ROUTES.ROUTE_PROVINCE_DISPENSERS, + }, + { + text: "مدیریت سردخانه ها", + icon: , + route: ROUTES.ROUTE_PROVINCE_COLD_HOUSES, + }, + { + text: "مدیریت اصناف", + icon: , + route: ROUTES.ROUTE_PROVINCE_ROUTE_MANAGE_GUILDS, + }, + { + text: "مدیریت مباشرین", + route: ROUTES.ROUTE_PROVINCE_ROUTE_MANAGE_STEWARDS, + icon: , + }, + { + text: "خودروها", + icon: , + route: ROUTES.ROUTE_PROVINCE_CARS, + }, + { + text: "کاربران", + icon: , + route: ROUTES.ROUTE_PROVINCE_USERS, + }, + // { + // text: "مدیریت تراکنش ها", + // icon: , + // route: ROUTES.ROUTE_PROVINCE_GUILD_TRANSACTIONS, + // }, + { + text: "مدیریت فارم ها", + icon: , + route: ROUTES.ROUTE_PROVINCE_POULTRIES, + }, + { + text: "خریداران", + icon: , + route: ROUTES.ROUTE_PROVINCE_SLAUGHTERS, + }, + // { + // text: "محصولات", + // icon: , + // route: ROUTES.ROUTE_PROVINCE_PRODUCTS, + // }, + { + text: "دامپزشکان", + icon: , + route: ROUTES.ROUTE_PROVINCE_ASSIGN_VET_FARM, + }, + { + text: "پنل اطلاع رسانی", + icon: , + route: ROUTES.ROUTE_PROVINCE_ROUTE_SMS, + }, + // { + // text: "مدیریت تیکت ها", + + // icon: , + // route: ROUTES.ROUTE_PROVINCE_TICKET, + // }, + { + text: "خریدهای بازگشتی", + route: ROUTES.ROUTE_PROVINCE_RETURN_PURCHASES, + icon: , + }, + ]; + case "ProvinceFinancial": + return [ + { + route: ROUTES.ROUTE_PROVINCE_FINANCIAL_PENDING_REQUESTS, + icon: , + text: "صدور فاکتور", + }, + { + route: ROUTES.ROUTE_PROVINCE_FINANCIAL_AWAITING_PAYMENT_REQUESTS, + icon: , + text: "در انتظار پرداخت", + }, + { + route: ROUTES.ROUTE_PROVINCE_FINANCIAL_CHECK_PAYED_FACTOR_REQUESTS, + icon: , + text: "فاکتورهای پرداخت شده", + }, + // { + // route: ROUTES.ROUTE_PROVINCE_FINANCIAL_TRANSACTIONS, + // icon: , + // text: "تراکنش ها", + // }, + { + route: ROUTES.ROUTE_PROVINCE_FINANCIAL_FINAL_FACTORS_REQUESTS, + icon: , + text: "اسناد مالی", + }, + { + text: "تعرفه زیربخش ها", + + route: ROUTES.ROUTE_PROVINCE_FINANCIAL_SUB_SECTORS_WAGE, + icon: , + }, + { + route: ROUTES.ROUTE_PROVINCE_FINANCIAL_ACTIVE_REQUESTS, + icon: , + text: "درخواست های فعال", + }, + { + route: ROUTES.ROUTE_PROVINCE_FINANCIAL_AWAITING_INSPECTION_REQUESTS, + icon: , + text: "در انتظار بازرسی", + }, + { + route: ROUTES.ROUTE_PROVINCE_FINANCIAL_ARCHIVED_REQUESTS, + icon: , + text: "بایگانی", + }, + { + route: ROUTES.ROUTE_PROVINCE_FINANCIAL_SETTLEMENT, + icon: , + text: "تسویه حساب", + }, + { + route: ROUTES.ROUTE_PROVINCE_PRICING, + icon: , + text: "قیمت گذاری", + }, + // { + // route: ROUTES.ROUTE_PROVINCE_FINANCIAL_STATICS, + // icon: , + // text: "آمار و اطلاعات", + // }, + // { + // route: ROUTES.ROUTE_PROVINCE_FINANCIAL_TICKET, + // icon: , + // text: "مدیریت تیکت ها", + // }, + { + route: ROUTES.ROUTE_PROVINCE_FINANCIAL_DOCUMENT_REGISTRATION, + icon: , + text: "ثبت سند مالی", + }, + ]; + case "KillHouse": + return [ + { + text: "ثبت درخواست", + route: ROUTES.ROUTE_SLAUGHTER_NEW_REQUESTS, + icon: , + }, + { + text: "سفارش های دریافت شده", + route: ROUTES.ROUTE_SLAUGHTER_PENDING_REQUESTS, + icon: , + }, + { + text: "خرید مستقیم", + route: ROUTES.ROUTE_SLAUGHTERـFREE_BUY, + icon: , + }, + { + text: "پنل معاملات", + route: ROUTES.ROUTE_SLAUGHTER_TRADING_PANEL, + icon: , + }, + { + text: "تخصیص خودرو", + route: ROUTES.ROUTE_SLAUGHTER_ALLOCATE_CAR_REQUESTS, + icon: , + }, + { + text: "وارد کردن اطلاعات بار", + route: ROUTES.ROUTE_SLAUGHTER_ENTER_BAR_INFO, + icon: , + }, + { + text: "انبار و توزیع", + route: ROUTES.ROUTE_SLAUGHTER_INVENTORY, + icon: , + }, + { + text: "زیر مجموعه ها", + route: ROUTES.ROUTE_SLAUGHTER_ROUTE_SUB_UNITS, + icon: , + }, + { + text: "مدیریت تعرفه ها", + route: ROUTES.ROUTE_SLAUGHTER_PAYING_FEES_REQUESTS, + icon: , + }, + { + text: "مدیریت بارها", + route: ROUTES.ROUTE_SLAUGHTER_ROUTE_MANAGE_BARS, + icon: , + }, + + { + text: "مدیریت اصناف", + route: ROUTES.ROUTE_SLAUGHTER_ROUTE_MANAGE_GUILDS, + icon: , + }, + { + text: "مدیریت مباشرین", + route: ROUTES.ROUTE_SLAUGHTER_ROUTE_MANAGE_STEWARDS, + icon: , + }, + // { + // text: "قیمت روز ", + // route: ROUTES.ROUTE_SLAUGHTER_PRICING, + // icon: , + // }, + { + text: "خودروها", + route: ROUTES.ROUTE_SLAUGHTER_CAR_MANAGEMENT, + icon: , + }, + // { + // text: "مدیریت توزیع", + // route: ROUTES.ROUTE_SLAUGHTER_DISPENSERS, + // icon: , + // }, + + { + text: "صادرات", + route: ROUTES.ROUTE_SLAUGHTERـEXPORT, + icon: , + }, + + { + text: "تخصیص", + route: ROUTES.ROUTE_SLAUGHTER_ALLOCATION_REQUESTS, + icon: , + }, + + // { + // text: "کیف پول", + // route: ROUTES.ROUTE_SLAUGHTER_WALLET, + // icon: , + // }, + // { + // text: "مدیریت تراکنش ها", + // route: ROUTES.ROUTE_SLAUGHTER_FINANCIAL_TRANSACTIONS, + // icon: , + // }, + // { + // text: "مدیریت فاکتورها", + // route: ROUTES.ROUTE_SLAUGHTER_PAY_FACTORS_REQUESTS, + // icon: , + // }, + { + text: "سردخانه", + route: ROUTES.ROUTE_SLAUGHTER_MORGUE, + icon: , + }, + { + text: "تسویه حساب", + route: ROUTES.ROUTE_SLAUGHTER_SETTLEMENTS, + icon: , + }, + { + text: "خریدهای بازگشتی", + route: ROUTES.ROUTE_SLAUGHTER_RETURN_PURCHASES, + icon: , + }, + { + route: ROUTES.ROUTE_SLAUGHTER_ROUTE_DEVICES, + icon: , + text: "مدیریت دستگاه‌ها", + }, + ]; + case "KillHouseVet": + return [ + { + route: ROUTES.ROUTE_SLAUGHTER_HOUSE_VET_FREE_BUY_ROUTE, + icon: , + text: "بارهای خارج استان", + }, + { + route: ROUTES.ROUTE_SLAUGHTER_HOUSE_VET_NEW_REQUESTS, + icon: , + text: "بارهای کشتار", + }, + { + route: ROUTES.ROUTE_SLAUGHTER_HOUSE_VET_ENTER_BAR_INFO, + icon: , + text: "وارد کردن اطلاعات بار", + }, + ]; + case "VetFarm": + return [ + // { + // text: "مدیریت جوجه ریزی", + // icon: , + // route: ROUTES.ROUTE_VETFARM_HATCHING, + // }, + { + route: ROUTES.ROUTE_VETFARM_ROUTE_ALLOCATIONS, + icon: , + text: "کدرهگیری قرنطینه", + }, + { + route: ROUTES.ROUTE_VETFARM_REGISTER_INFO, + icon: , + text: "مدیریت فارم", + }, + { + text: "مدیریت بازرسی", + route: ROUTES.ROUTE_VETFARM_ROUTE_INSPECTION, + icon: , + }, + ]; + case "Driver": + return [ + { + route: ROUTES.ROUTE_DRIVER_REQUESTS, + icon: , + text: "پنل مدیریت", + }, + ]; + case "VetSupervisor": + return [ + { + text: "مدیریت جوجه ریزی", + icon: , + route: ROUTES.ROUTE_VETـSUPERVISOR_HATCHING, + }, + { + text: "مدیریت فارم ها", + route: ROUTES.ROUTEـSUPERVISOR_POULTRIES, + icon: , + }, + // { + // text: "پرونده های کشتار", + // icon: , + // route: ROUTES.ROUTE_VETـSUPERVISOR_ROUTE_FILES_STATE, + // }, + // { + // text: "آمار و اطلاعات", + // icon: , + // route: ROUTES.ROUTE_VETـSUPERVISOR_STATICS, + // }, + { + text: "مدیریت بارها", + icon: , + route: ROUTES.ROUTE_VETـSUPERVISOR_ALLOCATIONS, + }, + // { + // text: "کشتار غیرمجاز", + // icon: , + // route: ROUTES.ROUTE_VETـSUPERVISOR_ILLEGALـKILLING, + // }, + // { + // text: "آمار کشتار استان", + // icon: , + // route: ROUTES.ROUTE_VETـSUPERVISOR_KILLS_STATS, + // }, + { + text: "گزارشات", + icon: , + route: ROUTES.ROUTE_VETـSUPERVISOR_REPORTING, + }, + ]; + case "ProvinceInspector": + return [ + { + route: ROUTES.ROUTE_INSPECTOR_REQUESTS_NEW_REQUESTS, + icon: , + text: "درخواست های کشتار", + }, + { + route: ROUTES.ROUTE_PROVINCE_INSPECTOR_AWAITING_PAYMENT_REQUESTS, + icon: , + text: "در انتظار پرداخت", + }, + { + route: ROUTES.ROUTE_PROVINCE_INSPECTOR_AWAITING_INSPECTION_REQUESTS, + icon: , + text: "در انتظار بازرسی", + }, + { + route: ROUTES.ROUTE_INSPECTOR_REJECTED_REQUESTS, + icon: , + text: "درخواست های رد شده", + }, + { + route: ROUTES.ROUTE_INSPECTOR_ARCHIVED_REQUESTS, + icon: , + text: "بایگانی", + }, + // { + // route: ROUTES.ROUTE_INSPECTOR_STATICS, + // icon: , + // text: "آمار و اطلاعات", + // }, + { + route: ROUTES.ROUTE_PROVINCE_INSPECTOR_REPORTING, + icon: , + text: "گزارشات", + }, + // { + // route: ROUTES.ROUTE_PROVINCE_INSPECTOR_TICKET, + // icon: , + // text: "مدیریت تیکت ها", + // }, + ]; + case "Jahad": + return [ + // { + // route: ROUTES.ROUTE_JAHAD_KILLS_STATS, + // icon: , + // text: "آمار کشتار استان", + // }, + { + route: ROUTES.ROUTE_JAHAD_ILLEGALـKILLING, + icon: , + text: "کشتار غیرمجاز", + }, + { + route: ROUTES.ROUTE_JAHAD_PRICING, + icon: , + text: "قیمت روز", + }, + // { + // route: ROUTES.ROUTE_JAHAD_FILES_STATE, + // icon: , + // text: "پرونده های کشتار", + // }, + ]; + case "ProvincialGovernment": + return [ + // { + // route: ROUTES.ROUTE_JAHAD_KILLS_STATS, + // icon: , + // text: "آمار کشتار استان", + // }, + { + route: ROUTES.ROUTE_JAHAD_ILLEGALـKILLING, + icon: , + text: "کشتار غیرمجاز", + }, + { + route: ROUTES.ROUTE_JAHAD_PRICING, + icon: , + text: "قیمت روز", + }, + // { + // route: ROUTES.ROUTE_JAHAD_FILES_STATE, + // icon: , + // text: "پرونده های کشتار", + // }, + ]; + case "Guilds": + return [ + { + route: ROUTES.ROUTE_SENF_INVENTORY, + icon: , + text: "انبار", + }, + { + route: ROUTES.ROUTE_GUILD_ROUTE_DEVICES, + icon: , + text: "مدیریت دستگاه‌ها", + }, + ]; + case "Steward": + return [ + { + route: ROUTES.ROUTE_STEWARD_INVENTORY, + icon: , + text: "انبار", + }, + { + route: ROUTES.ROUTE_STEWARD_ROUTE_SUB_UNITS, + icon: , + text: "زیر مجموعه ها", + }, + { + route: ROUTES.ROUTE_STEWARD_ROUTE_DEVICES, + icon: , + text: "مدیریت دستگاه‌ها", + }, + // { + // route: ROUTES.ROUTE_STEWARD_MANAGE_GUILDS, + // icon: , + // text: "مدیریت اصناف", + // }, + ]; + case "Commerce": + return [ + // { + // route: ROUTES.ROUTE_COMMERCE_STATICS, + // icon: , + // text: "پروفایل آماری", + // }, + { + route: ROUTES.ROUTE_COMMERCE_ROUTE_MANAGE_GUILDS, + icon: , + text: "مدیریت اصناف", + }, + { + text: "مدیریت مباشرین", + route: ROUTES.ROUTE_COMMERCE_ROUTE_MANAGE_STEWARDS, + icon: , + }, + // { + // route: ROUTES.ROUTE_COMMERCE_ROUTE_FILES_STATE, + // icon: , + // text: "پرونده های کشتار", + // }, + { + route: ROUTES.ROUTE_COMMERCE_ROUTE_ALLOCATIONS, + icon: , + text: "مدیریت بارها", + }, + { + route: ROUTES.ROUTE_COMMERCE_HATCHING, + icon: , + text: "مدیریت جوجه ریزی", + }, + ]; + case "ProvinceSupervisor": + return [ + // { + // route: ROUTES.ROUTE_PROVINCE_SUPERVISOR_STATICS, + // icon: , + // text: "پروفایل آماری", + // }, + // { + // route: ROUTES.ROUTE_PROVINCE_SUPERVISOR_ROUTE_FILES_STATE, + // icon: , + // text: "پرونده های کشتار", + // }, + { + text: "داشبورد", + route: ROUTES.ROUTE_PROVINCE_SUPERVISOR_DASHBOARD, + icon: , + }, + { + route: ROUTES.ROUTE_PROVINCE_SUPERVISORـHATCHINGS, + icon: , + text: "مدیریت جوجه ریزی", + }, + { + route: ROUTES.ROUTE_PROVINCE_SUPERVISOR_ROUTE_ALLOCATIONS, + icon: , + text: "مدیریت بارها", + }, + { + text: "مدیریت بازرسی", + route: ROUTES.ROUTE_PROVINCE_SUPERVISOR_ROUTE_INSPECTION, + icon: , + }, + { + route: ROUTES.ROUTE_PROVINCE_SUPERVISOR_ROUTE_MANAGE_GUILDS, + icon: , + text: "مدیریت اصناف", + }, + { + text: "مدیریت مباشرین", + route: ROUTES.ROUTE_PROVINCE_SUPERVISOR_ROUTE_MANAGE_STEWARDS, + icon: , + }, + { + text: "پایش کشوری", + route: ROUTES.ROUTE_PROVINCE_SUPERVISOR_ROUTE_NATIONAL_INFO, + icon: , + }, + { + route: ROUTES.ROUTE_PROVINCE_SUPERVISOR_REPORTING, + icon: , + text: "گزارشات", + }, + { + text: "قیمت روز", + route: ROUTES.ROUTE_PROVINCE_SUPERVISOR_PRICING, + icon: , + }, + { + text: "مدیریت توزیع", + route: ROUTES.ROUTE_PROVINCE_SUPERVISOR_DISPENSERS, + icon: , + }, + ]; + case "CityCommerce": + return [ + { + route: ROUTES.ROUTE_CITY_COMMERCE_ROUTE_MANAGE_GUILDS, + icon: , + text: "مدیریت اصناف", + }, + { + text: "مدیریت مباشرین", + route: ROUTES.ROUTE_CITY_COMMERCE_ROUTE_MANAGE_STEWARDS, + icon: , + }, + // { + // route: ROUTES.ROUTE_CITY_COMMERCE_ROUTE_FILES_STATE, + // icon: , + // text: "پرونده های کشتار", + // }, + { + route: ROUTES.ROUTE_CITY_COMMERCE_ROUTE_ALLOCATIONS, + icon: , + text: "مدیریت بارها", + }, + ]; + case "CityVet": + return [ + { + text: "مدیریت جوجه ریزی", + icon: , + route: ROUTES.ROUTE_CITYVET_HATCHING, + }, + { + route: ROUTES.ROUTE_CITYVET_ROUTE_ALLOCATIONS, + icon: , + text: "مدیریت بارها", + }, + { + route: ROUTES.ROUTE_CITYVET_REGISTER_INFO, + icon: , + text: "مدیریت فارم", + }, + ]; + case "CityJahad": + return [ + // { + // route: ROUTES.ROUTE_CITY_JIHAD_STATICS, + // icon: , + // text: "آمار و اطلاعات", + // }, + // { + // route: ROUTES.ROUTE_CITY_JIHAD_ROUTE_FILES_STATE, + // icon: , + // text: "پرونده های کشتار", + // }, + { + route: ROUTES.ROUTE_CITY_JIHAD_ROUTE_ALLOCATIONS, + icon: , + text: "مدیریت بارها", + }, + { + text: "مدیریت بازرسی", + route: ROUTES.ROUTE_CITY_JIHAD_ROUTE_INSPECTION, + icon: , + }, + { + route: ROUTES.ROUTE_CITY_JIHAD_ROUTE_MANAGE_GUILDS, + icon: , + text: "مدیریت اصناف", + }, + { + text: "مدیریت مباشرین", + route: ROUTES.ROUTE_CITY_JIHAD_ROUTE_MANAGE_STEWARDS, + icon: , + }, + { + route: ROUTES.ROUTE_CITY_JIHADـHATCHINGS, + icon: , + text: "مدیریت جوجه ریزی", + }, + { + text: "مدیریت توزیع", + route: ROUTES.ROUTE_CITY_JIHAD_DISPENSERS, + icon: , + }, + ]; + case "Observatory": + return [ + // { + // route: ROUTES.ROUTE_OBSERVATORY_STATICS, + // icon: , + // text: "آمار و اطلاعات", + // }, + + { + route: ROUTES.ROUTE_OBSERVATORY_VISOR_STATICS, + icon: , + text: "تحلیل داده", + }, + ]; + case "GuildRoom": + return [ + { + route: ROUTES.ROUTE_GUILD_ROOM_ROUTE_MANAGE_GUILDS, + icon: , + text: "اتاق اصناف", + }, + ]; + case "PosCompany": + return [ + { + route: ROUTES.ROUTE_PSP_ROUTE_COMPANY_PSP_COMPANIES, + icon: , + text: "اتاق اصناف", + }, + ]; + case "LiveStockSupport": + return [ + { + route: ROUTES.ROUTE_LIVE_STOCK_SUPPORT_MANAGE_BARS, + icon: , + text: "مدیریت بارها", + }, + // { + // route: ROUTES.ROUTE_LIVE_STOCK_SUPPORT_ROUTE_FILES_STATE, + // icon: , + // text: "پرونده های کشتار", + // }, + { + route: ROUTES.ROUTE_LIVE_STOCK_FREEZING_REQUESTS, + icon: , + text: "درخواست های انجماد", + }, + { + route: ROUTES.ROUTE_LIVE_STOCK_COLD_HOUSE, + icon: , + text: "سردخانه", + }, + ]; + case "SuperAdmin": + return [ + { + text: "داشبورد", + route: ROUTES.ROUTE_SUPER_ADMIN_DASHBOARD, + icon: , + }, + { + text: "درخواست های کشتار", + route: ROUTES.ROUTE_SUPER_ADMIN_CITY_NEW_REQUESTS, + icon: , + }, + { + text: "تخصیص", + route: ROUTES.ROUTE_SUPER_ADMIN_ALLOCATION_REQUESTS, + icon: , + }, + { + text: "مدیریت کشتار", + icon: , + route: ROUTES.ROUTE_SUPER_ADMIN_HATCHING, + }, + { + text: "مدیریت جوجه ریزی", + icon: , + route: ROUTES.ROUTE_SUPER_ADMINـHATCHINGS, + }, + { + text: "اختلاف کشتار", + route: ROUTES.ROUTE_SUPER_ADMIN_DIFFRENCE_KILLER, + icon: , + }, + { + text: "اعلام نیاز خریداران", + route: ROUTES.ROUTE_SUPER_ADMIN_STATEMENTـOFـNEED_REQUESTS, + icon: , + }, + { + text: "خرید مستقیم", + route: ROUTES.ROUT_SUPER_ADMIN_FREE_BUY, + icon: , + }, + { + text: "پنل معاملات", + route: ROUTES.ROUTE_SUPER_ADMIN_TRADING_PANEL, + icon: , + }, + { + text: "فروش به خارج استان", + route: ROUTES.ROUTE_SUPER_ADMIN_FREE_SALES_REQUESTS, + icon: , + }, + { + text: "زنجیره ها", + route: ROUTES.ROUTE_SUPER_ADMIN_CHAINS, + icon: , + }, + { + text: "تعرفه ها", + route: ROUTES.ROUTE_SUPER_ADMIN_PAYING_FEES_REQUESTS, + icon: , + }, + { + text: "پایش کشوری", + route: ROUTES.ROUTE_SUPER_ADMIN_ROUTE_NATIONAL_INFO, + icon: , + }, + { + text: "تعرفه زیربخش ها", + route: ROUTES.ROUTE_SUPER_ADMIN_SUB_SECTORS_WAGE, + icon: , + }, + { + text: "تسویه حساب", + route: ROUTES.ROUTE_SUPER_ADMIN_SETTLEMENTS, + icon: , + }, + { + text: "صادرات", + route: ROUTES.ROUTE_SUPER_ADMIN_EXPORT, + icon: , + }, + { + text: "مدیریت تخصیصات", + route: ROUTES.ROUTE_SUPER_ADMIN_ALLOCATED_REQUESTS, + icon: , + }, + { + text: "تخصیصات خودکار", + route: ROUTES.ROUTE_SUPER_ADMIN_AUTO_ALLOCATION_REQUESTS, + icon: , + }, + { + text: "صدور نامه", + route: ROUTES.ROUTE_SUPER_ADMIN_ISSUANCE_OF_LETTER, + icon: , + }, + // { + // text: "تراکنش ها", + // route: ROUTES.ROUTE_SUPER_ADMIN_TRANSACTIONS, + // icon: , + // }, + { + text: "تحلیل داده", + icon: , + route: ROUTES.ROUTE_SUPER_ADMIN_VISOR_STATICS, + }, + { + text: "کارشناسان علوم دام", + route: ROUTES.ROUTE_SUPER_ADMIN_POULTRY_LIVESTOCK_EXPERTS, + icon: , + }, + { + text: "قیمت روز", + icon: , + route: ROUTES.ROUTE_SUPER_ADMIN_PRICING3, + }, + // { + // text: "آمار و اطلاعات", + // icon: , + // route: ROUTES.ROUTE_SUPER_ADMIN_STATICS, + // }, + { + text: "گزارشات", + icon: , + route: ROUTES.ROUTE_SUPER_ADMIN_REPORT, + }, + + { + text: "مدیریت فرآیند", + route: ROUTES.ROUTE_SUPER_ADMIN_ROUTE_MANAGE_PROCESS, + icon: , + }, + // { + // text: "پرونده های کشتار", + // icon: , + // route: ROUTES.ROUTE_SUPER_ADMIN_ROUTE_FILES_STATE, + // }, + { + text: "مدیریت بارها", + icon: , + route: ROUTES.ROUTE_SUPER_ADMIN_ROUTE_ALLOCATIONS, + }, + { + text: "مدیریت بازرسی", + route: ROUTES.ROUTE_SUPER_ADMIN_ROUTE_INSPECTION, + icon: , + }, + { + text: "مدیریت توزیع", + icon: , + route: ROUTES.ROUTE_SUPER_ADMIN_DISPENSERS, + }, + { + text: "مدیریت اصناف", + icon: , + route: ROUTES.ROUTE_SUPER_ADMIN_ROUTE_MANAGE_GUILDS, + }, + { + text: "مدیریت مباشرین", + route: ROUTES.ROUTE_SUPER_ADMIN_ROUTE_MANAGE_STEWARDS, + icon: , + }, + { + text: "مدیریت سردخانه ها", + icon: , + route: ROUTES.ROUTE_SUPER_ADMIN_COLD_HOUSES, + }, + { + route: ROUTES.ROUTE_SUPER_ADMIN_ROUTE_PSP_COMPANIES, + icon: , + text: "شرکت‌های پرداخت الکترونیک", + }, + { + text: "خودروها", + icon: , + route: ROUTES.ROUTE_SUPER_ADMIN_CARS, + }, + { + text: "کاربران", + icon: , + route: ROUTES.ROUTE_SUPER_ADMIN_USERS, + }, + // { + // text: "مدیریت تراکنش ها", + // icon: , + // route: ROUTES.ROUTE_SUPER_ADMIN_GUILD_TRANSACTIONS, + // }, + { + text: "مدیریت فارم ها", + icon: , + route: ROUTES.ROUTE_SUPER_ADMIN_POULTRIES, + }, + { + text: "خریداران", + icon: , + route: ROUTES.ROUTE_SUPER_ADMIN_SLAUGHTERS, + }, + { + text: "محصولات", + icon: , + route: ROUTES.ROUTE_SUPER_ADMIN_PRODUCTS, + }, + { + text: "دامپزشکان", + icon: , + route: ROUTES.ROUTE_SUPER_ADMIN_ASSIGN_VET_FARM, + }, + { + text: "پنل اطلاع رسانی", + icon: , + route: ROUTES.ROUTE_SUPER_ADMIN_ROUTE_SMS, + }, + { + text: "خریدهای بازگشتی", + route: ROUTES.ROUTE_SUPER_ADMIN_RETURN_PURCHASES, + icon: , + }, + ]; + case "ChainCompany": + return [ + { + text: "مرغداران زیرمجموعه", + route: ROUTES.ROUTE_CHAIN_COMPANY_POULTRIES, + icon: , + }, + { + text: "مدیریت بارها", + route: ROUTES.ROUTE_CHAIN_COMPANY_MANAGE_BARS, + icon: , + }, + { + text: "مدیریت تعرفه", + route: ROUTES.ROUTE_CHAIN_COMPANY_MANAGE_FEES, + icon: , + }, + ]; + case "Supporter": + return [ + { + text: "مدیریت بارها", + route: ROUTES.ROUTE_SUPPORTER_ROUTE_ALLOCATIONS, + icon: , + }, + { + text: "مدیریت جوجه ریزی", + route: ROUTES.ROUTE_SUPPORTERـHATCHINGS, + icon: , + }, + ]; + case "CityPoultry": + return [ + { + text: "مدیریت کشتار", + icon: , + route: ROUTES.ROUTE_CITY_POULTRY_HATCHING, + }, + // { + // text: "آمار و اطلاعات", + // icon: , + // route: ROUTES.ROUTE_CITY_POULTRY_STATICS, + // }, + // { + // text: "پرونده های کشتار", + // icon: , + // route: ROUTES.ROUTE_CITY_POULTRY_ROUTE_FILES_STATE, + // }, + { + text: "مدیریت جوجه ریزی", + icon: , + route: ROUTES.ROUTE_CITY_POULTRYـHATCHINGS, + }, + { + text: "مدیریت بارها", + icon: , + route: ROUTES.ROUTE_CITY_POULTRY_ROUTE_ALLOCATIONS, + }, + { + text: "مدیریت اصناف", + icon: , + route: ROUTES.ROUTE_CITY_POULTRY_ROUTE_MANAGE_GUILDS, + }, + { + text: "مدیریت مباشرین", + route: ROUTES.ROUTE_CITY_POULTRY_ROUTE_MANAGE_STEWARDS, + icon: , + }, + // { + // text: "مدیریت توزیع", + // icon: , + // route: ROUTES.ROUTE_CITY_DISPENSERS, + // }, + ]; + case "ParentCompany": + return [ + { + text: "تعرفه ها", + route: ROUTES.ROUTE_PARENT_COMPANY_PAYING_FEES_REQUESTS, + icon: , + }, + { + text: "مدیریت بارها", + route: ROUTES.ROUTE_PARENT_COMPANY_ALLOCATIONS, + icon: , + }, + ]; + case "ColdHouseSteward": + return [ + { + text: "سردخانه", + route: ROUTES.ROUTE_COLD_HOUSE_STEWARD_MORGUE, + icon: , + }, + ]; + case "ProteinGuild": + return []; + + default: + return []; + } +}; diff --git a/src/utils/getSamasatProvinces.js b/src/utils/getSamasatProvinces.js new file mode 100644 index 0000000..304bb0b --- /dev/null +++ b/src/utils/getSamasatProvinces.js @@ -0,0 +1,128 @@ +export const getSamasatProvinces = () => { + return [ + { + name: "آذربایجان شرقی", + id: "65521", + }, + { + name: "آذربایجان غربی", + id: "65522", + }, + { + name: "اردبیل", + id: "65523", + }, + { + name: "اصفهان", + id: "65524", + }, + { + name: "البرز", + id: "65525", + }, + { + name: "ایلام", + id: "65526", + }, + { + name: "بوشهر", + id: "65527", + }, + { + name: "تهران", + id: "65528", + }, + { + name: "چهارمحال و بختیاری", + id: "65529", + }, + { + name: "خراسان جنوبی", + id: "65530", + }, + { + name: "خراسان رضوی", + id: "65531", + }, + { + name: "خراسان شمالی", + id: "65532", + }, + { + name: "خوزستان", + id: "65533", + }, + { + name: "زنجان", + id: "65534", + }, + { + name: "سمنان", + id: "65535", + }, + { + name: "سیستان و بلوچستان", + id: "65536", + }, + { + name: "فارس", + id: "65537", + }, + { + name: "قزوین", + id: "65538", + }, + { + name: "قم", + id: "65539", + }, + { + name: "کردستان", + id: "65540", + }, + { + name: "کرمان", + id: "65541", + }, + { + name: "کرمانشاه", + id: "65542", + }, + { + name: "کهکیلویه و بویراحمد", + id: "65543", + }, + { + name: "گلستان", + id: "65544", + }, + { + name: "گیلان", + id: "65545", + }, + { + name: "لرستان", + id: "65546", + }, + { + name: "مازندران", + id: "65547", + }, + { + name: "مرکزی", + id: "65548", + }, + { + name: "هرمزگان", + id: "65549", + }, + { + name: "همدان", + id: "65550", + }, + { + name: "یزد", + id: "65551", + }, + ]; +}; diff --git a/src/utils/getSelectedSubUserKey.js b/src/utils/getSelectedSubUserKey.js new file mode 100644 index 0000000..41575b1 --- /dev/null +++ b/src/utils/getSelectedSubUserKey.js @@ -0,0 +1,11 @@ +/** + * Helper function to get the selected sub user key from Redux state + * @param {Object} state - Redux state + * @returns {string|null} - The sub user key or null if not available + */ +export const getSelectedSubUserKey = (state) => { + const selectedSubUser = state?.userSlice?.selectedSubUser; + return selectedSubUser?.key || null; +}; + +export default getSelectedSubUserKey; diff --git a/src/utils/getSystemBaseAddress.js b/src/utils/getSystemBaseAddress.js new file mode 100644 index 0000000..f505fc2 --- /dev/null +++ b/src/utils/getSystemBaseAddress.js @@ -0,0 +1,18 @@ +export const getSystemBaseAddress = (userPath) => { + let province; + if (userPath === "https://testbackend.rasadyar.com/") { + province = "test"; + } else if (userPath === "https://mabackend.rasadyar.com/") { + province = "ma"; + } else if (userPath === "https://arbackend.rasadyar.com/") { + province = "ar"; + } else if (userPath === "https://habackend.rasadyar.com/") { + province = "ha"; + } else if (userPath === "https://bubackend.rasadyar.com/") { + province = "bu"; + } else { + province = "ha"; + } + + return province; +}; diff --git a/src/utils/getSystemName.js b/src/utils/getSystemName.js new file mode 100644 index 0000000..51a7a91 --- /dev/null +++ b/src/utils/getSystemName.js @@ -0,0 +1,18 @@ +import { useSelector } from "react-redux"; + +export const useSystemName = () => { + const userPath = useSelector((state) => state.userSlice.userPath); + if (userPath === "https://testbackend.rasadyar.com/") { + return "تست"; + } else if (userPath === "https://mabackend.rasadyar.com/") { + return "استان مرکزی"; + } else if (userPath === "https://bubackend.rasadyar.com/") { + return "استان بوشهر"; + } else if (userPath === "https://habackend.rasadyar.com/") { + return "استان همدان"; + } else if (userPath === "https://kubackend.rasadyar.com/") { + return "استان کردستان"; + } else { + return "تست"; + } +}; diff --git a/src/utils/getUserTypeOfActivity.js b/src/utils/getUserTypeOfActivity.js new file mode 100644 index 0000000..ab37394 --- /dev/null +++ b/src/utils/getUserTypeOfActivity.js @@ -0,0 +1,104 @@ +export function getUserTypeOfActivity(userRoles) { + const poultryRoles = [ + "CityOperator", + "Poultry", + "ProvinceOperator", + "KillHouse", + "KillHouseVet", + "VetFarm", + "ProvinceFinancial", + "ProvinceInspector", + "VetSupervisor", + "Commerce", + "CityCommerce", + "CityVet", + "CityJahad", + "Observatory", + "ProvinceSupervisor", + "Guilds", + "GuildRoom", + "LiveStockSupport", + "SuperAdmin", + "ChainCompany", + "AdminX", + "Supporter", + "Dispenser", + "CityPoultry", + "ParentCompany", + "ColdHouseSteward", + "PosCompany", + ]; + + const liveStockRoles = [ + "LiveStockProvinceJahad", + "Union", + "Cooperative", + "Rancher", + ]; + + const isPoultry = userRoles?.some((role) => poultryRoles?.includes(role)); + + const isLiveStock = userRoles?.some((role) => liveStockRoles?.includes(role)); + + if (isPoultry && isLiveStock) { + return "Both"; + } else if (isPoultry) { + return "Poultry"; + } else if (isLiveStock) { + return "LiveStock"; + } else { + return ""; + } +} + +export function getLiveStockRoles(userRoles) { + const liveStockRoles = [ + "LiveStockProvinceJahad", + "Union", + "Cooperative", + "Rancher", + ]; + + return userRoles.filter((role) => liveStockRoles.includes(role)); +} + +export function getBarSquareRoles(userRoles) { + const liveStockRoles = ["BarSquareProvinceJahad"]; + + return userRoles.filter((role) => liveStockRoles.includes(role)); +} + +export function getPoultryRoles(userRoles) { + const poultryRoles = [ + "CityOperator", + "Poultry", + "ProvinceOperator", + "KillHouse", + "KillHouseVet", + "VetFarm", + "ProvinceFinancial", + "ProvinceInspector", + "VetSupervisor", + "Commerce", + "CityCommerce", + "CityVet", + "CityJahad", + "Observatory", + "ProvinceSupervisor", + "Guilds", + "GuildRoom", + "LiveStockSupport", + "SuperAdmin", + "ChainCompany", + "AdminX", + "Supporter", + "Dispenser", + "CityPoultry", + "ParentCompany", + "ColdHouseSteward", + "PosCompany", + "Steward", + ]; + + return userRoles.filter((role) => poultryRoles.includes(role)); +} diff --git a/src/utils/groupBy.js b/src/utils/groupBy.js new file mode 100644 index 0000000..782f1f4 --- /dev/null +++ b/src/utils/groupBy.js @@ -0,0 +1,8 @@ +export function groupBy(array, key) { + return array.reduce((hash, obj) => { + if (obj[key] === undefined) return hash; + return Object.assign(hash, { + [obj[key]]: (hash[obj[key]] || []).concat(obj), + }); + }, {}); +} diff --git a/src/utils/isDateOlderThanToday.js b/src/utils/isDateOlderThanToday.js new file mode 100644 index 0000000..aeac923 --- /dev/null +++ b/src/utils/isDateOlderThanToday.js @@ -0,0 +1,14 @@ +export function isDateOlderThanToday(date) { + // Create a Date object for today's date + var today = new Date(); + today.toLocaleString("fa-IR", { timeZone: "Asia/Tehran" }); + + // Create a Date object for the input date + + // Compare the input date with today's date + if (date < today) { + return true; // The input date is older than today + } else { + return false; // The input date is today or a future date + } +} diff --git a/src/utils/isValidIndexWeight.js b/src/utils/isValidIndexWeight.js new file mode 100644 index 0000000..58911a7 --- /dev/null +++ b/src/utils/isValidIndexWeight.js @@ -0,0 +1,16 @@ +export const isValidIndexWeight = (weightRange, age, weight) => { + if ( + !Array.isArray(weightRange) || + typeof age !== "number" || + typeof weight !== "number" + ) { + return false; + } + + const range = weightRange.find((r) => age >= r.fromAge && age <= r.toAge); + + if (!range) return false; + + const maxAllowedWeight = range.toWeight * 1.2; + return weight >= range.fromWeight && weight <= maxAllowedWeight; +}; diff --git a/src/utils/isValidNationalId.js b/src/utils/isValidNationalId.js new file mode 100644 index 0000000..35ff216 --- /dev/null +++ b/src/utils/isValidNationalId.js @@ -0,0 +1,14 @@ +export const isValidNationalId = (id) => { + let s = 0; + if (id.toString().length === 10) { + for (let i = 0; i < 10; i++) s = s + String(id).substr(i, 1) * (10 - i); + + if (s % 11 === 0) { + return true; + } else { + return false; + } + } else { + return false; + } +}; diff --git a/src/utils/jalali.js b/src/utils/jalali.js new file mode 100644 index 0000000..8898e26 --- /dev/null +++ b/src/utils/jalali.js @@ -0,0 +1,21 @@ +import { toJalali as toJalaali, toGregorian } from "date-fns-jalali/_jalali"; + +export const toJalali = (date) => { + const gregorianDate = date instanceof Date ? date : new Date(date); + const jalali = toJalaali( + gregorianDate.getFullYear(), + gregorianDate.getMonth() + 1, + gregorianDate.getDate() + ); + return { + jy: jalali.jy, + jm: jalali.jm - 1, + jd: jalali.jd, + }; +}; + +export const fromJalali = (jy, jm, jd) => { + const month = jm >= 1 && jm <= 12 ? jm : jm + 1; + const gregorian = toGregorian(jy, month, jd); + return new Date(gregorian.gy, gregorian.gm - 1, gregorian.gd); +}; diff --git a/src/utils/lazyRetry.js b/src/utils/lazyRetry.js new file mode 100644 index 0000000..4b811c7 --- /dev/null +++ b/src/utils/lazyRetry.js @@ -0,0 +1,19 @@ +export const lazyRetry = function (componentImport) { + return new Promise((resolve, reject) => { + const hasRefreshed = JSON.parse( + window.sessionStorage.getItem("retry-lazy-refreshed") || "false" + ); + componentImport() + .then((component) => { + window.sessionStorage.setItem("retry-lazy-refreshed", "false"); + resolve(component); + }) + .catch((error) => { + if (!hasRefreshed) { + window.sessionStorage.setItem("retry-lazy-refreshed", "true"); + return window.location.reload(); + } + reject(error); + }); + }); +}; diff --git a/src/utils/numberDigitSeperator.js b/src/utils/numberDigitSeperator.js new file mode 100644 index 0000000..5da303c --- /dev/null +++ b/src/utils/numberDigitSeperator.js @@ -0,0 +1,10 @@ +export const numberDigitSeperator = (inputNumber) => { + let formetedNumber = Number(inputNumber) + .toFixed(2) + .replace(/\d(?=(\d{3})+\.)/g, "$&,"); + let splitArray = formetedNumber.split("."); + if (splitArray.length > 1) { + formetedNumber = splitArray[0]; + } + return formetedNumber; +}; diff --git a/src/utils/resizeImage.js b/src/utils/resizeImage.js new file mode 100644 index 0000000..15a90c1 --- /dev/null +++ b/src/utils/resizeImage.js @@ -0,0 +1,38 @@ +export const resizeImage = (file, callback) => { + const img = new Image(); + img.src = URL.createObjectURL(file); + let width = 1500; + let height = 1500; + img.onload = () => { + // if (width > height) { + // if (width > 3000) { + // height = Math.round(height / 2); + // width = 3000; + // } + // } else { + // if (height > 3000) { + // width = Math.round(width / 2); + // height = 3000; + // } + // } + + const canvas = document.createElement("canvas"); + canvas.width = width; + canvas.height = height; + + const ctx = canvas.getContext("2d"); + ctx.drawImage(img, 0, 0, width, height); + + canvas.toBlob( + (blob) => { + const reader = new FileReader(); + reader.onloadend = () => { + callback(reader.result); + }; + reader.readAsDataURL(blob); + }, + file.type, + 0.8 + ); + }; +}; diff --git a/src/utils/reverseNumbers.js b/src/utils/reverseNumbers.js new file mode 100644 index 0000000..0e8fd2e --- /dev/null +++ b/src/utils/reverseNumbers.js @@ -0,0 +1,7 @@ +export const reverseNumbers = (item) => { + const reversedText = item.replace(/\d+/g, (match) => { + return match.split("").reverse().join(""); + }); + + return reversedText; +}; diff --git a/src/utils/reverseToRtl.js b/src/utils/reverseToRtl.js new file mode 100644 index 0000000..e91585b --- /dev/null +++ b/src/utils/reverseToRtl.js @@ -0,0 +1,30 @@ +export function reverseToRtl(text) { + const regex = /(\d+(\.\d+)?)/g; + var reversedDecimal = ""; + reversedDecimal = text.replace(regex, (match) => { + if (match.includes(".")) { + const [integerPart, decimalPart] = match.split("."); + return ( + decimalPart.split("").reverse().join("") + + "." + + integerPart.split("").reverse().join("") + ); + } else { + return match.split("").reverse().join(""); + } + }); + + const datePattern = /\d{4}\/\d{2}\/\d{2}/g; + + const finaltext = reversedDecimal.replace(datePattern, (match) => { + const parts = match.split("/"); + if (parts.length === 3) { + const [year, month, day] = parts; + return `${day}/${month}/${year}`; + } else { + return match; + } + }); + + return finaltext; +} diff --git a/src/utils/showSnackbar.js b/src/utils/showSnackbar.js new file mode 100644 index 0000000..6dbfd14 --- /dev/null +++ b/src/utils/showSnackbar.js @@ -0,0 +1,27 @@ +import React from "react"; +import ReactDOM from "react-dom"; +import Snackbar from "@mui/material/Snackbar"; +import MuiAlert from "@mui/material/Alert"; + +export function showSnackbar(message, severity = "warning") { + const snackbarDiv = document.createElement("div"); + document.body.appendChild(snackbarDiv); + + const handleClose = () => { + ReactDOM.unmountComponentAtNode(snackbarDiv); + document.body.removeChild(snackbarDiv); + }; + + ReactDOM.render( + + + {message} + + , + snackbarDiv + ); +} diff --git a/src/utils/sortRoles.js b/src/utils/sortRoles.js new file mode 100644 index 0000000..b3bbe44 --- /dev/null +++ b/src/utils/sortRoles.js @@ -0,0 +1,35 @@ +export const sortRoles = (roles) => { + if (roles) { + const priorityRoles = [ + "AdminX", + "SuperAdmin", + "ProvinceOperator", + "LiveStockProvinceJahad", + "Union", + "Cooperative", + "Rancher", + "KillHouse", + "KillHouseVet", + "VetFarm", + "VetSupervisor", + "CityVet", + "ParentCompany", + "Steward", + "Guilds", + "ProvinceSupervisor", + "Commerce", + "PoultryScience", + ]; + return [...roles].sort((a, b) => { + const aIndex = priorityRoles.indexOf(a); + const bIndex = priorityRoles.indexOf(b); + if (aIndex !== -1 && bIndex !== -1) { + return aIndex - bIndex; + } + if (aIndex !== -1) return -1; + if (bIndex !== -1) return 1; + return a.localeCompare(b); + }); + } + return []; +}; diff --git a/src/utils/stringToColor.js b/src/utils/stringToColor.js new file mode 100644 index 0000000..41f937d --- /dev/null +++ b/src/utils/stringToColor.js @@ -0,0 +1,20 @@ +export function stringToColor(string) { + let hash = 0; + let i; + if (string) { + /* eslint-disable no-bitwise */ + for (i = 0; i < string.length; i += 1) { + hash = string.charCodeAt(i) + ((hash << 5) - hash); + } + + let color = "#"; + + for (i = 0; i < 3; i += 1) { + const value = (hash >> (i * 8)) & 0xff; + color += `00${value.toString(16)}`.slice(-2); + } + /* eslint-enable no-bitwise */ + return color; + } + return "red"; +} diff --git a/src/utils/toBase64.js b/src/utils/toBase64.js new file mode 100644 index 0000000..d20fe47 --- /dev/null +++ b/src/utils/toBase64.js @@ -0,0 +1,31 @@ +export const toBase64 = async (file) => { + const d = new Promise((resolve, reject) => { + const reader = new FileReader(); + reader.readAsDataURL(file); + reader.onload = () => resolve(reader.result); + reader.onerror = (error) => reject(error); + }); + return await d; +}; + +export const fixBase64 = (base64) => { + return base64.split(",").slice(1)[0]; +}; + +export const urlToBase64 = async (url) => { + try { + const response = await fetch(url); + if (!response.ok) { + throw new Error("Failed to fetch image: " + response.status); + } + const blob = await response.blob(); + const reader = new FileReader(); + reader.readAsDataURL(blob); + return new Promise((resolve) => { + reader.onloadend = () => resolve(reader.result); + }); + } catch (error) { + console.error("Error converting URL to base64:", error); + throw error; // Rethrow the error to propagate it further + } +}; diff --git a/src/utils/toCamelCase.js b/src/utils/toCamelCase.js new file mode 100644 index 0000000..166e4ba --- /dev/null +++ b/src/utils/toCamelCase.js @@ -0,0 +1,11 @@ +export function toCamelCase(str) { + return str.replace(/_([a-z])/g, function (match, letter) { + return letter.toUpperCase(); + }); +} + +export function toUnderscore(str) { + return str.replace(/[A-Z]/g, function (match) { + return "_" + match.toLowerCase(); + }); +} diff --git a/src/utils/toDDHHMMSS.js b/src/utils/toDDHHMMSS.js new file mode 100644 index 0000000..b292093 --- /dev/null +++ b/src/utils/toDDHHMMSS.js @@ -0,0 +1,18 @@ +export const toDDHHMMSS = (secs) => { + const seconds = Number(secs); + var d = Math.floor(seconds / (3600 * 24)); + var h = Math.floor((seconds % (3600 * 24)) / 3600); + var m = Math.floor((seconds % 3600) / 60); + // var s = Math.floor(seconds % 60); + + // var dDisplay = d > 0 ? d + (d === 1 ? " day, " : " days, ") : ""; + // var hDisplay = h > 0 ? h + (h === 1 ? " hour, " : " hours, ") : ""; + // var mDisplay = m > 0 ? m + (m === 1 ? " minute, " : " minutes, ") : ""; + // var sDisplay = s > 0 ? s + (s === 1 ? " second" : " seconds") : ""; + var dDisplay = d > 0 ? d + (d === 1 ? " روز " : " روز ") : ""; + var hDisplay = h > 0 ? h + (h === 1 ? " ساعت " : " ساعت ") : ""; + var mDisplay = m > 0 ? m + (m === 1 ? " دقیقه " : " دقیقه ") : ""; + // var sDisplay = s > 0 ? s + (s === 1 ? " ثانیه " : " ثانیه ") : ""; + // return dDisplay + hDisplay + mDisplay + sDisplay; + return dDisplay + hDisplay + mDisplay; +}; diff --git a/src/utils/toHHMMSS.js b/src/utils/toHHMMSS.js new file mode 100644 index 0000000..8f3a505 --- /dev/null +++ b/src/utils/toHHMMSS.js @@ -0,0 +1,11 @@ +export const toHHMMSS = (secs) => { + var sec_num = parseInt(secs, 10); + var hours = Math.floor(sec_num / 3600); + var minutes = Math.floor(sec_num / 60) % 60; + var seconds = sec_num % 60; + + return [hours, minutes, seconds] + .map((v) => (v < 10 ? "0" + v : v)) + .filter((v, i) => v !== "00" || i > 0) + .join(":"); +}; diff --git a/src/utils/usageTracker.js b/src/utils/usageTracker.js new file mode 100644 index 0000000..58f1c2d --- /dev/null +++ b/src/utils/usageTracker.js @@ -0,0 +1,159 @@ +/** + * Usage Tracker Utility + * Tracks user clicks on dashboard items and sorts them by usage frequency + */ + +const STORAGE_KEY = "dashboard_usage_stats"; + +/** + * Get all usage statistics from localStorage + * @returns {Object} Usage statistics object + */ +export const getUsageStats = () => { + try { + const stats = localStorage.getItem(STORAGE_KEY); + return stats ? JSON.parse(stats) : {}; + } catch (error) { + console.error("Error reading usage stats:", error); + return {}; + } +}; + +/** + * Save usage statistics to localStorage + * @param {Object} stats - Usage statistics object + */ +const saveUsageStats = (stats) => { + try { + localStorage.setItem(STORAGE_KEY, JSON.stringify(stats)); + } catch (error) { + console.error("Error saving usage stats:", error); + } +}; + +/** + * Get click count for a specific item in a role + * @param {string} role - User role (e.g., 'admix', 'Province') + * @param {string} itemKey - Unique identifier for the item (route or text) + * @returns {number} Click count + */ +export const getItemClickCount = (role, itemKey) => { + const stats = getUsageStats(); + return stats[role]?.[itemKey] || 0; +}; + +/** + * Increment click count for a specific item + * @param {string} role - User role (e.g., 'admix', 'Province') + * @param {string} itemKey - Unique identifier for the item (route or text) + */ +export const trackItemClick = (role, itemKey) => { + const stats = getUsageStats(); + + // Initialize role object if it doesn't exist + if (!stats[role]) { + stats[role] = {}; + } + + // Increment click count + stats[role][itemKey] = (stats[role][itemKey] || 0) + 1; + + saveUsageStats(stats); +}; + +/** + * Sort items array by their usage (click count) + * @param {Array} items - Array of items with route or text property + * @param {string} role - User role + * @param {string} keyField - Field to use as key (default: 'route') + * @returns {Array} Sorted items array (most used first) + */ +export const sortItemsByUsage = (items, role, keyField = "route") => { + if (!items || !Array.isArray(items)) return items; + + const stats = getUsageStats(); + const roleStats = stats[role] || {}; + + return [...items].sort((a, b) => { + const keyA = a[keyField] || a.text || ""; + const keyB = b[keyField] || b.text || ""; + + const countA = roleStats[keyA] || 0; + const countB = roleStats[keyB] || 0; + + // Sort descending (most clicked first) + return countB - countA; + }); +}; + +/** + * Get usage statistics for a specific role + * @param {string} role - User role + * @returns {Object} Usage statistics for the role + */ +export const getRoleUsageStats = (role) => { + const stats = getUsageStats(); + return stats[role] || {}; +}; + +/** + * Clear all usage statistics + */ +export const clearUsageStats = () => { + try { + localStorage.removeItem(STORAGE_KEY); + } catch (error) { + console.error("Error clearing usage stats:", error); + } +}; + +/** + * Clear usage statistics for a specific role + * @param {string} role - User role + */ +export const clearRoleUsageStats = (role) => { + const stats = getUsageStats(); + if (stats[role]) { + delete stats[role]; + saveUsageStats(stats); + } +}; + +/** + * Get top N most used items for a role + * @param {string} role - User role + * @param {number} limit - Number of top items to return + * @returns {Array} Array of {itemKey, count} objects + */ +export const getTopUsedItems = (role, limit = 5) => { + const roleStats = getRoleUsageStats(role); + + return Object.entries(roleStats) + .map(([itemKey, count]) => ({ itemKey, count })) + .sort((a, b) => b.count - a.count) + .slice(0, limit); +}; + +/** + * Export usage statistics (for backup or analysis) + * @returns {string} JSON string of all statistics + */ +export const exportUsageStats = () => { + const stats = getUsageStats(); + return JSON.stringify(stats, null, 2); +}; + +/** + * Import usage statistics (from backup) + * @param {string} jsonString - JSON string of statistics + */ +export const importUsageStats = (jsonString) => { + try { + const stats = JSON.parse(jsonString); + saveUsageStats(stats); + return true; + } catch (error) { + console.error("Error importing usage stats:", error); + return false; + } +}; diff --git a/src/version.txt b/src/version.txt new file mode 100644 index 0000000..6b4f41a --- /dev/null +++ b/src/version.txt @@ -0,0 +1 @@ +6.95 \ No newline at end of file diff --git a/users.txt b/users.txt new file mode 100644 index 0000000..f69ac8b --- /dev/null +++ b/users.txt @@ -0,0 +1,40 @@ +09187040838 + +4948 + +همدان + + +09368154593 + +4035 + +اراک + + +09163697126 + +2025 + +ادمین ایکس همدان + + + +09352322002 + +2025 + +شرکت مادر + + + +09163697127 + +1404 + +بوشهر + + + +ادمین همدان :09000000001 رمز 2020 +ادمین اراک : 09000000002 رمز 2020 diff --git a/vite-env.d.ts b/vite-env.d.ts new file mode 100644 index 0000000..03f1fa5 --- /dev/null +++ b/vite-env.d.ts @@ -0,0 +1,11 @@ +/// +/// + +interface ImportMetaEnv { + readonly VITE_API_URL?: string; + // Add more env variables here as needed +} + +interface ImportMeta { + readonly env: ImportMetaEnv; +} diff --git a/vite.config.js b/vite.config.js new file mode 100644 index 0000000..5059958 --- /dev/null +++ b/vite.config.js @@ -0,0 +1,148 @@ +import { defineConfig, transformWithEsbuild } from "vite"; +import react from "@vitejs/plugin-react"; +import { VitePWA } from "vite-plugin-pwa"; +import path from "path"; + +export default defineConfig({ + plugins: [ + { + name: "load-js-files-as-jsx", + enforce: "pre", + async transform(code, id) { + if (!id.match(/src\/.*\.js$/)) return null; + return transformWithEsbuild(code, id, { + loader: "jsx", + jsx: "automatic", + }); + }, + }, + react({ + fastRefresh: true, + include: /\.js$/, + jsxRuntime: "automatic", + }), + VitePWA({ + registerType: "autoUpdate", + includeAssets: [ + "favicon.ico", + "android-chrome-192x192.png", + "android-chrome-512x512.png", + "apple-touch-icon.png", + "logo192.png", + "logo512.png", + ], + manifest: { + short_name: "سامانه رصدیار", + name: "سامانه رصدیار", + icons: [ + { + src: "/android-chrome-192x192.png", + sizes: "192x192", + type: "image/png", + }, + { + src: "/android-chrome-512x512.png", + sizes: "512x512", + type: "image/png", + }, + ], + start_url: ".", + display: "standalone", + theme_color: "#000000", + background_color: "#ffffff", + }, + workbox: { + globPatterns: [ + "**/*.{js,css,html,ico,png,svg,jpg,jpeg,webp,woff,woff2}", + ], + runtimeCaching: [ + { + urlPattern: /^https:\/\/.*\.(?:png|jpg|jpeg|svg|gif|webp)$/, + handler: "CacheFirst", + options: { + cacheName: "images-cache", + expiration: { + maxEntries: 100, + maxAgeSeconds: 60 * 60 * 24 * 30, + }, + }, + }, + ], + }, + }), + ], + + preview: { + allowedHosts: ["rasadyar.com", "rasadyar.net", "rasadyar.ir", "dev.rasadyar.com"], + }, + + // Resolve configuration + resolve: { + alias: { + "@": path.resolve(__dirname, "./src"), + }, + }, + + server: { + port: 3000, + open: true, + host: true, + hmr: { + overlay: true, + }, + watch: { + usePolling: false, + interval: 100, + }, + }, + + build: { + outDir: "build", + sourcemap: false, + + chunkSizeWarningLimit: 1000, + rollupOptions: { + output: { + manualChunks: { + "react-vendor": ["react", "react-dom", "react-router-dom"], + "mui-vendor": [ + "@mui/material", + "@mui/icons-material", + "@mui/lab", + "@emotion/react", + "@emotion/styled", + ], + "redux-vendor": ["@reduxjs/toolkit", "react-redux", "redux-persist"], + "chart-vendor": [ + "chart.js", + "react-chartjs-2", + "echarts", + "echarts-for-react", + ], + }, + }, + }, + }, + + optimizeDeps: { + include: [ + "react", + "react-dom", + "react-router-dom", + "@mui/material", + "@mui/icons-material", + "@reduxjs/toolkit", + "react-redux", + ], + esbuildOptions: { + loader: { + ".js": "jsx", + }, + jsx: "automatic", + }, + }, + + define: { + "process.env": {}, + }, +});