Merge branch 'develop' into trunk

This commit is contained in:
Jérémy Munsch 2022-10-21 10:24:28 +02:00
commit df4f4d360e
No known key found for this signature in database
GPG key ID: 18361AF3BFEC0FEC
31 changed files with 434 additions and 155 deletions

View file

@ -0,0 +1,38 @@
<?php
namespace App\Console\Commands;
use App\Jobs\CafelMepPoultryJob;
use Illuminate\Console\Command;
class CafelPoultryMepCommand extends Command
{
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'cafel:mep_poultry';
/**
* The console command description.
*
* @var string
*/
protected $description = 'Syncronisation manuelle Cafel (/api/ldc/mepvolailles)';
/**
* Execute the console command.
*
* @return mixed
*/
public function handle()
{
$this->info('Running the Job, this could take some time.');
$job = new CafelMepPoultryJob();
$job->handle();
$this->info('Fin du traitement');
}
}

View file

@ -1,79 +0,0 @@
<?php
namespace App\Console\Commands;
/*
* Command Name: LDC Web Status Checker
* Description: Envoi des infos Serveur/Laravel vers LDC Web
* Version: 1.0
* Author: Vincent BRIDIER
* Author URI: vincent.bridier@ldc.fr
*/
use Illuminate\Console\Command;
use Illuminate\Support\Facades\Http;
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()
{
$data = [];
$data['uuid'] = config('app.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 . '/laravel-*.log');
if (count($files) > 0) {
foreach ($files as $file) {
$data['logs'] = $data['logs'] + filesize($file);
}
}
$data['code']['version'] = app()->version();
try {
Http::post(
'https://ldc-web.s-web.test/api/status-checker',
['token' => 'CE8S52Qq7stf5k8frF4T', 'datas' => json_encode($data)]
);
} catch (\Exception $e) {
report($e);
}
return 0;
}
}

View file

@ -38,6 +38,7 @@ class Kernel extends ConsoleKernel
$schedule->job(XmlFluxEggJob::class, 'tracea')->onOneServer()->dailyAt('02:00');
$schedule->job(XmlFluxPoultryJob::class, 'tracea')->onOneServer()->dailyAt('22:00');
$schedule->command('xml:clean_olds')->onOneServer()->dailyAt('06:00');
}
/**

View file

@ -3,8 +3,10 @@
namespace App\Http\Controllers\Fo;
use App\Http\Controllers\Controller;
use App\Http\Requests\Fo\Ajax\GetDistributionRequest;
use App\Http\Requests\Fo\SearchPoultryTraceaRequest;
use App\Models\TraceaPoultry;
use Illuminate\Http\JsonResponse;
use Illuminate\Support\Carbon;
use Illuminate\Support\Facades\File;
use Illuminate\Support\Facades\Session;
@ -68,14 +70,34 @@ class TraceaPoultryController extends Controller
\redirect()->route('poultry.search')->throwResponse();
}
$distributionPicture = $this->getDistributionPicture($traceaPoultry->sign);
// ! Test that food and mep are available
if (!$traceaPoultry->mep or !$traceaPoultry->food) {
return \view('front.poultry.unavailable');
}
return view('front.poultry.show', compact(
'traceaPoultry',
'distributionPicture'
'traceaPoultry'
));
}
/**
* Get Distribution Info
*
* @param \App\Http\Requests\Fo\Ajax\GetDistributionRequest $request
* @return \Illuminate\Http\JsonResponse
*/
public function getDistribution(GetDistributionRequest $request): JsonResponse
{
/** @var \App\Models\TraceaPoultry */
$traceaPoultry = TraceaPoultry::where('order_num', $request->ordernum)
->where('external_code_lot', $request->codelot)->firstOrFail();
return \response()->json([
'exp_date' => $traceaPoultry->exp_date,
'sign' => $traceaPoultry->sign,
'picture' => $this->getDistributionPicture($traceaPoultry->sign)
]);
}
/**
* Get distribution sign picture name if exists.
*

View file

@ -44,7 +44,7 @@ class SecureHeaders
// phpcs:ignore Generic.Files.LineLength.TooLong
"style-src 'self' $cssDev https://fonts.googleapis.com;",
// phpcs:ignore Generic.Files.LineLength.TooLong
"script-src 'self' $jsDev https://fonts.googleapis.com;"
"script-src 'self' $jsDev https://fonts.googleapis.com https://www.googletagmanager.com;"
];
$response->headers->set(
'Content-Security-Policy',

View file

@ -0,0 +1,31 @@
<?php
namespace App\Http\Requests\Fo\Ajax;
use Illuminate\Foundation\Http\FormRequest;
class GetDistributionRequest extends FormRequest
{
/**
* Determine if the user is authorized to make this request.
*
* @return boolean
*/
public function authorize()
{
return true;
}
/**
* Get the validation rules that apply to the request.
*
* @return array
*/
public function rules()
{
return [
'codelot' => 'required|numeric|digits:10',
'ordernum' => 'required|numeric|digits:6',
];
}
}

