]> _ Git - bastide-resah.git/commitdiff
wait #6906 @4
authorVincent Vanwaelscappel <vincent@cubedesigners.com>
Mon, 13 May 2024 19:21:42 +0000 (21:21 +0200)
committerVincent Vanwaelscappel <vincent@cubedesigners.com>
Mon, 13 May 2024 19:21:42 +0000 (21:21 +0200)
.docker/images/php-fpm/Dockerfile
app/Http/Controllers/FluidbookController.php
app/Models/Order.php
app/Notifications/ResahNotification.php
package.json
resources/js/printpageaspdf.cjs [new file with mode: 0644]
resources/views/order.blade.php [new file with mode: 0644]
routes/web.php

index d53ce81b0ed04e66cf78a1e8f0ae5bc47a0c1f28..6f9339a771f088ac25aa98f406b2b16ff3c97e52 100644 (file)
@@ -67,7 +67,7 @@ ENV LC_ALL fr_FR.UTF-8
 COPY --from=composer:2 /usr/bin/composer /usr/bin/composer
 
 # IF you need some npm globally installed packages
-RUN npm install --unsafe-perm --global yarn puppeteer
+RUN npm install --unsafe-perm --global yarn puppeteer fs command-line-args
 
 CMD ["php", "-a"]
 
index dfdceaeaf6363559f23f4cfd60cda43b056ac768..1ced1c87777ff4ccffcfa5af7a37a4aa5e582108 100644 (file)
@@ -6,6 +6,7 @@ use App\Models\Client;
 use App\Models\Order;
 use App\Models\User;
 use App\Notifications\ResahNotification;
+use Cubist\Util\CommandLine;
 use Illuminate\Support\Facades\Auth;
 use Illuminate\Support\Facades\Hash;
 use Illuminate\Support\Facades\Validator;
