Product print commercial sheet

This commit is contained in:
Jérémy Munsch 2023-01-18 19:21:08 +01:00
parent 6c19bf85b0
commit bb07aa98b5
No known key found for this signature in database
GPG key ID: 18361AF3BFEC0FEC
18 changed files with 845 additions and 70 deletions

View file

@ -5,6 +5,7 @@ namespace App\Http\Controllers\Fo;
use App\Http\Controllers\Controller;
use App\Http\Requests\Fo\Products\AjaxAddProductBasket;
use App\Http\Requests\Fo\Products\AjaxFilterProductsRequest;
use App\Http\Resources\Fo\Products\ProductCommercialSheetResource;
use App\Http\Resources\Fo\Products\ProductPaginatedCollectionResource;
use App\Http\Resources\Fo\Products\ProductResource;
use App\Models\Product;
@ -13,6 +14,8 @@ use Illuminate\Database\Eloquent\Builder;
use Illuminate\Http\JsonResponse;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\Session;
use Illuminate\Support\Str;
use Mccarlosen\LaravelMpdf\LaravelMpdf;
class ProductsController extends Controller
{
@ -120,6 +123,26 @@ class ProductsController extends Controller
return view('fo.pages.products.product', compact('product', 'recipes', 'tips', 'randomProducts'));
}
/**
* Print product commercial sheet
*
* @param \App\Models\Product $publishedProduct
* @return \Illuminate\Contracts\View\View|\Illuminate\Contracts\View\Factory
*/
public function printCommericalSheet(Product $publishedProduct)
{
$title = trans('Fiche commerciale du produit : :label - :appname', [
'label' => $publishedProduct->label,
'appname' => \config('app.name', 'Le Gaulois Pro')
]);
$filename = trans('fiche-commerciale-:slug-:date', [
'slug' => Str::slug($publishedProduct->label),
'date' => \now()->format('Y-m-d')
]);
return $this->generateProductCommercialPdf($publishedProduct, $title)
->stream("{$filename}.pdf");
}
/**
* Save a specific product in the session.
*
@ -176,4 +199,59 @@ class ProductsController extends Controller
}
return Session::get('saveProductInBasket');
}
/**
* Generate product commercial sheet PDF
*
* @param \App\Models\Product $product
* @param string $title
* @return \Mccarlosen\LaravelMpdf\LaravelMpdf
*/
private function generateProductCommercialPdf(Product $product, string $title): LaravelMpdf
{
/** @var \Mccarlosen\LaravelMpdf\LaravelMpdf */
$mpdf = app('laravel-mpdf');
/** @var \Mccarlosen\LaravelMpdf\LaravelMpdf */
$pdf = $mpdf->loadView(
'documents.product-commercial-sheet',
// * Dirty convert to object.
[
'title' => $title,
'product' => \json_decode(\json_encode(new ProductCommercialSheetResource($product)))
],
[],
[
'mode' => 'utf-8',
'format' => 'A4',
'default_font_size' => '12',
'default_font' => 'sans-serif',
// Recto Verso.
'margin_left' => 0,
'margin_right' => 0,
'mirrorMargins' => true,
'margin_top' => 0,
'margin_bottom' => 0,
'margin_header' => 0,
'margin_footer' => 0,
'margin_top' => 0,
'orientation' => 'P',
'title' => $title,
'author' => \config('app.name', 'Le Gaulois Pro'),
'watermark' => '',
'show_watermark' => false,
'watermark_font' => 'sans-serif',
'display_mode' => 'fullpage',
'watermark_text_alpha' => 0.1,
'custom_font_dir' => '',
'custom_font_data' => [],
'auto_language_detection' => false,
'temp_dir' => rtrim(sys_get_temp_dir(), DIRECTORY_SEPARATOR),
'pdfa' => false,
'pdfaauto' => false,
]
);
return $pdf;
}
}

View file

@ -49,7 +49,8 @@ class SecureHeaders
"connect-src 'self' blob:;",
"img-src * data: blob:;",
// "frame-src https://www.youtube.com;",
"frame-src https://www.youtube-nocookie.com https://www.google.com/recaptcha/;",
// ! Blob required for printjs
"frame-src blob: https://www.youtube-nocookie.com https://www.google.com/recaptcha/;",
"font-src 'self' data:;",
// ! Using CKEditor will must have unsafe-inline style
// phpcs:ignore Generic.Files.LineLength.TooLong