View file

@ -0,0 +1,49 @@
<?php
namespace App\Jobs;
use App\Lib\CafelApi\Models\CafelMepPoultry;
use App\Models\CafelPoultryMiseEnPlace;
class CafelMepPoultryJob extends CafelJobs
{
/**
* Execute the job.
*
* @return void
*/
public function handle()
{
$dateDebut = now()->subDays(config('cafel.mises_en_places_retain', 370));
$this->syncWithCafelApi(
CafelMepPoultry::class,
'cafel.ldc.mepvolailles',
[
'dateDebut' => $dateDebut->format('Y-m-d'),
'dateFin' => now()->format('Y-m-d')
],
function (array $row) {
// * Validate row data
CafelMepPoultry::validateDataRow($row);
/** @var array Unique Key columns */
$uniqueColumnsKey = [];
foreach (CafelMepPoultry::UNIQUE_COLUMN_KEYS as $uField) {
$uniqueColumnsKey[$uField] = $row[$uField];
}
forward_static_call_array(
[CafelPoultryMiseEnPlace::class, 'updateOrCreate'],
[$uniqueColumnsKey, $row]
);
}
);
$this->mailInvalidRows(CafelMepPoultry::UNIQUE_COLUMN_KEYS, CafelMepPoultry::class);
// * DeleteOld MEPs
// * Garder une interstice de X jours entre la suppression et ce qu'on récupère de CAFEL
CafelPoultryMiseEnPlace::whereDate('transfert_date', '<', $dateDebut->subDays(
config('cafel.mises_en_places_retain', 370)
))->delete();
}
}

View file

@ -0,0 +1,42 @@
<?php
namespace App\Lib\CafelApi\Models;
/**
* @author Jérémy Munsch <jeremy.munsch@ldc.fr>
*/
abstract class CafelMepPoultry extends CafelClientModel
{
/**
* Unique columns key
*
* @var array
*/
public const UNIQUE_COLUMN_KEYS = [
'batch_code'
];
/**
* Validation rules from cafel Api
*
* @var array
*/
protected static $validationRules = [
// Eg V072FXT (un seul par ligne).
'inuav_code' => 'required|string|regex:/^[A-Z]\d{3}[A-Z]{3}$/',
// Eg 19377/0 .
'batch_code' => 'required|max:10|regex:/^[0-9A-Z]*\/\d$/',
'transfert_date' => 'required|date_format:Y-m-d'
];
/**
* Column translations
*
* @var array
*/
protected static $columnsTranslations = [
'Inuav_code' => 'inuav_code',
'Batch_code' => 'batch_code',
'Transfert_date' => 'transfert_date'
];
}

View file

@ -0,0 +1,69 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Facades\Cache;
class CafelPoultryMiseEnPlace extends Model
{
/**
* The primary key for the model.
*
* @var string
*/
protected $primaryKey = 'batch_code';
/**
* Indicates if the IDs are auto-incrementing.
*
* @var boolean
*/
public $incrementing = false;
/**
* Indicates if the model should be timestamped.
*
* @var boolean
*/
public $timestamps = false;
/**
* The attributes that should be cast.
*
* @var array
*/
protected $casts = [
'transfert_date' => 'date'
];
/**
* The attributes that are mass assignable.
*
* @var array
*/
protected $fillable = [
'batch_code',
'inuav_code',
'transfert_date'
];
// * METHODS
/**
* Get Mep using cafel lot code
*
* @param integer $codeLotCafel
* @return self|null
*/
public static function whereCodeLotCafel(int $codeLotCafel): ?self
{
return Cache::remember("poultryMep$codeLotCafel", 5, function () use ($codeLotCafel) {
return self::where(
'batch_code',
'LIKE',
'%' . \filter_var($codeLotCafel, \FILTER_SANITIZE_STRING) . '/%'
)->first();
});
}
}

