Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature/wn 213 #191

Merged
merged 12 commits into from
Feb 28, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
130 changes: 130 additions & 0 deletions app/Classes/RcnApi/Importer/BulkUploadTemplateExport.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
<?php

namespace App\Classes\RcnApi\Importer;
use App\Models\EventType;
use Maatwebsite\Excel\Concerns\FromArray;
use Maatwebsite\Excel\Concerns\ShouldAutoSize;
use Maatwebsite\Excel\Concerns\WithEvents;
use Maatwebsite\Excel\Events\AfterSheet;
use Namshi\JOSE\Base64\Base64Encoder;
use PhpOffice\PhpSpreadsheet\Cell\DataValidation;
use PhpOffice\PhpSpreadsheet\Cell\Coordinate;
use PhpOffice\PhpSpreadsheet\Style\Fill;
use PhpOffice\PhpSpreadsheet\Style\Alignment;
use PhpOffice\PhpSpreadsheet\Style\Protection;
class BulkUploadTemplateExport implements FromArray, ShouldAutoSize, WithEvents
{
/**
* Constructor to initialize the export template
*/
private $nationalSociety;
private $region;
private $headings = [
'Title', 'Description', 'URL', 'Hazard', 'Urgency Level', 'Safety Message'
];
private $urgencyLevels = '"Immediate,Warning,Anticipated,Assess and Plan,Mitigate Risks,Prepare to Respond,Recover"';

private $eventTypesDropdown = [];

private $data;

public function __construct(string $nationalSociety, string $region,array $data, int $maxSupportingMessages)
{
$eventTypes = EventType::whereNotIn('code', ['other'])->get()->toArray();
$this->nationalSociety = $nationalSociety;
$this->eventTypesDropdown = '"' . implode(',', array_map(function ($event) {
return "{$event['name']}";
}, $eventTypes)) . '"';
$this->region = $region;
$this->data = $data;
for($i = 0; $i< $maxSupportingMessages; $i++){
$this->headings[] = 'Supporting Message ' . ($i + 1);
}

}


/**
* Define the data rows for the export
*/
public function array(): array
{
return array_merge(
[
['National Society', 'Region'],
[$this->nationalSociety, $this->region], // Row 1-2
$this->headings // Row 3
],
$this->data
);
}

/**
* Event to add dropdowns
*/
public function registerEvents(): array
{
return [
AfterSheet::class => function (AfterSheet $event) {
$sheet = $event->sheet->getDelegate();

$validationUrgency = $sheet->getCell('E4')->getDataValidation();
$validationUrgency->setType(DataValidation::TYPE_LIST);
$validationUrgency->setErrorStyle(DataValidation::STYLE_STOP);
$validationUrgency->setAllowBlank(false);
$validationUrgency->setShowInputMessage(true);
$validationUrgency->setShowErrorMessage(true);
$validationUrgency->setShowDropDown(true);
$validationUrgency->setFormula1($this->urgencyLevels);
$sheet->getCell('E4')->setDataValidation(clone $validationUrgency);

$validationEvent = $sheet->getCell('D4')->getDataValidation();
$validationEvent->setType(DataValidation::TYPE_LIST);
$validationEvent->setErrorStyle(DataValidation::STYLE_STOP);
$validationEvent->setAllowBlank(false);
$validationEvent->setShowInputMessage(true);
$validationEvent->setShowErrorMessage(true);
$validationEvent->setShowDropDown(true);
$validationEvent->setFormula1($this->eventTypesDropdown);
$sheet->getCell('D4')->setDataValidation(clone $validationEvent);


$maxColumnRow1 = Coordinate::stringFromColumnIndex(2);
$row1Range = 'A1:' . $maxColumnRow1 . '1';

$maxColumnRow3 = Coordinate::stringFromColumnIndex(count($this->headings));
$row3Range = 'A3:' . $maxColumnRow3 . '3';

$headerStyle = [
'font' => [
'bold' => true,
'color' => ['argb' => 'FFFFFFFF'],
],
'fill' => [
'fillType' => Fill::FILL_SOLID,
'startColor' => ['argb' => 'ff6b6b'],
],
'alignment' => [
'horizontal' => Alignment::HORIZONTAL_CENTER,
'vertical' => Alignment::VERTICAL_CENTER,
],
];

$sheet->getStyle($row1Range)->applyFromArray($headerStyle);
$sheet->getStyle($row3Range)->applyFromArray($headerStyle);

$protection = $sheet->getProtection();
$protection->setSheet(true);
$base = new Base64Encoder();
$protection->setPassword($base->encode('fsjsD-1FfJTZvs2X'));

$sheet->getStyle('A1:Z100')->getProtection()->setLocked(Protection::PROTECTION_UNPROTECTED);

$cellsToLock = ['A1', 'B1', 'A2', 'B2', 'A3:F3'];
foreach ($cellsToLock as $cell) {
$sheet->getStyle($cell)->getProtection()->setLocked(Protection::PROTECTION_PROTECTED);
}
}
];
}
}
123 changes: 123 additions & 0 deletions app/Classes/RcnApi/Importer/BulkUploadTemplateImport.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
<?php

namespace App\Classes\RcnApi\Importer;

use Illuminate\Support\Collection;
use Maatwebsite\Excel\Concerns\ToCollection;
use App\Classes\RcnApi\Importer\Exceptions\RcnImportException;
class BulkUploadTemplateImport implements ToCollection
{
private $data = [];

/**
* Process the imported data.
*
* @param ToCollection $rows
* @return array
* @throws RcnImportException
*/
public function collection(Collection $rows): array
{
$processedData = [
'nationalSociety' => null,
'region' => null,
'hazards' => []
];

$currentHazard = null;
$currentUrgencyLevel = null;
$firstRow = false;
foreach ($rows as $index => $row) {
if (!$firstRow || $index === 2) {
$firstRow = true;
continue;
};
if ($index === 1) {
if(!$row[0]){
throw new RcnImportException("Missing national society");
}
$processedData['nationalSociety'] = $row[0];
$processedData['region'] = $row[1] ?? 'National';
continue;
}
// Handle hazards and messages
if (!empty($row[3])) {
if(!$row[0] || !$row[1] || !$row[2]){
throw new RcnImportException("Title, description or url are missing or invalid");
}
$currentHazard = [
'title' => $row[0],
'description' => $row[1],
'url' => $row[2],
'hazard' => $row[3],
'urgencyLevels' => [],
];
}

if (!empty($row[4])) {
$currentUrgencyLevel = [
'urgencyLevel' => $row[4],
'safetyMessages' => []
];
}

if (!empty($row[5])) {
$currentUrgencyLevel['safetyMessages'][] = [
'safetyMessage' => $row[5],
'supportingMessages' => []
];
}

$supportingMessages = [];
for ($i = 6; $i < count($row); $i++) {
if (!empty($row[$i])) {
$supportingMessages[] = $row[$i];
}
}
if(count($supportingMessages) > 0){
$lastIndex = array_key_last($currentUrgencyLevel['safetyMessages']);
$currentUrgencyLevel['safetyMessages'][$lastIndex]['supportingMessages'] = $supportingMessages;
}



if ($currentUrgencyLevel) {
$existingHazardIndex = null;

foreach ($processedData['hazards'] as $pos => $hazardEntry) {
if ($hazardEntry['hazard'] === $currentHazard['hazard']) {
$existingHazardIndex = $pos;
break;
}
}
$existingUrgencyLevel = false;
if ($existingHazardIndex !== null) {

foreach ($processedData['hazards'][$existingHazardIndex]['urgencyLevels'] as $pos => $urgencyLevelEntry) {
if($urgencyLevelEntry['urgencyLevel'] === $currentUrgencyLevel['urgencyLevel']){
$processedData['hazards'][$existingHazardIndex]['urgencyLevels'][$pos]['safetyMessages'] = $currentUrgencyLevel['safetyMessages'];
$existingUrgencyLevel = true;
break;
}
}
if(!$existingUrgencyLevel){
$processedData['hazards'][$existingHazardIndex]['urgencyLevels'][] = $currentUrgencyLevel;
}
} else {
$currentHazard['urgencyLevels'][] = $currentUrgencyLevel;
$processedData['hazards'][] = $currentHazard;
}
}
}
$this->data = $processedData;
return $processedData;
}
public function getData()
{
return $this->data;
}



}

31 changes: 20 additions & 11 deletions app/Classes/RcnApi/Importer/ImportMetadata.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,46 +12,55 @@ class ImportMetadata
'INVALID_INVALID_DATE' => 40003,
];


protected $exportDate;


protected $countryCode;


protected $languageCode;


protected $region;


public function __construct(

array $metadataLine,

string $countryCode,
string $languageCode
string $languageCode,
string $region
) {
$this->countryCode = $countryCode;
$this->languageCode = $languageCode;
$this->validateMetadata($metadataLine);
$this->region = $region;
}


public function getExportDate(): \DateTimeImmutable
{
return $this->exportDate;
}


public function getCountryCode(): string
{
return $this->countryCode;
}


public function getLanguageCode(): string
{
return $this->languageCode;
}


public function getRegion(): string
{
return $this->region;
}



private function validateMetadata(array $metadataLine)
{
$header = array_first($metadataLine);
Expand Down
Loading
Loading