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"]
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;
$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') {
$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'];
$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));
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;
$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, '');
}
}
$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';
$m = (new MailMessage);
+ $m->bcc(env('MAIL_BCC_ALL'));
$m->subject($subjectPrefix . $subject);
$m->greeting($greetings);
if ($html) {
"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"
}
}
--- /dev/null
+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);
+ });
+})();
--- /dev/null
+<!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>
<?php
+use App\Http\Controllers\OrderController;
use App\Http\Middleware\VerifyCsrfToken;
use Illuminate\Support\Facades\Route;
use Spatie\Honeypot\ProtectAgainstSpam;
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', '.*');