View file

@ -98,6 +98,7 @@ class TraceaPoultry extends Model
public function getBreederAttribute(): ?CafelPoultryBreeder
{
$matches = [];
preg_match('/(?P<inuav>V\d{3}[A-Z]{3})/', \strval($this->breeder_code), $matches);
if (!\array_key_exists('inuav', $matches)) {
return collect();
@ -153,4 +154,25 @@ class TraceaPoultry extends Model
// * On utilise code lot_opa vue que son explication de merde est inversée ... Uu
return CafelFood::whereCodeLotCafel(FoodType::chicken(), \intval($this->opa_lot));
}
/**
* * Get Bea
*
* L'explication du batch code est un non sens.... putin de merde
*
* Comment faisons-nous pour lier notre lot à une note BEA ?
* (code lot sous ce format : XXXXX/0 pour les données BEA) -> Code lot CAFEL / Code OPA
* Comment faisons-nous pour lier notre lot à son alimentation ?
* (code lot sous ce format : XXXXX/0 pour les données alimentation) -> Code lot CAFEL / Code OPA
* Pour ces questions, peux-tu nous dire avec les informations que nous recevons du flux Sablé
* les règles que nous devons utiliser stp ? * -> @Mathilde Hervier peux-tu répondre à cette question ?
* Le 6e champ reçu dans le fichier xml est le code lot OPA qui sert donc à faire le lien avec la CAFEL
*
* @return \App\Models\CafelPoultryMiseEnPlace|null
*/
public function getMepAttribute(): ?CafelPoultryMiseEnPlace
{
// * On utilise code lot_opa vue que son explication de merde est inversée ... Uu
return CafelPoultryMiseEnPlace::whereCodeLotCafel(\intval($this->opa_lot));
}
}

View file

@ -19,12 +19,12 @@
"kwaadpepper/enum": "^2.1",
"kwaadpepper/exception-handler": "^0.0.6",
"kwaadpepper/refresh-sitemap": "^1.0",
"laravel/ui": "^3.0",
"laravel/framework": "^8.0",
"laravel/tinker": "^2.0",
"laravel/ui": "^3.0",
"laravelcollective/html": "^6.0",
"ldc/web-admin-secure-laravel": "1.0.1",
"ldc/web-status-checker-laravel": "1.0.3",
"ldc/web-status-checker-laravel": "^1.0",
"mews/purifier": "^3.3",
"nesbot/carbon": "^2.29",
"spatie/laravel-mix-preload": "^1.3"

4
composer.lock generated
View file

@ -4,7 +4,7 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically"
],
"content-hash": "040c7f9d55df10bfbad67ab4fc1eec41",
"content-hash": "3b8a85ff97e17a3645c1bb8dcb6a15bf",
"packages": [
{
"name": "arondeparon/laravel-request-sanitizer",
@ -9303,5 +9303,5 @@
"ext-xml": "*"
},
"platform-dev": [],
"plugin-api-version": "2.2.0"
"plugin-api-version": "2.3.0"
}

View file

@ -51,6 +51,12 @@ return [
'methods' => [
'GET'
]
],
'cafel.ldc.mepvolailles' => [
'uri' => 'api/ldc/mepvolailles',
'methods' => [
'GET'
]
]
]
];

View file

@ -0,0 +1,32 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class CreateCafelPoultryMiseEnPlacesTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('cafel_poultry_mise_en_places', function (Blueprint $table) {
$table->string('batch_code', 10)->unique();
$table->string('inuav_code', 100);
$table->date('transfert_date');
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('cafel_poultry_mise_en_places');
}
}

19
package-lock.json generated
View file