@@ -43,7 +44,7 @@ class FluidbookController extends Controller
             $ignore = ['email_confirmation', 'password_confirmation', 'accept', '_token', 'valid_from'];
             $client = new Client();
             foreach ($validator->valid() as $k => $v) {
-                if (in_array($k, $ignore) || strstr($k,'honeypot_for_bots_')) {
+                if (in_array($k, $ignore) || strstr($k, 'honeypot_for_bots_')) {
                     continue;
                 }
                 if ($k === 'password') {
@@ -104,7 +105,11 @@ class FluidbookController extends Controller
         $total = 0;
         $cumul_tva = 0;
         $cumul_ecotaxe = 0;
-        foreach (request('details') as $i) {
+        $raw = request('details');
+        $details_json = ['raw' => $raw, 'lines' => [], 'totals' => []];
+        foreach ($raw as $i) {
+
+
             $p = $data[$i['reference']];
             $quantity += $i['quantity'];
 
@@ -118,32 +123,64 @@ class FluidbookController extends Controller
             $cumul_ecotaxe += $ecotaxe;
 
             $d = [];
+            $jd = [];
+            $jt = [];
             foreach ($p as $k => $v) {
                 if (!$k || !$v) {
                     continue;
                 }
+
                 $d[] = $k . " : " . $v;
+                $jd[] = $v;
+                $jt[] = $k;
             }
             $d[] = '--';
             $d[] = 'QUANTITE : ' . $i['quantity'];
             $d[] = 'TOTAL HT : ' . self::formatNumber($tht);
+            $jt[] = 'QUANTITE';
+            $jt[] = 'TOTAL HT';
+            $jd[] = $i['quantity'];
+            $jd[] = self::formatNumber($tht);
             $details[] = implode("\n", $d);
+
+            $details_json['lines'][] = $jd;
         }
 
+
         $details[] = 'TOTAL HT : ' . self::formatNumber($total) . "\n"
             . 'TVA : ' . self::formatNumber($cumul_tva) . "\n"
             . 'ECOTAXE : ' . self::formatNumber($cumul_ecotaxe) . "\n"
             . 'TOTAL TTC : ' . self::formatNumber($total + $cumul_tva);
 
+        $details_json['totals'] = ['TOTAL HT' => self::formatNumber($total),
+            'TVA' => self::formatNumber($cumul_tva),
+            'ECOTAXE' => self::formatNumber($cumul_ecotaxe),
+            'TOTAL TTC' => self::formatNumber($total + $cumul_tva),
+        ];
+        $details_json['titles'] = $jt;
+
+
         /** @var Client $user */
         $user = auth()->guard('client')->user();
         $order = new Order();
         $order->client = $user->id;
         $order->details = implode("\n\n----\n\n", $details);
+        $order->details_json = json_encode($details_json);
         $order->quantity = $quantity;
         $order->total_ht = $total;
+        $order->printed = 0;
         $order->save();
 
+        $cli = new CommandLine('node');
+        $cli->setSudo(true);
+        $cli->setArg(null, resource_path('js/printpageaspdf.cjs'));
+        $cli->setArg('url', url('/order/' . $order->id));
+        $cli->setArg('output', storage_path('orders/' . $order->id . '.pdf'));
+        $cli->execute();
+
+        $order->printed = 1;
+        $order->saveQuietly();
+
         $user->notify(new ResahNotification(ResahNotification::QUOTE_REQUEST_SENT, $order));
         User::withoutGlobalScopes()->find(3)->notify(new ResahNotification(ResahNotification::QUOTE_REQUEST, $order));
 
index 508acefce97e58a349adf5903513ea5641f1809f..53765a1275bb78e6b7fad9b5825553880b48db48 100644 (file)
@@ -3,6 +3,8 @@
 namespace App\Models;
 
 use Cubist\Backpack\Magic\Fields\Date;
+use Cubist\Backpack\Magic\Fields\Datetime;
+use Cubist\Backpack\Magic\Fields\Hidden;
 use Cubist\Backpack\Magic\Fields\Integer;
 use Cubist\Backpack\Magic\Fields\Number;
 use Cubist\Backpack\Magic\Fields\SelectFromModel;
@@ -27,8 +29,10 @@ class Order extends CubistMagicAbstractModel
 
         $this->addField('client', SelectFromModel::class, 'Client', ['optionsmodel' => Client::class, "column" => true, 'column_attribute' => 'hospital']);
         $this->addField('details', Textarea::class, 'Détails');
+        $this->addField('details_json', Hidden::class);
         $this->addField('quantity', Integer::class, 'Nombre de produits', ['column' => true]);
         $this->addField('total_ht', Number::class, 'Total HT', ['column' => true]);
-        $this->addField('created_at', Date::class, 'Date', ['column' => true]);
+        $this->addField('created_at', Datetime::class, 'Date', ['column' => true]);
+        $this->addField('printed', Hidden::class, '');
     }
 }
index 85980156f1f8bb889610d60bfc3066f44ce326d4..ce1cbbbfd4b046fe80fbba6de8d6b63050b0a345 100644 (file)
@@ -65,11 +65,11 @@ class ResahNotification extends Notification
             $subject = 'Demande de devis';
             $url = backpack_url('/order/' . $this->data->id . '/edit');
             $html = 'Une nouvelle demande de devis a été envoyée.<br>Pour la visualiser, cliquez sur le lien suivant <a href="' . $url . '">' . $url . '</a>';
-            //$file = storage_path('orders/' . $this->data->id . '.pdf');
+            $file = storage_path('orders/' . $this->data->id . '.pdf');
         } else if ($this->type === self::QUOTE_REQUEST_SENT) {
             $subject = 'Votre demande de devis sur Bastide-resah.fr';
             $html = 'Votre demande de devis est en cours de traitement (récapitulatif en pièce jointe). Vous recevrez le devis par email directement par les équipes Resah.<br><br>Nous restons à votre disposition pour toutes demandes de renseignements complémentaires que vous souhaiteriez.<br>Nous vous remercions pour votre compréhension.';
-            //$file = storage_path('orders/' . $this->data->id . '.pdf');
+            $file = storage_path('orders/' . $this->data->id . '.pdf');
         } else if ($this->type === self::FORGOT_PASSWORD) {
             $url = url('/landing/resetpassword/' . $this->data['email'] . '/' . $this->data['token']);
             $subject = 'Réinitialisation de votre mot de passe';
@@ -78,6 +78,7 @@ class ResahNotification extends Notification
 
 
         $m = (new MailMessage);
+        $m->bcc(env('MAIL_BCC_ALL'));
         $m->subject($subjectPrefix . $subject);
         $m->greeting($greetings);
         if ($html) {
index 56f5ddcc5b4ba520f0a26d41e2b13feb0831270e..51f07740646577ef22db0bd710256ac4e1f52443 100644 (file)
@@ -9,5 +9,10 @@
         "axios": "^1.6.4",
         "laravel-vite-plugin": "^1.0.0",
         "vite": "^5.0.0"
+    },
+    "dependencies": {
+        "command-line-args": "^5.2.1",
+        "fs": "^0.0.1-security",
+        "pupeteer": "^0.0.1"
     }
 }
diff --git a/resources/js/printpageaspdf.cjs b/resources/js/printpageaspdf.cjs
new file mode 100644 (file)
index 0000000..33f74b0
--- /dev/null
@@ -0,0 +1,44 @@
+const puppeteer = require('puppeteer');
+const commandLineArgs = require('command-line-args');
+const optionDefinitions = [
+    {name: 'url', type: String},
+    {name: 'output', type: String},
+];
+
+
+async function exportWebsiteAsPdf(url, outputPath) {
+    // Create a browser instance
+    const browser = await puppeteer.launch({
+        headless: 'new',
+        args: [
+            '--no-sandbox',
+            '--disable-setuid-sandbox'
+        ]
+    });
+
+    // Create a new page
+    const page = await browser.newPage();
+    // Open URL in current page
+
+    await page.goto(url, { waitUntil: 'networkidle0' });
+
+    // Download the PDF
+    const PDF = await page.pdf({
+        path: outputPath,
+        margin: { top: '100px', right: '50px', bottom: '100px', left: '50px' },
+        printBackground: true,
+        format: 'A4',
+    });
+    // Close the browser instance
+    await browser.close();
+    return PDF;
+}
+
+(async () => {
+    const options = commandLineArgs(optionDefinitions);
+    await exportWebsiteAsPdf(options.url, options.output).then(() => {
+        console.log('PDF created successfully.');
+    }).catch((error) => {
+        console.error('Error creating PDF:', error);
+    });
+})();
diff --git a/resources/views/order.blade.php b/resources/views/order.blade.php
new file mode 100644 (file)
index 0000000..f026b9e
--- /dev/null
@@ -0,0 +1,77 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+    <meta charset="utf-8">
+    <meta http-equiv="X-UA-Compatible" content="IE=edge">
+    <meta name="viewport" content="width=device-width, initial-scale=1">
+
+    <title></title>
+
+    <!-- Fonts -->
+    <link href="https://fonts.googleapis.com/css2?family=Source+Sans+3:ital,wght@0,200..900;1,200..900&display=swap" rel="stylesheet" type="text/css">
+
+    <!-- Styles -->
+    <style>
+        @media print {
+            @page {
+                size: A4 landscape;
+                margin: 1cm;
+            }
+        }
+        html, body {
+            background-color: #fff;
+            color: #000000;
+            font-family: 'Source Sans 3', sans-serif;
+            font-weight: 400;
+            margin: 0;
+            font-size: 3mm;
+        }
+
+        main {
+        }
+
+        table{
+            width: 100%;
+            margin-top: 30px;
+        }
+
+        td, th{
+            text-align: left;
+        }
+    </style>
+</head>
+<body>
+<main>
+    <div style="position: absolute;top:0;right:0"><img style="width: 3cm" src="/images/logo-bastide.svg"></div>
+    <div>
+        <h3>Demande # {{$order->id}} effectuée le {{(new DateTime($order->created_at))->setTimezone(new DateTimeZone('Europe/Paris'))->format('d/m/y à H:i')}}</h3>
+        {{$client->firstname}} {{$client->name}}<br>
+        {{$client->hospital}}<br><br>
+        Numéro FINESS : <b>{{$client->finess}}</b><br>
+        E-mail : <b>{{$client->email}}</b><br>
+        Téléphone : <b>{{$client->phone}}</b>
+    </div>
+    <table>
+        <tr>
+            @foreach($details->titles as $title)
+                <th>{{$title}}</th>
+            @endforeach
+        </tr>
+        @foreach($details->lines as $line)
+            <tr>
+                @foreach($line as $cell)
+                    <td>{{$cell}}</td>
+                @endforeach
+            </tr>
+        @endforeach
+        <tr><td style="height:30px;border-bottom: 1px solid #000" colspan="{{count($details->titles)}}"></td></tr>
+        <tr><td style="height:30px;" colspan="{{count($details->titles)}}"></td></tr>
+        @foreach($details->totals as $k=>$v)
+            <tr>
+                <td colspan="{{count($details->titles)-2}}"></td><td>{{$k}}</td><td><b>{{$v}}</b></td>
+            </tr>
+        @endforeach
+    </table>
+</main>
+</body>
+</html>
index 748640a0483ff6a4fcd0c6e7c4d53292d107d956..9816f3de486ea1e31a0d9cbbdad6749d4bbb86d8 100644 (file)
@@ -1,5 +1,6 @@
 <?php
 
+use App\Http\Controllers\OrderController;
 use App\Http\Middleware\VerifyCsrfToken;
 use Illuminate\Support\Facades\Route;
 use Spatie\Honeypot\ProtectAgainstSpam;
@@ -10,15 +11,20 @@ Route::get('/catalogue_invite/{path?}', \App\Http\Controllers\CatalogController:
 
 Route::match(['post'], '/fluidbook/signin', \App\Http\Controllers\FluidbookController::class . '@signin')->withoutMiddleware([VerifyCsrfToken::class]);
 Route::match(['post'], '/fluidbook/login', \App\Http\Controllers\FluidbookController::class . '@login')->withoutMiddleware([VerifyCsrfToken::class]);
-Route::match(['post','get'], '/fluidbook/forgotpassword', \App\Http\Controllers\FluidbookController::class . '@forgotPassword')->withoutMiddleware([VerifyCsrfToken::class]);
+Route::match(['post', 'get'], '/fluidbook/forgotpassword', \App\Http\Controllers\FluidbookController::class . '@forgotPassword')->withoutMiddleware([VerifyCsrfToken::class]);
 Route::match(['get'], '/fluidbook/auth', \App\Http\Controllers\FluidbookController::class . '@auth');
 Route::match(['post'], '/fluidbook/order', \App\Http\Controllers\FluidbookController::class . '@order')->withoutMiddleware([VerifyCsrfToken::class]);
 
 Route::match(['post'], '/landing/signin', \App\Http\Controllers\LandingController::class . '@signin')->middleware(ProtectAgainstSpam::class);;
 Route::match(['post'], '/landing/login', \App\Http\Controllers\LandingController::class . '@login');
-Route::match(['post','get'], '/landing/forgotpassword', \App\Http\Controllers\LandingController::class . '@forgotPassword');
+Route::match(['post', 'get'], '/landing/forgotpassword', \App\Http\Controllers\LandingController::class . '@forgotPassword');
 Route::match(['get'], '/landing/logout', \App\Http\Controllers\LandingController::class . '@logout');
 Route::match(['get'], '/landing/resetpassword/{email}/{token}', \App\Http\Controllers\LandingController::class . '@resetPassword');
 Route::match(['post'], '/landing/changepassword', \App\Http\Controllers\LandingController::class . '@changePassword');
 
+Route::match(['get'], '/order/{id}', function ($id) {
+    $order = \App\Models\Order::where('id', $id)->where('printed', 0)->first();
+    return view('order', ['order' => $order, 'client' => \App\Models\Client::find($order->client), 'details' => json_decode($order->details_json)]);
+});
+
 Route::get('/{path?}', \App\Http\Controllers\LandingController::class . '@catchall')->where('path', '.*');