Add member search via meilisearch
This commit is contained in:
parent
26d0f49568
commit
4e378c8a57
|
@ -16,6 +16,8 @@ MAIL_FROM_NAME=me
|
|||
DB_PASSWORD=secret_db_password
|
||||
MYSQL_PASSWORD=secret_db_password
|
||||
|
||||
MEILI_MASTER_KEY=secret_meilisearch_password
|
||||
|
||||
PUSHER_APP_HOST=socketi
|
||||
|
||||
WORKERS=5
|
||||
|
|
|
@ -5,6 +5,7 @@ namespace App\Http\Views;
|
|||
use App\Activity;
|
||||
use App\Lib\Filter;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
use Laravel\Scout\Builder as ScoutBuilder;
|
||||
use Spatie\LaravelData\Attributes\MapInputName;
|
||||
use Spatie\LaravelData\Attributes\MapOutputName;
|
||||
use Spatie\LaravelData\Mappers\SnakeCaseMapper;
|
||||
|
@ -21,12 +22,9 @@ class ActivityFilterScope extends Filter
|
|||
) {
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function locks(): array
|
||||
public function getQuery(): ScoutBuilder
|
||||
{
|
||||
return [];
|
||||
return Activity::search('');
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -31,10 +31,14 @@ class InvoicePosition extends Model
|
|||
|
||||
public static function booted(): void
|
||||
{
|
||||
static::saved(function ($model) {
|
||||
$model->member->touch();
|
||||
});
|
||||
static::deleted(function ($model) {
|
||||
if ($model->invoice->positions()->get()->count() === 0) {
|
||||
$model->invoice->delete();
|
||||
}
|
||||
$model->member->touch();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,21 +2,22 @@
|
|||
|
||||
namespace App\Lib;
|
||||
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Laravel\Scout\Builder;
|
||||
use Spatie\LaravelData\Data;
|
||||
|
||||
/**
|
||||
* @template T of Model
|
||||
* @property Builder $query
|
||||
*/
|
||||
abstract class Filter extends Data
|
||||
{
|
||||
public string $unsetReplacer = 'yoNee3ainge4eetiier9ogaiChoe0ahcaR3Hu1uzah8xaiv7ael7yahphai7ruG9';
|
||||
|
||||
/**
|
||||
* @return array<string, mixed>
|
||||
* @return self<T>
|
||||
*/
|
||||
abstract protected function locks(): array;
|
||||
abstract public function getQuery(): Builder;
|
||||
protected Builder $query;
|
||||
|
||||
/**
|
||||
* @param array<string, mixed>|string|null $request
|
||||
|
@ -35,51 +36,6 @@ abstract class Filter extends Data
|
|||
*/
|
||||
public static function fromPost(?array $post = null): static
|
||||
{
|
||||
return static::withoutMagicalCreationFrom($post ?: [])->parseLocks();
|
||||
}
|
||||
|
||||
public function parseLocks(): static
|
||||
{
|
||||
foreach ($this->locks() as $key => $value) {
|
||||
if ($value === $this->unsetReplacer) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$this->{$key} = $value;
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed $value
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function when(bool $when, $value)
|
||||
{
|
||||
return $when ? $value : $this->unsetReplacer;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Builder<T> $query
|
||||
*
|
||||
* @return Builder<T>
|
||||
*/
|
||||
protected function applyOwnOthers(Builder $query, bool $own, bool $others): Builder
|
||||
{
|
||||
if ($own && !$others) {
|
||||
$query->where('user_id', auth()->id());
|
||||
}
|
||||
|
||||
if (!$own && $others) {
|
||||
$query->where('user_id', '!=', auth()->id());
|
||||
}
|
||||
|
||||
if (!$own && !$others) {
|
||||
$query->where('id', -1);
|
||||
}
|
||||
|
||||
return $query;
|
||||
return static::withoutMagicalCreationFrom($post ?: []);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -25,9 +25,7 @@ class ResyncAction
|
|||
*/
|
||||
public function getResults(Maildispatcher $dispatcher): Collection
|
||||
{
|
||||
return Member::search(data_get($dispatcher->filter, 'search', ''))->query(
|
||||
fn ($q) => $q->select('*')->withFilter(FilterScope::fromPost($dispatcher->filter))
|
||||
)->get()
|
||||
return FilterScope::fromPost($dispatcher->filter)->getQuery()->get()
|
||||
->filter(fn ($member) => $member->email || $member->email_parents)
|
||||
->map(fn ($member) => MailEntry::from(['email' => $member->email ?: $member->email_parents]))
|
||||
->unique(fn ($member) => $member->email);
|
||||
|
|
|
@ -43,9 +43,8 @@ class ExportAction
|
|||
|
||||
public function asController(ActionRequest $request): StreamedResponse
|
||||
{
|
||||
$filter = FilterScope::fromRequest($request->input('filter'));
|
||||
|
||||
$contents = $this->handle(Member::ordered()->withFilter($filter)->get());
|
||||
$members = FilterScope::fromRequest($request->input('filter'))->getQuery()->get();
|
||||
$contents = $this->handle($members);
|
||||
|
||||
Storage::disk('temp')->put('mitglieder.csv', $contents);
|
||||
|
||||
|
|
|
@ -15,19 +15,16 @@ class SearchAction
|
|||
use AsAction;
|
||||
|
||||
/**
|
||||
* @param array<string, mixed> $filter
|
||||
* @return LengthAwarePaginator<int, Member>
|
||||
*/
|
||||
public function handle(FilterScope $filter, int $perPage): LengthAwarePaginator
|
||||
public function handle(array $filter, int $perPage): LengthAwarePaginator
|
||||
{
|
||||
return Member::search($filter->search)->query(
|
||||
fn ($q) => $q->select('*')
|
||||
->withFilter($filter)
|
||||
->ordered()
|
||||
)->paginate($perPage);
|
||||
return FilterScope::fromPost($filter)->getQuery()->paginate($perPage);
|
||||
}
|
||||
|
||||
public function asController(ActionRequest $request): AnonymousResourceCollection
|
||||
{
|
||||
return MemberResource::collection($this->handle(FilterScope::fromRequest($request->input('filter', '')), $request->input('per_page', 15)));
|
||||
return MemberResource::collection($this->handle($request->input('filter', []), $request->input('per_page', 15)));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,7 +4,8 @@ namespace App\Member;
|
|||
|
||||
use App\Invoice\BillKind;
|
||||
use App\Lib\Filter;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
use Illuminate\Support\Collection;
|
||||
use Laravel\Scout\Builder;
|
||||
use Spatie\LaravelData\Attributes\MapInputName;
|
||||
use Spatie\LaravelData\Attributes\MapOutputName;
|
||||
use Spatie\LaravelData\Mappers\SnakeCaseMapper;
|
||||
|
@ -37,72 +38,93 @@ class FilterScope extends Filter
|
|||
) {
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function locks(): array
|
||||
public function getQuery(): Builder
|
||||
{
|
||||
return [];
|
||||
}
|
||||
$this->search = $this->search ?: '';
|
||||
|
||||
/**
|
||||
* @param Builder<Member> $query
|
||||
*
|
||||
* @return Builder<Member>
|
||||
*/
|
||||
public function apply(Builder $query): Builder
|
||||
{
|
||||
return $query->where(function ($query) {
|
||||
$query->orWhere(function ($query) {
|
||||
if ($this->ausstand) {
|
||||
$query->whereAusstand();
|
||||
}
|
||||
return Member::search($this->search, function ($engine, string $query, array $options) {
|
||||
$filter = collect([]);
|
||||
|
||||
if ($this->hasFullAddress === true) {
|
||||
$filter->push('address IS NOT EMPTY');
|
||||
}
|
||||
if ($this->hasFullAddress === false) {
|
||||
$filter->push('address IS EMPTY');
|
||||
}
|
||||
if ($this->hasBirthday === false) {
|
||||
$filter->push('birthday IS NULL');
|
||||
}
|
||||
if ($this->hasBirthday === true) {
|
||||
$filter->push('birthday IS NOT NULL');
|
||||
}
|
||||
if ($this->ausstand === true) {
|
||||
$filter->push('ausstand > 0');
|
||||
}
|
||||
if ($this->billKind) {
|
||||
$query->where('bill_kind', BillKind::fromValue($this->billKind));
|
||||
$filter->push('bill_kind = ' . BillKind::fromValue($this->billKind)->value);
|
||||
}
|
||||
|
||||
if (true === $this->hasFullAddress) {
|
||||
$query->whereNotNull('address')->whereNotNull('zip')->whereNotNull('location')->where('address', '!=', '')->where('zip', '!=', '')->where('location', '!=', '');
|
||||
}
|
||||
|
||||
if (false === $this->hasFullAddress) {
|
||||
$query->where(
|
||||
fn ($q) => $q
|
||||
->orWhere('address', '')->orWhereNull('address')
|
||||
->orWhere('zip', '')->orWhereNull('zip')
|
||||
->orWhere('location', '')->orWhereNull('location')
|
||||
);
|
||||
}
|
||||
|
||||
if (true === $this->hasBirthday) {
|
||||
$query->whereNotNull('birthday');
|
||||
}
|
||||
|
||||
if (count($this->groupIds)) {
|
||||
$query->whereIn('group_id', $this->groupIds);
|
||||
$filter->push($this->inExpression('group_id', $this->groupIds));
|
||||
}
|
||||
|
||||
if (count($this->subactivityIds) + count($this->activityIds) > 0) {
|
||||
$query->whereHas('memberships', function ($q) {
|
||||
$q->active();
|
||||
if (count($this->subactivityIds)) {
|
||||
$q->whereIn('subactivity_id', $this->subactivityIds);
|
||||
if (!$this->subactivityIds && $this->activityIds) {
|
||||
$filter->push($this->inExpression('memberships.activity_id', $this->activityIds));
|
||||
}
|
||||
if (count($this->activityIds)) {
|
||||
$q->whereIn('activity_id', $this->activityIds);
|
||||
if ($this->subactivityIds && !$this->activityIds) {
|
||||
$filter->push($this->inExpression('memberships.subactivity_id', $this->subactivityIds));
|
||||
}
|
||||
});
|
||||
if ($this->subactivityIds && $this->activityIds) {
|
||||
$combinations = collect($this->activityIds)
|
||||
->map(fn ($activityId) => collect($this->subactivityIds)->map(fn ($subactivityId) => $activityId . '|' . $subactivityId))
|
||||
->flatten()
|
||||
->map(fn ($combination) => str($combination)->wrap('"'));
|
||||
$filter->push($this->inExpression('memberships.both', $combinations));
|
||||
}
|
||||
|
||||
if (count($this->exclude)) {
|
||||
$query->whereNotIn('id', $this->exclude);
|
||||
$filter->push($this->notInExpression('id', $this->exclude));
|
||||
}
|
||||
})->orWhere(function ($query) {
|
||||
if (count($this->include)) {
|
||||
$query->whereIn('id', $this->include);
|
||||
|
||||
$andFilter = $filter->map(fn ($expression) => "($expression)")->implode(' AND ');
|
||||
|
||||
$options['filter'] = $this->implode(collect([$andFilter])->push($this->inExpression('id', $this->include)), 'OR');
|
||||
$options['sort'] = ['lastname:asc', 'firstname:asc'];
|
||||
|
||||
return $engine->search($query, $options);
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
/**
|
||||
* @param Collection<int, mixed> $values
|
||||
*/
|
||||
protected function implode(Collection $values, string $between): string
|
||||
{
|
||||
return $values->filter(fn ($expression) => $expression)->implode(" {$between} ");
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array<int, mixed>|Collection<int, mixed> $values
|
||||
*/
|
||||
private function inExpression(string $key, array|Collection $values): ?string
|
||||
{
|
||||
if (!count($values)) {
|
||||
return null;
|
||||
}
|
||||
$valueString = Collection::wrap($values)->implode(',');
|
||||
|
||||
return "$key IN [{$valueString}]";
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array<int, mixed>|Collection<int, mixed> $values
|
||||
*/
|
||||
private function notInExpression(string $key, array|Collection $values): ?string
|
||||
{
|
||||
if (!count($values)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$valueString = Collection::wrap($values)->implode(',');
|
||||
|
||||
return "$key NOT IN [{$valueString}]";
|
||||
}
|
||||
}
|
||||
|
|
|
@ -149,7 +149,9 @@ class Member extends Model implements Geolocatable
|
|||
|
||||
public function getFullAddressAttribute(): string
|
||||
{
|
||||
return $this->address . ', ' . $this->zip . ' ' . $this->location;
|
||||
return $this->address && $this->zip && $this->location
|
||||
? $this->address . ', ' . $this->zip . ' ' . $this->location
|
||||
: '';
|
||||
}
|
||||
|
||||
public function getEfzLink(): ?string
|
||||
|
@ -178,6 +180,11 @@ class Member extends Model implements Geolocatable
|
|||
return $this->birthday?->diffInYears(now());
|
||||
}
|
||||
|
||||
protected function getAusstand(): int
|
||||
{
|
||||
return (int) $this->invoicePositions()->whereHas('invoice', fn ($query) => $query->whereNeedsPayment())->sum('price');
|
||||
}
|
||||
|
||||
// ---------------------------------- Relations ----------------------------------
|
||||
/**
|
||||
* @return BelongsTo<Country, self>
|
||||
|
@ -324,18 +331,6 @@ class Member extends Model implements Geolocatable
|
|||
return $query->whereHas('invoicePositions', fn ($q) => $q->whereHas('invoice', fn ($q) => $q->whereNeedsPayment()));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Builder<self> $query
|
||||
*
|
||||
* @return Builder<self>
|
||||
*/
|
||||
public function scopeWhereAusstand(Builder $query): Builder
|
||||
{
|
||||
return $query->whereHas('invoicePositions', function ($q) {
|
||||
return $q->whereHas('invoice', fn ($query) => $query->whereNeedsPayment());
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Builder<self> $query
|
||||
*
|
||||
|
@ -356,18 +351,6 @@ class Member extends Model implements Geolocatable
|
|||
return $query->selectRaw('SUM(id)');
|
||||
}
|
||||
|
||||
/**
|
||||
* @todo refactor this to an actual filter model
|
||||
*
|
||||
* @param Builder<self> $query
|
||||
*
|
||||
* @return Builder<self>
|
||||
*/
|
||||
public function scopeWithFilter(Builder $query, FilterScope $filter): Builder
|
||||
{
|
||||
return $filter->apply($query);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Builder<self> $query
|
||||
*
|
||||
|
@ -512,6 +495,14 @@ class Member extends Model implements Geolocatable
|
|||
return [
|
||||
'address' => $this->fullAddress,
|
||||
'fullname' => $this->fullname,
|
||||
'firstname' => $this->firstname,
|
||||
'lastname' => $this->lastname,
|
||||
'birthday' => $this->birthday?->format('Y-m-d'),
|
||||
'ausstand' => $this->getAusstand(),
|
||||
'bill_kind' => $this->bill_kind?->value,
|
||||
'group_id' => $this->group->id,
|
||||
'memberships' => $this->memberships()->active()->get()
|
||||
->map(fn ($membership) => [...$membership->only('activity_id', 'subactivity_id'), 'both' => $membership->activity_id . '|' . $membership->subactivity_id]),
|
||||
];
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,15 +17,13 @@ class MemberController extends Controller
|
|||
{
|
||||
session()->put('menu', 'member');
|
||||
session()->put('title', 'Mitglieder');
|
||||
$filter = FilterScope::fromRequest($request->input('filter', ''));
|
||||
|
||||
return Inertia::render('member/VIndex', [
|
||||
'data' => MemberResource::collection(Member::search($filter->search)->query(
|
||||
fn ($q) => $q->select('*')
|
||||
->withFilter($filter)
|
||||
'data' => MemberResource::collection(FilterScope::fromRequest($request->input('filter', ''))->getQuery()->query(
|
||||
fn ($q) => $q
|
||||
->select('*')
|
||||
->with(['gender', 'subscription', 'leaderMemberships', 'ageGroupMemberships.subactivity'])
|
||||
->withPendingPayment()
|
||||
->ordered()
|
||||
)->paginate(15)),
|
||||
]);
|
||||
}
|
||||
|
|
|
@ -116,4 +116,14 @@ class Membership extends Model
|
|||
{
|
||||
return $query->active()->whereHas('activity', fn ($builder) => $builder->where('is_try', true));
|
||||
}
|
||||
|
||||
public static function booted(): void
|
||||
{
|
||||
static::saved(function ($membership) {
|
||||
$membership->member->touch();
|
||||
});
|
||||
static::deleted(function ($membership) {
|
||||
$membership->member->touch();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -133,10 +133,12 @@ return [
|
|||
|
||||
'meilisearch' => [
|
||||
'host' => env('MEILISEARCH_HOST', 'http://localhost:7700'),
|
||||
'key' => env('MEILISEARCH_KEY', null),
|
||||
'key' => env('MEILI_MASTER_KEY', null),
|
||||
'index-settings' => [
|
||||
Member::class => [
|
||||
'filterableAttributes' => ['fullname', 'address'],
|
||||
'filterableAttributes' => ['address', 'birthday', 'ausstand', 'bill_kind', 'group_id', 'memberships', 'id'],
|
||||
'searchableAttributes' => ['fullname', 'address'],
|
||||
'sortableAttributes' => ['lastname', 'firstname'],
|
||||
]
|
||||
],
|
||||
],
|
||||
|
|
|
@ -0,0 +1,626 @@
|
|||
/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */;
|
||||
/*!40103 SET TIME_ZONE='+00:00' */;
|
||||
/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
|
||||
/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
|
||||
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
|
||||
/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
|
||||
DROP TABLE IF EXISTS `activities`;
|
||||
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||
/*!40101 SET character_set_client = utf8 */;
|
||||
CREATE TABLE `activities` (
|
||||
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
|
||||
`name` varchar(255) NOT NULL,
|
||||
`slug` varchar(255) NOT NULL,
|
||||
`is_filterable` tinyint(1) NOT NULL DEFAULT 0,
|
||||
`is_member` tinyint(1) NOT NULL DEFAULT 0,
|
||||
`is_try` tinyint(1) NOT NULL DEFAULT 0,
|
||||
`nami_id` int(10) unsigned DEFAULT NULL,
|
||||
`has_efz` tinyint(1) NOT NULL DEFAULT 0,
|
||||
PRIMARY KEY (`id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
DROP TABLE IF EXISTS `activity_subactivity`;
|
||||
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||
/*!40101 SET character_set_client = utf8 */;
|
||||
CREATE TABLE `activity_subactivity` (
|
||||
`activity_id` bigint(20) unsigned NOT NULL,
|
||||
`subactivity_id` bigint(20) unsigned NOT NULL,
|
||||
UNIQUE KEY `activity_subactivity_activity_id_subactivity_id_unique` (`activity_id`,`subactivity_id`),
|
||||
KEY `activity_subactivity_subactivity_id_foreign` (`subactivity_id`),
|
||||
CONSTRAINT `activity_subactivity_activity_id_foreign` FOREIGN KEY (`activity_id`) REFERENCES `activities` (`id`),
|
||||
CONSTRAINT `activity_subactivity_subactivity_id_foreign` FOREIGN KEY (`subactivity_id`) REFERENCES `subactivities` (`id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
DROP TABLE IF EXISTS `confessions`;
|
||||
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||
/*!40101 SET character_set_client = utf8 */;
|
||||
CREATE TABLE `confessions` (
|
||||
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
|
||||
`name` varchar(255) NOT NULL,
|
||||
`nami_id` int(10) unsigned DEFAULT NULL,
|
||||
`is_null` tinyint(1) NOT NULL,
|
||||
PRIMARY KEY (`id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
DROP TABLE IF EXISTS `countries`;
|
||||
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||
/*!40101 SET character_set_client = utf8 */;
|
||||
CREATE TABLE `countries` (
|
||||
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
|
||||
`name` varchar(255) NOT NULL,
|
||||
`nami_id` int(10) unsigned DEFAULT NULL,
|
||||
PRIMARY KEY (`id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
DROP TABLE IF EXISTS `course_members`;
|
||||
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||
/*!40101 SET character_set_client = utf8 */;
|
||||
CREATE TABLE `course_members` (
|
||||
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
|
||||
`member_id` bigint(20) unsigned NOT NULL,
|
||||
`course_id` bigint(20) unsigned NOT NULL,
|
||||
`organizer` varchar(255) NOT NULL,
|
||||
`event_name` varchar(255) NOT NULL,
|
||||
`nami_id` int(10) unsigned NOT NULL,
|
||||
`completed_at` date NOT NULL,
|
||||
`created_at` timestamp NULL DEFAULT NULL,
|
||||
`updated_at` timestamp NULL DEFAULT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `course_members_member_id_foreign` (`member_id`),
|
||||
KEY `course_members_course_id_foreign` (`course_id`),
|
||||
CONSTRAINT `course_members_course_id_foreign` FOREIGN KEY (`course_id`) REFERENCES `courses` (`id`),
|
||||
CONSTRAINT `course_members_member_id_foreign` FOREIGN KEY (`member_id`) REFERENCES `members` (`id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
DROP TABLE IF EXISTS `courses`;
|
||||
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||
/*!40101 SET character_set_client = utf8 */;
|
||||
CREATE TABLE `courses` (
|
||||
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
|
||||
`nami_id` int(10) unsigned NOT NULL,
|
||||
`name` varchar(255) NOT NULL,
|
||||
PRIMARY KEY (`id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
DROP TABLE IF EXISTS `failed_jobs`;
|
||||
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||
/*!40101 SET character_set_client = utf8 */;
|
||||
CREATE TABLE `failed_jobs` (
|
||||
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
|
||||
`connection` text NOT NULL,
|
||||
`queue` text NOT NULL,
|
||||
`payload` longtext NOT NULL,
|
||||
`exception` longtext NOT NULL,
|
||||
`failed_at` timestamp NOT NULL DEFAULT current_timestamp(),
|
||||
PRIMARY KEY (`id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
DROP TABLE IF EXISTS `fees`;
|
||||
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||
/*!40101 SET character_set_client = utf8 */;
|
||||
CREATE TABLE `fees` (
|
||||
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
|
||||
`name` varchar(255) NOT NULL,
|
||||
`nami_id` int(10) unsigned NOT NULL,
|
||||
PRIMARY KEY (`id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
DROP TABLE IF EXISTS `genders`;
|
||||
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||
/*!40101 SET character_set_client = utf8 */;
|
||||
CREATE TABLE `genders` (
|
||||
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
|
||||
`name` varchar(255) NOT NULL,
|
||||
`nami_id` int(10) unsigned NOT NULL,
|
||||
`created_at` timestamp NULL DEFAULT NULL,
|
||||
`updated_at` timestamp NULL DEFAULT NULL,
|
||||
PRIMARY KEY (`id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
DROP TABLE IF EXISTS `groups`;
|
||||
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||
/*!40101 SET character_set_client = utf8 */;
|
||||
CREATE TABLE `groups` (
|
||||
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
|
||||
`name` varchar(255) NOT NULL,
|
||||
`nami_id` int(10) unsigned NOT NULL,
|
||||
`parent_id` bigint(20) unsigned DEFAULT NULL,
|
||||
`inner_name` varchar(255) NOT NULL,
|
||||
`level` varchar(255) DEFAULT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `groups_parent_id_foreign` (`parent_id`),
|
||||
CONSTRAINT `groups_parent_id_foreign` FOREIGN KEY (`parent_id`) REFERENCES `groups` (`id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
DROP TABLE IF EXISTS `invoice_positions`;
|
||||
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||
/*!40101 SET character_set_client = utf8 */;
|
||||
CREATE TABLE `invoice_positions` (
|
||||
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
|
||||
`invoice_id` bigint(20) unsigned NOT NULL,
|
||||
`description` varchar(255) NOT NULL,
|
||||
`member_id` bigint(20) unsigned NOT NULL,
|
||||
`price` bigint(20) unsigned NOT NULL,
|
||||
`created_at` timestamp NULL DEFAULT NULL,
|
||||
`updated_at` timestamp NULL DEFAULT NULL,
|
||||
PRIMARY KEY (`id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
DROP TABLE IF EXISTS `invoices`;
|
||||
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||
/*!40101 SET character_set_client = utf8 */;
|
||||
CREATE TABLE `invoices` (
|
||||
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
|
||||
`to` longtext CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL CHECK (json_valid(`to`)),
|
||||
`greeting` varchar(255) NOT NULL,
|
||||
`status` varchar(255) NOT NULL,
|
||||
`sent_at` date DEFAULT NULL,
|
||||
`via` varchar(255) NOT NULL,
|
||||
`usage` varchar(255) NOT NULL,
|
||||
`mail_email` varchar(255) DEFAULT NULL,
|
||||
`last_remembered_at` datetime DEFAULT NULL,
|
||||
`created_at` timestamp NULL DEFAULT NULL,
|
||||
`updated_at` timestamp NULL DEFAULT NULL,
|
||||
PRIMARY KEY (`id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
DROP TABLE IF EXISTS `job_batches`;
|
||||
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||
/*!40101 SET character_set_client = utf8 */;
|
||||
CREATE TABLE `job_batches` (
|
||||
`id` varchar(255) NOT NULL,
|
||||
`name` varchar(255) NOT NULL,
|
||||
`total_jobs` int(11) NOT NULL,
|
||||
`pending_jobs` int(11) NOT NULL,
|
||||
`failed_jobs` int(11) NOT NULL,
|
||||
`failed_job_ids` longtext NOT NULL,
|
||||
`options` mediumtext DEFAULT NULL,
|
||||
`cancelled_at` int(11) DEFAULT NULL,
|
||||
`created_at` int(11) NOT NULL,
|
||||
`finished_at` int(11) DEFAULT NULL,
|
||||
PRIMARY KEY (`id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
DROP TABLE IF EXISTS `localmaildispatchers`;
|
||||
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||
/*!40101 SET character_set_client = utf8 */;
|
||||
CREATE TABLE `localmaildispatchers` (
|
||||
`id` char(36) NOT NULL,
|
||||
`from` varchar(255) NOT NULL,
|
||||
`to` varchar(255) NOT NULL,
|
||||
UNIQUE KEY `localmaildispatchers_from_to_unique` (`from`,`to`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
DROP TABLE IF EXISTS `maildispatchers`;
|
||||
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||
/*!40101 SET character_set_client = utf8 */;
|
||||
CREATE TABLE `maildispatchers` (
|
||||
`id` char(36) NOT NULL,
|
||||
`name` varchar(255) NOT NULL,
|
||||
`gateway_id` char(36) NOT NULL,
|
||||
`filter` longtext CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL CHECK (json_valid(`filter`))
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
DROP TABLE IF EXISTS `mailgateways`;
|
||||
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||
/*!40101 SET character_set_client = utf8 */;
|
||||
CREATE TABLE `mailgateways` (
|
||||
`id` char(36) NOT NULL,
|
||||
`name` varchar(255) NOT NULL,
|
||||
`domain` varchar(255) NOT NULL,
|
||||
`type` longtext CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL CHECK (json_valid(`type`)),
|
||||
`created_at` timestamp NULL DEFAULT NULL,
|
||||
`updated_at` timestamp NULL DEFAULT NULL
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
DROP TABLE IF EXISTS `members`;
|
||||
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||
/*!40101 SET character_set_client = utf8 */;
|
||||
CREATE TABLE `members` (
|
||||
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
|
||||
`firstname` varchar(255) NOT NULL,
|
||||
`lastname` varchar(255) NOT NULL,
|
||||
`nickname` varchar(255) DEFAULT NULL,
|
||||
`gender_id` bigint(20) unsigned DEFAULT NULL,
|
||||
`country_id` bigint(20) unsigned DEFAULT NULL,
|
||||
`other_country` varchar(255) DEFAULT NULL,
|
||||
`confession_id` bigint(20) unsigned DEFAULT NULL,
|
||||
`birthday` date DEFAULT NULL,
|
||||
`joined_at` date DEFAULT NULL,
|
||||
`send_newspaper` tinyint(1) NOT NULL,
|
||||
`address` varchar(255) DEFAULT NULL,
|
||||
`further_address` varchar(255) DEFAULT NULL,
|
||||
`zip` varchar(255) DEFAULT NULL,
|
||||
`location` varchar(255) DEFAULT NULL,
|
||||
`group_id` bigint(20) unsigned NOT NULL,
|
||||
`region_id` bigint(20) unsigned DEFAULT NULL,
|
||||
`main_phone` varchar(255) DEFAULT NULL,
|
||||
`mobile_phone` varchar(255) DEFAULT NULL,
|
||||
`work_phone` varchar(255) DEFAULT NULL,
|
||||
`fax` varchar(255) DEFAULT NULL,
|
||||
`email` varchar(255) DEFAULT NULL,
|
||||
`email_parents` varchar(255) DEFAULT NULL,
|
||||
`nami_id` int(11) DEFAULT NULL,
|
||||
`nationality_id` bigint(20) unsigned DEFAULT NULL,
|
||||
`letter_address` text DEFAULT NULL,
|
||||
`bill_kind` varchar(255) DEFAULT NULL,
|
||||
`version` int(10) unsigned NOT NULL DEFAULT 1,
|
||||
`children_phone` varchar(255) DEFAULT NULL,
|
||||
`subscription_id` bigint(20) unsigned DEFAULT 1,
|
||||
`efz` date DEFAULT NULL,
|
||||
`created_at` timestamp NULL DEFAULT NULL,
|
||||
`updated_at` timestamp NULL DEFAULT NULL,
|
||||
`ps_at` date DEFAULT NULL,
|
||||
`more_ps_at` date DEFAULT NULL,
|
||||
`without_education_at` date DEFAULT NULL,
|
||||
`without_efz_at` date DEFAULT NULL,
|
||||
`has_svk` tinyint(1) NOT NULL DEFAULT 0,
|
||||
`has_vk` tinyint(1) NOT NULL DEFAULT 0,
|
||||
`multiply_pv` tinyint(1) NOT NULL DEFAULT 0,
|
||||
`multiply_more_pv` tinyint(1) NOT NULL DEFAULT 0,
|
||||
`slug` varchar(100) NOT NULL,
|
||||
`salutation` varchar(255) DEFAULT NULL,
|
||||
`comment` text DEFAULT NULL,
|
||||
`mitgliedsnr` varchar(255) DEFAULT NULL,
|
||||
`lat` double DEFAULT NULL,
|
||||
`lon` double DEFAULT NULL,
|
||||
`recertified_at` date DEFAULT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `members_gender_id_foreign` (`gender_id`),
|
||||
KEY `members_country_id_foreign` (`country_id`),
|
||||
KEY `members_confession_id_foreign` (`confession_id`),
|
||||
KEY `members_group_id_foreign` (`group_id`),
|
||||
KEY `members_region_id_foreign` (`region_id`),
|
||||
KEY `members_nationality_id_foreign` (`nationality_id`),
|
||||
KEY `members_bill_kind_id_foreign` (`bill_kind`),
|
||||
KEY `members_subscription_id_foreign` (`subscription_id`),
|
||||
CONSTRAINT `members_confession_id_foreign` FOREIGN KEY (`confession_id`) REFERENCES `confessions` (`id`),
|
||||
CONSTRAINT `members_country_id_foreign` FOREIGN KEY (`country_id`) REFERENCES `countries` (`id`),
|
||||
CONSTRAINT `members_gender_id_foreign` FOREIGN KEY (`gender_id`) REFERENCES `genders` (`id`),
|
||||
CONSTRAINT `members_group_id_foreign` FOREIGN KEY (`group_id`) REFERENCES `groups` (`id`),
|
||||
CONSTRAINT `members_nationality_id_foreign` FOREIGN KEY (`nationality_id`) REFERENCES `nationalities` (`id`),
|
||||
CONSTRAINT `members_region_id_foreign` FOREIGN KEY (`region_id`) REFERENCES `regions` (`id`),
|
||||
CONSTRAINT `members_subscription_id_foreign` FOREIGN KEY (`subscription_id`) REFERENCES `subscriptions` (`id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
DROP TABLE IF EXISTS `memberships`;
|
||||
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||
/*!40101 SET character_set_client = utf8 */;
|
||||
CREATE TABLE `memberships` (
|
||||
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
|
||||
`group_id` bigint(20) unsigned NOT NULL,
|
||||
`member_id` bigint(20) unsigned NOT NULL,
|
||||
`nami_id` int(10) unsigned DEFAULT NULL,
|
||||
`from` datetime NOT NULL,
|
||||
`created_at` timestamp NULL DEFAULT NULL,
|
||||
`updated_at` timestamp NULL DEFAULT NULL,
|
||||
`activity_id` bigint(20) unsigned NOT NULL,
|
||||
`subactivity_id` bigint(20) unsigned DEFAULT NULL,
|
||||
`promised_at` date DEFAULT NULL,
|
||||
`to` datetime DEFAULT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `memberships_unique` (`activity_id`,`subactivity_id`,`group_id`,`member_id`,`nami_id`),
|
||||
KEY `memberships_group_id_foreign` (`group_id`),
|
||||
KEY `memberships_subactivity_id_foreign` (`subactivity_id`),
|
||||
KEY `memberships_member_id_foreign` (`member_id`),
|
||||
CONSTRAINT `memberships_activity_id_foreign` FOREIGN KEY (`activity_id`) REFERENCES `activities` (`id`),
|
||||
CONSTRAINT `memberships_group_id_foreign` FOREIGN KEY (`group_id`) REFERENCES `groups` (`id`),
|
||||
CONSTRAINT `memberships_member_id_foreign` FOREIGN KEY (`member_id`) REFERENCES `members` (`id`),
|
||||
CONSTRAINT `memberships_subactivity_id_foreign` FOREIGN KEY (`subactivity_id`) REFERENCES `subactivities` (`id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
DROP TABLE IF EXISTS `migrations`;
|
||||
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||
/*!40101 SET character_set_client = utf8 */;
|
||||
CREATE TABLE `migrations` (
|
||||
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
|
||||
`migration` varchar(255) NOT NULL,
|
||||
`batch` int(11) NOT NULL,
|
||||
PRIMARY KEY (`id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
DROP TABLE IF EXISTS `nationalities`;
|
||||
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||
/*!40101 SET character_set_client = utf8 */;
|
||||
CREATE TABLE `nationalities` (
|
||||
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
|
||||
`name` varchar(255) NOT NULL,
|
||||
`nami_id` int(10) unsigned NOT NULL,
|
||||
`created_at` timestamp NULL DEFAULT NULL,
|
||||
`updated_at` timestamp NULL DEFAULT NULL,
|
||||
PRIMARY KEY (`id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
DROP TABLE IF EXISTS `oauth_access_tokens`;
|
||||
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||
/*!40101 SET character_set_client = utf8 */;
|
||||
CREATE TABLE `oauth_access_tokens` (
|
||||
`id` varchar(100) NOT NULL,
|
||||
`user_id` bigint(20) unsigned DEFAULT NULL,
|
||||
`client_id` bigint(20) unsigned NOT NULL,
|
||||
`name` varchar(255) DEFAULT NULL,
|
||||
`scopes` text DEFAULT NULL,
|
||||
`revoked` tinyint(1) NOT NULL,
|
||||
`created_at` timestamp NULL DEFAULT NULL,
|
||||
`updated_at` timestamp NULL DEFAULT NULL,
|
||||
`expires_at` datetime DEFAULT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `oauth_access_tokens_user_id_index` (`user_id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
DROP TABLE IF EXISTS `oauth_auth_codes`;
|
||||
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||
/*!40101 SET character_set_client = utf8 */;
|
||||
CREATE TABLE `oauth_auth_codes` (
|
||||
`id` varchar(100) NOT NULL,
|
||||
`user_id` bigint(20) unsigned NOT NULL,
|
||||
`client_id` bigint(20) unsigned NOT NULL,
|
||||
`scopes` text DEFAULT NULL,
|
||||
`revoked` tinyint(1) NOT NULL,
|
||||
`expires_at` datetime DEFAULT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `oauth_auth_codes_user_id_index` (`user_id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
DROP TABLE IF EXISTS `oauth_clients`;
|
||||
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||
/*!40101 SET character_set_client = utf8 */;
|
||||
CREATE TABLE `oauth_clients` (
|
||||
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
|
||||
`user_id` bigint(20) unsigned DEFAULT NULL,
|
||||
`name` varchar(255) NOT NULL,
|
||||
`secret` varchar(100) DEFAULT NULL,
|
||||
`provider` varchar(255) DEFAULT NULL,
|
||||
`redirect` text NOT NULL,
|
||||
`personal_access_client` tinyint(1) NOT NULL,
|
||||
`password_client` tinyint(1) NOT NULL,
|
||||
`revoked` tinyint(1) NOT NULL,
|
||||
`created_at` timestamp NULL DEFAULT NULL,
|
||||
`updated_at` timestamp NULL DEFAULT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `oauth_clients_user_id_index` (`user_id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
DROP TABLE IF EXISTS `oauth_personal_access_clients`;
|
||||
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||
/*!40101 SET character_set_client = utf8 */;
|
||||
CREATE TABLE `oauth_personal_access_clients` (
|
||||
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
|
||||
`client_id` bigint(20) unsigned NOT NULL,
|
||||
`created_at` timestamp NULL DEFAULT NULL,
|
||||
`updated_at` timestamp NULL DEFAULT NULL,
|
||||
PRIMARY KEY (`id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
DROP TABLE IF EXISTS `oauth_refresh_tokens`;
|
||||
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||
/*!40101 SET character_set_client = utf8 */;
|
||||
CREATE TABLE `oauth_refresh_tokens` (
|
||||
`id` varchar(100) NOT NULL,
|
||||
`access_token_id` varchar(100) NOT NULL,
|
||||
`revoked` tinyint(1) NOT NULL,
|
||||
`expires_at` datetime DEFAULT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `oauth_refresh_tokens_access_token_id_index` (`access_token_id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
DROP TABLE IF EXISTS `password_resets`;
|
||||
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||
/*!40101 SET character_set_client = utf8 */;
|
||||
CREATE TABLE `password_resets` (
|
||||
`email` varchar(255) NOT NULL,
|
||||
`token` varchar(255) NOT NULL,
|
||||
`created_at` timestamp NULL DEFAULT NULL,
|
||||
KEY `password_resets_email_index` (`email`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
DROP TABLE IF EXISTS `regions`;
|
||||
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||
/*!40101 SET character_set_client = utf8 */;
|
||||
CREATE TABLE `regions` (
|
||||
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
|
||||
`name` varchar(255) NOT NULL,
|
||||
`is_null` tinyint(1) NOT NULL,
|
||||
`nami_id` int(10) unsigned DEFAULT NULL,
|
||||
PRIMARY KEY (`id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
DROP TABLE IF EXISTS `settings`;
|
||||
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||
/*!40101 SET character_set_client = utf8 */;
|
||||
CREATE TABLE `settings` (
|
||||
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
|
||||
`group` varchar(255) NOT NULL,
|
||||
`name` varchar(255) NOT NULL,
|
||||
`locked` tinyint(1) NOT NULL,
|
||||
`payload` longtext CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL CHECK (json_valid(`payload`)),
|
||||
`created_at` timestamp NULL DEFAULT NULL,
|
||||
`updated_at` timestamp NULL DEFAULT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `settings_group_index` (`group`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
DROP TABLE IF EXISTS `statuses`;
|
||||
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||
/*!40101 SET character_set_client = utf8 */;
|
||||
CREATE TABLE `statuses` (
|
||||
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
|
||||
`name` varchar(255) NOT NULL,
|
||||
`is_bill` tinyint(1) NOT NULL,
|
||||
`is_remember` tinyint(1) NOT NULL,
|
||||
PRIMARY KEY (`id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
DROP TABLE IF EXISTS `subactivities`;
|
||||
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||
/*!40101 SET character_set_client = utf8 */;
|
||||
CREATE TABLE `subactivities` (
|
||||
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
|
||||
`name` varchar(255) NOT NULL,
|
||||
`slug` varchar(255) NOT NULL,
|
||||
`is_age_group` tinyint(1) NOT NULL DEFAULT 0,
|
||||
`is_filterable` tinyint(1) NOT NULL DEFAULT 0,
|
||||
`nami_id` int(10) unsigned DEFAULT NULL,
|
||||
PRIMARY KEY (`id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
DROP TABLE IF EXISTS `subscription_children`;
|
||||
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||
/*!40101 SET character_set_client = utf8 */;
|
||||
CREATE TABLE `subscription_children` (
|
||||
`id` char(36) NOT NULL,
|
||||
`parent_id` bigint(20) unsigned NOT NULL,
|
||||
`name` varchar(255) NOT NULL,
|
||||
`amount` int(10) unsigned NOT NULL,
|
||||
KEY `subscription_children_parent_id_foreign` (`parent_id`),
|
||||
CONSTRAINT `subscription_children_parent_id_foreign` FOREIGN KEY (`parent_id`) REFERENCES `subscriptions` (`id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
DROP TABLE IF EXISTS `subscriptions`;
|
||||
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||
/*!40101 SET character_set_client = utf8 */;
|
||||
CREATE TABLE `subscriptions` (
|
||||
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
|
||||
`name` varchar(255) NOT NULL,
|
||||
`fee_id` bigint(20) unsigned NOT NULL,
|
||||
`created_at` timestamp NULL DEFAULT NULL,
|
||||
`updated_at` timestamp NULL DEFAULT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `subscriptions_fee_id_foreign` (`fee_id`),
|
||||
CONSTRAINT `subscriptions_fee_id_foreign` FOREIGN KEY (`fee_id`) REFERENCES `fees` (`id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
DROP TABLE IF EXISTS `telescope_entries`;
|
||||
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||
/*!40101 SET character_set_client = utf8 */;
|
||||
CREATE TABLE `telescope_entries` (
|
||||
`sequence` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
|
||||
`uuid` char(36) NOT NULL,
|
||||
`batch_id` char(36) NOT NULL,
|
||||
`family_hash` varchar(255) DEFAULT NULL,
|
||||
`should_display_on_index` tinyint(1) NOT NULL DEFAULT 1,
|
||||
`type` varchar(20) NOT NULL,
|
||||
`content` longtext NOT NULL,
|
||||
`created_at` datetime DEFAULT NULL,
|
||||
PRIMARY KEY (`sequence`),
|
||||
UNIQUE KEY `telescope_entries_uuid_unique` (`uuid`),
|
||||
KEY `telescope_entries_batch_id_index` (`batch_id`),
|
||||
KEY `telescope_entries_family_hash_index` (`family_hash`),
|
||||
KEY `telescope_entries_created_at_index` (`created_at`),
|
||||
KEY `telescope_entries_type_should_display_on_index_index` (`type`,`should_display_on_index`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
DROP TABLE IF EXISTS `telescope_entries_tags`;
|
||||
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||
/*!40101 SET character_set_client = utf8 */;
|
||||
CREATE TABLE `telescope_entries_tags` (
|
||||
`entry_uuid` char(36) NOT NULL,
|
||||
`tag` varchar(255) NOT NULL,
|
||||
KEY `telescope_entries_tags_entry_uuid_tag_index` (`entry_uuid`,`tag`),
|
||||
KEY `telescope_entries_tags_tag_index` (`tag`),
|
||||
CONSTRAINT `telescope_entries_tags_entry_uuid_foreign` FOREIGN KEY (`entry_uuid`) REFERENCES `telescope_entries` (`uuid`) ON DELETE CASCADE
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
DROP TABLE IF EXISTS `telescope_monitoring`;
|
||||
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||
/*!40101 SET character_set_client = utf8 */;
|
||||
CREATE TABLE `telescope_monitoring` (
|
||||
`tag` varchar(255) NOT NULL
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
DROP TABLE IF EXISTS `users`;
|
||||
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||
/*!40101 SET character_set_client = utf8 */;
|
||||
CREATE TABLE `users` (
|
||||
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
|
||||
`email` varchar(255) NOT NULL,
|
||||
`name` varchar(255) NOT NULL,
|
||||
`password` varchar(255) NOT NULL,
|
||||
`created_at` timestamp NULL DEFAULT NULL,
|
||||
`updated_at` timestamp NULL DEFAULT NULL,
|
||||
`email_verified_at` timestamp NULL DEFAULT NULL,
|
||||
`remember_token` varchar(100) DEFAULT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `users_email_unique` (`email`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
DROP TABLE IF EXISTS `ways`;
|
||||
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||
/*!40101 SET character_set_client = utf8 */;
|
||||
CREATE TABLE `ways` (
|
||||
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
|
||||
`title` varchar(255) NOT NULL,
|
||||
PRIMARY KEY (`id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;
|
||||
|
||||
/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
|
||||
/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
|
||||
/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;
|
||||
/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
|
||||
|
||||
INSERT INTO `migrations` VALUES (1,'2010_08_08_100000_create_telescope_entries_table',1);
|
||||
INSERT INTO `migrations` VALUES (2,'2010_08_19_000000_create_failed_jobs_table',1);
|
||||
INSERT INTO `migrations` VALUES (3,'2014_10_12_100000_create_password_resets_table',1);
|
||||
INSERT INTO `migrations` VALUES (4,'2016_06_01_000001_create_oauth_auth_codes_table',1);
|
||||
INSERT INTO `migrations` VALUES (5,'2016_06_01_000002_create_oauth_access_tokens_table',1);
|
||||
INSERT INTO `migrations` VALUES (6,'2016_06_01_000003_create_oauth_refresh_tokens_table',1);
|
||||
INSERT INTO `migrations` VALUES (7,'2016_06_01_000004_create_oauth_clients_table',1);
|
||||
INSERT INTO `migrations` VALUES (8,'2016_06_01_000005_create_oauth_personal_access_clients_table',1);
|
||||
INSERT INTO `migrations` VALUES (9,'2017_01_14_235348_create_nationalities_table',1);
|
||||
INSERT INTO `migrations` VALUES (10,'2017_01_22_235143_create_subscriptions_table',1);
|
||||
INSERT INTO `migrations` VALUES (11,'2017_04_12_010000_create_groups_table',1);
|
||||
INSERT INTO `migrations` VALUES (12,'2017_07_04_235624_create_countries_table',1);
|
||||
INSERT INTO `migrations` VALUES (13,'2017_07_05_000438_create_genders_table',1);
|
||||
INSERT INTO `migrations` VALUES (14,'2017_07_05_000810_create_regions_table',1);
|
||||
INSERT INTO `migrations` VALUES (15,'2017_07_05_001729_create_confessions_table',1);
|
||||
INSERT INTO `migrations` VALUES (16,'2017_12_25_231219_create_ways_table',1);
|
||||
INSERT INTO `migrations` VALUES (17,'2018_01_16_012910_create_activities_table',1);
|
||||
INSERT INTO `migrations` VALUES (18,'2020_04_12_223230_create_members_table',1);
|
||||
INSERT INTO `migrations` VALUES (19,'2021_07_04_101300_create_payments_table',1);
|
||||
INSERT INTO `migrations` VALUES (20,'2021_11_18_001427_create_courses_table',1);
|
||||
INSERT INTO `migrations` VALUES (21,'2021_11_18_215522_create_settings_table',1);
|
||||
INSERT INTO `migrations` VALUES (22,'2021_11_18_230152_create_general_settings',1);
|
||||
INSERT INTO `migrations` VALUES (23,'2021_11_22_233113_create_allowed_nami_login_setting',1);
|
||||
INSERT INTO `migrations` VALUES (24,'2021_11_23_173033_create_users_table',1);
|
||||
INSERT INTO `migrations` VALUES (25,'2022_01_18_205354_create_memberships_table',1);
|
||||
INSERT INTO `migrations` VALUES (26,'2022_02_17_011021_create_groups_parent_id_column',1);
|
||||
INSERT INTO `migrations` VALUES (27,'2022_02_19_230152_create_nami_settings',1);
|
||||
INSERT INTO `migrations` VALUES (28,'2022_03_15_152907_create_members_efz_column',1);
|
||||
INSERT INTO `migrations` VALUES (29,'2022_03_20_145006_create_activities_has_efz_column',1);
|
||||
INSERT INTO `migrations` VALUES (30,'2022_04_28_203444_create_members_prevention_column',1);
|
||||
INSERT INTO `migrations` VALUES (31,'2022_05_01_185012_create_nami_settings_group',1);
|
||||
INSERT INTO `migrations` VALUES (32,'2022_08_30_132503_create_users_email_verified_add_column',1);
|
||||
INSERT INTO `migrations` VALUES (33,'2022_09_05_213938_bill_settings',1);
|
||||
INSERT INTO `migrations` VALUES (34,'2022_10_05_171451_create_members_slug_column',1);
|
||||
INSERT INTO `migrations` VALUES (35,'2022_10_18_123917_mailman_settings',1);
|
||||
INSERT INTO `migrations` VALUES (36,'2022_10_18_123918_mailman_is_active',1);
|
||||
INSERT INTO `migrations` VALUES (37,'2022_10_18_123919_mailman_lists',1);
|
||||
INSERT INTO `migrations` VALUES (38,'2022_11_05_213938_iban_settings',1);
|
||||
INSERT INTO `migrations` VALUES (39,'2022_11_08_154408_create_memberships_activity_column',1);
|
||||
INSERT INTO `migrations` VALUES (40,'2022_11_23_220958_drop_members_confirmed_at_column',1);
|
||||
INSERT INTO `migrations` VALUES (41,'2022_12_06_211901_edit_members_bill_kind_id_column',1);
|
||||
INSERT INTO `migrations` VALUES (42,'2022_12_11_192600_create_memberships_has_promise_column',1);
|
||||
INSERT INTO `migrations` VALUES (43,'2022_12_13_203644_create_subscription_children_table',1);
|
||||
INSERT INTO `migrations` VALUES (44,'2023_02_05_233824_create_memberships_to_column',1);
|
||||
INSERT INTO `migrations` VALUES (45,'2023_02_05_235353_edit_activities_nami_id_column',1);
|
||||
INSERT INTO `migrations` VALUES (46,'2023_02_12_223932_create_job_batches_table',1);
|
||||
INSERT INTO `migrations` VALUES (47,'2023_02_26_192658_create_members_search_column',1);
|
||||
INSERT INTO `migrations` VALUES (48,'2023_02_27_213656_create_members_salutation_column',1);
|
||||
INSERT INTO `migrations` VALUES (49,'2023_02_27_221231_create_members_comment_column',1);
|
||||
INSERT INTO `migrations` VALUES (50,'2023_03_02_220832_create_members_mitgliedsnr_column',1);
|
||||
INSERT INTO `migrations` VALUES (51,'2023_03_05_230539_edit_members_birthday_column',1);
|
||||
INSERT INTO `migrations` VALUES (52,'2023_03_05_231245_edit_members_address_column',1);
|
||||
INSERT INTO `migrations` VALUES (53,'2023_05_01_185012_create_nami_search_setting',1);
|
||||
INSERT INTO `migrations` VALUES (54,'2023_05_16_113849_create_members_latlon_column',1);
|
||||
INSERT INTO `migrations` VALUES (55,'2023_06_01_102056_create_mailgateways_table',1);
|
||||
INSERT INTO `migrations` VALUES (56,'2023_06_12_083133_create_maildispatchers_table',1);
|
||||
INSERT INTO `migrations` VALUES (57,'2023_06_12_093205_create_localmaildispatchers_table',1);
|
||||
INSERT INTO `migrations` VALUES (58,'2023_07_23_203851_edit_members_table',1);
|
||||
INSERT INTO `migrations` VALUES (59,'2023_11_16_101137_create_module_settings',1);
|
||||
INSERT INTO `migrations` VALUES (60,'2023_11_23_001310_create_invoice_data_column',1);
|
||||
INSERT INTO `migrations` VALUES (61,'2023_11_24_131853_create_members_recertified_at_column',1);
|
||||
INSERT INTO `migrations` VALUES (62,'2023_12_12_015320_create_invoices_table',1);
|
||||
INSERT INTO `migrations` VALUES (63,'2023_12_30_012316_create_groups_inner_name_column',1);
|
||||
INSERT INTO `migrations` VALUES (64,'2024_01_25_213922_drop_members_search_text_column',1);
|
|
@ -104,8 +104,7 @@ services:
|
|||
|
||||
meilisearch:
|
||||
image: getmeili/meilisearch:v1.6
|
||||
command: 'meilisearch --master-key="abc"'
|
||||
volumes:
|
||||
- ./data/meilisearch:/meili_data
|
||||
ports:
|
||||
- '7700:7700'
|
||||
env_file:
|
||||
- .app.env
|
||||
|
|
|
@ -340,7 +340,6 @@ export default {
|
|||
}
|
||||
},
|
||||
onInput(v) {
|
||||
console.log(this.modelModifiers);
|
||||
if (this.mode === 'none') {
|
||||
this.transformedValue = v.target.value;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,21 @@
|
|||
import {inject} from 'vue';
|
||||
|
||||
export default function useSearch() {
|
||||
const axios = inject('axios');
|
||||
async function search(text, filters = []) {
|
||||
var response = await axios.post(
|
||||
document.querySelector('meta[name="meilisearch_baseurl"]').content + '/indexes/members/search',
|
||||
{
|
||||
q: text,
|
||||
filter: filters,
|
||||
},
|
||||
{headers: {Authorization: 'Bearer ' + document.querySelector('meta[name="meilisearch_key"]').content}}
|
||||
);
|
||||
|
||||
return response.data;
|
||||
}
|
||||
|
||||
return {
|
||||
search,
|
||||
};
|
||||
}
|
|
@ -1,69 +1,49 @@
|
|||
<template>
|
||||
<page-layout>
|
||||
<form target="_BLANK" class="max-w-4xl w-full mx-auto gap-6 grid-cols-2 grid p-6">
|
||||
<f-text id="eventName" v-model="values.eventName" name="eventName" class="col-span-2" label="Veranstaltungs-Name" required></f-text>
|
||||
<f-text id="eventName" v-model="values.eventName" name="eventName" class="col-span-2"
|
||||
label="Veranstaltungs-Name" required></f-text>
|
||||
<f-text id="dateFrom" v-model="values.dateFrom" name="dateFrom" type="date" label="Datum von" required></f-text>
|
||||
<f-text id="dateUntil" v-model="values.dateUntil" name="dateUntil" type="date" label="Datum bis" required></f-text>
|
||||
<f-text id="dateUntil" v-model="values.dateUntil" name="dateUntil" type="date" label="Datum bis"
|
||||
required></f-text>
|
||||
|
||||
<f-text id="zipLocation" v-model="values.zipLocation" name="zipLocation" label="PLZ / Ort" required></f-text>
|
||||
<f-select id="country" v-model="values.country" :options="countries" name="country" label="Land" required></f-select>
|
||||
<f-select id="country" v-model="values.country" :options="countries" name="country" label="Land"
|
||||
required></f-select>
|
||||
|
||||
<div class="border-gray-200 shadow shadow-primary-700 p-3 shadow-[0_0_4px_gray] col-span-2">
|
||||
<f-text
|
||||
id="search_text"
|
||||
ref="search_text_field"
|
||||
v-model="searchText"
|
||||
class="col-span-2"
|
||||
name="search_text"
|
||||
label="Suchen …"
|
||||
size="sm"
|
||||
@keypress.enter.prevent="onSubmitFirstMemberResult"
|
||||
></f-text>
|
||||
<f-text id="search_text" ref="searchTextField" v-model="searchText" class="col-span-2" name="search_text"
|
||||
label="Suchen …" size="sm" @keypress.enter.prevent="onSubmitFirstMemberResult"></f-text>
|
||||
<div class="mt-2 grid grid-cols-[repeat(auto-fill,minmax(180px,1fr))] gap-2 col-span-2">
|
||||
<f-switch
|
||||
v-for="member in search.results"
|
||||
:id="`members-${member.id}`"
|
||||
:key="member.id"
|
||||
v-model="values.members"
|
||||
:label="`${member.firstname} ${member.lastname}`"
|
||||
name="members[]"
|
||||
:value="member.id"
|
||||
size="sm"
|
||||
inline
|
||||
@keypress.enter.prevent="onSubmitMemberResult(member)"
|
||||
></f-switch>
|
||||
<f-switch v-for="member in results" :id="`members-${member.id}`" :key="member.id"
|
||||
v-model="values.members" :label="member.fullname" name="members[]" :value="member.id" size="sm"
|
||||
inline @keypress.enter.prevent="onSubmitMemberResult(member)"></f-switch>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<button
|
||||
v-for="(compiler, index) in compilers"
|
||||
class="btn btn-primary mt-3 inline-block"
|
||||
@click.prevent="
|
||||
values.type = compiler.class;
|
||||
submit();
|
||||
"
|
||||
v-text="compiler.title"
|
||||
></button>
|
||||
<button v-for="(compiler, index) in compilers" class="btn btn-primary mt-3 inline-block"
|
||||
@click.prevent="submit(compiler.class)" v-text="compiler.title"></button>
|
||||
</form>
|
||||
</page-layout>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import debounce from 'lodash/debounce';
|
||||
<script setup>
|
||||
import { ref, computed, inject } from 'vue';
|
||||
import useSearch from '../../composables/useSearch.js';
|
||||
const axios = inject('axios');
|
||||
|
||||
export default {
|
||||
props: {
|
||||
const { search } = useSearch();
|
||||
|
||||
const props = defineProps({
|
||||
data: {},
|
||||
countries: {},
|
||||
compilers: {},
|
||||
},
|
||||
data: function () {
|
||||
return {
|
||||
search: {
|
||||
s: '',
|
||||
results: [],
|
||||
},
|
||||
values: {
|
||||
});
|
||||
|
||||
const searchRaw = ref('');
|
||||
const results = ref([]);
|
||||
const searchTextField = ref([]);
|
||||
const values = ref({
|
||||
type: null,
|
||||
members: [],
|
||||
event_name: '',
|
||||
|
@ -71,64 +51,40 @@ export default {
|
|||
dateUntil: '',
|
||||
zipLocation: '',
|
||||
country: null,
|
||||
...this.data,
|
||||
},
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
searchText: {
|
||||
get() {
|
||||
return this.search.s;
|
||||
},
|
||||
set: function (event) {
|
||||
this.search.s = event;
|
||||
...props.data,
|
||||
});
|
||||
|
||||
debounce(async () => {
|
||||
var response = await this.axios.post(
|
||||
'/api/member/search',
|
||||
{
|
||||
filter: {
|
||||
search: event,
|
||||
hasBirthday: true,
|
||||
hasFullAddress: true,
|
||||
},
|
||||
},
|
||||
{headers: {'X-Meta': 'false'}}
|
||||
);
|
||||
const searchText = computed({
|
||||
get: () => searchRaw.value,
|
||||
set: async (v) => {
|
||||
searchRaw.value = v;
|
||||
|
||||
this.search.results = response.data.data;
|
||||
}, 300)();
|
||||
results.value = (await search(v, ['birthday IS NOT NULL', 'address IS NOT EMPTY'])).hits;
|
||||
},
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
async submit() {
|
||||
try {
|
||||
await this.axios.post('/contribution-validate', this.values);
|
||||
var payload = btoa(encodeURIComponent(JSON.stringify(this.values)));
|
||||
});
|
||||
|
||||
async function submit(compiler) {
|
||||
values.value.type = compiler;
|
||||
await axios.post('/contribution-validate', values.value);
|
||||
var payload = btoa(encodeURIComponent(JSON.stringify(values.value)));
|
||||
window.open(`/contribution-generate?payload=${payload}`);
|
||||
} catch (e) {
|
||||
this.errorsFromException(e);
|
||||
}
|
||||
},
|
||||
onSubmitMemberResult(selected) {
|
||||
if (this.values.members.find((m) => m === selected.id) !== undefined) {
|
||||
this.values.members = this.values.members.filter((m) => m === selected.id);
|
||||
}
|
||||
function onSubmitMemberResult(selected) {
|
||||
if (values.value.members.find((m) => m === selected.id) !== undefined) {
|
||||
values.value.members = values.value.members.filter((m) => m !== selected.id);
|
||||
} else {
|
||||
this.values.members.push(selected.id);
|
||||
values.value.members.push(selected.id);
|
||||
}
|
||||
|
||||
this.searchText = '';
|
||||
this.$refs.search_text_field.$el.querySelector('input').focus();
|
||||
},
|
||||
onSubmitFirstMemberResult() {
|
||||
if (this.search.results.length === 0) {
|
||||
this.searchText = '';
|
||||
searchRaw.value = '';
|
||||
searchTextField.value.$el.querySelector('input').focus();
|
||||
}
|
||||
function onSubmitFirstMemberResult() {
|
||||
if (results.value.length === 0) {
|
||||
searchRaw.value = '';
|
||||
return;
|
||||
}
|
||||
|
||||
this.onSubmitMemberResult(this.search.results[0]);
|
||||
},
|
||||
},
|
||||
};
|
||||
onSubmitMemberResult(results.value[0]);
|
||||
}
|
||||
</script>
|
||||
|
|
|
@ -10,27 +10,56 @@
|
|||
<ui-box heading="Metadatem">
|
||||
<div class="grid gap-4 sm:grid-cols-2">
|
||||
<f-text id="name" v-model="model.name" name="name" label="Name" size="sm" required></f-text>
|
||||
<f-select id="gateway_id" v-model="model.gateway_id" name="gateway_id" :options="meta.gateways"
|
||||
label="Verbindung" size="sm" required></f-select>
|
||||
<f-select id="gateway_id" v-model="model.gateway_id" name="gateway_id" :options="meta.gateways" label="Verbindung" size="sm" required></f-select>
|
||||
</div>
|
||||
</ui-box>
|
||||
<ui-box v-if="members !== null" heading="Filterregeln">
|
||||
<div class="grid gap-4 sm:grid-cols-2">
|
||||
<f-multipleselect id="activity_ids" v-model="model.filter.activity_ids" name="activity_ids"
|
||||
:options="members.meta.filterActivities" label="Tätigkeit" size="sm"
|
||||
@update:model-value="reload(1)"></f-multipleselect>
|
||||
<f-multipleselect id="subactivity_ids" v-model="model.filter.subactivity_ids" name="subactivity_ids"
|
||||
:options="members.meta.filterSubactivities" label="Unterttätigkeit" size="sm"
|
||||
@update:model-value="reload(1)"></f-multipleselect>
|
||||
<f-multipleselect id="include" v-model="model.filter.include" name="include"
|
||||
:options="members.meta.members" label="Zusätzliche Mitglieder" size="sm"
|
||||
@update:model-value="reload(1)"></f-multipleselect>
|
||||
<f-multipleselect id="exclude" v-model="model.filter.exclude" name="exclude"
|
||||
:options="members.meta.members" label="Mitglieder ausschließen" size="sm"
|
||||
@update:model-value="reload(1)"></f-multipleselect>
|
||||
<f-multipleselect id="groupIds" v-model="model.filter.group_ids" name="groupIds"
|
||||
:options="members.meta.groups" label="Gruppierungen" size="sm"
|
||||
@update:model-value="reload(1)"></f-multipleselect>
|
||||
<f-multipleselect
|
||||
id="activity_ids"
|
||||
v-model="model.filter.activity_ids"
|
||||
name="activity_ids"
|
||||
:options="members.meta.filterActivities"
|
||||
label="Tätigkeit"
|
||||
size="sm"
|
||||
@update:model-value="reload(1)"
|
||||
></f-multipleselect>
|
||||
<f-multipleselect
|
||||
id="subactivity_ids"
|
||||
v-model="model.filter.subactivity_ids"
|
||||
name="subactivity_ids"
|
||||
:options="members.meta.filterSubactivities"
|
||||
label="Unterttätigkeit"
|
||||
size="sm"
|
||||
@update:model-value="reload(1)"
|
||||
></f-multipleselect>
|
||||
<f-multipleselect
|
||||
id="include"
|
||||
v-model="model.filter.include"
|
||||
name="include"
|
||||
:options="members.meta.members"
|
||||
label="Zusätzliche Mitglieder"
|
||||
size="sm"
|
||||
@update:model-value="reload(1)"
|
||||
></f-multipleselect>
|
||||
<f-multipleselect
|
||||
id="exclude"
|
||||
v-model="model.filter.exclude"
|
||||
name="exclude"
|
||||
:options="members.meta.members"
|
||||
label="Mitglieder ausschließen"
|
||||
size="sm"
|
||||
@update:model-value="reload(1)"
|
||||
></f-multipleselect>
|
||||
<f-multipleselect
|
||||
id="groupIds"
|
||||
v-model="model.filter.group_ids"
|
||||
name="groupIds"
|
||||
:options="members.meta.groups"
|
||||
label="Gruppierungen"
|
||||
size="sm"
|
||||
@update:model-value="reload(1)"
|
||||
></f-multipleselect>
|
||||
</div>
|
||||
</ui-box>
|
||||
<ui-box v-if="members !== null" heading="Mitglieder">
|
||||
|
@ -58,8 +87,8 @@
|
|||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, inject, defineProps } from 'vue';
|
||||
import { useIndex } from '../../composables/useIndex.js';
|
||||
import {ref, inject, defineProps} from 'vue';
|
||||
import {useIndex} from '../../composables/useIndex.js';
|
||||
|
||||
const props = defineProps({
|
||||
data: {
|
||||
|
@ -68,21 +97,21 @@ const props = defineProps({
|
|||
},
|
||||
meta: {
|
||||
type: Object,
|
||||
default: () => { },
|
||||
default: () => {},
|
||||
},
|
||||
});
|
||||
|
||||
const { toFilterString, router } = useIndex({ data: [], meta: {} }, 'maildispatcher');
|
||||
const {router} = useIndex({data: [], meta: {}}, 'maildispatcher');
|
||||
|
||||
const model = ref(props.data === undefined ? { ...props.meta.default_model } : { ...props.data });
|
||||
const model = ref(props.data === undefined ? {...props.meta.default_model} : {...props.data});
|
||||
const members = ref(null);
|
||||
const axios = inject('axios');
|
||||
|
||||
async function reload(page) {
|
||||
members.value = (
|
||||
await axios.post('/api/member/search', {
|
||||
page: page || 1,
|
||||
filter: toFilterString(model.value.filter),
|
||||
page: page,
|
||||
filter: model.value.filter,
|
||||
})
|
||||
).data;
|
||||
}
|
||||
|
|
|
@ -4,6 +4,10 @@
|
|||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0" />
|
||||
<meta name="socketport" content="{{env('SOCKET_PORT')}}" />
|
||||
@if(auth()->id())
|
||||
<meta name="meilisearch_key" content="{{config('scout.meilisearch.key')}}" />
|
||||
<meta name="meilisearch_baseurl" content="http://localhost:7700" />
|
||||
@endif
|
||||
@vite('resources/js/app.js')
|
||||
</head>
|
||||
<body class="min-h-full flex flex-col">
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<?php
|
||||
|
||||
namespace Tests\Feature\Maildispatcher;
|
||||
namespace Tests\EndToEnd\Maildispatcher;
|
||||
|
||||
use \Mockery as M;
|
||||
use App\Activity;
|
||||
|
@ -10,12 +10,10 @@ use App\Mailgateway\Models\Mailgateway;
|
|||
use App\Mailgateway\Types\LocalType;
|
||||
use App\Member\Member;
|
||||
use App\Member\Membership;
|
||||
use Illuminate\Foundation\Testing\DatabaseTransactions;
|
||||
use Tests\TestCase;
|
||||
use Tests\EndToEndTestCase;
|
||||
|
||||
class StoreTest extends TestCase
|
||||
class StoreTest extends EndToEndTestCase
|
||||
{
|
||||
use DatabaseTransactions;
|
||||
|
||||
public function setUp(): void
|
||||
{
|
||||
|
@ -31,6 +29,7 @@ class StoreTest extends TestCase
|
|||
Member::factory()->defaults()->has(Membership::factory()->inLocal('Leiter*in', 'Wölfling'))->create(['email' => 'jane@example.com']);
|
||||
$activityId = Activity::first()->id;
|
||||
|
||||
sleep(1);
|
||||
$response = $this->postJson('/maildispatcher', [
|
||||
'name' => 'test',
|
||||
'gateway_id' => $gateway->id,
|
||||
|
@ -61,6 +60,7 @@ class StoreTest extends TestCase
|
|||
Member::factory()->defaults()->create(['email' => 'jane@example.com']);
|
||||
Member::factory()->defaults()->create(['email' => 'jane@example.com']);
|
||||
|
||||
sleep(1);
|
||||
$this->postJson('/maildispatcher', [
|
||||
'name' => 'test',
|
||||
'gateway_id' => $gateway->id,
|
||||
|
@ -73,6 +73,7 @@ class StoreTest extends TestCase
|
|||
$gateway = Mailgateway::factory()->type(LocalType::class, [])->create();
|
||||
Member::factory()->defaults()->create(['email' => 'Jane@example.com']);
|
||||
|
||||
sleep(1);
|
||||
$this->postJson('/maildispatcher', [
|
||||
'name' => 'test',
|
||||
'gateway_id' => $gateway->id,
|
|
@ -1,6 +1,6 @@
|
|||
<?php
|
||||
|
||||
namespace Tests\Feature\Maildispatcher;
|
||||
namespace Tests\EndToEnd\Maildispatcher;
|
||||
|
||||
use App\Maildispatcher\Actions\ResyncAction;
|
||||
use App\Maildispatcher\Models\Maildispatcher;
|
||||
|
@ -8,13 +8,11 @@ use App\Mailgateway\Models\Mailgateway;
|
|||
use App\Mailgateway\Types\LocalType;
|
||||
use App\Member\FilterScope;
|
||||
use App\Member\Member;
|
||||
use Illuminate\Foundation\Testing\DatabaseTransactions;
|
||||
use Tests\TestCase;
|
||||
use Illuminate\Foundation\Testing\DatabaseMigrations;
|
||||
use Tests\EndToEndTestCase;
|
||||
|
||||
class UpdateTest extends TestCase
|
||||
class UpdateTest extends EndToEndTestCase
|
||||
{
|
||||
use DatabaseTransactions;
|
||||
|
||||
public function setUp(): void
|
||||
{
|
||||
parent::setUp();
|
||||
|
@ -24,13 +22,15 @@ class UpdateTest extends TestCase
|
|||
|
||||
public function testItCanUpdateFilters(): void
|
||||
{
|
||||
$this->withoutExceptionHandling();
|
||||
$dispatcher = Maildispatcher::factory()
|
||||
->for(Mailgateway::factory()->type(LocalType::class, [])->domain('example.com'), 'gateway')
|
||||
->filter(FilterScope::from([]))
|
||||
->create();
|
||||
Member::factory()->defaults()->create(['email' => 'to@example.com']);
|
||||
|
||||
$response = $this->patchJson("/maildispatcher/{$dispatcher->id}", [
|
||||
sleep(1);
|
||||
$this->patchJson("/maildispatcher/{$dispatcher->id}", [
|
||||
'name' => 'test',
|
||||
'gateway_id' => $dispatcher->gateway->id,
|
||||
'filter' => [],
|
||||
|
@ -51,6 +51,7 @@ class UpdateTest extends TestCase
|
|||
Member::factory()->defaults()->create(['email' => 'to@example.com']);
|
||||
ResyncAction::run();
|
||||
|
||||
sleep(1);
|
||||
$response = $this->patchJson("/maildispatcher/{$dispatcher->id}", [
|
||||
'name' => 'testa',
|
||||
'gateway_id' => $dispatcher->gateway->id,
|
||||
|
@ -73,6 +74,7 @@ class UpdateTest extends TestCase
|
|||
->filter(FilterScope::from([]))
|
||||
->create();
|
||||
$member = Member::factory()->defaults()->create(['email' => 'to@example.com']);
|
||||
sleep(1);
|
||||
ResyncAction::run();
|
||||
$member->update(['email' => 'to2@example.com']);
|
||||
ResyncAction::run();
|
|
@ -13,15 +13,14 @@ use App\Membership\Actions\MembershipStoreAction;
|
|||
use App\Subactivity;
|
||||
use Illuminate\Foundation\Testing\DatabaseMigrations;
|
||||
use Illuminate\Support\Facades\Queue;
|
||||
use Tests\EndToEndTestCase;
|
||||
use Tests\TestCase;
|
||||
use Throwable;
|
||||
use Zoomyboy\LaravelNami\Fakes\MembershipFake;
|
||||
|
||||
class MassstoreActionTest extends TestCase
|
||||
class MassstoreActionTest extends EndToEndTestCase
|
||||
{
|
||||
|
||||
use DatabaseMigrations;
|
||||
|
||||
public function testItFiresActionJobWhenUsingController(): void
|
||||
{
|
||||
Queue::fake();
|
||||
|
|
|
@ -1,19 +1,13 @@
|
|||
<?php
|
||||
|
||||
namespace Tests\Feature\Member;
|
||||
namespace Tests\EndToEnd\Member;
|
||||
|
||||
use App\Member\Member;
|
||||
use Illuminate\Foundation\Testing\DatabaseTransactions;
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
use Tests\TestCase;
|
||||
use Tests\EndToEndTestCase;
|
||||
|
||||
class ExportCsvActionTest extends TestCase
|
||||
class ExportCsvActionTest extends EndToEndTestCase
|
||||
{
|
||||
use DatabaseTransactions;
|
||||
|
||||
/**
|
||||
* A basic feature test example.
|
||||
*/
|
||||
public function testItExportsACsvFile(): void
|
||||
{
|
||||
Storage::fake('temp');
|
||||
|
@ -22,6 +16,7 @@ class ExportCsvActionTest extends TestCase
|
|||
Member::factory()->defaults()->postBillKind()->create(['firstname' => 'Jane', 'main_phone' => '+49 176 70343221', 'email' => 'max@muster.de']);
|
||||
Member::factory()->defaults()->emailBillKind()->create(['firstname' => 'Max']);
|
||||
|
||||
sleep(1);
|
||||
$response = $this->callFilter('member-export', ['bill_kind' => 'Post']);
|
||||
|
||||
$response->assertDownload('mitglieder.csv');
|
||||
|
@ -31,4 +26,25 @@ class ExportCsvActionTest extends TestCase
|
|||
$this->assertTrue(str_contains($contents, 'max@muster.de'));
|
||||
$this->assertFalse(str_contains($contents, 'Max'));
|
||||
}
|
||||
|
||||
public function testItOrdersByLastname(): void
|
||||
{
|
||||
Storage::fake('temp');
|
||||
|
||||
$this->withoutExceptionHandling()->login()->loginNami();
|
||||
Member::factory()->defaults()->create(['lastname' => 'C']);
|
||||
Member::factory()->defaults()->create(['lastname' => 'A']);
|
||||
|
||||
sleep(1);
|
||||
$response = $this->callFilter('member-export', []);
|
||||
|
||||
$response->assertDownload('mitglieder.csv');
|
||||
$contents = Storage::disk('temp')->get('mitglieder.csv');
|
||||
$this->assertEquals(['A', 'C'], collect(explode("\n", $contents))
|
||||
->filter(fn ($line) => $line !== '')
|
||||
->filter(fn ($line) => !str($line)->startsWith('Nachname'))
|
||||
->map(fn ($line) => (string) str($line)->substr(0, 1))
|
||||
->values()
|
||||
->toArray());
|
||||
}
|
||||
}
|
|
@ -2,37 +2,31 @@
|
|||
|
||||
namespace Tests\EndToEnd;
|
||||
|
||||
use App\Activity;
|
||||
use App\Group;
|
||||
use App\Invoice\BillKind;
|
||||
use App\Invoice\Enums\InvoiceStatus;
|
||||
use App\Invoice\Models\Invoice;
|
||||
use App\Invoice\Models\InvoicePosition;
|
||||
use App\Member\Member;
|
||||
use Illuminate\Foundation\Testing\DatabaseMigrations;
|
||||
use Illuminate\Support\Facades\Artisan;
|
||||
use Laravel\Scout\Console\SyncIndexSettingsCommand;
|
||||
use Tests\TestCase;
|
||||
use App\Member\Membership;
|
||||
use App\Subactivity;
|
||||
use Tests\EndToEndTestCase;
|
||||
|
||||
class MemberIndexTest extends TestCase
|
||||
class MemberIndexTest extends EndToEndTestCase
|
||||
{
|
||||
use DatabaseMigrations;
|
||||
|
||||
public function setUp(): void
|
||||
{
|
||||
parent::setUp();
|
||||
|
||||
config()->set('scout.driver', 'meilisearch');
|
||||
Artisan::call(SyncIndexSettingsCommand::class);
|
||||
}
|
||||
|
||||
public function testItHandlesFullTextSearch(): void
|
||||
{
|
||||
$this->withoutExceptionHandling()->login()->loginNami();
|
||||
Member::factory()->defaults()->create(['firstname' => 'Alexander']);
|
||||
Member::factory()->defaults()->count(2)->create(['firstname' => 'Alexander']);
|
||||
Member::factory()->defaults()->create(['firstname' => 'Heinrich']);
|
||||
|
||||
sleep(5);
|
||||
$response = $this->callFilter('member.index', ['search' => 'Alexander']);
|
||||
|
||||
$this->assertCount(1, $this->inertia($response, 'data.data'));
|
||||
sleep(1);
|
||||
$this->callFilter('member.index', ['search' => 'Alexander'])
|
||||
->assertInertiaCount('data.data', 2);
|
||||
$this->callFilter('member.index', ['search' => 'Heinrich'])
|
||||
->assertInertiaCount('data.data', 1);
|
||||
}
|
||||
|
||||
public function testItHandlesAddress(): void
|
||||
|
@ -41,25 +35,138 @@ class MemberIndexTest extends TestCase
|
|||
Member::factory()->defaults()->create(['address' => '']);
|
||||
Member::factory()->defaults()->create(['zip' => '']);
|
||||
Member::factory()->defaults()->create(['location' => '']);
|
||||
Member::factory()->defaults()->create();
|
||||
|
||||
sleep(5);
|
||||
$response = $this->callFilter('member.index', ['has_full_address' => true]);
|
||||
$noResponse = $this->callFilter('member.index', ['has_full_address' => false]);
|
||||
|
||||
$this->assertCount(0, $this->inertia($response, 'data.data'));
|
||||
$this->assertCount(3, $this->inertia($noResponse, 'data.data'));
|
||||
sleep(1);
|
||||
$this->callFilter('member.index', ['has_full_address' => false])
|
||||
->assertInertiaCount('data.data', 3)
|
||||
->assertInertiaPath('data.meta.total', 3)
|
||||
->assertInertiaPath('data.meta.from', 1)
|
||||
->assertInertiaPath('data.meta.to', 3);
|
||||
$this->callFilter('member.index', ['has_full_address' => true])
|
||||
->assertInertiaCount('data.data', 1)
|
||||
->assertInertiaPath('data.meta.total', 1)
|
||||
->assertInertiaPath('data.meta.from', 1)
|
||||
->assertInertiaPath('data.meta.to', 1);
|
||||
}
|
||||
|
||||
public function testItHandlesBirthday(): void
|
||||
{
|
||||
$this->withoutExceptionHandling()->login()->loginNami();
|
||||
$member = Member::factory()->defaults()->create(['birthday' => null]);
|
||||
Member::factory()->defaults()->create(['birthday' => null]);
|
||||
Member::factory()->defaults()->count(2)->create();
|
||||
|
||||
sleep(5);
|
||||
$response = $this->callFilter('member.index', ['has_birthday' => true]);
|
||||
sleep(1);
|
||||
$this->callFilter('member.index', ['has_birthday' => true])
|
||||
->assertInertiaCount('data.data', 2);
|
||||
$this->callFilter('member.index', ['has_birthday' => false])
|
||||
->assertInertiaCount('data.data', 1);
|
||||
}
|
||||
|
||||
$this->assertCount(0, $this->inertia($response, 'data.data'));
|
||||
$member->delete();
|
||||
public function testItHandlesBillKind(): void
|
||||
{
|
||||
$this->withoutExceptionHandling()->login()->loginNami();
|
||||
Member::factory()->defaults()->postBillKind()->create();
|
||||
Member::factory()->defaults()->emailBillKind()->count(2)->create();
|
||||
|
||||
sleep(1);
|
||||
$this->callFilter('member.index', ['bill_kind' => BillKind::POST->value])
|
||||
->assertInertiaCount('data.data', 1);
|
||||
$this->callFilter('member.index', ['bill_kind' => BillKind::EMAIL->value])
|
||||
->assertInertiaCount('data.data', 2);
|
||||
$this->callFilter('member.index', [])
|
||||
->assertInertiaCount('data.data', 3);
|
||||
}
|
||||
|
||||
public function testItHandlesGroupIds(): void
|
||||
{
|
||||
$this->withoutExceptionHandling()->login()->loginNami();
|
||||
$group = Group::factory()->create();
|
||||
$otherGroup = Group::factory()->create();
|
||||
$thirdGroup = Group::factory()->create();
|
||||
Member::factory()->defaults()->for($group)->create();
|
||||
Member::factory()->defaults()->count(2)->for($otherGroup)->create();
|
||||
Member::factory()->defaults()->count(3)->for($thirdGroup)->create();
|
||||
|
||||
sleep(1);
|
||||
$this->callFilter('member.index', ['group_ids' => [$group->id]])
|
||||
->assertInertiaCount('data.data', 1);
|
||||
$this->callFilter('member.index', ['group_ids' => [$otherGroup->id]])
|
||||
->assertInertiaCount('data.data', 2);
|
||||
$this->callFilter('member.index', ['group_ids' => [$otherGroup->id, $thirdGroup->id]])
|
||||
->assertInertiaCount('data.data', 5);
|
||||
$this->callFilter('member.index', [])
|
||||
->assertInertiaCount('data.data', 6);
|
||||
}
|
||||
|
||||
public function testItHandlesActivitiesAndSubactivities(): void
|
||||
{
|
||||
$this->withoutExceptionHandling()->login()->loginNami();
|
||||
$mitglied = Activity::factory()->name('€ Mitglied')->create();
|
||||
$schnuppermitglied = Activity::factory()->name('Schnuppermitgliedschaft')->create();
|
||||
$woelfling = Subactivity::factory()->name('Wölfling')->create();
|
||||
$rover = Subactivity::factory()->name('Rover')->create();
|
||||
Member::factory()->defaults()->create();
|
||||
Member::factory()->defaults()->count(2)->has(Membership::factory()->for($mitglied)->for($woelfling))->create();
|
||||
Member::factory()->defaults()->count(3)->has(Membership::factory()->for($schnuppermitglied)->for($rover))->create();
|
||||
|
||||
sleep(1);
|
||||
$this->callFilter('member.index', ['activity_ids' => [$mitglied->id]])
|
||||
->assertInertiaCount('data.data', 2);
|
||||
$this->callFilter('member.index', ['subactivity_ids' => [$woelfling->id]])
|
||||
->assertInertiaCount('data.data', 2);
|
||||
$this->callFilter('member.index', ['subactivity_ids' => [$rover->id]])
|
||||
->assertInertiaCount('data.data', 3);
|
||||
$this->callFilter('member.index', ['activity_ids' => [$schnuppermitglied->id], 'subactivity_ids' => [$woelfling->id]])
|
||||
->assertInertiaCount('data.data', 0);
|
||||
$this->callFilter('member.index', ['activity_ids' => [$schnuppermitglied->id], 'subactivity_ids' => [$rover->id]])
|
||||
->assertInertiaCount('data.data', 3);
|
||||
$this->callFilter('member.index', [])
|
||||
->assertInertiaCount('data.data', 6);
|
||||
}
|
||||
|
||||
public function testItHandlesActivityAndSubactivityForSingleMembership(): void
|
||||
{
|
||||
$this->withoutExceptionHandling()->login()->loginNami();
|
||||
$mitglied = Activity::factory()->name('€ Mitglied')->create();
|
||||
$schnuppermitglied = Activity::factory()->name('Schnuppermitgliedschaft')->create();
|
||||
$woelfling = Subactivity::factory()->name('Wölfling')->create();
|
||||
$rover = Subactivity::factory()->name('Rover')->create();
|
||||
Member::factory()->defaults()
|
||||
->has(Membership::factory()->for($mitglied)->for($woelfling))
|
||||
->has(Membership::factory()->for($schnuppermitglied)->for($rover))
|
||||
->create();
|
||||
|
||||
sleep(1);
|
||||
$this->callFilter('member.index', ['activity_ids' => [$mitglied->id, 5, 6], 'subactivity_ids' => [$rover->id, 8, 9]])
|
||||
->assertInertiaCount('data.data', 0);
|
||||
}
|
||||
|
||||
public function testItIgnoresInactiveMemberships(): void
|
||||
{
|
||||
$this->withoutExceptionHandling()->login()->loginNami();
|
||||
$mitglied = Activity::factory()->name('€ Mitglied')->create();
|
||||
$woelfling = Subactivity::factory()->name('Wölfling')->create();
|
||||
Member::factory()->defaults()->has(Membership::factory()->for($mitglied)->for($woelfling)->ended())->create();
|
||||
|
||||
sleep(1);
|
||||
$this->callFilter('member.index', ['activity_ids' => [$mitglied->id]])
|
||||
->assertInertiaCount('data.data', 0);
|
||||
$this->callFilter('member.index', ['subactivity_ids' => [$woelfling->id]])
|
||||
->assertInertiaCount('data.data', 0);
|
||||
}
|
||||
|
||||
public function testItListensForMembershipDeletion(): void
|
||||
{
|
||||
$this->withoutExceptionHandling()->login()->loginNami();
|
||||
$mitglied = Activity::factory()->name('€ Mitglied')->create();
|
||||
$member = Member::factory()->defaults()->has(Membership::factory()->for($mitglied))->create();
|
||||
$member->memberships->first()->delete();
|
||||
|
||||
|
||||
sleep(1);
|
||||
$this->callFilter('member.index', ['activity_ids' => [$mitglied->id]])
|
||||
->assertInertiaCount('data.data', 0);
|
||||
}
|
||||
|
||||
public function testItFiltersForSearchButNotForPayments(): void
|
||||
|
@ -67,12 +174,46 @@ class MemberIndexTest extends TestCase
|
|||
$this->withoutExceptionHandling()->login()->loginNami();
|
||||
Member::factory()->defaults()
|
||||
->has(InvoicePosition::factory()->for(Invoice::factory()))
|
||||
->create(['firstname' => '::firstname::']);
|
||||
Member::factory()->defaults()->create(['firstname' => '::firstname::']);
|
||||
->create(['firstname' => 'firstname']);
|
||||
Member::factory()->defaults()->create(['firstname' => 'firstname']);
|
||||
|
||||
sleep(5);
|
||||
$response = $this->callFilter('member.index', ['search' => '::firstname::', 'ausstand' => true]);
|
||||
sleep(1);
|
||||
$this->callFilter('member.index', ['search' => 'firstname', 'ausstand' => true])
|
||||
->assertInertiaCount('data.data', 1);
|
||||
}
|
||||
|
||||
$this->assertCount(1, $this->inertia($response, 'data.data'));
|
||||
public function testItIgnoresPaidInvoices(): void
|
||||
{
|
||||
$this->withoutExceptionHandling()->login()->loginNami();
|
||||
Member::factory()->defaults()
|
||||
->has(InvoicePosition::factory()->for(Invoice::factory()->status(InvoiceStatus::PAID)))
|
||||
->create();
|
||||
|
||||
sleep(1);
|
||||
$this->callFilter('member.index', ['ausstand' => true])
|
||||
->assertInertiaCount('data.data', 0);
|
||||
}
|
||||
|
||||
|
||||
public function testItIncludesMembers(): void
|
||||
{
|
||||
$this->withoutExceptionHandling()->login()->loginNami();
|
||||
$member = Member::factory()->defaults()->create(['birthday' => null, 'location' => '']);
|
||||
|
||||
sleep(1);
|
||||
$this->callFilter('member.index', ['hasBirthday' => true, 'hasFullAddress' => false])
|
||||
->assertInertiaCount('data.data', 0);
|
||||
$this->callFilter('member.index', ['hasBirthday' => true, 'hasFullAddress' => false, 'include' => [$member->id]])
|
||||
->assertInertiaCount('data.data', 1);
|
||||
}
|
||||
|
||||
public function testItExcludesMembers(): void
|
||||
{
|
||||
$this->withoutExceptionHandling()->login()->loginNami();
|
||||
$member = Member::factory()->defaults()->create(['birthday' => null]);
|
||||
|
||||
sleep(1);
|
||||
$this->callFilter('member.index', ['hasBirthday' => false, 'exclude' => [$member->id]])
|
||||
->assertInertiaCount('data.data', 0);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,23 @@
|
|||
<?php
|
||||
|
||||
namespace Tests\EndToEnd;
|
||||
|
||||
use App\Member\Member;
|
||||
use Tests\EndToEndTestCase;
|
||||
|
||||
class MemberSearchTest extends EndToEndTestCase
|
||||
{
|
||||
|
||||
public function testItHandlesFullTextSearch(): void
|
||||
{
|
||||
$this->withoutExceptionHandling()->login()->loginNami();
|
||||
Member::factory()->defaults()->count(2)->create(['firstname' => 'Alexander']);
|
||||
Member::factory()->defaults()->create(['firstname' => 'Heinrich']);
|
||||
|
||||
sleep(1);
|
||||
$this->post(route('member.search'), ['filter' => ['search' => 'Alexander']])
|
||||
->assertJsonCount(2, 'data');
|
||||
$this->post(route('member.search'), ['filter' => ['search' => 'Heinrich']])
|
||||
->assertJsonCount(1, 'data');
|
||||
}
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
<?php
|
||||
|
||||
namespace Tests;
|
||||
|
||||
use Illuminate\Foundation\Testing\DatabaseMigrations;
|
||||
|
||||
abstract class EndToEndTestCase extends TestCase
|
||||
{
|
||||
use DatabaseMigrations;
|
||||
|
||||
public function setUp(): void
|
||||
{
|
||||
parent::setUp();
|
||||
|
||||
$this->useMeilisearch();
|
||||
}
|
||||
}
|
|
@ -9,15 +9,19 @@ use App\Invoice\Models\Invoice;
|
|||
use App\Invoice\Models\InvoicePosition;
|
||||
use App\Member\Member;
|
||||
use App\Member\Membership;
|
||||
use App\Payment\Payment;
|
||||
use App\Subactivity;
|
||||
use Illuminate\Foundation\Testing\DatabaseTransactions;
|
||||
use Tests\RequestFactories\Child;
|
||||
use Illuminate\Foundation\Testing\DatabaseMigrations;
|
||||
use Tests\TestCase;
|
||||
|
||||
class IndexTest extends TestCase
|
||||
{
|
||||
use DatabaseTransactions;
|
||||
use DatabaseMigrations;
|
||||
|
||||
public function setUp(): void
|
||||
{
|
||||
parent::setUp();
|
||||
$this->useMeilisearch();
|
||||
}
|
||||
|
||||
public function testItGetsMembers(): void
|
||||
{
|
||||
|
@ -31,6 +35,7 @@ class IndexTest extends TestCase
|
|||
'location' => 'Hilden',
|
||||
]);
|
||||
|
||||
sleep(1);
|
||||
$response = $this->get('/member');
|
||||
|
||||
$this->assertComponent('member/VIndex', $response);
|
||||
|
@ -59,6 +64,7 @@ class IndexTest extends TestCase
|
|||
'location' => null,
|
||||
]);
|
||||
|
||||
sleep(1);
|
||||
$response = $this->get('/member');
|
||||
|
||||
$this->assertInertiaHas(null, $response, 'data.data.0.birthday');
|
||||
|
@ -82,6 +88,7 @@ class IndexTest extends TestCase
|
|||
->defaults()
|
||||
->create(['lastname' => 'C']);
|
||||
|
||||
sleep(1);
|
||||
$response = $this->get('/member');
|
||||
|
||||
$this->assertInertiaHas(url("/member/{$member->id}/efz"), $response, 'data.data.0.efz_link');
|
||||
|
@ -113,6 +120,7 @@ class IndexTest extends TestCase
|
|||
->has(Membership::factory()->in('€ Mitglied', 123, 'Wölfling', 12))
|
||||
->create();
|
||||
|
||||
sleep(1);
|
||||
$response = $this->get('/member');
|
||||
|
||||
$this->assertInertiaHas('woelfling', $response, 'data.data.0.age_group_icon');
|
||||
|
@ -121,7 +129,7 @@ class IndexTest extends TestCase
|
|||
public function testAgeIsNullWhenBirthdayIsNull(): void
|
||||
{
|
||||
$this->withoutExceptionHandling()->login()->loginNami();
|
||||
$member = Member::factory()->defaults()->create(['birthday' => null]);
|
||||
Member::factory()->defaults()->create(['birthday' => null]);
|
||||
|
||||
$response = $this->get('/member');
|
||||
|
||||
|
@ -135,11 +143,11 @@ class IndexTest extends TestCase
|
|||
$activity = Activity::factory()->hasAttached(Subactivity::factory()->name('Biber'))->name('€ Mitglied')->create();
|
||||
$subactivity = $activity->subactivities->first();
|
||||
|
||||
$response = $this->get('/member');
|
||||
|
||||
$this->assertInertiaHas('Biber', $response, "data.meta.formSubactivities.{$activity->id}.{$subactivity->id}");
|
||||
$this->assertInertiaHas('Biber', $response, "data.meta.filterSubactivities.{$subactivity->id}");
|
||||
$this->assertInertiaHas('€ Mitglied', $response, "data.meta.formActivities.{$activity->id}");
|
||||
sleep(1);
|
||||
$this->get('/member')
|
||||
->assertInertiaPath("data.meta.formSubactivities.{$activity->id}.{$subactivity->id}", 'Biber')
|
||||
->assertInertiaPath("data.meta.filterSubactivities.{$subactivity->id}", 'Biber')
|
||||
->assertInertiaPath("data.meta.formActivities.{$activity->id}", '€ Mitglied');
|
||||
}
|
||||
|
||||
public function testItCanFilterForBillKinds(): void
|
||||
|
@ -149,12 +157,12 @@ class IndexTest extends TestCase
|
|||
Member::factory()->defaults()->postBillKind()->create();
|
||||
Member::factory()->defaults()->postBillKind()->create();
|
||||
|
||||
$emailResponse = $this->callFilter('member.index', ['bill_kind' => 'E-Mail']);
|
||||
$postResponse = $this->callFilter('member.index', ['bill_kind' => 'Post']);
|
||||
|
||||
$this->assertCount(1, $this->inertia($emailResponse, 'data.data'));
|
||||
$this->assertCount(2, $this->inertia($postResponse, 'data.data'));
|
||||
$this->assertInertiaHas('E-Mail', $emailResponse, 'data.meta.filter.bill_kind');
|
||||
sleep(1);
|
||||
$this->callFilter('member.index', ['bill_kind' => 'E-Mail'])
|
||||
->assertInertiaCount('data.data', 1)
|
||||
->assertInertiaPath('data.meta.filter.bill_kind', 'E-Mail');
|
||||
$this->callFilter('member.index', ['bill_kind' => 'Post'])
|
||||
->assertInertiaCount('data.data', 2);
|
||||
}
|
||||
|
||||
public function testItCanFilterForGroups(): void
|
||||
|
@ -166,6 +174,7 @@ class IndexTest extends TestCase
|
|||
Member::factory()->defaults()->for($group1)->create();
|
||||
Member::factory()->defaults()->for($group1)->create();
|
||||
|
||||
sleep(1);
|
||||
$oneResponse = $this->callFilter('member.index', ['group_ids' => [$group1->id]]);
|
||||
$twoResponse = $this->callFilter('member.index', ['group_ids' => [$group2->id]]);
|
||||
|
||||
|
@ -174,24 +183,6 @@ class IndexTest extends TestCase
|
|||
$this->assertInertiaHas([$group1->id], $oneResponse, 'data.meta.filter.group_ids');
|
||||
}
|
||||
|
||||
public function testItFiltersForAusstand(): void
|
||||
{
|
||||
$this->withoutExceptionHandling()->login()->loginNami();
|
||||
Member::factory()
|
||||
->has(InvoicePosition::factory()->for(Invoice::factory()->status(InvoiceStatus::NEW)))
|
||||
->defaults()->create();
|
||||
Member::factory()->defaults()->create();
|
||||
Member::factory()->defaults()->create();
|
||||
|
||||
$defaultResponse = $this->callFilter('member.index', []);
|
||||
$ausstandResponse = $this->callFilter('member.index', ['ausstand' => true]);
|
||||
|
||||
$this->assertCount(3, $this->inertia($defaultResponse, 'data.data'));
|
||||
$this->assertCount(1, $this->inertia($ausstandResponse, 'data.data'));
|
||||
$this->assertInertiaHas(true, $ausstandResponse, 'data.meta.filter.ausstand');
|
||||
$this->assertInertiaHas(false, $defaultResponse, 'data.meta.filter.ausstand');
|
||||
}
|
||||
|
||||
public function testItLoadsGroups(): void
|
||||
{
|
||||
$this->withoutExceptionHandling();
|
||||
|
@ -201,6 +192,7 @@ class IndexTest extends TestCase
|
|||
$parent2 = Group::factory()->name('par2')->create();
|
||||
$this->withoutExceptionHandling()->login()->loginNami(12345, 'password', $parent1);
|
||||
|
||||
sleep(1);
|
||||
$response = $this->get('/member');
|
||||
$response->assertOk();
|
||||
|
||||
|
|
|
@ -13,10 +13,12 @@ use Illuminate\Testing\AssertableJsonString;
|
|||
use Illuminate\Testing\TestResponse;
|
||||
use Phake;
|
||||
use PHPUnit\Framework\Assert;
|
||||
use Symfony\Component\HttpFoundation\File\File;
|
||||
use Tests\Lib\MakesHttpCalls;
|
||||
use Tests\Lib\TestsInertia;
|
||||
use Zoomyboy\LaravelNami\Authentication\Auth;
|
||||
use Illuminate\Support\Facades\Artisan;
|
||||
use Laravel\Scout\Console\FlushCommand;
|
||||
use Laravel\Scout\Console\SyncIndexSettingsCommand;
|
||||
|
||||
abstract class TestCase extends BaseTestCase
|
||||
{
|
||||
|
@ -92,6 +94,15 @@ abstract class TestCase extends BaseTestCase
|
|||
return $this;
|
||||
}
|
||||
|
||||
public function useMeilisearch(): self
|
||||
{
|
||||
config()->set('scout.driver', 'meilisearch');
|
||||
Artisan::call(FlushCommand::class, ['model' => Member::class]);
|
||||
Artisan::call(SyncIndexSettingsCommand::class);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param <class-string> $class
|
||||
*/
|
||||
|
@ -123,6 +134,16 @@ abstract class TestCase extends BaseTestCase
|
|||
return $this;
|
||||
});
|
||||
|
||||
TestResponse::macro('assertInertiaCount', function ($path, $count) {
|
||||
/** @var TestResponse */
|
||||
$response = $this;
|
||||
$props = data_get($response->viewData('page'), 'props');
|
||||
Assert::assertNotNull($props);
|
||||
$json = new AssertableJsonString($props);
|
||||
$json->assertCount($count, $path);
|
||||
return $this;
|
||||
});
|
||||
|
||||
TestResponse::macro('assertPdfPageCount', function (int $count) {
|
||||
/** @var TestResponse */
|
||||
$response = $this;
|
||||
|
|
|
@ -6,6 +6,7 @@ use Symfony\Component\HttpFoundation\File\File;
|
|||
|
||||
/**
|
||||
* @method self assertInertiaPath(string $path, string|array<string, mixed>|int|null $value)
|
||||
* @method self assertInertiaCount(string $path, int $count)
|
||||
* @method self assertPdfPageCount(int $count)
|
||||
* @method self assertPdfName(string $filename)
|
||||
* @method File getFile()
|
||||
|
|
Loading…
Reference in New Issue