add spreadsheet

This commit is contained in:
philipp lang 2023-03-27 23:10:51 +02:00
parent 2a07614388
commit b443543ff9
7 changed files with 218 additions and 24 deletions

1
.gitignore vendored Normal file
View File

@ -0,0 +1 @@
/vendor/

View File

@ -5,6 +5,7 @@ namespace Zoomyboy\Event;
use Backend;
use Carbon\Carbon;
use System\Classes\PluginBase;
use Zoomyboy\Event\Console\EventManageCommand;
/**
* event Plugin Information File.
@ -33,6 +34,7 @@ class Plugin extends PluginBase
*/
public function register()
{
$this->registerConsoleCommand('event.event-manage', EventManageCommand::class);
}
/**

View File

@ -19,8 +19,6 @@ export default function (toasted) {
address: '',
zip: '',
location: '',
courses: [],
fcourses: [],
food_preferences: [],
activity: 'Teilnehmer*in',
gender: '',
@ -34,7 +32,7 @@ export default function (toasted) {
misc: '',
foto: false,
parent: false,
vorteam: null,
vorteam: false,
},
loading: false,
finished: false,
@ -55,10 +53,6 @@ export default function (toasted) {
{"id": "Weiblich", "name": "Weiblich"},
{"id": "Divers", "name": "Divers"},
],
fcourses: [
{"id": "Ich bin Samstags beim Abendprogramm dabei", "name": "Ich bin Samstags beim Abendprogramm dabei"},
{"id": "Ich esse sonntag Mittag mit", "name": "Ich esse sonntag Mittag mit"},
],
groups: [
{"id": "Gallier", "name": "Gallier (Wuppertal)"},
{"id": "Gandalf", "name": "Gandalf (SG-Mangenberg)"},
@ -103,16 +97,6 @@ export default function (toasted) {
{"id": "Glutenfrei", "name": "Ich vertrage kein Gluten"},
{"id": "Laktosefrei", "name": "Ich vertrage keine Laktose"},
],
get courses() {
return this.data.agegroup === 'Rover' ? [
{"id": "Schritt 2", "name": "Schritt 2"},
] : [
{"id": "Baustein 2a", "name": "Baustein 2a"},
{"id": "Baustein 2c", "name": "Baustein 2c"},
{"id": "Baustein 3c", "name": "Baustein 3c"},
{"id": "Schritt 2", "name": "Schritt 2"},
];
},
slideTo(e, index) {
if (e !== null) {
e.preventDefault();

View File

@ -3,12 +3,42 @@
namespace Zoomyboy\Event\Classes;
use PhpOffice\PhpSpreadsheet\Spreadsheet as BaseSpreadsheet;
use PhpOffice\PhpSpreadsheet\Style\Alignment as AlignmentStyle;
use PhpOffice\PhpSpreadsheet\Style\Fill as FillStyle;
use PhpOffice\PhpSpreadsheet\Worksheet\Worksheet;
class Spreadsheet
{
private array $headers;
private $sheet;
private $warningStyle = [
'font' => [
'size' => 10,
'bold' => true,
'color' => [
'rgb' => 'ff0000',
],
],
'alignment' => [
'vertical' => AlignmentStyle::VERTICAL_CENTER,
],
];
private $headerStyle = [
'font' => [
'size' => 12,
'bold' => true,
'color' => [
'rgb' => 'e9fcfc',
],
],
'alignment' => [
'vertical' => AlignmentStyle::VERTICAL_CENTER,
],
'fill' => [
'fillType' => FillStyle::FILL_SOLID,
'color' => ['rgb' => '117878'],
],
];
public function __construct(string $title)
{
@ -17,6 +47,7 @@ class Spreadsheet
->setTitle($title)
->setSubject($title)
->setDescription($title);
$this->spreadsheet->getDefaultStyle()->getFont()->setSize(12);
$this->spreadsheet->getActiveSheet()->setTitle('unfilled');
}
@ -31,9 +62,12 @@ class Spreadsheet
{
$this->spreadsheet->setActiveSheetIndex(0);
$writer = new \PhpOffice\PhpSpreadsheet\Writer\Xlsx($this->spreadsheet);
$writer->save('/home/pille/s.xlsx');
$writer->save('/home/pille/spreadsheet.xlsx');
// $writer->save(sys_get_temp_dir().'/spreadsheet.xlsx');
$this->spreadsheet->disconnectWorksheets();
unset($this->spreadsheet);
return sys_get_temp_dir().'/spreadsheet.xlsx';
}
public function sheet(string $name, array $data): self
@ -53,8 +87,17 @@ class Spreadsheet
private function fill(array $data): self
{
$headers = collect($this->headers)->map(fn ($header) => $header->name)->toArray();
$this->spreadsheet->getActiveSheet()->fromArray($headers, null, 'A1');
$this->spreadsheet->getActiveSheet()->fromArray($data, null, 'A2');
$this->spreadsheet->getActiveSheet()->fromArray(['Achtung: Dieses Dokument wird bei neuen Teilnehmern automatisch aktualisiert. Gespeicherte Änderungen können daher jederzeit verloren gehen. Wenn du dieses Dokument bearbeiten willst, speichere es bitte an einem anderen Ort ab und editiere es dann.'], null, 'A1');
$this->spreadsheet->getActiveSheet()->fromArray($headers, null, 'A2');
$this->spreadsheet->getActiveSheet()->fromArray($data, null, 'A3');
$this->spreadsheet->getActiveSheet()->getStyle('A2:Z2')->applyFromArray($this->headerStyle);
$this->spreadsheet->getActiveSheet()->getStyle('A1')->applyFromArray($this->warningStyle);
foreach (range('A', 'Z') as $col) {
$this->spreadsheet->getActiveSheet()->getColumnDimension($col)->setAutoSize(true);
}
$this->spreadsheet->getActiveSheet()->getRowDimension(2)->setRowHeight(18);
$this->spreadsheet->getActiveSheet()->mergeCells('A1:Z1');
return $this;
}

View File

@ -5,9 +5,9 @@ namespace Zoomyboy\Event\Components;
use Cms\Classes\ComponentBase;
use Illuminate\Http\JsonResponse;
use Illuminate\Support\Facades\Lang;
use Illuminate\Support\Facades\Mail;
use Input;
use Winter\Storm\Support\Facades\Validator;
use Zoomyboy\Event\Jobs\ProcessSubmitJob;
use Zoomyboy\Event\Models\Event;
use Zoomyboy\Event\Models\Participant;
@ -70,9 +70,8 @@ class EventForm extends ComponentBase
'event_id' => $this->event->id,
'payload' => $this->event->transformInputs(Input::all()),
]);
Mail::send('confirm_'.$this->event->slug, ['data' => $participant->payload], function ($message) use ($participant) {
$message->to($participant->email, $participant->firstname.' '.$participant->lastname);
});
ProcessSubmitJob::dispatch($participant->id);
return response()->json([], 201);
}

View File

@ -0,0 +1,36 @@
<?php namespace Zoomyboy\Event\Console;
use Winter\Storm\Console\Command;
use Zoomyboy\Event\Models\Participant;
class EventManageCommand extends Command
{
/**
* @var string The console command name.
*/
protected static $defaultName = 'Manage events';
/**
* @var string The name and signature of this command.
*/
protected $signature = 'event:manage';
/**
* @var string The console command description.
*/
protected $description = 'No description provided yet...';
/**
* Execute the console command.
* @return void
*/
public function handle()
{
foreach (Participant::get() as $participant) {
if (in_array('2e', $participant->payload['courses']) || in_array('3c', $participant->payload['courses'])) {
echo $participant->email."\n";
}
}
}
}

