100 lines
2.8 KiB
PHP
100 lines
2.8 KiB
PHP
<?php
|
|
|
|
namespace Modules\MasterData\Imports;
|
|
|
|
use Illuminate\Support\Collection;
|
|
use Illuminate\Support\Str;
|
|
use Maatwebsite\Excel\Concerns\ToCollection;
|
|
use Maatwebsite\Excel\Concerns\WithHeadingRow;
|
|
use Maatwebsite\Excel\Concerns\WithValidation;
|
|
use Maatwebsite\Excel\Concerns\SkipsOnFailure;
|
|
use Maatwebsite\Excel\Concerns\SkipsFailures;
|
|
use Modules\MasterData\Models\Material;
|
|
use Modules\MasterData\Models\MaterialGroup;
|
|
|
|
class MaterialImport implements ToCollection, WithHeadingRow, WithValidation, SkipsOnFailure
|
|
{
|
|
use SkipsFailures;
|
|
|
|
private int $importedCount = 0;
|
|
private int $skippedCount = 0;
|
|
private array $groupsCreated = [];
|
|
|
|
public function collection(Collection $rows): void
|
|
{
|
|
foreach ($rows as $row) {
|
|
// Skip completely empty rows
|
|
if (empty($row['name'])) {
|
|
continue;
|
|
}
|
|
|
|
$sku = $row['sku'] ?? null;
|
|
$name = $row['name'];
|
|
|
|
$matchAttributes = [];
|
|
if (!empty($sku)) {
|
|
$matchAttributes['sku'] = $sku;
|
|
} else {
|
|
$matchAttributes['name'] = $name;
|
|
}
|
|
|
|
$material = Material::updateOrCreate(
|
|
$matchAttributes,
|
|
[
|
|
'name' => $name,
|
|
'sku' => $sku,
|
|
'category' => $row['category'] ?? null,
|
|
'unit' => $row['unit'] ?? 'pcs',
|
|
'unit_cost' => $row['unit_cost'] ?? 0,
|
|
'description' => $row['description'] ?? null,
|
|
]
|
|
);
|
|
|
|
// Handle group assignment
|
|
$groupName = trim($row['group'] ?? '');
|
|
if ($groupName) {
|
|
$group = MaterialGroup::firstOrCreate(
|
|
['name' => $groupName],
|
|
['description' => "Auto-created from import"]
|
|
);
|
|
|
|
$group->materials()->syncWithoutDetaching([$material->id]);
|
|
|
|
if (!in_array($groupName, $this->groupsCreated)) {
|
|
$this->groupsCreated[] = $groupName;
|
|
}
|
|
}
|
|
|
|
$this->importedCount++;
|
|
}
|
|
}
|
|
|
|
public function rules(): array
|
|
{
|
|
return [
|
|
'name' => 'required|string|max:255',
|
|
'sku' => 'nullable|string|max:50',
|
|
'category' => 'nullable|string|max:50',
|
|
'unit' => 'nullable|string|max:20',
|
|
'unit_cost' => 'nullable|numeric|min:0',
|
|
'description' => 'nullable|string',
|
|
'group' => 'nullable|string|max:255',
|
|
];
|
|
}
|
|
|
|
public function getImportedCount(): int
|
|
{
|
|
return $this->importedCount;
|
|
}
|
|
|
|
public function getSkippedCount(): int
|
|
{
|
|
return $this->skippedCount;
|
|
}
|
|
|
|
public function getGroupsCreated(): array
|
|
{
|
|
return $this->groupsCreated;
|
|
}
|
|
}
|