Merge branch 'issue-61' into 'master'

feat: ✨ set winning proofs optionnal

See merge request ldc-web/projets/gen-game-web!74
This commit is contained in:
Noix 2026-09-29 13:27:02 +00:00
commit b240c614fc
9 changed files with 85 additions and 60 deletions

View file

@ -33,42 +33,50 @@ class SubmitWinningProofRequest extends CreateAccountRequest
$this->integer('country') : ($authUser ? $this->integer('country') : ($authUser ?
(new CrmRepository())->fetchCrmCustomer($authUser)->country->value : 0); (new CrmRepository())->fetchCrmCustomer($authUser)->country->value : 0);
$countryRules = match ($countryCode) { $countryRules = match ($countryCode) {
Country::belgium->value => [ Country::belgium->value => ['phone' => 'phone:BE'],
'phone' => 'phone:BE', Country::luxembourg->value => ['phone' => 'phone:LU'],
], Country::germany->value => ['phone' => 'phone:DE'],
Country::luxembourg->value => [ default => ['phone' => 'phone:FR'],
'phone' => 'phone:LU',
],
Country::germany->value => [
'phone' => 'phone:DE',
],
default => [
'phone' => 'phone:FR',
]
}; };
return \array_merge(Arr::only( return \array_merge(
parent::rules(), Arr::only(
parent::rules(),
[
'lastname',
'firstname',
'address',
'address2',
'postal_code',
'city',
'country',
]
),
[ [
'lastname', 'phone' => [
'firstname', 'required',
'address', 'max:255',
'address2', $countryRules['phone'],
'postal_code', ],
'city',
'country'
]
), [
'phone' => [
'required',
'max:255',
$countryRules['phone'],
], ],
// * Min 10 KB, Max 2MB $this->proofRules()
'sticker' => 'required|mimes:jpeg,jpg,png,pdf|min:10|max:2048', );
'ticket' => 'required|mimes:jpeg,jpg,png,pdf|min:10|max:2048', }
'barcode' => 'required|mimes:jpeg,jpg,png,pdf|min:10|max:2048',
]); /**
* Rules of winning proof.
*
* @return array<string, string>
*/
private function proofRules(): array
{
// * Min 10 KB, Max 2MB
$fileRules = 'required|mimes:jpeg,jpg,png,pdf|min:10|max:2048';
return collect(['sticker', 'ticket', 'barcode'])
->filter(fn (string $proof) => config("proofs.$proof"))
->mapWithKeys(fn (string $proof) => [$proof => $fileRules])
->all();
} }
/** /**

View file

@ -28,10 +28,10 @@ class WinningProofAdminMail extends Mailable implements ShouldQueue
* @param \LDC\LDCCRM\Models\Customer $customer The customer who won. * @param \LDC\LDCCRM\Models\Customer $customer The customer who won.
* @param string|null $unique_code The unique code used to participate if any. * @param string|null $unique_code The unique code used to participate if any.
* @param string|null $ean_code The product code used to participate if any. * @param string|null $ean_code The product code used to participate if any.
* @param string $sticker Fichier image du sticker utilisé. * @param string|null $sticker Fichier image du sticker utilisé.
* @param string $ticket Fichier image du ticket de caisse prouvant * @param string|null $ticket Fichier image du ticket de caisse prouvant
* l'achat du produit stické. * l'achat du produit stické.
* @param string $barcode Fichier image du code-barres du produit acheté. * @param string|null $barcode Fichier image du code-barres du produit acheté.
* *
* @return void * @return void
*/ */
@ -42,9 +42,9 @@ class WinningProofAdminMail extends Mailable implements ShouldQueue
protected Customer $customer, protected Customer $customer,
protected ?string $unique_code, protected ?string $unique_code,
protected ?string $ean_code, protected ?string $ean_code,
protected string $sticker, protected ?string $sticker,
protected string $ticket, protected ?string $ticket,
protected string $barcode, protected ?string $barcode,
) { ) {
} }
@ -71,7 +71,7 @@ class WinningProofAdminMail extends Mailable implements ShouldQueue
public function content(): \Illuminate\Mail\Mailables\Content public function content(): \Illuminate\Mail\Mailables\Content
{ {
$participation = []; $participation = [];
if (!is_null($this->ean_code)) { if (!is_null($this->unique_code)) {
$participation = [ $participation = [
trans('Code Unique : :code', ['code' => $this->unique_code]), trans('Code Unique : :code', ['code' => $this->unique_code]),
]; ];
@ -106,10 +106,12 @@ class WinningProofAdminMail extends Mailable implements ShouldQueue
*/ */
public function attachments(): array public function attachments(): array
{ {
return [ return collect([$this->sticker, $this->ticket, $this->barcode])
Attachment::fromPath(FileStorageHelper::getFileFullPath($this->sticker)), ->filter()
Attachment::fromPath(FileStorageHelper::getFileFullPath($this->ticket)), ->map(fn (string $file) => Attachment::fromPath(
Attachment::fromPath(FileStorageHelper::getFileFullPath($this->barcode)), FileStorageHelper::getFileFullPath($file)
]; ))
->values()
->all();
} }
} }

View file

@ -17,9 +17,9 @@ use IPLib\Address\AddressInterface;
* Participation. * Participation.
* *
* @property \IPLib\Address\AddressInterface $ip IP * @property \IPLib\Address\AddressInterface $ip IP
* @property string $sticker Path of the sticker file * @property string|null $sticker Path of the sticker file
* @property string $ticket Path of the ticket file * @property string|null $ticket Path of the ticket file
* @property string $barcode Path of the barcode file * @property string|null $barcode Path of the barcode file
* @property string|null $discount_code Treatment code of the BR * @property string|null $discount_code Treatment code of the BR
* @property string $comment Administrators comments * @property string $comment Administrators comments
* @property boolean $prize_sent Has the won prize been sent ? * @property boolean $prize_sent Has the won prize been sent ?

View file

@ -90,19 +90,26 @@ class ParticipationPolicy
{ {
/** @var \App\Models\Settings */ /** @var \App\Models\Settings */
$settings = app(Settings::class); $settings = app(Settings::class);
return $settings->winning_proof and Participation::query()
// Columns of the winning proofs enabled in the config.
$enabledProofs = array_keys(array_filter(config('proofs')));
// Winning proofs are disabled globally or no proof is enabled in the config.
if (! $settings->winning_proof || empty($enabledProofs)) {
return false;
}
return Participation::query()
->where('prize_sent', false) ->where('prize_sent', false)
->whereHas( ->whereHas(
'customer', 'customer',
fn (Builder $q) => fn (Builder $q) => $q->where('id', $authUser->id)
$q->where('id', $authUser->id) )
)->where('id', $model->id)->whereHas('instantWin') ->where('id', $model->id)
->where(function (Builder $q) { ->whereHas('instantWin')
$q->whereNull( // At least one enabled proof has not been submitted yet.
['sticker', 'ticket', 'barcode'], ->where(fn (Builder $q) => $q->whereNull($enabledProofs, 'or'))
'or' ->exists();
);
})->exists();
} }
/** /**

View file

@ -1,6 +1,6 @@
{ {
"name": "uwil/gen-game-web", "name": "uwil/gen-game-web",
"version": "4.1.2", "version": "4.2.0",
"type": "project", "type": "project",
"description": "Game generator", "description": "Game generator",
"support": { "support": {

7
config/proofs.php Normal file
View file

@ -0,0 +1,7 @@
<?php
return [
'sticker' => filter_var(env('PROOF_STICKER', true), FILTER_VALIDATE_BOOLEAN),
'ticket' => filter_var(env('PROOF_TICKET', true), FILTER_VALIDATE_BOOLEAN),
'barcode' => filter_var(env('PROOF_BARCODE', true), FILTER_VALIDATE_BOOLEAN),
];

2
package-lock.json generated
View file

@ -28,7 +28,7 @@
"@fortawesome/free-solid-svg-icons": "^7.3.1", "@fortawesome/free-solid-svg-icons": "^7.3.1",
"@fortawesome/vue-fontawesome": "^3.3.2", "@fortawesome/vue-fontawesome": "^3.3.2",
"@types/bootstrap": "^5.2.11", "@types/bootstrap": "^5.2.11",
"@types/node": "^20.8.2", "@types/node": "^20.19.43",
"@types/toastify-js": "^1.12.1", "@types/toastify-js": "^1.12.1",
"@uwil/husky-config": "^1.1.1", "@uwil/husky-config": "^1.1.1",
"@vitejs/plugin-basic-ssl": "^2.3.0", "@vitejs/plugin-basic-ssl": "^2.3.0",

View file

@ -19,7 +19,7 @@
"@fortawesome/free-solid-svg-icons": "^7.3.1", "@fortawesome/free-solid-svg-icons": "^7.3.1",
"@fortawesome/vue-fontawesome": "^3.3.2", "@fortawesome/vue-fontawesome": "^3.3.2",
"@types/bootstrap": "^5.2.11", "@types/bootstrap": "^5.2.11",
"@types/node": "^20.8.2", "@types/node": "^20.19.43",
"@types/toastify-js": "^1.12.1", "@types/toastify-js": "^1.12.1",
"@uwil/husky-config": "^1.1.1", "@uwil/husky-config": "^1.1.1",
"@vitejs/plugin-basic-ssl": "^2.3.0", "@vitejs/plugin-basic-ssl": "^2.3.0",

View file

@ -7,6 +7,7 @@
"~/*": ["./node_modules/*", "./node_modules/@types/*"], "~/*": ["./node_modules/*", "./node_modules/@types/*"],
"@/*": ["./resources/assets/*"] "@/*": ["./resources/assets/*"]
}, },
"types": ["node"],
"typeRoots": [ "typeRoots": [
"./resources/ts/@types", "./resources/ts/@types",
"resources/theme/mounted/ts/@types", "resources/theme/mounted/ts/@types",