View file

@ -0,0 +1,86 @@
<?php
namespace App\Http\Resources\Fo\Products;
use App\Models\Product;
use Illuminate\Http\Resources\Json\JsonResource;
class ProductCommercialSheetResource extends JsonResource
{
/** @var \App\Models\Product */
private $product;
/** @var array */
private static $skeleton = [
'id' => '',
'label' => '',
'slug' => '',
'species' => null,
'is_frenchpoultry' => false,
'nutriscore' => [
'label' => 'none',
'value' => 0
],
'advantage' => '',
'packaging' => [],
'caliber' => [],
'ingredients' => '',
'preparation' => '',
'sticker_sm' => '',
'nutritionnal_values' => [],
'slider_pictures' => [],
'subrange' => null,
];
/**
* ProductResource
*
* @param \App\Models\Product $product
* @return void
*/
public function __construct(Product $product)
{
$this->product = $product;
}
/**
* Transform the resource into an array.
*
* @param \Illuminate\Http\Request|null $request
* @return array
* @phpcs:disable Generic.CodeAnalysis.UnusedFunctionParameter.FoundInExtendedClass
*/
public function toArray($request = null)
{
return array_intersect_key(
[
'id' => $this->product->id,
'label' => $this->product->label,
'slug' => $this->product->slug,
'species' => $this->product->species,
'is_frenchpoultry' => $this->product->is_frenchpoultry,
'nutriscore' => $this->product->nutriscore,
'advantage' => $this->product->advantage,
'packaging' => $this->product->packaging,
'caliber' => $this->product->caliber,
'ingredients' => $this->product->ingredients,
'preparation' => $this->product->preparation,
'nutritionnal_values' => $this->product->nutritionnal_values,
'sticker_sm' => $this->product->sticker_sm,
'slider_pictures' => $this->product->slider_pictures,
'subrange' => (new SubrangeResource($this->product->subrange))->toArray($request),
],
$this->getSkeleton()
);
}
/**
* Returns the resource skeletton
*
* @return array
*/
public static function getSkeleton(): array
{
return self::$skeleton;
}
}

View file

@ -10,6 +10,7 @@
"require": {
"php": "^7.3|^8.0",
"axlon/laravel-postal-code-validation": "^3.3",
"carlos-meneses/laravel-mpdf": "^2.1",
"diglactic/laravel-breadcrumbs": "^8.0",
"fruitcake/laravel-cors": "^2.0",
"guzzlehttp/guzzle": "^7.0.1",

375
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": "2bf81c8319df6fcbfd391b6c08e0b161",
"content-hash": "9256c04c28d5e4644fcd2c1384db3635",
"packages": [
{
"name": "asm89/stack-cors",
@ -189,6 +189,62 @@
],
"time": "2021-08-15T20:50:18+00:00"
},
{
"name": "carlos-meneses/laravel-mpdf",
"version": "2.1.11",
"source": {
"type": "git",
"url": "https://github.com/mccarlosen/laravel-mpdf.git",
"reference": "cb52e5c17df9caa340eaed8566cfb1e3c7b37c33"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/mccarlosen/laravel-mpdf/zipball/cb52e5c17df9caa340eaed8566cfb1e3c7b37c33",
"reference": "cb52e5c17df9caa340eaed8566cfb1e3c7b37c33",
"shasum": ""
},
"require": {
"mpdf/mpdf": "^8.0",
"php": "^5.6|^7.0|^8.0"
},
"type": "library",
"extra": {
"laravel": {
"providers": [
"Mccarlosen\\LaravelMpdf\\LaravelMpdfServiceProvider"
],
"aliases": {
"PDF": "Mccarlosen\\LaravelMpdf\\Facades\\LaravelMpdf"
}
}
},
"autoload": {
"psr-4": {
"Mccarlosen\\LaravelMpdf\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"description": "Laravel Mpdf: Using Mpdf in Laravel to generate Pdfs.",
"keywords": [
"laravel",
"mpdf",
"pdf"
],
"support": {
"issues": "https://github.com/mccarlosen/laravel-mpdf/issues",
"source": "https://github.com/mccarlosen/laravel-mpdf/tree/2.1.11"
},
"funding": [
{
"url": "https://www.paypal.me/mccarlosen",
"type": "custom"
}
],
"time": "2022-12-28T02:20:09+00:00"
},
{
"name": "clue/stream-filter",
"version": "v1.6.0",
@ -2860,6 +2916,142 @@
],
"time": "2022-07-24T11:55:47+00:00"
},
{
"name": "mpdf/mpdf",
"version": "v8.1.4",
"source": {
"type": "git",
"url": "https://github.com/mpdf/mpdf.git",
"reference": "add590e93b7502efafd9839a68cff99f3497b318"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/mpdf/mpdf/zipball/add590e93b7502efafd9839a68cff99f3497b318",
"reference": "add590e93b7502efafd9839a68cff99f3497b318",
"shasum": ""
},
"require": {
"ext-gd": "*",
"ext-mbstring": "*",
"myclabs/deep-copy": "^1.7",
"paragonie/random_compat": "^1.4|^2.0|^9.99.99",
"php": "^5.6 || ^7.0 || ~8.0.0 || ~8.1.0 || ~8.2.0",
"php-http/message-factory": "^1.0",
"psr/http-message": "^1.0",
"psr/log": "^1.0 || ^2.0",
"setasign/fpdi": "^2.1"
},
"require-dev": {
"mockery/mockery": "^1.3.0",
"mpdf/qrcode": "^1.1.0",
"squizlabs/php_codesniffer": "^3.5.0",
"tracy/tracy": "~2.5",
"yoast/phpunit-polyfills": "^1.0"
},
"suggest": {
"ext-bcmath": "Needed for generation of some types of barcodes",
"ext-xml": "Needed mainly for SVG manipulation",
"ext-zlib": "Needed for compression of embedded resources, such as fonts"
},
"type": "library",
"autoload": {
"psr-4": {
"Mpdf\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"GPL-2.0-only"
],
"authors": [
{
"name": "Matěj Humpál",
"role": "Developer, maintainer"
},
{
"name": "Ian Back",
"role": "Developer (retired)"
}
],
"description": "PHP library generating PDF files from UTF-8 encoded HTML",
"homepage": "https://mpdf.github.io",
"keywords": [
"pdf",
"php",
"utf-8"
],
"support": {
"docs": "http://mpdf.github.io",
"issues": "https://github.com/mpdf/mpdf/issues",
"source": "https://github.com/mpdf/mpdf"
},
"funding": [
{
"url": "https://www.paypal.me/mpdf",
"type": "custom"
}
],
"time": "2022-12-15T11:24:39+00:00"
},
{
"name": "myclabs/deep-copy",
"version": "1.11.0",
"source": {
"type": "git",
"url": "https://github.com/myclabs/DeepCopy.git",
"reference": "14daed4296fae74d9e3201d2c4925d1acb7aa614"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/14daed4296fae74d9e3201d2c4925d1acb7aa614",
"reference": "14daed4296fae74d9e3201d2c4925d1acb7aa614",
"shasum": ""
},
"require": {
"php": "^7.1 || ^8.0"
},
"conflict": {
"doctrine/collections": "<1.6.8",
"doctrine/common": "<2.13.3 || >=3,<3.2.2"
},
"require-dev": {
"doctrine/collections": "^1.6.8",
"doctrine/common": "^2.13.3 || ^3.2.2",
"phpunit/phpunit": "^7.5.20 || ^8.5.23 || ^9.5.13"
},
"type": "library",
"autoload": {
"files": [
"src/DeepCopy/deep_copy.php"
],
"psr-4": {
"DeepCopy\\": "src/DeepCopy/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"description": "Create deep copies (clones) of your objects",
"keywords": [
"clone",
"copy",
"duplicate",
"object",
"object graph"
],
"support": {
"issues": "https://github.com/myclabs/DeepCopy/issues",
"source": "https://github.com/myclabs/DeepCopy/tree/1.11.0"
},
"funding": [
{
"url": "https://tidelift.com/funding/github/packagist/myclabs/deep-copy",
"type": "tidelift"
}
],
"time": "2022-03-03T13:19:32+00:00"
},
{
"name": "nesbot/carbon",
"version": "2.64.0",
@ -3206,6 +3398,56 @@
},
"time": "2022-01-27T09:35:39+00:00"
},
{
"name": "paragonie/random_compat",
"version": "v9.99.100",
"source": {
"type": "git",
"url": "https://github.com/paragonie/random_compat.git",
"reference": "996434e5492cb4c3edcb9168db6fbb1359ef965a"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/paragonie/random_compat/zipball/996434e5492cb4c3edcb9168db6fbb1359ef965a",
"reference": "996434e5492cb4c3edcb9168db6fbb1359ef965a",
"shasum": ""
},
"require": {
"php": ">= 7"
},
"require-dev": {
"phpunit/phpunit": "4.*|5.*",
"vimeo/psalm": "^1"
},
"suggest": {
"ext-libsodium": "Provides a modern crypto API that can be used to generate random bytes."
},
"type": "library",
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Paragon Initiative Enterprises",
"email": "security@paragonie.com",
"homepage": "https://paragonie.com"
}
],
"description": "PHP 5.x polyfill for random_bytes() and random_int() from PHP 7",
"keywords": [
"csprng",
"polyfill",
"pseudorandom",
"random"
],
"support": {
"email": "info@paragonie.com",
"issues": "https://github.com/paragonie/random_compat/issues",
"source": "https://github.com/paragonie/random_compat"
},
"time": "2020-10-15T08:29:30+00:00"
},
{
"name": "php-http/client-common",
"version": "2.6.0",
@ -4651,6 +4893,78 @@
],
"time": "2022-11-23T13:25:02+00:00"
},
{
"name": "setasign/fpdi",
"version": "v2.3.6",
"source": {
"type": "git",
"url": "https://github.com/Setasign/FPDI.git",
"reference": "6231e315f73e4f62d72b73f3d6d78ff0eed93c31"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/Setasign/FPDI/zipball/6231e315f73e4f62d72b73f3d6d78ff0eed93c31",
"reference": "6231e315f73e4f62d72b73f3d6d78ff0eed93c31",
"shasum": ""
},
"require": {
"ext-zlib": "*",
"php": "^5.6 || ^7.0 || ^8.0"
},
"conflict": {
"setasign/tfpdf": "<1.31"
},
"require-dev": {
"phpunit/phpunit": "~5.7",
"setasign/fpdf": "~1.8",
"setasign/tfpdf": "1.31",
"squizlabs/php_codesniffer": "^3.5",
"tecnickcom/tcpdf": "~6.2"
},
"suggest": {
"setasign/fpdf": "FPDI will extend this class but as it is also possible to use TCPDF or tFPDF as an alternative. There's no fixed dependency configured."
},
"type": "library",
"autoload": {
"psr-4": {
"setasign\\Fpdi\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Jan Slabon",
"email": "jan.slabon@setasign.com",
"homepage": "https://www.setasign.com"
},
{
"name": "Maximilian Kresse",
"email": "maximilian.kresse@setasign.com",
"homepage": "https://www.setasign.com"
}
],
"description": "FPDI is a collection of PHP classes facilitating developers to read pages from existing PDF documents and use them as templates in FPDF. Because it is also possible to use FPDI with TCPDF, there are no fixed dependencies defined. Please see suggestions for packages which evaluates the dependencies automatically.",
"homepage": "https://www.setasign.com/fpdi",
"keywords": [
"fpdf",
"fpdi",
"pdf"
],
"support": {
"issues": "https://github.com/Setasign/FPDI/issues",
"source": "https://github.com/Setasign/FPDI/tree/v2.3.6"
},
"funding": [
{
"url": "https://tidelift.com/funding/github/packagist/setasign/fpdi",
"type": "tidelift"
}
],
"time": "2021-02-11T11:37:01+00:00"
},
{
"name": "spatie/browsershot",
"version": "3.40.2",
@ -9273,65 +9587,6 @@
},
"time": "2022-09-07T15:32:08+00:00"
},
{
"name": "myclabs/deep-copy",
"version": "1.11.0",
"source": {
"type": "git",
"url": "https://github.com/myclabs/DeepCopy.git",
"reference": "14daed4296fae74d9e3201d2c4925d1acb7aa614"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/14daed4296fae74d9e3201d2c4925d1acb7aa614",
"reference": "14daed4296fae74d9e3201d2c4925d1acb7aa614",
"shasum": ""
},
"require": {
"php": "^7.1 || ^8.0"
},
"conflict": {
"doctrine/collections": "<1.6.8",
"doctrine/common": "<2.13.3 || >=3,<3.2.2"
},
"require-dev": {
"doctrine/collections": "^1.6.8",
"doctrine/common": "^2.13.3 || ^3.2.2",
"phpunit/phpunit": "^7.5.20 || ^8.5.23 || ^9.5.13"
},
"type": "library",
"autoload": {
"files": [
"src/DeepCopy/deep_copy.php"
],
"psr-4": {
"DeepCopy\\": "src/DeepCopy/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"description": "Create deep copies (clones) of your objects",
"keywords": [
"clone",
"copy",
"duplicate",
"object",
"object graph"
],
"support": {
"issues": "https://github.com/myclabs/DeepCopy/issues",
"source": "https://github.com/myclabs/DeepCopy/tree/1.11.0"
},
"funding": [
{
"url": "https://tidelift.com/funding/github/packagist/myclabs/deep-copy",
"type": "tidelift"
}
],
"time": "2022-03-03T13:19:32+00:00"
},
{
"name": "nunomaduro/collision",
"version": "v5.11.0",

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 64 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

View file

@ -8,6 +8,13 @@
.searchbar-wrapper,
.filter-wrapper { max-width: 334px; }
// Print fiche commerciale
@media print {
#print-id-product {
display: block;
}
}
#search-products {
border: unset;
background-color: $primary;
@ -76,9 +83,6 @@
.label-interest::after { display: none; }
.business-infos {
background-color: rgb(0 0 0 / 70%);
transition: visibility 0s ease-in-out, opacity 0.3s ease-in-out;
.business-wrap { max-width: 1186px; }
.img-anatomie-wrapper {

View file

@ -222,7 +222,14 @@ window.addEventListener("DOMContentLoaded", () => {
eltButtonPrintProd.addEventListener("click", function () {
if (businessSheet) {
setTimeout(() => {
printJS("printIdProduct", "html");
// ! Seule solution: imprimer un pdf spécifique pour avoir le rendu souhaité.
printJS({
printable:
window.location.pathname +
"/print-commercial-sheet",
type: "pdf",
showModal: true,
});
});
} else {
console.error(

View file

@ -0,0 +1,13 @@
{{-- TITRE et LOGOS --}}
<table class="header-table" width="100%" cellspacing="0" cellpadding="0">
<tr class="header-row">
<td class="cell-text-center">
{{-- Nasty hack for height --}}
&nbsp;<br>&nbsp;<br>&nbsp;
</td>
</tr>
</table>
{{-- positionfixed --}}
<div class="header-logo-block">
<img class="header-logo" src="{{ public_path('build/assets/images/header/logo-lgp-header.png') }}" alt="{{ config('app.name') }}">
</div>

View file

@ -0,0 +1,26 @@
{{-- TITRE et LOGOS --}}
<table width="100%" cellspacing="0" cellpadding="0">
<tr>
<td width="50%">
<h1 class="text-bold ">{{ $product->label }}</h1>
</td>
<td>
<table>
<tr>
@if ($product->is_frenchpoultry)
<td>
<img class="logo" src="{{ public_path('build/assets/images/logo-vf.png') }}" alt="{{ __('Logo de la volaille française') }}">
</td>
@endif
@if ($product->nutriscore->value > 0)
<td>
<img class="logo" src="{{ public_path('build/assets/images/nutriscore/logo-nutriscore-'. $product->nutriscore->label .'.png') }}" alt="{{ __('Logo Nutriscore') }}">
</td>
@endif
<td>
</tr>
</table>
</td>
</tr>
</table>
<br/>

View file

@ -0,0 +1,302 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>
{{ $title }}
</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
<style type="text/css">
html,
body {
position: relative;
width: 210mm;
height: 297mm;
margin: 0;
padding: 0;
}
body {
font-family: Tahoma;
font-size: 12px;
color: #333333;
background-color: #FFFFFF;
}
table {
border-collapse: collapse;
}
.section {
margin: auto;
height: 244mm;
width: 178mm;
}
/* RESET title */
h6, .h6, h5, .h5, h4, .h4, h3, .h3, h2, .h2, h1, .h1{
margin-top:0;
margin-bottom:0.5rem;
font-weight:500;
line-height:1.2;
}
h1,.h1 {
font-size: 1.375rem;
}
h2,.h2 {
font-size: 1.325rem;
}
h3,.h3 {
font-size: 1.3rem;
}
h4,.h4 {
font-size: 1.275rem;
}
h5,.h5 {
font-size: 1.25rem;
}
h6,.h6 {
font-size: 1rem;
}
/* HEADER ribbon */
.header-table {
margin-bottom: 15mm;
}
.header-row {
background: no-repeat center/cover url({{ public_path('build/assets/images/fond-inox.jpg') }});
}
.header-logo-block {
position: absolute;
top: 0;
left: 85mm;
}
.header-logo {
max-width: 40mm;
width: auto;
}
/* Vollaille FR et nutri */
.logo {
max-height: 13mm;
max-width: 20mm;
width: auto;
}
.product-picture {
padding-left: 10mm;
max-width: 70mm;
width: auto;
}
.footer-picture-logo {
max-width: 20mm;
width: auto;
}
.footer-picture-logo-small {
max-width: 6mm;
width: auto;
}
.footer-text {
font-size: 0.9rem;
}
/* Text utilities */
.text-normal {
font-weight: normal;
}
.text-bold {
font-weight: bold;
}
.text-underline {
border-bottom: 1px solid black;
}
.cell-text-v-top {
vertical-align: top;
}
.cell-text-center {
text-align: center;
}
.cell-text-right {
text-align: right;
padding-right: 1mm;
}
.cell-text-left {
text-align: left;
padding-left: 1mm;
}
</style>
</head>
<body>
{{-- HEADER ribbon --}}
@include('documents.partials.product-com-sheet-header')
<div class="section" cellpadding="0" cellspacing="0">
{{-- TITRE et LOGOS --}}
@include('documents.partials.product-com-sheet-title')
{{-- Atouts produit et image --}}
<table width="100%" cellspacing="0" cellpadding="0">
<tr>
{{-- ATOUTS --}}
<td width="50%">
<h2><span class="text-bold text-underline">{{ __('Les atouts produits') }}</span></h2><br>
<p>{{ strip_tags($product->advantage) }}</p><br>
<p>{{ __('Gamme : ') }}<span class="text-bold">{{ $product->subrange->range->label }}</span></p><br>
<p>{{ __('Famille : ') }}<span class="text-bold">{{ $product->species->label }}</span></p><br>
<p>
<span class="text-bold">{{ __('Conditionnement :') }}</span><br>
{{ collect($product->packaging)->pluck('value')->implode(', ') }}
</p><br>
<p>
<span class="text-bold">{{ __('Calibre :') }}</span><br>
{{ collect($product->caliber)->pluck('value')->implode(', ') }}
</p><br>
<p><span class="text-bold">{{ __('Origine de la viande :') }}</span>{{ $product->is_frenchpoultry ? __('France') : __('Étrangère') }}</p><br>
<p>
<span class="text-bold">{{ __('Conseils de Ingrédient :') }}</span><br>
{{ strip_tags($product->ingredients) }}
</p><br>
<p>
<span class="text-bold">{{ __('Conseils de préparation :') }}</span><br>
{{ strip_tags($product->preparation) }}
</p><br>
</td>
<td class="cell-text-v-top">
<img class="product-picture" src="{{ public_path(collect($product->slider_pictures)->first() ?? $product->sticker_sm) }}" alt="{{ $product->label }}">
</td>
</tr>
<tr>
<td colspan="2">
</td>
</tr>
</table>
</div>
@php
$titles = [];
$lines = [];
$svg = null;
$svg_alt = 'non défini';
switch ($product->species) {
case App\Enums\Products\ProductSpeciesEnum::canard():
$svg = public_path('build/assets/images/canard-dark.png');
$titles = ['1/ Aile', '2/ Filet', '3/ Cuisse'];
$svg_alt = __('Dessin de l\'anatomie d\'une dinde');
break;
case App\Enums\Products\ProductSpeciesEnum::canard():
$svg = public_path('build/assets/images/dinde-dark.png');
$titles = ['1/ Filet', '2/ Cuisse', '3/ Filer', '4/ Cuisse', '5/ Filet', '6/ Cuisse', '7/ Filet'];
$svg_alt = __('Dessin de l\'anatomie d\'une dinde');
break;
case App\Enums\Products\ProductSpeciesEnum::lapin():
$svg = public_path('build/assets/images/lapin-dark.png');
$titles = ['1/ Rable', '2/ Cuisse', '3/ Filet'];
$svg_alt = __('Dessin de l\'anatomie d\'un lapin');
break;
case App\Enums\Products\ProductSpeciesEnum::pintade():
$svg = public_path('build/assets/images/pintade-dark.png');
$titles = ['1/ Filet', '2/ Cuisse', '3/ Cuisse'];
$svg_alt = __('Dessin de l\'anatomie d\'une pintade');
break;
case App\Enums\Products\ProductSpeciesEnum::poulet():
$svg = public_path('build/assets/images/poulet-dark.png');
$titles = ['1/ Filet', '2/ Aile', '3/ Cuisse'];
$lines = [[], ['2A/ Manchon', '2B/ Médiane', '2C/Pilon'], ['3A/ Haut de cuisse', '3B Pilon']];
$svg_alt = __('Dessin de l\'anatomie d\'un poulet');
break;
}
@endphp
@if(!is_null($svg))
{{-- Nouvelle page --}}
<pagebreak>
{{-- HEADER ribbon --}}
@include('documents.partials.product-com-sheet-header')
<div class="section">
{{-- TITRE et LOGOS --}}
@include('documents.partials.product-com-sheet-title')
<h2><span class="text-bold text-underline">{{ $svg_alt }}</span></h2><br>
<table width="100%" cellspacing="0" cellpadding="0">
<tr>
<td width="30%" class="cell-text-v-top">
<ul>
@foreach ($titles as $key => $title)
<li>
<span class="text-bold">{{ $title }}</span>
@if (count($lines[$key]) > 0)
<ul>
@foreach ($lines[$key] as $line)
<li><span>{{ $line }}</span></li>
@endforeach
</ul>
@endif
<div>&nbsp;<br></div>
</li>
@endforeach
</ul>
</td>
<td class="cell-text-left">
<img src="{{ $svg }}" alt="{{ $svg_alt }}">
</td>
</tr>
</table>
</div>
@else
{{-- Nasty hack for FF DEV display --}}
<div></div>
@endif
<sethtmlpagefooter name="default_foot" value="1" show-this-page="1">
<table class="footer-text" width="90%" cellspacing="0" cellpadding="10" style="margin: auto;margin-bottom: 10mm;">
<tr>
<td class="cell-text-right">
<span>{{ parse_url(config('app.url'), \PHP_URL_HOST) }}</span>
</td>
<td width="30mm cell-text-center">
<img class="footer-picture-logo" src="{{ public_path('build/assets/images/logo-lgp-dark.png') }}" alt="{{ config('app.name') }}">
</td>
<td class="cell-text-left">
<table cellspacing="0" cellpadding="2">
<tr>
<td>
<img class="footer-picture-logo-small" src="{{ public_path('build/assets/images/linkedin-circle.png') }}" alt="{{ __('LinkedIn') }}">
</td>
<td>
<span>{{ __('Le Gaulois Professionnel') }}</span>
</td>
</tr>
</table>
</td>
</tr>
</table>
</sethtmlpagefooter>
<htmlpagefooter name="default_foot"></htmlpagefooter>
</body>
</html>

View file

@ -137,6 +137,8 @@ Route::prefix('/produit')
Route::get('/{publishedProduct:slug}', [ProductsController::class, 'show'])->name('show');
Route::post('/{publishedProduct:slug}/ajout-au-panier', [ProductsController::class, 'addProductToBasket'])
->name('add-product-to-basket');
Route::get('/{publishedProduct:slug}/print-commercial-sheet', [ProductsController::class, 'printCommericalSheet'])
->name('print-commercial-sheet');
Route::post('/{slug}/retrait-du-panier', [ProductsController::class, 'removeProductFromBasket'])
->name('remove-product-from-basket');
});
@ -152,11 +154,11 @@ Route::prefix('/nos-actualites')
});
Route::prefix('/contactez-nous')
->name('contact.')
->group(function () {
Route::get('/', [ContactController::class, 'index'])->name('show');
Route::post('/mail', [ContactController::class, 'contactSubmit'])->name('submit');
});
->name('contact.')
->group(function () {
Route::get('/', [ContactController::class, 'index'])->name('show');
Route::post('/mail', [ContactController::class, 'contactSubmit'])->name('submit');
});
Route::get('/restauration-sociale', [ActivitiesController::class, 'sociale'])->name('group');
Route::get('/restauration-commerciale', [ActivitiesController::class, 'commerciale'])->name('trade');