Add table export
continuous-integration/drone/push Build is failing
Details
continuous-integration/drone/push Build is failing
Details
This commit is contained in:
parent
2425ff6638
commit
ae450ef9ae
|
@ -17,3 +17,6 @@
|
|||
[submodule "packages/flysystem-webdav"]
|
||||
path = packages/flysystem-webdav
|
||||
url = https://github.com/zoomyboy/flysystem-webdav.git
|
||||
[submodule "packages/table-document"]
|
||||
path = packages/table-document
|
||||
url = https://git.zoomyboy.de/zoomyboy/table-document.git
|
||||
|
|
|
@ -2,6 +2,8 @@
|
|||
|
||||
namespace App\Fileshare\Data;
|
||||
|
||||
use App\Fileshare\Models\Fileshare;
|
||||
use Illuminate\Filesystem\FilesystemAdapter;
|
||||
use Spatie\LaravelData\Attributes\MapInputName;
|
||||
use Spatie\LaravelData\Attributes\MapOutputName;
|
||||
use Spatie\LaravelData\Data;
|
||||
|
@ -15,4 +17,14 @@ class FileshareResourceData extends Data
|
|||
public function __construct(public int $connectionId, public string $resource)
|
||||
{
|
||||
}
|
||||
|
||||
public function getConnection(): Fileshare
|
||||
{
|
||||
return Fileshare::find($this->connectionId);
|
||||
}
|
||||
|
||||
public function getStorage(): FilesystemAdapter
|
||||
{
|
||||
return $this->getConnection()->type->getFilesystem();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,87 @@
|
|||
<?php
|
||||
|
||||
namespace App\Form\Actions;
|
||||
|
||||
use App\Form\Models\Form;
|
||||
use App\Group;
|
||||
use Illuminate\Support\Collection;
|
||||
use Lorisleiva\Actions\Concerns\AsAction;
|
||||
use Zoomyboy\TableDocument\SheetData;
|
||||
use Zoomyboy\TableDocument\TableDocumentData;
|
||||
|
||||
class ExportSyncAction
|
||||
{
|
||||
use AsAction;
|
||||
|
||||
public Form $form;
|
||||
|
||||
public function handle(Form $form)
|
||||
{
|
||||
$this->form = $form;
|
||||
|
||||
if (!$form->export->root) {
|
||||
return;
|
||||
}
|
||||
|
||||
$storage = $form->export->root->getStorage();
|
||||
|
||||
$storage->put($form->export->root->resource . '/Anmeldungen ' . $form->name . '.xlsx', file_get_contents($this->allSheet($this->form->participants)->compile($this->tempPath())));
|
||||
|
||||
if ($form->export->toGroupField) {
|
||||
foreach ($form->participants->groupBy(fn ($participant) => $participant->data[$form->export->toGroupField]) as $groupId => $participants) {
|
||||
$group = Group::find($groupId);
|
||||
if (!$group?->fileshare) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$group->fileshare->getStorage()->put($group->fileshare->resource . '/Anmeldungen ' . $form->name . '.xlsx', file_get_contents($this->allSheet($participants)->compile($this->tempPath())));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function asJob(int $formId): void
|
||||
{
|
||||
$this->handle(Form::find($formId));
|
||||
}
|
||||
|
||||
private function allSheet(Collection $participants): TableDocumentData
|
||||
{
|
||||
$document = TableDocumentData::from(['title' => 'Anmeldungen für ' . $this->form->name, 'sheets' => []]);
|
||||
$headers = $this->form->getFields()->map(fn ($field) => $field->name)->toArray();
|
||||
|
||||
$document->addSheet(SheetData::from([
|
||||
'header' => $headers,
|
||||
'data' => $participants
|
||||
->map(fn ($participant) => $this->form->getFields()->map(fn ($field) => $participant->getFields()->find($field)->presentRaw())->toArray())
|
||||
->toArray(),
|
||||
'name' => 'Alle',
|
||||
]));
|
||||
|
||||
if ($this->form->export->groupBy) {
|
||||
$groups = $participants->groupBy(fn ($participant) => $participant->getFields()->findByKey($this->form->export->groupBy)->presentRaw());
|
||||
|
||||
foreach ($groups as $name => $participants) {
|
||||
$document->addSheet(SheetData::from([
|
||||
'header' => $headers,
|
||||
'data' => $participants
|
||||
->map(fn ($participant) => $this->form->getFields()->map(fn ($field) => $participant->getFields()->find($field)->presentRaw())->toArray())
|
||||
->toArray(),
|
||||
'name' => $name,
|
||||
]));
|
||||
}
|
||||
|
||||
$document->addSheet(SheetData::from([
|
||||
'header' => ['Wert', 'Anzahl'],
|
||||
'data' => $groups->map(fn ($participants, $name) => [$name, (string) count($participants)])->toArray(),
|
||||
'name' => 'Statistik',
|
||||
]));
|
||||
}
|
||||
|
||||
return $document;
|
||||
}
|
||||
|
||||
private function tempPath(): string
|
||||
{
|
||||
return sys_get_temp_dir() . '/' . str()->uuid()->toString();
|
||||
}
|
||||
}
|
|
@ -32,6 +32,7 @@ class RegisterAction
|
|||
$form->getFields()->each(fn ($field) => $field->afterRegistration($form, $participant, $input));
|
||||
|
||||
$participant->sendConfirmationMail();
|
||||
ExportSyncAction::dispatch($form->id);
|
||||
|
||||
return $participant;
|
||||
}
|
||||
|
|
|
@ -104,10 +104,7 @@ abstract class Field extends Data
|
|||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function presentRaw()
|
||||
public function presentRaw(): string
|
||||
{
|
||||
return $this->getPresenter()->present($this->value);
|
||||
}
|
||||
|
|
|
@ -14,6 +14,13 @@
|
|||
"symlink": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "path",
|
||||
"url": "./packages/table-document",
|
||||
"options": {
|
||||
"symlink": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "path",
|
||||
"url": "./packages/flysystem-webdav",
|
||||
|
@ -69,6 +76,7 @@
|
|||
"league/flysystem-webdav": "dev-master as 3.28.0",
|
||||
"zoomyboy/osm": "1.0.3",
|
||||
"zoomyboy/phone": "^1.0",
|
||||
"zoomyboy/table-document": "dev-master as 1.0",
|
||||
"zoomyboy/tex": "dev-main as 1.0"
|
||||
},
|
||||
"require-dev": {
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
||||
"This file is @generated automatically"
|
||||
],
|
||||
"content-hash": "552ce1f9c6448e20c08c2b3baca394df",
|
||||
"content-hash": "7541aa772bfd34e379ec31ce8cefdb58",
|
||||
"packages": [
|
||||
{
|
||||
"name": "amphp/amp",
|
||||
|
@ -5205,6 +5205,113 @@
|
|||
],
|
||||
"time": "2023-06-21T14:59:35+00:00"
|
||||
},
|
||||
{
|
||||
"name": "markbaker/complex",
|
||||
"version": "3.0.2",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/MarkBaker/PHPComplex.git",
|
||||
"reference": "95c56caa1cf5c766ad6d65b6344b807c1e8405b9"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/MarkBaker/PHPComplex/zipball/95c56caa1cf5c766ad6d65b6344b807c1e8405b9",
|
||||
"reference": "95c56caa1cf5c766ad6d65b6344b807c1e8405b9",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": "^7.2 || ^8.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"dealerdirect/phpcodesniffer-composer-installer": "dev-master",
|
||||
"phpcompatibility/php-compatibility": "^9.3",
|
||||
"phpunit/phpunit": "^7.0 || ^8.0 || ^9.0",
|
||||
"squizlabs/php_codesniffer": "^3.7"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Complex\\": "classes/src/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Mark Baker",
|
||||
"email": "mark@lange.demon.co.uk"
|
||||
}
|
||||
],
|
||||
"description": "PHP Class for working with complex numbers",
|
||||
"homepage": "https://github.com/MarkBaker/PHPComplex",
|
||||
"keywords": [
|
||||
"complex",
|
||||
"mathematics"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/MarkBaker/PHPComplex/issues",
|
||||
"source": "https://github.com/MarkBaker/PHPComplex/tree/3.0.2"
|
||||
},
|
||||
"time": "2022-12-06T16:21:08+00:00"
|
||||
},
|
||||
{
|
||||
"name": "markbaker/matrix",
|
||||
"version": "3.0.1",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/MarkBaker/PHPMatrix.git",
|
||||
"reference": "728434227fe21be27ff6d86621a1b13107a2562c"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/MarkBaker/PHPMatrix/zipball/728434227fe21be27ff6d86621a1b13107a2562c",
|
||||
"reference": "728434227fe21be27ff6d86621a1b13107a2562c",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": "^7.1 || ^8.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"dealerdirect/phpcodesniffer-composer-installer": "dev-master",
|
||||
"phpcompatibility/php-compatibility": "^9.3",
|
||||
"phpdocumentor/phpdocumentor": "2.*",
|
||||
"phploc/phploc": "^4.0",
|
||||
"phpmd/phpmd": "2.*",
|
||||
"phpunit/phpunit": "^7.0 || ^8.0 || ^9.0",
|
||||
"sebastian/phpcpd": "^4.0",
|
||||
"squizlabs/php_codesniffer": "^3.7"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Matrix\\": "classes/src/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Mark Baker",
|
||||
"email": "mark@demon-angel.eu"
|
||||
}
|
||||
],
|
||||
"description": "PHP Class for working with matrices",
|
||||
"homepage": "https://github.com/MarkBaker/PHPMatrix",
|
||||
"keywords": [
|
||||
"mathematics",
|
||||
"matrix",
|
||||
"vector"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/MarkBaker/PHPMatrix/issues",
|
||||
"source": "https://github.com/MarkBaker/PHPMatrix/tree/3.0.1"
|
||||
},
|
||||
"time": "2022-12-02T22:17:43+00:00"
|
||||
},
|
||||
{
|
||||
"name": "maximebf/debugbar",
|
||||
"version": "v1.22.3",
|
||||
|
@ -7136,6 +7243,110 @@
|
|||
},
|
||||
"time": "2024-02-23T11:10:43+00:00"
|
||||
},
|
||||
{
|
||||
"name": "phpoffice/phpspreadsheet",
|
||||
"version": "2.1.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/PHPOffice/PhpSpreadsheet.git",
|
||||
"reference": "dbed77bd3a0f68f96c0dd68ad4499d5674fecc3e"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/PHPOffice/PhpSpreadsheet/zipball/dbed77bd3a0f68f96c0dd68ad4499d5674fecc3e",
|
||||
"reference": "dbed77bd3a0f68f96c0dd68ad4499d5674fecc3e",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"ext-ctype": "*",
|
||||
"ext-dom": "*",
|
||||
"ext-fileinfo": "*",
|
||||
"ext-gd": "*",
|
||||
"ext-iconv": "*",
|
||||
"ext-libxml": "*",
|
||||
"ext-mbstring": "*",
|
||||
"ext-simplexml": "*",
|
||||
"ext-xml": "*",
|
||||
"ext-xmlreader": "*",
|
||||
"ext-xmlwriter": "*",
|
||||
"ext-zip": "*",
|
||||
"ext-zlib": "*",
|
||||
"maennchen/zipstream-php": "^2.1 || ^3.0",
|
||||
"markbaker/complex": "^3.0",
|
||||
"markbaker/matrix": "^3.0",
|
||||
"php": "^8.0",
|
||||
"psr/http-client": "^1.0",
|
||||
"psr/http-factory": "^1.0",
|
||||
"psr/simple-cache": "^1.0 || ^2.0 || ^3.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"dealerdirect/phpcodesniffer-composer-installer": "dev-main",
|
||||
"dompdf/dompdf": "^2.0",
|
||||
"friendsofphp/php-cs-fixer": "^3.2",
|
||||
"mitoteam/jpgraph": "^10.3",
|
||||
"mpdf/mpdf": "^8.1.1",
|
||||
"phpcompatibility/php-compatibility": "^9.3",
|
||||
"phpstan/phpstan": "^1.1",
|
||||
"phpstan/phpstan-phpunit": "^1.0",
|
||||
"phpunit/phpunit": "^9.6",
|
||||
"squizlabs/php_codesniffer": "^3.7",
|
||||
"tecnickcom/tcpdf": "^6.5"
|
||||
},
|
||||
"suggest": {
|
||||
"dompdf/dompdf": "Option for rendering PDF with PDF Writer",
|
||||
"ext-intl": "PHP Internationalization Functions",
|
||||
"mitoteam/jpgraph": "Option for rendering charts, or including charts with PDF or HTML Writers",
|
||||
"mpdf/mpdf": "Option for rendering PDF with PDF Writer",
|
||||
"tecnickcom/tcpdf": "Option for rendering PDF with PDF Writer"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"PhpOffice\\PhpSpreadsheet\\": "src/PhpSpreadsheet"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Maarten Balliauw",
|
||||
"homepage": "https://blog.maartenballiauw.be"
|
||||
},
|
||||
{
|
||||
"name": "Mark Baker",
|
||||
"homepage": "https://markbakeruk.net"
|
||||
},
|
||||
{
|
||||
"name": "Franck Lefevre",
|
||||
"homepage": "https://rootslabs.net"
|
||||
},
|
||||
{
|
||||
"name": "Erik Tilt"
|
||||
},
|
||||
{
|
||||
"name": "Adrien Crivelli"
|
||||
}
|
||||
],
|
||||
"description": "PHPSpreadsheet - Read, Create and Write Spreadsheet documents in PHP - Spreadsheet engine",
|
||||
"homepage": "https://github.com/PHPOffice/PhpSpreadsheet",
|
||||
"keywords": [
|
||||
"OpenXML",
|
||||
"excel",
|
||||
"gnumeric",
|
||||
"ods",
|
||||
"php",
|
||||
"spreadsheet",
|
||||
"xls",
|
||||
"xlsx"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/PHPOffice/PhpSpreadsheet/issues",
|
||||
"source": "https://github.com/PHPOffice/PhpSpreadsheet/tree/2.1.0"
|
||||
},
|
||||
"time": "2024-05-11T04:17:56+00:00"
|
||||
},
|
||||
{
|
||||
"name": "phpoption/phpoption",
|
||||
"version": "1.9.2",
|
||||
|
@ -14154,6 +14365,37 @@
|
|||
"description": "Phone number formatting",
|
||||
"time": "2023-03-02T23:22:08+00:00"
|
||||
},
|
||||
{
|
||||
"name": "zoomyboy/table-document",
|
||||
"version": "dev-master",
|
||||
"dist": {
|
||||
"type": "path",
|
||||
"url": "./packages/table-document",
|
||||
"reference": "c478784bbb26d7dc28c08670322dbf3b0d845f8c"
|
||||
},
|
||||
"require": {
|
||||
"laravel/framework": "^9.0",
|
||||
"phpoffice/phpspreadsheet": "^2.1",
|
||||
"spatie/laravel-data": "^3.0"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Zoomyboy\\TableDocument\\": "src/"
|
||||
}
|
||||
},
|
||||
"authors": [
|
||||
{
|
||||
"name": "Philipp Lang",
|
||||
"email": "philipp@zoomyboy.de"
|
||||
}
|
||||
],
|
||||
"description": "Table document creator",
|
||||
"transport-options": {
|
||||
"symlink": true,
|
||||
"relative": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "zoomyboy/tex",
|
||||
"version": "dev-main",
|
||||
|
@ -15877,6 +16119,12 @@
|
|||
"alias": "1.0",
|
||||
"alias_normalized": "1.0.0.0"
|
||||
},
|
||||
{
|
||||
"package": "zoomyboy/table-document",
|
||||
"version": "9999999-dev",
|
||||
"alias": "1.0",
|
||||
"alias_normalized": "1.0.0.0"
|
||||
},
|
||||
{
|
||||
"package": "zoomyboy/tex",
|
||||
"version": "dev-main",
|
||||
|
@ -15889,6 +16137,7 @@
|
|||
"zoomyboy/laravel-nami": 20,
|
||||
"zoomyboy/medialibrary-helper": 20,
|
||||
"league/flysystem-webdav": 20,
|
||||
"zoomyboy/table-document": 20,
|
||||
"zoomyboy/tex": 20
|
||||
},
|
||||
"prefer-stable": true,
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
Subproject commit c1d0221dcd2b4200b3ff17747e31f451fcc749f0
|
|
@ -2,6 +2,8 @@
|
|||
|
||||
namespace Tests\Feature\Form;
|
||||
|
||||
use App\Form\Actions\ExportAction;
|
||||
use App\Form\Actions\ExportSyncAction;
|
||||
use App\Form\Enums\NamiType;
|
||||
use App\Form\Enums\SpecialType;
|
||||
use App\Form\Mails\ConfirmRegistrationMail;
|
||||
|
@ -41,6 +43,7 @@ class FormRegisterActionTest extends FormTestCase
|
|||
]),
|
||||
])
|
||||
->create();
|
||||
ExportSyncAction::shouldRun()->once()->with($form->id);
|
||||
|
||||
$this->register($form, ['vorname' => 'Max', 'nachname' => 'Muster', 'spitzname' => 'Abraham'])
|
||||
->assertOk();
|
||||
|
|
|
@ -0,0 +1,70 @@
|
|||
<?php
|
||||
|
||||
namespace Tests\Fileshare;
|
||||
|
||||
use App\Fileshare\ConnectionTypes\OwncloudConnection;
|
||||
use App\Fileshare\Data\FileshareResourceData;
|
||||
use App\Fileshare\Models\Fileshare;
|
||||
use App\Form\Actions\ExportSyncAction;
|
||||
use App\Form\Data\ExportData;
|
||||
use App\Form\Models\Form;
|
||||
use App\Form\Models\Participant;
|
||||
use App\Group;
|
||||
use Tests\FileshareTestCase;
|
||||
use Tests\Lib\CreatesFormFields;
|
||||
|
||||
class ExportSyncActionTest extends FileshareTestCase
|
||||
{
|
||||
|
||||
use CreatesFormFields;
|
||||
|
||||
public function testItDoesntUploadFileWhenNoExportGiven(): void
|
||||
{
|
||||
$form = Form::factory()->fields([
|
||||
$this->textField('vorname'),
|
||||
$this->textField('nachname'),
|
||||
])->create();
|
||||
|
||||
ExportSyncAction::run($form);
|
||||
$this->assertTrue(true);
|
||||
}
|
||||
|
||||
public function testItUploadsRootFile(): void
|
||||
{
|
||||
$this->withoutExceptionHandling()->withOwncloudUser('badenpowell', 'secret')->withDirs('badenpowell', ['/abc']);
|
||||
$connection = Fileshare::factory()
|
||||
->type(OwncloudConnection::from(['user' => 'badenpowell', 'password' => 'secret', 'base_url' => env('TEST_OWNCLOUD_DOMAIN')]))
|
||||
->create();
|
||||
$form = Form::factory()->name('Formular')->fields([
|
||||
$this->textField('vorname'),
|
||||
$this->textField('nachname'),
|
||||
])->export(ExportData::from(['root' => FileshareResourceData::from(['connection_id' => $connection->id, 'resource' => '/abc'])]))->create();
|
||||
Participant::factory()->for($form)->data(['firstname' => 'AAA', 'lastname' => 'BBB'])->create();
|
||||
|
||||
ExportSyncAction::run($form);
|
||||
|
||||
$this->assertEquals(['abc/Anmeldungen Formular.xlsx'], $connection->type->getFilesystem()->files('/abc'));
|
||||
$this->assertTrue(true);
|
||||
}
|
||||
|
||||
public function testItUploadsGroupFile(): void
|
||||
{
|
||||
$this->withoutExceptionHandling()->withOwncloudUser('badenpowell', 'secret')->withDirs('badenpowell', ['/abc', '/stamm']);
|
||||
$connection = Fileshare::factory()
|
||||
->type(OwncloudConnection::from(['user' => 'badenpowell', 'password' => 'secret', 'base_url' => env('TEST_OWNCLOUD_DOMAIN')]))
|
||||
->create();
|
||||
$group = Group::factory()->create(['fileshare' => FileshareResourceData::from(['connection_id' => $connection->id, 'resource' => '/stamm'])]);
|
||||
$form = Form::factory()->name('Formular')->fields([
|
||||
$this->textField('vorname')->name('Vorname'),
|
||||
$this->textField('nachname')->name('Nachname'),
|
||||
$this->groupField('stamm')->name('Stamm'),
|
||||
])->export(ExportData::from(['to_group_field' => 'stamm', 'group_by' => 'vorname', 'root' => FileshareResourceData::from(['connection_id' => $connection->id, 'resource' => '/abc'])]))->create();
|
||||
Participant::factory()->for($form)->data(['vorname' => 'AAA', 'nachname' => 'BBB', 'stamm' => $group->id])->create();
|
||||
Participant::factory()->for($form)->data(['vorname' => 'CCC', 'nachname' => 'DDD', 'stamm' => null])->create();
|
||||
|
||||
ExportSyncAction::run($form);
|
||||
|
||||
$this->assertEquals(['stamm/Anmeldungen Formular.xlsx'], $connection->type->getFilesystem()->files('/stamm'));
|
||||
$this->assertTrue(true);
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue