EV3-357 Árlista feltöltés és feldolgzás újra gondolása phase4 fejléc adatok akciós lehetőség bővítése
This commit is contained in:
parent
e49b7515e0
commit
a30aa2dd51
@ -106,6 +106,7 @@ public function getExcelFieldPointer(): array
|
|||||||
19 => 'Vevői megnevezés',
|
19 => 'Vevői megnevezés',
|
||||||
20 => 'Megjegyzés',
|
20 => 'Megjegyzés',
|
||||||
21 => 'KREL',
|
21 => 'KREL',
|
||||||
|
22 => 'Akció',
|
||||||
];
|
];
|
||||||
|
|
||||||
private array $excelFieldPointer = [
|
private array $excelFieldPointer = [
|
||||||
@ -131,6 +132,7 @@ public function getExcelFieldPointer(): array
|
|||||||
'buyerProductName' => 19,
|
'buyerProductName' => 19,
|
||||||
'note' => 20,
|
'note' => 20,
|
||||||
'krel' => 21,
|
'krel' => 21,
|
||||||
|
'specialOffer' => 22,
|
||||||
|
|
||||||
];
|
];
|
||||||
|
|
||||||
@ -157,6 +159,7 @@ public function getExcelFieldPointer(): array
|
|||||||
'buyerProductName' => ['string'], // 19
|
'buyerProductName' => ['string'], // 19
|
||||||
'note' => ['string'], // 20
|
'note' => ['string'], // 20
|
||||||
'krel' => ['string'], // 21
|
'krel' => ['string'], // 21
|
||||||
|
'specialOffer' => ['string'], // 22
|
||||||
];
|
];
|
||||||
|
|
||||||
private array $excelFieldConverter = [
|
private array $excelFieldConverter = [
|
||||||
@ -165,6 +168,7 @@ public function getExcelFieldPointer(): array
|
|||||||
'vat' => ['percentage'],
|
'vat' => ['percentage'],
|
||||||
'note' => ['null'],
|
'note' => ['null'],
|
||||||
'krel' => ['booleanCustom'],
|
'krel' => ['booleanCustom'],
|
||||||
|
'specialOffer' => ['booleanCustom'],
|
||||||
'hooreycaId' => ['null'],
|
'hooreycaId' => ['null'],
|
||||||
'HooreycaUnit' => ['null'],
|
'HooreycaUnit' => ['null'],
|
||||||
'HooreycaMultiplier' => ['null'],
|
'HooreycaMultiplier' => ['null'],
|
||||||
|
|||||||
@ -187,6 +187,15 @@ public function updateStepStatus(
|
|||||||
private const HEADER_ROW = 3;
|
private const HEADER_ROW = 3;
|
||||||
private const DATA_START_ROW = 5;
|
private const DATA_START_ROW = 5;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Opcionális (visszafelé kompatibilis) oszlopfejlécek indexei.
|
||||||
|
* Ha egy ilyen oszlop hiányzik a 3. sorból, az nem blokkoló hiba, csak figyelmeztetés,
|
||||||
|
* és a hozzá tartozó feldolgozás (pl. akciós jelölés) kimarad.
|
||||||
|
*/
|
||||||
|
private const OPTIONAL_HEADER_INDEXES = [
|
||||||
|
22, // Akció (specialOffer)
|
||||||
|
];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Előfeldolgozás (Pre-processing) - Strukturális és technikai ellenőrzés
|
* Előfeldolgozás (Pre-processing) - Strukturális és technikai ellenőrzés
|
||||||
*
|
*
|
||||||
@ -384,6 +393,12 @@ private function buildColumnMap(Worksheet $worksheet): array
|
|||||||
if (isset($headerByName[$normalizedExpected])) {
|
if (isset($headerByName[$normalizedExpected])) {
|
||||||
$map[$index] = $headerByName[$normalizedExpected];
|
$map[$index] = $headerByName[$normalizedExpected];
|
||||||
$usedColumns[$headerByName[$normalizedExpected]] = true;
|
$usedColumns[$headerByName[$normalizedExpected]] = true;
|
||||||
|
} elseif (in_array($index, self::OPTIONAL_HEADER_INDEXES, true)) {
|
||||||
|
// Opcionális oszlop hiánya nem blokkoló, csak figyelmeztetés (visszafelé kompatibilitás)
|
||||||
|
$warnings[] = $this->buildWarning(
|
||||||
|
PreProcessErrorCode::COLUMN_MISSING,
|
||||||
|
"Hiányzó opcionális oszlopfejléc: '{$expectedLabel}' (a " . self::HEADER_ROW . ". sorban nem található); a feldolgozás e nélkül folytatódik."
|
||||||
|
);
|
||||||
} else {
|
} else {
|
||||||
// Hiányzó kötelező fejléc: blokkoló hiba
|
// Hiányzó kötelező fejléc: blokkoló hiba
|
||||||
$errors[] = $this->buildError(
|
$errors[] = $this->buildError(
|
||||||
@ -626,7 +641,9 @@ public function validate(PricelistFile $pricelistFile): bool
|
|||||||
PricelistFileLine::insert($dataToInsert);
|
PricelistFileLine::insert($dataToInsert);
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->runBusinessValidation($pricelistFile);
|
// Az "Akció" (specialOffer) opcionális oszlop: csak akkor kezeljük, ha ténylegesen szerepel a fájlban
|
||||||
|
$hasSpecialOfferColumn = isset($columnMap[22]);
|
||||||
|
$this->runBusinessValidation($pricelistFile, $hasSpecialOfferColumn);
|
||||||
|
|
||||||
$duration = round(microtime(true) - $startTime, 2);
|
$duration = round(microtime(true) - $startTime, 2);
|
||||||
|
|
||||||
@ -897,7 +914,7 @@ protected function validateProducer(array $payload, array $producerLookup): ?str
|
|||||||
*
|
*
|
||||||
* @param PricelistFile $pricelistFile
|
* @param PricelistFile $pricelistFile
|
||||||
*/
|
*/
|
||||||
protected function runBusinessValidation(PricelistFile $pricelistFile): void
|
protected function runBusinessValidation(PricelistFile $pricelistFile, bool $hasSpecialOfferColumn = false): void
|
||||||
{
|
{
|
||||||
$this->updateStepStatus($pricelistFile, PricelistWorkflowStep::Validation, 'inprogress', 'Üzleti validálás...', 100);
|
$this->updateStepStatus($pricelistFile, PricelistWorkflowStep::Validation, 'inprogress', 'Üzleti validálás...', 100);
|
||||||
|
|
||||||
@ -908,7 +925,7 @@ protected function runBusinessValidation(PricelistFile $pricelistFile): void
|
|||||||
$producerIdToName = $this->getProducerIdMap();
|
$producerIdToName = $this->getProducerIdMap();
|
||||||
$groupIdToPath = $this->getProductGroupIdMap();
|
$groupIdToPath = $this->getProductGroupIdMap();
|
||||||
|
|
||||||
$pricelistFile->lines()->chunk(1000, function ($lines) use ($groupLookup, $producerLookup, $productLookup, $producerIdToName, $groupIdToPath) {
|
$pricelistFile->lines()->chunk(1000, function ($lines) use ($groupLookup, $producerLookup, $productLookup, $producerIdToName, $groupIdToPath, $hasSpecialOfferColumn) {
|
||||||
$updates = [];
|
$updates = [];
|
||||||
|
|
||||||
foreach ($lines as $line) {
|
foreach ($lines as $line) {
|
||||||
@ -1116,6 +1133,25 @@ protected function runBusinessValidation(PricelistFile $pricelistFile): void
|
|||||||
];
|
];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 5. Akciós (specialOffer) módosulás - csak ha az "Akció" oszlop szerepel a fájlban.
|
||||||
|
// booleanCustom logika: üres érték => false, bármilyen más érték => true.
|
||||||
|
if ($hasSpecialOfferColumn) {
|
||||||
|
$specialOfferRaw = $payload[PriceListService::EXPECTED_HEADERS[22]] ?? null;
|
||||||
|
$newSpecialOffer = strlen(trim((string)$specialOfferRaw)) > 0;
|
||||||
|
$oldSpecialOffer = (bool)($existingProduct['specialOffer'] ?? false);
|
||||||
|
|
||||||
|
if ($newSpecialOffer !== $oldSpecialOffer) {
|
||||||
|
$isUpdated = true;
|
||||||
|
$diff['specialOffer'] = [
|
||||||
|
'old' => (int)$oldSpecialOffer,
|
||||||
|
'new' => (int)$newSpecialOffer,
|
||||||
|
'old_label' => $oldSpecialOffer ? 'Akciós' : 'Nem akciós',
|
||||||
|
'new_label' => $newSpecialOffer ? 'Akciós' : 'Nem akciós',
|
||||||
|
'label' => PriceListService::EXPECTED_HEADERS[22],
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$updates[] = [
|
$updates[] = [
|
||||||
|
|||||||
@ -121,7 +121,7 @@
|
|||||||
'icon' => 'price_list',
|
'icon' => 'price_list',
|
||||||
'link' => '/admin/pricelist-files',
|
'link' => '/admin/pricelist-files',
|
||||||
'noAjax' => true,
|
'noAjax' => true,
|
||||||
'roles' => ['developer'],
|
'roles' => ['developer','admin'],
|
||||||
],
|
],
|
||||||
'delivery' => [
|
'delivery' => [
|
||||||
'name' => 'delivery',
|
'name' => 'delivery',
|
||||||
|
|||||||
@ -81,6 +81,41 @@ function makeWorksheetWithHeaderOrder(array $order): Worksheet
|
|||||||
expect($result['map'])->toHaveCount(count($expected));
|
expect($result['map'])->toHaveCount(count($expected));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('a hiányzó opcionális "Akció" oszlop csak figyelmeztetést ad, nem blokkol', function () {
|
||||||
|
$expected = PriceListService::EXPECTED_HEADERS;
|
||||||
|
|
||||||
|
$worksheet = (new Spreadsheet())->getActiveSheet();
|
||||||
|
$col = 1;
|
||||||
|
foreach ($expected as $fieldIndex => $label) {
|
||||||
|
if ($fieldIndex === 22) {
|
||||||
|
// Az "Akció" oszlopot szándékosan kihagyjuk (visszafelé kompatibilis fájl)
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
$worksheet->setCellValueByColumnAndRow($col, 3, $label);
|
||||||
|
$col++;
|
||||||
|
}
|
||||||
|
|
||||||
|
$result = invokeBuildColumnMap($worksheet);
|
||||||
|
|
||||||
|
$hasBlocker = collect($result['errors'])->contains(fn ($error) => ($error['severity'] ?? '') === 'blocker');
|
||||||
|
expect($hasBlocker)->toBeFalse();
|
||||||
|
expect($result['map'])->not->toHaveKey(22);
|
||||||
|
expect(collect($result['warnings']))->not->toBeEmpty();
|
||||||
|
});
|
||||||
|
|
||||||
|
test('a jelen lévő "Akció" oszlop leképeződik', function () {
|
||||||
|
$expected = PriceListService::EXPECTED_HEADERS;
|
||||||
|
|
||||||
|
$worksheet = makeWorksheetWithHeaderOrder(array_keys($expected));
|
||||||
|
$result = invokeBuildColumnMap($worksheet);
|
||||||
|
|
||||||
|
expect($result['errors'])->toBe([]);
|
||||||
|
expect($result['map'])->toHaveKey(22);
|
||||||
|
|
||||||
|
$value = $worksheet->getCellByColumnAndRow($result['map'][22], 5)->getValue();
|
||||||
|
expect($value)->toBe('VAL_22');
|
||||||
|
});
|
||||||
|
|
||||||
test('hiányzó kötelező fejléc blokkoló hibát ad', function () {
|
test('hiányzó kötelező fejléc blokkoló hibát ad', function () {
|
||||||
$expected = PriceListService::EXPECTED_HEADERS;
|
$expected = PriceListService::EXPECTED_HEADERS;
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user