ldc-portsalaries/app/Imports/PlanningImport.php
2021-06-07 18:28:25 +02:00

139 lines
4.9 KiB
PHP

<?php
namespace App\Imports;
use App\Models\Employee;
use App\Models\Planning as ModelsPlanning;
use App\Models\Site;
use Illuminate\Support\Carbon;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Validator;
use Maatwebsite\Excel\Concerns\ToCollection;
use Maatwebsite\Excel\Concerns\Importable;
use Maatwebsite\Excel\Concerns\WithHeadingRow;
class PlanningImport implements ToCollection, WithHeadingRow
{
use Importable;
/** @var \App\Models\Site */
private $site;
/** @var string */
private $title;
public $importedCount = 0;
public $importedFailed = [];
public function __construct(Site $site, array $headers)
{
$this->site = $site;
$this->title = implode(collect($headers)->flatten()->all());
}
public function collection(Collection $rows)
{
$dates = null;
$planningLines = [];
$k = -1;
foreach ($rows as $row) {
// concatenate all merged rows where 'nom_prenom' is null
if (!is_null($row['nom_prenom'])) {
$planningLines[++$k] = $row;
} else {
$planningLines[$k] = $planningLines[$k]->map(function ($item, $key) use ($row) {
// ignore empty row titles
if (!strlen($key)) {
return false;
}
$d = $row->get($key);
if ($d and is_string($d) and strlen($d)) {
$item = strlen($item) ? sprintf('%s \n %s', $item, $d) : $d;
}
return $item;
})->reject(function ($value) {
return $value === false;
});
}
}
$planningLines = collect($planningLines);
// Get Start and End dates
$keys = collect(array_keys($planningLines->first()->all()));
$startDate = collect(explode('_', $keys->get(1)));
$endDate = collect(explode('_', $keys->last()));
$validator = Validator::make([
'startDay' => $startDate->first(),
'start' => Carbon::createFromFormat('dmY', $startDate->last()),
'endDay' => $endDate->first(),
'end' => Carbon::createFromFormat('dmY', $endDate->last()),
], [
'startDay' => 'required|in:lundi,mardi,mercredi,jeudi,vendredi,samedi,dimanche',
'start' => 'required|date',
'endDay' => 'required|in:lundi,mardi,mercredi,jeudi,vendredi,samedi,dimanche',
'end' => 'required|date',
]);
$validator->validate();
$dates = (object)$validator->validated();
/**
* Non mais bordel, déjà parser un xsls c'est de la merde
* mais en plus de pas fournir de clé et en plus ne pas séparer
* le nom et prénom, c'est vraiment WTF
*/
foreach ($planningLines as $line) {
// Try to find employee with "nom_prenom", pfff
$np = trim(preg_replace('/SST$/', '', $line['nom_prenom']));
$ns = explode(' ', $np);
$firstName = '';
$lastName = '';
$employee = null;
do {
$lastName = strlen($lastName) ?
sprintf('%s %s', $lastName, \array_shift($ns)) : \array_shift($ns);
$firstName = trim(implode(' ', $ns));
$employee = Employee::where('site_id', $this->site->id)
->whereRaw("UPPER(`lastname`) = '" . strtoupper($lastName) . "'")
->whereRaw("UPPER(`firstname`) = '" . strtoupper($firstName) . "'")
->get();
// phpcs:ignore Squiz.PHP.DisallowSizeFunctionsInLoops.Found
} while (strlen($firstName) and !count($employee) and count($ns) > 1);
if (!count($employee)) {
$this->importedFailed[] = $line;
Log::debug(sprintf('Planning Import, skipped (Employee not found) %s', $line->implode(' | ')));
continue;
}
$line->forget('nom_prenom');
$this->parsePlanningData($line);
// Get existing planning using start date or create a new one
$planning = ModelsPlanning::whereDate('start', $dates->start->format('Y/m/d'))
->where('employee_id', $employee->first()->id)->firstOrNew();
$planning->fill([
'start' => $dates->start,
'end' => $dates->end,
'data' => $line->all()
]);
$planning->employee_id = $employee->first()->id;
$planning->saveOrFail();
$this->importedCount += 1;
}
}
private function parsePlanningData(Collection &$data)
{
$data = $data->mapWithKeys(function ($day, $key) {
$key = substr($key, strpos($key, '_') + 1);
return ["$key" => $day];
});
}
public function headingRow(): int
{
return 2;
}
}