129
jobs/ProcessSubmitJob.php Normal file
View File

@ -0,0 +1,129 @@
<?php
namespace Zoomyboy\Event\Jobs;
use Carbon\Carbon;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
use Mail;
use Zoomyboy\Event\Classes\Spreadsheet;
use Zoomyboy\Event\Classes\SpreadsheetHeader;
use Zoomyboy\Event\Models\Event;
use Zoomyboy\Event\Models\Participant;
use Zoomyboy\Owncloud\Classes\Filesystem;
class ProcessSubmitJob implements ShouldQueue
{
use Dispatchable;
use InteractsWithQueue;
use Queueable;
use SerializesModels;
public Participant $participant;
public Event $event;
/**
* Create a new job instance.
*/
public function __construct(public int $participantId)
{
}
/**
* Execute the job.
*/
public function handle(): void
{
$this->participant = Participant::find($this->participantId);
$this->event = $this->participant->event;
$this->uploadFile();
$this->sendMail();
}
private function sendMail(): void
{
Mail::send('confirm_'.$this->event->slug, ['data' => $this->participant->payload], function ($message) {
$message->to($this->participant->email, $this->participant->firstname.' '.$this->participant->lastname);
});
}
private function uploadFile(): void
{
$filesystem = app(Filesystem::class)->client();
$headers = $this->getFields()->map(fn ($field) => new SpreadsheetHeader($field['label']))->toArray();
$orderBy = collect($this->event->loadConfig('orderBy'))->map(fn ($order) => "{$order['key']} {$order['direction']}")->implode(',');
$groupBy = $this->event->loadConfig('groupBy');
$participants = Participant::where('event_id', $this->event->id)->orderByRaw($orderBy)->get()->groupBy(fn ($p) => data_get($p->payload, $groupBy));
$s = (new Spreadsheet('Anmeldezahlen '.$this->event->title))->headers($headers);
if ($this->event->loadConfig('groupAll')) {
$this->makeSheet($s, 'Alle', Participant::where('event_id', $this->event->id)->orderByRaw($orderBy)->get());
}
foreach ($participants as $group => $groupParticipants) {
$this->makeSheet($s, $group, $groupParticipants);
}
$spreadsheetFile = $s->generate();
$filesystem->write($this->event->slug.'/anmeldungen.xlsx', file_get_contents($spreadsheetFile));
}
private function getfields()
{
return collect($this->event->loadConfig('fields'));
}
private function makeSheet(Spreadsheet $s, $group, $groupParticipants)
{
$groupParticipants = $groupParticipants->map(function ($participant) {
$payload = $participant->payload;
$content = $this->getFields()->map(function ($field) use ($payload) {
$type = $field['type'];
$method = 'format'.ucfirst($type);
return $this->{$method}(data_get($payload, $field['key']));
});
return $content->toArray();
})->toArray();
$s->sheet($group, $groupParticipants);
}
private function formatString(?string $input = null): string
{
return $input ?: '';
}
private function formatDate(?string $input = null): string
{
if (!$input) {
return '';
}
return Carbon::parse($input)->format('d.m.Y');
}
private function formatEnum(?array $input = []): string
{
if (!$input) {
return '';
}
return collect($input)->implode(', ');
}
private function formatBool($input = false): string
{
return true === $input ? 'Ja' : 'Nein';
}
}