@ -4,10 +4,6 @@
"requires": true,
"packages": {
"": {
"name": "bogt",
"dependencies": {
"sweetalert2": "^11.4.20"
},
"devDependencies": {
"@lighting-beetle/glider-js": "^1.8.2",
"@popperjs/core": "^2.11.5",
@ -24,6 +20,7 @@
"resolve-url-loader": "^5.0.0",
"sass": "1.32.13",
"sass-loader": "^8.0.2",
"sweetalert2": "^11.4.35",
"vue": "^2.6.14",
"vue-template-compiler": "^2.6.14"
}
@ -8454,9 +8451,10 @@
}
},
"node_modules/sweetalert2": {
"version": "11.4.20",
"resolved": "https://registry.npmjs.org/sweetalert2/-/sweetalert2-11.4.20.tgz",
"integrity": "sha512-3LiBFa5yRmTcqM0vGcFmo0EnhmaMSJfzhFpvZoXK6BOY94HIcIUbwhhW+NY5oXOpz5CT21qFAu0fKCUkOc/Pew==",
"version": "11.4.35",
"resolved": "https://registry.npmjs.org/sweetalert2/-/sweetalert2-11.4.35.tgz",
"integrity": "sha512-nifH7Hd8oSIO8qf6GHhob6xZK2KoX7+EalTFm3nHshdQ38TY/r0m/QiuJCDL0cTGbRhzMWL7WYBSA3fjnh+F1g==",
"dev": true,
"funding": {
"type": "individual",
"url": "https://sweetalert2.github.io/#donations"
@ -15709,9 +15707,10 @@
}
},
"sweetalert2": {
"version": "11.4.20",
"resolved": "https://registry.npmjs.org/sweetalert2/-/sweetalert2-11.4.20.tgz",
"integrity": "sha512-3LiBFa5yRmTcqM0vGcFmo0EnhmaMSJfzhFpvZoXK6BOY94HIcIUbwhhW+NY5oXOpz5CT21qFAu0fKCUkOc/Pew=="
"version": "11.4.35",
"resolved": "https://registry.npmjs.org/sweetalert2/-/sweetalert2-11.4.35.tgz",
"integrity": "sha512-nifH7Hd8oSIO8qf6GHhob6xZK2KoX7+EalTFm3nHshdQ38TY/r0m/QiuJCDL0cTGbRhzMWL7WYBSA3fjnh+F1g==",
"dev": true
},
"tapable": {
"version": "2.2.1",

View file

@ -25,10 +25,8 @@
"resolve-url-loader": "^5.0.0",
"sass": "1.32.13",
"sass-loader": "^8.0.2",
"sweetalert2": "^11.4.35",
"vue": "^2.6.14",
"vue-template-compiler": "^2.6.14"
},
"dependencies": {
"sweetalert2": "^11.4.20"
}
}

View file

@ -1,5 +1,5 @@
// ES6 Modules or TypeScript
import Swal from 'sweetalert2'
import Swal from 'sweetalert2/dist/sweetalert2.js'
document.addEventListener('DOMContentLoaded', () => {
if (document.getElementsByClassName('oldEgg').length) {

View file

@ -7,8 +7,8 @@ require('./alert');
import IMask from 'imask'
document.addEventListener('DOMContentLoaded', () => {
let maskInputs = document.getElementsByClassName('inputMask')
for (let maskInput of maskInputs) {
const maskInputs = document.getElementsByClassName('inputMask')
for (const maskInput of maskInputs) {
if (maskInput.dataset.mask) {
maskInput.imask = IMask(maskInput, {
mask: maskInput.dataset.mask.indexOf('|') !== -1 ?

View file

@ -1,12 +1,16 @@
import Glider from '@lighting-beetle/glider-js'
import axios from 'axios'
document.addEventListener('DOMContentLoaded', () => {
let labelSlider = document.querySelector('.container.poultryShow .glider-container.labels > .glider'),
const labelSlider = document.querySelector('.container.poultryShow .glider-container.labels > .glider'),
linksSlider = document.querySelector('.container.poultryShow .glider-container.links > .glider'),
orderNum = document.getElementById('order_num'),
orderVal = document.getElementById('order_val'),
orderInvalid = document.getElementById('order_num_invalid'),
orderExp = document.getElementById('order_exp')
orderExp = document.getElementById('order_exp'),
distriSign = document.getElementById('distriSign'),
distriPicture = document.getElementById('distriPicture'),
distriDate = document.getElementById('distriDate');
if (labelSlider) {
new Glider(labelSlider, {
slidesToShow: 1,
@ -43,7 +47,8 @@ document.addEventListener('DOMContentLoaded', () => {
]
})
}
if (orderNum && orderVal && orderExp && orderInvalid) {
// * Distribution
if (orderNum && orderVal && orderExp && orderInvalid && distriPicture && distriDate) {
orderVal.addEventListener('click', (e) => {
e.preventDefault()
@ -57,17 +62,32 @@ document.addEventListener('DOMContentLoaded', () => {
behavior: "smooth"
})
}
if (orderNum.imask.value.slice(0, -5) !== orderNum.dataset.orderNumber) {
orderInvalid.classList.add('d-block')
orderExp.classList.add('d-none')
orderNum.imask.masked.reset()
scrollToIdWithOffset('order_num_invalid', 50)
return;
}
orderInvalid.classList.remove('d-block')
orderExp.classList.remove('d-none')
orderNum.imask.masked.reset()
scrollToIdWithOffset(orderExp.id, 50)
axios.get(
`/tracabilite/volaille/distribution?codelot=${orderNum.dataset.codeLot}&ordernum=${orderNum.imask.value.slice(0, -5)}`
).then((response) => {
const date = new Date(response.data.exp_date);
distriDate.textContent = new Intl.DateTimeFormat('fr-FR', { dateStyle: 'full'}).format(date);
distriSign.querySelector('span').textContent = response.data.sign;
if (response.data.picture) {
distriPicture.querySelector('img').classList.remove('d-none');
distriPicture.querySelector('img').src = `/assets/images/signs/${response.data.picture}`;
} else {
distriPicture.querySelector('img').classList.add('d-none');
}
orderInvalid.classList.remove('d-block');
orderExp.classList.remove('d-none');
orderNum.imask.masked.reset();
scrollToIdWithOffset(orderExp.id, 50);
}).catch((e) => {
orderInvalid.classList.add('d-block');
orderExp.classList.add('d-none');
orderNum.imask.masked.reset();
scrollToIdWithOffset('order_num_invalid', 50);
});
})
} else {
throw new Error('Missing Dom elements');
}
})

View file

@ -45,3 +45,8 @@ body {
}
}
.egg-alert {
margin-top:10px;
margin-bottom:10px;
}

View file

@ -1,3 +1,5 @@
@import 'sweetalert2/dist/sweetalert2.css';
.swal2-confirm {
border-radius: 0 !important;
box-shadow: 0px 5px 5px #00000069 !important;
@ -8,4 +10,4 @@
text-decoration: none;
font-family: MyriadProBold;
}
}
}

View file

@ -1,15 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" style="display: none;">
<symbol id="check-circle-fill" fill="currentColor" viewBox="0 0 16 16">
<path d="M16 8A8 8 0 1 1 0 8a8 8 0 0 1 16 0zm-3.97-3.03a.75.75 0 0 0-1.08.022L7.477 9.417 5.384 7.323a.75.75 0 0 0-1.06 1.06L6.97 11.03a.75.75 0 0 0 1.079-.02l3.992-4.99a.75.75 0 0 0-.01-1.05z"/>
</symbol>
<symbol id="info-fill" fill="currentColor" viewBox="0 0 16 16">
<path d="M8 16A8 8 0 1 0 8 0a8 8 0 0 0 0 16zm.93-9.412-1 4.705c-.07.34.029.533.304.533.194 0 .487-.07.686-.246l-.088.416c-.287.346-.92.598-1.465.598-.703 0-1.002-.422-.808-1.319l.738-3.468c.064-.293.006-.399-.287-.47l-.451-.081.082-.381 2.29-.287zM8 5.5a1 1 0 1 1 0-2 1 1 0 0 1 0 2z"/>
</symbol>
<symbol id="exclamation-triangle-fill" fill="currentColor" viewBox="0 0 16 16">
<path d="M8.982 1.566a1.13 1.13 0 0 0-1.96 0L.165 13.233c-.457.778.091 1.767.98 1.767h13.713c.889 0 1.438-.99.98-1.767L8.982 1.566zM8 5c.535 0 .954.462.9.995l-.35 3.507a.552.552 0 0 1-1.1 0L7.1 5.995A.905.905 0 0 1 8 5zm.002 6a1 1 0 1 1 0 2 1 1 0 0 1 0-2z"/>
</symbol>
</svg>
@if ($message = Session::get('success'))
<div class="alert alert-success d-flex align-items-center alert-dismissible fade show" role="alert">
<svg class="bi flex-shrink-0 me-2" width="24" height="24" role="img" aria-label="Success:"><use xlink:href="#check-circle-fill"/></svg>

Before

Width:  |  Height:  |  Size: 3.7 KiB

After

Width:  |  Height:  |  Size: 2.7 KiB

View file

@ -12,7 +12,7 @@
<p>Erreur</p>
<p>Ne mettez pas tous vos oeufs dans le même panier ! :)</p>
</div>
<div class="body" style="margin-top:10px; margin-bottom:10px;">
<div class="body egg-alert">
<img class="img-fluid" src="{{ asset('assets/images/egg/generique.jpg') }}" alt="Élevage">
<p class="message blue">Nous n'avons pu retrouver l'éleveur concerné par votre boite.</p>
<p></p>

View file

@ -5,9 +5,21 @@
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>{{ __('Autorisation nécessaire') }}</title>
<style @if(isset($nonce)) nonce="{{ $nonce }}" @endif>
.h-title {
padding: 1rem;
background-color: rgb(153, 153, 153);
color: #FFF;
position: absolute;
top:50%;
left: 50%;
transform:translateX(-50%)
translateY(-50%);
}
</style>
</head>
<body>
<h2 style="padding: 1rem; background-color: rgb(153, 153, 153); color: #FFF; position: absolute; top:50%; left: 50%; transform:translateX(-50%) translateY(-50%);">
<h2 class="h-title ">
{{__("Vous devez autoriser les cookies '".request()->type."' pour visualiser cet élément") }}
</h2>
</body>

View file

@ -1,15 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" style="display: none;">
<symbol id="check-circle-fill" fill="currentColor" viewBox="0 0 16 16">
<path d="M16 8A8 8 0 1 1 0 8a8 8 0 0 1 16 0zm-3.97-3.03a.75.75 0 0 0-1.08.022L7.477 9.417 5.384 7.323a.75.75 0 0 0-1.06 1.06L6.97 11.03a.75.75 0 0 0 1.079-.02l3.992-4.99a.75.75 0 0 0-.01-1.05z"/>
</symbol>
<symbol id="info-fill" fill="currentColor" viewBox="0 0 16 16">
<path d="M8 16A8 8 0 1 0 8 0a8 8 0 0 0 0 16zm.93-9.412-1 4.705c-.07.34.029.533.304.533.194 0 .487-.07.686-.246l-.088.416c-.287.346-.92.598-1.465.598-.703 0-1.002-.422-.808-1.319l.738-3.468c.064-.293.006-.399-.287-.47l-.451-.081.082-.381 2.29-.287zM8 5.5a1 1 0 1 1 0-2 1 1 0 0 1 0 2z"/>
</symbol>
<symbol id="exclamation-triangle-fill" fill="currentColor" viewBox="0 0 16 16">
<path d="M8.982 1.566a1.13 1.13 0 0 0-1.96 0L.165 13.233c-.457.778.091 1.767.98 1.767h13.713c.889 0 1.438-.99.98-1.767L8.982 1.566zM8 5c.535 0 .954.462.9.995l-.35 3.507a.552.552 0 0 1-1.1 0L7.1 5.995A.905.905 0 0 1 8 5zm.002 6a1 1 0 1 1 0 2 1 1 0 0 1 0-2z"/>
</symbol>
</svg>
@if ($message = Session::get('success'))
<div class="row justify-content-center">
<div class="col col-md-10 mt-3">

Before

Width:  |  Height:  |  Size: 4.6 KiB

After

Width:  |  Height:  |  Size: 3.5 KiB

View file

@ -15,7 +15,7 @@
<div class="row">
<div class="col text-center">
<span class="d-block h5 fw-bold text-loue-blue mb-3">{{ __('Les poussins sont arrivés dans le poulailler le') }}&nbsp;:</span>
<span class="d-inline-block badge-loue-green">{{ now()->formatLocalized('%A') }} {{ now()->format('d/m/Y') }}</span>
<span class="d-inline-block badge-loue-green">{{ $mep->transfert_date->formatLocalized('%A') }} {{ $mep->transfert_date->format('d/m/Y') }}</span>
</div>
</div>
<div class="row mt-5">

View file

@ -21,7 +21,12 @@
<div class="col text-center">
<div class="d-flex flex-column">
<div class="text-center">
<input id="order_num" name="order_num" type="text" class="commandInput inputMask" pattern="^[0-9]{6}\/[0-9]{3}[A-Z]$" data-mask="000000/000a" length="10" placeholder="{{ __('123456/123A') }}" title="{{ __('Saisissez le numéro de commande tel qu\'indiqué sur l\'image ci-dessous') }}" data-order-number="{{ str_pad($traceaPoultry->order_num, 6, '0', STR_PAD_LEFT) }}">
<input
id="order_num" name="order_num" type="text"
class="commandInput inputMask" pattern="^[0-9]{6}\/[0-9]{3}[A-Z]$"
data-mask="000000/000a" length="10" placeholder="{{ __('123456/123A') }}"
title="{{ __('Saisissez le numéro de commande tel qu\'indiqué sur l\'image ci-dessous') }}"
data-code-lot="{{ $traceaPoultry->external_code_lot }}">
@include('back.modules.input-error', ['inputName' => 'order_num'])
<div id="order_num_invalid" class="invalid-feedback">{{ __('Numéro de commande invalide') }}</div>
</div>
@ -51,16 +56,14 @@
<span class="h5 fw-bold text-light">{{ __('Date') }}</span>
</div>
<div class="text-center mt-1">
<span class="fw-bold textDistriResult text-uppercase">{{ $date }}</span>
<span id="distriDate" class="fw-bold textDistriResult text-uppercase">{{ $date }}</span>
</div>
@if($distributionPicture)
<div class="text-center mt-3">
<span class="h5 fw-bold text-light">{{ $sign }}</span>
<div id="distriSign" class="text-center mt-3">
<span class="h5 fw-bold text-light"></span>
</div>
<div class="text-center mt-1">
<img class="img-fluid signPicture" src="{{ asset("assets/images/signs/$distributionPicture") }}" alt="{{ $sign }}">
<div id="distriPicture" class="text-center mt-1">
<img class="img-fluid signPicture" src="">
</div>
@endif
</div>
</div>
</div>

View file

@ -117,7 +117,8 @@
@if($traceaPoultry->breeder)
<div class="container-fluid g-2 poultryShow subpart">
@include('front.poultry.parts.breeding', [
'breeder' => $traceaPoultry->breeder
'breeder' => $traceaPoultry->breeder,
'mep' => $traceaPoultry->mep
])
</div>
@endif
@ -152,7 +153,6 @@ nous avions dit que nous fonctionnions comme cela lors d'une réunion en décemb
</div>
<div class="container-fluid g-2 poultryShow subpart">
@include('front.poultry.parts.distribution', [
'distributionPicture' => $distributionPicture,
'sign' => $traceaPoultry->sign,
'date' => sprintf('%s %s', $traceaPoultry->exp_date->formatLocalized('%A'), $traceaPoultry->exp_date->format('d/m/Y'))
])

View file

@ -0,0 +1,29 @@
@extends('layouts.front')
@section('title', __('Traceabilité des Volailles de Loué'))
@section('description', __('Recherchez la treaceabilité de votre produit Loué ainsi que sa provenance.'))
@section('breadcrumb', request()->route()->getName())
@section('content')
<div class="container poultryShow">
<div class="row header g-5 bg-loue-blue text-light">
<div class="col-12 m-2 h1 fw-bold text-center">
{{ __('Erreur') }}
</div>
<div class="col m-2 h3 fw-bold text-center fst-italic">
{{ __('Une erreur est survenue') }}
</div>
</div>
@include('front.modules.flashMessage')
<div class="row justify-content-center">
<div class="col mt-5 px-5 py-3 text-center">
<img class="img-fluid" src="{{ asset('assets/images/egg/generique.jpg') }}" alt="Élevage">
</div>
</div>
<div class="row justify-content-center pb-5">
<div class="col mt-5 px-5 py-3 text-center">
<span class="d-block h5 fw-bold text-loue-blue">{{ __('Nous sommes dans l’incapacité de vous afficher la traçabilité de votre poulet. Nous nous excusons pour ce désagrément.') }}</span>
</div>
</div>
</div>
@endsection

View file

@ -22,6 +22,8 @@ Route::name('poultry.')->group(function () {
Route::view('/', 'front.poultry.search')->name('search');
Route::post('/', [TraceaPoultryController::class, 'searchSubmit'])->name('searchSubmit');
Route::get('tracabilite/volaille', [TraceaPoultryController::class, 'show'])->name('show');
Route::get('tracabilite/volaille/distribution', [TraceaPoultryController::class, 'getDistribution'])
->name('distribution');
Route::get('tracabilite/volaille/info', [InfoController::class, 'poultry'])->name('infos');
Route::get(
'tracabilite/volaille/info/des-poulets-libres-par-nature',