Compare commits
1 Commits
master
...
skip_remem
| Author | SHA1 | Date |
|---|---|---|
|
|
0724052313 |
|
|
@ -31,15 +31,10 @@ steps:
|
||||||
commands:
|
commands:
|
||||||
- while ! curl --silent 'http://owncloudserver:8080/ocs/v1.php/cloud/capabilities?format=json' -u admin:admin | grep '"status":"ok"'; do sleep 1; done
|
- while ! curl --silent 'http://owncloudserver:8080/ocs/v1.php/cloud/capabilities?format=json' -u admin:admin | grep '"status":"ok"'; do sleep 1; done
|
||||||
|
|
||||||
- name: node_submodules
|
|
||||||
image: node:20.15.0-slim
|
|
||||||
commands:
|
|
||||||
- cd packages/adrema-form && npm ci && npm run build-import && rm -R node_modules && cd ../../
|
|
||||||
|
|
||||||
- name: node
|
- name: node
|
||||||
image: node:20.15.0-slim
|
image: node:20.15.0-slim
|
||||||
commands:
|
commands:
|
||||||
- npm ci && npm run img && npm run prod && rm -R node_modules
|
- npm ci && cd packages/adrema-form && npm ci && npm run build && rm -R node_modules && cd ../../ && npm run img && npm run prod && rm -R node_modules
|
||||||
|
|
||||||
- name: tests
|
- name: tests
|
||||||
image: zoomyboy/adrema-base:latest
|
image: zoomyboy/adrema-base:latest
|
||||||
|
|
|
||||||
12
CHANGELOG.md
12
CHANGELOG.md
|
|
@ -1,17 +1,5 @@
|
||||||
# Letzte Änderungen
|
# Letzte Änderungen
|
||||||
|
|
||||||
### 1.12.27
|
|
||||||
|
|
||||||
- Bei Rechnungs-und Erinnerungsmails wird nun der Stammesname angezeigt. Zudm kann eine ReplyTo gesetzt werden, wenn gewünscht
|
|
||||||
|
|
||||||
### 1.12.26
|
|
||||||
|
|
||||||
- Felder im Form-Builder können nun verschoben und kopiert werden
|
|
||||||
|
|
||||||
### 1.12.25
|
|
||||||
|
|
||||||
- Ein Bug wurde behoben, sodass nun wieder Bedingungen für Formular-Mails vergeben werden können
|
|
||||||
|
|
||||||
### 1.12.24
|
### 1.12.24
|
||||||
|
|
||||||
- Gruppen werden nun wöchentlich aus NaMi neu abgerufen
|
- Gruppen werden nun wöchentlich aus NaMi neu abgerufen
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,6 @@ class InvoiceSettings extends LocalSettings implements Storeable
|
||||||
public ?string $zip;
|
public ?string $zip;
|
||||||
public ?string $iban;
|
public ?string $iban;
|
||||||
public ?string $bic;
|
public ?string $bic;
|
||||||
public ?string $replyTo;
|
|
||||||
public ?int $rememberWeeks;
|
public ?int $rememberWeeks;
|
||||||
|
|
||||||
public static function group(): string
|
public static function group(): string
|
||||||
|
|
@ -44,7 +43,6 @@ class InvoiceSettings extends LocalSettings implements Storeable
|
||||||
'iban' => $this->iban,
|
'iban' => $this->iban,
|
||||||
'bic' => $this->bic,
|
'bic' => $this->bic,
|
||||||
'rememberWeeks' => $this->rememberWeeks,
|
'rememberWeeks' => $this->rememberWeeks,
|
||||||
'replyTo' => $this->replyTo,
|
|
||||||
]
|
]
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
@ -66,7 +64,6 @@ class InvoiceSettings extends LocalSettings implements Storeable
|
||||||
'iban' => '',
|
'iban' => '',
|
||||||
'bic' => '',
|
'bic' => '',
|
||||||
'rememberWeeks' => '',
|
'rememberWeeks' => '',
|
||||||
'replyTo' => '',
|
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,6 @@
|
||||||
|
|
||||||
namespace App\Invoice\Mails;
|
namespace App\Invoice\Mails;
|
||||||
|
|
||||||
use App\Invoice\InvoiceSettings;
|
|
||||||
use App\Invoice\Models\Invoice;
|
use App\Invoice\Models\Invoice;
|
||||||
use Illuminate\Bus\Queueable;
|
use Illuminate\Bus\Queueable;
|
||||||
use Illuminate\Mail\Mailable;
|
use Illuminate\Mail\Mailable;
|
||||||
|
|
@ -13,8 +12,6 @@ class BillMail extends Mailable
|
||||||
use Queueable;
|
use Queueable;
|
||||||
use SerializesModels;
|
use SerializesModels;
|
||||||
|
|
||||||
public InvoiceSettings $settings;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new message instance.
|
* Create a new message instance.
|
||||||
*
|
*
|
||||||
|
|
@ -22,7 +19,6 @@ class BillMail extends Mailable
|
||||||
*/
|
*/
|
||||||
public function __construct(public Invoice $invoice, public string $filename)
|
public function __construct(public Invoice $invoice, public string $filename)
|
||||||
{
|
{
|
||||||
$this->settings = app(InvoiceSettings::class);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -34,7 +30,7 @@ class BillMail extends Mailable
|
||||||
{
|
{
|
||||||
return $this->markdown('mail.invoice.bill')
|
return $this->markdown('mail.invoice.bill')
|
||||||
->attach($this->filename)
|
->attach($this->filename)
|
||||||
->when($this->settings->replyTo, fn ($mail) => $mail->replyTo($this->settings->replyTo))
|
->replyTo('kasse@stamm-silva.de')
|
||||||
->subject('Rechnung | '.$this->settings->from_long);
|
->subject('Rechnung | DPSG Stamm Silva');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,6 @@
|
||||||
|
|
||||||
namespace App\Invoice\Mails;
|
namespace App\Invoice\Mails;
|
||||||
|
|
||||||
use App\Invoice\InvoiceSettings;
|
|
||||||
use App\Invoice\Models\Invoice;
|
use App\Invoice\Models\Invoice;
|
||||||
use Illuminate\Bus\Queueable;
|
use Illuminate\Bus\Queueable;
|
||||||
use Illuminate\Mail\Mailable;
|
use Illuminate\Mail\Mailable;
|
||||||
|
|
@ -13,8 +12,6 @@ class RememberMail extends Mailable
|
||||||
use Queueable;
|
use Queueable;
|
||||||
use SerializesModels;
|
use SerializesModels;
|
||||||
|
|
||||||
public InvoiceSettings $settings;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new message instance.
|
* Create a new message instance.
|
||||||
*
|
*
|
||||||
|
|
@ -22,7 +19,6 @@ class RememberMail extends Mailable
|
||||||
*/
|
*/
|
||||||
public function __construct(public Invoice $invoice, public string $filename)
|
public function __construct(public Invoice $invoice, public string $filename)
|
||||||
{
|
{
|
||||||
$this->settings = app(InvoiceSettings::class);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -34,7 +30,7 @@ class RememberMail extends Mailable
|
||||||
{
|
{
|
||||||
return $this->markdown('mail.invoice.remember')
|
return $this->markdown('mail.invoice.remember')
|
||||||
->attach($this->filename)
|
->attach($this->filename)
|
||||||
->when($this->settings->replyTo, fn ($mail) => $mail->replyTo($this->settings->replyTo))
|
->replyTo('kasse@stamm-silva.de')
|
||||||
->subject('Zahlungserinnerung | '.$this->settings->from_long);
|
->subject('Zahlungserinnerung | DPSG Stamm Silva');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@
|
||||||
namespace App\Lib;
|
namespace App\Lib;
|
||||||
|
|
||||||
use Illuminate\Database\Eloquent\Model;
|
use Illuminate\Database\Eloquent\Model;
|
||||||
|
use Illuminate\Support\Collection;
|
||||||
use Laravel\Scout\Builder;
|
use Laravel\Scout\Builder;
|
||||||
use Spatie\LaravelData\Data;
|
use Spatie\LaravelData\Data;
|
||||||
|
|
||||||
|
|
@ -40,4 +41,20 @@ abstract class ScoutFilter extends Data
|
||||||
{
|
{
|
||||||
return static::factory()->withoutMagicalCreation()->from($post ?: []);
|
return static::factory()->withoutMagicalCreation()->from($post ?: []);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param Collection<int, string> $filter
|
||||||
|
* @param array<string, bool|null> $conditions
|
||||||
|
* @return Collection<int, string>
|
||||||
|
*/
|
||||||
|
public function switches(Collection $filter, array $conditions): Collection
|
||||||
|
{
|
||||||
|
foreach ($conditions as $field => $value) {
|
||||||
|
if ($value !== null) {
|
||||||
|
$filter->push($field . ' = ' . ($value ? 'true' : 'false'));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $filter;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -48,6 +48,8 @@ class FilterScope extends ScoutFilter
|
||||||
public ?bool $hasBirthday = null,
|
public ?bool $hasBirthday = null,
|
||||||
public ?bool $hasSvk = null,
|
public ?bool $hasSvk = null,
|
||||||
public ?bool $hasVk = null,
|
public ?bool $hasVk = null,
|
||||||
|
public ?bool $skipYearlyPrevention = null,
|
||||||
|
public ?bool $skipEventPrevention = null,
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -72,6 +74,7 @@ class FilterScope extends ScoutFilter
|
||||||
$this->search = $this->search ?: '';
|
$this->search = $this->search ?: '';
|
||||||
|
|
||||||
return Member::search($this->search, function ($engine, string $query, array $options) {
|
return Member::search($this->search, function ($engine, string $query, array $options) {
|
||||||
|
/** @var Collection<int, string> */
|
||||||
$filter = collect([]);
|
$filter = collect([]);
|
||||||
|
|
||||||
if ($this->hasFullAddress === true) {
|
if ($this->hasFullAddress === true) {
|
||||||
|
|
@ -86,12 +89,12 @@ class FilterScope extends ScoutFilter
|
||||||
if ($this->hasBirthday === true) {
|
if ($this->hasBirthday === true) {
|
||||||
$filter->push('birthday IS NOT NULL');
|
$filter->push('birthday IS NOT NULL');
|
||||||
}
|
}
|
||||||
if ($this->hasSvk !== null) {
|
$filter = $this->switches($filter, [
|
||||||
$filter->push('has_svk = ' . ($this->hasSvk ? 'true' : 'false'));
|
'skip_yearly_prevention' => $this->skipYearlyPrevention,
|
||||||
}
|
'skip_event_prevention' => $this->skipEventPrevention,
|
||||||
if ($this->hasVk !== null) {
|
'has_vk' => $this->hasVk,
|
||||||
$filter->push('has_vk = ' . ($this->hasVk ? 'true' : 'false'));
|
'has_svk' => $this->hasSvk,
|
||||||
}
|
]);
|
||||||
if ($this->ausstand === true) {
|
if ($this->ausstand === true) {
|
||||||
$filter->push('ausstand > 0');
|
$filter->push('ausstand > 0');
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -79,6 +79,8 @@ class Member extends Model implements Geolocatable, Preventable
|
||||||
'nami_id' => 'integer',
|
'nami_id' => 'integer',
|
||||||
'has_svk' => 'boolean',
|
'has_svk' => 'boolean',
|
||||||
'has_vk' => 'boolean',
|
'has_vk' => 'boolean',
|
||||||
|
'skip_yearly_prevention' => 'boolean',
|
||||||
|
'skip_event_prevention' => 'boolean',
|
||||||
'multiply_pv' => 'boolean',
|
'multiply_pv' => 'boolean',
|
||||||
'multiply_more_pv' => 'boolean',
|
'multiply_more_pv' => 'boolean',
|
||||||
'is_leader' => 'boolean',
|
'is_leader' => 'boolean',
|
||||||
|
|
@ -597,6 +599,8 @@ class Member extends Model implements Geolocatable, Preventable
|
||||||
'group_name' => $this->group->inner_name ?: $this->group->name,
|
'group_name' => $this->group->inner_name ?: $this->group->name,
|
||||||
'has_vk' => $this->has_vk,
|
'has_vk' => $this->has_vk,
|
||||||
'has_svk' => $this->has_svk,
|
'has_svk' => $this->has_svk,
|
||||||
|
'skip_yearly_prevention' => $this->skip_yearly_prevention,
|
||||||
|
'skip_event_prevention' => $this->skip_event_prevention,
|
||||||
'links' => [
|
'links' => [
|
||||||
'show' => route('member.show', ['member' => $this], false),
|
'show' => route('member.show', ['member' => $this], false),
|
||||||
'edit' => route('member.edit', ['member' => $this], false),
|
'edit' => route('member.edit', ['member' => $this], false),
|
||||||
|
|
|
||||||
|
|
@ -26,7 +26,7 @@ class YearlyRememberAction
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach ($settings->yearlyMemberFilter->getQuery()->get() as $member) {
|
foreach ($settings->getYearlyMemberFilter()->getQuery()->get() as $member) {
|
||||||
// @todo add this check to FilterScope
|
// @todo add this check to FilterScope
|
||||||
if ($member->getMailRecipient() === null) {
|
if ($member->getMailRecipient() === null) {
|
||||||
continue;
|
continue;
|
||||||
|
|
|
||||||
|
|
@ -53,4 +53,11 @@ class PreventionSettings extends LocalSettings
|
||||||
'replyToMail' => $this->replyToMail,
|
'replyToMail' => $this->replyToMail,
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function getYearlyMemberFilter(): FilterScope
|
||||||
|
{
|
||||||
|
$this->yearlyMemberFilter->skipYearlyPrevention = false;
|
||||||
|
|
||||||
|
return $this->yearlyMemberFilter;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -138,10 +138,10 @@ return [
|
||||||
'key' => env('MEILI_MASTER_KEY', null),
|
'key' => env('MEILI_MASTER_KEY', null),
|
||||||
'index-settings' => [
|
'index-settings' => [
|
||||||
Member::class => [
|
Member::class => [
|
||||||
'filterableAttributes' => ['address', 'birthday', 'ausstand', 'bill_kind', 'group_id', 'memberships', 'has_vk', 'has_svk', 'id'],
|
'filterableAttributes' => ['address', 'birthday', 'ausstand', 'bill_kind', 'group_id', 'memberships', 'has_vk', 'has_svk', 'id', 'skip_yearly_prevention', 'skip_event_prevention'],
|
||||||
'searchableAttributes' => ['fullname', 'address'],
|
'searchableAttributes' => ['fullname', 'address'],
|
||||||
'sortableAttributes' => ['lastname', 'firstname'],
|
'sortableAttributes' => ['lastname', 'firstname'],
|
||||||
'displayedAttributes' => ['age_group_icon', 'group_name', 'links', 'is_leader', 'lastname', 'firstname', 'fullname', 'address', 'ausstand', 'birthday', 'id', 'memberships', 'bill_kind', 'group_id'],
|
'displayedAttributes' => ['age_group_icon', 'group_name', 'links', 'is_leader', 'lastname', 'firstname', 'fullname', 'address', 'ausstand', 'birthday', 'id', 'memberships', 'bill_kind', 'group_id', 'skip_yearly_prevention', 'skip_event_prevention', 'has_vk', 'has_svk'],
|
||||||
'pagination' => [
|
'pagination' => [
|
||||||
'maxTotalHits' => 1000000,
|
'maxTotalHits' => 1000000,
|
||||||
]
|
]
|
||||||
|
|
|
||||||
|
|
@ -39,6 +39,8 @@ class MemberFactory extends Factory
|
||||||
'keepdata' => false,
|
'keepdata' => false,
|
||||||
'has_svk' => $this->faker->boolean(),
|
'has_svk' => $this->faker->boolean(),
|
||||||
'has_vk' => $this->faker->boolean(),
|
'has_vk' => $this->faker->boolean(),
|
||||||
|
'skip_yearly_prevention' => false,
|
||||||
|
'skip_event_prevention' => false,
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,30 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
use Illuminate\Database\Migrations\Migration;
|
||||||
|
use Illuminate\Database\Schema\Blueprint;
|
||||||
|
use Illuminate\Support\Facades\Schema;
|
||||||
|
|
||||||
|
return new class extends Migration
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Run the migrations.
|
||||||
|
*/
|
||||||
|
public function up(): void
|
||||||
|
{
|
||||||
|
Schema::table('members', function (Blueprint $table) {
|
||||||
|
$table->boolean('skip_yearly_prevention')->default(false);
|
||||||
|
$table->boolean('skip_event_prevention')->default(false);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reverse the migrations.
|
||||||
|
*/
|
||||||
|
public function down(): void
|
||||||
|
{
|
||||||
|
Schema::table('members', function (Blueprint $table) {
|
||||||
|
$table->dropColumn('skip_yearly_prevention');
|
||||||
|
$table->dropColumn('skip_event_prevention');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
@ -1,11 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
use Spatie\LaravelSettings\Migrations\SettingsMigration;
|
|
||||||
|
|
||||||
return new class extends SettingsMigration
|
|
||||||
{
|
|
||||||
public function up(): void
|
|
||||||
{
|
|
||||||
$this->migrator->add('bill.replyTo', '');
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
@ -1 +1 @@
|
||||||
Subproject commit 010825124f7791dfc0dc607e23ec99f49be8aef5
|
Subproject commit a4a2a2b3fd7a099cf1e5a9360d5d5450030bf673
|
||||||
|
|
@ -69,13 +69,13 @@
|
||||||
<div>
|
<div>
|
||||||
<ui-tabs v-model="activeMailTab" :entries="mailTabs" />
|
<ui-tabs v-model="activeMailTab" :entries="mailTabs" />
|
||||||
<f-editor v-if="activeMailTab === 0" id="mail_top" v-model="single.mail_top" name="mail_top" label="E-Mail-Teil 1" :rows="8" conditions required>
|
<f-editor v-if="activeMailTab === 0" id="mail_top" v-model="single.mail_top" name="mail_top" label="E-Mail-Teil 1" :rows="8" conditions required>
|
||||||
<template #conditions="{data, resolve}">
|
<template #conditions="{cData, resolve}">
|
||||||
<conditions-form id="mail_top_conditions" :single="single" :value="data" @save="resolve" />
|
<conditions-form id="mail_top_conditions" :single="single" :value="cData" @save="resolve" />
|
||||||
</template>
|
</template>
|
||||||
</f-editor>
|
</f-editor>
|
||||||
<f-editor v-if="activeMailTab === 1" id="mail_bottom" v-model="single.mail_bottom" name="mail_bottom" label="E-Mail-Teil 2" :rows="8" conditions required>
|
<f-editor v-if="activeMailTab === 1" id="mail_bottom" v-model="single.mail_bottom" name="mail_bottom" label="E-Mail-Teil 2" :rows="8" conditions required>
|
||||||
<template #conditions="{data, resolve}">
|
<template #conditions="{d, resolve}">
|
||||||
<conditions-form id="mail_bottom_conditions" :single="single" :value="data" @save="resolve" />
|
<conditions-form id="mail_bottom_conditions" :single="single" :value="d" @save="resolve" />
|
||||||
</template>
|
</template>
|
||||||
</f-editor>
|
</f-editor>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -11,17 +11,6 @@
|
||||||
<f-text id="sectionform-name" v-model="singleSection.model.name" label="Name"></f-text>
|
<f-text id="sectionform-name" v-model="singleSection.model.name" label="Name"></f-text>
|
||||||
<f-textarea id="sectionform-intro" v-model="singleSection.model.intro" label="Einleitung"></f-textarea>
|
<f-textarea id="sectionform-intro" v-model="singleSection.model.intro" label="Einleitung"></f-textarea>
|
||||||
</asideform>
|
</asideform>
|
||||||
<asideform
|
|
||||||
v-if="moving !== null"
|
|
||||||
heading="Feld verschieben nach Sektion …"
|
|
||||||
@close="moving = null"
|
|
||||||
>
|
|
||||||
<div class="mt-3 grid gap-3">
|
|
||||||
<a v-for="(section, index) in modelValue.sections" :key="index" class="py-2 px-3 border rounded bg-zinc-800 hover:bg-zinc-700 transition" href="#" @click.prevent="moveFieldToSection(index)">
|
|
||||||
<span v-text="section.name"></span>
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
</asideform>
|
|
||||||
<asideform v-if="singleSection !== null && singleSection.mode === 'reorder'" heading="Felder ordnen" @close="singleSection = null" @submit="storeSection">
|
<asideform v-if="singleSection !== null && singleSection.mode === 'reorder'" heading="Felder ordnen" @close="singleSection = null" @submit="storeSection">
|
||||||
<draggable v-model="singleSection.model.fields" item-key="key" :component-data="{class: 'mt-3 grid gap-3'}">
|
<draggable v-model="singleSection.model.fields" item-key="key" :component-data="{class: 'mt-3 grid gap-3'}">
|
||||||
<template #item="{element}">
|
<template #item="{element}">
|
||||||
|
|
@ -70,8 +59,6 @@
|
||||||
@editFields="startReordering($event.detail[0])"
|
@editFields="startReordering($event.detail[0])"
|
||||||
@deleteSection="deleteSection($event.detail[0])"
|
@deleteSection="deleteSection($event.detail[0])"
|
||||||
@active="updateActive($event.detail[0])"
|
@active="updateActive($event.detail[0])"
|
||||||
@copy-field="copyField($event.detail[0], $event.detail[1])"
|
|
||||||
@move-field="moving = {section: $event.detail[0], field: $event.detail[1]}"
|
|
||||||
></event-form>
|
></event-form>
|
||||||
</ui-box>
|
</ui-box>
|
||||||
</form>
|
</form>
|
||||||
|
|
@ -80,7 +67,7 @@
|
||||||
<script lang="js" setup>
|
<script lang="js" setup>
|
||||||
import { watch, computed, ref } from 'vue';
|
import { watch, computed, ref } from 'vue';
|
||||||
import { snakeCase } from 'change-case';
|
import { snakeCase } from 'change-case';
|
||||||
import '!/adrema-form/dist/assets/main.js';
|
import '!/adrema-form/dist/main.js';
|
||||||
import Asideform from './Asideform.vue';
|
import Asideform from './Asideform.vue';
|
||||||
import TextareaField from './TextareaField.vue';
|
import TextareaField from './TextareaField.vue';
|
||||||
import TextField from './TextField.vue';
|
import TextField from './TextField.vue';
|
||||||
|
|
@ -96,7 +83,6 @@ import Draggable from 'vuedraggable';
|
||||||
|
|
||||||
const singleSection = ref(null);
|
const singleSection = ref(null);
|
||||||
const singleField = ref(null);
|
const singleField = ref(null);
|
||||||
const moving = ref(null);
|
|
||||||
const active = ref(null);
|
const active = ref(null);
|
||||||
|
|
||||||
async function onReorder() {
|
async function onReorder() {
|
||||||
|
|
@ -138,29 +124,6 @@ function editSection(sectionIndex) {
|
||||||
mode: 'edit',
|
mode: 'edit',
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
function moveFieldToSection(newSectionIndex) {
|
|
||||||
if (!moving.value) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
singleField.value = {
|
|
||||||
model: JSON.parse(JSON.stringify(inner.value.sections[moving.value.section].fields[moving.value.field])),
|
|
||||||
sectionIndex: newSectionIndex,
|
|
||||||
index: null,
|
|
||||||
};
|
|
||||||
storeField();
|
|
||||||
deleteField(moving.value.section, moving.value.field);
|
|
||||||
moving.value = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
function copyField(sectionIndex, fieldIndex) {
|
|
||||||
var field = JSON.parse(JSON.stringify(inner.value.sections[sectionIndex].fields[fieldIndex]));
|
|
||||||
field.name = field.name + ' - Kopie';
|
|
||||||
singleField.value = {
|
|
||||||
model: field,
|
|
||||||
sectionIndex: sectionIndex,
|
|
||||||
index: null,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
function startReordering(index) {
|
function startReordering(index) {
|
||||||
singleSection.value = {
|
singleSection.value = {
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,6 @@
|
||||||
<f-text id="iban" v-model="inner.iban" label="IBAN"></f-text>
|
<f-text id="iban" v-model="inner.iban" label="IBAN"></f-text>
|
||||||
<f-text id="bic" v-model="inner.bic" label="BIC"></f-text>
|
<f-text id="bic" v-model="inner.bic" label="BIC"></f-text>
|
||||||
<f-text id="remember_weeks" v-model="inner.rememberWeeks" type="number" label="Erinnerung alle X Wochen versenden"></f-text>
|
<f-text id="remember_weeks" v-model="inner.rememberWeeks" type="number" label="Erinnerung alle X Wochen versenden"></f-text>
|
||||||
<f-text id="reply_to" v-model="inner.replyTo" label="Reply-To E-Mail-Adresse"></f-text>
|
|
||||||
</form>
|
</form>
|
||||||
</setting-layout>
|
</setting-layout>
|
||||||
</page-layout>
|
</page-layout>
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
@component('mail::message')
|
@component('mail::message')
|
||||||
# {{ $invoice->greeting }},
|
# {{ $invoice->greeting }},
|
||||||
|
|
||||||
Im Anhang findet ihr die aktuelle Rechnung an {{$settings->from}} für das laufende Jahr. Bitte begleicht diese bis zum angegebenen Datum.
|
Im Anhang findet ihr die aktuelle Rechnung des Stammes Silva für das laufende Jahr. Bitte begleicht diese bis zum angegebenen Datum.
|
||||||
|
|
||||||
@component('mail::subcopy')
|
@component('mail::subcopy')
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
@component('mail::message')
|
@component('mail::message')
|
||||||
# {{ $invoice->greeting }},
|
# {{ $invoice->greeting }},
|
||||||
|
|
||||||
Hiermit möchten wir euch an die noch ausstehenden Mitgliedsbeiträge an {{$settings->from}} für das laufende Jahr erinnern. Bitte begleicht diese bis zum angegebenen Datum.
|
Hiermit möchten wir euch an die noch ausstehenden Mitgliedsbeiträge des Stammes Silva für das laufende Jahr erinnern. Bitte begleicht diese bis zum angegebenen Datum.
|
||||||
|
|
||||||
@component('mail::subcopy')
|
@component('mail::subcopy')
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -248,6 +248,18 @@ it('notices a few weeks before', function ($date, bool $shouldSend) {
|
||||||
[fn() => now()->subYears(5)->addWeeks(2)->subDay(), false],
|
[fn() => now()->subYears(5)->addWeeks(2)->subDay(), false],
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
it('skips members that are marked as skipped for yearly mail', function (bool $skip) {
|
||||||
|
Mail::fake();
|
||||||
|
createMember(['efz' => null, 'skip_yearly_prevention' => $skip]);
|
||||||
|
|
||||||
|
sleep(2);
|
||||||
|
YearlyRememberAction::run();
|
||||||
|
|
||||||
|
$skip
|
||||||
|
? Mail::assertNotSent(YearlyMail::class)
|
||||||
|
: Mail::assertSent(YearlyMail::class);
|
||||||
|
})->with([true, false]);
|
||||||
|
|
||||||
it('sets reply to mail', function () {
|
it('sets reply to mail', function () {
|
||||||
Mail::fake();
|
Mail::fake();
|
||||||
app(PreventionSettings::class)->fill(['replyToMail' => 'admin@example.com'])->save();
|
app(PreventionSettings::class)->fill(['replyToMail' => 'admin@example.com'])->save();
|
||||||
|
|
@ -256,7 +268,7 @@ it('sets reply to mail', function () {
|
||||||
sleep(2);
|
sleep(2);
|
||||||
YearlyRememberAction::run();
|
YearlyRememberAction::run();
|
||||||
|
|
||||||
Mail::assertSent(YearlyMail::class, fn ($message) => $message->hasReplyTo('admin@example.com'));
|
Mail::assertSent(YearlyMail::class, fn($message) => $message->hasReplyTo('admin@example.com'));
|
||||||
});
|
});
|
||||||
|
|
||||||
it('remembers members yearly', function ($date, $shouldSend) {
|
it('remembers members yearly', function ($date, $shouldSend) {
|
||||||
|
|
|
||||||
|
|
@ -48,7 +48,6 @@ class InvoiceSendActionTest extends TestCase
|
||||||
Tex::spy();
|
Tex::spy();
|
||||||
Storage::fake('temp');
|
Storage::fake('temp');
|
||||||
$this->withoutExceptionHandling()->login()->loginNami();
|
$this->withoutExceptionHandling()->login()->loginNami();
|
||||||
app(InvoiceSettings::class)->fill(['from_long' => 'Stammname', 'replyTo' => 'reply@mail.com'])->save();
|
|
||||||
$invoice = Invoice::factory()
|
$invoice = Invoice::factory()
|
||||||
->to(ReceiverRequestFactory::new()->name('Familie Muster'))
|
->to(ReceiverRequestFactory::new()->name('Familie Muster'))
|
||||||
->has(InvoicePosition::factory()->withMember(), 'positions')
|
->has(InvoicePosition::factory()->withMember(), 'positions')
|
||||||
|
|
@ -58,13 +57,7 @@ class InvoiceSendActionTest extends TestCase
|
||||||
|
|
||||||
InvoiceSendAction::run();
|
InvoiceSendAction::run();
|
||||||
|
|
||||||
Mail::assertSent(RememberMail::class, fn ($mail) => $mail->build()
|
Mail::assertSent(RememberMail::class, fn ($mail) => $mail->build() && $mail->hasTo('max@muster.de', 'Familie Muster') && Storage::disk('temp')->path('zahlungserinnerung-fur-familie-muster.pdf') === $mail->filename && Storage::disk('temp')->exists('zahlungserinnerung-fur-familie-muster.pdf'));
|
||||||
&& $mail->hasTo('max@muster.de', 'Familie Muster')
|
|
||||||
&& $mail->hasSubject('Zahlungserinnerung | Stammname')
|
|
||||||
&& Storage::disk('temp')->path('zahlungserinnerung-fur-familie-muster.pdf') === $mail->filename
|
|
||||||
&& Storage::disk('temp')->exists('zahlungserinnerung-fur-familie-muster.pdf')
|
|
||||||
&& $mail->hasReplyTo('reply@mail.com')
|
|
||||||
);
|
|
||||||
Tex::assertCompiled(RememberDocument::class, fn ($document) => 'Familie Muster' === $document->toName);
|
Tex::assertCompiled(RememberDocument::class, fn ($document) => 'Familie Muster' === $document->toName);
|
||||||
$this->assertEquals(now()->format('Y-m-d'), $invoice->fresh()->last_remembered_at->format('Y-m-d'));
|
$this->assertEquals(now()->format('Y-m-d'), $invoice->fresh()->last_remembered_at->format('Y-m-d'));
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -33,8 +33,7 @@ class SettingTest extends TestCase
|
||||||
'zip' => '12345',
|
'zip' => '12345',
|
||||||
'iban' => 'DE05',
|
'iban' => 'DE05',
|
||||||
'bic' => 'SOLSDE',
|
'bic' => 'SOLSDE',
|
||||||
'rememberWeeks' => 6,
|
'rememberWeeks' => 6
|
||||||
'replyTo' => 'reply@example.com',
|
|
||||||
])->save();
|
])->save();
|
||||||
|
|
||||||
$this->get(route('setting.data', ['settingGroup' => 'bill']))
|
$this->get(route('setting.data', ['settingGroup' => 'bill']))
|
||||||
|
|
@ -50,8 +49,7 @@ class SettingTest extends TestCase
|
||||||
->assertInertiaPath('data.zip', '12345')
|
->assertInertiaPath('data.zip', '12345')
|
||||||
->assertInertiaPath('data.iban', 'DE05')
|
->assertInertiaPath('data.iban', 'DE05')
|
||||||
->assertInertiaPath('data.bic', 'SOLSDE')
|
->assertInertiaPath('data.bic', 'SOLSDE')
|
||||||
->assertInertiaPath('data.rememberWeeks', 6)
|
->assertInertiaPath('data.rememberWeeks', 6);
|
||||||
->assertInertiaPath('data.replyTo', 'reply@example.com');
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testItReturnsTabs(): void
|
public function testItReturnsTabs(): void
|
||||||
|
|
@ -80,8 +78,7 @@ class SettingTest extends TestCase
|
||||||
'zip' => '12345',
|
'zip' => '12345',
|
||||||
'iban' => 'DE05',
|
'iban' => 'DE05',
|
||||||
'bic' => 'SOLSDE',
|
'bic' => 'SOLSDE',
|
||||||
'rememberWeeks' => 10,
|
'rememberWeeks' => 10
|
||||||
'replyTo' => 'reply@example.com2',
|
|
||||||
]);
|
]);
|
||||||
|
|
||||||
$response->assertRedirect('/setting/bill');
|
$response->assertRedirect('/setting/bill');
|
||||||
|
|
@ -89,7 +86,6 @@ class SettingTest extends TestCase
|
||||||
$this->assertEquals('DPSG Stamm Muster', $settings->from_long);
|
$this->assertEquals('DPSG Stamm Muster', $settings->from_long);
|
||||||
$this->assertEquals('DE05', $settings->iban);
|
$this->assertEquals('DE05', $settings->iban);
|
||||||
$this->assertEquals('SOLSDE', $settings->bic);
|
$this->assertEquals('SOLSDE', $settings->bic);
|
||||||
$this->assertEquals('reply@example.com2', $settings->replyTo);
|
|
||||||
$this->assertEquals(10, $settings->rememberWeeks);
|
$this->assertEquals(10, $settings->rememberWeeks);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue