ldc-boutique-cnc-sable/infra/Adapters/Services/EloquentEmployeeImportStorageService.php
Jérémy Munsch 8b96ce90be
test(casts): add tests for EmployeeSitesCast functionality
test(casts): add tests for ShopperEstablishmentCodeCast functionality

test(casts): add tests for ShopperServiceCodeCast functionality

test(casts): add tests for ShopperSiteCodeCast functionality

test(dto): update ProductDtoTest to include additional fields

test(dto): update SettingDtoTest to remove arcadiaSites assertions

test(events): update AnOrderHasBeenPlacedTest to use value objects

test(entities): update OrderTest to use value objects for employee details

test(value-objects): update EmployeeUpsertDataTest to use value objects

test(pagination): update PaginationTest to access value properties

test(services): update AppCustomerAuthServiceTest to use CrmHashcode

test(services): update CrmServiceTest to use CrmHashcode for customer retrieval
2026-10-27 09:58:45 +01:00

78 lines
2.9 KiB
PHP

<?php
declare(strict_types=1);
namespace Infrastructure\Adapters\Services;
use App\Models\Employee;
use Carbon\CarbonImmutable;
use Domain\Models\ValueObjects\EmployeeUpsertData;
use Domain\Ports\Services\EmployeeImportStorageService;
class EloquentEmployeeImportStorageService implements EmployeeImportStorageService
{
/**
* @param list<EmployeeUpsertData> $upsertData
*/
public function upsertEmployees(array $upsertData): void
{
$now = CarbonImmutable::now()->format('Y-m-d H:i:s');
$mappedData = array_map(static function (EmployeeUpsertData $data) use ($now): array {
return [
'matricule' => $data->matricule->value,
'nom' => $data->lastname,
'prenom' => $data->firstname,
'etablissement' => $data->etablissement->value,
'service' => $data->service->value,
'site' => $data->site->value,
'start_date' => $data->startDate->format('Y-m-d H:i:s'),
'end_date' => $data->endDate?->format('Y-m-d H:i:s'),
'code' => $data->code->value,
'last_sync' => $now,
];
}, $upsertData);
// NOTE: chunking is essential here because the query builder has a binding limit of 65535
// each row has 10 bindings, so we can insert at most 65535 / 10 = 6553 rows at once
// we use 1000 to be safe
foreach (array_chunk($mappedData, 1000) as $chunk) {
Employee::query()->upsert(
values: $chunk,
uniqueBy: ['matricule'],
update: ['nom', 'prenom', 'etablissement', 'service', 'site', 'start_date', 'end_date', 'last_sync']
);
}
}
/**
* @param \Domain\Models\ValueObjects\Matricule[] $matriculesToInsert
* @return object{insertedCount: int, updatedCount: int, matriculesInserted: \Domain\Models\ValueObjects\Matricule[]}
*/
public function getImportedAfter(array $matriculesToInsert, CarbonImmutable $importStartTime): object
{
$employees = Employee::query()
->whereIn('matricule', $matriculesToInsert)
->get(['matricule', 'created_at', 'updated_at']);
/** @var list<\Domain\Models\ValueObjects\Matricule> $matriculesInserted */
$matriculesInserted = $employees
->pluck('matricule')
->values()
->toArray();
$insertedCount = $employees
->where('created_at', '>=', $importStartTime)
->count();
$updatedCount = $employees
->where('created_at', '<', $importStartTime)
->where('updated_at', '>=', $importStartTime)
->count();
return (object) [
'insertedCount' => $insertedCount,
'updatedCount' => $updatedCount,
'matriculesInserted' => $matriculesInserted,
];
}
}