Compare commits
287 commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a69f51b61a | ||
|
|
1069076e48 | ||
|
|
a2ded8f2b2 | ||
|
|
4fa91c3c88 | ||
|
|
d49d28ffc6 | ||
|
|
ca569455dd | ||
| b01f0fb9dd | |||
| cc6ad2e6e1 | |||
| ea1d6c6bba | |||
| 132c25a75e | |||
| c235055b62 | |||
| 4eaebf86c0 | |||
| 61641660e6 | |||
| 29e5728220 | |||
|
|
feda6e7613 | ||
|
|
07804370d5 | ||
|
|
c1a244a4f4 | ||
|
|
700992e89f | ||
|
|
c26b8c071d | ||
|
|
eeddf109f5 | ||
|
|
25188fcbcf | ||
|
|
3e954bb51b | ||
|
|
d8e00b3833 | ||
|
|
820eb7b62c | ||
|
|
85acd0be1e | ||
|
|
56c96cc794 | ||
|
|
b5bf949dca | ||
|
|
a226e37086 | ||
|
|
49ee59295b | ||
|
|
8f7ef0ed92 | ||
|
|
6e12256a33 | ||
|
|
5ef171c666 | ||
|
|
15eef6a692 | ||
|
|
8f5f01df8e | ||
|
|
6ceb32fdca | ||
|
|
e6194a3d73 | ||
|
|
1defb88357 | ||
|
|
c5cb57d88a | ||
|
|
0787d77beb | ||
|
|
69b63d0aae | ||
|
|
01f3c8a319 | ||
|
|
47018bad75 | ||
|
|
b23a1ab795 | ||
|
|
c4d45c2501 | ||
|
|
1920acf6e6 | ||
|
|
2a56bf4c67 | ||
|
|
25e58a6ed2 | ||
|
|
67d4debcdb | ||
|
|
e170cf351e | ||
|
|
1d28cbe7cd | ||
|
|
cfeca2bd21 | ||
|
|
4f21f46464 | ||
|
|
f2965dd9ef | ||
|
|
dac9b12106 | ||
|
|
d20d3bd710 | ||
|
|
6e8a296205 | ||
|
|
83400e1e20 | ||
|
|
e7ca76950a | ||
|
|
ff3550893a | ||
|
|
93202edd09 | ||
|
|
285e12bde4 | ||
|
|
93294ef6de | ||
|
|
06f71db87b | ||
|
|
a2fe764732 | ||
|
|
a831803437 | ||
|
|
e815b89e53 | ||
|
|
215fb1327e | ||
|
|
92607611dd | ||
|
|
00a9fc7d76 | ||
|
|
ffaaf1ec1b | ||
|
|
dbd4c88e74 | ||
|
|
f7bac9c221 | ||
|
|
5354adab6e | ||
|
|
8887aabac4 | ||
|
|
faa63e271f | ||
|
|
bd5862d592 | ||
|
|
b6fe43cdcf | ||
|
|
647943da11 | ||
|
|
0aea086f26 | ||
|
|
2b240ed4ca | ||
|
|
b7b4013897 | ||
|
|
8fbaa234b4 | ||
|
|
d8796ee78a | ||
|
|
d1d9ffd418 | ||
|
|
45849688f6 | ||
|
|
5d5a4c828f | ||
|
|
58c116f2f0 | ||
|
|
cc9521c233 | ||
|
|
b4f343940e | ||
|
|
de20063c5f | ||
|
|
fd11b966e4 | ||
|
|
d9357de45f | ||
|
|
aa8ac3fec5 | ||
|
|
b36aa19028 | ||
|
|
16e4e4ee19 | ||
|
|
151d9e04a9 | ||
|
|
bd343277cc | ||
|
|
44035c9589 | ||
|
|
14de384af1 | ||
|
|
b6b06d6cf8 | ||
|
|
9c91351388 | ||
|
|
d5d9ef6fdc | ||
|
|
b31f87bf8b | ||
|
|
ace4e0cce8 | ||
|
|
c9f25b17aa | ||
|
|
ecc2b7059e | ||
|
|
3ab1a2244e | ||
|
|
7a2318b6a3 | ||
|
|
ded7cd7266 | ||
|
|
1aaadb88d0 | ||
|
|
b3fb0301f8 | ||
|
|
09414e228f | ||
|
|
ff123f6769 | ||
|
|
811795abd8 | ||
|
|
de13bde18f | ||
|
|
18b83b7197 | ||
|
|
93331aaca1 | ||
|
|
d61da12e63 | ||
|
|
11a999ce42 | ||
|
|
1b9a5dacf8 | ||
|
|
e76312fad2 | ||
|
|
0f008b0db4 | ||
|
|
06694f0a48 | ||
|
|
448369c7ab | ||
|
|
eeb467d1f0 | ||
|
|
4a23d74917 | ||
|
|
b9f43428d8 | ||
|
|
5527740c26 | ||
|
|
83c4e4d7c4 | ||
|
|
2f8a53c653 | ||
|
|
351126ebf8 | ||
|
|
da8074c5a4 | ||
|
|
36494a7944 | ||
|
|
c4473115d2 | ||
|
|
30c113a30c | ||
|
|
1ac10f9276 | ||
|
|
515bbf4758 | ||
|
|
76cc3a5cd8 | ||
|
|
978cfc2109 | ||
|
|
8caaff989c | ||
|
|
fff623144a | ||
|
|
927ae02240 | ||
|
|
281d23b03e | ||
|
|
ed7ed6f55e | ||
|
|
7df0fe4634 | ||
|
|
ced124b60e | ||
|
|
187b96fbaf | ||
|
|
a3a84446f8 | ||
|
|
af090bbef7 | ||
|
|
a269295a79 | ||
|
|
c828952e7b | ||
|
|
6a60f00fbe | ||
|
|
7cfe36b40f | ||
|
|
89609454ad | ||
|
|
b178539626 | ||
|
|
688ac1a2e2 | ||
|
|
6fdcdd1a2a | ||
|
|
f9c19f2334 | ||
|
|
64d4397c0c | ||
|
|
0f1f258706 | ||
|
|
20546b8625 | ||
|
|
c74935eb99 | ||
|
|
7eeeb54ccd | ||
|
|
699d9acb07 | ||
|
|
b494c36849 | ||
|
|
1ea25ed3c7 | ||
|
|
dd3a4b53c2 | ||
|
|
074322aca5 | ||
|
|
bddd622895 | ||
|
|
5d3896c261 | ||
|
|
48c6b1feaf | ||
|
|
8be2809dc6 | ||
|
|
8949a22b5f | ||
|
|
683bc1c8f3 | ||
|
|
6ca2fe1779 | ||
|
|
a9f28657e5 | ||
|
|
acef67939a | ||
|
|
b340a252ff | ||
|
|
88531b4906 | ||
|
|
b472ab94d8 | ||
|
|
d9f44df691 | ||
|
|
7d2e072c9e | ||
|
|
9e3e855485 | ||
|
|
7b3193fa82 | ||
|
|
becc1234d9 | ||
|
|
ce931c6dcf | ||
|
|
5778c7aa02 | ||
|
|
9c835ff767 | ||
|
|
46787d2677 | ||
|
|
f23aa94101 | ||
|
|
760e68737b | ||
|
|
7b5b7d5ada | ||
|
|
8fae9e9e4c | ||
|
|
36997e6a28 | ||
|
|
b0e381768a | ||
|
|
44d60527b8 | ||
|
|
132ec57bde | ||
|
|
5922dbf143 | ||
|
|
680afd45f3 | ||
|
|
0939ae3cca | ||
|
|
2a7cd8bb9f | ||
|
|
f528c6a5f8 | ||
|
|
bbeef29646 | ||
|
|
ea360d9263 | ||
|
|
ff4167aa5a | ||
|
|
d57e1c55af | ||
|
|
a571775f33 | ||
|
|
8814ca0a46 | ||
|
|
076398d1c0 | ||
|
|
996a0594a7 | ||
|
|
cbbb389a47 | ||
|
|
0ff4de2b1f | ||
|
|
9eaccbb15a | ||
|
|
2f860b9a42 | ||
|
|
f56ef0999e | ||
|
|
9c6842bc56 | ||
|
|
9183822b72 | ||
|
|
031d2b25b5 | ||
|
|
96ea1483f9 | ||
|
|
0fd22a9a82 | ||
|
|
e422d5dfd4 | ||
|
|
21c839f90d | ||
|
|
e6135ab857 | ||
|
|
391d99528c | ||
|
|
0300fada45 | ||
|
|
5f3d03fd96 | ||
|
|
05f0e2c229 | ||
|
|
d504821bea | ||
|
|
a53acba571 | ||
|
|
60cff329fd | ||
|
|
cf2f6bbf76 | ||
|
|
2bdd7f639b | ||
|
|
3c1958ea75 | ||
|
|
a6639cb87e | ||
|
|
394d558cf1 | ||
|
|
513e0c25a4 | ||
|
|
186a271540 | ||
|
|
d60aa2c35c | ||
|
|
702504c539 | ||
|
|
12fbf8d67f | ||
|
|
fe254722b0 | ||
|
|
095c420191 | ||
|
|
932a5bb84e | ||
|
|
3b11316017 | ||
|
|
c9fcb85fff | ||
|
|
fdb5ddabd7 | ||
|
|
fd0f14fc9c | ||
|
|
2b494c7324 | ||
|
|
ae4da57006 | ||
|
|
13bc1d9ce5 | ||
|
|
78d1ab42d4 | ||
|
|
efc930a2db | ||
|
|
7f7d9d68f2 | ||
|
|
cd85772884 | ||
|
|
8100b8ccf0 | ||
|
|
02f515629e | ||
|
|
cd2af65e8a | ||
|
|
5198fe6264 | ||
|
|
282ebffbb8 | ||
|
|
e57c36ca8b | ||
|
|
1e1b6be8ea | ||
|
|
0406c5c97f | ||
|
|
71ccade4ad | ||
|
|
7cdd5df10a | ||
|
|
04f337b21d | ||
|
|
ef28c99ed3 | ||
|
|
b59dcf576c | ||
|
|
7000243424 | ||
|
|
6adff1d5a5 | ||
|
|
87273397b2 | ||
|
|
dcf222e1a2 | ||
|
|
75e65e7ebe | ||
|
|
4e57bfdb15 | ||
|
|
9ac4da9a5c | ||
|
|
974386cc7a | ||
|
|
b1071c57de | ||
|
|
255c5f245b | ||
|
|
f11ed1dc17 | ||
|
|
017fcec47a | ||
|
|
a3cf5f0ee2 | ||
|
|
72f44ef3a3 | ||
|
|
6fa57cd878 | ||
|
|
6e548a7823 | ||
|
|
d02f2df5b3 | ||
|
|
1974969ccc | ||
|
|
391b76d75a | ||
|
|
c5182b65b4 |
766 changed files with 18659 additions and 106346 deletions
44
.env.example
44
.env.example
|
|
@ -14,18 +14,9 @@ DB_DATABASE=laravel
|
||||||
DB_USERNAME=root
|
DB_USERNAME=root
|
||||||
DB_PASSWORD=
|
DB_PASSWORD=
|
||||||
|
|
||||||
DB_CONNECTION_OLD=mysql
|
|
||||||
DB_HOST_OLD=127.0.0.1
|
|
||||||
DB_PORT_OLD=3306
|
|
||||||
DB_DATABASE_OLD=ldccrm_12_2020
|
|
||||||
DB_USERNAME_OLD=root
|
|
||||||
DB_PASSWORD_OLD=
|
|
||||||
|
|
||||||
MIGRATIONPAGINATION=20000
|
|
||||||
|
|
||||||
BROADCAST_DRIVER=log
|
BROADCAST_DRIVER=log
|
||||||
CACHE_DRIVER=apc
|
CACHE_DRIVER=file
|
||||||
QUEUE_CONNECTION=sync
|
QUEUE_CONNECTION=database
|
||||||
SESSION_DRIVER=file
|
SESSION_DRIVER=file
|
||||||
SESSION_LIFETIME=120
|
SESSION_LIFETIME=120
|
||||||
|
|
||||||
|
|
@ -34,26 +25,27 @@ REDIS_PASSWORD=null
|
||||||
REDIS_PORT=6379
|
REDIS_PORT=6379
|
||||||
|
|
||||||
MAIL_MAILER=smtp
|
MAIL_MAILER=smtp
|
||||||
MAIL_HOST=smtp.mailtrap.io
|
MAIL_HOST=dev-mailpit
|
||||||
MAIL_PORT=2525
|
MAIL_PORT=1025
|
||||||
MAIL_USERNAME=null
|
MAIL_USERNAME=null
|
||||||
MAIL_PASSWORD=null
|
MAIL_PASSWORD=null
|
||||||
MAIL_ENCRYPTION=null
|
MAIL_ENCRYPTION=null
|
||||||
MAIL_FROM_ADDRESS=null
|
MAIL_FROM_ADDRESS=null
|
||||||
MAIL_FROM_NAME="${APP_NAME}"
|
MAIL_FROM_NAME="${APP_NAME}"
|
||||||
|
MAIL_DIGITAL_SERVICE=""
|
||||||
AWS_ACCESS_KEY_ID=
|
|
||||||
AWS_SECRET_ACCESS_KEY=
|
|
||||||
AWS_DEFAULT_REGION=us-east-1
|
|
||||||
AWS_BUCKET=
|
|
||||||
|
|
||||||
PUSHER_APP_ID=
|
|
||||||
PUSHER_APP_KEY=
|
|
||||||
PUSHER_APP_SECRET=
|
|
||||||
PUSHER_APP_CLUSTER=mt1
|
|
||||||
|
|
||||||
MIX_PUSHER_APP_KEY="${PUSHER_APP_KEY}"
|
|
||||||
MIX_PUSHER_APP_CLUSTER="${PUSHER_APP_CLUSTER}"
|
|
||||||
|
|
||||||
# Sentry
|
# Sentry
|
||||||
SENTRY_LARAVEL_DSN=
|
SENTRY_LARAVEL_DSN=
|
||||||
|
|
||||||
|
# UWIL ADMIN SECURE
|
||||||
|
# - LIST SEPARATED WITH ',' (Required)
|
||||||
|
UWIL_ADMIN_SECURE_CIDR_LIST=""
|
||||||
|
# - LIST SEPARATED WITH ',' (Optional)
|
||||||
|
UWIL_ADMIN_SECURE_CIDR_PROJECT_ALLOWED_LIST=""
|
||||||
|
|
||||||
|
# SAML
|
||||||
|
SAML2_DEFAULT_TENANT_UUID=
|
||||||
|
SAML2_SP_CERT_x509=
|
||||||
|
SAML2_SP_CERT_PRIVATEKEY=
|
||||||
|
SAML2_CONTACT_TECHNICAL_EMAIL=
|
||||||
|
SAML2_CONTACT_SUPPORT_EMAIL=
|
||||||
|
|
|
||||||
|
|
@ -14,15 +14,6 @@ DB_DATABASE=testing_ldccrm_12_2020
|
||||||
DB_USERNAME=root
|
DB_USERNAME=root
|
||||||
DB_PASSWORD=DBPASSWORD
|
DB_PASSWORD=DBPASSWORD
|
||||||
|
|
||||||
DB_CONNECTION_OLD=mysql
|
|
||||||
DB_HOST_OLD=127.0.0.1
|
|
||||||
DB_PORT_OLD=3306
|
|
||||||
DB_DATABASE_OLD="ldc-crm"
|
|
||||||
DB_USERNAME_OLD=root
|
|
||||||
DB_PASSWORD_OLD=
|
|
||||||
|
|
||||||
MIGRATIONPAGINATION=20000
|
|
||||||
|
|
||||||
BROADCAST_DRIVER=log
|
BROADCAST_DRIVER=log
|
||||||
CACHE_DRIVER=file
|
CACHE_DRIVER=file
|
||||||
QUEUE_CONNECTION=database
|
QUEUE_CONNECTION=database
|
||||||
|
|
|
||||||
5
.gitignore
vendored
5
.gitignore
vendored
|
|
@ -9,6 +9,7 @@
|
||||||
/.phpunit.cache
|
/.phpunit.cache
|
||||||
/.vscode
|
/.vscode
|
||||||
/node_modules
|
/node_modules
|
||||||
|
/bootstrap
|
||||||
/public/build
|
/public/build
|
||||||
/public/cache
|
/public/cache
|
||||||
/public/hot
|
/public/hot
|
||||||
|
|
@ -24,3 +25,7 @@ npm-debug.log
|
||||||
yarn-error.log
|
yarn-error.log
|
||||||
.npmrc
|
.npmrc
|
||||||
.phpdoc
|
.phpdoc
|
||||||
|
.zshrc
|
||||||
|
.npm/
|
||||||
|
.composer/
|
||||||
|
tests/coverage
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@ include:
|
||||||
file: "security/security.yml"
|
file: "security/security.yml"
|
||||||
- project: "ldc-web/shared-ci"
|
- project: "ldc-web/shared-ci"
|
||||||
ref: "main"
|
ref: "main"
|
||||||
file: "build/build.yml"
|
file: "build/docker-multistage.yml"
|
||||||
- project: "ldc-web/shared-ci"
|
- project: "ldc-web/shared-ci"
|
||||||
ref: "main"
|
ref: "main"
|
||||||
file: "test/test.yml"
|
file: "test/test.yml"
|
||||||
|
|
|
||||||
3
.husky/commit-msg
Normal file
3
.husky/commit-msg
Normal file
|
|
@ -0,0 +1,3 @@
|
||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
npx --no -- commitlint --config node_modules/@uwil/husky-config/commitlint.config.cjs --edit $1
|
||||||
3
.vscode/settings.json
vendored
3
.vscode/settings.json
vendored
|
|
@ -1,6 +1,5 @@
|
||||||
|
|
||||||
{
|
{
|
||||||
"phpcs.executablePath": "vendor/bin/phpcs",
|
|
||||||
"workbench.colorCustomizations": {
|
"workbench.colorCustomizations": {
|
||||||
"activityBar.activeBackground": "#8dc952",
|
"activityBar.activeBackground": "#8dc952",
|
||||||
"activityBar.activeBorder": "#3d7fc2",
|
"activityBar.activeBorder": "#3d7fc2",
|
||||||
|
|
@ -22,5 +21,5 @@
|
||||||
"commandCenter.border": "#15202b99"
|
"commandCenter.border": "#15202b99"
|
||||||
},
|
},
|
||||||
"peacock.remoteColor": "#73b137",
|
"peacock.remoteColor": "#73b137",
|
||||||
"intelephense.environment.phpVersion": "8.2"
|
"intelephense.environment.phpVersion": "8.5"
|
||||||
}
|
}
|
||||||
|
|
|
||||||
53
Dockerfile
53
Dockerfile
|
|
@ -1,7 +1,50 @@
|
||||||
FROM registry.s-web.fr/ldc-web/projets/ldc-web-images-docker/ldcweb-production-8.2:latest
|
ARG PHP_8_5_TAG=latest
|
||||||
COPY --chown=www-data:www-data . /app/srcs
|
|
||||||
COPY --chown=www-data:www-data ./public /app/srcs/public
|
FROM composer:2.8 AS vendor
|
||||||
COPY --chown=www-data:www-data ./vendor /app/srcs/vendor
|
|
||||||
|
WORKDIR /app
|
||||||
|
|
||||||
|
ARG GITLAB_USER
|
||||||
|
ARG GITLAB_PASSWORD
|
||||||
|
|
||||||
|
COPY database/ database/
|
||||||
|
|
||||||
|
COPY composer.json composer.json
|
||||||
|
COPY composer.lock composer.lock
|
||||||
|
|
||||||
|
RUN composer config gitlab-token.lab.s-web.fr "${GITLAB_USER}" "${GITLAB_PASSWORD}"
|
||||||
|
RUN composer install \
|
||||||
|
--ignore-platform-reqs \
|
||||||
|
--no-interaction \
|
||||||
|
--no-plugins \
|
||||||
|
--no-scripts \
|
||||||
|
--no-dev \
|
||||||
|
--prefer-dist
|
||||||
|
|
||||||
|
FROM node:20.18 AS frontend
|
||||||
|
|
||||||
|
ARG GITLAB_PASSWORD
|
||||||
|
|
||||||
|
RUN mkdir -p /app/public/build
|
||||||
|
|
||||||
|
COPY package*.json tsconfig.json vite.config.ts .eslintrc.json .stylelintrc.json /app/
|
||||||
|
COPY resources/ /app/resources/
|
||||||
|
WORKDIR /app
|
||||||
|
RUN npm config set @ldc-web:registry https://lab.s-web.fr/api/v4/packages/npm/
|
||||||
|
RUN npm config set -- '//lab.s-web.fr/api/v4/packages/npm/:_authToken' "${GITLAB_PASSWORD}"
|
||||||
|
RUN npm config set @uwil:registry https://lab.s-web.fr/api/v4/groups/ldc-web/-/packages/npm/
|
||||||
|
RUN npm config set -- '//lab.s-web.fr/api/v4/groups/ldc-web/-/packages/npm/:_authToken' "${GITLAB_PASSWORD}"
|
||||||
|
RUN npm ci --no-audit --no-fund --loglevel=error && npm run prod
|
||||||
|
|
||||||
|
ARG PHP_8_5_TAG
|
||||||
|
FROM registry.s-web.fr/ldc-web/projets/ldc-web-images-docker/uwil-production-8.5:${PHP_8_5_TAG}
|
||||||
|
|
||||||
|
ARG USER=www-data
|
||||||
|
|
||||||
|
COPY --chown=${USER}:${USER} . /app/srcs
|
||||||
|
COPY --from=vendor --chown=${USER}:${USER} /app/vendor/ /app/srcs/vendor/
|
||||||
|
COPY --from=frontend --chown=${USER}:${USER} /app/public/build/ /app/srcs/public/build/
|
||||||
|
|
||||||
USER root
|
USER root
|
||||||
RUN chmod -R 755 /app/srcs/storage
|
RUN chmod -R 755 /app/srcs/storage
|
||||||
USER www-data
|
USER ${USER}
|
||||||
|
|
|
||||||
|
|
@ -1,69 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
use phpseclib3\Crypt\Rijndael;
|
|
||||||
|
|
||||||
class CPlatosChiffrement
|
|
||||||
{
|
|
||||||
private static $cipher = MCRYPT_RIJNDAEL_128; // Algorithme utilisé pour le cryptage des blocs
|
|
||||||
//private static $key = "yY75y2kLQ"; // Clé de cryptage PROD
|
|
||||||
private static $key = "123456789"; // Clé de cryptage DEV
|
|
||||||
private static $mode = 'cbc'; // Mode opératoire (traitement des blocs)
|
|
||||||
|
|
||||||
public static function crypt($data)
|
|
||||||
{
|
|
||||||
$keyHash = md5(self::$key);
|
|
||||||
$data = mcrypt_encrypt(self::$cipher, self::getKey($keyHash), $data, self::$mode, self::getIv($keyHash));
|
|
||||||
return base64_encode($data);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static function decrypt($data)
|
|
||||||
{
|
|
||||||
$keyHash = md5(self::$key);
|
|
||||||
$data = base64_decode($data);
|
|
||||||
$data = mcrypt_decrypt(self::$cipher, self::getKey($keyHash), $data, self::$mode, self::getIv($keyHash));
|
|
||||||
return rtrim($data);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static function getIv($keyHash)
|
|
||||||
{
|
|
||||||
$iv = substr($keyHash, 0, mcrypt_get_block_size(self::$cipher, self::$mode));
|
|
||||||
return $iv;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static function getKey($keyHash)
|
|
||||||
{
|
|
||||||
$key = substr($keyHash, 0, mcrypt_get_key_size(self::$cipher, self::$mode));
|
|
||||||
return $key;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private function encryptRJ256($key, $iv, $text)
|
|
||||||
{
|
|
||||||
$cipher = new Rijndael('cbc');
|
|
||||||
$cipher->setBlockLength(128);
|
|
||||||
// keys are null-padded to the closest valid size
|
|
||||||
// longer than the longest key and it's truncated
|
|
||||||
$cipher->setKeyLength(128);
|
|
||||||
$cipher->setKey($key);
|
|
||||||
// the IV defaults to all-NULLs if not explicitly defined
|
|
||||||
$cipher->setIV($iv);
|
|
||||||
$cipher->disablePadding();
|
|
||||||
$length = strlen($text);
|
|
||||||
$pad = 32 - ($length % 32);
|
|
||||||
$text = str_pad($text, $length + $pad, chr(0));
|
|
||||||
return base64_encode($cipher->encrypt($text));
|
|
||||||
}
|
|
||||||
private function decryptRJ256($key, $iv, $text)
|
|
||||||
{
|
|
||||||
$cipher = new Rijndael('cbc'); // could use CRYPT_RIJNDAEL_MODE_CBC
|
|
||||||
$cipher->setBlockLength(128);
|
|
||||||
// keys are null-padded to the closest valid size
|
|
||||||
// longer than the longest key and it's truncated
|
|
||||||
$cipher->setKeyLength(128);
|
|
||||||
$cipher->setKey($key);
|
|
||||||
// the IV defaults to all-NULLs if not explicitly defined
|
|
||||||
$cipher->setIV($iv);
|
|
||||||
$cipher->disablePadding();
|
|
||||||
return $cipher->decrypt(base64_decode($text));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
96
MIG/Db.php
96
MIG/Db.php
|
|
@ -1,96 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
class Database
|
|
||||||
{
|
|
||||||
|
|
||||||
static $instance;
|
|
||||||
private static $host;
|
|
||||||
private static $database;
|
|
||||||
private static $user;
|
|
||||||
private static $password;
|
|
||||||
|
|
||||||
public function __construct($host, $database, $user, $password)
|
|
||||||
{
|
|
||||||
self::$host = $host;
|
|
||||||
self::$database = $database;
|
|
||||||
self::$user = $user;
|
|
||||||
self::$password = $password;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static function Instance()
|
|
||||||
{
|
|
||||||
if (!self::$instance) {
|
|
||||||
try {
|
|
||||||
self::$instance = new \PDO('mysql:host=' . self::$host . ';dbname=' . self::$database . ';charset=UTF8', self::$user, self::$password, array(\PDO::ATTR_ERRMODE => \PDO::ERRMODE_EXCEPTION));
|
|
||||||
} catch (\Exception $e) {
|
|
||||||
die($e->getMessage());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return self::$instance;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function request($statement, $params = false)
|
|
||||||
{
|
|
||||||
try {
|
|
||||||
$db = self::Instance();
|
|
||||||
$query = $db->prepare($statement);
|
|
||||||
if ($params) {
|
|
||||||
$query->execute($params);
|
|
||||||
} else {
|
|
||||||
$query->execute();
|
|
||||||
}
|
|
||||||
} catch (\PDOException $e) {
|
|
||||||
die($e->getMessage());
|
|
||||||
}
|
|
||||||
$query->setFetchMode(\PDO::FETCH_ASSOC);
|
|
||||||
$result = $query->fetch();
|
|
||||||
$query->closeCursor();
|
|
||||||
return ($result);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function requestAll($statement, $params = false)
|
|
||||||
{
|
|
||||||
try {
|
|
||||||
$db = self::Instance();
|
|
||||||
$query = $db->prepare($statement);
|
|
||||||
if ($params) {
|
|
||||||
$query->execute($params);
|
|
||||||
} else {
|
|
||||||
$query->execute();
|
|
||||||
}
|
|
||||||
} catch (\PDOException $e) {
|
|
||||||
die($e->getMessage());
|
|
||||||
}
|
|
||||||
$query->setFetchMode(\PDO::FETCH_ASSOC);
|
|
||||||
$result = $query->fetchAll();
|
|
||||||
$query->closeCursor();
|
|
||||||
return ($result);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function requestPush($statement, $params = false)
|
|
||||||
{
|
|
||||||
try {
|
|
||||||
$db = self::Instance();
|
|
||||||
$query = $db->prepare($statement);
|
|
||||||
if ($params)
|
|
||||||
$query->execute($params);
|
|
||||||
else
|
|
||||||
$query->execute();
|
|
||||||
return true;
|
|
||||||
} catch (\PDOException $e) {
|
|
||||||
die($e->getMessage());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public function requestPushInsert($statement, $params)
|
|
||||||
{
|
|
||||||
try {
|
|
||||||
$db = self::Instance();
|
|
||||||
$query = $db->prepare($statement);
|
|
||||||
$query->execute($params);
|
|
||||||
return $db->lastInsertId();
|
|
||||||
} catch (\PDOException $e) {
|
|
||||||
file_put_contents("errors_sql.txt", implode(',', $params) . PHP_EOL, FILE_APPEND);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,91 +0,0 @@
|
||||||
<?php
|
|
||||||
ini_set("memory_limit", "-1");
|
|
||||||
set_time_limit(0);
|
|
||||||
error_reporting(E_ALL);
|
|
||||||
|
|
||||||
require_once 'Db.php';
|
|
||||||
require_once 'CPlatosChiffrement.class.php';
|
|
||||||
// FIXME: utiliser crm V2
|
|
||||||
require_once 'LDCCRM_V1.php';
|
|
||||||
|
|
||||||
$db = new Database('localhost', 'ldc-crm', 'ldc-crmadm', 'wai6dahB');
|
|
||||||
//$db = new Database('192.168.30.3', 'ldc-crm', 'ldc-crmadm', 'wai6dahB');
|
|
||||||
$apiCrm = new \LDCCRM\ApiV1('http://crm.test', 'giu6OCyG6FuJvM56zFntDcrtDI23GU7WNnkvOk9rPPTOzKArI8IV9nqgEAnsA8wEQUDnKheQ9FDfKUwG');
|
|
||||||
|
|
||||||
$siteId = 17;
|
|
||||||
$siteName = "REGHALAL";
|
|
||||||
|
|
||||||
$accounts = $db->requestAll("SELECT *
|
|
||||||
FROM useraccount
|
|
||||||
INNER JOIN siteuser su ON useraccount.user_id = su.siteuser_useraccountId
|
|
||||||
WHERE su.siteuser_siteId = :siteid
|
|
||||||
AND user_status = 1
|
|
||||||
AND user_lastUpdateDate >= '2018-03-01'
|
|
||||||
AND (user_emailCheckStatus <> 0 OR user_emailCheckStatus IS NULL)
|
|
||||||
AND (user_lastCnxDateHeure IS NOT NULL AND user_lastCnxDateHeure <> '0000-00-00 00:00:00')", ['siteid' => $siteId]);
|
|
||||||
|
|
||||||
foreach ($accounts as $account) {
|
|
||||||
$isSingleOptin = false;
|
|
||||||
|
|
||||||
$oldCRMid = $account['user_id'];
|
|
||||||
|
|
||||||
$civility = $account['user_civilite'];
|
|
||||||
$firstname = $account['user_prenom'];
|
|
||||||
$lastname = $account['user_nom'];
|
|
||||||
|
|
||||||
$birthdate = $account['user_dateNaissance'];
|
|
||||||
|
|
||||||
$address1 = !empty($account['user_adresse1']) ? $account['user_adresse1'] : null;
|
|
||||||
$address2 = !empty($account['user_adresse2']) ? $account['user_adresse2'] : null;
|
|
||||||
$postcode = (!empty($account['user_codePostal']) && $account['user_codePostal'] !== 0 ? $account['user_codePostal'] : null);
|
|
||||||
$city = !empty($account['user_ville']) ? $account['user_ville'] : null;
|
|
||||||
|
|
||||||
$optin = $account['user_inscritNewsletter'];
|
|
||||||
$haschcode = $account['user_hashcode'];
|
|
||||||
$status = $account['user_status'];
|
|
||||||
|
|
||||||
$created_at = $account['user_creationDate'];
|
|
||||||
$updated_at = $account['user_lastUpdateDate'];
|
|
||||||
|
|
||||||
$email = $account['user_email'];
|
|
||||||
$password = CPlatosChiffrement::decrypt($account['user_pwd']);
|
|
||||||
|
|
||||||
$last_cnx = $account['user_lastCnxDateHeure'];
|
|
||||||
|
|
||||||
if (empty($firstname) && empty($lastname))
|
|
||||||
$isSingleOptin = true;
|
|
||||||
|
|
||||||
// Récupération des champs complémentaires
|
|
||||||
$fields = [['fieldkey' => 'created_at', 'fieldvalue' => $created_at], ['fieldkey' => 'updated_at', 'fieldvalue' => $updated_at], ['fieldkey' => 'last_cnx', 'fieldvalue' => $last_cnx]];
|
|
||||||
|
|
||||||
if (!$isSingleOptin) {
|
|
||||||
$crmUser = $apiCrm->createCustomer($email, $password, $firstname, $lastname, $optin, $birthdate, null, $address1, $address2, $city, $postcode, "France");
|
|
||||||
if ($crmUser->status === 'OK') {
|
|
||||||
$newCRMId = $crmUser->user->crm_id;
|
|
||||||
$activate = $apiCrm->activateCustomer($newCRMId);
|
|
||||||
if ($activate->status === 'NOK') {
|
|
||||||
file_put_contents("Export_errors.txt", "OLD CRM ID : $oldCRMid - NEW CRM ID : $newCRMId - ACTIVATE API ERROR : " . $activate->code . " - " . $activate->message . PHP_EOL, FILE_APPEND);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
file_put_contents("Export_errors.txt", "OLD CRM ID : $oldCRMid - API ERROR : " . $crmUser->code . " - " . $crmUser->message . PHP_EOL, FILE_APPEND);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
$result = $apiCrm->createSingleOptin($email);
|
|
||||||
|
|
||||||
if ($result->status === 'OK') {
|
|
||||||
$newCRMId = "SINGLEOPTIN";
|
|
||||||
} else {
|
|
||||||
file_put_contents("Export_errors.txt", "OLD CRM ID : $oldCRMid - API ERROR : " . $crmUser->code . " - " . $crmUser->message . PHP_EOL, FILE_APPEND);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
write("$oldCRMid;$newCRMId;$email;" . json_encode($fields) . PHP_EOL, $siteName);
|
|
||||||
}
|
|
||||||
|
|
||||||
function write($text, $siteName)
|
|
||||||
{
|
|
||||||
if (!file_exists("Export_$siteName.csv"))
|
|
||||||
file_put_contents("Export_$siteName.csv", "\xEF\xBB\xBF", FILE_APPEND); // BOM UTF-8
|
|
||||||
file_put_contents("Export_$siteName.csv", $text, FILE_APPEND);
|
|
||||||
}
|
|
||||||
|
|
@ -1,9 +0,0 @@
|
||||||
CREATE TABLE `legaulois_migration` (
|
|
||||||
`id` BIGINT(20) NOT NULL AUTO_INCREMENT,
|
|
||||||
`user_id` BIGINT(20) NOT NULL DEFAULT '0',
|
|
||||||
`pwd` VARCHAR(255) NOT NULL DEFAULT '0',
|
|
||||||
PRIMARY KEY (`id`)
|
|
||||||
)
|
|
||||||
COLLATE='utf8_unicode_ci'
|
|
||||||
ENGINE=InnoDB
|
|
||||||
AUTO_INCREMENT=0;
|
|
||||||
|
|
@ -1,80 +0,0 @@
|
||||||
<?php
|
|
||||||
ini_set("memory_limit", "-1");
|
|
||||||
set_time_limit(0);
|
|
||||||
error_reporting(E_ALL);
|
|
||||||
|
|
||||||
require_once 'Db.php';
|
|
||||||
|
|
||||||
$db = new Database('192.168.31.102', 'ldccrm_12_2020', 'ldccrmadm', 'wai6dahB'); // INFOS NOUVELLE CRM
|
|
||||||
|
|
||||||
$newBrandId = 2; // BRAND ID de la migration
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return Generator
|
|
||||||
*/
|
|
||||||
$fileData = function() {
|
|
||||||
$file = fopen(__DIR__ . '/Export_REGHALAL.csv', 'r');
|
|
||||||
|
|
||||||
if (!$file)
|
|
||||||
die('file does not exist or cannot be opened');
|
|
||||||
|
|
||||||
while (($line = fgets($file)) !== false) {
|
|
||||||
yield $line;
|
|
||||||
}
|
|
||||||
|
|
||||||
fclose($file);
|
|
||||||
};
|
|
||||||
|
|
||||||
foreach ($fileData() as $line) {
|
|
||||||
$isSingleOptin = false;
|
|
||||||
|
|
||||||
$datas = explode(";", $line);
|
|
||||||
$oldCrmId = $datas[0];
|
|
||||||
$newCrmId = $datas[1];
|
|
||||||
$email = $datas[2];
|
|
||||||
$otherFields = json_decode($datas[3]);
|
|
||||||
|
|
||||||
if ($newCrmId === 'SINGLEOPTIN')
|
|
||||||
$isSingleOptin = true;
|
|
||||||
|
|
||||||
foreach ($otherFields as $otherField){
|
|
||||||
// created_at - updated_at - last_cnx ne bougent pas car génériques et db sur nouvelle CRM sinon DB sur nouveau site.
|
|
||||||
switch($otherField->fieldkey){
|
|
||||||
case 'created_at':
|
|
||||||
if (!$isSingleOptin) {
|
|
||||||
$query = "UPDATE customers SET created_at = :nvalue WHERE id = :newid";
|
|
||||||
$db->requestPush($query, ['nvalue' => $otherField->fieldvalue, 'newid' => $newCrmId]);
|
|
||||||
$query = "UPDATE customer_infos SET created_at = :nvalue WHERE customer_id = :newid AND brand_id = :brandid";
|
|
||||||
$db->requestPush($query, ['nvalue' => $otherField->fieldvalue, 'newid' => $newCrmId, 'brandid' => $newBrandId]);
|
|
||||||
$query = "UPDATE customer_login SET created_at = :nvalue WHERE customer_id = :newid AND brand_id = :brandid";
|
|
||||||
$db->requestPush($query, ['nvalue' => $otherField->fieldvalue, 'newid' => $newCrmId, 'brandid' => $newBrandId]);
|
|
||||||
$query = "UPDATE customer_opt_in_history SET created_at = :nvalue WHERE customer_id = :newid AND brand_id = :brandid";
|
|
||||||
$db->requestPush($query, ['nvalue' => $otherField->fieldvalue, 'newid' => $newCrmId, 'brandid' => $newBrandId]);
|
|
||||||
}else{
|
|
||||||
$query = "UPDATE single_optin SET created_at = :nvalue, updated_at = :nvalue WHERE email = :email AND brand_id = :brandid";
|
|
||||||
$db->requestPush($query, ['nvalue' => $otherField->fieldvalue, 'email' => $email, 'brandid' => $newBrandId]);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 'updated_at':
|
|
||||||
if (!$isSingleOptin) {
|
|
||||||
$query = "UPDATE customers SET updated_at = :nvalue WHERE id = :newid";
|
|
||||||
$db->requestPush($query, ['nvalue' => $otherField->fieldvalue, 'newid' => $newCrmId]);
|
|
||||||
$query = "UPDATE customer_infos SET updated_at = :nvalue WHERE customer_id = :newid AND brand_id = :brandid";
|
|
||||||
$db->requestPush($query, ['nvalue' => $otherField->fieldvalue, 'newid' => $newCrmId, 'brandid' => $newBrandId]);
|
|
||||||
$query = "UPDATE customer_login SET updated_at = :nvalue WHERE customer_id = :newid AND brand_id = :brandid";
|
|
||||||
$db->requestPush($query, ['nvalue' => $otherField->fieldvalue, 'newid' => $newCrmId, 'brandid' => $newBrandId]);
|
|
||||||
$query = "UPDATE customer_opt_in_history SET updated_at = :nvalue WHERE customer_id = :newid AND brand_id = :brandid";
|
|
||||||
$db->requestPush($query, ['nvalue' => $otherField->fieldvalue, 'newid' => $newCrmId, 'brandid' => $newBrandId]);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 'last_cnx':
|
|
||||||
if (!$isSingleOptin) {
|
|
||||||
$query = "UPDATE customer_login SET last_connection = :nvalue WHERE customer_id = :newid AND brand_id = :brandid";
|
|
||||||
$db->requestPush($query, ['nvalue' => $otherField->fieldvalue, 'newid' => $newCrmId, 'brandid' => $newBrandId]);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
}
|
|
||||||
//var_dump($otherField);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
89
MIG/pwd.php
89
MIG/pwd.php
|
|
@ -1,89 +0,0 @@
|
||||||
<?php
|
|
||||||
ini_set("memory_limit", "-1");
|
|
||||||
set_time_limit(0);
|
|
||||||
error_reporting(E_ALL);
|
|
||||||
require_once 'Db.php';
|
|
||||||
require_once 'CPlatosChiffrement.class.php';
|
|
||||||
$db = new Database('localhost', 'ldc-crm', 'root', '');
|
|
||||||
//$db = new Database('192.168.34.2', 'ldc-crm', 'ldc-crmadm', 'wai6dahB');
|
|
||||||
if (!isset($argv[1]) || !isset($argv[2]))
|
|
||||||
die('params missing');
|
|
||||||
$name = $argv[1];
|
|
||||||
$siteId = $argv[2];
|
|
||||||
$table = $name."_migration";
|
|
||||||
$maxdate = date("Y-m-d", strtotime("-36 month", time()));
|
|
||||||
$db->requestPush("CREATE TABLE IF NOT EXISTS $table (
|
|
||||||
`id` BIGINT(20) NOT NULL AUTO_INCREMENT,
|
|
||||||
`user_id` BIGINT(20) NOT NULL DEFAULT '0',
|
|
||||||
`firstname` VARCHAR(255) NOT NULL DEFAULT '0',
|
|
||||||
`lastname` VARCHAR(255) NOT NULL DEFAULT '0',
|
|
||||||
`birthdate` VARCHAR(255) NULL DEFAULT '0',
|
|
||||||
`address` VARCHAR(255) NULL DEFAULT '0',
|
|
||||||
`address2` VARCHAR(255) NULL DEFAULT '0',
|
|
||||||
`city` VARCHAR(255) NULL DEFAULT '0',
|
|
||||||
`postcode` VARCHAR(255) NULL DEFAULT '0',
|
|
||||||
`optin` INT(11) NOT NULL DEFAULT '0',
|
|
||||||
`email` VARCHAR(255) NOT NULL DEFAULT '0',
|
|
||||||
`pwd` VARCHAR(255) NOT NULL DEFAULT '0',
|
|
||||||
`created_at` TIMESTAMP NOT NULL,
|
|
||||||
`updated_at` TIMESTAMP NOT NULL,
|
|
||||||
`last_cnx` TIMESTAMP NOT NULL,
|
|
||||||
PRIMARY KEY (`id`)
|
|
||||||
) COLLATE='utf8_unicode_ci' ENGINE=InnoDB AUTO_INCREMENT=0;");
|
|
||||||
|
|
||||||
$getAccounts = function ($skip) use ($db, $siteId, $maxdate){
|
|
||||||
return $db->requestAll("SELECT *
|
|
||||||
FROM useraccount
|
|
||||||
INNER JOIN siteuser su ON useraccount.user_id = su.siteuser_useraccountId
|
|
||||||
WHERE su.siteuser_siteId = :siteid
|
|
||||||
AND user_id >= 701697
|
|
||||||
AND user_status = 1
|
|
||||||
AND user_lastUpdateDate >= :maxdate
|
|
||||||
AND (user_emailCheckStatus <> 0 OR user_emailCheckStatus IS NULL)
|
|
||||||
AND (user_lastCnxDateHeure IS NOT NULL AND user_lastCnxDateHeure <> '0000-00-00 00:00:00')
|
|
||||||
AND user_lastCnxDateHeure >= :maxdate
|
|
||||||
AND user_email IS NOT NULL LIMIT 4600 OFFSET ". ($skip * 4600), ['siteid' => $siteId, 'maxdate' => $maxdate]);
|
|
||||||
};
|
|
||||||
$k = 0;
|
|
||||||
while (count($accounts = $getAccounts($k++))) {
|
|
||||||
$sql = [];
|
|
||||||
$toto = "";
|
|
||||||
foreach ($accounts as $account){
|
|
||||||
$crm_id = $account['user_id'];
|
|
||||||
$civility = $account['user_civilite'];
|
|
||||||
$firstname = ucfirst($account['user_prenom']);
|
|
||||||
$lastname = ucfirst($account['user_nom']);
|
|
||||||
$birthdate = $account['user_dateNaissance'];
|
|
||||||
$address1 = !empty($account['user_adresse1']) ? $account['user_adresse1'] : null;
|
|
||||||
$address2 = !empty($account['user_adresse2']) ? $account['user_adresse2'] : null;
|
|
||||||
$postcode = (!empty($account['user_codePostal']) && $account['user_codePostal'] !== 0 ? $account['user_codePostal'] : null);
|
|
||||||
$city = !empty($account['user_ville']) ? $account['user_ville'] : null;
|
|
||||||
$optin = $account['user_inscritNewsletter'];
|
|
||||||
$haschcode = $account['user_hashcode'];
|
|
||||||
$status = $account['user_status'];
|
|
||||||
$created_at = $account['user_creationDate'];
|
|
||||||
$updated_at = $account['user_lastUpdateDate'];
|
|
||||||
$email = strtolower($account['user_email']);
|
|
||||||
//$password = CPlatosChiffrement::decrypt($account['user_pwd']);
|
|
||||||
$password = "toto";
|
|
||||||
$last_cnx = $account['user_lastCnxDateHeure'];
|
|
||||||
$datas = [
|
|
||||||
$crm_id,
|
|
||||||
$firstname,
|
|
||||||
$lastname,
|
|
||||||
$birthdate,
|
|
||||||
$address1,
|
|
||||||
$address2,
|
|
||||||
$city,
|
|
||||||
$postcode,
|
|
||||||
$optin,
|
|
||||||
$email,
|
|
||||||
$password,
|
|
||||||
$created_at,
|
|
||||||
$updated_at,
|
|
||||||
$last_cnx
|
|
||||||
];
|
|
||||||
$toto = "(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";
|
|
||||||
$db->requestPushInsert("INSERT INTO $table (user_id, firstname, lastname, birthdate, address, address2, city, postcode, optin, email, pwd, created_at, updated_at, last_cnx) VALUES $toto", $datas);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
54
README.md
54
README.md
|
|
@ -1,52 +1,10 @@
|
||||||
# Comment lancer les tests unitaires ?
|
# CRM
|
||||||
|
|
||||||
### Attention, si vous utilisez juste un .env à la place d'un .env.testing votre base de donnée de developpement sera effacée à chaque lancement des tests unitaires
|
## Documentation
|
||||||
|
https://cdlfr.sharepoint.com/:b:/r/sites/LDCWEB/Documents%20partages/Documentations/Projets/CRM/FICHE%20FONCTIONNELLE%20OUTIL%20R%C3%89CLAMATIONS%20CONSO.pdf?csf=1&web=1&e=qktL4V
|
||||||
|
|
||||||
Etapes :
|
## Tests unitaire
|
||||||
- cp .env.testing.example .env.testing (spécial tests unitaires)
|
|
||||||
- php artisan key:generate
|
|
||||||
- parameter les BDD dans le .env.testing
|
|
||||||
- php artisan config:cache
|
|
||||||
- git submodule init
|
|
||||||
- git submodule update (récupérer le client)
|
|
||||||
- composer install
|
|
||||||
- service start mysql (votre base de donnée accessible sur 127.0.0.1:3306)
|
|
||||||
- chmod u+x ./test.sh
|
|
||||||
- php artisan optimize
|
|
||||||
- composer run test
|
|
||||||
|
|
||||||
Config Supervisor 2 Fichiers :
|
### Comment lancer les tests unitaires ?
|
||||||
|
|
||||||
`ldccrm-worker.conf`
|
[Suivre le wiki dédié au tests unitaires](https://lab.s-web.fr/ldc-web/projets/crm/-/wikis/Tests-unitaires)
|
||||||
**Pour les jobs en général**
|
|
||||||
|
|
||||||
[program:ldccrm-worker]
|
|
||||||
process_name=%(program_name)s_%(process_num)02d
|
|
||||||
command=php /u1/DATA01/webldc/Apps/ldccrm/ldccrm-12-2020/srcs/artisan queue:work --sleep=3 --tries=3 --max-time=3600
|
|
||||||
autostart=true
|
|
||||||
autorestart=true
|
|
||||||
startasgroup=true
|
|
||||||
killasgroup=true
|
|
||||||
user=www-data
|
|
||||||
umask=077
|
|
||||||
numprocs=8
|
|
||||||
redirect_stderr=true
|
|
||||||
stdout_logfile=/u1/DATA01/webldc/Apps/ldccrm/ldccrm-12-2020/srcs/storage/logs/worker.log
|
|
||||||
stopwaitsecs=3600
|
|
||||||
|
|
||||||
`ldccrm-stats-worker.conf`
|
|
||||||
**Pour les jobs de stats uniquement**
|
|
||||||
|
|
||||||
[program:ldccrm-stats-worker]
|
|
||||||
process_name=%(program_name)s_%(process_num)02d
|
|
||||||
command=php /u1/DATA01/webldc/Apps/ldccrm/ldccrm-12-2020/srcs/artisan queue:work --queue=stats --sleep=3 --tries=3 --max-time=3600
|
|
||||||
autostart=true
|
|
||||||
autorestart=true
|
|
||||||
startasgroup=true
|
|
||||||
killasgroup=true
|
|
||||||
user=www-data
|
|
||||||
umask=077
|
|
||||||
numprocs=1
|
|
||||||
redirect_stderr=true
|
|
||||||
stdout_logfile=/u1/DATA01/webldc/Apps/ldccrm/ldccrm-12-2020/srcs/storage/logs/worker.log
|
|
||||||
stopwaitsecs=3600
|
|
||||||
|
|
|
||||||
|
|
@ -1,79 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Console\Commands;
|
|
||||||
|
|
||||||
use Illuminate\Console\Command;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Command Name: LDC Web Status Checker
|
|
||||||
* Description: Envoi des infos Serveur/Laravel vers LDC Web
|
|
||||||
* Version: 1.1
|
|
||||||
* Author: Vincent BRIDIER
|
|
||||||
* Author URI: vincent.bridier@ldc.fr
|
|
||||||
*
|
|
||||||
* @codeCoverageIgnore
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
class LdcWebStatusChecker extends Command
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* The name and signature of the console command.
|
|
||||||
*
|
|
||||||
* @var string
|
|
||||||
*/
|
|
||||||
protected $signature = 'ldcweb:statuschecker';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The console command description.
|
|
||||||
*
|
|
||||||
* @var string
|
|
||||||
*/
|
|
||||||
protected $description = 'Envoi des infos Serveur/Laravel vers LDC Web';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Execute the console command.
|
|
||||||
*
|
|
||||||
* @return mixed
|
|
||||||
*/
|
|
||||||
public function handle(): mixed
|
|
||||||
{
|
|
||||||
$data = [];
|
|
||||||
$data['uuid'] = config('ldcweb.project_uuid');
|
|
||||||
|
|
||||||
// Sitemap.xml ?
|
|
||||||
if (file_exists(public_path() . '/sitemap.xml')) {
|
|
||||||
$data['sitemap'] = 'true';
|
|
||||||
} else {
|
|
||||||
$data['sitemap'] = 'false';
|
|
||||||
}
|
|
||||||
|
|
||||||
// Robots.txt ?
|
|
||||||
if (file_exists(public_path() . '/robots.txt')) {
|
|
||||||
$data['robots'] = 'true';
|
|
||||||
} else {
|
|
||||||
$data['robots'] = 'false';
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check logs.
|
|
||||||
$data['logs'] = 0;
|
|
||||||
$patherror = storage_path('/logs');
|
|
||||||
$files = glob($patherror . '/*.log');
|
|
||||||
if (count($files) > 0) {
|
|
||||||
foreach ($files as $file) {
|
|
||||||
$data['logs'] = $data['logs'] + filesize($file);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$data['code']['version'] = app()->version();
|
|
||||||
|
|
||||||
// Send by cURL.
|
|
||||||
$url = 'https://ldc-web.ldc.fr/api/status-checker';
|
|
||||||
$ch = curl_init($url);
|
|
||||||
$payload = ['token' => 'CE8S52Qq7stf5k8frF4T', 'datas' => json_encode($data)];
|
|
||||||
curl_setopt($ch, CURLOPT_POSTFIELDS, $payload);
|
|
||||||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
|
|
||||||
curl_exec($ch);
|
|
||||||
curl_close($ch);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,72 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Console\Commands;
|
|
||||||
|
|
||||||
use App\Lib\MigrateOldData;
|
|
||||||
use App\Models\Brand;
|
|
||||||
use Illuminate\Console\Command;
|
|
||||||
use Illuminate\Support\Facades\DB;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @codeCoverageIgnore
|
|
||||||
*/
|
|
||||||
class MigrateCrmUsers extends Command
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* The name and signature of the console command.
|
|
||||||
*
|
|
||||||
* @var string
|
|
||||||
*/
|
|
||||||
protected $signature = 'migrate:crm';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The console command description.
|
|
||||||
*
|
|
||||||
* @var string
|
|
||||||
*/
|
|
||||||
protected $description = 'Migrate crm users';
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Execute the console command.
|
|
||||||
*
|
|
||||||
* @return integer
|
|
||||||
*/
|
|
||||||
public function handle(): int
|
|
||||||
{
|
|
||||||
try {
|
|
||||||
$table = $this->ask('What is the tmp table name with users data ?');
|
|
||||||
|
|
||||||
try {
|
|
||||||
DB::connection(config('database.oldDB'))->table($table)->exists();
|
|
||||||
} catch (\Exception $e) {
|
|
||||||
$this->error(sprintf('%s table not found on old crm database', $table));
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
$brandname = $this->ask('What is the brand name ?');
|
|
||||||
$brand = Brand::query()->where('name', 'LIKE', "%$brandname%")->first();
|
|
||||||
if (!$brand) {
|
|
||||||
if (!$this->confirm(sprintf('Would you like to use %s ? ', $brandname))) {
|
|
||||||
$this->info('Command cancelled');
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
if ($this->confirm('Would you like to create a new one ?')) {
|
|
||||||
$brand = new Brand();
|
|
||||||
$brand->name = $brandname;
|
|
||||||
$brand->save();
|
|
||||||
} else {
|
|
||||||
$this->info('Command cancelled');
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$mgOldData = new MigrateOldData();
|
|
||||||
$mgOldData->runMigration($brand, $table);
|
|
||||||
} catch (\Exception $e) {
|
|
||||||
$this->error(sprintf('Failed %s', $e));
|
|
||||||
return -1;
|
|
||||||
} //end try
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -8,6 +8,7 @@ use Carbon\Carbon;
|
||||||
use Illuminate\Console\Command;
|
use Illuminate\Console\Command;
|
||||||
use Illuminate\Support\Facades\Validator;
|
use Illuminate\Support\Facades\Validator;
|
||||||
use Illuminate\Validation\ValidationException;
|
use Illuminate\Validation\ValidationException;
|
||||||
|
use Illuminate\Support\Str;
|
||||||
|
|
||||||
class UserCreate extends Command
|
class UserCreate extends Command
|
||||||
{
|
{
|
||||||
|
|
@ -28,74 +29,61 @@ class UserCreate extends Command
|
||||||
/**
|
/**
|
||||||
* The first name of the new user.
|
* The first name of the new user.
|
||||||
*
|
*
|
||||||
* @var string
|
* @var string|null
|
||||||
*/
|
*/
|
||||||
protected $first_name;
|
protected $firstName;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The last name of the new user.
|
* The last name of the new user.
|
||||||
*
|
*
|
||||||
* @var string
|
* @var string|null
|
||||||
*/
|
*/
|
||||||
protected $last_name;
|
protected $lastName;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The email of the new user.
|
* The email of the new user.
|
||||||
*
|
*
|
||||||
* @var string
|
* @var string|null
|
||||||
*/
|
*/
|
||||||
protected $email;
|
protected $email;
|
||||||
|
|
||||||
/**
|
|
||||||
* The password of the new user.
|
|
||||||
*
|
|
||||||
* @var string
|
|
||||||
*/
|
|
||||||
protected $password;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The role of the new user.
|
* The role of the new user.
|
||||||
*
|
*
|
||||||
* @var string
|
* @var string|null
|
||||||
*/
|
*/
|
||||||
protected $role;
|
protected $role;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Execute the console command.
|
* Execute the console command.
|
||||||
*
|
*
|
||||||
* @return integer
|
* @return void
|
||||||
*/
|
*/
|
||||||
public function handle(): int
|
public function handle(): void
|
||||||
{
|
{
|
||||||
$this->first_name = null;
|
$this->firstName = null;
|
||||||
$this->addFirstName();
|
$this->addFirstName();
|
||||||
|
|
||||||
$this->last_name = null;
|
$this->lastName = null;
|
||||||
$this->addLastName();
|
$this->addLastName();
|
||||||
|
|
||||||
$this->email = null;
|
$this->email = null;
|
||||||
$this->addEmail();
|
$this->addEmail();
|
||||||
|
|
||||||
$this->password = null;
|
|
||||||
$this->addPassword();
|
|
||||||
|
|
||||||
$this->role = null;
|
$this->role = null;
|
||||||
$this->addRole();
|
$this->addRole();
|
||||||
|
|
||||||
$user = new User([
|
$user = new User([
|
||||||
'first_name' => $this->first_name,
|
'first_name' => $this->firstName,
|
||||||
'last_name' => $this->last_name,
|
'last_name' => $this->lastName,
|
||||||
'email' => $this->email,
|
'email' => $this->email,
|
||||||
'password' => $this->password,
|
'role' => $this->role,
|
||||||
'role' => $this->role,
|
'published' => true,
|
||||||
'published' => true,
|
|
||||||
'published_at' => Carbon::now(),
|
'published_at' => Carbon::now(),
|
||||||
]);
|
]);
|
||||||
$user->saveOrFail();
|
$user->saveOrFail();
|
||||||
|
|
||||||
$this->info('User created 👌');
|
$this->info('User created 👌');
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -105,22 +93,22 @@ class UserCreate extends Command
|
||||||
*/
|
*/
|
||||||
private function addFirstName(): void
|
private function addFirstName(): void
|
||||||
{
|
{
|
||||||
while (is_null($this->first_name)) {
|
while (is_null($this->firstName)) {
|
||||||
try {
|
try {
|
||||||
$tmp = $this->ask('Type the wanted user first name', 'Admin');
|
$tmp = $this->ask('Type the wanted user first name', 'Admin');
|
||||||
$validator = Validator::make(['first_name' => $tmp], [
|
$validator = Validator::make(['first_name' => $tmp], [
|
||||||
'first_name' => 'required|min:3|max:255'
|
'first_name' => 'required|min:3|max:255'
|
||||||
]);
|
]);
|
||||||
$validator->validate();
|
$validator->validate();
|
||||||
$this->first_name = $tmp;
|
$this->firstName = $tmp;
|
||||||
} catch (ValidationException $e) {
|
} catch (ValidationException $e) {
|
||||||
$this->error(sprintf(
|
$this->error(sprintf(
|
||||||
'Please provide a valid first name %s',
|
'Please provide a valid first name %s',
|
||||||
\implode(',', collect($e->errors())->flatten()->all())
|
\implode(',', collect($e->errors())->flatten()->all())
|
||||||
));
|
));
|
||||||
continue;
|
continue;
|
||||||
} //end try
|
}
|
||||||
}; //end while
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -130,22 +118,22 @@ class UserCreate extends Command
|
||||||
*/
|
*/
|
||||||
private function addLastName(): void
|
private function addLastName(): void
|
||||||
{
|
{
|
||||||
while (is_null($this->last_name)) {
|
while (is_null($this->lastName)) {
|
||||||
try {
|
try {
|
||||||
$tmp = $this->ask('Type the wanted user last name', 'Saïtama');
|
$tmp = $this->ask('Type the wanted user last name', 'Saïtama');
|
||||||
$validator = Validator::make(['last_name' => $tmp], [
|
$validator = Validator::make(['last_name' => $tmp], [
|
||||||
'last_name' => 'required|min:3|max:255'
|
'last_name' => 'required|min:3|max:255'
|
||||||
]);
|
]);
|
||||||
$validator->validate();
|
$validator->validate();
|
||||||
$this->last_name = $tmp;
|
$this->lastName = $tmp;
|
||||||
} catch (ValidationException $e) {
|
} catch (ValidationException $e) {
|
||||||
$this->error(sprintf(
|
$this->error(sprintf(
|
||||||
'Please provide a valid last_name %s',
|
'Please provide a valid last_name %s',
|
||||||
\implode(',', collect($e->errors())->flatten()->all())
|
\implode(',', collect($e->errors())->flatten()->all())
|
||||||
));
|
));
|
||||||
continue;
|
continue;
|
||||||
} //end try
|
}
|
||||||
}; //end while
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -169,24 +157,8 @@ class UserCreate extends Command
|
||||||
\implode(',', collect($e->errors())->flatten()->all())
|
\implode(',', collect($e->errors())->flatten()->all())
|
||||||
));
|
));
|
||||||
continue;
|
continue;
|
||||||
} //end try
|
}
|
||||||
}; //end while
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Add a password to the user.
|
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
private function addPassword(): void
|
|
||||||
{
|
|
||||||
while (
|
|
||||||
($this->password = $this->secret(
|
|
||||||
(!\is_null($this->password) ? 'Failed to confirm, ' : '') . 'Type the wanted user password'
|
|
||||||
)) !== $this->secret('Confirm the password')
|
|
||||||
) {
|
|
||||||
continue;
|
|
||||||
}; //end while
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -198,21 +170,23 @@ class UserCreate extends Command
|
||||||
{
|
{
|
||||||
while (is_null($this->role)) {
|
while (is_null($this->role)) {
|
||||||
try {
|
try {
|
||||||
$tmp = $this->choice(
|
$tmp = $this->choice(
|
||||||
'Select his role',
|
'Select his role',
|
||||||
[RoleEnum::conceptor->name, RoleEnum::admin->name, RoleEnum::visitor->name],
|
[
|
||||||
RoleEnum::visitor->name,
|
Str::ucFirst(RoleEnum::conceptor->label()),
|
||||||
$maxAttempts = null,
|
Str::ucFirst(RoleEnum::admin->label()),
|
||||||
$allowMultipleSelections = false
|
Str::ucFirst(RoleEnum::marketing->label())
|
||||||
|
],
|
||||||
|
Str::ucFirst(RoleEnum::marketing->label()),
|
||||||
);
|
);
|
||||||
if ($tmp === RoleEnum::conceptor->name) {
|
if ($tmp === Str::ucFirst(RoleEnum::conceptor->label())) {
|
||||||
$tmp = RoleEnum::conceptor;
|
$tmp = RoleEnum::conceptor;
|
||||||
}
|
}
|
||||||
if ($tmp === RoleEnum::admin->name) {
|
if ($tmp === Str::ucFirst(RoleEnum::admin->label())) {
|
||||||
$tmp = RoleEnum::admin;
|
$tmp = RoleEnum::admin;
|
||||||
}
|
}
|
||||||
if ($tmp === RoleEnum::visitor->name) {
|
if ($tmp === Str::ucFirst(RoleEnum::marketing->label())) {
|
||||||
$tmp = RoleEnum::visitor;
|
$tmp = RoleEnum::marketing;
|
||||||
}
|
}
|
||||||
$validator = Validator::make(['role' => $tmp], [
|
$validator = Validator::make(['role' => $tmp], [
|
||||||
'role' => 'required'
|
'role' => 'required'
|
||||||
|
|
@ -221,11 +195,11 @@ class UserCreate extends Command
|
||||||
$this->role = $tmp;
|
$this->role = $tmp;
|
||||||
} catch (ValidationException $e) {
|
} catch (ValidationException $e) {
|
||||||
$this->error(sprintf(
|
$this->error(sprintf(
|
||||||
'Please choose from the selection',
|
'Please choose from the selection %s',
|
||||||
\implode(',', collect($e->errors())->flatten()->all())
|
\implode(',', collect($e->errors())->flatten()->all())
|
||||||
));
|
));
|
||||||
continue;
|
continue;
|
||||||
} //end try
|
}
|
||||||
}; //end while
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@
|
||||||
namespace App\Console;
|
namespace App\Console;
|
||||||
|
|
||||||
use App\Console\Commands\DeleteUnconfirmedCustomers;
|
use App\Console\Commands\DeleteUnconfirmedCustomers;
|
||||||
|
use App\Jobs\SendTransferredToDigitalCountMail;
|
||||||
use App\Jobs\StartStatJobs;
|
use App\Jobs\StartStatJobs;
|
||||||
use Illuminate\Console\Scheduling\Schedule;
|
use Illuminate\Console\Scheduling\Schedule;
|
||||||
use Illuminate\Foundation\Console\Kernel as ConsoleKernel;
|
use Illuminate\Foundation\Console\Kernel as ConsoleKernel;
|
||||||
|
|
@ -26,6 +27,7 @@ class Kernel extends ConsoleKernel
|
||||||
{
|
{
|
||||||
// @codeCoverageIgnoreStart
|
// @codeCoverageIgnoreStart
|
||||||
$schedule->job(StartStatJobs::class)->dailyAt('03:30');
|
$schedule->job(StartStatJobs::class)->dailyAt('03:30');
|
||||||
|
$schedule->job(SendTransferredToDigitalCountMail::class)->weekdays()->at('07:00');
|
||||||
$schedule->command(DeleteUnconfirmedCustomers::class)->dailyAt('05:30');
|
$schedule->command(DeleteUnconfirmedCustomers::class)->dailyAt('05:30');
|
||||||
// @codeCoverageIgnoreEnd
|
// @codeCoverageIgnoreEnd
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
namespace App\Enums\ActivityLogs;
|
namespace App\Enums\ActivityLogs;
|
||||||
|
|
||||||
use App\Traits\Enums\BaseEnum;
|
use Uwil\LaravelCommon\Traits\Enums\BaseEnum;
|
||||||
|
|
||||||
enum ActivityLogsEventEnum: int
|
enum ActivityLogsEventEnum: int
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
namespace App\Enums;
|
namespace App\Enums;
|
||||||
|
|
||||||
use App\Traits\Enums\BaseEnum;
|
use Uwil\LaravelCommon\Traits\Enums\BaseEnum;
|
||||||
|
|
||||||
enum ApiError: int
|
enum ApiError: int
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
namespace App\Enums;
|
namespace App\Enums;
|
||||||
|
|
||||||
use App\Traits\Enums\BaseEnum;
|
use Uwil\LaravelCommon\Traits\Enums\BaseEnum;
|
||||||
|
|
||||||
enum ApiStatus: int
|
enum ApiStatus: int
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
namespace App\Enums;
|
namespace App\Enums;
|
||||||
|
|
||||||
use App\Traits\Enums\BaseEnum;
|
use Uwil\LaravelCommon\Traits\Enums\BaseEnum;
|
||||||
|
|
||||||
enum ArcadiaMailType: int
|
enum ArcadiaMailType: int
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
namespace App\Enums;
|
namespace App\Enums;
|
||||||
|
|
||||||
use App\Traits\Enums\BaseEnum;
|
use Uwil\LaravelCommon\Traits\Enums\BaseEnum;
|
||||||
|
|
||||||
enum ArcadiaOrderType: int
|
enum ArcadiaOrderType: int
|
||||||
{
|
{
|
||||||
|
|
|
||||||
21
app/Enums/Claims/ClaimMessageType.php
Normal file
21
app/Enums/Claims/ClaimMessageType.php
Normal file
|
|
@ -0,0 +1,21 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Enums\Claims;
|
||||||
|
|
||||||
|
use Uwil\LaravelCommon\Traits\Enums\BaseEnum;
|
||||||
|
|
||||||
|
enum ClaimMessageType: int
|
||||||
|
{
|
||||||
|
use BaseEnum;
|
||||||
|
|
||||||
|
case system = 1;
|
||||||
|
case human = 2;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Optionnal labels definition
|
||||||
|
*/
|
||||||
|
private const LABELS = [
|
||||||
|
self::system->name => 'Système',
|
||||||
|
self::human->name => 'Humain',
|
||||||
|
];
|
||||||
|
}
|
||||||
51
app/Enums/Claims/ClaimResponseType.php
Normal file
51
app/Enums/Claims/ClaimResponseType.php
Normal file
|
|
@ -0,0 +1,51 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Enums\Claims;
|
||||||
|
|
||||||
|
use Uwil\LaravelCommon\Traits\Enums\BaseEnum;
|
||||||
|
|
||||||
|
enum ClaimResponseType: int
|
||||||
|
{
|
||||||
|
use BaseEnum;
|
||||||
|
|
||||||
|
case none = 1;
|
||||||
|
case manual = 2;
|
||||||
|
case mail = 3;
|
||||||
|
case email = 4;
|
||||||
|
case phone = 5;
|
||||||
|
case other = 99;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Optionnal labels definition
|
||||||
|
*/
|
||||||
|
private const LABELS = [
|
||||||
|
self::none->name => 'Non défini',
|
||||||
|
self::manual->name => 'Manuelle',
|
||||||
|
self::mail->name => 'Courrier',
|
||||||
|
self::email->name => 'E-mail',
|
||||||
|
self::phone->name => 'Téléphone',
|
||||||
|
self::other->name => 'Autre',
|
||||||
|
];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Optionnal labels definition.
|
||||||
|
*/
|
||||||
|
private const COLORS = [
|
||||||
|
self::none->name => '#b8b8b8',
|
||||||
|
self::manual->name => '#a7a7a7',
|
||||||
|
self::mail->name => '#757575',
|
||||||
|
self::email->name => '#5e5e5e',
|
||||||
|
self::phone->name => '#414141',
|
||||||
|
self::other->name => '#2b2b2b',
|
||||||
|
];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get Class.
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function color(): string
|
||||||
|
{
|
||||||
|
return self::COLORS[$this->name];
|
||||||
|
}
|
||||||
|
}
|
||||||
48
app/Enums/Claims/ClaimStatus.php
Normal file
48
app/Enums/Claims/ClaimStatus.php
Normal file
|
|
@ -0,0 +1,48 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Enums\Claims;
|
||||||
|
|
||||||
|
use Uwil\LaravelCommon\Traits\Enums\BaseEnum;
|
||||||
|
|
||||||
|
enum ClaimStatus: int
|
||||||
|
{
|
||||||
|
use BaseEnum;
|
||||||
|
|
||||||
|
case untreated = 1;
|
||||||
|
case sentDigital = 2;
|
||||||
|
case sentMarketing = 3;
|
||||||
|
case treated = 4;
|
||||||
|
case refused = 5;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Optionnal labels definition
|
||||||
|
*/
|
||||||
|
private const LABELS = [
|
||||||
|
self::untreated->name => 'Non traitée',
|
||||||
|
self::sentDigital->name => 'Transférée au service Digital',
|
||||||
|
self::sentMarketing->name => 'Retournée au Marketing',
|
||||||
|
self::treated->name => 'Traitée',
|
||||||
|
self::refused->name => 'Refusé de répondre',
|
||||||
|
];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Optionnal labels definition.
|
||||||
|
*/
|
||||||
|
private const COLORS = [
|
||||||
|
self::untreated->name => '#5a5a5a',
|
||||||
|
self::sentDigital->name => '#0033c0',
|
||||||
|
self::sentMarketing->name => '#69077c',
|
||||||
|
self::treated->name => '#188618',
|
||||||
|
self::refused->name => '#dc143c',
|
||||||
|
];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get Class.
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function color(): string
|
||||||
|
{
|
||||||
|
return self::COLORS[$this->name];
|
||||||
|
}
|
||||||
|
}
|
||||||
42
app/Enums/Claims/ClaimType.php
Normal file
42
app/Enums/Claims/ClaimType.php
Normal file
|
|
@ -0,0 +1,42 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Enums\Claims;
|
||||||
|
|
||||||
|
use Uwil\LaravelCommon\Traits\Enums\BaseEnum;
|
||||||
|
|
||||||
|
enum ClaimType: int
|
||||||
|
{
|
||||||
|
use BaseEnum;
|
||||||
|
|
||||||
|
case classic = 1;
|
||||||
|
case br = 2;
|
||||||
|
case rgpd = 3;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Optionnal labels definition
|
||||||
|
*/
|
||||||
|
private const LABELS = [
|
||||||
|
self::classic->name => 'Classique',
|
||||||
|
self::br->name => 'BR',
|
||||||
|
self::rgpd->name => 'RGPD',
|
||||||
|
];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Optionnal labels definition.
|
||||||
|
*/
|
||||||
|
private const COLORS = [
|
||||||
|
self::classic->name => '#08818a',
|
||||||
|
self::br->name => '#9021f8',
|
||||||
|
self::rgpd->name => '#c2237a',
|
||||||
|
];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get Class.
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function color(): string
|
||||||
|
{
|
||||||
|
return self::COLORS[$this->name];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
namespace App\Enums;
|
namespace App\Enums;
|
||||||
|
|
||||||
use App\Traits\Enums\BaseEnum;
|
use Uwil\LaravelCommon\Traits\Enums\BaseEnum;
|
||||||
|
|
||||||
enum Country: int
|
enum Country: int
|
||||||
{
|
{
|
||||||
|
|
@ -520,9 +520,9 @@ enum Country: int
|
||||||
*/
|
*/
|
||||||
public static function getValidCountriesLabel(): array
|
public static function getValidCountriesLabel(): array
|
||||||
{
|
{
|
||||||
return collect(self::getValidCountries())->map(function (self $country) {
|
return \array_map(function (self $country) {
|
||||||
return $country->label();
|
return $country->label();
|
||||||
})->all();
|
}, self::getValidCountries());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -532,9 +532,9 @@ enum Country: int
|
||||||
*/
|
*/
|
||||||
public static function getValidCountriesValues(): array
|
public static function getValidCountriesValues(): array
|
||||||
{
|
{
|
||||||
return collect(self::getValidCountries())->map(function (self $country) {
|
return \array_map(function (self $country) {
|
||||||
return $country->value();
|
return $country->value();
|
||||||
})->all();
|
}, self::getValidCountries());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -568,7 +568,9 @@ enum Country: int
|
||||||
Country::saintMartinFrenchPart,
|
Country::saintMartinFrenchPart,
|
||||||
Country::wallisAndFutuna,
|
Country::wallisAndFutuna,
|
||||||
Country::frenchPolynesia,
|
Country::frenchPolynesia,
|
||||||
Country::newCaledonia
|
Country::newCaledonia,
|
||||||
|
Country::netherlands,
|
||||||
|
Country::germany,
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -580,20 +582,22 @@ enum Country: int
|
||||||
protected static function isoCodes(): array
|
protected static function isoCodes(): array
|
||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
'france' => 'FR',
|
'france' => 'FR',
|
||||||
'belgium' => 'BE',
|
'belgium' => 'BE',
|
||||||
'luxembourg' => 'LU',
|
'luxembourg' => 'LU',
|
||||||
'guadeloupe' => 'GP',
|
'guadeloupe' => 'GP',
|
||||||
'martinique' => 'MQ',
|
'martinique' => 'MQ',
|
||||||
'frenchGuiana' => 'GF',
|
'frenchGuiana' => 'GF',
|
||||||
'reunion' => 'RE',
|
'reunion' => 'RE',
|
||||||
'saintPierreAndMiquelon' => 'PM',
|
'saintPierreAndMiquelon' => 'PM',
|
||||||
'mayotte' => 'YT',
|
'mayotte' => 'YT',
|
||||||
'saintBarthelemy' => 'BL',
|
'saintBarthelemy' => 'BL',
|
||||||
'saintMartinFrenchPart' => 'MF',
|
'saintMartinFrenchPart' => 'MF',
|
||||||
'wallisAndFutuna' => 'WF',
|
'wallisAndFutuna' => 'WF',
|
||||||
'frenchPolynesia' => 'PF',
|
'frenchPolynesia' => 'PF',
|
||||||
'newCaledonia' => 'NC',
|
'newCaledonia' => 'NC',
|
||||||
|
'netherlands' => 'NL',
|
||||||
|
'germany' => 'DE',
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
namespace App\Enums;
|
namespace App\Enums;
|
||||||
|
|
||||||
use App\Traits\Enums\BaseEnum;
|
use Uwil\LaravelCommon\Traits\Enums\BaseEnum;
|
||||||
|
|
||||||
enum CustomerExportType: int
|
enum CustomerExportType: int
|
||||||
{
|
{
|
||||||
|
|
@ -16,8 +16,9 @@ enum CustomerExportType: int
|
||||||
* Optionnal labels definition
|
* Optionnal labels definition
|
||||||
*/
|
*/
|
||||||
private const LABELS = [
|
private const LABELS = [
|
||||||
self::singleOptin->name => 'Les single optins uniquement',
|
self::singleOptin->name => 'Les single-optins uniquement',
|
||||||
self::customer->name => 'Les clients uniquement acceptant de recevoir les newsletters',
|
self::customer->name => 'Les clients uniquement acceptant de recevoir les newsletters',
|
||||||
self::both->name => 'La totalité des client acceptant de recevoir les newsletters',
|
self::both->name => 'La totalité des single-optins ainsi que des clients acceptant
|
||||||
|
de recevoir les newsletters',
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
|
||||||
85
app/Enums/ExportFormat.php
Normal file
85
app/Enums/ExportFormat.php
Normal file
|
|
@ -0,0 +1,85 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Enums;
|
||||||
|
|
||||||
|
use Uwil\LaravelCommon\Traits\Enums\BaseEnum;
|
||||||
|
|
||||||
|
enum ExportFormat: int
|
||||||
|
{
|
||||||
|
use BaseEnum;
|
||||||
|
|
||||||
|
case csv = 1;
|
||||||
|
case csvWithoutAttachment = 2;
|
||||||
|
case pdf = 3;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Optionnal labels definition
|
||||||
|
*/
|
||||||
|
private const LABELS = [
|
||||||
|
self::csv->name => 'csv',
|
||||||
|
self::csvWithoutAttachment->name => 'csv sans pièces jointes',
|
||||||
|
self::pdf->name => 'pdf',
|
||||||
|
];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Bootstrap color class to use for the export buttons.
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function class(): string
|
||||||
|
{
|
||||||
|
return match ($this) {
|
||||||
|
self::csv,
|
||||||
|
self::csvWithoutAttachment => 'success',
|
||||||
|
self::pdf => 'danger',
|
||||||
|
default => 'primary',
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Font Awesome picto to use for the export buttons.
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function picto(): string
|
||||||
|
{
|
||||||
|
return match ($this) {
|
||||||
|
self::csv,
|
||||||
|
self::csvWithoutAttachment => 'fa-solid fa-file-csv',
|
||||||
|
self::pdf => 'fa-solid fa-file-pdf',
|
||||||
|
default => 'fa-solid fa-file',
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* File headers to use when the exported file is return with StreamedResponse.
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function fileHeaders(): array
|
||||||
|
{
|
||||||
|
return match ($this) {
|
||||||
|
self::csv,
|
||||||
|
self::csvWithoutAttachment => [
|
||||||
|
'Content-Type' => 'text/csv',
|
||||||
|
'Content-Disposition' => 'attachment; filename="export.csv"',
|
||||||
|
],
|
||||||
|
default => [],
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Export file name.
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function fileName(): string
|
||||||
|
{
|
||||||
|
return match ($this) {
|
||||||
|
self::csv,
|
||||||
|
self::csvWithoutAttachment => 'export.csv',
|
||||||
|
self::pdf => 'export.pdf',
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
namespace App\Enums\Pagination;
|
namespace App\Enums\Pagination;
|
||||||
|
|
||||||
use App\Traits\Enums\BaseEnum;
|
use Uwil\LaravelCommon\Traits\Enums\BaseEnum;
|
||||||
|
|
||||||
enum ItemsPerPaginationEnum: int
|
enum ItemsPerPaginationEnum: int
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
namespace App\Enums;
|
namespace App\Enums;
|
||||||
|
|
||||||
use App\Traits\Enums\BaseEnum;
|
use Uwil\LaravelCommon\Traits\Enums\BaseEnum;
|
||||||
|
|
||||||
enum QuestionType: int
|
enum QuestionType: int
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
namespace App\Enums\Theme;
|
namespace App\Enums\Theme;
|
||||||
|
|
||||||
use App\Traits\Enums\BaseEnum;
|
use Uwil\LaravelCommon\Traits\Enums\BaseEnum;
|
||||||
|
|
||||||
enum BootstrapThemeEnum: int
|
enum BootstrapThemeEnum: int
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
namespace App\Enums\Users;
|
namespace App\Enums\Users;
|
||||||
|
|
||||||
use App\Traits\Enums\BaseEnum;
|
use Uwil\LaravelCommon\Traits\Enums\BaseEnum;
|
||||||
|
|
||||||
enum RoleEnum: int
|
enum RoleEnum: int
|
||||||
{
|
{
|
||||||
|
|
@ -10,7 +10,7 @@ enum RoleEnum: int
|
||||||
|
|
||||||
case conceptor = 1;
|
case conceptor = 1;
|
||||||
case admin = 2;
|
case admin = 2;
|
||||||
case visitor = 3;
|
case marketing = 3;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Optionnal labels definition.
|
* Optionnal labels definition.
|
||||||
|
|
@ -18,6 +18,6 @@ enum RoleEnum: int
|
||||||
private const LABELS = [
|
private const LABELS = [
|
||||||
self::conceptor->name => 'Concepteur',
|
self::conceptor->name => 'Concepteur',
|
||||||
self::admin->name => 'Administrateur',
|
self::admin->name => 'Administrateur',
|
||||||
self::visitor->name => 'Visiteur',
|
self::marketing->name => 'Marketing',
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
|
||||||
55
app/Events/ClaimModelChanged.php
Normal file
55
app/Events/ClaimModelChanged.php
Normal file
|
|
@ -0,0 +1,55 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Events;
|
||||||
|
|
||||||
|
use App\Models\Claim;
|
||||||
|
use App\Models\User;
|
||||||
|
use Illuminate\Broadcasting\InteractsWithSockets;
|
||||||
|
use Illuminate\Foundation\Events\Dispatchable;
|
||||||
|
use Illuminate\Queue\SerializesModels;
|
||||||
|
|
||||||
|
class ClaimModelChanged
|
||||||
|
{
|
||||||
|
use Dispatchable;
|
||||||
|
use InteractsWithSockets;
|
||||||
|
use SerializesModels;
|
||||||
|
|
||||||
|
/** @var \App\Models\Claim $claim Current claim modified. */
|
||||||
|
public $claim;
|
||||||
|
|
||||||
|
/** @var string $field Modified field. */
|
||||||
|
public $field;
|
||||||
|
|
||||||
|
/** @var string $label Label of the modified field. */
|
||||||
|
public $label;
|
||||||
|
|
||||||
|
/** @var \App\Models\User|null $user Current authenticated user. */
|
||||||
|
public $user;
|
||||||
|
|
||||||
|
/** @var string|null $content Custom content message. */
|
||||||
|
public $content;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new event instance.
|
||||||
|
*
|
||||||
|
* @param \App\Models\Claim $claim
|
||||||
|
* @param string $field
|
||||||
|
* @param string $label
|
||||||
|
* @param \App\Models\User|null $user
|
||||||
|
* @param string|null $content
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function __construct(
|
||||||
|
Claim $claim,
|
||||||
|
string $field,
|
||||||
|
string $label,
|
||||||
|
User|null $user = null,
|
||||||
|
string|null $content = null,
|
||||||
|
) {
|
||||||
|
$this->claim = $claim;
|
||||||
|
$this->field = $field;
|
||||||
|
$this->label = $label;
|
||||||
|
$this->user = $user;
|
||||||
|
$this->content = $content;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,13 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Exceptions;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This class Exception is used to skip a row import from
|
|
||||||
* database migration (2016 -> 2020)
|
|
||||||
*
|
|
||||||
* @author Jérémy Munsch <jeremy.munsch@ldc.fr>
|
|
||||||
*/
|
|
||||||
class AbortRowImportException extends \RuntimeException
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
@ -155,7 +155,7 @@ class Handler extends ExceptionHandler
|
||||||
// @codeCoverageIgnoreStart
|
// @codeCoverageIgnoreStart
|
||||||
if (config('app.env') === 'testing') {
|
if (config('app.env') === 'testing') {
|
||||||
// phpcs:ignore Squiz.PHP.DiscouragedFunctions.Found
|
// phpcs:ignore Squiz.PHP.DiscouragedFunctions.Found
|
||||||
print_r((string)$e);
|
print_r((string) $e);
|
||||||
}
|
}
|
||||||
return $this->getReponse($request, 500, \intval($e->getCode()), $e->getMessage());
|
return $this->getReponse($request, 500, \intval($e->getCode()), $e->getMessage());
|
||||||
// @codeCoverageIgnoreEnd
|
// @codeCoverageIgnoreEnd
|
||||||
|
|
@ -180,13 +180,13 @@ class Handler extends ExceptionHandler
|
||||||
): JsonResponse {
|
): JsonResponse {
|
||||||
if (Helper::isRequestForApiV2($request)) {
|
if (Helper::isRequestForApiV2($request)) {
|
||||||
return (new V2ApiResponse(
|
return (new V2ApiResponse(
|
||||||
(object)array_merge($data, ['message' => $message, 'code' => $apiCode]),
|
ApiStatus::KO,
|
||||||
ApiStatus::KO
|
(object) array_merge($data, ['message' => $message, 'code' => $apiCode]),
|
||||||
))->toResponse($request)->setStatusCode($httpCode);
|
))->toResponse($request)->setStatusCode($httpCode);
|
||||||
}
|
}
|
||||||
return (new V4ApiResponse(
|
return (new V4ApiResponse(
|
||||||
(object)array_merge($data, ['message' => $message, 'code' => $apiCode]),
|
ApiStatus::KO,
|
||||||
ApiStatus::KO
|
(object) array_merge($data, ['message' => $message, 'code' => $apiCode]),
|
||||||
))->toResponse($request)->setStatusCode($httpCode);
|
))->toResponse($request)->setStatusCode($httpCode);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -4,10 +4,9 @@ namespace App\Http\Controllers\Api\V2;
|
||||||
|
|
||||||
use App\Http\Controllers\Controller;
|
use App\Http\Controllers\Controller;
|
||||||
use App\Http\Requests\Api\V2\StoreCustomerAnswers;
|
use App\Http\Requests\Api\V2\StoreCustomerAnswers;
|
||||||
use App\Models\Answer;
|
|
||||||
use App\Models\Customer;
|
use App\Models\Customer;
|
||||||
use App\Models\Service;
|
use App\Models\ModelAnswer;
|
||||||
use Illuminate\Http\JsonResponse;
|
use App\Models\Question;
|
||||||
|
|
||||||
class AnswerController extends Controller
|
class AnswerController extends Controller
|
||||||
{
|
{
|
||||||
|
|
@ -15,21 +14,33 @@ class AnswerController extends Controller
|
||||||
* Store the customer answers.
|
* Store the customer answers.
|
||||||
*
|
*
|
||||||
* @param \App\Http\Requests\Api\V2\StoreCustomerAnswers $request
|
* @param \App\Http\Requests\Api\V2\StoreCustomerAnswers $request
|
||||||
* @param \App\Models\Service $service
|
|
||||||
* @param \App\Models\Customer $customer
|
* @param \App\Models\Customer $customer
|
||||||
* @return \Illuminate\Http\JsonResponse
|
* @return \Illuminate\Http\JsonResponse
|
||||||
*/
|
*/
|
||||||
public function storeCustomerAnswers(
|
public function storeCustomerAnswers(
|
||||||
StoreCustomerAnswers $request,
|
StoreCustomerAnswers $request,
|
||||||
Service $service,
|
|
||||||
Customer $customer
|
Customer $customer
|
||||||
): JsonResponse {
|
): \Illuminate\Http\JsonResponse {
|
||||||
// * Make sure we are accessing a customer that belongs to our service.
|
// * Make sure we are accessing a customer that belongs to our service.
|
||||||
$this->authorize('customerBelongsToService', $customer);
|
$this->authorize('customerBelongsToService', $customer);
|
||||||
|
|
||||||
$existingAnswerIds = $customer->getAnswers($service)->pluck('id');
|
$question = Question::find($request->validated('question'));
|
||||||
$answersID = Answer::query()->whereIn('id', $request->answers)->pluck('id');
|
|
||||||
$customer->answers()->sync($answersID->merge($existingAnswerIds));
|
// Column model_id is varchar because of singleoptin uuid, so force cast in string.
|
||||||
|
ModelAnswer::query()
|
||||||
|
->where('model_type', Customer::class)
|
||||||
|
->where('model_id', (string) $customer->getKey())
|
||||||
|
->whereIn('answer_id', $question->answers->modelKeys())
|
||||||
|
->delete();
|
||||||
|
|
||||||
|
foreach ($request->validated('answers') as $answerId) {
|
||||||
|
ModelAnswer::create([
|
||||||
|
'model_type' => Customer::class,
|
||||||
|
'model_id' => (string) $customer->getKey(),
|
||||||
|
'answer_id' => $answerId,
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
return response()->json();
|
return response()->json();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -34,7 +34,7 @@ class CustomerController extends Controller
|
||||||
*/
|
*/
|
||||||
public function store(StoreCustomerRequest $request, Service $service): JsonResource
|
public function store(StoreCustomerRequest $request, Service $service): JsonResource
|
||||||
{
|
{
|
||||||
$data = (object)$request->validated();
|
$data = (object) $request->validated();
|
||||||
|
|
||||||
/** @var \App\Models\Customer */
|
/** @var \App\Models\Customer */
|
||||||
$customer = Customer::query()->where('email', $data->email)->firstOrCreate([
|
$customer = Customer::query()->where('email', $data->email)->firstOrCreate([
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,6 @@ use App\Http\Requests\Api\V2\SingleOptinRequest;
|
||||||
use App\Http\Requests\Api\V2\SingleOptinRemoveWithHashcodeRequest;
|
use App\Http\Requests\Api\V2\SingleOptinRemoveWithHashcodeRequest;
|
||||||
use App\Models\CustomerInfo;
|
use App\Models\CustomerInfo;
|
||||||
use App\Models\Service;
|
use App\Models\Service;
|
||||||
use Illuminate\Http\JsonResponse;
|
|
||||||
use App\Models\SingleOptin;
|
use App\Models\SingleOptin;
|
||||||
|
|
||||||
class OptinController extends Controller
|
class OptinController extends Controller
|
||||||
|
|
@ -26,24 +25,31 @@ class OptinController extends Controller
|
||||||
* if this email already has a full account.
|
* if this email already has a full account.
|
||||||
* @throws \App\Exceptions\Api\V2\CrmException If the single optin could not be added or removed.
|
* @throws \App\Exceptions\Api\V2\CrmException If the single optin could not be added or removed.
|
||||||
*/
|
*/
|
||||||
public function optin(SingleOptinRequest $request, Service $service): JsonResponse
|
public function optin(SingleOptinRequest $request, Service $service): \Illuminate\Http\JsonResponse
|
||||||
{
|
{
|
||||||
if (CustomerInfo::getFromEmail($service->brand, $request->email)->exists()) {
|
$validatedData = $request->validated();
|
||||||
|
if (CustomerInfo::getFromEmail($service->brand, $validatedData['email'])->exists()) {
|
||||||
throw new ApiErrorException(ApiError::singleOptinCustomerExists);
|
throw new ApiErrorException(ApiError::singleOptinCustomerExists);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @var \App\Models\SingleOptin */
|
/** @var \App\Models\SingleOptin */
|
||||||
$singleOptin = SingleOptin::query()->where('email', $request->email)
|
$singleOptin = SingleOptin::query()
|
||||||
|
->where('email', $validatedData['email'])
|
||||||
->whereHas('brand', function ($q) use ($service) {
|
->whereHas('brand', function ($q) use ($service) {
|
||||||
$q->where('id', $service->brand->id);
|
$q->where('id', $service->brand->id);
|
||||||
})->firstOrNew();
|
})
|
||||||
|
->firstOrNew();
|
||||||
|
|
||||||
if (!$this->changeOptin($service, $request, \boolval($request->opt_in), $singleOptin)) {
|
if (!$this->changeOptin($service, $request, \boolval($validatedData['opt_in']), $singleOptin)) {
|
||||||
// @codeCoverageIgnoreStart
|
// @codeCoverageIgnoreStart
|
||||||
throw new CrmException('Api failed to update single optin.');
|
throw new CrmException('Api failed to update single optin.');
|
||||||
// @codeCoverageIgnoreEnd
|
// @codeCoverageIgnoreEnd
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (isset($validatedData['answer_id'])) {
|
||||||
|
$singleOptin->answers()->attach($validatedData['answer_id']);
|
||||||
|
}
|
||||||
|
|
||||||
return response()->json();
|
return response()->json();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -55,13 +61,17 @@ class OptinController extends Controller
|
||||||
* @return \Illuminate\Http\JsonResponse
|
* @return \Illuminate\Http\JsonResponse
|
||||||
* @throws \App\Exceptions\Api\V2\CrmException If the single optin could not be removed.
|
* @throws \App\Exceptions\Api\V2\CrmException If the single optin could not be removed.
|
||||||
*/
|
*/
|
||||||
public function optoutWithHashcode(SingleOptinRemoveWithHashcodeRequest $request, Service $service): JsonResponse
|
public function optoutWithHashcode(
|
||||||
{
|
SingleOptinRemoveWithHashcodeRequest $request,
|
||||||
|
Service $service
|
||||||
|
): \Illuminate\Http\JsonResponse {
|
||||||
/** @var \App\Models\SingleOptin */
|
/** @var \App\Models\SingleOptin */
|
||||||
$singleOptin = SingleOptin::query()->where('hashcode', $request->hashcode)
|
$singleOptin = SingleOptin::query()
|
||||||
|
->where('hashcode', $request->hashcode)
|
||||||
->whereHas('brand', function ($q) use ($service) {
|
->whereHas('brand', function ($q) use ($service) {
|
||||||
$q->whereId($service->brand->id);
|
$q->whereId($service->brand->id);
|
||||||
})->firstOrFail();
|
})
|
||||||
|
->firstOrFail();
|
||||||
|
|
||||||
if ($singleOptin and !$this->changeOptin($service, $request, \boolval($request->opt_in), $singleOptin)) {
|
if ($singleOptin and !$this->changeOptin($service, $request, \boolval($request->opt_in), $singleOptin)) {
|
||||||
// @codeCoverageIgnoreStart
|
// @codeCoverageIgnoreStart
|
||||||
|
|
|
||||||
|
|
@ -8,10 +8,9 @@ use App\Http\Requests\Api\V2\GetQuestionStatsRequest;
|
||||||
use App\Http\Resources\Api\V2\BrandStatsResource;
|
use App\Http\Resources\Api\V2\BrandStatsResource;
|
||||||
use App\Http\Resources\Api\V2\QuestionStatsResource;
|
use App\Http\Resources\Api\V2\QuestionStatsResource;
|
||||||
use App\Models\BrandStat;
|
use App\Models\BrandStat;
|
||||||
use App\Models\CustomerAnswer;
|
use App\Models\ModelAnswer;
|
||||||
use App\Models\Question;
|
use App\Models\Question;
|
||||||
use App\Models\Service;
|
use App\Models\Service;
|
||||||
use Illuminate\Http\Resources\Json\ResourceCollection;
|
|
||||||
use Illuminate\Support\Carbon;
|
use Illuminate\Support\Carbon;
|
||||||
use Illuminate\Support\Collection;
|
use Illuminate\Support\Collection;
|
||||||
|
|
||||||
|
|
@ -24,8 +23,10 @@ class StatsController extends Controller
|
||||||
* @param \App\Models\Service $service
|
* @param \App\Models\Service $service
|
||||||
* @return \Illuminate\Http\Resources\Json\ResourceCollection
|
* @return \Illuminate\Http\Resources\Json\ResourceCollection
|
||||||
*/
|
*/
|
||||||
public function brandStats(GetBrandStatsRequest $request, Service $service): ResourceCollection
|
public function brandStats(
|
||||||
{
|
GetBrandStatsRequest $request,
|
||||||
|
Service $service
|
||||||
|
): \Illuminate\Http\Resources\Json\ResourceCollection {
|
||||||
$stats = BrandStat::query()->whereDate('created_at', '>=', $request->start)
|
$stats = BrandStat::query()->whereDate('created_at', '>=', $request->start)
|
||||||
->whereDate('created_at', '<=', $request->end)
|
->whereDate('created_at', '<=', $request->end)
|
||||||
->whereBrandId($service->brand->id)->get();
|
->whereBrandId($service->brand->id)->get();
|
||||||
|
|
@ -39,8 +40,10 @@ class StatsController extends Controller
|
||||||
* @param \App\Models\Question $question
|
* @param \App\Models\Question $question
|
||||||
* @return \App\Http\Resources\Api\V2\QuestionStatsResource
|
* @return \App\Http\Resources\Api\V2\QuestionStatsResource
|
||||||
*/
|
*/
|
||||||
public function questionStats(GetQuestionStatsRequest $request, Question $question): QuestionStatsResource
|
public function questionStats(
|
||||||
{
|
GetQuestionStatsRequest $request,
|
||||||
|
Question $question
|
||||||
|
): \App\Http\Resources\Api\V2\QuestionStatsResource {
|
||||||
// * Make sure we are accessing a customer that belongs to our service.
|
// * Make sure we are accessing a customer that belongs to our service.
|
||||||
$this->authorize('questionBelongsToService', $question);
|
$this->authorize('questionBelongsToService', $question);
|
||||||
|
|
||||||
|
|
@ -62,18 +65,22 @@ class StatsController extends Controller
|
||||||
* @param \Illuminate\Support\Carbon $end
|
* @param \Illuminate\Support\Carbon $end
|
||||||
* @return \Illuminate\Support\Collection
|
* @return \Illuminate\Support\Collection
|
||||||
*/
|
*/
|
||||||
private function answersByDays(Collection $answers, Carbon $start, Carbon $end): Collection
|
private function answersByDays(Collection $answers, Carbon $start, Carbon $end): \Illuminate\Support\Collection
|
||||||
{
|
{
|
||||||
// * Totalize by date all answers.
|
// * Totalize by date all answers.
|
||||||
$answersByDays = CustomerAnswer::query()->whereDate('created_at', '>=', $start)
|
$answersByDays = ModelAnswer::query()
|
||||||
|
->whereDate('created_at', '>=', $start)
|
||||||
->whereDate('created_at', '<=', $end)
|
->whereDate('created_at', '<=', $end)
|
||||||
->whereIn('answer_id', $answers->pluck('id'))
|
->whereIn('answer_id', $answers->pluck('id'))
|
||||||
->get()->map(function ($custAnswer) {
|
->get()
|
||||||
|
->map(function ($custAnswer) {
|
||||||
return [
|
return [
|
||||||
'answer_id' => $custAnswer->answer_id,
|
'answer_id' => $custAnswer->answer_id,
|
||||||
'created_at' => $custAnswer->created_at->isoFormat('YYYY-MM-DD'),
|
'created_at' => $custAnswer->created_at->isoFormat('YYYY-MM-DD'),
|
||||||
];
|
];
|
||||||
})->groupBy(['created_at', 'answer_id'])->map(function ($day) {
|
})
|
||||||
|
->groupBy(['created_at', 'answer_id'])
|
||||||
|
->map(function ($day) {
|
||||||
return $day->map(function ($custAnswers) {
|
return $day->map(function ($custAnswers) {
|
||||||
return $custAnswers->count();
|
return $custAnswers->count();
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -4,10 +4,9 @@ namespace App\Http\Controllers\Api\V4;
|
||||||
|
|
||||||
use App\Http\Controllers\Controller;
|
use App\Http\Controllers\Controller;
|
||||||
use App\Http\Requests\Api\V4\StoreCustomerAnswers;
|
use App\Http\Requests\Api\V4\StoreCustomerAnswers;
|
||||||
use App\Models\Answer;
|
|
||||||
use App\Models\Customer;
|
use App\Models\Customer;
|
||||||
use App\Models\Service;
|
use App\Models\ModelAnswer;
|
||||||
use Illuminate\Http\JsonResponse;
|
use App\Models\Question;
|
||||||
|
|
||||||
class AnswerController extends Controller
|
class AnswerController extends Controller
|
||||||
{
|
{
|
||||||
|
|
@ -15,21 +14,33 @@ class AnswerController extends Controller
|
||||||
* Store the customer answers.
|
* Store the customer answers.
|
||||||
*
|
*
|
||||||
* @param \App\Http\Requests\Api\V4\StoreCustomerAnswers $request
|
* @param \App\Http\Requests\Api\V4\StoreCustomerAnswers $request
|
||||||
* @param \App\Models\Service $service
|
|
||||||
* @param \App\Models\Customer $customer
|
* @param \App\Models\Customer $customer
|
||||||
* @return \Illuminate\Http\JsonResponse
|
* @return \Illuminate\Http\JsonResponse
|
||||||
*/
|
*/
|
||||||
public function storeCustomerAnswers(
|
public function storeCustomerAnswers(
|
||||||
StoreCustomerAnswers $request,
|
StoreCustomerAnswers $request,
|
||||||
Service $service,
|
|
||||||
Customer $customer
|
Customer $customer
|
||||||
): JsonResponse {
|
): \Illuminate\Http\JsonResponse {
|
||||||
// * Make sure we are accessing a customer that belongs to our service.
|
// * Make sure we are accessing a customer that belongs to our service.
|
||||||
$this->authorize('customerBelongsToService', $customer);
|
$this->authorize('customerBelongsToService', $customer);
|
||||||
|
|
||||||
$existingAnswerIds = $customer->getAnswers($service)->pluck('id');
|
$question = Question::find($request->validated('question'));
|
||||||
$answersID = Answer::query()->whereIn('id', $request->answers)->pluck('id');
|
|
||||||
$customer->answers()->sync($answersID->merge($existingAnswerIds));
|
// Column model_id is varchar because of singleoptin uuid, so force cast in string.
|
||||||
|
ModelAnswer::query()
|
||||||
|
->where('model_type', Customer::class)
|
||||||
|
->where('model_id', (string) $customer->getKey())
|
||||||
|
->whereIn('answer_id', $question->answers->modelKeys())
|
||||||
|
->delete();
|
||||||
|
|
||||||
|
foreach ($request->validated('answers') as $answerId) {
|
||||||
|
ModelAnswer::create([
|
||||||
|
'model_type' => Customer::class,
|
||||||
|
'model_id' => (string) $customer->getKey(),
|
||||||
|
'answer_id' => $answerId,
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
return response()->json();
|
return response()->json();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
51
app/Http/Controllers/Api/V4/ClaimController.php
Normal file
51
app/Http/Controllers/Api/V4/ClaimController.php
Normal file
|
|
@ -0,0 +1,51 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Controllers\Api\V4;
|
||||||
|
|
||||||
|
use App\Exceptions\Api\V4\CrmException;
|
||||||
|
use App\Http\Controllers\Controller;
|
||||||
|
use App\Http\Requests\Api\V4\SendClaimRequest;
|
||||||
|
use App\Models\Claim;
|
||||||
|
use App\Models\CustomerInfo;
|
||||||
|
use App\Models\Service;
|
||||||
|
use Illuminate\Support\Arr;
|
||||||
|
use Uwil\LaravelCommon\Helpers\FileHelper;
|
||||||
|
|
||||||
|
class ClaimController extends Controller
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Just returns HTTP 200 response.
|
||||||
|
*
|
||||||
|
* @param \App\Http\Requests\Api\V4\SendClaimRequest $request
|
||||||
|
* @param \App\Models\Service $service
|
||||||
|
* @return \Illuminate\Http\JsonResponse
|
||||||
|
* @throws \App\Exceptions\Api\V4\CrmException If the single optin could not be added or removed.
|
||||||
|
*/
|
||||||
|
public function store(SendClaimRequest $request, Service $service): \Illuminate\Http\JsonResponse
|
||||||
|
{
|
||||||
|
$claimModel = (new Claim())->fill(Arr::except($request->validated(), 'file'));
|
||||||
|
if ($request->filled('file')) {
|
||||||
|
$claimModel->file = FileHelper::storeBase64File(
|
||||||
|
tableName: 'claim',
|
||||||
|
fileBase64: $request->file,
|
||||||
|
private: true,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add brand id from service.
|
||||||
|
$claimModel->brand_id = $service->brand->getKey();
|
||||||
|
|
||||||
|
// Add customer relation if exist.
|
||||||
|
$crmCustomer = CustomerInfo::getFromEmail($claimModel->brand, $claimModel->email)->first();
|
||||||
|
if (!is_null($crmCustomer)) {
|
||||||
|
$claimModel->hashcode = $crmCustomer->hashcode;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!$claimModel->saveOrFail()) {
|
||||||
|
throw new CrmException('Api failed to store claim.');
|
||||||
|
}
|
||||||
|
$claimModel->brand()->associate($service->brand);
|
||||||
|
|
||||||
|
return response()->json();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -34,7 +34,7 @@ class CustomerController extends Controller
|
||||||
*/
|
*/
|
||||||
public function store(StoreCustomerRequest $request, Service $service): JsonResource
|
public function store(StoreCustomerRequest $request, Service $service): JsonResource
|
||||||
{
|
{
|
||||||
$data = (object)$request->validated();
|
$data = (object) $request->validated();
|
||||||
|
|
||||||
/** @var \App\Models\Customer */
|
/** @var \App\Models\Customer */
|
||||||
$customer = Customer::query()->where('email', $data->email)->firstOrCreate([
|
$customer = Customer::query()->where('email', $data->email)->firstOrCreate([
|
||||||
|
|
|
||||||
|
|
@ -2,8 +2,6 @@
|
||||||
|
|
||||||
namespace App\Http\Controllers\Api\V4;
|
namespace App\Http\Controllers\Api\V4;
|
||||||
|
|
||||||
use App\Enums\ApiError;
|
|
||||||
use App\Exceptions\Api\V4\ApiErrorException;
|
|
||||||
use App\Exceptions\Api\V4\CrmException;
|
use App\Exceptions\Api\V4\CrmException;
|
||||||
use App\Http\Controllers\Controller;
|
use App\Http\Controllers\Controller;
|
||||||
use App\Http\Requests\Api\V4\BaseApiRequest;
|
use App\Http\Requests\Api\V4\BaseApiRequest;
|
||||||
|
|
@ -11,7 +9,6 @@ use App\Http\Requests\Api\V4\SingleOptinRequest;
|
||||||
use App\Http\Requests\Api\V4\SingleOptinRemoveWithHashcodeRequest;
|
use App\Http\Requests\Api\V4\SingleOptinRemoveWithHashcodeRequest;
|
||||||
use App\Models\CustomerInfo;
|
use App\Models\CustomerInfo;
|
||||||
use App\Models\Service;
|
use App\Models\Service;
|
||||||
use Illuminate\Http\JsonResponse;
|
|
||||||
use App\Models\SingleOptin;
|
use App\Models\SingleOptin;
|
||||||
|
|
||||||
class OptinController extends Controller
|
class OptinController extends Controller
|
||||||
|
|
@ -22,27 +19,49 @@ class OptinController extends Controller
|
||||||
* @param \App\Http\Requests\Api\V4\SingleOptinRequest $request
|
* @param \App\Http\Requests\Api\V4\SingleOptinRequest $request
|
||||||
* @param \App\Models\Service $service
|
* @param \App\Models\Service $service
|
||||||
* @return \Illuminate\Http\JsonResponse
|
* @return \Illuminate\Http\JsonResponse
|
||||||
* @throws \App\Exceptions\Api\V4\ApiErrorException With ApiError::singleOptinCustomerExists
|
|
||||||
* if this email already has a full account.
|
|
||||||
* @throws \App\Exceptions\Api\V4\CrmException If the single optin could not be added or removed.
|
* @throws \App\Exceptions\Api\V4\CrmException If the single optin could not be added or removed.
|
||||||
*/
|
*/
|
||||||
public function optin(SingleOptinRequest $request, Service $service): JsonResponse
|
public function optin(SingleOptinRequest $request, Service $service): \Illuminate\Http\JsonResponse
|
||||||
{
|
{
|
||||||
if (CustomerInfo::getFromEmail($service->brand, $request->email)->exists()) {
|
$validatedData = $request->validated();
|
||||||
throw new ApiErrorException(ApiError::singleOptinCustomerExists);
|
$crmCustomer = CustomerInfo::getFromEmail($service->brand, $validatedData['email'])->first();
|
||||||
}
|
if ($crmCustomer) {
|
||||||
|
// Update the optin field.
|
||||||
|
$crmCustomer->opt_in = \boolval($validatedData['opt_in']);
|
||||||
|
|
||||||
/** @var \App\Models\SingleOptin */
|
// Check the saving.
|
||||||
$singleOptin = SingleOptin::query()->where('email', $request->email)
|
if (!$crmCustomer->saveOrFail()) {
|
||||||
->whereHas('brand', function ($q) use ($service) {
|
// @codeCoverageIgnoreStart
|
||||||
$q->where('id', $service->brand->id);
|
throw new CrmException('Api failed to update customer optin.');
|
||||||
})->firstOrNew();
|
// @codeCoverageIgnoreEnd
|
||||||
|
}
|
||||||
|
|
||||||
if (!$this->changeOptin($service, $request, \boolval($request->opt_in), $singleOptin)) {
|
// Associate answers if presents.
|
||||||
// @codeCoverageIgnoreStart
|
if (isset($validatedData['answer_id'])) {
|
||||||
throw new CrmException('Api failed to update single optin.');
|
$crmCustomer->answers()->attach($validatedData['answer_id']);
|
||||||
// @codeCoverageIgnoreEnd
|
}
|
||||||
}
|
} else {
|
||||||
|
// Get the single optin if exist or create it.
|
||||||
|
/** @var \App\Models\SingleOptin */
|
||||||
|
$singleOptin = SingleOptin::query()
|
||||||
|
->where('email', $validatedData['email'])
|
||||||
|
->whereHas('brand', function ($q) use ($service) {
|
||||||
|
$q->whereKey($service->brand->getKey());
|
||||||
|
})
|
||||||
|
->firstOrNew();
|
||||||
|
|
||||||
|
// Update the optin field and check the saving.
|
||||||
|
if (!$this->changeOptin($service, $request, \boolval($validatedData['opt_in']), $singleOptin)) {
|
||||||
|
// @codeCoverageIgnoreStart
|
||||||
|
throw new CrmException('Api failed to update single optin.');
|
||||||
|
// @codeCoverageIgnoreEnd
|
||||||
|
}
|
||||||
|
|
||||||
|
// Associate answers if presents.
|
||||||
|
if (isset($validatedData['answer_id'])) {
|
||||||
|
$singleOptin->answers()->attach($validatedData['answer_id']);
|
||||||
|
}
|
||||||
|
} //end if
|
||||||
|
|
||||||
return response()->json();
|
return response()->json();
|
||||||
}
|
}
|
||||||
|
|
@ -55,19 +74,37 @@ class OptinController extends Controller
|
||||||
* @return \Illuminate\Http\JsonResponse
|
* @return \Illuminate\Http\JsonResponse
|
||||||
* @throws \App\Exceptions\Api\V4\CrmException If the single optin could not be removed.
|
* @throws \App\Exceptions\Api\V4\CrmException If the single optin could not be removed.
|
||||||
*/
|
*/
|
||||||
public function optoutWithHashcode(SingleOptinRemoveWithHashcodeRequest $request, Service $service): JsonResponse
|
public function optoutWithHashcode(
|
||||||
{
|
SingleOptinRemoveWithHashcodeRequest $request,
|
||||||
/** @var \App\Models\SingleOptin */
|
Service $service
|
||||||
$singleOptin = SingleOptin::query()->where('hashcode', $request->hashcode)
|
): \Illuminate\Http\JsonResponse {
|
||||||
->whereHas('brand', function ($q) use ($service) {
|
$validatedData = $request->validated();
|
||||||
$q->whereId($service->brand->id);
|
$crmCustomer = CustomerInfo::getFromHashcode($service->brand, $validatedData['hashcode'])->first();
|
||||||
})->firstOrFail();
|
if ($crmCustomer) {
|
||||||
|
// Update the optin field.
|
||||||
|
$crmCustomer->opt_in = false;
|
||||||
|
|
||||||
if ($singleOptin and !$this->changeOptin($service, $request, \boolval($request->opt_in), $singleOptin)) {
|
// Check the saving.
|
||||||
// @codeCoverageIgnoreStart
|
if (!$crmCustomer->saveOrFail()) {
|
||||||
throw new CrmException('Api failed to update single optin.');
|
// @codeCoverageIgnoreStart
|
||||||
// @codeCoverageIgnoreEnd
|
throw new CrmException('Api failed to update customer optin.');
|
||||||
}
|
// @codeCoverageIgnoreEnd
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Get the single optin if exist or create it.
|
||||||
|
/** @var \App\Models\SingleOptin */
|
||||||
|
$singleOptin = SingleOptin::query()->where('hashcode', $validatedData['hashcode'])
|
||||||
|
->whereHas('brand', function ($q) use ($service) {
|
||||||
|
$q->whereId($service->brand->getKey());
|
||||||
|
})->firstOrFail();
|
||||||
|
|
||||||
|
// Update the optin field and check the saving.
|
||||||
|
if ($singleOptin and !$this->changeOptin($service, $request, false, $singleOptin)) {
|
||||||
|
// @codeCoverageIgnoreStart
|
||||||
|
throw new CrmException('Api failed to update single optin.');
|
||||||
|
// @codeCoverageIgnoreEnd
|
||||||
|
}
|
||||||
|
} //end if
|
||||||
|
|
||||||
return response()->json();
|
return response()->json();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -8,8 +8,6 @@ use App\Models\Answer;
|
||||||
use App\Models\Customer;
|
use App\Models\Customer;
|
||||||
use App\Models\Question;
|
use App\Models\Question;
|
||||||
use App\Models\Service;
|
use App\Models\Service;
|
||||||
use Illuminate\Http\Resources\Json\JsonResource;
|
|
||||||
use Illuminate\Http\Resources\Json\ResourceCollection;
|
|
||||||
|
|
||||||
class QuestionController extends Controller
|
class QuestionController extends Controller
|
||||||
{
|
{
|
||||||
|
|
@ -19,7 +17,7 @@ class QuestionController extends Controller
|
||||||
* @param \App\Models\Service $service
|
* @param \App\Models\Service $service
|
||||||
* @return \Illuminate\Http\Resources\Json\ResourceCollection
|
* @return \Illuminate\Http\Resources\Json\ResourceCollection
|
||||||
*/
|
*/
|
||||||
public function index(Service $service): ResourceCollection
|
public function index(Service $service): \Illuminate\Http\Resources\Json\ResourceCollection
|
||||||
{
|
{
|
||||||
return new QuestionsResource($service->brand->questions);
|
return new QuestionsResource($service->brand->questions);
|
||||||
}
|
}
|
||||||
|
|
@ -31,8 +29,10 @@ class QuestionController extends Controller
|
||||||
* @param \App\Models\Customer $customer
|
* @param \App\Models\Customer $customer
|
||||||
* @return \Illuminate\Http\Resources\Json\ResourceCollection
|
* @return \Illuminate\Http\Resources\Json\ResourceCollection
|
||||||
*/
|
*/
|
||||||
public function indexWithResponse(Service $service, Customer $customer): ResourceCollection
|
public function indexWithResponse(
|
||||||
{
|
Service $service,
|
||||||
|
Customer $customer
|
||||||
|
): \Illuminate\Http\Resources\Json\ResourceCollection {
|
||||||
// * Make sure we are accessing a customer that belongs to our service.
|
// * Make sure we are accessing a customer that belongs to our service.
|
||||||
$this->authorize('customerBelongsToService', $customer);
|
$this->authorize('customerBelongsToService', $customer);
|
||||||
|
|
||||||
|
|
@ -47,18 +47,22 @@ class QuestionController extends Controller
|
||||||
* @param \App\Models\Customer $customer
|
* @param \App\Models\Customer $customer
|
||||||
* @return \Illuminate\Http\Resources\Json\JsonResource
|
* @return \Illuminate\Http\Resources\Json\JsonResource
|
||||||
*/
|
*/
|
||||||
public function unAnsweredBy(Service $service, Customer $customer): JsonResource
|
public function unAnsweredBy(Service $service, Customer $customer): \Illuminate\Http\Resources\Json\JsonResource
|
||||||
{
|
{
|
||||||
// * Make sure we are accessing a customer that belongs to our service.
|
// * Make sure we are accessing a customer that belongs to our service.
|
||||||
$this->authorize('customerBelongsToService', $customer);
|
$this->authorize('customerBelongsToService', $customer);
|
||||||
|
|
||||||
$questions = Question::query()->whereHas('brand', function ($q) use ($service) {
|
$questions = Question::query()
|
||||||
$q->where('id', $service->brand->id);
|
->whereHas('brand', function ($q) use ($service) {
|
||||||
})->whereDoesntHave('answers', function ($q) use ($customer) {
|
$q->where('id', $service->brand->id);
|
||||||
$q->whereIn('id', Answer::query()->whereHas('customers', function ($q) use ($customer) {
|
})
|
||||||
$q->where('id', $customer->id);
|
->whereDoesntHave('answers', function ($q) use ($customer) {
|
||||||
})->pluck('id'));
|
$q->whereIn('id', Answer::query()->whereHas('customers', function ($q) use ($customer) {
|
||||||
})->with('answers')->get();
|
$q->where('id', $customer->id);
|
||||||
|
})->pluck('id'));
|
||||||
|
})
|
||||||
|
->with('answers')
|
||||||
|
->get();
|
||||||
return new QuestionsResource($questions);
|
return new QuestionsResource($questions);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -8,10 +8,9 @@ use App\Http\Requests\Api\V4\GetQuestionStatsRequest;
|
||||||
use App\Http\Resources\Api\V4\BrandStatsResource;
|
use App\Http\Resources\Api\V4\BrandStatsResource;
|
||||||
use App\Http\Resources\Api\V4\QuestionStatsResource;
|
use App\Http\Resources\Api\V4\QuestionStatsResource;
|
||||||
use App\Models\BrandStat;
|
use App\Models\BrandStat;
|
||||||
use App\Models\CustomerAnswer;
|
use App\Models\ModelAnswer;
|
||||||
use App\Models\Question;
|
use App\Models\Question;
|
||||||
use App\Models\Service;
|
use App\Models\Service;
|
||||||
use Illuminate\Http\Resources\Json\ResourceCollection;
|
|
||||||
use Illuminate\Support\Carbon;
|
use Illuminate\Support\Carbon;
|
||||||
use Illuminate\Support\Collection;
|
use Illuminate\Support\Collection;
|
||||||
|
|
||||||
|
|
@ -24,8 +23,10 @@ class StatsController extends Controller
|
||||||
* @param \App\Models\Service $service
|
* @param \App\Models\Service $service
|
||||||
* @return \Illuminate\Http\Resources\Json\ResourceCollection
|
* @return \Illuminate\Http\Resources\Json\ResourceCollection
|
||||||
*/
|
*/
|
||||||
public function brandStats(GetBrandStatsRequest $request, Service $service): ResourceCollection
|
public function brandStats(
|
||||||
{
|
GetBrandStatsRequest $request,
|
||||||
|
Service $service
|
||||||
|
): \Illuminate\Http\Resources\Json\ResourceCollection {
|
||||||
$stats = BrandStat::query()->whereDate('created_at', '>=', $request->start)
|
$stats = BrandStat::query()->whereDate('created_at', '>=', $request->start)
|
||||||
->whereDate('created_at', '<=', $request->end)
|
->whereDate('created_at', '<=', $request->end)
|
||||||
->whereBrandId($service->brand->id)->get();
|
->whereBrandId($service->brand->id)->get();
|
||||||
|
|
@ -39,8 +40,10 @@ class StatsController extends Controller
|
||||||
* @param \App\Models\Question $question
|
* @param \App\Models\Question $question
|
||||||
* @return \App\Http\Resources\Api\V4\QuestionStatsResource
|
* @return \App\Http\Resources\Api\V4\QuestionStatsResource
|
||||||
*/
|
*/
|
||||||
public function questionStats(GetQuestionStatsRequest $request, Question $question): QuestionStatsResource
|
public function questionStats(
|
||||||
{
|
GetQuestionStatsRequest $request,
|
||||||
|
Question $question
|
||||||
|
): \App\Http\Resources\Api\V4\QuestionStatsResource {
|
||||||
// * Make sure we are accessing a customer that belongs to our service.
|
// * Make sure we are accessing a customer that belongs to our service.
|
||||||
$this->authorize('questionBelongsToService', $question);
|
$this->authorize('questionBelongsToService', $question);
|
||||||
|
|
||||||
|
|
@ -62,18 +65,22 @@ class StatsController extends Controller
|
||||||
* @param \Illuminate\Support\Carbon $end
|
* @param \Illuminate\Support\Carbon $end
|
||||||
* @return \Illuminate\Support\Collection
|
* @return \Illuminate\Support\Collection
|
||||||
*/
|
*/
|
||||||
private function answersByDays(Collection $answers, Carbon $start, Carbon $end): Collection
|
private function answersByDays(Collection $answers, Carbon $start, Carbon $end): \Illuminate\Support\Collection
|
||||||
{
|
{
|
||||||
// * Totalize by date all answers.
|
// * Totalize by date all answers.
|
||||||
$answersByDays = CustomerAnswer::query()->whereDate('created_at', '>=', $start)
|
$answersByDays = ModelAnswer::query()
|
||||||
|
->whereDate('created_at', '>=', $start)
|
||||||
->whereDate('created_at', '<=', $end)
|
->whereDate('created_at', '<=', $end)
|
||||||
->whereIn('answer_id', $answers->pluck('id'))
|
->whereIn('answer_id', $answers->pluck('id'))
|
||||||
->get()->map(function ($custAnswer) {
|
->get()
|
||||||
|
->map(function ($custAnswer) {
|
||||||
return [
|
return [
|
||||||
'answer_id' => $custAnswer->answer_id,
|
'answer_id' => $custAnswer->answer_id,
|
||||||
'created_at' => $custAnswer->created_at->isoFormat('YYYY-MM-DD'),
|
'created_at' => $custAnswer->created_at->isoFormat('YYYY-MM-DD'),
|
||||||
];
|
];
|
||||||
})->groupBy(['created_at', 'answer_id'])->map(function ($day) {
|
})
|
||||||
|
->groupBy(['created_at', 'answer_id'])
|
||||||
|
->map(function ($day) {
|
||||||
return $day->map(function ($custAnswers) {
|
return $day->map(function ($custAnswers) {
|
||||||
return $custAnswers->count();
|
return $custAnswers->count();
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -13,6 +13,14 @@ class ActivityLogsController extends Controller
|
||||||
use ChangesModelOrder;
|
use ChangesModelOrder;
|
||||||
use UpdateModelPublished;
|
use UpdateModelPublished;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create the controller instance.
|
||||||
|
*/
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
$this->authorizeResource(ActivityLog::class);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Display a listing of the resource.
|
* Display a listing of the resource.
|
||||||
*
|
*
|
||||||
|
|
@ -43,7 +51,7 @@ class ActivityLogsController extends Controller
|
||||||
$this->sortQuery($query);
|
$this->sortQuery($query);
|
||||||
|
|
||||||
/** Custom pagination */
|
/** Custom pagination */
|
||||||
$activitylogModels = $this->paginate($query);
|
$activitylogModels = $query->paginate($this->getPagination());
|
||||||
|
|
||||||
return view('bo.pages.activity_logs.index', compact('activitylogModels', 'search', 'searchFields'));
|
return view('bo.pages.activity_logs.index', compact('activitylogModels', 'search', 'searchFields'));
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -13,6 +13,14 @@ use Illuminate\Support\Str;
|
||||||
|
|
||||||
class AnswerController extends Controller
|
class AnswerController extends Controller
|
||||||
{
|
{
|
||||||
|
/**
|
||||||
|
* Create the controller instance.
|
||||||
|
*/
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
$this->authorizeResource(Answer::class);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Display a listing of the resource.
|
* Display a listing of the resource.
|
||||||
*
|
*
|
||||||
|
|
@ -24,22 +32,22 @@ class AnswerController extends Controller
|
||||||
/** @var \App\Models\Question $questionModel */
|
/** @var \App\Models\Question $questionModel */
|
||||||
$questionModel = $request->question;
|
$questionModel = $request->question;
|
||||||
|
|
||||||
/** @var \Illuminate\Database\Eloquent\Builder $answers */
|
/** @var \Illuminate\Database\Eloquent\Builder $query */
|
||||||
$answers = Answer::query()->where('question_id', $questionModel->id);
|
$query = Answer::query()->where('question_id', $questionModel->id);
|
||||||
|
|
||||||
if ($request->search) {
|
if ($request->search) {
|
||||||
$this->searchQuery(
|
$this->searchQuery(
|
||||||
$answers,
|
$query,
|
||||||
$request->search,
|
$request->search,
|
||||||
null,
|
null,
|
||||||
'answer',
|
'answer',
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->sortQuery($answers);
|
$this->sortQuery($query);
|
||||||
$searchFields = trans('Réponse');
|
$searchFields = trans('Réponse');
|
||||||
|
|
||||||
$answerModels = $this->paginate($answers);
|
$answerModels = $query->paginate($this->getPagination());
|
||||||
|
|
||||||
return view('bo.pages.answers.index', compact('answerModels', 'questionModel', 'searchFields'));
|
return view('bo.pages.answers.index', compact('answerModels', 'questionModel', 'searchFields'));
|
||||||
}
|
}
|
||||||
|
|
@ -57,8 +65,8 @@ class AnswerController extends Controller
|
||||||
$questionModel = $request->question;
|
$questionModel = $request->question;
|
||||||
|
|
||||||
return view('bo.pages.answers.create', [
|
return view('bo.pages.answers.create', [
|
||||||
'answerModel' => $answer,
|
'answerModel' => $answer,
|
||||||
'questionModel' => $questionModel
|
'questionModel' => $questionModel,
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -73,9 +81,11 @@ class AnswerController extends Controller
|
||||||
return DB::transaction(function () use ($request) {
|
return DB::transaction(function () use ($request) {
|
||||||
$answer = new Answer();
|
$answer = new Answer();
|
||||||
$answer->fill($request->validated());
|
$answer->fill($request->validated());
|
||||||
|
$questionModel = $request->route()->parameter('question');
|
||||||
|
$answer->question()->associate($questionModel->getKey());
|
||||||
if ($answer->saveOrFail()) {
|
if ($answer->saveOrFail()) {
|
||||||
return redirect()
|
return redirect()
|
||||||
->route('bo.answers.edit', $answer)
|
->route('bo.questions.answers.edit', ['question' => $questionModel, 'answer' => $answer])
|
||||||
->with('success', trans(
|
->with('success', trans(
|
||||||
':model a été créé.',
|
':model a été créé.',
|
||||||
['model' => Str::singular(trans('models.classes.answers'))]
|
['model' => Str::singular(trans('models.classes.answers'))]
|
||||||
|
|
@ -100,8 +110,8 @@ class AnswerController extends Controller
|
||||||
public function edit(Question $question, Answer $answers): \Illuminate\Contracts\View\View
|
public function edit(Question $question, Answer $answers): \Illuminate\Contracts\View\View
|
||||||
{
|
{
|
||||||
return view('bo.pages.answers.edit', [
|
return view('bo.pages.answers.edit', [
|
||||||
'answerModel' => $answers,
|
'answerModel' => $answers,
|
||||||
'questionModel' => $question
|
'questionModel' => $question,
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -146,6 +156,7 @@ class AnswerController extends Controller
|
||||||
*/
|
*/
|
||||||
public function destroy(Question $question, Answer $answer): \Illuminate\Http\RedirectResponse
|
public function destroy(Question $question, Answer $answer): \Illuminate\Http\RedirectResponse
|
||||||
{
|
{
|
||||||
|
$answer->singleOptins()->detach();
|
||||||
if ($answer->deleteOrFail()) {
|
if ($answer->deleteOrFail()) {
|
||||||
return redirect()->route('bo.questions.answers.index', $question)
|
return redirect()->route('bo.questions.answers.index', $question)
|
||||||
->with('success', trans(
|
->with('success', trans(
|
||||||
|
|
|
||||||
|
|
@ -5,14 +5,24 @@ namespace App\Http\Controllers\Bo;
|
||||||
use App\Http\Controllers\Controller;
|
use App\Http\Controllers\Controller;
|
||||||
use App\Http\Requests\Bo\Brands\StoreBrandRequest;
|
use App\Http\Requests\Bo\Brands\StoreBrandRequest;
|
||||||
use App\Http\Requests\Bo\Brands\UpdateBrandRequest;
|
use App\Http\Requests\Bo\Brands\UpdateBrandRequest;
|
||||||
|
use App\Http\Requests\Bo\PaginateModelsRequest;
|
||||||
use App\Models\Brand;
|
use App\Models\Brand;
|
||||||
use Illuminate\Database\Eloquent\Builder;
|
use Illuminate\Database\Eloquent\Builder;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
use Illuminate\Support\Facades\DB;
|
use Illuminate\Support\Facades\DB;
|
||||||
use Illuminate\Support\Str;
|
use Illuminate\Support\Str;
|
||||||
|
use Uwil\LaravelCommon\Helpers\CollectionHelper;
|
||||||
|
|
||||||
class BrandController extends Controller
|
class BrandController extends Controller
|
||||||
{
|
{
|
||||||
|
/**
|
||||||
|
* Create the controller instance.
|
||||||
|
*/
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
$this->authorizeResource(Brand::class);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Display a listing of the resource.
|
* Display a listing of the resource.
|
||||||
*
|
*
|
||||||
|
|
@ -40,7 +50,7 @@ class BrandController extends Controller
|
||||||
$q->where('opt_in', true);
|
$q->where('opt_in', true);
|
||||||
}]);
|
}]);
|
||||||
|
|
||||||
$brandModels = $this->paginate($query);
|
$brandModels = $query->paginate($this->getPagination());
|
||||||
|
|
||||||
return view('bo.pages.brands.index', compact('brandModels', 'searchFields'));
|
return view('bo.pages.brands.index', compact('brandModels', 'searchFields'));
|
||||||
}
|
}
|
||||||
|
|
@ -128,16 +138,18 @@ class BrandController extends Controller
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Store a newly created resource in storage.
|
* Get a paginate resource.
|
||||||
*
|
*
|
||||||
|
* @param \App\Http\Requests\Bo\PaginateModelsRequest $request
|
||||||
* @return \Illuminate\Http\JsonResponse
|
* @return \Illuminate\Http\JsonResponse
|
||||||
*/
|
*/
|
||||||
public function jsonPaginate(): \Illuminate\Http\JsonResponse
|
public function jsonPaginateModels(PaginateModelsRequest $request): \Illuminate\Http\JsonResponse
|
||||||
{
|
{
|
||||||
return DB::transaction(function () {
|
$models = CollectionHelper::paginateManually(
|
||||||
/** @var \App\Models\Brand */
|
Brand::getUserAssociatedBrands(),
|
||||||
$brandModels = Brand::paginate(12);
|
$this->jsonItemPerPagination,
|
||||||
return \response()->json($brandModels ?? 500);
|
(int) $request->validated('page'),
|
||||||
});
|
);
|
||||||
|
return \response()->json($models);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
298
app/Http/Controllers/Bo/ClaimController.php
Normal file
298
app/Http/Controllers/Bo/ClaimController.php
Normal file
|
|
@ -0,0 +1,298 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Controllers\Bo;
|
||||||
|
|
||||||
|
use App\Enums\Claims\ClaimResponseType;
|
||||||
|
use App\Enums\Claims\ClaimStatus;
|
||||||
|
use App\Enums\ExportFormat;
|
||||||
|
use App\Enums\Users\RoleEnum;
|
||||||
|
use App\Events\ClaimModelChanged;
|
||||||
|
use App\Http\Controllers\Controller;
|
||||||
|
use App\Http\Requests\Bo\Claims\ExportClaimRequest;
|
||||||
|
use App\Http\Requests\Bo\Claims\SendClaimAnswerRequest;
|
||||||
|
use App\Http\Requests\Bo\Claims\UpdateClaimRequest;
|
||||||
|
use App\Http\Requests\Bo\Claims\ViewClaimAttachmentRequest;
|
||||||
|
use App\Http\Requests\Bo\PaginateModelsRequest;
|
||||||
|
use App\Lib\Helpers\FileHelper;
|
||||||
|
use App\Mail\ClaimAnswerMail;
|
||||||
|
use App\Models\Brand;
|
||||||
|
use App\Models\Claim;
|
||||||
|
use App\Models\ClaimMailTemplate;
|
||||||
|
use App\Models\ClaimMessage;
|
||||||
|
use App\Models\ClaimSubject;
|
||||||
|
use App\Traits\Controllers\ExportDatas;
|
||||||
|
use App\Traits\Controllers\UpdateModelPublished;
|
||||||
|
use Illuminate\Http\Request;
|
||||||
|
use Illuminate\Support\Facades\DB;
|
||||||
|
use Illuminate\Support\Facades\Mail;
|
||||||
|
use Illuminate\Support\Facades\Storage;
|
||||||
|
use Symfony\Component\HttpFoundation\StreamedResponse;
|
||||||
|
use Uwil\LaravelCommon\Helpers\CollectionHelper;
|
||||||
|
|
||||||
|
class ClaimController extends Controller
|
||||||
|
{
|
||||||
|
use UpdateModelPublished;
|
||||||
|
use ExportDatas;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create the controller instance.
|
||||||
|
*/
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
$this->authorizeResource(Claim::class);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Display a listing of the resource.
|
||||||
|
*
|
||||||
|
* @param \Illuminate\Http\Request $request
|
||||||
|
* @return \Illuminate\Contracts\View\View
|
||||||
|
*/
|
||||||
|
public function index(Request $request): \Illuminate\Contracts\View\View
|
||||||
|
{
|
||||||
|
/** @var \App\Models\User $userModel */
|
||||||
|
$userModel = auth('backend')->user();
|
||||||
|
|
||||||
|
/** @var \Illuminate\Database\Eloquent\Builder $query */
|
||||||
|
$query = Claim::query()
|
||||||
|
->when(
|
||||||
|
$request->filled('brand'),
|
||||||
|
fn($q) => $q->whereHas('brand', fn($q) => $q->where('id', $request->brand))
|
||||||
|
)->when(
|
||||||
|
$userModel->role->equals(RoleEnum::marketing),
|
||||||
|
fn($q) => $q->whereHas('brand', fn($q) => $q->whereIn('id', $userModel->brands->modelKeys()))
|
||||||
|
)
|
||||||
|
->when(
|
||||||
|
$request->filled('subject'),
|
||||||
|
fn($q) => $q->whereHas('claimSubject', fn($q) => $q->where('id', $request->subject))
|
||||||
|
)
|
||||||
|
->when(
|
||||||
|
$request->filled('status'),
|
||||||
|
fn($q) => $q->whereIn('status', $request->status),
|
||||||
|
fn($q) => $q->whereNotIn('status', [ClaimStatus::treated, ClaimStatus::refused])
|
||||||
|
);
|
||||||
|
|
||||||
|
/** @var string $search Search field */
|
||||||
|
$search = $request->search;
|
||||||
|
if ($search) {
|
||||||
|
$this->searchQuery(
|
||||||
|
$query,
|
||||||
|
$search,
|
||||||
|
null,
|
||||||
|
'reference',
|
||||||
|
'first_name',
|
||||||
|
'last_name',
|
||||||
|
'email',
|
||||||
|
);
|
||||||
|
}
|
||||||
|
$searchFields = \implode(', ', [
|
||||||
|
trans('validation.custom.reference'),
|
||||||
|
trans('validation.attributes.first_name'),
|
||||||
|
trans('validation.attributes.last_name'),
|
||||||
|
trans('validation.attributes.email'),
|
||||||
|
]);
|
||||||
|
|
||||||
|
/** Sort columns with a query */
|
||||||
|
$this->sortQuery($query);
|
||||||
|
|
||||||
|
/** Custom pagination */
|
||||||
|
$claimModels = $query->simplePaginate($this->getPagination());
|
||||||
|
|
||||||
|
/** Define request brand filter if user only has 1 brand */
|
||||||
|
if (auth('backend')->user()->brands()->count() === 1) {
|
||||||
|
$request->merge(['brand' => auth('backend')->user()->brands()->value('id')]);
|
||||||
|
};
|
||||||
|
|
||||||
|
$claimSubjectModels = ClaimSubject::query()
|
||||||
|
->when(
|
||||||
|
$request->filled('brand'),
|
||||||
|
fn($q) => $q->whereHas('brand', fn($q) => $q->where('id', $request->brand)),
|
||||||
|
)
|
||||||
|
->when(
|
||||||
|
auth('backend')->user()->brands()->count() === 1,
|
||||||
|
fn($q) => $q->whereHas(
|
||||||
|
'brand',
|
||||||
|
fn($q) => $q->where('id', auth('backend')->user()->brands()->pluck('id'))
|
||||||
|
)
|
||||||
|
);
|
||||||
|
$claimSubjectModels = $request->filled('brand') || (auth('backend')->user()->brands()->count() === 1) ?
|
||||||
|
$claimSubjectModels->orderBy('label', 'ASC')->get() :
|
||||||
|
null;
|
||||||
|
|
||||||
|
return view('bo.pages.claims.index', compact('claimModels', 'search', 'searchFields', 'claimSubjectModels'));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Show the form for editing the specified resource.
|
||||||
|
*
|
||||||
|
* @param App\Models\Claim $claim
|
||||||
|
* @return \Illuminate\Contracts\View\View
|
||||||
|
*/
|
||||||
|
public function edit(Claim $claim): \Illuminate\Contracts\View\View
|
||||||
|
{
|
||||||
|
$customerClaimModels = !is_null($claim->customerInfos) ? Claim::query()
|
||||||
|
->where('hashcode', $claim->customerInfos->hashcode)
|
||||||
|
->whereHas('brand', fn($q) => $q->whereKey($claim->brand->getKey()))
|
||||||
|
->whereNot('id', $claim->getKey())
|
||||||
|
->paginate($this->jsonItemPerPagination) : collect();
|
||||||
|
|
||||||
|
$brandModels = CollectionHelper::paginate(
|
||||||
|
Brand::getUserAssociatedBrands(),
|
||||||
|
$this->jsonItemPerPagination,
|
||||||
|
);
|
||||||
|
$claimMessageModels = ClaimMessage::getAllModelsFromClaim($claim->getKey());
|
||||||
|
$claimSubjectModels = CollectionHelper::paginate(
|
||||||
|
ClaimSubject::getAllModelsFromBrand($claim->brand->getKey()),
|
||||||
|
$this->jsonItemPerPagination,
|
||||||
|
);
|
||||||
|
$claimTemplateModels = CollectionHelper::paginate(
|
||||||
|
ClaimMailTemplate::getAllModelsFromBrand($claim->brand->getKey()),
|
||||||
|
$this->jsonItemPerPagination,
|
||||||
|
);
|
||||||
|
|
||||||
|
return view('bo.pages.claims.edit', [
|
||||||
|
'claimModel' => $claim->load(['brand', 'claimSubject']),
|
||||||
|
'customerClaimModels' => $customerClaimModels,
|
||||||
|
'brandModels' => $brandModels,
|
||||||
|
'claimMessageModels' => $claimMessageModels,
|
||||||
|
'claimSubjectModels' => $claimSubjectModels,
|
||||||
|
'claimTemplateModels' => $claimTemplateModels,
|
||||||
|
'customerInfoModel' => $claim->customerInfos,
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update the specified resource.
|
||||||
|
*
|
||||||
|
* @param \App\Http\Requests\Bo\Claims\UpdateClaimRequest $request
|
||||||
|
* @param \App\Models\Claim $claim
|
||||||
|
* @return \Illuminate\Http\JsonResponse
|
||||||
|
*/
|
||||||
|
public function update(UpdateClaimRequest $request, Claim $claim): \Illuminate\Http\JsonResponse
|
||||||
|
{
|
||||||
|
return DB::transaction(function () use ($request, $claim) {
|
||||||
|
$claim->fill($request->validated());
|
||||||
|
|
||||||
|
if ($claim->saveOrFail()) {
|
||||||
|
$claimMessageModels = ClaimMessage::getAllModelsFromClaim($claim->getKey());
|
||||||
|
return response()->json($claimMessageModels);
|
||||||
|
}
|
||||||
|
return response()->json([], 500);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Send the claim answer.
|
||||||
|
*
|
||||||
|
* @param \App\Http\Requests\Bo\Claims\SendClaimAnswerRequest $request
|
||||||
|
* @param \App\Models\Claim $claim
|
||||||
|
* @return \Illuminate\Http\JsonResponse
|
||||||
|
*/
|
||||||
|
public function answer(SendClaimAnswerRequest $request, Claim $claim): \Illuminate\Http\JsonResponse
|
||||||
|
{
|
||||||
|
return DB::transaction(function () use ($request, $claim) {
|
||||||
|
/** @var \App\Models\User $userModel */
|
||||||
|
$userModel = auth()->user();
|
||||||
|
$enum = ClaimResponseType::manual;
|
||||||
|
$claim->response_type = $enum;
|
||||||
|
$claim->status = ClaimStatus::treated;
|
||||||
|
|
||||||
|
if ($claim->saveOrFail()) {
|
||||||
|
// Get only the content of the response.
|
||||||
|
$content = $request->validated()['content'];
|
||||||
|
|
||||||
|
// Send the response to the claim author.
|
||||||
|
Mail::to($claim->email)->send(new ClaimAnswerMail($claim, $content));
|
||||||
|
|
||||||
|
// Create custom event with content message.
|
||||||
|
// @phpcs:disable Generic.Files.LineLength.TooLong
|
||||||
|
$content = sprintf(
|
||||||
|
"<b>%s %s</b> %s <i class='badge' style='background-color:{$enum->color()}'>%s</i><hr class='my-2'>%s",
|
||||||
|
$userModel->first_name,
|
||||||
|
$userModel->last_name,
|
||||||
|
trans('a modifié :field en', ['field' => trans('validation.custom.response_type')]),
|
||||||
|
$claim->response_type->label(),
|
||||||
|
clean($content),
|
||||||
|
);
|
||||||
|
event(new ClaimModelChanged($claim, '', '', null, $content));
|
||||||
|
// @phpcs:enable
|
||||||
|
|
||||||
|
// Return conversation.
|
||||||
|
$claimMessageModels = ClaimMessage::getAllModelsFromClaim($claim->getKey());
|
||||||
|
return response()->json($claimMessageModels);
|
||||||
|
}
|
||||||
|
return response()->json([], 500);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Undocumented function
|
||||||
|
*
|
||||||
|
* @param ViewClaimAttachmentRequest $request
|
||||||
|
* @param Claim $claim
|
||||||
|
* @return \Symfony\Component\HttpFoundation\BinaryFileResponse
|
||||||
|
*
|
||||||
|
* @phpcs:disable Generic.CodeAnalysis.UnusedFunctionParameter
|
||||||
|
*/
|
||||||
|
public function viewAttachment(
|
||||||
|
ViewClaimAttachmentRequest $request,
|
||||||
|
Claim $claim
|
||||||
|
): \Symfony\Component\HttpFoundation\BinaryFileResponse {
|
||||||
|
// phpcs:enable
|
||||||
|
return response()->file(Storage::disk('private')->path(FileHelper::getPrivateFilePath($claim->file)));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a paginate resource.
|
||||||
|
* Needed to overheight the controller method and add a brand condition.
|
||||||
|
*
|
||||||
|
* @param \App\Http\Requests\Bo\PaginateModelsRequest $request
|
||||||
|
* @return \Illuminate\Http\JsonResponse
|
||||||
|
*/
|
||||||
|
public function jsonClaimPaginateModels(PaginateModelsRequest $request): \Illuminate\Http\JsonResponse
|
||||||
|
{
|
||||||
|
$data = $request->validated();
|
||||||
|
$brandModelKey = $request->route()->parameter('brand')->getKey();
|
||||||
|
$models = CollectionHelper::paginateManually(
|
||||||
|
$data['targetModel']::getAllModelsFromBrand($brandModelKey),
|
||||||
|
$this->jsonItemPerPagination,
|
||||||
|
$request->validated('page'),
|
||||||
|
);
|
||||||
|
return \response()->json($models);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// * EXPORT
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Export claim datas to a given format
|
||||||
|
*
|
||||||
|
* @param ExportClaimRequest $request
|
||||||
|
* @return \Illuminate\Http\Response|Symfony\Component\HttpFoundation\StreamedResponse|\Illuminate\Http\RedirectResponse
|
||||||
|
*/
|
||||||
|
public function export(ExportClaimRequest $request)
|
||||||
|
{
|
||||||
|
/** @var \Illuminate\Database\Eloquent\Collection<int, \App\Models\Claim> $claims*/
|
||||||
|
$claims = Claim::query()->whereIn('id', $request->validated('claimList'))->get();
|
||||||
|
$format = ExportFormat::from($request->validated('format'));
|
||||||
|
|
||||||
|
// * CSV
|
||||||
|
if ($format->equals(ExportFormat::csvWithoutAttachment, ExportFormat::csv)) {
|
||||||
|
$csv = $this->generateCsv($claims);
|
||||||
|
if (!$this->needsZip($format, $claims)) {
|
||||||
|
return new StreamedResponse(function () use ($format, $csv) {
|
||||||
|
echo $csv;
|
||||||
|
}, 200, $this->getFileHeaders($format));
|
||||||
|
}
|
||||||
|
return $this->returnExportZip($format, $claims, $csv);
|
||||||
|
// * PDF
|
||||||
|
} elseif ($format->equals(ExportFormat::pdf)) {
|
||||||
|
$pdf = $this->generatePdf($claims);
|
||||||
|
|
||||||
|
if (!$this->needsZip(ExportFormat::pdf, $claims)) {
|
||||||
|
return $pdf->download('export.pdf');
|
||||||
|
}
|
||||||
|
return $this->returnExportZip($format, $claims, $pdf->output());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
183
app/Http/Controllers/Bo/ClaimMailTemplateController.php
Normal file
183
app/Http/Controllers/Bo/ClaimMailTemplateController.php
Normal file
|
|
@ -0,0 +1,183 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Controllers\Bo;
|
||||||
|
|
||||||
|
use App\Enums\Users\RoleEnum;
|
||||||
|
use App\Http\Controllers\Controller;
|
||||||
|
use App\Http\Requests\Bo\ClaimMailTemplates\ClaimMailTemplateRequest;
|
||||||
|
use App\Models\Brand;
|
||||||
|
use App\Models\ClaimMailTemplate;
|
||||||
|
use Illuminate\Http\Request;
|
||||||
|
use Illuminate\Support\Facades\DB;
|
||||||
|
use Illuminate\Support\Str;
|
||||||
|
use Uwil\LaravelCommon\Helpers\CollectionHelper;
|
||||||
|
|
||||||
|
class ClaimMailTemplateController extends Controller
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Create the controller instance.
|
||||||
|
*/
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
$this->authorizeResource(ClaimMailTemplate::class);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Display a listing of the resource.
|
||||||
|
*
|
||||||
|
* @param \Illuminate\Http\Request $request
|
||||||
|
* @return \Illuminate\Contracts\View\View
|
||||||
|
*/
|
||||||
|
public function index(Request $request): \Illuminate\Contracts\View\View
|
||||||
|
{
|
||||||
|
/** @var \App\Models\User $userModel */
|
||||||
|
$userModel = auth('backend')->user();
|
||||||
|
|
||||||
|
/** @var \Illuminate\Database\Eloquent\Builder $query */
|
||||||
|
$query = ClaimMailTemplate::query()
|
||||||
|
->when(
|
||||||
|
$request->filled('brand'),
|
||||||
|
fn($q) => $q->whereHas('brand', fn($q) => $q->where('id', $request->brand))
|
||||||
|
)->when(
|
||||||
|
$userModel->role->equals(RoleEnum::marketing),
|
||||||
|
fn($q) => $q->whereHas('brand', fn($q) => $q->whereIn('id', $userModel->brands->modelKeys()))
|
||||||
|
);
|
||||||
|
|
||||||
|
if ($request->search) {
|
||||||
|
$this->searchQuery(
|
||||||
|
$query,
|
||||||
|
$request->search,
|
||||||
|
null,
|
||||||
|
'label',
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->sortQuery($query);
|
||||||
|
$searchFields = trans('validation.custom.label');
|
||||||
|
|
||||||
|
$claimMailTemplateModels = $query->paginate($this->getPagination());
|
||||||
|
|
||||||
|
return view('bo.pages.claim_mail_templates.index', compact('claimMailTemplateModels', 'searchFields'));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Show the specified resource.
|
||||||
|
*
|
||||||
|
* @param \App\Models\ClaimMailTemplate $claim_mail_template
|
||||||
|
* @return \Illuminate\Contracts\View\View
|
||||||
|
*/
|
||||||
|
public function show(ClaimMailTemplate $claim_mail_template): \Illuminate\Contracts\View\View
|
||||||
|
{
|
||||||
|
return view('bo.pages.claim_mail_templates.show', [
|
||||||
|
'claimMailTemplateModel' => $claim_mail_template,
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Show the form for creating a new resource.
|
||||||
|
*
|
||||||
|
* @param \App\Models\ClaimMailTemplate $claim_mail_template
|
||||||
|
* @return \Illuminate\Contracts\View\View
|
||||||
|
*/
|
||||||
|
public function create(ClaimMailTemplate $claim_mail_template): \Illuminate\Contracts\View\View
|
||||||
|
{
|
||||||
|
$brandModels = CollectionHelper::paginate(Brand::getUserAssociatedBrands(), $this->jsonItemPerPagination);
|
||||||
|
return view('bo.pages.claim_mail_templates.create', [
|
||||||
|
'claimMailTemplateModel' => $claim_mail_template,
|
||||||
|
'brandModels' => $brandModels,
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Store a newly created resource in storage.
|
||||||
|
*
|
||||||
|
* @param \App\Http\Requests\Bo\ClaimMailTemplates\ClaimMailTemplateRequest $request
|
||||||
|
* @return \Illuminate\Http\RedirectResponse
|
||||||
|
*/
|
||||||
|
public function store(ClaimMailTemplateRequest $request): \Illuminate\Http\RedirectResponse
|
||||||
|
{
|
||||||
|
return DB::transaction(function () use ($request) {
|
||||||
|
$claimMailTemplateModel = new ClaimMailTemplate();
|
||||||
|
$claimMailTemplateModel->fill($request->validated());
|
||||||
|
if ($claimMailTemplateModel->saveOrFail()) {
|
||||||
|
return redirect()
|
||||||
|
->route('bo.claim_mail_templates.edit', $claimMailTemplateModel)
|
||||||
|
->with('success', trans(
|
||||||
|
':model a été créé.',
|
||||||
|
['model' => Str::singular(trans('models.classes.claimmailtemplates'))]
|
||||||
|
));
|
||||||
|
}
|
||||||
|
return redirect()
|
||||||
|
->back()
|
||||||
|
->with('error', trans(
|
||||||
|
':model n\'a pas été créé.',
|
||||||
|
['model' => Str::singular(trans('models.classes.claimmailtemplates'))]
|
||||||
|
));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Show the form for editing the specified resource.
|
||||||
|
*
|
||||||
|
* @param \App\Models\ClaimMailTemplate $claim_mail_template
|
||||||
|
* @return \Illuminate\Contracts\View\View
|
||||||
|
*/
|
||||||
|
public function edit(ClaimMailTemplate $claim_mail_template): \Illuminate\Contracts\View\View
|
||||||
|
{
|
||||||
|
$brandModels = CollectionHelper::paginate(Brand::getUserAssociatedBrands(), $this->jsonItemPerPagination);
|
||||||
|
return view('bo.pages.claim_mail_templates.edit', [
|
||||||
|
'claimMailTemplateModel' => $claim_mail_template,
|
||||||
|
'brandModels' => $brandModels,
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update a spacific resource in storage.
|
||||||
|
*
|
||||||
|
* @param \App\Http\Requests\Bo\ClaimSubjects\ClaimMailTemplateRequest $request
|
||||||
|
* @param \App\Models\ClaimMailTemplate $claim_mail_template
|
||||||
|
* @return \Illuminate\Http\RedirectResponse
|
||||||
|
*/
|
||||||
|
public function update(
|
||||||
|
ClaimMailTemplateRequest $request,
|
||||||
|
ClaimMailTemplate $claim_mail_template
|
||||||
|
): \Illuminate\Http\RedirectResponse {
|
||||||
|
return DB::transaction(function () use ($request, $claim_mail_template) {
|
||||||
|
$claim_mail_template->fill($request->validated());
|
||||||
|
if ($claim_mail_template->saveOrFail()) {
|
||||||
|
return redirect()
|
||||||
|
->route('bo.claim_mail_templates.edit', $claim_mail_template)
|
||||||
|
->with('success', trans(
|
||||||
|
':model a été mis à jour.',
|
||||||
|
['model' => Str::singular(trans('models.classes.claimmailtemplates'))]
|
||||||
|
));
|
||||||
|
}
|
||||||
|
return redirect()
|
||||||
|
->back()
|
||||||
|
->with('error', trans(
|
||||||
|
':model n\'a pas été mis à jour.',
|
||||||
|
['model' => Str::singular(trans('models.classes.claimmailtemplates'))]
|
||||||
|
));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove the specified resource from storage.
|
||||||
|
*
|
||||||
|
* @param \App\Models\ClaimMailTemplate $claim_mail_template
|
||||||
|
* @return \Illuminate\Http\RedirectResponse
|
||||||
|
*/
|
||||||
|
public function destroy(ClaimMailTemplate $claim_mail_template): \Illuminate\Http\RedirectResponse
|
||||||
|
{
|
||||||
|
if ($claim_mail_template->deleteOrFail()) {
|
||||||
|
return redirect()->route('bo.claim_mail_templates.index')
|
||||||
|
->with('success', __('crud.messages.has_been_deleted', [
|
||||||
|
'model' => Str::of(__('models.classes.claimmailtemplates'))->singular()
|
||||||
|
]));
|
||||||
|
}
|
||||||
|
return redirect()->back()
|
||||||
|
->with('error', __('crud.messages.cannot_be_deleted', [
|
||||||
|
'model' => Str::of(__('models.classes.claimmailtemplates'))->singular()
|
||||||
|
]));
|
||||||
|
}
|
||||||
|
}
|
||||||
53
app/Http/Controllers/Bo/ClaimMessageController.php
Normal file
53
app/Http/Controllers/Bo/ClaimMessageController.php
Normal file
|
|
@ -0,0 +1,53 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Controllers\Bo;
|
||||||
|
|
||||||
|
use App\Http\Controllers\Controller;
|
||||||
|
use App\Http\Requests\Bo\ClaimMessages\StoreMessageRequest;
|
||||||
|
use App\Http\Requests\Bo\ClaimMessages\UpdateMessageRequest;
|
||||||
|
use App\Models\ClaimMessage;
|
||||||
|
use App\Traits\Controllers\UpdateModelPublished;
|
||||||
|
use Illuminate\Support\Facades\DB;
|
||||||
|
|
||||||
|
class ClaimMessageController extends Controller
|
||||||
|
{
|
||||||
|
use UpdateModelPublished;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Store a new specific resource.
|
||||||
|
*
|
||||||
|
* @param \App\Http\Requests\Bo\ClaimMessages\StoreMessageRequest $request
|
||||||
|
* @return \Illuminate\Http\JsonResponse
|
||||||
|
*/
|
||||||
|
public function store(StoreMessageRequest $request): \Illuminate\Http\JsonResponse
|
||||||
|
{
|
||||||
|
$this->authorize('store', ClaimMessage::class);
|
||||||
|
|
||||||
|
$validatedData = $request->validated();
|
||||||
|
return DB::transaction(function () use ($validatedData) {
|
||||||
|
$claimMessage = (new ClaimMessage())->fill($validatedData);
|
||||||
|
if ($claimMessage->saveOrFail()) {
|
||||||
|
$claimMessageModels = ClaimMessage::getAllModelsFromClaim($claimMessage->claim->getKey());
|
||||||
|
return response()->json($claimMessageModels);
|
||||||
|
}
|
||||||
|
return response()->json([], 500);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update a specified resource.
|
||||||
|
*
|
||||||
|
* @param \App\Http\Requests\Bo\ClaimMessages\UpdateMessageRequest $request
|
||||||
|
* @param \App\Models\ClaimMessage $claim_message
|
||||||
|
* @return \Illuminate\Http\JsonResponse
|
||||||
|
*/
|
||||||
|
public function update(UpdateMessageRequest $request, ClaimMessage $claim_message): \Illuminate\Http\JsonResponse
|
||||||
|
{
|
||||||
|
$this->authorize('update', ClaimMessage::class);
|
||||||
|
|
||||||
|
$claim_message->content = $request->validated()['content'];
|
||||||
|
$claim_message->saveOrFail();
|
||||||
|
|
||||||
|
return response()->json($claim_message);
|
||||||
|
}
|
||||||
|
}
|
||||||
173
app/Http/Controllers/Bo/ClaimSubjectController.php
Normal file
173
app/Http/Controllers/Bo/ClaimSubjectController.php
Normal file
|
|
@ -0,0 +1,173 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Controllers\Bo;
|
||||||
|
|
||||||
|
use App\Http\Controllers\Controller;
|
||||||
|
use App\Http\Requests\Bo\ClaimSubjects\ClaimSubjectRequest;
|
||||||
|
use App\Models\Brand;
|
||||||
|
use App\Models\ClaimSubject;
|
||||||
|
use Illuminate\Http\Request;
|
||||||
|
use Illuminate\Support\Facades\DB;
|
||||||
|
use Illuminate\Support\Str;
|
||||||
|
use Uwil\LaravelCommon\Helpers\CollectionHelper;
|
||||||
|
|
||||||
|
class ClaimSubjectController extends Controller
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Create the controller instance.
|
||||||
|
*/
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
$this->authorizeResource(ClaimSubject::class);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Display a listing of the resource.
|
||||||
|
*
|
||||||
|
* @param \Illuminate\Http\Request $request
|
||||||
|
* @return \Illuminate\Contracts\View\View
|
||||||
|
*/
|
||||||
|
public function index(Request $request): \Illuminate\Contracts\View\View
|
||||||
|
{
|
||||||
|
/** @var \Illuminate\Database\Eloquent\Builder $query */
|
||||||
|
$query = ClaimSubject::query()->when(
|
||||||
|
$request->filled('brand'),
|
||||||
|
fn($q) => $q->whereHas('brand', fn($q) => $q->where('id', $request->brand))
|
||||||
|
);
|
||||||
|
|
||||||
|
if ($request->search) {
|
||||||
|
$this->searchQuery(
|
||||||
|
$query,
|
||||||
|
$request->search,
|
||||||
|
null,
|
||||||
|
'label',
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->sortQuery($query);
|
||||||
|
$searchFields = trans('validation.custom.label');
|
||||||
|
|
||||||
|
$claimSubjectModels = $query->paginate($this->getPagination());
|
||||||
|
|
||||||
|
return view('bo.pages.claim_subjects.index', compact('claimSubjectModels', 'searchFields'));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Show the specified resource.
|
||||||
|
*
|
||||||
|
* @param \App\Models\ClaimSubject $claim_subject
|
||||||
|
* @return \Illuminate\Contracts\View\View
|
||||||
|
*/
|
||||||
|
public function show(ClaimSubject $claim_subject): \Illuminate\Contracts\View\View
|
||||||
|
{
|
||||||
|
return view('bo.pages.claim_subjects.show', [
|
||||||
|
'claimSubjectModel' => $claim_subject
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Show the form for creating a new resource.
|
||||||
|
*
|
||||||
|
* @param \App\Models\ClaimSubject $claim_subject
|
||||||
|
* @return \Illuminate\Contracts\View\View
|
||||||
|
*/
|
||||||
|
public function create(ClaimSubject $claim_subject): \Illuminate\Contracts\View\View
|
||||||
|
{
|
||||||
|
$brandModels = CollectionHelper::paginate(Brand::getUserAssociatedBrands(), $this->jsonItemPerPagination);
|
||||||
|
return view('bo.pages.claim_subjects.create', [
|
||||||
|
'claimSubjectModel' => $claim_subject,
|
||||||
|
'brandModels' => $brandModels,
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Store a newly created resource in storage.
|
||||||
|
*
|
||||||
|
* @param \App\Http\Requests\Bo\ClaimSubjects\ClaimSubjectRequest $request
|
||||||
|
* @return \Illuminate\Http\RedirectResponse
|
||||||
|
*/
|
||||||
|
public function store(ClaimSubjectRequest $request): \Illuminate\Http\RedirectResponse
|
||||||
|
{
|
||||||
|
return DB::transaction(function () use ($request) {
|
||||||
|
$claimSubjectModel = new ClaimSubject();
|
||||||
|
$claimSubjectModel->fill($request->validated());
|
||||||
|
if ($claimSubjectModel->saveOrFail()) {
|
||||||
|
return redirect()
|
||||||
|
->route('bo.claim_subjects.edit', $claimSubjectModel)
|
||||||
|
->with('success', trans(
|
||||||
|
':model a été créé.',
|
||||||
|
['model' => Str::singular(trans('models.classes.claimsubjects'))]
|
||||||
|
));
|
||||||
|
}
|
||||||
|
return redirect()
|
||||||
|
->back()
|
||||||
|
->with('error', trans(
|
||||||
|
':model n\'a pas été créé.',
|
||||||
|
['model' => Str::singular(trans('models.classes.claimsubjects'))]
|
||||||
|
));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Show the form for editing the specified resource.
|
||||||
|
*
|
||||||
|
* @param \App\Models\ClaimSubject $claim_subject
|
||||||
|
* @return \Illuminate\Contracts\View\View
|
||||||
|
*/
|
||||||
|
public function edit(ClaimSubject $claim_subject): \Illuminate\Contracts\View\View
|
||||||
|
{
|
||||||
|
$brandModels = CollectionHelper::paginate(Brand::getUserAssociatedBrands(), $this->jsonItemPerPagination);
|
||||||
|
return view('bo.pages.claim_subjects.edit', [
|
||||||
|
'claimSubjectModel' => $claim_subject,
|
||||||
|
'brandModels' => $brandModels,
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update a spacific resource in storage.
|
||||||
|
*
|
||||||
|
* @param \App\Http\Requests\Bo\ClaimSubjects\ClaimSubjectRequest $request
|
||||||
|
* @param \App\Models\ClaimSubject $claim_subject
|
||||||
|
* @return \Illuminate\Http\RedirectResponse
|
||||||
|
*/
|
||||||
|
public function update(ClaimSubjectRequest $request, ClaimSubject $claim_subject): \Illuminate\Http\RedirectResponse
|
||||||
|
{
|
||||||
|
return DB::transaction(function () use ($request, $claim_subject) {
|
||||||
|
$claim_subject->fill($request->validated());
|
||||||
|
if ($claim_subject->saveOrFail()) {
|
||||||
|
return redirect()
|
||||||
|
->route('bo.claim_subjects.edit', $claim_subject)
|
||||||
|
->with('success', trans(
|
||||||
|
':model a été mis à jour.',
|
||||||
|
['model' => Str::singular(trans('models.classes.claimsubjects'))]
|
||||||
|
));
|
||||||
|
}
|
||||||
|
return redirect()
|
||||||
|
->back()
|
||||||
|
->with('error', trans(
|
||||||
|
':model n\'a pas été mis à jour.',
|
||||||
|
['model' => Str::singular(trans('models.classes.claimsubjects'))]
|
||||||
|
));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove the specified resource from storage.
|
||||||
|
*
|
||||||
|
* @param \App\Models\ClaimSubject $claim_subject
|
||||||
|
* @return \Illuminate\Http\RedirectResponse
|
||||||
|
*/
|
||||||
|
public function destroy(ClaimSubject $claim_subject): \Illuminate\Http\RedirectResponse
|
||||||
|
{
|
||||||
|
if ($claim_subject->deleteOrFail()) {
|
||||||
|
return redirect()->route('bo.claim_subjects.index')
|
||||||
|
->with('success', __('crud.messages.has_been_deleted', [
|
||||||
|
'model' => Str::of(__('models.classes.claimsubjects'))->singular()
|
||||||
|
]));
|
||||||
|
}
|
||||||
|
return redirect()->back()
|
||||||
|
->with('error', __('crud.messages.cannot_be_deleted', [
|
||||||
|
'model' => Str::of(__('models.classes.claimsubjects'))->singular()
|
||||||
|
]));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -5,15 +5,18 @@ namespace App\Http\Controllers\Bo;
|
||||||
use App\Enums\CustomerExportType;
|
use App\Enums\CustomerExportType;
|
||||||
use App\Http\Controllers\Controller;
|
use App\Http\Controllers\Controller;
|
||||||
use App\Http\Requests\Bo\CustomerExport;
|
use App\Http\Requests\Bo\CustomerExport;
|
||||||
|
use App\Models\Answer;
|
||||||
use App\Models\Brand;
|
use App\Models\Brand;
|
||||||
use App\Models\Customer;
|
use App\Models\Customer;
|
||||||
use App\Models\CustomerInfo;
|
use App\Models\CustomerInfo;
|
||||||
use App\Models\CustomerLogin;
|
use App\Models\CustomerLogin;
|
||||||
|
use App\Models\Question;
|
||||||
use App\Models\SingleOptin;
|
use App\Models\SingleOptin;
|
||||||
use Illuminate\Database\Eloquent\Builder;
|
use Illuminate\Database\Eloquent\Builder;
|
||||||
use Illuminate\Database\Query\JoinClause;
|
use Illuminate\Database\Query\JoinClause;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
use Illuminate\Support\Carbon;
|
use Illuminate\Support\Carbon;
|
||||||
|
use Illuminate\Support\Collection;
|
||||||
use Illuminate\Support\Facades\DB;
|
use Illuminate\Support\Facades\DB;
|
||||||
use Illuminate\Support\Facades\Schema;
|
use Illuminate\Support\Facades\Schema;
|
||||||
use Illuminate\Support\Facades\Session;
|
use Illuminate\Support\Facades\Session;
|
||||||
|
|
@ -23,6 +26,14 @@ use Symfony\Component\HttpFoundation\StreamedResponse;
|
||||||
|
|
||||||
class CustomerController extends Controller
|
class CustomerController extends Controller
|
||||||
{
|
{
|
||||||
|
/**
|
||||||
|
* Create the controller instance.
|
||||||
|
*/
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
$this->authorizeResource(Customer::class);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* View all customers.
|
* View all customers.
|
||||||
*
|
*
|
||||||
|
|
@ -31,90 +42,41 @@ class CustomerController extends Controller
|
||||||
*/
|
*/
|
||||||
public function index(Request $request): \Illuminate\Contracts\View\View
|
public function index(Request $request): \Illuminate\Contracts\View\View
|
||||||
{
|
{
|
||||||
$modelTable = (new Customer())->getTable();
|
$modelClass = Customer::class;
|
||||||
$modelClass = Customer::class;
|
$modelTable = (new Customer())->getTable();
|
||||||
$brands = Brand::query()->select('id', 'name')->get();
|
$questionModels = null;
|
||||||
$columns = ['customer_infos.lastname', 'customer_infos.firstname'];
|
$answerModels = null;
|
||||||
|
$searchFields = trans('Email, Prénom, Nom');
|
||||||
|
|
||||||
// * Jointure pour pouvoir trier les colonnes.
|
// Reset session sorts.
|
||||||
/** @var \Illuminate\Database\Eloquent\Builder */
|
if ($request->rstSrts) {
|
||||||
$query = CustomerInfo::query()->join('customer_logins', function (JoinClause $join) {
|
$this->resetSessionSorts($modelTable);
|
||||||
$join->on('customer_logins.brand_id', '=', 'customer_infos.brand_id')
|
}
|
||||||
->on('customer_logins.customer_id', '=', 'customer_infos.customer_id');
|
// Reset session filters.
|
||||||
})->join('customers', function (JoinClause $join) {
|
if ($request->rstFltrs) {
|
||||||
$join->on('customers.id', '=', 'customer_infos.customer_id');
|
$this->resetSessionFilters($modelTable);
|
||||||
})->join('brands', function (JoinClause $join) {
|
|
||||||
$join->on('brands.id', '=', 'customer_infos.brand_id');
|
|
||||||
});
|
|
||||||
|
|
||||||
if ($request->rst) {
|
|
||||||
Session::remove("crud.$modelTable.brand");
|
|
||||||
Session::remove("crud.$modelTable.search");
|
|
||||||
Session::remove("crud.$modelTable.sort_way");
|
|
||||||
Session::remove("crud.$modelTable.sort_col");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (request()->brand or Session::has("crud.$modelTable.brand")) {
|
if ($request->filled('search') || Session::get("crud.$modelTable.search")) {
|
||||||
$brand = $request->brand ?? Session::get("crud.$modelTable.brand");
|
$columns = ['customer_infos.lastname', 'customer_infos.firstname'];
|
||||||
Session::put("crud.$modelTable.brand", $brand);
|
$query = $this->buildCustomerQuery();
|
||||||
$query = $query->where('customer_infos.brand_id', $brand);
|
|
||||||
}
|
|
||||||
|
|
||||||
// * Search on crud Label column.
|
// Apply filters.
|
||||||
if ($request->search or Session::has("crud.$modelTable.search")) {
|
$this->applyBrandFilter($request, $query, $modelTable, $questionModels, $answerModels);
|
||||||
$search = $request->search ?? Session::get("crud.$modelTable.search");
|
$this->applySearchFilter($request, $query, $modelTable, $columns);
|
||||||
Session::put("crud.$modelTable.search", $search);
|
$this->applySort($request, $query, $modelTable);
|
||||||
$query->where(function ($q) use ($columns, $search) {
|
|
||||||
foreach ($columns as $column) {
|
|
||||||
$q = $q->orWhere($column, 'LIKE', "%$search%");
|
|
||||||
}
|
|
||||||
$q = $q->orWhere('customers.email', 'LIKE', "%$search%");
|
|
||||||
$q = $q->orWhere('customer_logins.last_connection', 'LIKE', "%$search%");
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// * Sort columns.
|
$customerModels = $query->with(['customer', 'brand'])->simplePaginate($this->getPagination());
|
||||||
if ($request->sort_col) {
|
} //end if
|
||||||
Session::put("crud.$modelTable.sort_col", $request->sort_col);
|
|
||||||
}
|
|
||||||
if ($request->sort_way) {
|
|
||||||
Session::put("crud.$modelTable.sort_way", $request->sort_way);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (
|
return view('bo.pages.customers.index', [
|
||||||
Session::has("crud.$modelTable.sort_col") and
|
'modelClass' => $modelClass,
|
||||||
Session::has("crud.$modelTable.sort_way") and
|
'modelTable' => $modelTable,
|
||||||
(Schema::hasColumn($modelTable, Session::get("crud.$modelTable.sort_col")) or
|
'customerModels' => $customerModels ?? collect(),
|
||||||
in_array(Session::get("crud.$modelTable.sort_col"), [
|
'searchFields' => $searchFields,
|
||||||
'brands.name',
|
'questionModels' => $questionModels,
|
||||||
'customers.email',
|
'answerModels' => $answerModels,
|
||||||
'customer_infos.firstname',
|
]);
|
||||||
'customer_infos.lastname',
|
|
||||||
'customer_infos.opt_in',
|
|
||||||
'customer_logins.last_connection',
|
|
||||||
'customer_logins.status'
|
|
||||||
]))
|
|
||||||
) {
|
|
||||||
$query = $query->orderBy(
|
|
||||||
Session::get("crud.$modelTable.sort_col"),
|
|
||||||
Session::get("crud.$modelTable.sort_way")
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
$searchFields = trans('Email, Prénom, Nom');
|
|
||||||
|
|
||||||
$query->with(['customer', 'brand']);
|
|
||||||
|
|
||||||
/** @var \Illuminate\Pagination\AbstractPaginator */
|
|
||||||
$customerModels = $this->paginate($query);
|
|
||||||
|
|
||||||
return view('bo.pages.customers.index', compact(
|
|
||||||
'modelClass',
|
|
||||||
'modelTable',
|
|
||||||
'customerModels',
|
|
||||||
'brands',
|
|
||||||
'searchFields'
|
|
||||||
));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -195,6 +157,7 @@ class CustomerController extends Controller
|
||||||
*/
|
*/
|
||||||
public function export(): \Illuminate\Contracts\View\View
|
public function export(): \Illuminate\Contracts\View\View
|
||||||
{
|
{
|
||||||
|
$this->authorize('export', Customer::class);
|
||||||
$brands = Brand::all();
|
$brands = Brand::all();
|
||||||
return view('bo.pages.customers.export', compact(
|
return view('bo.pages.customers.export', compact(
|
||||||
'brands'
|
'brands'
|
||||||
|
|
@ -303,4 +266,157 @@ class CustomerController extends Controller
|
||||||
});
|
});
|
||||||
return $response;
|
return $response;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reset all session sorts.
|
||||||
|
*
|
||||||
|
* @param string $table
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
private function resetSessionSorts(string $table): void
|
||||||
|
{
|
||||||
|
Session::forget([
|
||||||
|
"crud.$table.sort_col",
|
||||||
|
"crud.$table.sort_way",
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reset all session filters.
|
||||||
|
*
|
||||||
|
* @param string $table
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
private function resetSessionFilters(string $table): void
|
||||||
|
{
|
||||||
|
Session::forget([
|
||||||
|
"crud.$table.brand",
|
||||||
|
"crud.$table.question",
|
||||||
|
"crud.$table.answer",
|
||||||
|
"crud.$table.search",
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Build the customer query.
|
||||||
|
*
|
||||||
|
* @return Builder
|
||||||
|
*/
|
||||||
|
private function buildCustomerQuery(): Builder
|
||||||
|
{
|
||||||
|
return CustomerInfo::query()
|
||||||
|
->join('customer_logins', function (JoinClause $join) {
|
||||||
|
$join->on('customer_logins.brand_id', '=', 'customer_infos.brand_id')
|
||||||
|
->on('customer_logins.customer_id', '=', 'customer_infos.customer_id');
|
||||||
|
})
|
||||||
|
->join('customers', fn($join) => $join->on('customers.id', '=', 'customer_infos.customer_id'))
|
||||||
|
->join('brands', fn($join) => $join->on('brands.id', '=', 'customer_infos.brand_id'));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Apply all filters (brand, question, answer).
|
||||||
|
*
|
||||||
|
* @param \Illuminate\Http\Request $request
|
||||||
|
* @param \Illuminate\Database\Eloquent\Builder $query
|
||||||
|
* @param string $table
|
||||||
|
* @param \Illuminate\Support\Collection|null $questionModels
|
||||||
|
* @param \Illuminate\Support\Collection|null $answerModels
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
private function applyBrandFilter(
|
||||||
|
Request $request,
|
||||||
|
Builder &$query,
|
||||||
|
string $table,
|
||||||
|
?Collection &$questionModels,
|
||||||
|
?Collection &$answerModels
|
||||||
|
): void {
|
||||||
|
$brand = $request->brand ?? Session::get("crud.$table.brand");
|
||||||
|
if (!(int) $brand) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Session::put("crud.$table.brand", $brand);
|
||||||
|
$query->where('customer_infos.brand_id', $brand);
|
||||||
|
|
||||||
|
$questionModels = Question::getAllModelsFromBrand($brand);
|
||||||
|
|
||||||
|
if (($request->filled('question') || Session::has("crud.$table.question")) && $questionModels->count()) {
|
||||||
|
$question = $request->question ?? Session::get("crud.$table.question");
|
||||||
|
Session::put("crud.$table.question", $question);
|
||||||
|
|
||||||
|
$answerModels = Answer::getAllAnswersFromQuestion($question);
|
||||||
|
$questionAnswers = Question::find($question)?->answers->modelKeys() ?? [];
|
||||||
|
|
||||||
|
$query->whereHas('customer.answers', fn($q) => $q->whereIn('answer_id', $questionAnswers));
|
||||||
|
|
||||||
|
if (
|
||||||
|
($request->filled('answer') || Session::has("crud.$table.answer"))
|
||||||
|
&& $questionModels->count()
|
||||||
|
&& $answerModels->count()
|
||||||
|
) {
|
||||||
|
$answer = $request->answer ?? Session::get("crud.$table.answer");
|
||||||
|
Session::put("crud.$table.answer", $answer);
|
||||||
|
|
||||||
|
$query->whereHas('customer.answers', fn($q) => $q->whereKey($answer));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Apply the search filter.
|
||||||
|
*
|
||||||
|
* @param \Illuminate\Http\Request $request
|
||||||
|
* @param \Illuminate\Database\Eloquent\Builder $query
|
||||||
|
* @param string $table
|
||||||
|
* @param array $columns
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
private function applySearchFilter(Request $request, Builder &$query, string $table, array $columns): void
|
||||||
|
{
|
||||||
|
$search = $request->search ?? Session::get("crud.$table.search");
|
||||||
|
Session::put("crud.$table.search", $search);
|
||||||
|
|
||||||
|
$query->where(function ($q) use ($columns, $search) {
|
||||||
|
foreach ($columns as $column) {
|
||||||
|
$q->orWhere($column, 'LIKE', "%$search%");
|
||||||
|
}
|
||||||
|
|
||||||
|
$q->orWhere('customers.email', 'LIKE', "%$search%")
|
||||||
|
->orWhere('customer_logins.last_connection', 'LIKE', "%$search%");
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Apply sorts.
|
||||||
|
*
|
||||||
|
* @param \Illuminate\Http\Request $request
|
||||||
|
* @param \Illuminate\Database\Eloquent\Builder $query
|
||||||
|
* @param string $table
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
private function applySort(Request $request, Builder &$query, string $table): void
|
||||||
|
{
|
||||||
|
$sortCol = $request->sort_col ?? Session::get("crud.$table.sort_col");
|
||||||
|
$sortWay = $request->sort_way ?? Session::get("crud.$table.sort_way");
|
||||||
|
|
||||||
|
if ($sortCol) {
|
||||||
|
Session::put("crud.$table.sort_col", $sortCol);
|
||||||
|
}
|
||||||
|
if ($sortWay) {
|
||||||
|
Session::put("crud.$table.sort_way", $sortWay);
|
||||||
|
}
|
||||||
|
|
||||||
|
$sortable = [
|
||||||
|
'brands.name',
|
||||||
|
'customers.email',
|
||||||
|
'customer_infos.firstname',
|
||||||
|
'customer_infos.lastname',
|
||||||
|
'customer_infos.opt_in',
|
||||||
|
'customer_logins.last_connection',
|
||||||
|
'customer_logins.status',
|
||||||
|
];
|
||||||
|
|
||||||
|
if ($sortCol && $sortWay && (Schema::hasColumn($table, $sortCol) || in_array($sortCol, $sortable))) {
|
||||||
|
$query->orderBy($sortCol, $sortWay);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -3,16 +3,15 @@
|
||||||
namespace App\Http\Controllers\Bo;
|
namespace App\Http\Controllers\Bo;
|
||||||
|
|
||||||
use App\Http\Controllers\Controller;
|
use App\Http\Controllers\Controller;
|
||||||
use Illuminate\Contracts\View\View;
|
|
||||||
|
|
||||||
class DashboardController extends Controller
|
class DashboardController extends Controller
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* Dashboard Page
|
* Dashboard page.
|
||||||
*
|
*
|
||||||
* @return \Illuminate\Contracts\View\View
|
* @return \Illuminate\Contracts\View\View
|
||||||
*/
|
*/
|
||||||
public function index(): View
|
public function index(): \Illuminate\Contracts\View\View
|
||||||
{
|
{
|
||||||
return view('bo.pages.dashboard');
|
return view('bo.pages.dashboard');
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,7 @@ use App\Http\Requests\Bo\QuestionExport;
|
||||||
use App\Http\Requests\Bo\Questions\StoreQuestionRequest;
|
use App\Http\Requests\Bo\Questions\StoreQuestionRequest;
|
||||||
use App\Http\Requests\Bo\Questions\UpdateQuestionRequest;
|
use App\Http\Requests\Bo\Questions\UpdateQuestionRequest;
|
||||||
use App\Models\Brand;
|
use App\Models\Brand;
|
||||||
|
use App\Models\Customer;
|
||||||
use App\Models\Question;
|
use App\Models\Question;
|
||||||
use Carbon\Carbon;
|
use Carbon\Carbon;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
|
|
@ -17,6 +18,14 @@ use Symfony\Component\HttpFoundation\StreamedResponse;
|
||||||
|
|
||||||
class QuestionController extends Controller
|
class QuestionController extends Controller
|
||||||
{
|
{
|
||||||
|
/**
|
||||||
|
* Create the controller instance.
|
||||||
|
*/
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
$this->authorizeResource(Question::class);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Display a listing of the resource.
|
* Display a listing of the resource.
|
||||||
*
|
*
|
||||||
|
|
@ -26,11 +35,11 @@ class QuestionController extends Controller
|
||||||
public function index(Request $request): \Illuminate\Contracts\View\View
|
public function index(Request $request): \Illuminate\Contracts\View\View
|
||||||
{
|
{
|
||||||
/** @var \Illuminate\Database\Eloquent\Builder $query */
|
/** @var \Illuminate\Database\Eloquent\Builder $query */
|
||||||
$query = Question::query();
|
$query = Question::query()->when(
|
||||||
|
$request->filled('brand'),
|
||||||
|
fn($q) => $q->whereHas('brand', fn($q) => $q->where('id', $request->brand))
|
||||||
|
);
|
||||||
|
|
||||||
if ($request->brand) {
|
|
||||||
$query = $query->where('brand_id', '=', $request->brand);
|
|
||||||
}
|
|
||||||
if ($request->search) {
|
if ($request->search) {
|
||||||
$this->searchQuery(
|
$this->searchQuery(
|
||||||
$query,
|
$query,
|
||||||
|
|
@ -46,7 +55,7 @@ class QuestionController extends Controller
|
||||||
$query->with(['brand', 'answers']);
|
$query->with(['brand', 'answers']);
|
||||||
|
|
||||||
/** @var \Illuminate\Pagination\AbstractPaginator */
|
/** @var \Illuminate\Pagination\AbstractPaginator */
|
||||||
$questionModels = $this->paginate($query);
|
$questionModels = $query->paginate($this->getPagination());
|
||||||
|
|
||||||
return view('bo.pages.questions.index', compact('questionModels', 'searchFields'));
|
return view('bo.pages.questions.index', compact('questionModels', 'searchFields'));
|
||||||
}
|
}
|
||||||
|
|
@ -59,11 +68,10 @@ class QuestionController extends Controller
|
||||||
*/
|
*/
|
||||||
public function create(Question $question): \Illuminate\Contracts\View\View
|
public function create(Question $question): \Illuminate\Contracts\View\View
|
||||||
{
|
{
|
||||||
$brandModels = Brand::all();
|
$brandModels = Brand::query()->orderBy('name', 'ASC')->paginate($this->jsonItemPerPagination);
|
||||||
|
|
||||||
return view('bo.pages.questions.create', [
|
return view('bo.pages.questions.create', [
|
||||||
'questionModel' => $question,
|
'questionModel' => $question,
|
||||||
'brandModels' => $brandModels
|
'brandModels' => $brandModels
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -103,9 +111,8 @@ class QuestionController extends Controller
|
||||||
*/
|
*/
|
||||||
public function edit(Question $question): \Illuminate\Contracts\View\View
|
public function edit(Question $question): \Illuminate\Contracts\View\View
|
||||||
{
|
{
|
||||||
$brandModels = Brand::all();
|
$brandModels = Brand::query()->orderBy('name', 'ASC')->paginate($this->jsonItemPerPagination);
|
||||||
$question->load('brand');
|
$question->load('brand');
|
||||||
|
|
||||||
return view('bo.pages.questions.edit', [
|
return view('bo.pages.questions.edit', [
|
||||||
'questionModel' => $question,
|
'questionModel' => $question,
|
||||||
'brandModels' => $brandModels
|
'brandModels' => $brandModels
|
||||||
|
|
@ -182,6 +189,7 @@ class QuestionController extends Controller
|
||||||
*/
|
*/
|
||||||
public function export(): \Illuminate\Contracts\View\View
|
public function export(): \Illuminate\Contracts\View\View
|
||||||
{
|
{
|
||||||
|
$this->authorize('export', Question::class);
|
||||||
$brands = Brand::all();
|
$brands = Brand::all();
|
||||||
return view('bo.pages.questions.export', compact('brands'));
|
return view('bo.pages.questions.export', compact('brands'));
|
||||||
}
|
}
|
||||||
|
|
@ -202,10 +210,12 @@ class QuestionController extends Controller
|
||||||
foreach ($questions as $question) {
|
foreach ($questions as $question) {
|
||||||
$answersCounts = DB::query()
|
$answersCounts = DB::query()
|
||||||
->selectRaw('count(*) as total, answer_id')
|
->selectRaw('count(*) as total, answer_id')
|
||||||
->from('customer_answer')
|
->from('model_answer')
|
||||||
->whereIn('answer_id', $question->answers->pluck('id'))
|
->where('model_type', '=', Customer::class)
|
||||||
|
->whereIn('answer_id', $question->answers->modelKeys())
|
||||||
->groupBy('answer_id')
|
->groupBy('answer_id')
|
||||||
->get()->keyBy('answer_id');
|
->get()
|
||||||
|
->keyBy('answer_id');
|
||||||
|
|
||||||
$results[$question->id] = [
|
$results[$question->id] = [
|
||||||
'question' => $question->question,
|
'question' => $question->question,
|
||||||
|
|
@ -218,7 +228,7 @@ class QuestionController extends Controller
|
||||||
$answersCounts[$answer->id]->total ?? 0
|
$answersCounts[$answer->id]->total ?? 0
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
}
|
} //end foreach
|
||||||
|
|
||||||
$w = Writer::createFromString('');
|
$w = Writer::createFromString('');
|
||||||
$w->setDelimiter(';');
|
$w->setDelimiter(';');
|
||||||
|
|
|
||||||
|
|
@ -14,9 +14,18 @@ use Illuminate\Support\Facades\DB;
|
||||||
use Illuminate\Support\Facades\Hash;
|
use Illuminate\Support\Facades\Hash;
|
||||||
use Illuminate\Support\Facades\Mail;
|
use Illuminate\Support\Facades\Mail;
|
||||||
use Illuminate\Support\Str;
|
use Illuminate\Support\Str;
|
||||||
|
use Uwil\LaravelCommon\Helpers\CollectionHelper;
|
||||||
|
|
||||||
class ServiceController extends Controller
|
class ServiceController extends Controller
|
||||||
{
|
{
|
||||||
|
/**
|
||||||
|
* Create the controller instance.
|
||||||
|
*/
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
$this->authorizeResource(Service::class);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Display a listing of the resource.
|
* Display a listing of the resource.
|
||||||
*
|
*
|
||||||
|
|
@ -26,11 +35,11 @@ class ServiceController extends Controller
|
||||||
public function index(Request $request): \Illuminate\Contracts\View\View
|
public function index(Request $request): \Illuminate\Contracts\View\View
|
||||||
{
|
{
|
||||||
/** @var \Illuminate\Database\Eloquent\Builder $query */
|
/** @var \Illuminate\Database\Eloquent\Builder $query */
|
||||||
$query = Service::query();
|
$query = Service::query()->when(
|
||||||
|
$request->filled('brand'),
|
||||||
|
fn($q) => $q->whereHas('brand', fn($q) => $q->where('id', $request->brand))
|
||||||
|
);
|
||||||
|
|
||||||
if ($request->brand) {
|
|
||||||
$query = $query->where('brand_id', '=', $request->brand);
|
|
||||||
}
|
|
||||||
if ($request->search) {
|
if ($request->search) {
|
||||||
$this->searchQuery(
|
$this->searchQuery(
|
||||||
$query,
|
$query,
|
||||||
|
|
@ -45,7 +54,7 @@ class ServiceController extends Controller
|
||||||
|
|
||||||
$query->with(['brand']);
|
$query->with(['brand']);
|
||||||
|
|
||||||
$serviceModels = $this->paginate($query);
|
$serviceModels = $query->paginate($this->getPagination());
|
||||||
|
|
||||||
return view('bo.pages.services.index', compact('serviceModels', 'searchFields'));
|
return view('bo.pages.services.index', compact('serviceModels', 'searchFields'));
|
||||||
}
|
}
|
||||||
|
|
@ -58,8 +67,7 @@ class ServiceController extends Controller
|
||||||
*/
|
*/
|
||||||
public function create(Service $service): \Illuminate\Contracts\View\View
|
public function create(Service $service): \Illuminate\Contracts\View\View
|
||||||
{
|
{
|
||||||
$brandModels = Brand::all();
|
$brandModels = CollectionHelper::paginate(Brand::getUserAssociatedBrands(), $this->jsonItemPerPagination);
|
||||||
|
|
||||||
return view('bo.pages.services.create', [
|
return view('bo.pages.services.create', [
|
||||||
'serviceModel' => $service,
|
'serviceModel' => $service,
|
||||||
'brandModels' => $brandModels
|
'brandModels' => $brandModels
|
||||||
|
|
@ -104,8 +112,7 @@ class ServiceController extends Controller
|
||||||
*/
|
*/
|
||||||
public function edit(Service $service): \Illuminate\Contracts\View\View
|
public function edit(Service $service): \Illuminate\Contracts\View\View
|
||||||
{
|
{
|
||||||
$brandModels = Brand::all();
|
$brandModels = CollectionHelper::paginate(Brand::getUserAssociatedBrands(), $this->jsonItemPerPagination);
|
||||||
|
|
||||||
return view('bo.pages.services.edit', [
|
return view('bo.pages.services.edit', [
|
||||||
'serviceModel' => $service,
|
'serviceModel' => $service,
|
||||||
'brandModels' => $brandModels
|
'brandModels' => $brandModels
|
||||||
|
|
|
||||||
|
|
@ -3,13 +3,24 @@
|
||||||
namespace App\Http\Controllers\Bo;
|
namespace App\Http\Controllers\Bo;
|
||||||
|
|
||||||
use App\Http\Controllers\Controller;
|
use App\Http\Controllers\Controller;
|
||||||
|
use App\Models\Answer;
|
||||||
|
use App\Models\Question;
|
||||||
use App\Models\SingleOptin;
|
use App\Models\SingleOptin;
|
||||||
use Illuminate\Database\Eloquent\Builder;
|
use Illuminate\Database\Eloquent\Builder;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
|
use Illuminate\Support\Collection;
|
||||||
use Illuminate\Support\Str;
|
use Illuminate\Support\Str;
|
||||||
|
|
||||||
class SingleOptinController extends Controller
|
class SingleOptinController extends Controller
|
||||||
{
|
{
|
||||||
|
/**
|
||||||
|
* Create the controller instance.
|
||||||
|
*/
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
$this->authorizeResource(SingleOptin::class);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Display a listing of the resource.
|
* Display a listing of the resource.
|
||||||
*
|
*
|
||||||
|
|
@ -18,34 +29,30 @@ class SingleOptinController extends Controller
|
||||||
*/
|
*/
|
||||||
public function index(Request $request): \Illuminate\Contracts\View\View
|
public function index(Request $request): \Illuminate\Contracts\View\View
|
||||||
{
|
{
|
||||||
/** @var \Illuminate\Database\Eloquent\Builder $query */
|
$questionModels = null;
|
||||||
$query = SingleOptin::query();
|
$answerModels = null;
|
||||||
|
$searchFields = trans('E-mail');
|
||||||
|
|
||||||
if ($request->brand) {
|
if ($request->filled('search')) {
|
||||||
$query = $query->whereHas('brand', function (Builder $q) use ($request) {
|
$query = SingleOptin::query();
|
||||||
$q->where('id', $request->brand);
|
|
||||||
});
|
$this->applyBrandAndAnswerFilters($request, $query, $questionModels, $answerModels);
|
||||||
}
|
$this->applySearch($request, $query);
|
||||||
if ($request->search) {
|
$this->sortQuery($query);
|
||||||
$this->searchQuery(
|
|
||||||
$query,
|
$query->with('brand');
|
||||||
$request->search,
|
$singleoptinModels = $query->simplePaginate($this->getPagination());
|
||||||
null,
|
|
||||||
'email',
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->sortQuery($query);
|
return view('bo.pages.singleoptins.index', [
|
||||||
$searchFields = trans('E-mail');
|
'singleoptinModels' => $singleoptinModels ?? collect(),
|
||||||
|
'searchFields' => $searchFields,
|
||||||
$query->with(['brand']);
|
'questionModels' => $questionModels,
|
||||||
|
'answerModels' => $answerModels,
|
||||||
/** @var \Illuminate\Pagination\AbstractPaginator */
|
]);
|
||||||
$singleoptinModels = $this->paginate($query);
|
|
||||||
|
|
||||||
return view('bo.pages.singleoptins.index', compact('singleoptinModels', 'searchFields'));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Remove the specified resource from storage.
|
* Remove the specified resource from storage.
|
||||||
*
|
*
|
||||||
|
|
@ -54,6 +61,7 @@ class SingleOptinController extends Controller
|
||||||
*/
|
*/
|
||||||
public function destroy(SingleOptin $singleoptin): \Illuminate\Http\RedirectResponse
|
public function destroy(SingleOptin $singleoptin): \Illuminate\Http\RedirectResponse
|
||||||
{
|
{
|
||||||
|
$singleoptin->answers()->detach();
|
||||||
if ($singleoptin->deleteOrFail()) {
|
if ($singleoptin->deleteOrFail()) {
|
||||||
return redirect()->route('bo.single_optins.index')
|
return redirect()->route('bo.single_optins.index')
|
||||||
->with('success', trans(
|
->with('success', trans(
|
||||||
|
|
@ -67,4 +75,59 @@ class SingleOptinController extends Controller
|
||||||
['model' => Str::singular(trans('models.classes.singleoptins'))]
|
['model' => Str::singular(trans('models.classes.singleoptins'))]
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Undocumented function
|
||||||
|
*
|
||||||
|
* @param \Illuminate\Http\Request $request
|
||||||
|
* @param \Illuminate\Database\Eloquent\Builder $query
|
||||||
|
* @param \Illuminate\Support\Collection|null $questionModels
|
||||||
|
* @param \Illuminate\Support\Collection|null $answerModels
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
private function applyBrandAndAnswerFilters(
|
||||||
|
Request $request,
|
||||||
|
Builder $query,
|
||||||
|
?Collection &$questionModels,
|
||||||
|
?Collection &$answerModels
|
||||||
|
): void {
|
||||||
|
if (!$request->filled('brand') || !(int) $request->brand) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$brandId = $request->brand;
|
||||||
|
$query->whereHas('brand', fn($q) => $q->whereKey($brandId));
|
||||||
|
$questionModels = Question::getAllModelsFromBrand($brandId);
|
||||||
|
|
||||||
|
if (!$request->filled('question')) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$questionId = $request->question;
|
||||||
|
$question = Question::find($questionId);
|
||||||
|
|
||||||
|
if ($question) {
|
||||||
|
$questionAnswers = $question->answers->modelKeys();
|
||||||
|
$query->whereHas('answers', fn($q) => $q->whereIn('answer_id', $questionAnswers));
|
||||||
|
$answerModels = Answer::getAllAnswersFromQuestion($questionId);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($request->filled('answer')) {
|
||||||
|
$query->whereHas('answers', fn($q) => $q->whereKey($request->answer));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Apply search filter.
|
||||||
|
*
|
||||||
|
* @param \Illuminate\Http\Request $request
|
||||||
|
* @param \Illuminate\Database\Eloquent\Builder $query
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
private function applySearch(Request $request, Builder $query): void
|
||||||
|
{
|
||||||
|
if ($request->filled('search')) {
|
||||||
|
$this->searchQuery($query, $request->search, null, 'email');
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -7,10 +7,11 @@ use App\Http\Requests\Bo\StatsByBrandRequest;
|
||||||
use App\Http\Requests\Bo\StatsByQuestionRequest;
|
use App\Http\Requests\Bo\StatsByQuestionRequest;
|
||||||
use App\Models\Brand;
|
use App\Models\Brand;
|
||||||
use App\Models\BrandStat;
|
use App\Models\BrandStat;
|
||||||
use App\Models\CustomerAnswer;
|
use App\Models\ModelAnswer;
|
||||||
use App\Models\Question;
|
use App\Models\Question;
|
||||||
use Illuminate\Support\Carbon;
|
use Illuminate\Support\Carbon;
|
||||||
use Illuminate\Support\Collection;
|
use Illuminate\Support\Collection;
|
||||||
|
use Illuminate\Support\Facades\Gate;
|
||||||
use Illuminate\Support\Facades\Schema;
|
use Illuminate\Support\Facades\Schema;
|
||||||
use League\Csv\Writer;
|
use League\Csv\Writer;
|
||||||
|
|
||||||
|
|
@ -24,6 +25,7 @@ class StatsController extends Controller
|
||||||
*/
|
*/
|
||||||
public function viewStatsByBrand(StatsByBrandRequest $request)
|
public function viewStatsByBrand(StatsByBrandRequest $request)
|
||||||
{
|
{
|
||||||
|
Gate::authorize('viewStatsByBrand');
|
||||||
$stats = null;
|
$stats = null;
|
||||||
if ($request->post()) {
|
if ($request->post()) {
|
||||||
$stats = BrandStat::query()->whereDate('created_at', '>=', $request->start)
|
$stats = BrandStat::query()->whereDate('created_at', '>=', $request->start)
|
||||||
|
|
@ -68,7 +70,7 @@ class StatsController extends Controller
|
||||||
}
|
}
|
||||||
$w->insertOne($cols);
|
$w->insertOne($cols);
|
||||||
}
|
}
|
||||||
return response((string)$w, 200, [
|
return response((string) $w, 200, [
|
||||||
'Content-Encoding' => 'none',
|
'Content-Encoding' => 'none',
|
||||||
'Content-Type' => 'text/csv; charset=UTF-8',
|
'Content-Type' => 'text/csv; charset=UTF-8',
|
||||||
// phpcs:ignore Generic.Files.LineLength.TooLong
|
// phpcs:ignore Generic.Files.LineLength.TooLong
|
||||||
|
|
@ -85,6 +87,7 @@ class StatsController extends Controller
|
||||||
*/
|
*/
|
||||||
public function viewByQuestion(StatsByQuestionRequest $request): \Illuminate\Contracts\View\View
|
public function viewByQuestion(StatsByQuestionRequest $request): \Illuminate\Contracts\View\View
|
||||||
{
|
{
|
||||||
|
Gate::authorize('viewByQuestion');
|
||||||
$question = null;
|
$question = null;
|
||||||
$answers = null;
|
$answers = null;
|
||||||
$answersByDays = null;
|
$answersByDays = null;
|
||||||
|
|
@ -132,7 +135,7 @@ class StatsController extends Controller
|
||||||
$dayAnswers->values()->all()
|
$dayAnswers->values()->all()
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
return response((string)$w, 200, [
|
return response((string) $w, 200, [
|
||||||
'Content-Encoding' => 'none',
|
'Content-Encoding' => 'none',
|
||||||
'Content-Type' => 'text/csv; charset=UTF-8',
|
'Content-Type' => 'text/csv; charset=UTF-8',
|
||||||
// phpcs:ignore Generic.Files.LineLength.TooLong
|
// phpcs:ignore Generic.Files.LineLength.TooLong
|
||||||
|
|
@ -152,10 +155,12 @@ class StatsController extends Controller
|
||||||
*/
|
*/
|
||||||
private function answersByDays(Collection $answers, Carbon $start, Carbon $end): \Illuminate\Support\Collection
|
private function answersByDays(Collection $answers, Carbon $start, Carbon $end): \Illuminate\Support\Collection
|
||||||
{
|
{
|
||||||
|
Gate::authorize('answersByDays');
|
||||||
// * Totalize by date all answers.
|
// * Totalize by date all answers.
|
||||||
$answersByDays = CustomerAnswer::query()->whereDate('created_at', '>=', $start)
|
$answersByDays = ModelAnswer::query()
|
||||||
|
->whereDate('created_at', '>=', $start)
|
||||||
->whereDate('created_at', '<=', $end)
|
->whereDate('created_at', '<=', $end)
|
||||||
->whereIn('answer_id', $answers->pluck('id'))
|
->whereIn('answer_id', $answers->modelKeys())
|
||||||
->get()->map(function ($custAnswer) {
|
->get()->map(function ($custAnswer) {
|
||||||
return [
|
return [
|
||||||
'answer_id' => $custAnswer->answer_id,
|
'answer_id' => $custAnswer->answer_id,
|
||||||
|
|
|
||||||
|
|
@ -5,13 +5,15 @@ namespace App\Http\Controllers\Bo;
|
||||||
use App\Http\Controllers\Controller;
|
use App\Http\Controllers\Controller;
|
||||||
use App\Http\Requests\Bo\Users\StoreUserRequest;
|
use App\Http\Requests\Bo\Users\StoreUserRequest;
|
||||||
use App\Http\Requests\Bo\Users\UpdateUserRequest;
|
use App\Http\Requests\Bo\Users\UpdateUserRequest;
|
||||||
|
use App\Models\Brand;
|
||||||
use App\Models\User;
|
use App\Models\User;
|
||||||
use App\Traits\Controllers\UpdateModelPublished;
|
use App\Traits\Controllers\UpdateModelPublished;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
use Illuminate\Support\Facades\DB;
|
use Illuminate\Support\Facades\DB;
|
||||||
use Illuminate\Support\Str;
|
use Illuminate\Support\Str;
|
||||||
|
use Uwil\LaravelCommon\Helpers\CollectionHelper;
|
||||||
|
|
||||||
class UsersController extends Controller
|
class UserController extends Controller
|
||||||
{
|
{
|
||||||
use UpdateModelPublished;
|
use UpdateModelPublished;
|
||||||
|
|
||||||
|
|
@ -31,14 +33,14 @@ class UsersController extends Controller
|
||||||
*/
|
*/
|
||||||
public function index(Request $request): \Illuminate\Contracts\View\View
|
public function index(Request $request): \Illuminate\Contracts\View\View
|
||||||
{
|
{
|
||||||
/** @var \Illuminate\Database\Eloquent\Builder $userModels */
|
/** @var \Illuminate\Database\Eloquent\Builder $query */
|
||||||
$userModels = User::query();
|
$query = User::query();
|
||||||
|
|
||||||
/** @var string $search Search field */
|
/** @var string $search Search field */
|
||||||
$search = $request->search;
|
$search = $request->search;
|
||||||
if ($search) {
|
if ($search) {
|
||||||
$this->searchQuery(
|
$this->searchQuery(
|
||||||
$userModels,
|
$query,
|
||||||
$search,
|
$search,
|
||||||
null,
|
null,
|
||||||
'first_name',
|
'first_name',
|
||||||
|
|
@ -55,10 +57,10 @@ class UsersController extends Controller
|
||||||
]);
|
]);
|
||||||
|
|
||||||
/** Sort columns with a query */
|
/** Sort columns with a query */
|
||||||
$this->sortQuery($userModels);
|
$this->sortQuery($query);
|
||||||
|
|
||||||
/** Custom pagination */
|
/** Custom pagination */
|
||||||
$userModels = $this->paginate($userModels);
|
$userModels = $query->paginate($this->getPagination());
|
||||||
|
|
||||||
return view('bo.pages.users.index', compact('userModels', 'search', 'searchFields'));
|
return view('bo.pages.users.index', compact('userModels', 'search', 'searchFields'));
|
||||||
}
|
}
|
||||||
|
|
@ -72,7 +74,8 @@ class UsersController extends Controller
|
||||||
*/
|
*/
|
||||||
public function create(User $user): \Illuminate\Contracts\View\View
|
public function create(User $user): \Illuminate\Contracts\View\View
|
||||||
{
|
{
|
||||||
return view('bo.pages.users.create', ['userModel' => $user]);
|
$brandModels = CollectionHelper::paginate(Brand::getUserAssociatedBrands(), $this->jsonItemPerPagination);
|
||||||
|
return view('bo.pages.users.create', ['userModel' => $user, 'brandModels' => $brandModels]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -88,6 +91,7 @@ class UsersController extends Controller
|
||||||
$user->fill($request->validated());
|
$user->fill($request->validated());
|
||||||
|
|
||||||
if ($user->saveOrFail()) {
|
if ($user->saveOrFail()) {
|
||||||
|
$user->brands()->sync(collect($request->validated()['brand_id'])->pluck('id')->toArray());
|
||||||
return redirect()->route('bo.users.edit', $user)
|
return redirect()->route('bo.users.edit', $user)
|
||||||
->with('success', __('crud.messages.has_been_created', [
|
->with('success', __('crud.messages.has_been_created', [
|
||||||
'model' => Str::ucfirst(__('models.classes.user'))
|
'model' => Str::ucfirst(__('models.classes.user'))
|
||||||
|
|
@ -108,7 +112,8 @@ class UsersController extends Controller
|
||||||
*/
|
*/
|
||||||
public function edit(User $user): \Illuminate\Contracts\View\View
|
public function edit(User $user): \Illuminate\Contracts\View\View
|
||||||
{
|
{
|
||||||
return view('bo.pages.users.edit', ['userModel' => $user]);
|
$brandModels = CollectionHelper::paginate(Brand::getUserAssociatedBrands(), $this->jsonItemPerPagination);
|
||||||
|
return view('bo.pages.users.edit', ['userModel' => $user, 'brandModels' => $brandModels]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -124,6 +129,7 @@ class UsersController extends Controller
|
||||||
$user->fill($request->validated());
|
$user->fill($request->validated());
|
||||||
|
|
||||||
if ($user->saveOrFail()) {
|
if ($user->saveOrFail()) {
|
||||||
|
$user->brands()->sync(collect($request->validated()['brand_id'])->pluck('id')->toArray());
|
||||||
return redirect()->route('bo.users.edit', $user)
|
return redirect()->route('bo.users.edit', $user)
|
||||||
->with('success', __('crud.messages.has_been_updated', [
|
->with('success', __('crud.messages.has_been_updated', [
|
||||||
'model' => Str::ucfirst(__('models.classes.user'))
|
'model' => Str::ucfirst(__('models.classes.user'))
|
||||||
|
|
@ -4,11 +4,12 @@ namespace App\Http\Controllers;
|
||||||
|
|
||||||
use App\Enums\Pagination\ItemsPerPaginationEnum;
|
use App\Enums\Pagination\ItemsPerPaginationEnum;
|
||||||
use App\Enums\Theme\BootstrapThemeEnum;
|
use App\Enums\Theme\BootstrapThemeEnum;
|
||||||
|
use App\Http\Requests\Bo\PaginateModelsRequest;
|
||||||
|
use App\Http\Requests\Bo\ThemeRequest;
|
||||||
use App\Lib\Helpers\ToolboxHelper;
|
use App\Lib\Helpers\ToolboxHelper;
|
||||||
use Illuminate\Database\Eloquent\Builder;
|
use Illuminate\Database\Eloquent\Builder;
|
||||||
use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
|
use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
|
||||||
use Illuminate\Foundation\Validation\ValidatesRequests;
|
use Illuminate\Foundation\Validation\ValidatesRequests;
|
||||||
use Illuminate\Http\Request;
|
|
||||||
use Illuminate\Routing\Controller as BaseController;
|
use Illuminate\Routing\Controller as BaseController;
|
||||||
use Illuminate\Support\Facades\Cache;
|
use Illuminate\Support\Facades\Cache;
|
||||||
use Illuminate\Support\Facades\Schema;
|
use Illuminate\Support\Facades\Schema;
|
||||||
|
|
@ -20,6 +21,9 @@ class Controller extends BaseController
|
||||||
use AuthorizesRequests;
|
use AuthorizesRequests;
|
||||||
use ValidatesRequests;
|
use ValidatesRequests;
|
||||||
|
|
||||||
|
/** @var integer $itemPerPagination */
|
||||||
|
public $jsonItemPerPagination = 5;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Build Search query on specified fields
|
* Build Search query on specified fields
|
||||||
* splitting search into words or using whole sentence
|
* splitting search into words or using whole sentence
|
||||||
|
|
@ -156,7 +160,7 @@ class Controller extends BaseController
|
||||||
Session::put("$rName.sort_way", request()->sort_way);
|
Session::put("$rName.sort_way", request()->sort_way);
|
||||||
Session::put("$rName.sorted", true);
|
Session::put("$rName.sorted", true);
|
||||||
}
|
}
|
||||||
if (request()->rst) {
|
if (request()->rstSrts) {
|
||||||
Session::remove("$rName.sorted");
|
Session::remove("$rName.sorted");
|
||||||
Session::remove("$rName.sort_col");
|
Session::remove("$rName.sort_col");
|
||||||
Session::remove("$rName.sort_way");
|
Session::remove("$rName.sort_way");
|
||||||
|
|
@ -185,16 +189,13 @@ class Controller extends BaseController
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Customize pagination with cache or config (default).
|
* Get the number of items per page.
|
||||||
*
|
*
|
||||||
* @param \Illuminate\Database\Eloquent\Builder $query
|
|
||||||
* @param \App\Enums\Pagination\ItemsPerPaginationEnum|null $pagination
|
* @param \App\Enums\Pagination\ItemsPerPaginationEnum|null $pagination
|
||||||
* @return \Illuminate\Contracts\Pagination\LengthAwarePaginator
|
* @return integer
|
||||||
*/
|
*/
|
||||||
protected function paginate(
|
protected function getPagination(ItemsPerPaginationEnum $pagination = null): int
|
||||||
Builder $query,
|
{
|
||||||
ItemsPerPaginationEnum $pagination = null
|
|
||||||
): \Illuminate\Contracts\Pagination\LengthAwarePaginator {
|
|
||||||
$currentRoutePath = Str::slug(request()->route()->getName());
|
$currentRoutePath = Str::slug(request()->route()->getName());
|
||||||
$cacheKey = "pagination.{$currentRoutePath}";
|
$cacheKey = "pagination.{$currentRoutePath}";
|
||||||
$pagination = $pagination ?? ItemsPerPaginationEnum::twelve;
|
$pagination = $pagination ?? ItemsPerPaginationEnum::twelve;
|
||||||
|
|
@ -206,20 +207,35 @@ class Controller extends BaseController
|
||||||
if (Cache::get($cacheKey) !== $pagination) {
|
if (Cache::get($cacheKey) !== $pagination) {
|
||||||
Cache::put($cacheKey, $pagination);
|
Cache::put($cacheKey, $pagination);
|
||||||
}
|
}
|
||||||
$query = $query->paginate($pagination);
|
return $pagination;
|
||||||
return $query;
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a paginate resource.
|
||||||
|
*
|
||||||
|
* @param \App\Http\Requests\Bo\PaginateModelsRequest $request
|
||||||
|
* @return \Illuminate\Http\JsonResponse
|
||||||
|
*/
|
||||||
|
public function jsonPaginateModels(PaginateModelsRequest $request): \Illuminate\Http\JsonResponse
|
||||||
|
{
|
||||||
|
/** @var \Illuminate\Database\Eloquent\Model $models */
|
||||||
|
$models = $request->targetModel::query()
|
||||||
|
->where($request->input('fieldName') ?? 'name', 'like', "%{$request->input('search')}%")
|
||||||
|
->orderBy($request->input('fieldName') ?? 'name', 'ASC')
|
||||||
|
->paginate($request->input('paginate') ?? 10);
|
||||||
|
return \response()->json($models);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the bootstrap theme or light (default).
|
* Set the bootstrap theme or light (default).
|
||||||
*
|
*
|
||||||
* @param \Illuminate\Http\Request $request
|
* @param \App\Http\Requests\Bo\ThemeRequest $request
|
||||||
* @return \Illuminate\Http\RedirectResponse
|
* @return \Illuminate\Http\RedirectResponse
|
||||||
*/
|
*/
|
||||||
protected function setTheme(Request $request): \Illuminate\Http\RedirectResponse
|
protected function setTheme(ThemeRequest $request): \Illuminate\Http\RedirectResponse
|
||||||
{
|
{
|
||||||
$theme = ToolboxHelper::getValidatedEnum(
|
$theme = ToolboxHelper::getValidatedEnum(
|
||||||
$request->theme ?: Cache::get('theme', BootstrapThemeEnum::light->value()),
|
$request->validated('theme') ?: Cache::get('theme', BootstrapThemeEnum::light->value()),
|
||||||
'theme',
|
'theme',
|
||||||
'\App\Http\Controllers\BootstrapThemeEnum',
|
'\App\Http\Controllers\BootstrapThemeEnum',
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -20,7 +20,6 @@ class Kernel extends HttpKernel
|
||||||
\App\Http\Middleware\PreventRequestsDuringMaintenance::class,
|
\App\Http\Middleware\PreventRequestsDuringMaintenance::class,
|
||||||
\Illuminate\Foundation\Http\Middleware\ValidatePostSize::class,
|
\Illuminate\Foundation\Http\Middleware\ValidatePostSize::class,
|
||||||
\App\Http\Middleware\TrimStrings::class,
|
\App\Http\Middleware\TrimStrings::class,
|
||||||
\App\Http\Middleware\HtmlSanitizer::class
|
|
||||||
];
|
];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -39,7 +38,6 @@ class Kernel extends HttpKernel
|
||||||
\Illuminate\Routing\Middleware\SubstituteBindings::class,
|
\Illuminate\Routing\Middleware\SubstituteBindings::class,
|
||||||
\App\Http\Middleware\SecureHeaders::class
|
\App\Http\Middleware\SecureHeaders::class
|
||||||
],
|
],
|
||||||
|
|
||||||
'api' => [
|
'api' => [
|
||||||
\Illuminate\Routing\Middleware\ThrottleRequests::class . ':api',
|
\Illuminate\Routing\Middleware\ThrottleRequests::class . ':api',
|
||||||
\App\Http\Middleware\JsonOnly::class,
|
\App\Http\Middleware\JsonOnly::class,
|
||||||
|
|
@ -47,6 +45,11 @@ class Kernel extends HttpKernel
|
||||||
\App\Http\Middleware\ApiCheckTimeStamps::class,
|
\App\Http\Middleware\ApiCheckTimeStamps::class,
|
||||||
\Illuminate\Routing\Middleware\SubstituteBindings::class
|
\Illuminate\Routing\Middleware\SubstituteBindings::class
|
||||||
],
|
],
|
||||||
|
'saml' => [
|
||||||
|
\App\Http\Middleware\EncryptCookies::class,
|
||||||
|
\Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
|
||||||
|
\Illuminate\Session\Middleware\StartSession::class,
|
||||||
|
],
|
||||||
];
|
];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -57,16 +60,17 @@ class Kernel extends HttpKernel
|
||||||
* @var array
|
* @var array
|
||||||
*/
|
*/
|
||||||
protected $routeMiddleware = [
|
protected $routeMiddleware = [
|
||||||
'auth' => \App\Http\Middleware\Authenticate::class,
|
'auth' => \App\Http\Middleware\Authenticate::class,
|
||||||
'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
|
'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
|
||||||
'auth.session' => \Illuminate\Session\Middleware\AuthenticateSession::class,
|
'auth.session' => \Illuminate\Session\Middleware\AuthenticateSession::class,
|
||||||
'cache.headers' => \Illuminate\Http\Middleware\SetCacheHeaders::class,
|
'cache.headers' => \Illuminate\Http\Middleware\SetCacheHeaders::class,
|
||||||
'can' => \Illuminate\Auth\Middleware\Authorize::class,
|
'can' => \Illuminate\Auth\Middleware\Authorize::class,
|
||||||
'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class,
|
'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class,
|
||||||
'password.confirm' => \Illuminate\Auth\Middleware\RequirePassword::class,
|
'password.confirm' => \Illuminate\Auth\Middleware\RequirePassword::class,
|
||||||
'signed' => \App\Http\Middleware\ValidateSignature::class,
|
'signed' => \App\Http\Middleware\ValidateSignature::class,
|
||||||
'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,
|
'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,
|
||||||
'verified' => \Illuminate\Auth\Middleware\EnsureEmailIsVerified::class,
|
'verified' => \Illuminate\Auth\Middleware\EnsureEmailIsVerified::class,
|
||||||
'htmlsanitize' => \App\Http\Middleware\HtmlSanitizer::class,
|
'htmlsanitize' => \App\Http\Middleware\HtmlSanitizer::class,
|
||||||
|
'logoutusers' => \App\Http\Middleware\LogoutUnpublishedUsers::class,
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -57,9 +57,8 @@ class ApiResponse
|
||||||
$status = intval($response->getStatusCode() / 100) == 2 ? ApiStatus::OK : ApiStatus::KO;
|
$status = intval($response->getStatusCode() / 100) == 2 ? ApiStatus::OK : ApiStatus::KO;
|
||||||
|
|
||||||
if (Helper::isRequestForApiV2($request)) {
|
if (Helper::isRequestForApiV2($request)) {
|
||||||
return $response->setData(new V2ApiResponse((object)$data, $status));
|
return $response->setData(new V2ApiResponse($status, (object) $data));
|
||||||
}
|
}
|
||||||
|
return $response->setData(new V4ApiResponse($status, (object) $data));
|
||||||
return $response->setData(new V4ApiResponse((object)$data, $status));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -31,7 +31,7 @@ class Authenticate extends Middleware
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return route('login');
|
return route('bo.login');
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,6 @@ namespace App\Http\Middleware;
|
||||||
|
|
||||||
use App\Lib\Helpers\ToolboxHelper;
|
use App\Lib\Helpers\ToolboxHelper;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
use Symfony\Component\HttpFoundation\Response;
|
|
||||||
|
|
||||||
class HtmlSanitizer
|
class HtmlSanitizer
|
||||||
{
|
{
|
||||||
|
|
@ -16,8 +15,11 @@ class HtmlSanitizer
|
||||||
* @param string|array ...$params
|
* @param string|array ...$params
|
||||||
* @return \Symfony\Component\HttpFoundation\Response
|
* @return \Symfony\Component\HttpFoundation\Response
|
||||||
*/
|
*/
|
||||||
public function handle(Request $request, \Closure $next, string|array ...$params): Response
|
public function handle(
|
||||||
{
|
Request $request,
|
||||||
|
\Closure $next,
|
||||||
|
string|array ...$params
|
||||||
|
): \Symfony\Component\HttpFoundation\Response {
|
||||||
$inputs = $request->all();
|
$inputs = $request->all();
|
||||||
/** @var callable|null */
|
/** @var callable|null */
|
||||||
$cleanInput = null;
|
$cleanInput = null;
|
||||||
|
|
|
||||||
28
app/Http/Middleware/LogoutUnpublishedUsers.php
Normal file
28
app/Http/Middleware/LogoutUnpublishedUsers.php
Normal file
|
|
@ -0,0 +1,28 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Middleware;
|
||||||
|
|
||||||
|
use Closure;
|
||||||
|
use Illuminate\Http\Request;
|
||||||
|
use Illuminate\Support\Facades\Auth;
|
||||||
|
|
||||||
|
class LogoutUnpublishedUsers
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Handle an incoming request.
|
||||||
|
*
|
||||||
|
* @param \Illuminate\Http\Request $request
|
||||||
|
* @param \Closure $next
|
||||||
|
* @return mixed
|
||||||
|
*/
|
||||||
|
public function handle(Request $request, Closure $next)
|
||||||
|
{
|
||||||
|
/** @var \App\Models\User|null $userModel */
|
||||||
|
$userModel = Auth::user();
|
||||||
|
if (!is_null($userModel) && !$userModel->published) {
|
||||||
|
Auth::logout();
|
||||||
|
return redirect()->route('bo.login')->with('warning', trans('auth.unpublished_user'));
|
||||||
|
}
|
||||||
|
return $next($request);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -15,6 +15,7 @@ class TrustHosts extends Middleware
|
||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
$this->allSubdomainsOfApplicationUrl(),
|
$this->allSubdomainsOfApplicationUrl(),
|
||||||
|
config('app.k8s_internal_url'),
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -22,7 +22,7 @@ class GetBrandStatsRequest extends BaseApiRequest
|
||||||
public function rules(): array
|
public function rules(): array
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
if (Carbon::parse($this->end)->floatDiffInMonths(Carbon::parse($this->start)) > 3) {
|
if (Carbon::parse($this->end)->floatDiffInMonths(Carbon::parse($this->start), true) > 3) {
|
||||||
throw ValidationException::withMessages([
|
throw ValidationException::withMessages([
|
||||||
'Vous devez sélectionner une période de maximum 3 mois'
|
'Vous devez sélectionner une période de maximum 3 mois'
|
||||||
]);
|
]);
|
||||||
|
|
@ -36,7 +36,7 @@ class GetBrandStatsRequest extends BaseApiRequest
|
||||||
throw $e;
|
throw $e;
|
||||||
}
|
}
|
||||||
return [
|
return [
|
||||||
'start' => 'required|date|date_format:Y-m-d',
|
'start' => 'required|date|date_format:Y-m-d|before_or_equal:end',
|
||||||
'end' => 'required|date|date_format:Y-m-d|after_or_equal:start',
|
'end' => 'required|date|date_format:Y-m-d|after_or_equal:start',
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -23,7 +23,7 @@ class GetQuestionStatsRequest extends BaseApiRequest
|
||||||
public function rules(): array
|
public function rules(): array
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
if (Carbon::parse($this->end)->floatDiffInMonths(Carbon::parse($this->start)) > 3) {
|
if (Carbon::parse($this->end)->floatDiffInMonths(Carbon::parse($this->start), true) > 3) {
|
||||||
throw ValidationException::withMessages([
|
throw ValidationException::withMessages([
|
||||||
'Vous devez sélectionner une période de maximum 3 mois'
|
'Vous devez sélectionner une période de maximum 3 mois'
|
||||||
]);
|
]);
|
||||||
|
|
@ -37,7 +37,7 @@ class GetQuestionStatsRequest extends BaseApiRequest
|
||||||
throw $e;
|
throw $e;
|
||||||
}
|
}
|
||||||
return [
|
return [
|
||||||
'start' => 'required|date|date_format:Y-m-d',
|
'start' => 'required|date|date_format:Y-m-d|before_or_equal:end',
|
||||||
'end' => 'required|date|date_format:Y-m-d|after_or_equal:start',
|
'end' => 'required|date|date_format:Y-m-d|after_or_equal:start',
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -15,8 +15,10 @@ class SingleOptinRequest extends BaseApiRequest
|
||||||
public function rules(): array
|
public function rules(): array
|
||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
'email' => 'required|email:rfc,dns,spoof,filter',
|
'email' => 'required|email:rfc,dns,spoof,filter',
|
||||||
'opt_in' => 'required|boolean'
|
'opt_in' => 'required|boolean',
|
||||||
|
'answer_id' => 'sometimes|array|min:1',
|
||||||
|
'answer_id.*' => 'sometimes|integer|exists:answers,id',
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -28,7 +28,7 @@ class StoreCustomerAnswers extends BaseApiRequest
|
||||||
'question' => [
|
'question' => [
|
||||||
'required',
|
'required',
|
||||||
"exists:$questionTableName,id",
|
"exists:$questionTableName,id",
|
||||||
// phpcs:ignore Generic.CodeAnalysis.UnusedFunctionParameter.FoundInExtendedClassBeforeLastUsed
|
// phpcs:ignore Generic.CodeAnalysis.UnusedFunctionParameter.FoundBeforeLastUsed
|
||||||
function ($attribute, $value, $fail) use ($question, $brandId) {
|
function ($attribute, $value, $fail) use ($question, $brandId) {
|
||||||
if ($question->brand->id !== $brandId) {
|
if ($question->brand->id !== $brandId) {
|
||||||
$fail("$attribute does not belong to brand $brandId");
|
$fail("$attribute does not belong to brand $brandId");
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,6 @@ namespace App\Http\Requests\Api\V4;
|
||||||
use App\Http\Sanitizers\RemoveSpaces;
|
use App\Http\Sanitizers\RemoveSpaces;
|
||||||
use ArondeParon\RequestSanitizer\Sanitizers\Capitalize;
|
use ArondeParon\RequestSanitizer\Sanitizers\Capitalize;
|
||||||
use ArondeParon\RequestSanitizer\Sanitizers\Lowercase;
|
use ArondeParon\RequestSanitizer\Sanitizers\Lowercase;
|
||||||
use ArondeParon\RequestSanitizer\Sanitizers\RemoveNonNumeric;
|
|
||||||
use ArondeParon\RequestSanitizer\Sanitizers\Trim;
|
use ArondeParon\RequestSanitizer\Sanitizers\Trim;
|
||||||
use ArondeParon\RequestSanitizer\Sanitizers\TrimDuplicateSpaces;
|
use ArondeParon\RequestSanitizer\Sanitizers\TrimDuplicateSpaces;
|
||||||
use ArondeParon\RequestSanitizer\Traits\SanitizesInputs;
|
use ArondeParon\RequestSanitizer\Traits\SanitizesInputs;
|
||||||
|
|
@ -29,7 +28,7 @@ abstract class BaseApiRequest extends FormRequest
|
||||||
'password' => Trim::class,
|
'password' => Trim::class,
|
||||||
'phone' => [Trim::class, RemoveSpaces::class],
|
'phone' => [Trim::class, RemoveSpaces::class],
|
||||||
'email' => [Lowercase::class, Trim::class, RemoveSpaces::class],
|
'email' => [Lowercase::class, Trim::class, RemoveSpaces::class],
|
||||||
'postcode' => [RemoveNonNumeric::class, Trim::class]
|
'postcode' => [Trim::class]
|
||||||
];
|
];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,7 @@ class GetBrandStatsRequest extends BaseApiRequest
|
||||||
public function rules(): array
|
public function rules(): array
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
if (Carbon::parse($this->end)->floatDiffInMonths(Carbon::parse($this->start)) > 3) {
|
if (Carbon::parse($this->end)->floatDiffInMonths(Carbon::parse($this->start), true) > 3) {
|
||||||
throw ValidationException::withMessages([
|
throw ValidationException::withMessages([
|
||||||
'Vous devez sélectionner une période de maximum 3 mois'
|
'Vous devez sélectionner une période de maximum 3 mois'
|
||||||
]);
|
]);
|
||||||
|
|
@ -27,13 +27,13 @@ class GetBrandStatsRequest extends BaseApiRequest
|
||||||
} catch (\Exception $e) {
|
} catch (\Exception $e) {
|
||||||
if (\get_class($e) !== ValidationException::class) {
|
if (\get_class($e) !== ValidationException::class) {
|
||||||
throw ValidationException::withMessages([
|
throw ValidationException::withMessages([
|
||||||
'Les dates séléectionnées ne sembles pas être valides'
|
'Les dates sélectionnées ne sembles pas être valides'
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
throw $e;
|
throw $e;
|
||||||
}
|
}
|
||||||
return [
|
return [
|
||||||
'start' => 'required|date|date_format:Y-m-d',
|
'start' => 'required|date|date_format:Y-m-d|before_or_equal:end',
|
||||||
'end' => 'required|date|date_format:Y-m-d|after_or_equal:start',
|
'end' => 'required|date|date_format:Y-m-d|after_or_equal:start',
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,7 @@ class GetQuestionStatsRequest extends BaseApiRequest
|
||||||
public function rules(): array
|
public function rules(): array
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
if (Carbon::parse($this->end)->floatDiffInMonths(Carbon::parse($this->start)) > 3) {
|
if (Carbon::parse($this->end)->floatDiffInMonths(Carbon::parse($this->start), true) > 3) {
|
||||||
throw ValidationException::withMessages([
|
throw ValidationException::withMessages([
|
||||||
'Vous devez sélectionner une période de maximum 3 mois'
|
'Vous devez sélectionner une période de maximum 3 mois'
|
||||||
]);
|
]);
|
||||||
|
|
@ -33,7 +33,7 @@ class GetQuestionStatsRequest extends BaseApiRequest
|
||||||
throw $e;
|
throw $e;
|
||||||
}
|
}
|
||||||
return [
|
return [
|
||||||
'start' => 'required|date|date_format:Y-m-d',
|
'start' => 'required|date|date_format:Y-m-d|before_or_equal:end',
|
||||||
'end' => 'required|date|date_format:Y-m-d|after_or_equal:start',
|
'end' => 'required|date|date_format:Y-m-d|after_or_equal:start',
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
|
||||||
86
app/Http/Requests/Api/V4/SendClaimRequest.php
Normal file
86
app/Http/Requests/Api/V4/SendClaimRequest.php
Normal file
|
|
@ -0,0 +1,86 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Requests\Api\V4;
|
||||||
|
|
||||||
|
use App\Enums\Country;
|
||||||
|
use App\Http\Sanitizers\RemoveSpaces;
|
||||||
|
use ArondeParon\RequestSanitizer\Sanitizers\Capitalize;
|
||||||
|
use ArondeParon\RequestSanitizer\Sanitizers\Lowercase;
|
||||||
|
use ArondeParon\RequestSanitizer\Sanitizers\Trim;
|
||||||
|
use ArondeParon\RequestSanitizer\Sanitizers\TrimDuplicateSpaces;
|
||||||
|
|
||||||
|
class SendClaimRequest extends BaseApiRequest
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Using these sanitizers before proceeding the request.
|
||||||
|
*
|
||||||
|
* @var array
|
||||||
|
*/
|
||||||
|
protected $sanitizers = [
|
||||||
|
'first_name' => [Trim::class, TrimDuplicateSpaces::class, Capitalize::class],
|
||||||
|
'last_name' => [Trim::class, TrimDuplicateSpaces::class, Capitalize::class],
|
||||||
|
'email' => [Trim::class, RemoveSpaces::class, Lowercase::class],
|
||||||
|
'address' => [Trim::class, TrimDuplicateSpaces::class],
|
||||||
|
'city' => [Trim::class, TrimDuplicateSpaces::class],
|
||||||
|
'postcode' => [Trim::class],
|
||||||
|
'file' => [Trim::class],
|
||||||
|
'message' => [Trim::class],
|
||||||
|
];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determine if the user is authorized to make this request.
|
||||||
|
*
|
||||||
|
* @return boolean
|
||||||
|
*/
|
||||||
|
public function authorize(): bool
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the validation rules that apply to the request.
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function rules(): array
|
||||||
|
{
|
||||||
|
$countryList = ($this->currentCountry && $this->currentCountry->get('iso')) ?
|
||||||
|
$this->currentCountry->get('iso') : implode(',', Country::getValidIsoAplha2Codes());
|
||||||
|
return [
|
||||||
|
'first_name' => 'required|string|between:3,255',
|
||||||
|
'last_name' => 'required|string|between:3,255',
|
||||||
|
'email' => 'required|email:rfc,dns,spoof,filter|max:255',
|
||||||
|
'address' => 'sometimes|nullable|string|max:255',
|
||||||
|
'city' => 'sometimes|nullable|string|between:2,255',
|
||||||
|
'postcode' => ['sometimes', 'nullable', 'string', "postal_code:{$countryList}"],
|
||||||
|
'file' => [
|
||||||
|
'sometimes',
|
||||||
|
'nullable',
|
||||||
|
'string',
|
||||||
|
// @phpcs:ignore Generic.CodeAnalysis.UnusedFunctionParameter.FoundBeforeLastUsed
|
||||||
|
function ($attribute, $value, $fail) {
|
||||||
|
// Base64 validation.
|
||||||
|
$decoded = base64_decode($value, true);
|
||||||
|
if ($decoded === false) {
|
||||||
|
return $fail('Le fichier doit être un encodage base64 valide.');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check the size (5 MB max = 5 * 1024 * 1024).
|
||||||
|
if (strlen($decoded) > 5 * 1024 * 1024) {
|
||||||
|
return $fail('Le fichier est trop volumineux (max 5 Mo).');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check the MIME type.
|
||||||
|
$finfo = finfo_open(FILEINFO_MIME_TYPE);
|
||||||
|
$mime = finfo_buffer($finfo, $decoded);
|
||||||
|
$allowed = ['image/jpeg', 'image/png', 'application/pdf'];
|
||||||
|
if (!in_array($mime, $allowed)) {
|
||||||
|
return $fail('Le fichier doit être une image JPG/PNG ou un PDF.');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
'message' => 'required|string|min:3',
|
||||||
|
'subject_id' => 'required|integer|exists:claim_subjects,id',
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -12,8 +12,10 @@ class SingleOptinRequest extends BaseApiRequest
|
||||||
public function rules(): array
|
public function rules(): array
|
||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
'email' => 'required|email:rfc,dns,spoof,filter',
|
'email' => 'required|email:rfc,dns,spoof,filter',
|
||||||
'opt_in' => 'required|boolean'
|
'opt_in' => 'required|boolean',
|
||||||
|
'answer_id' => 'sometimes|array|min:1',
|
||||||
|
'answer_id.*' => 'sometimes|integer|exists:answers,id',
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -25,7 +25,7 @@ class StoreCustomerAnswers extends BaseApiRequest
|
||||||
'question' => [
|
'question' => [
|
||||||
'required',
|
'required',
|
||||||
"exists:$questionTableName,id",
|
"exists:$questionTableName,id",
|
||||||
// phpcs:ignore Generic.CodeAnalysis.UnusedFunctionParameter.FoundInExtendedClassBeforeLastUsed
|
// phpcs:ignore Generic.CodeAnalysis.UnusedFunctionParameter.FoundBeforeLastUsed
|
||||||
function ($attribute, $value, $fail) use ($question, $brandId) {
|
function ($attribute, $value, $fail) use ($question, $brandId) {
|
||||||
if ($question->brand->id !== $brandId) {
|
if ($question->brand->id !== $brandId) {
|
||||||
$fail("$attribute does not belong to brand $brandId");
|
$fail("$attribute does not belong to brand $brandId");
|
||||||
|
|
|
||||||
|
|
@ -3,9 +3,12 @@
|
||||||
namespace App\Http\Requests\Bo\Brands;
|
namespace App\Http\Requests\Bo\Brands;
|
||||||
|
|
||||||
use Illuminate\Foundation\Http\FormRequest;
|
use Illuminate\Foundation\Http\FormRequest;
|
||||||
|
use Uwil\LaravelCommon\Traits\Requests\HasPicture;
|
||||||
|
|
||||||
class StoreBrandRequest extends FormRequest
|
class StoreBrandRequest extends FormRequest
|
||||||
{
|
{
|
||||||
|
use HasPicture;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Determine if the user is authorized to make this request.
|
* Determine if the user is authorized to make this request.
|
||||||
*
|
*
|
||||||
|
|
@ -16,6 +19,16 @@ class StoreBrandRequest extends FormRequest
|
||||||
return auth('backend')->check();
|
return auth('backend')->check();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Prepare the data for validation.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
protected function prepareForValidation(): void
|
||||||
|
{
|
||||||
|
$this->mergePicture('logo');
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the validation rules that apply to the request.
|
* Get the validation rules that apply to the request.
|
||||||
*
|
*
|
||||||
|
|
@ -23,9 +36,16 @@ class StoreBrandRequest extends FormRequest
|
||||||
*/
|
*/
|
||||||
public function rules(): array
|
public function rules(): array
|
||||||
{
|
{
|
||||||
return [
|
$rules = [
|
||||||
'name' => 'required|string|min:5|max:255',
|
'name' => 'required|unique:brands,name|string|min:5|max:255',
|
||||||
|
'url' => 'required|url|min:5|max:255',
|
||||||
|
'url_claim' => 'required|url|min:5|max:255',
|
||||||
|
'domain' => 'required|unique:brands,domain|string|min:5|max:255',
|
||||||
];
|
];
|
||||||
|
return \array_merge(
|
||||||
|
$rules,
|
||||||
|
$this->pictureRules('logo', 550, 550, 550, 550),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -36,7 +56,11 @@ class StoreBrandRequest extends FormRequest
|
||||||
public function attributes(): array
|
public function attributes(): array
|
||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
'name' => trans('Nom de la marque'),
|
'name' => trans('validation.attributes.name'),
|
||||||
|
'logo' => trans('validation.custom.logo'),
|
||||||
|
'url' => trans('validation.custom.url'),
|
||||||
|
'url_claim' => trans('validation.custom.url_claim'),
|
||||||
|
'domain' => trans('validation.custom.domain'),
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -4,4 +4,34 @@ namespace App\Http\Requests\Bo\Brands;
|
||||||
|
|
||||||
class UpdateBrandRequest extends StoreBrandRequest
|
class UpdateBrandRequest extends StoreBrandRequest
|
||||||
{
|
{
|
||||||
|
/**
|
||||||
|
* Get the validation rules that apply to the request.
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function rules(): array
|
||||||
|
{
|
||||||
|
/** @var integer $brandModelKey */
|
||||||
|
$brandModelKey = request()->route()->parameter('brand')->getKey();
|
||||||
|
$rules = [
|
||||||
|
'name' => [
|
||||||
|
'required',
|
||||||
|
"unique:brands,name,$brandModelKey",
|
||||||
|
'string',
|
||||||
|
'min:5',
|
||||||
|
'max:255',
|
||||||
|
],
|
||||||
|
'domain' => [
|
||||||
|
'required',
|
||||||
|
"unique:brands,domain,$brandModelKey",
|
||||||
|
'string',
|
||||||
|
'min:5',
|
||||||
|
'max:255',
|
||||||
|
],
|
||||||
|
];
|
||||||
|
return \array_merge(
|
||||||
|
parent::rules(),
|
||||||
|
$rules,
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,47 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Requests\Bo\ClaimMailTemplates;
|
||||||
|
|
||||||
|
use Illuminate\Foundation\Http\FormRequest;
|
||||||
|
use Uwil\LaravelCommon\Rules\WysiwygLength;
|
||||||
|
|
||||||
|
class ClaimMailTemplateRequest extends FormRequest
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Determine if the user is authorized to make this request.
|
||||||
|
*
|
||||||
|
* @return boolean
|
||||||
|
*/
|
||||||
|
public function authorize(): bool
|
||||||
|
{
|
||||||
|
return auth('backend')->check();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the validation rules that apply to the request.
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function rules(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'brand_id' => 'required|exists:brands,id',
|
||||||
|
'label' => 'required|string|min:3|max:255',
|
||||||
|
'content' => ['required', 'string', new WysiwygLength()],
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get custom attributes for validator errors.
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function attributes(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'brand_id' => trans('models.classes.brands'),
|
||||||
|
'label' => trans('validation.custom.label'),
|
||||||
|
'content' => trans('validation.attributes.content'),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
66
app/Http/Requests/Bo/ClaimMessages/StoreMessageRequest.php
Normal file
66
app/Http/Requests/Bo/ClaimMessages/StoreMessageRequest.php
Normal file
|
|
@ -0,0 +1,66 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Requests\Bo\ClaimMessages;
|
||||||
|
|
||||||
|
use App\Enums\Claims\ClaimMessageType;
|
||||||
|
use Illuminate\Foundation\Http\FormRequest;
|
||||||
|
use Illuminate\Validation\Rules\Enum;
|
||||||
|
|
||||||
|
class StoreMessageRequest extends FormRequest
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Determine if the user is authorized to make this request.
|
||||||
|
*
|
||||||
|
* @return boolean
|
||||||
|
*/
|
||||||
|
public function authorize(): bool
|
||||||
|
{
|
||||||
|
return auth('backend')->check();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Prepare the data for validation.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
protected function prepareForValidation(): void
|
||||||
|
{
|
||||||
|
/** @var \App\Models\User $userModel */
|
||||||
|
$userModel = auth('backend')->user();
|
||||||
|
|
||||||
|
$this->merge([
|
||||||
|
'user_id' => $userModel->getKey(),
|
||||||
|
'type' => ClaimMessageType::human->value(),
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the validation rules that apply to the request.
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function rules(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'claim_id' => 'required|numeric|exists:claims,id',
|
||||||
|
'user_id' => 'required|numeric|exists:users,id',
|
||||||
|
'content' => 'required|string|between:3,255',
|
||||||
|
'type' => ['required', new Enum(ClaimMessageType::class)],
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get custom attributes for validator errors.
|
||||||
|
*
|
||||||
|
* @return array<string,\Illuminate\Contracts\Translation\Translator|string|array<mixed>|null>
|
||||||
|
*/
|
||||||
|
public function attributes(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'claim_id' => trans('models.classes.claims'),
|
||||||
|
'user_id' => trans('models.classes.users'),
|
||||||
|
'content' => trans('validation.attributes.content'),
|
||||||
|
'type' => trans('validation.custom.type'),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
44
app/Http/Requests/Bo/ClaimMessages/UpdateMessageRequest.php
Normal file
44
app/Http/Requests/Bo/ClaimMessages/UpdateMessageRequest.php
Normal file
|
|
@ -0,0 +1,44 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Requests\Bo\ClaimMessages;
|
||||||
|
|
||||||
|
use Illuminate\Foundation\Http\FormRequest;
|
||||||
|
|
||||||
|
class UpdateMessageRequest extends FormRequest
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Determine if the user is authorized to make this request.
|
||||||
|
*
|
||||||
|
* @return boolean
|
||||||
|
*/
|
||||||
|
public function authorize(): bool
|
||||||
|
{
|
||||||
|
return auth('backend')->check();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the validation rules that apply to the request.
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function rules(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'claim_message_id' => 'required|numeric|exists:claim_messages,id',
|
||||||
|
'content' => 'required|string|between:3,255',
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get custom attributes for validator errors.
|
||||||
|
*
|
||||||
|
* @return array<string,\Illuminate\Contracts\Translation\Translator|string|array<mixed>|null>
|
||||||
|
*/
|
||||||
|
public function attributes(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'claim_message_id' => trans('models.classes.claim_messages'),
|
||||||
|
'content' => trans('validation.attributes.content'),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
44
app/Http/Requests/Bo/ClaimSubjects/ClaimSubjectRequest.php
Normal file
44
app/Http/Requests/Bo/ClaimSubjects/ClaimSubjectRequest.php
Normal file
|
|
@ -0,0 +1,44 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Requests\Bo\ClaimSubjects;
|
||||||
|
|
||||||
|
use Illuminate\Foundation\Http\FormRequest;
|
||||||
|
|
||||||
|
class ClaimSubjectRequest extends FormRequest
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Determine if the user is authorized to make this request.
|
||||||
|
*
|
||||||
|
* @return boolean
|
||||||
|
*/
|
||||||
|
public function authorize(): bool
|
||||||
|
{
|
||||||
|
return auth('backend')->check();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the validation rules that apply to the request.
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function rules(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'brand_id' => 'required|exists:brands,id',
|
||||||
|
'label' => 'required|string|min:3|max:255',
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get custom attributes for validator errors.
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function attributes(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'brand_id' => trans('models.classes.brands'),
|
||||||
|
'label' => trans('validation.custom.label'),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
65
app/Http/Requests/Bo/Claims/ExportClaimRequest.php
Normal file
65
app/Http/Requests/Bo/Claims/ExportClaimRequest.php
Normal file
|
|
@ -0,0 +1,65 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Requests\Bo\Claims;
|
||||||
|
|
||||||
|
use App\Enums\ExportFormat;
|
||||||
|
use Illuminate\Foundation\Http\FormRequest;
|
||||||
|
use Illuminate\Validation\Rule;
|
||||||
|
|
||||||
|
class ExportClaimRequest extends FormRequest
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Determine if the user is authorized to make this request.
|
||||||
|
*
|
||||||
|
* @return boolean
|
||||||
|
*/
|
||||||
|
public function authorize(): bool
|
||||||
|
{
|
||||||
|
return auth('backend')->check();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Prepare the data for validation.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function prepareForValidation()
|
||||||
|
{
|
||||||
|
$this->merge([
|
||||||
|
'claimList' => json_decode($this->input('claimList'), true)
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the validation rules that apply to the request.
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function rules(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'format' => [
|
||||||
|
'required',
|
||||||
|
Rule::enum(ExportFormat::class)
|
||||||
|
],
|
||||||
|
'claimList' => 'required|array',
|
||||||
|
'claimList.*' => 'required|numeric|exists:claims,id',
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get custom attributes for validator errors.
|
||||||
|
*
|
||||||
|
* @return array<string,\Illuminate\Contracts\Translation\Translator|string|array<mixed>|null>
|
||||||
|
*/
|
||||||
|
public function attributes(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'brand_id' => trans('models.classes.brands'),
|
||||||
|
'subject_id' => trans('models.classes.claimsubjects'),
|
||||||
|
'type' => trans('validation.custom.type'),
|
||||||
|
'status' => trans('validation.custom.status'),
|
||||||
|
'response_type' => trans('validation.custom.response_type'),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
44
app/Http/Requests/Bo/Claims/SendClaimAnswerRequest.php
Normal file
44
app/Http/Requests/Bo/Claims/SendClaimAnswerRequest.php
Normal file
|
|
@ -0,0 +1,44 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Requests\Bo\Claims;
|
||||||
|
|
||||||
|
use Illuminate\Foundation\Http\FormRequest;
|
||||||
|
|
||||||
|
class SendClaimAnswerRequest extends FormRequest
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Determine if the user is authorized to make this request.
|
||||||
|
*
|
||||||
|
* @return boolean
|
||||||
|
*/
|
||||||
|
public function authorize(): bool
|
||||||
|
{
|
||||||
|
return auth('backend')->check();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the validation rules that apply to the request.
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function rules(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'claim_id' => 'required|numeric|exists:claims,id',
|
||||||
|
'content' => 'required|string|between:3,2000',
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get custom attributes for validator errors.
|
||||||
|
*
|
||||||
|
* @return array<string,\Illuminate\Contracts\Translation\Translator|string|array<mixed>|null>
|
||||||
|
*/
|
||||||
|
public function attributes(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'claim_id' => trans('models.classes.claims'),
|
||||||
|
'content' => trans('validation.attributes.content'),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
54
app/Http/Requests/Bo/Claims/UpdateClaimRequest.php
Normal file
54
app/Http/Requests/Bo/Claims/UpdateClaimRequest.php
Normal file
|
|
@ -0,0 +1,54 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Requests\Bo\Claims;
|
||||||
|
|
||||||
|
use App\Enums\Claims\ClaimResponseType;
|
||||||
|
use App\Enums\Claims\ClaimStatus;
|
||||||
|
use App\Enums\Claims\ClaimType;
|
||||||
|
use Illuminate\Foundation\Http\FormRequest;
|
||||||
|
use Illuminate\Validation\Rules\Enum;
|
||||||
|
|
||||||
|
class UpdateClaimRequest extends FormRequest
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Determine if the user is authorized to make this request.
|
||||||
|
*
|
||||||
|
* @return boolean
|
||||||
|
*/
|
||||||
|
public function authorize(): bool
|
||||||
|
{
|
||||||
|
return auth('backend')->check();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the validation rules that apply to the request.
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function rules(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'brand_id' => 'required|numeric|exists:brands,id',
|
||||||
|
'subject_id' => 'required|numeric|exists:claim_subjects,id',
|
||||||
|
'type' => ['required', new Enum(ClaimType::class)],
|
||||||
|
'status' => ['required', new Enum(ClaimStatus::class)],
|
||||||
|
'response_type' => ['present', 'nullable', new Enum(ClaimResponseType::class)],
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get custom attributes for validator errors.
|
||||||
|
*
|
||||||
|
* @return array<string,\Illuminate\Contracts\Translation\Translator|string|array<mixed>|null>
|
||||||
|
*/
|
||||||
|
public function attributes(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'brand_id' => trans('models.classes.brands'),
|
||||||
|
'subject_id' => trans('models.classes.claimsubjects'),
|
||||||
|
'type' => trans('validation.custom.type'),
|
||||||
|
'status' => trans('validation.custom.status'),
|
||||||
|
'response_type' => trans('validation.custom.response_type'),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
35
app/Http/Requests/Bo/Claims/ViewClaimAttachmentRequest.php
Normal file
35
app/Http/Requests/Bo/Claims/ViewClaimAttachmentRequest.php
Normal file
|
|
@ -0,0 +1,35 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Requests\Bo\Claims;
|
||||||
|
|
||||||
|
use App\Enums\Users\RoleEnum;
|
||||||
|
use App\Policies\Rules\UserStaticRules;
|
||||||
|
use Illuminate\Foundation\Http\FormRequest;
|
||||||
|
|
||||||
|
class ViewClaimAttachmentRequest extends FormRequest
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Determine if the user is authorized to make this request.
|
||||||
|
*
|
||||||
|
* @return boolean
|
||||||
|
*/
|
||||||
|
public function authorize(): bool
|
||||||
|
{
|
||||||
|
/** @var \App\Models\User $user */
|
||||||
|
$user = auth('backend')->user();
|
||||||
|
|
||||||
|
return auth('backend')->check() &&
|
||||||
|
($user->brands->contains($this->claim->brand->id) ||
|
||||||
|
UserStaticRules::atLeastRole($user, RoleEnum::admin));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the validation rules that apply to the request.
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function rules(): array
|
||||||
|
{
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -29,7 +29,7 @@ class CustomerExport extends FormRequest
|
||||||
'export_type' => [
|
'export_type' => [
|
||||||
'required',
|
'required',
|
||||||
'numeric',
|
'numeric',
|
||||||
// phpcs:ignore Generic.CodeAnalysis.UnusedFunctionParameter.FoundInExtendedClassBeforeLastUsed
|
// phpcs:ignore Generic.CodeAnalysis.UnusedFunctionParameter.FoundBeforeLastUsed
|
||||||
function ($attribute, $value, $fail) {
|
function ($attribute, $value, $fail) {
|
||||||
if (!\in_array($value, CustomerExportType::toValues())) {
|
if (!\in_array($value, CustomerExportType::toValues())) {
|
||||||
$fail(trans('Le type d\'export invalide'));
|
$fail(trans('Le type d\'export invalide'));
|
||||||
|
|
|
||||||
52
app/Http/Requests/Bo/PaginateModelsRequest.php
Normal file
52
app/Http/Requests/Bo/PaginateModelsRequest.php
Normal file
|
|
@ -0,0 +1,52 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Requests\Bo;
|
||||||
|
|
||||||
|
use Illuminate\Foundation\Http\FormRequest;
|
||||||
|
|
||||||
|
class PaginateModelsRequest extends FormRequest
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Get the validation rules that apply to the request.
|
||||||
|
*
|
||||||
|
* @return array<string,\Illuminate\Contracts\Validation\ValidationRule|array<mixed>|string>
|
||||||
|
*/
|
||||||
|
public function rules(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'targetModel' => [
|
||||||
|
'required',
|
||||||
|
'string',
|
||||||
|
'starts_with:App\\Models\\',
|
||||||
|
// phpcs:ignore Generic.CodeAnalysis.UnusedFunctionParameter.FoundBeforeLastUsed
|
||||||
|
function ($attribute, $value, $fail) {
|
||||||
|
if (!class_exists($value)) {
|
||||||
|
$fail("Le modèle spécifié n'existe pas.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!is_subclass_of($value, \Illuminate\Database\Eloquent\Model::class)) {
|
||||||
|
$fail("Le modèle spécifié n'est pas un modèle Eloquent.");
|
||||||
|
}
|
||||||
|
},
|
||||||
|
],
|
||||||
|
'page' => 'required|integer|min:1',
|
||||||
|
'paginate' => 'required|integer|min:1',
|
||||||
|
'fieldName' => 'required|string|alpha_dash|max:255',
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get custom attributes for validator errors.
|
||||||
|
*
|
||||||
|
* @return array<string,\Illuminate\Contracts\Translation\Translator|string|array<mixed>|null>
|
||||||
|
*/
|
||||||
|
public function attributes(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'targetModel' => trans('validation.custom.targetModel'),
|
||||||
|
'page' => trans('validation.custom.page'),
|
||||||
|
'paginate' => trans('validation.custom.paginate'),
|
||||||
|
'fieldName' => trans('validation.custom.fieldName'),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -18,18 +18,6 @@ class StoreQuestionRequest extends FormRequest
|
||||||
return auth('backend')->check();
|
return auth('backend')->check();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Prepare the data for validation.
|
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
protected function prepareForValidation(): void
|
|
||||||
{
|
|
||||||
$this->merge([
|
|
||||||
'brand_id' => collect($this->brand)->pluck('id')->first()
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the validation rules that apply to the request.
|
* Get the validation rules that apply to the request.
|
||||||
*
|
*
|
||||||
|
|
|
||||||
|
|
@ -16,18 +16,6 @@ class StoreServiceRequest extends FormRequest
|
||||||
return auth('backend')->check();
|
return auth('backend')->check();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Prepare the data for validation.
|
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
protected function prepareForValidation(): void
|
|
||||||
{
|
|
||||||
$this->merge([
|
|
||||||
'brand_id' => collect($this->brand)->pluck('id')->first()
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the validation rules that apply to the request.
|
* Get the validation rules that apply to the request.
|
||||||
*
|
*
|
||||||
|
|
|
||||||
|
|
@ -30,9 +30,9 @@ class StatsByBrandRequest extends FormRequest
|
||||||
{
|
{
|
||||||
if ($this->post()) {
|
if ($this->post()) {
|
||||||
try {
|
try {
|
||||||
if ((Carbon::parse($this->end)->diffInDays(Carbon::parse($this->start)) + 1) > 365) {
|
if ((Carbon::parse($this->end)->diffInDays(Carbon::parse($this->start)->addDay(), true)) > 365) {
|
||||||
throw ValidationException::withMessages([
|
throw ValidationException::withMessages([
|
||||||
'Vous devez sélectionner une période de maximum 1 ans'
|
'Vous devez sélectionner une période de maximum 1 an'
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
} catch (\Exception $e) {
|
} catch (\Exception $e) {
|
||||||
|
|
|
||||||
|
|
@ -30,7 +30,7 @@ class StatsByQuestionRequest extends FormRequest
|
||||||
{
|
{
|
||||||
if ($this->post()) {
|
if ($this->post()) {
|
||||||
try {
|
try {
|
||||||
if ((Carbon::parse($this->end)->diffInDays(Carbon::parse($this->start)) + 1) > 365) {
|
if ((Carbon::parse($this->end)->diffInDays(Carbon::parse($this->start)->addDay(), true)) > 365) {
|
||||||
throw ValidationException::withMessages([
|
throw ValidationException::withMessages([
|
||||||
'Vous devez sélectionner une période de maximum 1 ans'
|
'Vous devez sélectionner une période de maximum 1 ans'
|
||||||
]);
|
]);
|
||||||
|
|
|
||||||
34
app/Http/Requests/Bo/ThemeRequest.php
Normal file
34
app/Http/Requests/Bo/ThemeRequest.php
Normal file
|
|
@ -0,0 +1,34 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Requests\Bo;
|
||||||
|
|
||||||
|
use App\Enums\Theme\BootstrapThemeEnum;
|
||||||
|
use Illuminate\Foundation\Http\FormRequest;
|
||||||
|
use Illuminate\Validation\Rules\Enum;
|
||||||
|
|
||||||
|
class ThemeRequest extends FormRequest
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Get the validation rules that apply to the request.
|
||||||
|
*
|
||||||
|
* @return array<string,\Illuminate\Contracts\Validation\ValidationRule|array<mixed>|string>
|
||||||
|
*/
|
||||||
|
public function rules(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'theme' => ['required', new Enum(BootstrapThemeEnum::class)],
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get custom attributes for validator errors.
|
||||||
|
*
|
||||||
|
* @return array<string,\Illuminate\Contracts\Translation\Translator|string|array<mixed>|null>
|
||||||
|
*/
|
||||||
|
public function attributes(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'theme' => trans('validation.custom.theme'),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -100,11 +100,11 @@ abstract class UpdateMiniCrudRequest extends FormRequest
|
||||||
}) : $input['dimensions'];
|
}) : $input['dimensions'];
|
||||||
|
|
||||||
// * Adapt dimensions
|
// * Adapt dimensions
|
||||||
$sizes = (object)[
|
$sizes = (object) [
|
||||||
'minHeight' => $dim['height'],
|
'minHeight' => $dim['height'],
|
||||||
'maxHeight' => $dim['height'],
|
'maxHeight' => $dim['height'],
|
||||||
'minWith' => $dim['width'],
|
'minWith' => $dim['width'],
|
||||||
'maxWith' => $dim['width'],
|
'maxWith' => $dim['width'],
|
||||||
];
|
];
|
||||||
$rules = array_merge($rules, [
|
$rules = array_merge($rules, [
|
||||||
"data.$iptName.value" => [
|
"data.$iptName.value" => [
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,6 @@ namespace App\Http\Requests\Bo\Users;
|
||||||
use App\Enums\Users\RoleEnum;
|
use App\Enums\Users\RoleEnum;
|
||||||
use Illuminate\Foundation\Http\FormRequest;
|
use Illuminate\Foundation\Http\FormRequest;
|
||||||
use Illuminate\Validation\Rules\Enum;
|
use Illuminate\Validation\Rules\Enum;
|
||||||
use Illuminate\Validation\Rules\Password;
|
|
||||||
|
|
||||||
class StoreUserRequest extends FormRequest
|
class StoreUserRequest extends FormRequest
|
||||||
{
|
{
|
||||||
|
|
@ -24,10 +23,11 @@ class StoreUserRequest extends FormRequest
|
||||||
*
|
*
|
||||||
* @return void
|
* @return void
|
||||||
*/
|
*/
|
||||||
protected function prepareForValidation()
|
protected function prepareForValidation(): void
|
||||||
{
|
{
|
||||||
$this->merge([
|
$this->merge([
|
||||||
'published' => $this->published ? true : false
|
'published' => $this->input('published') ? true : false,
|
||||||
|
'brand_id' => $this->input('brand_id') ?: [],
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -39,19 +39,14 @@ class StoreUserRequest extends FormRequest
|
||||||
public function rules(): array
|
public function rules(): array
|
||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
'first_name' => 'required|string|min:3|max:255',
|
'first_name' => 'required|string|min:3|max:255',
|
||||||
'last_name' => 'required|string|min:3|max:255',
|
'last_name' => 'required|string|min:3|max:255',
|
||||||
'email' => 'required|email:rfc,strict,dns,spoof,filter|unique:users,email',
|
'email' => 'required|email:rfc,strict,dns,spoof,filter|unique:users,email',
|
||||||
'password' => [
|
'role' => ['required', new Enum(RoleEnum::class)],
|
||||||
'required', 'required_with:password_confirmation', 'confirmed', 'max:255', Password::min(8)
|
'published' => 'required|boolean',
|
||||||
->letters()
|
'brand_id' => 'present|array',
|
||||||
->mixedCase()
|
'brand_id.*' => 'sometimes|nullable|array',
|
||||||
->numbers()
|
'brand_id.*.id' => 'sometimes|nullable|numeric|exists:brands,id',
|
||||||
->symbols()
|
|
||||||
->uncompromised()
|
|
||||||
],
|
|
||||||
'role' => ['required', new Enum(RoleEnum::class)],
|
|
||||||
'published' => 'required|boolean',
|
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -63,12 +58,14 @@ class StoreUserRequest extends FormRequest
|
||||||
public function attributes(): array
|
public function attributes(): array
|
||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
'first_name' => trans('validation.attributes.first_name'),
|
'first_name' => trans('validation.attributes.first_name'),
|
||||||
'last_name' => trans('validation.attributes.last_name'),
|
'last_name' => trans('validation.attributes.last_name'),
|
||||||
'email' => trans('validation.attributes.email'),
|
'email' => trans('validation.attributes.email'),
|
||||||
'password' => trans('validation.attributes.password'),
|
'role' => trans('validation.attributes.role'),
|
||||||
'role' => trans('validation.attributes.role'),
|
'published' => trans('validation.custom.publication'),
|
||||||
'published' => trans('validation.custom.publication')
|
'brand_id' => trans('models.classes.brands'),
|
||||||
|
'brand_id.*' => trans('models.classes.brands'),
|
||||||
|
'brand_id.*.id' => trans('models.classes.brands'),
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,8 +2,6 @@
|
||||||
|
|
||||||
namespace App\Http\Requests\Bo\Users;
|
namespace App\Http\Requests\Bo\Users;
|
||||||
|
|
||||||
use Illuminate\Validation\Rules\Password;
|
|
||||||
|
|
||||||
class UpdateUserRequest extends StoreUserRequest
|
class UpdateUserRequest extends StoreUserRequest
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
|
|
@ -11,14 +9,11 @@ class UpdateUserRequest extends StoreUserRequest
|
||||||
*
|
*
|
||||||
* @return void
|
* @return void
|
||||||
*/
|
*/
|
||||||
protected function prepareForValidation()
|
protected function prepareForValidation(): void
|
||||||
{
|
{
|
||||||
$this->merge([
|
$this->merge([
|
||||||
'published' => $this->published ? true : false,
|
'published' => $this->input('published') ? true : false,
|
||||||
'password' => $this->password ? $this->password : $this->route('user')->password,
|
'brand_id' => $this->input('brand_id') ?: [],
|
||||||
'password_confirmation' => $this->password_confirmation ?
|
|
||||||
$this->password_confirmation :
|
|
||||||
$this->route('user')->password
|
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -29,19 +24,15 @@ class UpdateUserRequest extends StoreUserRequest
|
||||||
*/
|
*/
|
||||||
public function rules(): array
|
public function rules(): array
|
||||||
{
|
{
|
||||||
|
/** @var \App\Models\User $userModel */
|
||||||
|
$userModel = request()->route()->parameter('user');
|
||||||
|
|
||||||
return array_merge(parent::rules(), [
|
return array_merge(parent::rules(), [
|
||||||
'email' => [
|
'email' => [
|
||||||
'required',
|
'required',
|
||||||
|
'string',
|
||||||
'email:rfc,strict,dns,spoof,filter',
|
'email:rfc,strict,dns,spoof,filter',
|
||||||
'unique:users,email,' . $this->route('user')->id . ',id',
|
'unique:users,email,' . $userModel->getKey(),
|
||||||
],
|
|
||||||
'password' => [
|
|
||||||
'required', 'required_with:password_confirmation', 'confirmed', 'max:255', Password::min(8)
|
|
||||||
->letters()
|
|
||||||
->mixedCase()
|
|
||||||
->numbers()
|
|
||||||
->symbols()
|
|
||||||
->uncompromised()
|
|
||||||
],
|
],
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -16,10 +16,10 @@ class ApiResponse extends JsonResource
|
||||||
protected $status;
|
protected $status;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param \stdClass|null $data
|
|
||||||
* @param \App\Enums\ApiStatus $status
|
* @param \App\Enums\ApiStatus $status
|
||||||
|
* @param \stdClass|null $data
|
||||||
*/
|
*/
|
||||||
public function __construct(stdClass|null $data = null, ApiStatus $status)
|
public function __construct(ApiStatus $status, stdClass|null $data = null)
|
||||||
{
|
{
|
||||||
$this->status = $status;
|
$this->status = $status;
|
||||||
$this->data = $data;
|
$this->data = $data;
|
||||||
|
|
@ -36,8 +36,8 @@ class ApiResponse extends JsonResource
|
||||||
{
|
{
|
||||||
//phpcs:enable
|
//phpcs:enable
|
||||||
return [
|
return [
|
||||||
'status' => $this->status->value(),
|
'status' => $this->status->value(),
|
||||||
'data' => (array)($this->data ?? []),
|
'data' => (array) ($this->data ?? []),
|
||||||
'version' => '3.0.6'
|
'version' => '3.0.6'
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Reference in a new issue