Merge branch 'develop' into trunk

This commit is contained in:
Jérémy Munsch 2023-09-11 11:52:29 +02:00
commit 93db102d7b
No known key found for this signature in database
GPG key ID: 18361AF3BFEC0FEC
5 changed files with 126 additions and 30 deletions

View file

@ -28,7 +28,6 @@ class ProductController extends Controller
*/
public function index(IndexFilterRequest $request)
{
// DB::enableQueryLog();
/** @var \Illuminate\Database\Eloquent\Builder $brands */
$brandsQuery = Brand::query();
@ -40,7 +39,6 @@ class ProductController extends Controller
$this->sortQuery($productsQuery);
$products = $this->paginate($productsQuery);
// dd(DB::getQueryLog(), $products->items());
/** @var array $printMultiProduct Array of id */
$printMultiProduct = session('printMultiProduct') ?? [];
@ -320,6 +318,7 @@ class ProductController extends Controller
*/
public function printMultiProductSheet()
{
// FIXME: This should not use session.
/** @var array printMultiProduct */
$printMultiProduct = session('printMultiProduct') ?? [];
asort($printMultiProduct);

View file

@ -6,6 +6,7 @@ use App\Enums\Products\ClaimEnum;
use App\Enums\Products\OriginEnum;
use App\Models\Keyword;
use App\Models\Product;
use App\Models\ProductComment;
use Illuminate\Http\Resources\Json\JsonResource;
class ProductResource extends JsonResource
@ -87,7 +88,13 @@ class ProductResource extends JsonResource
'product_range' => $this->product->product_range->label(),
'geo_area' => $this->product->geo_area->label(),
'freeComment' => $this->product->comment,
'productComments' => $this->product->productComments,
// FIXME: Use dedicaced resources for relations.
'productComments' => $this->product->productComments->map(function (ProductComment $comment) {
return (object)\array_merge($comment->toArray(), [
'created_at' => $comment->created_at->isoFormat('DD\/MM\/YYYY'),
'updated_at' => $comment->updated_at->isoFormat('DD\/MM\/YYYY'),
]);
}),
'productKeywords' => $this->product->productKeywords
->map(fn (Keyword $keyword) => $keyword->label)
->implode(', '),

View file

@ -319,14 +319,14 @@ class Product extends Model
// * 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' => (object)(new ProductResource($product))->toArray()],
));
}
// * 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;
}

View file

@ -13,9 +13,12 @@ use App\Lib\Helpers\FileStorageHelper;
use App\Models\Brand;
use App\Models\Keyword;
use App\Models\Product;
use App\Models\ProductComment;
use App\Models\User;
use Carbon\Carbon;
use Illuminate\Console\OutputStyle;
use Illuminate\Contracts\Database\Query\Builder;
use Illuminate\Database\Eloquent\ModelNotFoundException;
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\QueryException;
use Illuminate\Database\Schema\Blueprint;
@ -24,8 +27,10 @@ use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\File;
use Illuminate\Support\Facades\Schema;
use Illuminate\Support\Facades\Storage;
use Illuminate\Support\ItemNotFoundException;
use Illuminate\Support\Str;
use Symfony\Component\Console\Helper\ProgressBar;
use Symfony\Component\Console\Input\ArgvInput;
use Symfony\Component\Console\Output\ConsoleOutput;
return new class extends Migration
@ -49,6 +54,12 @@ return new class extends Migration
'VEILLE_PROD', 'VEILLE_PROD_COMM',
];
/**
* Console tabulation (margin left)
* @var integer
*/
private $consoleTabulation = 28;
/** @var \App\Models\User */
private $dummyUser;
@ -63,10 +74,14 @@ return new class extends Migration
*/
public function up(): void
{
// ! DEV: Uncomment this to skip the migration
// return;
$console = new ConsoleOutput();
$section = $console->section();
$ouput = new ConsoleOutput();
$input = new ArgvInput();
$style = new OutputStyle($input, $ouput);
$section = $ouput->section();
if (!$style->confirm('Do this migration or skip ?', false)) {
return;
}
// * SEED KEYWORDS As they are needed on runtime.
Schema::disableForeignKeyConstraints();
@ -74,6 +89,7 @@ return new class extends Migration
DB::table('keywordables')->truncate();
DB::table('keywords')->truncate();
DB::table('products')->truncate();
DB::table('product_comments')->truncate();
// * Remove previously uploaded files.
File::deleteDirectory(storage_path('app/public/modelfiles/products'));
Schema::enableForeignKeyConstraints();
@ -99,15 +115,16 @@ return new class extends Migration
$this->fixForeignKeyActionOnProcesses();
// ! DEV: Comment this after running once, to develop a migration without remigrating every temp table.
// $this->createAndFillTempTables();
$this->createAndFillTempTables();
// * Migrate PRODUCTS, comment all except the one you want to develop here.
$this->migrateBrands();
$this->migrateProducts();
// ! DEV: Add a die here to develop migration and prevent droping temp tables
// dd('');
$this->migrateBrands($style);
$this->migrateProducts($style);
$this->migrateProductsComments($style);
if (!$style->confirm('Continue ?')) {
throw new \RuntimeException('Migration stoped');
}
$this->dropTempTables();
$section->clear();
}
@ -126,21 +143,91 @@ return new class extends Migration
// - MIGRATION METHODS -
/**
* Migrate products
*
* Migrate products comments
*
* @param \Illuminate\Console\OutputStyle $style
* @return void
* @throws \Error In case of failure.
* @phpcs:disable Generic.Metrics.CyclomaticComplexity.MaxExceeded
* @phpcs:disable Generic.CodeAnalysis.UnusedFunctionParameter.Found
*/
private function migrateProducts(): void
private function migrateProductsComments(OutputStyle $style): void
{
// phpcs:enable
$index = "NUM_COMM";
$query = $this->getQuery("VEILLE_PROD_COMM")->orderBy($index);
$nbRowsToMigrate = (clone $query)->count();
$totalRowsToMigrate = $nbRowsToMigrate;
$console = new ConsoleOutput();
$console->writeln('');
$progress = new ProgressBar($console, $nbRowsToMigrate);
$progress->setMessage(str_pad('Migrate Products Comments', $this->consoleTabulation, ' '));
$progress->setFormat(' - %message% [%bar%] %percent:3s%% %current%/%max% %elapsed:6s%/%estimated:-6s%');
$skipped = collect();
while ($nbRowsToMigrate > 0) {
$progress->display();
$progress->advance(1);
$row = (clone $query)->skip($totalRowsToMigrate - $nbRowsToMigrate--)->limit(1)->first();
try {
/** @var \App\Models\ProductComment $comment */
$comment = ProductComment::query()->where('id', $row->{$index})->firstOrNew();
$comment->id = $row->NUM_COMM;
/** @var \App\Models\Product $product */
$product = Product::query()->where('id', $row->NUM_PROD)->firstOrFail();
$product->id = $row->NUM_PROD;
$date_saisie = $row->DATE_SAISIE ? $this->tryToParseCarbon($row->DATE_SAISIE, true) : null;
$fill = [
'product_id' => $product->id,
'evaluation' => $row->APPRECIATION ?? '',
'aspect' => $row->ASPECT,
'taste' => $row->GOUT,
'odor' => $row->ODEUR,
'texture' => $row->TEXTURE,
];
if ($date_saisie) {
// ? FIXME: IS this pertinent ?
$fill['created_at'] = $date_saisie;
$fill['updated_at'] = $date_saisie;
}
$comment->fill($fill);
if (!DB::transaction(fn () => $comment->saveQuietly())) {
throw new \Error("Failed to save comment {$row->NUM_COMM}");
}
} catch (ModelNotFoundException $e) {
$model = $e->getModel();
$skipped->push("No {$model} found for '{$row->NUM_PROD}', skip comment '{$row->NUM_COMM}'");
} //end try
} //end while
$progress->finish();
if ($skipped->count() and !$console->writeln('') and $style->confirm('Show errors ?', false)) {
$console->writeln('');
$skipped->each(fn (string $error) => $console->writeln(str_repeat(' ', 8) . $error));
}
}
/**
* Migrate products
*
*
* @param \Illuminate\Console\OutputStyle $style
* @return void
* @throws \Error In case of failure.
* @phpcs:disable Generic.Metrics.CyclomaticComplexity.MaxExceeded
* @phpcs:disable Generic.CodeAnalysis.UnusedFunctionParameter.Found
*/
private function migrateProducts(OutputStyle $style): void
{
// phpcs:enable
$otherAllegations = Str::of(File::get(base_path('database/migrations/other_allegations.txt')))
->explode(PHP_EOL)->map(fn (string $other_allegation) => Str::of($other_allegation)->squish())
->unique();
$MOTKS = Keyword::all();
$MOTKS = Keyword::query()->where('keyword_cat', 'LIKE', 'product_%')->get();
/** @var \Illuminate\Support\Collection<string,string> */
$START_SOURCES = $this->getQuery('SOURCE')->get();
/** @var \Illuminate\Support\Collection<string,string> */
@ -169,7 +256,7 @@ return new class extends Migration
$console = new ConsoleOutput();
$console->writeln('');
$progress = new ProgressBar($console, $nbRowsToMigrate);
$progress->setMessage(str_pad('Migrate Products', 24, ' '));
$progress->setMessage(str_pad('Migrate Products', $this->consoleTabulation, ' '));
$progress->setFormat(' - %message% [%bar%] %percent:3s%% %current%/%max% %elapsed:6s%/%estimated:-6s%');
while ($nbRowsToMigrate > 0) {
@ -239,7 +326,7 @@ return new class extends Migration
fn (Keyword $keyword) => Str::of($keyword->label)->ascii()->replace(' ', '')
== Str::of($motk)->trim()->ascii()->replace(' ', '')
);
} catch (\Exception) {
} catch (ItemNotFoundException) {
dump(
$motk,
$MOTKS->pluck('label')
@ -406,10 +493,13 @@ return new class extends Migration
/**
* Create unique brands using veille products
*
* @param \Illuminate\Console\OutputStyle $style
* @return void
* @phpcs:disable Generic.CodeAnalysis.UnusedFunctionParameter.Found
*/
private function migrateBrands(): void
private function migrateBrands(OutputStyle $style): void
{
// phpcs:enable
$query = $this->getQuery("VEILLE_PROD");
/** @var \Illuminate\Support\Collection<string,string> */
$brands = (clone $query)->pluck('MARQUE')->filter()
@ -417,7 +507,7 @@ return new class extends Migration
$console = new ConsoleOutput();
$console->writeln('');
$progress = new ProgressBar($console, $brands->count());
$progress->setMessage(str_pad('Migrate Brands', 24, ' '));
$progress->setMessage(str_pad('Migrate Brands', $this->consoleTabulation, ' '));
$progress->setFormat(' - %message% [%bar%] %percent:3s%% %current%/%max% %elapsed:6s%/%estimated:-6s%');
// FIXME: Insert brand->filter and find from where it should be fetched.
$brands->each(function ($brandName) use ($progress) {
@ -615,7 +705,7 @@ return new class extends Migration
$this->getTableName($tableName),
$header
);
$message = str_pad("{$this->tablePrefix} {$tableName}", 24, ' ');
$message = str_pad("{$this->tablePrefix} {$tableName}", $this->consoleTabulation, ' ');
$section->write(" - {$message} -> Fetching OCI DATA..");
$content = $this->fetchOciTableContent($tableName, $header);
$section->clear();

View file

@ -71,7 +71,7 @@
<p><strong>{{ __('Commentaire libre : ') }}</strong>{{ strip_tags($product->freeComment) }}</p>
@endif
@foreach ($product->productComments as $productComment)
<p><strong>{{ __('Commentaire dégustation du : ') }}</strong>{{ $productComment->created_at->isoFormat('DD\/MM\/YYYY') }}</p>
<p><strong>{{ __('Commentaire dégustation du : ') }}</strong>{{ $productComment->created_at }}</p>
<table class="table" width="100%">
<tr class="table-header">
<td class="table-cell-text-center" width="20%"><strong>{{ __('Appréciation') }}</strong></td>