Refactor and fixes

Fixes #33
Fixes #34
This commit is contained in:
Jérémy Munsch 2023-09-08 16:02:21 +02:00
parent 16f4af41fd
commit 615263f233
No known key found for this signature in database
GPG key ID: 18361AF3BFEC0FEC
13 changed files with 195 additions and 169 deletions

View file

@ -4,7 +4,7 @@ namespace App\Enums\Products;
use App\Traits\Enums\BaseEnum;
enum CertificationEnum : int
enum CertificationEnum: int
{
use BaseEnum;

View file

@ -4,7 +4,7 @@ namespace App\Enums\Products;
use App\Traits\Enums\BaseEnum;
enum ClaimEnum : int
enum ClaimEnum: int
{
use BaseEnum;

View file

@ -4,7 +4,7 @@ namespace App\Enums\Products;
use App\Traits\Enums\BaseEnum;
enum DistributionNetworkEnum : int
enum DistributionNetworkEnum: int
{
use BaseEnum;

View file

@ -4,7 +4,7 @@ namespace App\Enums\Products;
use App\Traits\Enums\BaseEnum;
enum GeoAreaEnum : int
enum GeoAreaEnum: int
{
use BaseEnum;

View file

@ -4,7 +4,7 @@ namespace App\Enums\Products;
use App\Traits\Enums\BaseEnum;
enum OriginEnum : int
enum OriginEnum: int
{
use BaseEnum;

View file

@ -4,7 +4,7 @@ namespace App\Enums\Products;
use App\Traits\Enums\BaseEnum;
enum RangeEnum : int
enum RangeEnum: int
{
use BaseEnum;

View file

@ -4,7 +4,7 @@ namespace App\Enums\Products;
use App\Traits\Enums\BaseEnum;
enum RayEnum : int
enum RayEnum: int
{
use BaseEnum;

View file

@ -4,7 +4,7 @@ namespace App\Enums\Products;
use App\Traits\Enums\BaseEnum;
enum SourceEnum : int
enum SourceEnum: int
{
use BaseEnum;

View file

@ -2,13 +2,10 @@
namespace App\Http\Resources;
use App\Enums\Products\CertificationEnum;
use App\Enums\Products\ClaimEnum;
use App\Enums\Products\OriginEnum;
use App\Models\Brand;
use App\Models\Keyword;
use App\Models\Product;
use App\Models\User;
use Carbon\Carbon;
use Illuminate\Http\Resources\Json\JsonResource;
class ProductResource extends JsonResource
@ -19,8 +16,8 @@ class ProductResource extends JsonResource
/** @var array */
private static $skeleton = [
'id' => null,
'user_id' => null,
'brand_id' => null,
'user' => null,
'brand' => null,
'name' => null,
'seen_at' => null,
'source' => null,
@ -65,56 +62,13 @@ class ProductResource extends JsonResource
*/
public function toArray($request = null)
{
foreach (CertificationEnum::toArray() as $enumValue) {
if ($this->product->certification->value === $enumValue->value) {
$certification = $enumValue->label;
}
}
if (count($this->product->origins)) {
$origins = "";
foreach ($this->product->origins as $originValue) {
/** @var \App\Enums\Products\OriginEnum $enumValue */
foreach (OriginEnum::toArray() as $enumValue) {
if ($originValue === $enumValue->value) {
$origins = $origins . $enumValue->label . ", ";
}
}
}
}
if (count($this->product->claims)) {
$claims = "";
foreach ($this->product->claims as $originValue) {
/** @var \App\Enums\Products\ClaimEnum $enumValue */
foreach (ClaimEnum::toArray() as $enumValue) {
if ($originValue === $enumValue->value) {
if ($enumValue->value === ClaimEnum::others->value) {
$claims = $claims . $enumValue->label . ": " . $this->product->specified_claim . ", ";
} else {
$claims = $claims . $enumValue->label . ", ";
}
}
}
}
}
foreach ($this->product->productComments as $productComment) {
$productComment->date = Carbon::createFromFormat(
'Y-m-d H:i:s',
$productComment->created_at
)->format('d/m/Y');
}
if (count($this->product->productKeywords)) {
$productKeywords = "";
foreach ($this->product->productKeywords as $productKeyword) {
$productKeywords = $productKeywords . $productKeyword->label . ", ";
}
}
return array_intersect_key(
[
'id' => $this->product->id,
'user_id' => User::where('id', $this->product->user_id)->firstOrFail(),
'brand_id' => Brand::where('id', $this->product->brand_id)->firstOrFail(),
'user' => (object)$this->product->user->toArray(),
'brand' => (object)$this->product->brand->toArray(),
'name' => $this->product->name,
'seen_at' => Carbon::createFromFormat('Y-m-d H:i:s', $this->product->seen_at)->format('d/m/Y'),
'seen_at' => $this->product->seen_at->isoFormat('DD\/MM\/YYYY \à HH\hmm'),
'source' => $this->product->source->label(),
'fair' => $this->product->fair,
'shop' => $this->product->shop,
@ -125,16 +79,18 @@ class ProductResource extends JsonResource
'picture' => $this->product->picture,
'picture_alt' => $this->product->picture_alt,
'picture_title' => $this->product->picture_title,
'certification' => $certification,
'origins' => $origins ?? null,
'claims' => $claims ?? null,
'certification' => \optional($this->product->certification)->label,
'origins' => $this->product->origins_enum->map(fn (OriginEnum $enum) => $enum->label())->implode(', '),
'claims' => $this->product->claims_enum->map(fn (ClaimEnum $enum) => $enum->label())->implode(', '),
'distribution_network' => $this->product->distribution_network->label(),
'ray' => $this->product->ray->label(),
'product_range' => $this->product->product_range->label(),
'geo_area' => $this->product->geo_area->label(),
'freeComment' => $this->product->comment,
'productComments' => $this->product->productComments,
'productKeywords' => $productKeywords ?? null,
'productKeywords' => $this->product->productKeywords
->map(fn (Keyword $keyword) => $keyword->label)
->implode(', '),
],
$this->getSkeleton()
);

View file

@ -11,7 +11,10 @@ use Illuminate\Database\Eloquent\Model;
* @property \App\Enums\KeywordCategoryEnum $keyword_cat
* @property \Carbon\Carbon $created_at
* @property \Carbon\Carbon $updated_at
* @property Keywordable[] $keywordables
*
* * RELATIONSHIPS
* @property-read \Illuminate\Database\Eloquent\Collection<\App\Models\Product> $products
* @property-read \Illuminate\Database\Eloquent\Collection<\App\Models\Keyword> $keywordables
*/
class Keyword extends Model
{
@ -34,6 +37,8 @@ class Keyword extends Model
'keyword_cat' => KeywordCategoryEnum::class
];
// * RELATIONSHIPS
/**
* @return \Illuminate\Database\Eloquent\Relations\HasMany
*/

View file

@ -3,8 +3,10 @@
namespace App\Models;
use App\Enums\Products\CertificationEnum;
use App\Enums\Products\ClaimEnum;
use App\Enums\Products\DistributionNetworkEnum;
use App\Enums\Products\GeoAreaEnum;
use App\Enums\Products\OriginEnum;
use App\Enums\Products\RangeEnum;
use App\Enums\Products\RayEnum;
use App\Enums\Products\SourceEnum;
@ -13,43 +15,53 @@ use App\Lib\Helpers\FileStorageHelper;
use App\Lib\Helpers\ToolboxHelper;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\Storage;
use Mccarlosen\LaravelMpdf\LaravelMpdf;
use Symfony\Component\HttpFoundation\StreamedResponse;
/**
* @property integer $id
* @property integer $user_id
* @property integer $brand_id
* @property string $name
* @property string $brand
* @property string $seen_at
* @property enum $source
* @property string $fair
* @property string $shop
* @property string $catalogue
* @property string $gencod
* @property string $picture
* @property array $docs
* @property string $url
* @property enum $certification
* @property array<integer> $origins
* @property array<integer> $claims
* @property string $specified_claim
* @property enum $distribution_network
* @property enum $ray
* @property enum $product_range
* @property enum $geo area
* @property integer $weight
* @property integer $pvc
* @property string $comment
* @property boolean $is_tasted
* @property integer $tasters_number
* @property string $created_at
* @property string $updated_at
* @property string $deleted_at
* @property ProductComment[] $productComments
* @property User $user
* FIXME: using migration, do not set nullable props without a real need.
*
* @property integer $id
* @property integer $user_id
* @property integer $brand_id
* @property string $name
* @property \Carbon\Carbon $seen_at
* @property \App\Enums\Products\SourceEnum $source
* @property string|null $fair
* @property string|null $shop
* @property string|null $catalogue
* @property string|null $gencod
* @property string|null $picture
* @property string $picture_alt
* @property string $picture_title
* @property array|null $docs
* @property string|null $url
* @property \App\Enums\Products\CertificationEnum|null $certification
* @property array<integer>|null $origins
* @property \Illuminate\Support\Collection<\App\Enums\Products\OriginEnum> $origins_enum
* @property array<integer>|null $claims
* @property \Illuminate\Support\Collection<\App\Enums\Products\OriginEnum> $claims_enum
* @property string|null $specified_claim
* @property \App\Enums\Products\DistributionNetworkEnum $distribution_network
* @property \App\Enums\Products\RayEnum $ray
* @property \App\Enums\Products\RangeEnum $product_range
* @property \App\Enums\Products\GeoAreaEnum $geo area
* @property integer|null $weight
* @property integer|null $pvc
* @property string|null $comment
* @property boolean $is_tasted
* @property integer|null $tasters_number
* @property \Carbon\Carbon|null $created_at
* @property \Carbon\Carbon|null $updated_at
* @property \Carbon\Carbon|null $deleted_at
*
* * RELATIONSHIPS
* @property-read \App\Models\Brand $brand
* @property-read \App\Models\User $user
* @property-read \Illuminate\Database\Eloquent\Collection<\App\Models\ProductComment> $productComments
* @property-read \Illuminate\Database\Eloquent\Collection<\App\Models\Keyword> $productKeywords
*/
class Product extends Model
{
@ -109,10 +121,10 @@ class Product extends Model
'product_range' => RangeEnum::class,
'geo_area' => GeoAreaEnum::class,
'is_tasted' => 'boolean',
'seen_at' => 'datetime:Y-m-d',
'created_at' => 'datetime:Y-m-d',
'updated_at' => 'datetime:Y-m-d',
'deleted_at' => 'datetime:Y-m-d',
'seen_at' => 'datetime',
'created_at' => 'datetime',
'updated_at' => 'datetime',
'deleted_at' => 'datetime',
];
// * EVENTS
@ -292,28 +304,29 @@ class Product extends Model
/**
* Generate a pdf with multiple products.
*
* @param array $printMultiProduct
* @param string $title
* @param array<integer> $printMultiProduct
* @param string $title
* @return \Mccarlosen\LaravelMpdf\LaravelMpdf
*/
public static function generateMultipleProductPdf(array $printMultiProduct, string $title)
{
/** @var \Mccarlosen\LaravelMpdf\LaravelMpdf */
/** @var \Mccarlosen\LaravelMpdf\LaravelMpdf|null */
$pdf = null;
// Loop all views.
// * Loop all Model ids.
foreach ($printMultiProduct as $productId) {
$product = Product::where('id', $productId)->firstOrFail();
// If not yet defined, set the first page.
/** @var \App\Models\Product */
$product = Product::query()->where('id', $productId)->firstOrFail();
// * If not yet defined, set the first page.
if (is_null($pdf)) {
$pdf = Product::generateProductPdf($product, $title);
} else {
// Add another page and add HTML from view to this.
$pdf->getMpdf()->AddPage();
$pdf->getMpdf()->WriteHTML((string)view(
'documents.product-body',
['product' => \json_decode(\json_encode(new ProductResource($product)))],
));
}
// * Add another page and add HTML from view to this.
$pdf->getMpdf()->AddPage();
$pdf->getMpdf()->WriteHTML((string)view(
'documents.product-body',
['product' => (object)(new ProductResource($product))->toArray()],
));
}
return $pdf;
}
@ -349,14 +362,64 @@ class Product extends Model
])->send();
}
// * RELATIONS
// * GETTERS
/**
* Get origins_enum attribute
*
* @return \Illuminate\Support\Collection<\App\Enums\Ingredients\OriginEnum>
*/
public function getOriginsEnumAttribute(): Collection
{
return \collect($this->getAttribute('origins'))->filter()
->map(fn (int $originEnumValue) => OriginEnum::make($originEnumValue));
}
/**
* Set origins_enum attribute
*
* @param mixed $value
* @return void
*/
public function setOriginsEnumAttribute(mixed $value): void
{
$this->setAttribute('origins', \collect($value)->filter()
->map(fn ($originEnumValue) => OriginEnum::make($originEnumValue)->value())
->all());
}
/**
* Get claims_enum attribute
*
* @return \Illuminate\Support\Collection<\App\Enums\Ingredients\ClaimEnum>
*/
public function getClaimsEnumAttribute(): Collection
{
return \collect($this->getAttribute('claims'))->filter()
->map(fn (int $originEnumValue) => ClaimEnum::make($originEnumValue));
}
/**
* Set claims_enum attribute
*
* @param mixed $value
* @return void
*/
public function setClaimsEnumAttribute(mixed $value): void
{
$this->setAttribute('claims', \collect($value)->filter()
->map(fn ($claimEnumValue) => OriginEnum::make($claimEnumValue)->value())
->all());
}
// * RELATIONSHIPS
/**
* @return \Illuminate\Database\Eloquent\Relations\HasMany
*/
public function productComments()
{
return $this->hasMany('App\Models\ProductComment');
return $this->hasMany(ProductComment::class);
}
/**
@ -364,7 +427,7 @@ class Product extends Model
*/
public function user()
{
return $this->belongsTo('App\Models\User');
return $this->belongsTo(User::class);
}
/**
@ -372,7 +435,7 @@ class Product extends Model
*/
public function brand()
{
return $this->belongsTo('App\Models\Brand');
return $this->belongsTo(Brand::class);
}
/**

View file

@ -6,16 +6,18 @@ use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
/**
* @property integer $id
* @property integer $product_id
* @property string $evaluation
* @property string $aspect
* @property string $taste
* @property string $odor
* @property string $texture
* @property string $created_at
* @property string $updated_at
* @property Product $product
* @property integer $id
* @property integer $product_id
* @property string $evaluation
* @property string|null $aspect
* @property string|null $taste
* @property string|null $odor
* @property string|null $texture
* @property \Carbon\Carbon $created_at
* @property \Carbon\Carbon $updated_at
*
* * RELATIONSHIPS
* @property-read \App\Models\Product $product
*/
class ProductComment extends Model
{
@ -35,11 +37,23 @@ class ProductComment extends Model
'updated_at'
];
/**
* The attributes that should be cast.
*
* @var array
*/
protected $casts = [
'created_at' => 'datetime',
'updated_at' => 'datetime',
];
// * RELATIONSHIPS
/**
* @return \Illuminate\Database\Eloquent\Relations\BelongsTo
*/
public function product()
{
return $this->belongsTo('App\Models\Product');
return $this->belongsTo(Product::class);
}
}

View file

@ -13,21 +13,13 @@
@else
<td width="100%">
@endif
@if (isset($product->brand_id->name))
<h2><strong>{{ __('Marque du produit : ') }}</strong><span>{{ $product->brand_id->name }}</span></h2>
@endif
@if (isset($product->name))
<h2><strong>{{ __('Nom du produit : ') }}</strong><span>{{ $product->name }}</span></h2>
@endif
<h2><strong>{{ __('Marque du produit : ') }}</strong><span>{{ $product->brand->name }}</span></h2>
<h2><strong>{{ __('Nom du produit : ') }}</strong><span>{{ $product->name }}</span></h2>
@if (isset($product->certification))
<p><strong>{{ __('Certification : ') }}</strong>{{ $product->certification }}</p>
@endif
@if (isset($product->origins))
<p><strong>{{ __('Origines : ') }}</strong>{{ Str::replaceLast(', ', '', $product->origins) }}</p>
@endif
@if (isset($product->claims))
<p><strong>{{ __('Allégations : ') }}</strong>{{ Str::replaceLast(', ', '', $product->claims) }}</p>
@endif
<p><strong>{{ __('Origines : ') }}</strong>{{ $product->origins }}</p>
<p><strong>{{ __('Allégations : ') }}</strong>{{ $product->claims }}</p>
<table class="table" width="100%">
<tr class="table-header">
@if (isset($product->gencod))
@ -78,41 +70,37 @@
@if (isset($product->freeComment))
<p><strong>{{ __('Commentaire libre : ') }}</strong>{{ strip_tags($product->freeComment) }}</p>
@endif
@if (isset($product->productComments))
@foreach ($product->productComments as $productComment)
<p><strong>{{ __('Commentaire dégustation du : ') }}</strong>{{ $productComment->date }}</p>
<table class="table" width="100%">
<tr class="table-header">
<td class="table-cell-text-center" width="20%"><strong>{{ __('Appréciation') }}</strong></td>
<td class="table-cell-text-center" width="20%"><strong>{{ __('Aspect') }}</strong></td>
<td class="table-cell-text-center" width="20%"><strong>{{ __('Odeur') }}</strong></td>
<td class="table-cell-text-center" width="20%"><strong>{{ __('Texture') }}</strong></td>
<td class="table-cell-text-center" width="20%"><strong>{{ __('Goût') }}</strong></td>
</tr>
<tr class="table-body">
<td class="table-cell-text-center" width="20%">{{ $productComment->evaluation }}</td>
<td class="table-cell-text-center" width="20%">{{ $productComment->aspect }}</td>
<td class="table-cell-text-center" width="20%">{{ $productComment->taste }}</td>
<td class="table-cell-text-center" width="20%">{{ $productComment->odor }}</td>
<td class="table-cell-text-center" width="20%">{{ $productComment->texture }}</td>
</tr>
</table>
@endforeach
@endif
@foreach ($product->productComments as $productComment)
<p><strong>{{ __('Commentaire dégustation du : ') }}</strong>{{ $productComment->created_at->isoFormat('DD\/MM\/YYYY') }}</p>
<table class="table" width="100%">
<tr class="table-header">
<td class="table-cell-text-center" width="20%"><strong>{{ __('Appréciation') }}</strong></td>
<td class="table-cell-text-center" width="20%"><strong>{{ __('Aspect') }}</strong></td>
<td class="table-cell-text-center" width="20%"><strong>{{ __('Odeur') }}</strong></td>
<td class="table-cell-text-center" width="20%"><strong>{{ __('Texture') }}</strong></td>
<td class="table-cell-text-center" width="20%"><strong>{{ __('Goût') }}</strong></td>
</tr>
<tr class="table-body">
<td class="table-cell-text-center" width="20%">{{ $productComment->evaluation }}</td>
<td class="table-cell-text-center" width="20%">{{ $productComment->aspect }}</td>
<td class="table-cell-text-center" width="20%">{{ $productComment->taste }}</td>
<td class="table-cell-text-center" width="20%">{{ $productComment->odor }}</td>
<td class="table-cell-text-center" width="20%">{{ $productComment->texture }}</td>
</tr>
</table>
@endforeach
<table class="product-saw" width="100%">
<tr>
@if (isset($product->seen_at))
<td class="table-cell-text-center" width="50%">
<strong>{{ __('Téléchargez les documents :') }}</strong>
<a href="{{ route('products.download', $product->id) }}">{{ __('ICI') }}</a>
</td>
@endif
<td class="table-cell-text-center" width="50%">
<strong>{{ __('Téléchargez les documents :') }}</strong>
<a href="{{ route('products.download', $product->id) }}">{{ __('ICI') }}</a>
</td>
@if (isset($product->source))
<td class="table-cell-text-center" width="50%">
<p><strong>{{ __('Vu le : ') }}</strong>{{ $product->seen_at }}</p>
<p><strong>{{ __('Lieu : ') }}</strong>{{ $product->source }},&nbsp;{{ $product->fair }}{{ $product->shop }}{{ $product->catalogue }}
</p>
<p><strong>{{ __('Par : ') }}</strong>{{ $product->user_id->firstname }}&nbsp;{{ $product->user_id->lastname }}</p>
<p><strong>{{ __('Par : ') }}</strong>{{ $product->user->firstname }}&nbsp;{{ $product->user->lastname }}</p>
</td>
@endif
</tr>