From 244fc1c15d725000a6bbf48994baffab38badcca Mon Sep 17 00:00:00 2001
From: Rahman Ramsi
Date: Mon, 11 Dec 2023 16:08:51 +0800
Subject: [PATCH 1/9] disable sticky toolbar on tinyeditor
---
app/Panel/Livewire/Submissions/CallforAbstract.php | 3 ++-
app/Panel/Livewire/Submissions/Components/ParticipantList.php | 3 ++-
2 files changed, 4 insertions(+), 2 deletions(-)
diff --git a/app/Panel/Livewire/Submissions/CallforAbstract.php b/app/Panel/Livewire/Submissions/CallforAbstract.php
index e88df541b..691649ee9 100644
--- a/app/Panel/Livewire/Submissions/CallforAbstract.php
+++ b/app/Panel/Livewire/Submissions/CallforAbstract.php
@@ -139,7 +139,8 @@ public function acceptAction()
TextInput::make('subject')
->required(),
TinyEditor::make('message')
- ->minHeight(300),
+ ->minHeight(300)
+ ->toolbarSticky(false),
Checkbox::make('no-notification')
->label("Don't send notification to author")
->default(false),
diff --git a/app/Panel/Livewire/Submissions/Components/ParticipantList.php b/app/Panel/Livewire/Submissions/Components/ParticipantList.php
index b499f4007..e29b14ec5 100644
--- a/app/Panel/Livewire/Submissions/Components/ParticipantList.php
+++ b/app/Panel/Livewire/Submissions/Components/ParticipantList.php
@@ -149,7 +149,8 @@ function (Model $record) {
->readOnly(),
TinyEditor::make('message')
->minHeight(300)
- ->columnSpanFull(),
+ ->columnSpanFull()
+ ->toolbarSticky(false),
]),
Checkbox::make('no-notification')
->label("Don't Send Notification")
From b4f5f13f81594b2d374154ede631b08030a6d78f Mon Sep 17 00:00:00 2001
From: Rahman Ramsi
Date: Tue, 12 Dec 2023 11:55:47 +0800
Subject: [PATCH 2/9] add index
---
.../migrations/2023_04_14_034800_create_submissions_table.php | 3 +++
1 file changed, 3 insertions(+)
diff --git a/database/migrations/2023_04_14_034800_create_submissions_table.php b/database/migrations/2023_04_14_034800_create_submissions_table.php
index 54d69f859..bca2ebc40 100644
--- a/database/migrations/2023_04_14_034800_create_submissions_table.php
+++ b/database/migrations/2023_04_14_034800_create_submissions_table.php
@@ -26,6 +26,9 @@ public function up(): void
$table->string('withdrawn_reason')->nullable();
$table->timestamp('withdrawn_at')->nullable();
$table->timestamps();
+
+ $table->index(['status']);
+ $table->index(['stage']);
});
Schema::create('submission_meta', function (Blueprint $table) {
From 82842c8f44b8670f199870f5a8de01b3ddcf9af0 Mon Sep 17 00:00:00 2001
From: Rahman Ramsi
Date: Thu, 14 Dec 2023 11:01:14 +0800
Subject: [PATCH 3/9] wip
---
app/Application.php | 2 +
app/Facades/Payment.php | 14 ++
app/Interfaces/PaymentDriver.php | 22 +++
app/Managers/PaymentManager.php | 32 ++++
app/Models/Enums/PaymentState.php | 20 ++
app/Models/Enums/PaymentType.php | 14 ++
app/Models/Enums/SubmissionStage.php | 11 +-
app/Models/Payment.php | 28 +++
app/Models/Submission.php | 6 +-
app/Models/SubmissionPaymentItem.php | 34 ++++
app/Models/Timeline.php | 3 +-
app/Observers/ConferenceObserver.php | 1 +
app/Panel/Livewire/Submissions/Payment.php | 52 +++++
.../Workflows/Payment/Tables/PaymentItems.php | 137 +++++++++++++
.../Livewire/Workflows/PaymentSetting.php | 105 ++++++++++
app/Panel/Pages/Settings/Workflow.php | 23 ++-
.../Pages/ViewSubmission.php | 37 ++--
app/Providers/Filament/PanelProvider.php | 2 +-
app/Services/Payments/BasePayment.php | 11 ++
app/Services/Payments/ManualPayment.php | 68 +++++++
app/Tables/Columns/ListColumn.php | 10 +
composer.json | 1 +
composer.lock | 180 +++++++++++++++++-
...023_12_12_112200_create_payments_table.php | 61 ++++++
public/build/manifest.json | 6 +-
.../livewire/submissions/editing.blade.php | 6 +-
.../livewire/submissions/payment.blade.php | 8 +
.../workflows/payment-setting.blade.php | 19 ++
.../payment/tables/payment-items.blade.php | 3 +
resources/views/tables/columns/list.blade.php | 5 +
30 files changed, 889 insertions(+), 32 deletions(-)
create mode 100644 app/Facades/Payment.php
create mode 100644 app/Interfaces/PaymentDriver.php
create mode 100644 app/Managers/PaymentManager.php
create mode 100644 app/Models/Enums/PaymentState.php
create mode 100644 app/Models/Enums/PaymentType.php
create mode 100644 app/Models/Payment.php
create mode 100644 app/Models/SubmissionPaymentItem.php
create mode 100644 app/Panel/Livewire/Submissions/Payment.php
create mode 100644 app/Panel/Livewire/Workflows/Payment/Tables/PaymentItems.php
create mode 100644 app/Panel/Livewire/Workflows/PaymentSetting.php
create mode 100644 app/Services/Payments/BasePayment.php
create mode 100644 app/Services/Payments/ManualPayment.php
create mode 100644 app/Tables/Columns/ListColumn.php
create mode 100644 database/migrations/2023_12_12_112200_create_payments_table.php
create mode 100644 resources/views/panel/livewire/submissions/payment.blade.php
create mode 100644 resources/views/panel/livewire/workflows/payment-setting.blade.php
create mode 100644 resources/views/panel/livewire/workflows/payment/tables/payment-items.blade.php
create mode 100644 resources/views/tables/columns/list.blade.php
diff --git a/app/Application.php b/app/Application.php
index 12ab7969a..0022c1b5d 100644
--- a/app/Application.php
+++ b/app/Application.php
@@ -12,6 +12,7 @@
use App\Models\Site;
use App\Models\StaticPage;
use App\Models\Submission;
+use App\Models\SubmissionPaymentItem;
use App\Models\Timeline;
use App\Models\Topic;
use App\Models\Venue;
@@ -66,6 +67,7 @@ public function scopeCurrentConference(): void
Announcement::class,
StaticPage::class,
Timeline::class,
+ SubmissionPaymentItem::class,
] as $model) {
$model::addGlobalScope(new ConferenceScope);
}
diff --git a/app/Facades/Payment.php b/app/Facades/Payment.php
new file mode 100644
index 000000000..ebb9d7e9e
--- /dev/null
+++ b/app/Facades/Payment.php
@@ -0,0 +1,14 @@
+customCreators])->mapWithKeys(function ($driver) {
+ return [$driver => $this->driver($driver)->getName()];
+ });
+ }
+}
diff --git a/app/Models/Enums/PaymentState.php b/app/Models/Enums/PaymentState.php
new file mode 100644
index 000000000..f6a5bf47b
--- /dev/null
+++ b/app/Models/Enums/PaymentState.php
@@ -0,0 +1,20 @@
+name;
+ }
+}
diff --git a/app/Models/Enums/PaymentType.php b/app/Models/Enums/PaymentType.php
new file mode 100644
index 000000000..bc7fa634b
--- /dev/null
+++ b/app/Models/Enums/PaymentType.php
@@ -0,0 +1,14 @@
+ PaymentState::Pending,
+ ];
+
+ /**
+ * The attributes that should be cast.
+ *
+ * @var array
+ */
+ protected $casts = [
+ 'state' => PaymentState::class,
+ ];
+}
diff --git a/app/Models/Submission.php b/app/Models/Submission.php
index 04785847b..b69636d3f 100644
--- a/app/Models/Submission.php
+++ b/app/Models/Submission.php
@@ -85,13 +85,13 @@ protected static function booted(): void
static::created(function (Submission $submission) {
$submission->participants()->create([
- 'user_id' => auth()->id(),
+ 'user_id' => $submission->user_id,
'role_id' => Role::where('name', UserRole::Author->value)->first()->getKey(),
]);
//If current user does not exists in participant
- if (! $userAsParticipant = auth()->user()->asParticipant()) {
- $userAsParticipant = CreateParticipantFromUserAction::run(auth()->user());
+ if (! $userAsParticipant = $submission->user->asParticipant()) {
+ $userAsParticipant = CreateParticipantFromUserAction::run($submission->user);
}
// Current user as a contributors
diff --git a/app/Models/SubmissionPaymentItem.php b/app/Models/SubmissionPaymentItem.php
new file mode 100644
index 000000000..581aa95db
--- /dev/null
+++ b/app/Models/SubmissionPaymentItem.php
@@ -0,0 +1,34 @@
+
+ */
+ protected $fillable = [
+ 'name',
+ 'description',
+ 'fees',
+ ];
+
+ /**
+ * The attributes that should be cast.
+ *
+ * @var array
+ */
+ protected $casts = [
+ 'fees' => 'array',
+ ];
+}
diff --git a/app/Models/Timeline.php b/app/Models/Timeline.php
index 179acb6e2..8fe7b72af 100644
--- a/app/Models/Timeline.php
+++ b/app/Models/Timeline.php
@@ -3,12 +3,13 @@
namespace App\Models;
use App\Models\Concerns\BelongsToConference;
+use GeneaLabs\LaravelModelCaching\Traits\Cachable;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class Timeline extends Model
{
- use BelongsToConference, HasFactory;
+ use Cachable, BelongsToConference, HasFactory;
protected $fillable = [
'title',
diff --git a/app/Observers/ConferenceObserver.php b/app/Observers/ConferenceObserver.php
index 60381e62c..e1abfb327 100644
--- a/app/Observers/ConferenceObserver.php
+++ b/app/Observers/ConferenceObserver.php
@@ -56,6 +56,7 @@ public function created(Conference $conference): void
]);
$conference->setMeta('page_footer', view('examples.footer')->render());
+ $conference->setMeta('workflow.payment.supported_currencies', ['USD']);
$conference->save();
}
diff --git a/app/Panel/Livewire/Submissions/Payment.php b/app/Panel/Livewire/Submissions/Payment.php
new file mode 100644
index 000000000..8cbcbcb1b
--- /dev/null
+++ b/app/Panel/Livewire/Submissions/Payment.php
@@ -0,0 +1,52 @@
+ StageManager::peerReview()->isStageOpen(),
+ ]);
+ }
+
+ public function form(Form $form)
+ {
+ // return PaymentFacade::getPaymentForm($form);
+ return $form->schema([
+
+ ]);
+ }
+}
diff --git a/app/Panel/Livewire/Workflows/Payment/Tables/PaymentItems.php b/app/Panel/Livewire/Workflows/Payment/Tables/PaymentItems.php
new file mode 100644
index 000000000..a24ce7dd6
--- /dev/null
+++ b/app/Panel/Livewire/Workflows/Payment/Tables/PaymentItems.php
@@ -0,0 +1,137 @@
+required(),
+ Textarea::make('description')
+ ->autosize(),
+ Repeater::make('fees')
+ ->required()
+ ->schema([
+ Grid::make()
+ ->schema([
+ Select::make('currency_id')
+ ->label('Currency')
+ ->searchable()
+ ->required()
+ ->disabled()
+ ->dehydrated(true)
+ // ->options(Currency::whereIn('id', App::getCurrentConference()->getMeta('workflow.payment.supported_currencies') ?? [])->pluck('name', 'id'))
+ ->options(Currency::pluck('name', 'id'))
+ ->optionsLimit(250)
+ ->distinct(),
+ TextInput::make('fee')
+ ->required()
+ ->minValue(1)
+ ->prefix(fn(Get $get) => $get('currency_id') ? Currency::find($get('currency_id'))->symbol_native : null)
+ ->numeric(),
+ ]),
+ ])
+ ->deletable(false)
+ ->reorderable(false)
+ // ->reorderableWithButtons()
+ ->addable(false)
+ ->addActionLabel('Add Fee')
+ ];
+
+ return $table
+ ->query(SubmissionPaymentItem::query())
+ ->reorderable('order_column')
+ ->heading('Payment Items')
+ ->paginated(false)
+ ->columns([
+ IndexColumn::make('no'),
+ TextColumn::make('name')
+ ->searchable(),
+ TextColumn::make('description')
+ ->searchable()
+ ->wrap(),
+ ])
+ ->headerActions([
+ CreateAction::make()
+ ->label("New Payment Item")
+ ->mountUsing(function (Form $form) {
+ $fees = collect(App::getCurrentConference()->getMeta('workflow.payment.supported_currencies'))->map(function ($currency) {
+ return [
+ 'currency_id' => $currency,
+ 'fee' => 0,
+ ];
+ })->toArray();
+ $form->fill([
+ 'fees' => $fees
+ ]);
+ })
+ ->model(SubmissionPaymentItem::class)
+ ->modalWidth('2xl')
+ ->form($formField)
+ ])
+ ->filters([
+ // ...
+ ])
+ ->actions([
+ EditAction::make()
+ ->mutateRecordDataUsing(function ($data) {
+ $supportedCurrencies = App::getCurrentConference()->getMeta('workflow.payment.supported_currencies') ?? [];
+ $fees = collect($supportedCurrencies)
+ ->map(fn ($currency) => ['currency_id' => $currency, 'fee' => 0])
+ ->keyBy('currency_id')
+ ->merge(collect($data['fees'])->keyBy('currency_id'))
+ ->filter(fn($fee) => in_array($fee['currency_id'], $supportedCurrencies))
+ ->toArray();
+ $data['fees'] = $fees;
+
+ return $data;
+ })
+ ->modalWidth('2xl')
+ ->form($formField),
+ DeleteAction::make(),
+ ])
+ ->bulkActions([
+ // ...
+ ]);
+ }
+}
diff --git a/app/Panel/Livewire/Workflows/PaymentSetting.php b/app/Panel/Livewire/Workflows/PaymentSetting.php
new file mode 100644
index 000000000..66d322adb
--- /dev/null
+++ b/app/Panel/Livewire/Workflows/PaymentSetting.php
@@ -0,0 +1,105 @@
+form->fill([
+ 'settings' => [
+ 'payment_method' => $this->getSetting('payment_method', 'manual'),
+ 'supported_currencies' => $this->getSetting('supported_currencies'),
+ ],
+ ...Payment::getAllDriverNames()->map(fn ($name, $key) => Payment::driver($key)->getSettingFormFill())->toArray(),
+ ]);
+ }
+
+ public function submitAction()
+ {
+ return Action::make('submitAction')
+ ->label('Save')
+ ->icon('lineawesome-save-solid')
+ ->failureNotificationTitle('Save Failed')
+ ->successNotificationTitle('Saved')
+ ->action(function (Action $action) {
+ $this->form->validate();
+
+ try {
+ $data = $this->form->getState();
+ foreach ($data['settings'] as $key => $value) {
+ $this->updateSetting($key, $value);
+ }
+
+ Payment::driver($data['settings']['payment_method'])
+ ->saveSetting(data_get($data, $data['settings']['payment_method'], []));
+ } catch (\Throwable $th) {
+ //throw $th;
+ Log::error($th);
+ $action->failure();
+ return;
+ }
+
+ $action->success();
+ });
+ }
+
+ public function form(Form $form): Form
+ {
+ return $form
+ ->statePath('data')
+ ->schema([
+ Shout::make('stage-closed')
+ ->hidden(fn (): bool => $this->isStageOpen())
+ ->color('warning')
+ ->content('The payment stage is not open yet, Start now or schedule opening'),
+ Select::make('settings.payment_method')
+ ->label('Payment Method')
+ ->required()
+ ->options(Payment::getAllDriverNames())
+ ->reactive(),
+ Select::make('settings.supported_currencies')
+ ->searchable()
+ ->required()
+ ->multiple()
+ ->options(Currency::query()->get()->mapWithKeys(fn (Currency $currency) => [$currency->id => $currency->name . ' (' . $currency->symbol_native . ')'])->toArray())
+ ->optionsLimit(250),
+ Grid::make(1)
+ ->hidden(fn (Get $get) => !$get('settings.payment_method'))
+ ->schema(fn (Get $get) => Payment::driver($get('payment_method'))->getSettingFormSchema())
+ ]);
+ }
+
+ public function render()
+ {
+ return view('panel.livewire.workflows.payment-setting');
+ }
+}
diff --git a/app/Panel/Pages/Settings/Workflow.php b/app/Panel/Pages/Settings/Workflow.php
index e8d6a2626..e5825d6f0 100644
--- a/app/Panel/Pages/Settings/Workflow.php
+++ b/app/Panel/Pages/Settings/Workflow.php
@@ -7,6 +7,8 @@
use App\Infolists\Components\VerticalTabs\Tabs;
use App\Panel\Livewire\Workflows\AbstractSetting;
use App\Panel\Livewire\Workflows\EditingSetting;
+use App\Panel\Livewire\Workflows\Payment\Tables\PaymentItems;
+use App\Panel\Livewire\Workflows\PaymentSetting;
use App\Panel\Livewire\Workflows\PeerReview\Forms\Guidelines;
use App\Panel\Livewire\Workflows\PeerReviewSetting;
use Filament\Facades\Filament;
@@ -33,7 +35,7 @@ class Workflow extends Page implements HasForms, HasInfolists
public function booted(): void
{
- abort_if(! static::canView(), 403);
+ abort_if(!static::canView(), 403);
}
public static function shouldRegisterNavigation(): bool
@@ -50,6 +52,7 @@ public function infolist(Infolist $infolist): Infolist
{
return $infolist->schema([
Tabs::make()
+ ->persistTabInQueryString()
->tabs([
Tab::make('Call for Abstract')
->icon('iconpark-documentfolder-o')
@@ -64,6 +67,24 @@ public function infolist(Infolist $infolist): Infolist
]),
]),
]),
+ Tab::make('Payment')
+ ->icon('heroicon-o-currency-dollar')
+ ->schema([
+ HorizontalTabs::make()
+ ->tabs([
+ HorizontalTab::make('General')
+ ->schema([
+ LivewireEntry::make('payment-setting')
+ ->livewire(PaymentSetting::class),
+ ]),
+ HorizontalTab::make('Items')
+ ->schema([
+ LivewireEntry::make('payment-items')
+ ->livewire(PaymentItems::class),
+ ]),
+ ]),
+
+ ]),
Tab::make('Peer Review')
->icon('iconpark-search-o')
->schema([
diff --git a/app/Panel/Resources/SubmissionResource/Pages/ViewSubmission.php b/app/Panel/Resources/SubmissionResource/Pages/ViewSubmission.php
index 41b53910f..d0cb8970e 100644
--- a/app/Panel/Resources/SubmissionResource/Pages/ViewSubmission.php
+++ b/app/Panel/Resources/SubmissionResource/Pages/ViewSubmission.php
@@ -21,6 +21,7 @@
use App\Panel\Livewire\Submissions\Forms\Detail;
use App\Panel\Livewire\Submissions\Forms\Publish;
use App\Panel\Livewire\Submissions\Forms\References;
+use App\Panel\Livewire\Submissions\Payment;
use App\Panel\Livewire\Submissions\PeerReview;
use App\Panel\Livewire\Workflows\Classes\StageManager;
use App\Panel\Livewire\Workflows\Concerns\InteractWithTenant;
@@ -73,7 +74,7 @@ protected function getHeaderActions(): array
$action->successRedirectUrl(
static::getResource()::getUrl('view', [
'record' => $this->record,
- 'stage' => '-'.str($this->record->stage->value)->slug('-').'-tab',
+ 'stage' => '-' . str($this->record->stage->value)->slug('-') . '-tab',
])
);
@@ -122,7 +123,7 @@ protected function getHeaderActions(): array
$action->successRedirectUrl(
SubmissionResource::getUrl('view', [
'record' => $this->record,
- 'stage' => '-'.str($this->record->stage->value)->slug('-').'-tab',
+ 'stage' => '-' . str($this->record->stage->value)->slug('-') . '-tab',
]),
);
$action->success();
@@ -133,7 +134,7 @@ protected function getHeaderActions(): array
->color('danger')
->extraAttributes(function (Action $action) {
if (filled($this->record->withdrawn_reason)) {
- $attributeValue = '$nextTick(() => { $wire.mountAction(\''.$action->getName().'\') })';
+ $attributeValue = '$nextTick(() => { $wire.mountAction(\'' . $action->getName() . '\') })';
return [
'x-init' => new HtmlString($attributeValue),
@@ -157,7 +158,7 @@ protected function getHeaderActions(): array
])
->requiresConfirmation()
->modalHeading(function () {
- return $this->record->user->fullName.' has requested to withdraw this submission.';
+ return $this->record->user->fullName . ' has requested to withdraw this submission.';
})
->modalDescription("You can either reject the request or accept it, remember it can't be undone.")
->modalCancelActionLabel('Ignore')
@@ -172,7 +173,7 @@ protected function getHeaderActions(): array
$action->successRedirectUrl(
SubmissionResource::getUrl('view', [
'record' => $this->record,
- 'stage' => '-'.str($this->record->stage->value)->slug('-').'-tab',
+ 'stage' => '-' . str($this->record->stage->value)->slug('-') . '-tab',
]),
);
$action->successNotificationTitle('Withdrawal request rejected');
@@ -192,7 +193,7 @@ protected function getHeaderActions(): array
$action->successRedirectUrl(
SubmissionResource::getUrl('view', [
'record' => $this->record,
- 'stage' => '-'.str($this->record->stage->value)->slug('-').'-tab',
+ 'stage' => '-' . str($this->record->stage->value)->slug('-') . '-tab',
]),
);
$action->success();
@@ -204,13 +205,13 @@ protected function getHeaderActions(): array
public function getSubheading(): string|Htmlable|null
{
$badgeHtml = match ($this->record->status) {
- SubmissionStatus::Queued => ''.SubmissionStatus::Queued->value.'',
- SubmissionStatus::Declined => ''.SubmissionStatus::Declined->value.'',
- SubmissionStatus::Withdrawn => ''.SubmissionStatus::Withdrawn->value.'',
- SubmissionStatus::Published => ''.SubmissionStatus::Published->value.'',
- SubmissionStatus::OnReview => ''.SubmissionStatus::OnReview->value.'',
- SubmissionStatus::Incomplete => ''.SubmissionStatus::Incomplete->value.'',
- SubmissionStatus::Editing => ''.SubmissionStatus::Editing->value.'',
+ SubmissionStatus::Queued => '' . SubmissionStatus::Queued->value . '',
+ SubmissionStatus::Declined => '' . SubmissionStatus::Declined->value . '',
+ SubmissionStatus::Withdrawn => '' . SubmissionStatus::Withdrawn->value . '',
+ SubmissionStatus::Published => '' . SubmissionStatus::Published->value . '',
+ SubmissionStatus::OnReview => '' . SubmissionStatus::OnReview->value . '',
+ SubmissionStatus::Incomplete => '' . SubmissionStatus::Incomplete->value . '',
+ SubmissionStatus::Editing => '' . SubmissionStatus::Editing->value . '',
default => null,
};
@@ -246,6 +247,14 @@ public function infolist(Infolist $infolist): Infolist
'submission' => $this->record,
]),
]),
+ Tab::make('Payment')
+ ->icon('heroicon-o-currency-dollar')
+ ->schema([
+ LivewireEntry::make('payment')
+ ->livewire(Payment::class, [
+ 'submission' => $this->record,
+ ]),
+ ]),
Tab::make('Peer Review')
->visible(
fn (): bool => StageManager::peerReview()->isStageOpen()
@@ -298,7 +307,7 @@ public function infolist(Infolist $infolist): Infolist
LivewireEntry::make('contributors')
->livewire(ContributorList::class, [
'submission' => $this->record,
- 'viewOnly' => ! auth()->user()->can('editing', $this->record),
+ 'viewOnly' => !auth()->user()->can('editing', $this->record),
]),
]),
Tab::make('References')
diff --git a/app/Providers/Filament/PanelProvider.php b/app/Providers/Filament/PanelProvider.php
index d4a6755e1..e5c35eb13 100644
--- a/app/Providers/Filament/PanelProvider.php
+++ b/app/Providers/Filament/PanelProvider.php
@@ -232,7 +232,7 @@ public static function setupFilamentComponent()
$tinyEditor
->setRelativeUrls(false)
->setRemoveScriptHost(false)
- ->toolbarSticky(true);
+ ->toolbarSticky(false);
});
}
diff --git a/app/Services/Payments/BasePayment.php b/app/Services/Payments/BasePayment.php
new file mode 100644
index 000000000..cf841796a
--- /dev/null
+++ b/app/Services/Payments/BasePayment.php
@@ -0,0 +1,11 @@
+update([
+ 'payment_amount' => $amount,
+ 'payment_status' => 'paid',
+ ]);
+ }
+
+ public function getPaymentForm(Form $form): Form
+ {
+ return $form->schema([
+ Section::make('Payment')
+ ->schema([
+ TextInput::make('payment_amount')
+ ->label('Payment Amount')
+ ->placeholder('Payment Amount')
+ ->required()
+ ->rules('required', 'numeric'),
+ ]),
+ ]);
+ }
+
+ public function getSettingFormSchema(): array
+ {
+ return [
+ TinyEditor::make('manual.instructions')
+ ->label('Payment Instruction')
+ ->required(),
+ ];
+ }
+
+ public function getSettingFormFill(): array
+ {
+ $conference = App::getCurrentConference();
+
+ return [
+ 'instructions' => $conference->getMeta('manual_payment.instructions'),
+ ];
+ }
+
+ public function saveSetting(array $data): void
+ {
+ $conference = App::getCurrentConference();
+
+ $conference->setManyMeta([
+ 'manual_payment.instructions' => data_get($data, 'instructions'),
+ ]);
+ }
+}
diff --git a/app/Tables/Columns/ListColumn.php b/app/Tables/Columns/ListColumn.php
new file mode 100644
index 000000000..739730409
--- /dev/null
+++ b/app/Tables/Columns/ListColumn.php
@@ -0,0 +1,10 @@
+id();
+ $table->foreignIdFor(Conference::class)->constrained();
+ $table->morphs('model');
+ $table->enum('type', PaymentType::array());
+ $table->enum('state', PaymentState::array())->default(PaymentState::Pending->value);
+ $table->double('amount');
+ $table->string('currency_id');
+ $table->timestamp('paid_at')->nullable();
+ $table->string('payment_method');
+ $table->timestamps();
+
+ $table->index(['type']);
+ $table->index(['state']);
+ });
+
+ Schema::create('submission_payment_items', function (Blueprint $table){
+ $table->id();
+ $table->foreignIdFor(Conference::class)->constrained();
+ $table->string('name');
+ $table->text('description')->nullable();
+ $table->integer('order_column')->nullable();
+ $table->json('fees');
+ $table->boolean('active')->default(true);
+ $table->timestamps();
+ });
+
+ // Schema::create('submission_payment_items_details', function (Blueprint $table){
+ // $table->id();
+ // $table->foreignId('submission_payment_item_id')->constrained('submission_payment_items', indexName:'items_details_item_id_foreign')->cascadeOnDelete();
+ // $table->string('currency_id');
+ // $table->double('fee');
+ // $table->integer('order_column')->nullable();
+ // $table->timestamps();
+ // });
+ }
+
+ /**
+ * Reverse the migrations.
+ */
+ public function down(): void
+ {
+ Schema::dropIfExists('payments');
+ }
+};
diff --git a/public/build/manifest.json b/public/build/manifest.json
index e55fdd52c..f3e3596e9 100644
--- a/public/build/manifest.json
+++ b/public/build/manifest.json
@@ -4,7 +4,7 @@
"src": "resources/assets/images/logo.png"
},
"resources/panel/css/panel.css": {
- "file": "assets/panel-ddf5feee.css",
+ "file": "assets/panel-df6f1873.css",
"isEntry": true,
"src": "resources/panel/css/panel.css"
},
@@ -14,12 +14,12 @@
"src": "resources/panel/js/panel.js"
},
"resources/website/css/website.css": {
- "file": "assets/website-c47d7688.css",
+ "file": "assets/website-163957e0.css",
"isEntry": true,
"src": "resources/website/css/website.css"
},
"resources/website/js/website.js": {
- "file": "assets/website-a9ec73b1.js",
+ "file": "assets/website-02a4b6a2.js",
"isEntry": true,
"src": "resources/website/js/website.js"
}
diff --git a/resources/views/panel/livewire/submissions/editing.blade.php b/resources/views/panel/livewire/submissions/editing.blade.php
index 7205472a0..36d3d4ffc 100644
--- a/resources/views/panel/livewire/submissions/editing.blade.php
+++ b/resources/views/panel/livewire/submissions/editing.blade.php
@@ -11,12 +11,12 @@
{{-- Participants --}}
@livewire(App\Panel\Livewire\Submissions\Components\ParticipantList::class, ['submission' => $submission, 'lazy' => true])
-
+
@can('publish', $submission)
-
+
Publish
@endcan
-
\ No newline at end of file
+
diff --git a/resources/views/panel/livewire/submissions/payment.blade.php b/resources/views/panel/livewire/submissions/payment.blade.php
new file mode 100644
index 000000000..38a477472
--- /dev/null
+++ b/resources/views/panel/livewire/submissions/payment.blade.php
@@ -0,0 +1,8 @@
+@php
+ use App\Panel\Livewire\Submissions\Components;
+ use App\Models\Enums\SubmissionStage;
+ use App\Constants\SubmissionFileCategory;
+@endphp
+
+ {{ $this->form }}
+
diff --git a/resources/views/panel/livewire/workflows/payment-setting.blade.php b/resources/views/panel/livewire/workflows/payment-setting.blade.php
new file mode 100644
index 000000000..268bc8199
--- /dev/null
+++ b/resources/views/panel/livewire/workflows/payment-setting.blade.php
@@ -0,0 +1,19 @@
+
+
+
+
+ Payment
+
+ @if ($this->isStageOpen())
+ Open
+ @else
+ Close
+ @endif
+
+ @livewire(App\Panel\Livewire\Workflows\Components\StageSchedule::class, ['stage' => $this->getStage()])
+
+
+
diff --git a/resources/views/panel/livewire/workflows/payment/tables/payment-items.blade.php b/resources/views/panel/livewire/workflows/payment/tables/payment-items.blade.php
new file mode 100644
index 000000000..0689aea9d
--- /dev/null
+++ b/resources/views/panel/livewire/workflows/payment/tables/payment-items.blade.php
@@ -0,0 +1,3 @@
+
+ {{ $this->table }}
+
\ No newline at end of file
diff --git a/resources/views/tables/columns/list.blade.php b/resources/views/tables/columns/list.blade.php
new file mode 100644
index 000000000..7ccc26ce3
--- /dev/null
+++ b/resources/views/tables/columns/list.blade.php
@@ -0,0 +1,5 @@
+
+ @foreach ($getState() as $item)
+ - {{ $item }}
+ @endforeach
+
From b84c18229926a6b059cfc18524c615ef63fed3e1 Mon Sep 17 00:00:00 2001
From: Rahman Ramsi
Date: Fri, 15 Dec 2023 10:09:18 +0800
Subject: [PATCH 4/9] move method to state machine
---
.../Submissions/UnpublishSubmissionAction.php | 22 --
app/Interfaces/PaymentDriver.php | 10 +-
app/Models/Enums/PaymentState.php | 6 +-
app/Models/Enums/PaymentType.php | 3 +-
app/Models/Enums/SubmissionStage.php | 12 +-
app/Models/Enums/SubmissionStatus.php | 16 +-
app/Models/Payment.php | 1 -
.../Interfaces/SubmissionStateInterface.php | 22 ++
.../States/Submission/BaseSubmissionState.php | 53 +++
.../Submission/DeclinedSubmissionState.php | 12 +
.../Submission/EditingSubmissionState.php | 23 ++
.../Submission/IncompleteSubmissionState.php | 34 ++
.../Submission/OnReviewSubmissionState.php | 24 ++
.../Submission/PaymentSubmissionState.php | 23 ++
.../Submission/PublishedSubmissionState.php | 18 +
.../Submission/QueuedSubmissionState.php | 30 ++
.../Submission/WithdrawnSubmissionState.php | 23 ++
app/Models/Submission.php | 24 ++
app/Models/SubmissionPaymentItem.php | 1 -
app/Models/Timeline.php | 2 +-
app/Observers/ConferenceObserver.php | 2 +-
.../Livewire/Submissions/CallforAbstract.php | 79 ++---
.../Livewire/Submissions/Forms/Publish.php | 7 +-
app/Panel/Livewire/Submissions/Payment.php | 20 +-
app/Panel/Livewire/Submissions/PeerReview.php | 11 +-
.../SubmissionWizard/Steps/ReviewStep.php | 27 +-
.../Workflows/Classes/StageManager.php | 5 +
.../Workflows/Payment/Tables/PaymentItems.php | 33 +-
.../Livewire/Workflows/PaymentSetting.php | 16 +-
app/Panel/Pages/Settings/Workflow.php | 2 +-
app/Panel/Resources/SubmissionResource.php | 8 -
.../Pages/ViewSubmission.php | 32 +-
app/Services/Payments/BasePayment.php | 2 -
app/Services/Payments/ManualPayment.php | 2 -
...023_12_12_112200_create_payments_table.php | 2 +-
nohup.out | 313 ++++++++++++++++++
36 files changed, 721 insertions(+), 199 deletions(-)
delete mode 100644 app/Actions/Submissions/UnpublishSubmissionAction.php
create mode 100644 app/Models/States/Interfaces/SubmissionStateInterface.php
create mode 100644 app/Models/States/Submission/BaseSubmissionState.php
create mode 100644 app/Models/States/Submission/DeclinedSubmissionState.php
create mode 100644 app/Models/States/Submission/EditingSubmissionState.php
create mode 100644 app/Models/States/Submission/IncompleteSubmissionState.php
create mode 100644 app/Models/States/Submission/OnReviewSubmissionState.php
create mode 100644 app/Models/States/Submission/PaymentSubmissionState.php
create mode 100644 app/Models/States/Submission/PublishedSubmissionState.php
create mode 100644 app/Models/States/Submission/QueuedSubmissionState.php
create mode 100644 app/Models/States/Submission/WithdrawnSubmissionState.php
create mode 100644 nohup.out
diff --git a/app/Actions/Submissions/UnpublishSubmissionAction.php b/app/Actions/Submissions/UnpublishSubmissionAction.php
deleted file mode 100644
index 9ae3f5cac..000000000
--- a/app/Actions/Submissions/UnpublishSubmissionAction.php
+++ /dev/null
@@ -1,22 +0,0 @@
- SubmissionStage::Editing,
- 'status' => SubmissionStatus::Editing,
- ], $submission);
- }
-}
diff --git a/app/Interfaces/PaymentDriver.php b/app/Interfaces/PaymentDriver.php
index 0c092c521..835d30838 100644
--- a/app/Interfaces/PaymentDriver.php
+++ b/app/Interfaces/PaymentDriver.php
@@ -6,17 +6,17 @@
interface PaymentDriver
{
- public function getName() : string;
+ public function getName(): string;
public function pay($amount, $submission);
- public function getPaymentForm(Form $form) : Form;
+ public function getPaymentForm(Form $form): Form;
+
+ public function getSettingFormSchema(): array;
- public function getSettingFormSchema() : array;
-
public function getSettingFormFill(): array;
public function saveSetting(array $data): void;
// public function fillSettingForm(Form $form): void;
-}
\ No newline at end of file
+}
diff --git a/app/Models/Enums/PaymentState.php b/app/Models/Enums/PaymentState.php
index f6a5bf47b..9d89eec6a 100644
--- a/app/Models/Enums/PaymentState.php
+++ b/app/Models/Enums/PaymentState.php
@@ -9,9 +9,9 @@ enum PaymentState: string implements HasLabel
{
use UsefulEnums;
- case Pending = 'Pending';
- case Confirmation = 'Confirmation';
- case Paid = 'Paid';
+ case Pending = 'Pending';
+ case Confirmation = 'Confirmation';
+ case Paid = 'Paid';
public function getLabel(): ?string
{
diff --git a/app/Models/Enums/PaymentType.php b/app/Models/Enums/PaymentType.php
index bc7fa634b..3daaff98c 100644
--- a/app/Models/Enums/PaymentType.php
+++ b/app/Models/Enums/PaymentType.php
@@ -3,9 +3,8 @@
namespace App\Models\Enums;
use App\Models\Enums\Concern\UsefulEnums;
-use Filament\Support\Contracts\HasLabel;
-enum PaymentType: string
+enum PaymentType: string
{
use UsefulEnums;
diff --git a/app/Models/Enums/SubmissionStage.php b/app/Models/Enums/SubmissionStage.php
index 52e4c6db5..46d7d15ec 100644
--- a/app/Models/Enums/SubmissionStage.php
+++ b/app/Models/Enums/SubmissionStage.php
@@ -9,12 +9,12 @@ enum SubmissionStage: string implements HasLabel
{
use UsefulEnums;
- case Wizard = 'Wizard';
- case CallforAbstract = 'Call for Abstract';
- case Payment = 'Payment';
- case PeerReview = 'Peer Review';
- case Editing = 'Editing';
- case Proceeding = 'Proceeding';
+ case Wizard = 'Wizard';
+ case CallforAbstract = 'Call for Abstract';
+ case Payment = 'Payment';
+ case PeerReview = 'Peer Review';
+ case Editing = 'Editing';
+ case Proceeding = 'Proceeding';
public function getLabel(): ?string
{
diff --git a/app/Models/Enums/SubmissionStatus.php b/app/Models/Enums/SubmissionStatus.php
index 656525bdc..186723cfd 100644
--- a/app/Models/Enums/SubmissionStatus.php
+++ b/app/Models/Enums/SubmissionStatus.php
@@ -3,14 +3,16 @@
namespace App\Models\Enums;
use App\Models\Enums\Concern\UsefulEnums;
+use Filament\Support\Contracts\HasColor;
use Filament\Support\Contracts\HasLabel;
-enum SubmissionStatus: string implements HasLabel
+enum SubmissionStatus: string implements HasLabel, HasColor
{
use UsefulEnums;
case Incomplete = 'Incomplete';
case Queued = 'Queued';
+ case Payment = 'Payment';
case OnReview = 'On Review';
case Editing = 'Editing';
case Published = 'Published';
@@ -22,4 +24,16 @@ public function getLabel(): ?string
{
return $this->name;
}
+
+ public function getColor(): string | array | null
+ {
+ return match ($this) {
+ self::Declined, self::Withdrawn => 'danger',
+ self::OnReview => 'warning',
+ self::Queued, self::Payment => 'primary',
+ self::Editing => 'info',
+ self::Published => 'success',
+ default => 'gray'
+ };
+ }
}
diff --git a/app/Models/Payment.php b/app/Models/Payment.php
index 72caba686..8d4455734 100644
--- a/app/Models/Payment.php
+++ b/app/Models/Payment.php
@@ -3,7 +3,6 @@
namespace App\Models;
use App\Models\Enums\PaymentState;
-use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class Payment extends Model
diff --git a/app/Models/States/Interfaces/SubmissionStateInterface.php b/app/Models/States/Interfaces/SubmissionStateInterface.php
new file mode 100644
index 000000000..c9ba00b97
--- /dev/null
+++ b/app/Models/States/Interfaces/SubmissionStateInterface.php
@@ -0,0 +1,22 @@
+ SubmissionStage::Proceeding,
+ 'status' => SubmissionStatus::Published,
+ ], $this->submission);
+ }
+
+ public function withdraw(): void
+ {
+ SubmissionUpdateAction::run(['status' => SubmissionStatus::Withdrawn], $this->submission);
+ }
+}
diff --git a/app/Models/States/Submission/IncompleteSubmissionState.php b/app/Models/States/Submission/IncompleteSubmissionState.php
new file mode 100644
index 000000000..3cfbb2415
--- /dev/null
+++ b/app/Models/States/Submission/IncompleteSubmissionState.php
@@ -0,0 +1,34 @@
+ SubmissionStage::CallforAbstract,
+ 'status' => SubmissionStatus::Queued,
+ ], $this->submission);
+
+ Mail::to($this->submission->user)->send(
+ new ThankAuthorMail($this->submission)
+ );
+
+ User::role([
+ UserRole::Admin->value,
+ UserRole::ConferenceManager->value,
+ ])
+ ->lazy()
+ ->each(fn ($user) => $user->notify(new NewSubmission($this->submission)));
+ }
+}
diff --git a/app/Models/States/Submission/OnReviewSubmissionState.php b/app/Models/States/Submission/OnReviewSubmissionState.php
new file mode 100644
index 000000000..5f5b7a11f
--- /dev/null
+++ b/app/Models/States/Submission/OnReviewSubmissionState.php
@@ -0,0 +1,24 @@
+ false,
+ 'stage' => SubmissionStage::Editing,
+ 'status' => SubmissionStatus::Editing,
+ ], $this->submission);
+ }
+
+ public function withdraw(): void
+ {
+ SubmissionUpdateAction::run(['status' => SubmissionStatus::Withdrawn], $this->submission);
+ }
+}
diff --git a/app/Models/States/Submission/PaymentSubmissionState.php b/app/Models/States/Submission/PaymentSubmissionState.php
new file mode 100644
index 000000000..7630d541c
--- /dev/null
+++ b/app/Models/States/Submission/PaymentSubmissionState.php
@@ -0,0 +1,23 @@
+ SubmissionStage::PeerReview,
+ 'status' => SubmissionStatus::OnReview,
+ ], $this->submission);
+ }
+
+ public function withdraw(): void
+ {
+ SubmissionUpdateAction::run(['status' => SubmissionStatus::Withdrawn], $this->submission);
+ }
+}
diff --git a/app/Models/States/Submission/PublishedSubmissionState.php b/app/Models/States/Submission/PublishedSubmissionState.php
new file mode 100644
index 000000000..e152f7aa9
--- /dev/null
+++ b/app/Models/States/Submission/PublishedSubmissionState.php
@@ -0,0 +1,18 @@
+ SubmissionStage::Editing,
+ 'status' => SubmissionStatus::Editing,
+ ], $this->submission);
+ }
+}
diff --git a/app/Models/States/Submission/QueuedSubmissionState.php b/app/Models/States/Submission/QueuedSubmissionState.php
new file mode 100644
index 000000000..a12d6111b
--- /dev/null
+++ b/app/Models/States/Submission/QueuedSubmissionState.php
@@ -0,0 +1,30 @@
+ SubmissionStage::Payment,
+ 'status' => SubmissionStatus::Payment,
+ ], $this->submission);
+ }
+
+ public function decline():void
+ {
+ SubmissionUpdateAction::run([
+ 'status' => SubmissionStatus::Declined,
+ ], $this->submission);
+ }
+
+ public function withdraw(): void
+ {
+ SubmissionUpdateAction::run(['status' => SubmissionStatus::Withdrawn], $this->submission);
+ }
+}
diff --git a/app/Models/States/Submission/WithdrawnSubmissionState.php b/app/Models/States/Submission/WithdrawnSubmissionState.php
new file mode 100644
index 000000000..35d0c48b6
--- /dev/null
+++ b/app/Models/States/Submission/WithdrawnSubmissionState.php
@@ -0,0 +1,23 @@
+ SubmissionStage::Proceeding,
+ 'status' => SubmissionStatus::Published,
+ ], $this->submission);
+ }
+
+ public function withdraw(): void
+ {
+ SubmissionUpdateAction::run(['status' => SubmissionStatus::Withdrawn], $this->submission);
+ }
+}
diff --git a/app/Models/Submission.php b/app/Models/Submission.php
index b69636d3f..679f66a12 100644
--- a/app/Models/Submission.php
+++ b/app/Models/Submission.php
@@ -8,6 +8,15 @@
use App\Models\Enums\SubmissionStatus;
use App\Models\Enums\UserRole;
use App\Models\Meta\SubmissionMeta;
+use App\Models\States\Submission\BaseSubmissionState;
+use App\Models\States\Submission\DeclinedSubmissionState;
+use App\Models\States\Submission\EditingSubmissionState;
+use App\Models\States\Submission\IncompleteSubmissionState;
+use App\Models\States\Submission\OnReviewSubmissionState;
+use App\Models\States\Submission\PaymentSubmissionState;
+use App\Models\States\Submission\PublishedSubmissionState;
+use App\Models\States\Submission\QueuedSubmissionState;
+use App\Models\States\Submission\WithdrawnSubmissionState;
use GeneaLabs\LaravelModelCaching\Traits\Cachable;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Factories\HasFactory;
@@ -175,4 +184,19 @@ public function getEditors(): Collection
->pluck('user_id')
->map(fn ($userId) => User::find($userId));
}
+
+ public function state(): BaseSubmissionState
+ {
+ return match ($this->status) {
+ SubmissionStatus::Incomplete => new IncompleteSubmissionState($this),
+ SubmissionStatus::Queued => new QueuedSubmissionState($this),
+ SubmissionStatus::Payment => new PaymentSubmissionState($this),
+ SubmissionStatus::OnReview => new OnReviewSubmissionState($this),
+ SubmissionStatus::Editing => new EditingSubmissionState($this),
+ SubmissionStatus::Published => new PublishedSubmissionState($this),
+ SubmissionStatus::Declined => new DeclinedSubmissionState($this),
+ SubmissionStatus::Withdrawn => new WithdrawnSubmissionState($this),
+ default => throw new \Exception('Invalid submission status'),
+ };
+ }
}
diff --git a/app/Models/SubmissionPaymentItem.php b/app/Models/SubmissionPaymentItem.php
index 581aa95db..5e2e65e17 100644
--- a/app/Models/SubmissionPaymentItem.php
+++ b/app/Models/SubmissionPaymentItem.php
@@ -3,7 +3,6 @@
namespace App\Models;
use App\Models\Concerns\BelongsToConference;
-use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Spatie\EloquentSortable\Sortable;
use Spatie\EloquentSortable\SortableTrait;
diff --git a/app/Models/Timeline.php b/app/Models/Timeline.php
index 8fe7b72af..2faceae1c 100644
--- a/app/Models/Timeline.php
+++ b/app/Models/Timeline.php
@@ -9,7 +9,7 @@
class Timeline extends Model
{
- use Cachable, BelongsToConference, HasFactory;
+ use BelongsToConference, Cachable, HasFactory;
protected $fillable = [
'title',
diff --git a/app/Observers/ConferenceObserver.php b/app/Observers/ConferenceObserver.php
index e1abfb327..1191b38ff 100644
--- a/app/Observers/ConferenceObserver.php
+++ b/app/Observers/ConferenceObserver.php
@@ -56,7 +56,7 @@ public function created(Conference $conference): void
]);
$conference->setMeta('page_footer', view('examples.footer')->render());
- $conference->setMeta('workflow.payment.supported_currencies', ['USD']);
+ $conference->setMeta('workflow.payment.supported_currencies', ['USD']);
$conference->save();
}
diff --git a/app/Panel/Livewire/Submissions/CallforAbstract.php b/app/Panel/Livewire/Submissions/CallforAbstract.php
index 691649ee9..70f01daf0 100644
--- a/app/Panel/Livewire/Submissions/CallforAbstract.php
+++ b/app/Panel/Livewire/Submissions/CallforAbstract.php
@@ -23,6 +23,7 @@
use Filament\Forms\Concerns\InteractsWithForms;
use Filament\Forms\Contracts\HasForms;
use Filament\Forms\Form;
+use Illuminate\Support\Facades\Log;
use Livewire\Component;
use Mohamedsabil83\FilamentFormsTinyeditor\Components\TinyEditor;
@@ -69,10 +70,7 @@ public function declineAction()
->successNotificationTitle('Submission declined')
->successRedirectUrl(fn (): string => SubmissionResource::getUrl('view', ['record' => $this->submission]))
->action(function (Action $action, array $data) {
- SubmissionUpdateAction::run([
- 'stage' => SubmissionStage::CallforAbstract,
- 'status' => SubmissionStatus::Declined,
- ], $this->submission);
+ $this->submission->state()->decline();
if (! $data['no-notification']) {
try {
@@ -148,46 +146,49 @@ public function acceptAction()
])
->action(
function (Action $action, array $data) {
- SubmissionUpdateAction::run([
- 'stage' => SubmissionStage::PeerReview,
- 'status' => SubmissionStatus::OnReview,
- ], $this->submission);
+ try {
+ $this->submission->state()->acceptAbstract();
- if (! $data['no-notification']) {
- try {
- $this->submission->user
- ->notify(
- new AbstractAccepted(
- submission: $this->submission,
- message: $data['message'],
- subject: $data['subject'],
- channels: ['mail']
- )
- );
- } catch (\Exception $e) {
- $action->failureNotificationTitle('The email notification was not delivered.');
- $action->failure();
+ if (! $data['no-notification']) {
+ try {
+ $this->submission->user
+ ->notify(
+ new AbstractAccepted(
+ submission: $this->submission,
+ message: $data['message'],
+ subject: $data['subject'],
+ channels: ['mail']
+ )
+ );
+ } catch (\Exception $e) {
+ $action->failureNotificationTitle('The email notification was not delivered.');
+ $action->failure();
+ }
}
- }
- $this->submission->user
- ->notify(
- new AbstractAccepted(
- submission: $this->submission,
- message: $data['message'],
- subject: $data['subject'],
- channels: ['database']
- )
- );
+ $this->submission->user
+ ->notify(
+ new AbstractAccepted(
+ submission: $this->submission,
+ message: $data['message'],
+ subject: $data['subject'],
+ channels: ['database']
+ )
+ );
- $action->successRedirectUrl(
- SubmissionResource::getUrl('view', [
- 'record' => $this->submission->getKey(),
- 'stage' => '-peer-review-tab',
- ])
- );
+ $action->successRedirectUrl(
+ SubmissionResource::getUrl('view', [
+ 'record' => $this->submission->getKey(),
+ 'stage' => '-payment-tab',
+ ])
+ );
- $action->success();
+ $action->success();
+ } catch (\Throwable $th) {
+ Log::error($th->getMessage());
+ $action->failureNotificationTitle('Failed to accept abstract');
+ $action->failure();
+ }
}
);
}
diff --git a/app/Panel/Livewire/Submissions/Forms/Publish.php b/app/Panel/Livewire/Submissions/Forms/Publish.php
index 04872d73d..502d3d187 100644
--- a/app/Panel/Livewire/Submissions/Forms/Publish.php
+++ b/app/Panel/Livewire/Submissions/Forms/Publish.php
@@ -34,11 +34,8 @@ class Publish extends \Livewire\Component implements HasActions, HasForms, HasIn
public Submission $submission;
public function handlePublishAction(Action $action, array $data)
- {
- SubmissionUpdateAction::run([
- 'stage' => SubmissionStage::Proceeding,
- 'status' => SubmissionStatus::Published,
- ], $this->submission);
+ {
+ $this->submission->state()->publish();
if (! $data['do-not-notify-author']) {
try {
diff --git a/app/Panel/Livewire/Submissions/Payment.php b/app/Panel/Livewire/Submissions/Payment.php
index 8cbcbcb1b..a178d9a72 100644
--- a/app/Panel/Livewire/Submissions/Payment.php
+++ b/app/Panel/Livewire/Submissions/Payment.php
@@ -2,32 +2,16 @@
namespace App\Panel\Livewire\Submissions;
-use App\Actions\Submissions\SubmissionUpdateAction;
-use App\Mail\Templates\AcceptAbstractMail;
-use App\Mail\Templates\DeclineAbstractMail;
-use App\Managers\PaymentManager;
-use App\Models\Enums\SubmissionStage;
-use App\Models\Enums\SubmissionStatus;
-use App\Models\MailTemplate;
+use App\Facades\Payment as PaymentFacade;
use App\Models\Submission;
-use App\Notifications\AbstractAccepted;
-use App\Notifications\AbstractDeclined;
use App\Panel\Livewire\Workflows\Classes\StageManager;
use App\Panel\Livewire\Workflows\Concerns\InteractWithTenant;
-use App\Panel\Resources\SubmissionResource;
-use Filament\Actions\Action;
use Filament\Actions\Concerns\InteractsWithActions;
use Filament\Actions\Contracts\HasActions;
-use Filament\Forms\Components\Checkbox;
-use Filament\Forms\Components\Fieldset;
-use Filament\Forms\Components\Section;
-use Filament\Forms\Components\TextInput;
use Filament\Forms\Concerns\InteractsWithForms;
use Filament\Forms\Contracts\HasForms;
use Filament\Forms\Form;
use Livewire\Component;
-use Mohamedsabil83\FilamentFormsTinyeditor\Components\TinyEditor;
-use App\Facades\Payment as PaymentFacade;
class Payment extends Component implements HasActions, HasForms
{
@@ -46,7 +30,7 @@ public function form(Form $form)
{
// return PaymentFacade::getPaymentForm($form);
return $form->schema([
-
+
]);
}
}
diff --git a/app/Panel/Livewire/Submissions/PeerReview.php b/app/Panel/Livewire/Submissions/PeerReview.php
index 45731eebf..128374b49 100644
--- a/app/Panel/Livewire/Submissions/PeerReview.php
+++ b/app/Panel/Livewire/Submissions/PeerReview.php
@@ -74,10 +74,7 @@ public function declineSubmissionAction()
]),
])
->action(function (Action $action, array $data) {
- SubmissionUpdateAction::run([
- 'revision_required' => false,
- 'status' => SubmissionStatus::Declined,
- ], $this->submission);
+ $this->submission->state()->decline();
if (! $data['do-not-notify-author']) {
try {
@@ -138,11 +135,7 @@ public function acceptSubmissionAction()
]),
])
->action(function (Action $action, array $data) {
- SubmissionUpdateAction::run([
- 'revision_required' => false,
- 'stage' => SubmissionStage::Editing,
- 'status' => SubmissionStatus::Editing,
- ], $this->submission);
+ $this->submission->state()->accept();
if (! $data['do-not-notify-author']) {
try {
diff --git a/app/Panel/Livewire/Wizards/SubmissionWizard/Steps/ReviewStep.php b/app/Panel/Livewire/Wizards/SubmissionWizard/Steps/ReviewStep.php
index 076b121e6..d34c4caa8 100644
--- a/app/Panel/Livewire/Wizards/SubmissionWizard/Steps/ReviewStep.php
+++ b/app/Panel/Livewire/Wizards/SubmissionWizard/Steps/ReviewStep.php
@@ -2,14 +2,7 @@
namespace App\Panel\Livewire\Wizards\SubmissionWizard\Steps;
-use App\Actions\Submissions\SubmissionUpdateAction;
-use App\Mail\Templates\ThankAuthorMail;
-use App\Models\Enums\SubmissionStage;
-use App\Models\Enums\SubmissionStatus;
-use App\Models\Enums\UserRole;
use App\Models\Submission;
-use App\Models\User;
-use App\Notifications\NewSubmission;
use App\Panel\Livewire\Wizards\SubmissionWizard\Contracts\HasWizardStep;
use App\Panel\Resources\SubmissionResource;
use Filament\Actions\Action;
@@ -17,7 +10,6 @@
use Filament\Actions\Contracts\HasActions;
use Filament\Forms\Concerns\InteractsWithForms;
use Filament\Forms\Contracts\HasForms;
-use Illuminate\Support\Facades\Mail;
use Livewire\Component;
class ReviewStep extends Component implements HasActions, HasForms, HasWizardStep
@@ -42,29 +34,14 @@ public function submitAction()
->requiresConfirmation()
->modalHeading('Submit abstract')
->modalDescription(function (): string {
- return 'Your about to submit your abstract to the conference, Please review your submission carefully before proceeding.';
+ return 'You will be submitting your abstract to the conference, Please review your submission carefully before proceeding.';
})
->modalSubmitActionLabel('Submit')
->successNotificationTitle('Abstract submitted, please wait for the conference manager to review your submission.')
->successRedirectUrl(fn (): string => SubmissionResource::getUrl('complete', ['record' => $this->record]))
->action(function (Action $action) {
-
- SubmissionUpdateAction::run([
- 'stage' => SubmissionStage::CallforAbstract,
- 'status' => SubmissionStatus::Queued,
- ], $this->record);
-
try {
- Mail::to($this->record->user)->send(
- new ThankAuthorMail($this->record)
- );
-
- $users = User::role([
- UserRole::Admin->value,
- UserRole::ConferenceManager->value,
- ])->get();
-
- $users->each(fn ($user) => $user->notify(new NewSubmission($this->record)));
+ $this->record->state()->fulfill();
} catch (\Exception $e) {
$action->failureNotificationTitle('Failed to send notifications');
$action->failure();
diff --git a/app/Panel/Livewire/Workflows/Classes/StageManager.php b/app/Panel/Livewire/Workflows/Classes/StageManager.php
index efe8469cf..d48ebb313 100644
--- a/app/Panel/Livewire/Workflows/Classes/StageManager.php
+++ b/app/Panel/Livewire/Workflows/Classes/StageManager.php
@@ -22,6 +22,11 @@ public static function callForAbstract(): static
return static::stage('call-for-abstract');
}
+ public static function payment(): static
+ {
+ return static::stage('payment');
+ }
+
public static function peerReview(): static
{
return static::stage('peer-review');
diff --git a/app/Panel/Livewire/Workflows/Payment/Tables/PaymentItems.php b/app/Panel/Livewire/Workflows/Payment/Tables/PaymentItems.php
index a24ce7dd6..7259c4f60 100644
--- a/app/Panel/Livewire/Workflows/Payment/Tables/PaymentItems.php
+++ b/app/Panel/Livewire/Workflows/Payment/Tables/PaymentItems.php
@@ -3,39 +3,30 @@
namespace App\Panel\Livewire\Workflows\Payment\Tables;
use App\Models\SubmissionPaymentItem;
-use Filament\Forms\Form;
-use Filament\Forms\Contracts\HasForms;
-use Stevebauman\Purify\Facades\Purify;
-use Filament\Tables\Contracts\HasTable;
-use Filament\Notifications\Notification;
-use Filament\Forms\Concerns\InteractsWithForms;
-use Filament\Tables\Concerns\InteractsWithTable;
-use App\Panel\Livewire\Workflows\Concerns\InteractWithTenant;
use App\Tables\Columns\IndexColumn;
-use App\Tables\Columns\ListColumn;
-use Faker\Provider\ar_EG\Text;
use Filament\Forms\Components\Grid;
-use Filament\Forms\Components\Group;
use Filament\Forms\Components\Repeater;
use Filament\Forms\Components\Select;
use Filament\Forms\Components\Textarea;
use Filament\Forms\Components\TextInput;
+use Filament\Forms\Concerns\InteractsWithForms;
+use Filament\Forms\Contracts\HasForms;
+use Filament\Forms\Form;
use Filament\Forms\Get;
use Filament\Tables\Actions\CreateAction;
use Filament\Tables\Actions\DeleteAction;
use Filament\Tables\Actions\EditAction;
-use Filament\Tables\Columns\Layout\Panel;
-use Filament\Tables\Columns\Layout\Stack;
use Filament\Tables\Columns\TextColumn;
+use Filament\Tables\Concerns\InteractsWithTable;
+use Filament\Tables\Contracts\HasTable;
use Filament\Tables\Table;
use Illuminate\Support\Facades\App;
-use Mohamedsabil83\FilamentFormsTinyeditor\Components\TinyEditor;
use Squire\Models\Currency;
class PaymentItems extends \Livewire\Component implements HasForms, HasTable
{
- use InteractsWithTable;
use InteractsWithForms;
+ use InteractsWithTable;
public function render()
{
@@ -67,7 +58,7 @@ public function table(Table $table): Table
TextInput::make('fee')
->required()
->minValue(1)
- ->prefix(fn(Get $get) => $get('currency_id') ? Currency::find($get('currency_id'))->symbol_native : null)
+ ->prefix(fn (Get $get) => $get('currency_id') ? Currency::find($get('currency_id'))->symbol_native : null)
->numeric(),
]),
])
@@ -75,7 +66,7 @@ public function table(Table $table): Table
->reorderable(false)
// ->reorderableWithButtons()
->addable(false)
- ->addActionLabel('Add Fee')
+ ->addActionLabel('Add Fee'),
];
return $table
@@ -93,7 +84,7 @@ public function table(Table $table): Table
])
->headerActions([
CreateAction::make()
- ->label("New Payment Item")
+ ->label('New Payment Item')
->mountUsing(function (Form $form) {
$fees = collect(App::getCurrentConference()->getMeta('workflow.payment.supported_currencies'))->map(function ($currency) {
return [
@@ -102,12 +93,12 @@ public function table(Table $table): Table
];
})->toArray();
$form->fill([
- 'fees' => $fees
+ 'fees' => $fees,
]);
})
->model(SubmissionPaymentItem::class)
->modalWidth('2xl')
- ->form($formField)
+ ->form($formField),
])
->filters([
// ...
@@ -120,7 +111,7 @@ public function table(Table $table): Table
->map(fn ($currency) => ['currency_id' => $currency, 'fee' => 0])
->keyBy('currency_id')
->merge(collect($data['fees'])->keyBy('currency_id'))
- ->filter(fn($fee) => in_array($fee['currency_id'], $supportedCurrencies))
+ ->filter(fn ($fee) => in_array($fee['currency_id'], $supportedCurrencies))
->toArray();
$data['fees'] = $fees;
diff --git a/app/Panel/Livewire/Workflows/PaymentSetting.php b/app/Panel/Livewire/Workflows/PaymentSetting.php
index 66d322adb..c3139eb08 100644
--- a/app/Panel/Livewire/Workflows/PaymentSetting.php
+++ b/app/Panel/Livewire/Workflows/PaymentSetting.php
@@ -3,23 +3,18 @@
namespace App\Panel\Livewire\Workflows;
use App\Facades\Payment;
-use App\Panel\Livewire\Submissions\Components\Files\SubmissionFilesTable;
use App\Panel\Livewire\Workflows\Base\WorkflowStage;
use Awcodes\Shout\Components\Shout;
use Filament\Actions\Action;
use Filament\Actions\Concerns\InteractsWithActions;
use Filament\Actions\Contracts\HasActions;
use Filament\Forms\Components\Grid;
-use Filament\Forms\Components\Section;
use Filament\Forms\Components\Select;
-use Filament\Forms\Components\TagsInput;
-use Filament\Forms\Components\Textarea;
use Filament\Forms\Concerns\InteractsWithForms;
use Filament\Forms\Contracts\HasForms;
use Filament\Forms\Form;
use Filament\Forms\Get;
use Illuminate\Support\Facades\Log;
-use Mohamedsabil83\FilamentFormsTinyeditor\Components\TinyEditor;
use Squire\Models\Currency;
class PaymentSetting extends WorkflowStage implements HasActions, HasForms
@@ -36,7 +31,7 @@ public function mount()
{
$this->form->fill([
'settings' => [
- 'payment_method' => $this->getSetting('payment_method', 'manual'),
+ 'payment_method' => $this->getSetting('payment_method', 'manual'),
'supported_currencies' => $this->getSetting('supported_currencies'),
],
...Payment::getAllDriverNames()->map(fn ($name, $key) => Payment::driver($key)->getSettingFormFill())->toArray(),
@@ -58,13 +53,14 @@ public function submitAction()
foreach ($data['settings'] as $key => $value) {
$this->updateSetting($key, $value);
}
-
+
Payment::driver($data['settings']['payment_method'])
->saveSetting(data_get($data, $data['settings']['payment_method'], []));
} catch (\Throwable $th) {
//throw $th;
Log::error($th);
$action->failure();
+
return;
}
@@ -90,11 +86,11 @@ public function form(Form $form): Form
->searchable()
->required()
->multiple()
- ->options(Currency::query()->get()->mapWithKeys(fn (Currency $currency) => [$currency->id => $currency->name . ' (' . $currency->symbol_native . ')'])->toArray())
+ ->options(Currency::query()->get()->mapWithKeys(fn (Currency $currency) => [$currency->id => $currency->name.' ('.$currency->symbol_native.')'])->toArray())
->optionsLimit(250),
Grid::make(1)
- ->hidden(fn (Get $get) => !$get('settings.payment_method'))
- ->schema(fn (Get $get) => Payment::driver($get('payment_method'))->getSettingFormSchema())
+ ->hidden(fn (Get $get) => ! $get('settings.payment_method'))
+ ->schema(fn (Get $get) => Payment::driver($get('payment_method'))->getSettingFormSchema()),
]);
}
diff --git a/app/Panel/Pages/Settings/Workflow.php b/app/Panel/Pages/Settings/Workflow.php
index e5825d6f0..2b0b466d5 100644
--- a/app/Panel/Pages/Settings/Workflow.php
+++ b/app/Panel/Pages/Settings/Workflow.php
@@ -35,7 +35,7 @@ class Workflow extends Page implements HasForms, HasInfolists
public function booted(): void
{
- abort_if(!static::canView(), 403);
+ abort_if(! static::canView(), 403);
}
public static function shouldRegisterNavigation(): bool
diff --git a/app/Panel/Resources/SubmissionResource.php b/app/Panel/Resources/SubmissionResource.php
index d581d5550..9e72eacdd 100644
--- a/app/Panel/Resources/SubmissionResource.php
+++ b/app/Panel/Resources/SubmissionResource.php
@@ -137,14 +137,6 @@ public static function table(Table $table): Table
'class' => 'mt-2',
])
->badge()
- ->color(fn (Submission $record): string => match ($record->status) {
- SubmissionStatus::Declined, SubmissionStatus::Withdrawn => 'danger',
- SubmissionStatus::OnReview => 'warning',
- SubmissionStatus::Queued => 'primary',
- SubmissionStatus::Editing => 'info',
- SubmissionStatus::Published => 'success',
- default => 'gray'
- })
->formatStateUsing(
fn (Submission $record) => $record->status
),
diff --git a/app/Panel/Resources/SubmissionResource/Pages/ViewSubmission.php b/app/Panel/Resources/SubmissionResource/Pages/ViewSubmission.php
index d0cb8970e..b4f4b98e8 100644
--- a/app/Panel/Resources/SubmissionResource/Pages/ViewSubmission.php
+++ b/app/Panel/Resources/SubmissionResource/Pages/ViewSubmission.php
@@ -70,11 +70,12 @@ protected function getHeaderActions(): array
->requiresConfirmation()
->successNotificationTitle('Submission unpublished')
->action(function (Action $action) {
- UnpublishSubmissionAction::run($this->record);
+ $this->record->state()->unpublish();
+
$action->successRedirectUrl(
static::getResource()::getUrl('view', [
'record' => $this->record,
- 'stage' => '-' . str($this->record->stage->value)->slug('-') . '-tab',
+ 'stage' => '-'.str($this->record->stage->value)->slug('-').'-tab',
])
);
@@ -123,7 +124,7 @@ protected function getHeaderActions(): array
$action->successRedirectUrl(
SubmissionResource::getUrl('view', [
'record' => $this->record,
- 'stage' => '-' . str($this->record->stage->value)->slug('-') . '-tab',
+ 'stage' => '-'.str($this->record->stage->value)->slug('-').'-tab',
]),
);
$action->success();
@@ -134,7 +135,7 @@ protected function getHeaderActions(): array
->color('danger')
->extraAttributes(function (Action $action) {
if (filled($this->record->withdrawn_reason)) {
- $attributeValue = '$nextTick(() => { $wire.mountAction(\'' . $action->getName() . '\') })';
+ $attributeValue = '$nextTick(() => { $wire.mountAction(\''.$action->getName().'\') })';
return [
'x-init' => new HtmlString($attributeValue),
@@ -158,7 +159,7 @@ protected function getHeaderActions(): array
])
->requiresConfirmation()
->modalHeading(function () {
- return $this->record->user->fullName . ' has requested to withdraw this submission.';
+ return $this->record->user->fullName.' has requested to withdraw this submission.';
})
->modalDescription("You can either reject the request or accept it, remember it can't be undone.")
->modalCancelActionLabel('Ignore')
@@ -173,7 +174,7 @@ protected function getHeaderActions(): array
$action->successRedirectUrl(
SubmissionResource::getUrl('view', [
'record' => $this->record,
- 'stage' => '-' . str($this->record->stage->value)->slug('-') . '-tab',
+ 'stage' => '-'.str($this->record->stage->value)->slug('-').'-tab',
]),
);
$action->successNotificationTitle('Withdrawal request rejected');
@@ -193,7 +194,7 @@ protected function getHeaderActions(): array
$action->successRedirectUrl(
SubmissionResource::getUrl('view', [
'record' => $this->record,
- 'stage' => '-' . str($this->record->stage->value)->slug('-') . '-tab',
+ 'stage' => '-'.str($this->record->stage->value)->slug('-').'-tab',
]),
);
$action->success();
@@ -205,13 +206,14 @@ protected function getHeaderActions(): array
public function getSubheading(): string|Htmlable|null
{
$badgeHtml = match ($this->record->status) {
- SubmissionStatus::Queued => '' . SubmissionStatus::Queued->value . '',
- SubmissionStatus::Declined => '' . SubmissionStatus::Declined->value . '',
- SubmissionStatus::Withdrawn => '' . SubmissionStatus::Withdrawn->value . '',
- SubmissionStatus::Published => '' . SubmissionStatus::Published->value . '',
- SubmissionStatus::OnReview => '' . SubmissionStatus::OnReview->value . '',
- SubmissionStatus::Incomplete => '' . SubmissionStatus::Incomplete->value . '',
- SubmissionStatus::Editing => '' . SubmissionStatus::Editing->value . '',
+ SubmissionStatus::Incomplete => ''.SubmissionStatus::Incomplete->value.'',
+ SubmissionStatus::Queued => ''.SubmissionStatus::Queued->value.'',
+ SubmissionStatus::Payment => ''.SubmissionStatus::Payment->value.'',
+ SubmissionStatus::OnReview => ''.SubmissionStatus::OnReview->value.'',
+ SubmissionStatus::Published => ''.SubmissionStatus::Published->value.'',
+ SubmissionStatus::Editing => ''.SubmissionStatus::Editing->value.'',
+ SubmissionStatus::Declined => ''.SubmissionStatus::Declined->value.'',
+ SubmissionStatus::Withdrawn => ''.SubmissionStatus::Withdrawn->value.'',
default => null,
};
@@ -307,7 +309,7 @@ public function infolist(Infolist $infolist): Infolist
LivewireEntry::make('contributors')
->livewire(ContributorList::class, [
'submission' => $this->record,
- 'viewOnly' => !auth()->user()->can('editing', $this->record),
+ 'viewOnly' => ! auth()->user()->can('editing', $this->record),
]),
]),
Tab::make('References')
diff --git a/app/Services/Payments/BasePayment.php b/app/Services/Payments/BasePayment.php
index cf841796a..6b6a9bdbc 100644
--- a/app/Services/Payments/BasePayment.php
+++ b/app/Services/Payments/BasePayment.php
@@ -3,9 +3,7 @@
namespace App\Services\Payments;
use App\Interfaces\PaymentDriver;
-use App\Models\Conference;
abstract class BasePayment implements PaymentDriver
{
-
}
diff --git a/app/Services/Payments/ManualPayment.php b/app/Services/Payments/ManualPayment.php
index dff5de155..2e74d91c7 100644
--- a/app/Services/Payments/ManualPayment.php
+++ b/app/Services/Payments/ManualPayment.php
@@ -2,9 +2,7 @@
namespace App\Services\Payments;
-use App\Interfaces\PaymentDriver;
use Filament\Forms\Components\Section;
-use Filament\Forms\Components\Textarea;
use Filament\Forms\Components\TextInput;
use Filament\Forms\Form;
use Illuminate\Support\Facades\App;
diff --git a/database/migrations/2023_12_12_112200_create_payments_table.php b/database/migrations/2023_12_12_112200_create_payments_table.php
index 1a0db45f8..ca5a89a38 100644
--- a/database/migrations/2023_12_12_112200_create_payments_table.php
+++ b/database/migrations/2023_12_12_112200_create_payments_table.php
@@ -30,7 +30,7 @@ public function up(): void
$table->index(['state']);
});
- Schema::create('submission_payment_items', function (Blueprint $table){
+ Schema::create('submission_payment_items', function (Blueprint $table) {
$table->id();
$table->foreignIdFor(Conference::class)->constrained();
$table->string('name');
diff --git a/nohup.out b/nohup.out
new file mode 100644
index 000000000..abcfedee6
--- /dev/null
+++ b/nohup.out
@@ -0,0 +1,313 @@
+Horizon started successfully.
+ 2023-12-15 10:01:36 App\Mail\Templates\ThankAuthorMail ............. RUNNING
+ 2023-12-15 10:01:36 App\Mail\Templates\ThankAuthorMail ........ 84.65ms DONE
+ 2023-12-15 10:01:36 App\Notifications\NewSubmission ................ RUNNING
+ 2023-12-15 10:01:37 App\Notifications\NewSubmission ........... 34.20ms DONE
+ 2023-12-15 10:01:37 App\Notifications\NewSubmission ................ RUNNING
+ 2023-12-15 10:01:37 App\Notifications\NewSubmission ........... 24.47ms FAIL
+ 2023-12-15 10:01:37 App\Notifications\NewSubmission ................ RUNNING
+ 2023-12-15 10:01:37 App\Notifications\NewSubmission ............ 8.43ms DONE
+ 2023-12-15 10:01:37 App\Notifications\NewSubmission ................ RUNNING
+ 2023-12-15 10:01:37 App\Notifications\NewSubmission ............ 7.95ms FAIL
+ 2023-12-15 10:01:37 App\Notifications\NewSubmission ................ RUNNING
+ 2023-12-15 10:01:37 App\Notifications\NewSubmission ............ 7.19ms DONE
+ 2023-12-15 10:01:37 App\Notifications\NewSubmission ................ RUNNING
+ 2023-12-15 10:01:37 App\Notifications\NewSubmission ........... 17.05ms FAIL
+ 2023-12-15 10:01:37 App\Notifications\NewSubmission ................ RUNNING
+ 2023-12-15 10:01:37 App\Notifications\NewSubmission ............ 7.87ms DONE
+ 2023-12-15 10:01:37 App\Notifications\NewSubmission ................ RUNNING
+ 2023-12-15 10:01:37 App\Notifications\NewSubmission ............ 8.69ms FAIL
+ 2023-12-15 10:01:37 App\Notifications\NewSubmission ................ RUNNING
+ 2023-12-15 10:01:37 App\Notifications\NewSubmission ............ 8.28ms DONE
+ 2023-12-15 10:01:37 App\Notifications\NewSubmission ................ RUNNING
+ 2023-12-15 10:01:37 App\Notifications\NewSubmission ............ 7.16ms FAIL
+ 2023-12-15 10:01:37 App\Notifications\NewSubmission ................ RUNNING
+ 2023-12-15 10:01:37 App\Notifications\NewSubmission ............ 7.48ms DONE
+ 2023-12-15 10:01:37 App\Notifications\NewSubmission ................ RUNNING
+ 2023-12-15 10:01:37 App\Notifications\NewSubmission ............ 7.34ms FAIL
+ 2023-12-15 10:01:37 App\Notifications\NewSubmission ................ RUNNING
+ 2023-12-15 10:01:37 App\Notifications\NewSubmission ............ 8.14ms DONE
+ 2023-12-15 10:01:37 App\Notifications\NewSubmission ................ RUNNING
+ 2023-12-15 10:01:37 App\Notifications\NewSubmission ............ 7.48ms FAIL
+ 2023-12-15 10:01:37 App\Notifications\NewSubmission ................ RUNNING
+ 2023-12-15 10:01:37 App\Notifications\NewSubmission ............ 7.86ms DONE
+ 2023-12-15 10:01:37 App\Notifications\NewSubmission ................ RUNNING
+ 2023-12-15 10:01:37 App\Notifications\NewSubmission ............ 7.36ms FAIL
+ 2023-12-15 10:01:37 App\Notifications\NewSubmission ................ RUNNING
+ 2023-12-15 10:01:37 App\Notifications\NewSubmission ............ 6.73ms DONE
+ 2023-12-15 10:01:37 App\Notifications\NewSubmission ................ RUNNING
+ 2023-12-15 10:01:37 App\Notifications\NewSubmission ............ 8.13ms FAIL
+ 2023-12-15 10:01:37 App\Notifications\NewSubmission ................ RUNNING
+ 2023-12-15 10:01:37 App\Notifications\NewSubmission ............ 8.31ms DONE
+ 2023-12-15 10:01:37 App\Notifications\NewSubmission ................ RUNNING
+ 2023-12-15 10:01:37 App\Notifications\NewSubmission ............ 8.31ms FAIL
+ 2023-12-15 10:01:37 App\Notifications\NewSubmission ................ RUNNING
+ 2023-12-15 10:01:37 App\Notifications\NewSubmission ............ 6.85ms DONE
+ 2023-12-15 10:01:37 App\Notifications\NewSubmission ................ RUNNING
+ 2023-12-15 10:01:37 App\Notifications\NewSubmission ............ 7.92ms FAIL
+ 2023-12-15 10:01:37 App\Notifications\NewSubmission ................ RUNNING
+ 2023-12-15 10:01:37 App\Notifications\NewSubmission ............ 9.01ms DONE
+ 2023-12-15 10:01:37 App\Notifications\NewSubmission ................ RUNNING
+ 2023-12-15 10:01:37 App\Notifications\NewSubmission ............ 8.52ms FAIL
+ 2023-12-15 10:01:37 App\Notifications\NewSubmission ................ RUNNING
+ 2023-12-15 10:01:37 App\Notifications\NewSubmission ........... 10.24ms DONE
+ 2023-12-15 10:01:37 App\Notifications\NewSubmission ................ RUNNING
+ 2023-12-15 10:01:37 App\Notifications\NewSubmission ............ 7.76ms FAIL
+ 2023-12-15 10:01:37 App\Notifications\NewSubmission ................ RUNNING
+ 2023-12-15 10:01:37 App\Notifications\NewSubmission ............ 9.21ms DONE
+ 2023-12-15 10:01:37 App\Notifications\NewSubmission ................ RUNNING
+ 2023-12-15 10:01:37 App\Notifications\NewSubmission ............ 9.49ms FAIL
+ 2023-12-15 10:01:37 App\Notifications\NewSubmission ................ RUNNING
+ 2023-12-15 10:01:37 App\Notifications\NewSubmission ............ 9.50ms DONE
+ 2023-12-15 10:01:37 App\Notifications\NewSubmission ................ RUNNING
+ 2023-12-15 10:01:37 App\Notifications\NewSubmission ............ 7.81ms FAIL
+ 2023-12-15 10:01:37 App\Notifications\NewSubmission ................ RUNNING
+ 2023-12-15 10:01:37 App\Notifications\NewSubmission ............ 9.83ms DONE
+ 2023-12-15 10:01:37 App\Notifications\NewSubmission ................ RUNNING
+ 2023-12-15 10:01:37 App\Notifications\NewSubmission ............ 8.44ms FAIL
+ 2023-12-15 10:01:37 App\Notifications\NewSubmission ................ RUNNING
+ 2023-12-15 10:01:37 App\Notifications\NewSubmission ............ 9.48ms DONE
+ 2023-12-15 10:01:37 App\Notifications\NewSubmission ................ RUNNING
+ 2023-12-15 10:01:37 App\Notifications\NewSubmission ............ 8.38ms FAIL
+ 2023-12-15 10:01:37 App\Notifications\NewSubmission ................ RUNNING
+ 2023-12-15 10:01:37 App\Notifications\NewSubmission ............ 7.84ms DONE
+ 2023-12-15 10:01:37 App\Notifications\NewSubmission ................ RUNNING
+ 2023-12-15 10:01:37 App\Notifications\NewSubmission ............ 8.20ms FAIL
+ 2023-12-15 10:01:37 App\Notifications\NewSubmission ................ RUNNING
+ 2023-12-15 10:01:37 App\Notifications\NewSubmission ............ 9.12ms DONE
+ 2023-12-15 10:01:37 App\Notifications\NewSubmission ................ RUNNING
+ 2023-12-15 10:01:37 App\Notifications\NewSubmission ............ 7.89ms FAIL
+ 2023-12-15 10:01:37 App\Notifications\NewSubmission ................ RUNNING
+ 2023-12-15 10:01:37 App\Notifications\NewSubmission ............ 8.49ms DONE
+ 2023-12-15 10:01:37 App\Notifications\NewSubmission ................ RUNNING
+ 2023-12-15 10:01:37 App\Notifications\NewSubmission ............ 9.64ms FAIL
+ 2023-12-15 10:01:37 App\Notifications\NewSubmission ................ RUNNING
+ 2023-12-15 10:01:37 App\Notifications\NewSubmission ............ 7.16ms DONE
+ 2023-12-15 10:01:37 App\Notifications\NewSubmission ................ RUNNING
+ 2023-12-15 10:01:37 App\Notifications\NewSubmission ............ 9.04ms FAIL
+ 2023-12-15 10:01:37 App\Notifications\NewSubmission ................ RUNNING
+ 2023-12-15 10:01:37 App\Notifications\NewSubmission ............ 7.25ms DONE
+ 2023-12-15 10:01:37 App\Notifications\NewSubmission ................ RUNNING
+ 2023-12-15 10:01:37 App\Notifications\NewSubmission ............ 7.82ms FAIL
+ 2023-12-15 10:01:37 App\Notifications\NewSubmission ................ RUNNING
+ 2023-12-15 10:01:37 App\Notifications\NewSubmission ............ 7.07ms DONE
+ 2023-12-15 10:01:37 App\Notifications\NewSubmission ................ RUNNING
+ 2023-12-15 10:01:37 App\Notifications\NewSubmission ............ 8.20ms FAIL
+ 2023-12-15 10:01:37 App\Notifications\NewSubmission ................ RUNNING
+ 2023-12-15 10:01:37 App\Notifications\NewSubmission ............ 8.14ms DONE
+ 2023-12-15 10:01:37 App\Notifications\NewSubmission ................ RUNNING
+ 2023-12-15 10:01:37 App\Notifications\NewSubmission ............ 8.86ms FAIL
+ 2023-12-15 10:01:37 App\Notifications\NewSubmission ................ RUNNING
+ 2023-12-15 10:01:37 App\Notifications\NewSubmission ............ 7.54ms DONE
+ 2023-12-15 10:01:37 App\Notifications\NewSubmission ................ RUNNING
+ 2023-12-15 10:01:37 App\Notifications\NewSubmission ............ 8.08ms FAIL
+ 2023-12-15 10:01:37 App\Notifications\NewSubmission ................ RUNNING
+ 2023-12-15 10:01:37 App\Notifications\NewSubmission ............ 8.17ms DONE
+ 2023-12-15 10:01:37 App\Notifications\NewSubmission ................ RUNNING
+ 2023-12-15 10:01:37 App\Notifications\NewSubmission ............ 8.92ms FAIL
+ 2023-12-15 10:01:37 App\Notifications\NewSubmission ................ RUNNING
+ 2023-12-15 10:01:37 App\Notifications\NewSubmission ............ 6.97ms DONE
+ 2023-12-15 10:01:37 App\Notifications\NewSubmission ................ RUNNING
+ 2023-12-15 10:01:37 App\Notifications\NewSubmission ........... 18.88ms FAIL
+ 2023-12-15 10:01:37 App\Notifications\NewSubmission ................ RUNNING
+ 2023-12-15 10:01:37 App\Notifications\NewSubmission ............ 6.64ms DONE
+ 2023-12-15 10:01:37 App\Notifications\NewSubmission ................ RUNNING
+ 2023-12-15 10:01:37 App\Notifications\NewSubmission ........... 11.24ms FAIL
+ 2023-12-15 10:01:37 App\Notifications\NewSubmission ................ RUNNING
+ 2023-12-15 10:01:37 App\Notifications\NewSubmission ............ 6.69ms DONE
+ 2023-12-15 10:01:37 App\Notifications\NewSubmission ................ RUNNING
+ 2023-12-15 10:01:37 App\Notifications\NewSubmission ............ 8.63ms FAIL
+ 2023-12-15 10:01:37 App\Notifications\NewSubmission ................ RUNNING
+ 2023-12-15 10:01:37 App\Notifications\NewSubmission ............ 8.59ms DONE
+ 2023-12-15 10:01:37 App\Notifications\NewSubmission ................ RUNNING
+ 2023-12-15 10:01:37 App\Notifications\NewSubmission ............ 9.16ms FAIL
+ 2023-12-15 10:01:37 App\Notifications\NewSubmission ................ RUNNING
+ 2023-12-15 10:01:37 App\Notifications\NewSubmission ............ 8.79ms DONE
+ 2023-12-15 10:01:37 App\Notifications\NewSubmission ................ RUNNING
+ 2023-12-15 10:01:37 App\Notifications\NewSubmission ............ 8.88ms FAIL
+ 2023-12-15 10:01:37 App\Notifications\NewSubmission ................ RUNNING
+ 2023-12-15 10:01:37 App\Notifications\NewSubmission ............ 7.88ms DONE
+ 2023-12-15 10:01:37 App\Notifications\NewSubmission ................ RUNNING
+ 2023-12-15 10:01:37 App\Notifications\NewSubmission ............ 8.85ms FAIL
+ 2023-12-15 10:01:37 App\Notifications\NewSubmission ................ RUNNING
+ 2023-12-15 10:01:37 App\Notifications\NewSubmission ............ 7.24ms DONE
+ 2023-12-15 10:01:37 App\Notifications\NewSubmission ................ RUNNING
+ 2023-12-15 10:01:37 App\Notifications\NewSubmission ............ 8.09ms FAIL
+ 2023-12-15 10:01:37 App\Notifications\NewSubmission ................ RUNNING
+ 2023-12-15 10:01:37 App\Notifications\NewSubmission ........... 14.14ms DONE
+ 2023-12-15 10:01:37 App\Notifications\NewSubmission ................ RUNNING
+ 2023-12-15 10:01:37 App\Notifications\NewSubmission ............ 8.76ms FAIL
+ 2023-12-15 10:01:37 App\Notifications\NewSubmission ................ RUNNING
+ 2023-12-15 10:01:37 App\Notifications\NewSubmission ............ 8.32ms DONE
+ 2023-12-15 10:01:37 App\Notifications\NewSubmission ................ RUNNING
+ 2023-12-15 10:01:37 App\Notifications\NewSubmission ............ 9.30ms FAIL
+ 2023-12-15 10:01:37 App\Notifications\NewSubmission ................ RUNNING
+ 2023-12-15 10:01:37 App\Notifications\NewSubmission ............ 7.20ms DONE
+ 2023-12-15 10:01:37 App\Notifications\NewSubmission ................ RUNNING
+ 2023-12-15 10:01:37 App\Notifications\NewSubmission ............ 9.17ms FAIL
+ 2023-12-15 10:01:37 App\Notifications\NewSubmission ................ RUNNING
+ 2023-12-15 10:01:37 App\Notifications\NewSubmission ............ 7.55ms DONE
+ 2023-12-15 10:01:37 App\Notifications\NewSubmission ................ RUNNING
+ 2023-12-15 10:01:37 App\Notifications\NewSubmission ............ 9.16ms FAIL
+ 2023-12-15 10:01:37 App\Notifications\NewSubmission ................ RUNNING
+ 2023-12-15 10:01:37 App\Notifications\NewSubmission ........... 10.07ms DONE
+ 2023-12-15 10:01:37 App\Notifications\NewSubmission ................ RUNNING
+ 2023-12-15 10:01:37 App\Notifications\NewSubmission ............ 9.47ms FAIL
+ 2023-12-15 10:02:56 App\Mail\Templates\ThankAuthorMail ............. RUNNING
+ 2023-12-15 10:02:56 App\Mail\Templates\ThankAuthorMail ........ 30.44ms DONE
+ 2023-12-15 10:02:56 App\Notifications\NewSubmission ................ RUNNING
+ 2023-12-15 10:02:56 App\Notifications\NewSubmission ........... 13.22ms DONE
+ 2023-12-15 10:02:56 App\Notifications\NewSubmission ................ RUNNING
+ 2023-12-15 10:02:56 App\Notifications\NewSubmission ........... 11.16ms FAIL
+ 2023-12-15 10:02:56 App\Notifications\NewSubmission ................ RUNNING
+ 2023-12-15 10:02:56 App\Notifications\NewSubmission ............ 8.19ms DONE
+ 2023-12-15 10:02:56 App\Notifications\NewSubmission ................ RUNNING
+ 2023-12-15 10:02:56 App\Notifications\NewSubmission ............ 9.50ms FAIL
+ 2023-12-15 10:02:56 App\Notifications\NewSubmission ................ RUNNING
+ 2023-12-15 10:02:56 App\Notifications\NewSubmission ............ 7.70ms DONE
+ 2023-12-15 10:02:56 App\Notifications\NewSubmission ................ RUNNING
+ 2023-12-15 10:02:56 App\Notifications\NewSubmission ............ 7.67ms FAIL
+ 2023-12-15 10:02:56 App\Notifications\NewSubmission ................ RUNNING
+ 2023-12-15 10:02:56 App\Notifications\NewSubmission ............ 9.52ms DONE
+ 2023-12-15 10:02:56 App\Notifications\NewSubmission ................ RUNNING
+ 2023-12-15 10:02:56 App\Notifications\NewSubmission ............ 8.14ms FAIL
+ 2023-12-15 10:02:56 App\Notifications\NewSubmission ................ RUNNING
+ 2023-12-15 10:02:56 App\Notifications\NewSubmission ........... 21.84ms DONE
+ 2023-12-15 10:02:56 App\Notifications\NewSubmission ................ RUNNING
+ 2023-12-15 10:02:56 App\Notifications\NewSubmission ............ 7.98ms FAIL
+ 2023-12-15 10:02:56 App\Notifications\NewSubmission ................ RUNNING
+ 2023-12-15 10:02:56 App\Notifications\NewSubmission ............ 7.37ms DONE
+ 2023-12-15 10:02:56 App\Notifications\NewSubmission ................ RUNNING
+ 2023-12-15 10:02:56 App\Notifications\NewSubmission ............ 9.20ms FAIL
+ 2023-12-15 10:02:56 App\Notifications\NewSubmission ................ RUNNING
+ 2023-12-15 10:02:56 App\Notifications\NewSubmission ............ 7.92ms DONE
+ 2023-12-15 10:02:56 App\Notifications\NewSubmission ................ RUNNING
+ 2023-12-15 10:02:56 App\Notifications\NewSubmission ............ 7.74ms FAIL
+ 2023-12-15 10:02:56 App\Notifications\NewSubmission ................ RUNNING
+ 2023-12-15 10:02:56 App\Notifications\NewSubmission ............ 8.18ms DONE
+ 2023-12-15 10:02:56 App\Notifications\NewSubmission ................ RUNNING
+ 2023-12-15 10:02:56 App\Notifications\NewSubmission ............ 7.60ms FAIL
+ 2023-12-15 10:02:56 App\Notifications\NewSubmission ................ RUNNING
+ 2023-12-15 10:02:56 App\Notifications\NewSubmission ........... 19.38ms DONE
+ 2023-12-15 10:02:56 App\Notifications\NewSubmission ................ RUNNING
+ 2023-12-15 10:02:56 App\Notifications\NewSubmission ............ 7.98ms FAIL
+ 2023-12-15 10:02:56 App\Notifications\NewSubmission ................ RUNNING
+ 2023-12-15 10:02:56 App\Notifications\NewSubmission ............ 7.18ms DONE
+ 2023-12-15 10:02:56 App\Notifications\NewSubmission ................ RUNNING
+ 2023-12-15 10:02:56 App\Notifications\NewSubmission ............ 8.22ms FAIL
+ 2023-12-15 10:02:56 App\Notifications\NewSubmission ................ RUNNING
+ 2023-12-15 10:02:56 App\Notifications\NewSubmission ............ 7.84ms DONE
+ 2023-12-15 10:02:56 App\Notifications\NewSubmission ................ RUNNING
+ 2023-12-15 10:02:56 App\Notifications\NewSubmission ............ 9.51ms FAIL
+ 2023-12-15 10:02:56 App\Notifications\NewSubmission ................ RUNNING
+ 2023-12-15 10:02:56 App\Notifications\NewSubmission ............ 8.18ms DONE
+ 2023-12-15 10:02:56 App\Notifications\NewSubmission ................ RUNNING
+ 2023-12-15 10:02:56 App\Notifications\NewSubmission ........... 15.58ms FAIL
+ 2023-12-15 10:02:56 App\Notifications\NewSubmission ................ RUNNING
+ 2023-12-15 10:02:56 App\Notifications\NewSubmission ........... 13.57ms DONE
+ 2023-12-15 10:02:56 App\Notifications\NewSubmission ................ RUNNING
+ 2023-12-15 10:02:56 App\Notifications\NewSubmission ........... 10.37ms FAIL
+ 2023-12-15 10:02:56 App\Notifications\NewSubmission ................ RUNNING
+ 2023-12-15 10:02:56 App\Notifications\NewSubmission ........... 10.22ms DONE
+ 2023-12-15 10:02:56 App\Notifications\NewSubmission ................ RUNNING
+ 2023-12-15 10:02:56 App\Notifications\NewSubmission ............ 9.82ms FAIL
+ 2023-12-15 10:02:56 App\Notifications\NewSubmission ................ RUNNING
+ 2023-12-15 10:02:56 App\Notifications\NewSubmission ............ 8.58ms DONE
+ 2023-12-15 10:02:56 App\Notifications\NewSubmission ................ RUNNING
+ 2023-12-15 10:02:56 App\Notifications\NewSubmission ............ 8.15ms FAIL
+ 2023-12-15 10:02:56 App\Notifications\NewSubmission ................ RUNNING
+ 2023-12-15 10:02:56 App\Notifications\NewSubmission ............ 8.02ms DONE
+ 2023-12-15 10:02:56 App\Notifications\NewSubmission ................ RUNNING
+ 2023-12-15 10:02:56 App\Notifications\NewSubmission ............ 8.38ms FAIL
+ 2023-12-15 10:02:56 App\Notifications\NewSubmission ................ RUNNING
+ 2023-12-15 10:02:56 App\Notifications\NewSubmission ............ 6.66ms DONE
+ 2023-12-15 10:02:56 App\Notifications\NewSubmission ................ RUNNING
+ 2023-12-15 10:02:56 App\Notifications\NewSubmission ............ 7.79ms FAIL
+ 2023-12-15 10:02:56 App\Notifications\NewSubmission ................ RUNNING
+ 2023-12-15 10:02:56 App\Notifications\NewSubmission ............ 8.01ms DONE
+ 2023-12-15 10:02:56 App\Notifications\NewSubmission ................ RUNNING
+ 2023-12-15 10:02:56 App\Notifications\NewSubmission ............ 9.05ms FAIL
+ 2023-12-15 10:02:56 App\Notifications\NewSubmission ................ RUNNING
+ 2023-12-15 10:02:56 App\Notifications\NewSubmission ........... 13.68ms DONE
+ 2023-12-15 10:02:56 App\Notifications\NewSubmission ................ RUNNING
+ 2023-12-15 10:02:56 App\Notifications\NewSubmission ............ 8.55ms FAIL
+ 2023-12-15 10:02:56 App\Notifications\NewSubmission ................ RUNNING
+ 2023-12-15 10:02:56 App\Notifications\NewSubmission ............ 7.68ms DONE
+ 2023-12-15 10:02:56 App\Notifications\NewSubmission ................ RUNNING
+ 2023-12-15 10:02:56 App\Notifications\NewSubmission ........... 18.78ms FAIL
+ 2023-12-15 10:02:56 App\Notifications\NewSubmission ................ RUNNING
+ 2023-12-15 10:02:56 App\Notifications\NewSubmission ............ 8.73ms DONE
+ 2023-12-15 10:02:56 App\Notifications\NewSubmission ................ RUNNING
+ 2023-12-15 10:02:56 App\Notifications\NewSubmission ............ 8.87ms FAIL
+ 2023-12-15 10:02:56 App\Notifications\NewSubmission ................ RUNNING
+ 2023-12-15 10:02:56 App\Notifications\NewSubmission ........... 10.57ms DONE
+ 2023-12-15 10:02:56 App\Notifications\NewSubmission ................ RUNNING
+ 2023-12-15 10:02:56 App\Notifications\NewSubmission ............ 9.32ms FAIL
+ 2023-12-15 10:02:56 App\Notifications\NewSubmission ................ RUNNING
+ 2023-12-15 10:02:56 App\Notifications\NewSubmission ............ 7.96ms DONE
+ 2023-12-15 10:02:56 App\Notifications\NewSubmission ................ RUNNING
+ 2023-12-15 10:02:56 App\Notifications\NewSubmission ............ 9.29ms FAIL
+ 2023-12-15 10:02:56 App\Notifications\NewSubmission ................ RUNNING
+ 2023-12-15 10:02:56 App\Notifications\NewSubmission ............ 7.82ms DONE
+ 2023-12-15 10:02:56 App\Notifications\NewSubmission ................ RUNNING
+ 2023-12-15 10:02:56 App\Notifications\NewSubmission ........... 10.10ms FAIL
+ 2023-12-15 10:02:56 App\Notifications\NewSubmission ................ RUNNING
+ 2023-12-15 10:02:56 App\Notifications\NewSubmission ............ 9.23ms DONE
+ 2023-12-15 10:02:56 App\Notifications\NewSubmission ................ RUNNING
+ 2023-12-15 10:02:56 App\Notifications\NewSubmission ............ 9.21ms FAIL
+ 2023-12-15 10:02:56 App\Notifications\NewSubmission ................ RUNNING
+ 2023-12-15 10:02:56 App\Notifications\NewSubmission ............ 7.12ms DONE
+ 2023-12-15 10:02:56 App\Notifications\NewSubmission ................ RUNNING
+ 2023-12-15 10:02:56 App\Notifications\NewSubmission ........... 14.43ms FAIL
+ 2023-12-15 10:02:56 App\Notifications\NewSubmission ................ RUNNING
+ 2023-12-15 10:02:56 App\Notifications\NewSubmission ............ 7.50ms DONE
+ 2023-12-15 10:02:56 App\Notifications\NewSubmission ................ RUNNING
+ 2023-12-15 10:02:56 App\Notifications\NewSubmission ............ 9.68ms FAIL
+ 2023-12-15 10:02:56 App\Notifications\NewSubmission ................ RUNNING
+ 2023-12-15 10:02:56 App\Notifications\NewSubmission ............ 7.65ms DONE
+ 2023-12-15 10:02:56 App\Notifications\NewSubmission ................ RUNNING
+ 2023-12-15 10:02:56 App\Notifications\NewSubmission ........... 10.62ms FAIL
+ 2023-12-15 10:02:56 App\Notifications\NewSubmission ................ RUNNING
+ 2023-12-15 10:02:56 App\Notifications\NewSubmission ............ 8.79ms DONE
+ 2023-12-15 10:02:56 App\Notifications\NewSubmission ................ RUNNING
+ 2023-12-15 10:02:56 App\Notifications\NewSubmission ........... 11.25ms FAIL
+ 2023-12-15 10:02:56 App\Notifications\NewSubmission ................ RUNNING
+ 2023-12-15 10:02:56 App\Notifications\NewSubmission ........... 10.18ms DONE
+ 2023-12-15 10:02:56 App\Notifications\NewSubmission ................ RUNNING
+ 2023-12-15 10:02:56 App\Notifications\NewSubmission ........... 10.10ms FAIL
+ 2023-12-15 10:02:56 App\Notifications\NewSubmission ................ RUNNING
+ 2023-12-15 10:02:56 App\Notifications\NewSubmission ............ 8.72ms DONE
+ 2023-12-15 10:02:56 App\Notifications\NewSubmission ................ RUNNING
+ 2023-12-15 10:02:56 App\Notifications\NewSubmission ............ 9.89ms FAIL
+ 2023-12-15 10:02:56 App\Notifications\NewSubmission ................ RUNNING
+ 2023-12-15 10:02:56 App\Notifications\NewSubmission ............ 6.98ms DONE
+ 2023-12-15 10:02:56 App\Notifications\NewSubmission ................ RUNNING
+ 2023-12-15 10:02:56 App\Notifications\NewSubmission ............ 9.76ms FAIL
+ 2023-12-15 10:02:56 App\Notifications\NewSubmission ................ RUNNING
+ 2023-12-15 10:02:56 App\Notifications\NewSubmission ............ 8.00ms DONE
+ 2023-12-15 10:02:56 App\Notifications\NewSubmission ................ RUNNING
+ 2023-12-15 10:02:56 App\Notifications\NewSubmission ............ 9.66ms FAIL
+ 2023-12-15 10:02:56 App\Notifications\NewSubmission ................ RUNNING
+ 2023-12-15 10:02:56 App\Notifications\NewSubmission ............ 8.29ms DONE
+ 2023-12-15 10:02:56 App\Notifications\NewSubmission ................ RUNNING
+ 2023-12-15 10:02:56 App\Notifications\NewSubmission ............ 9.08ms FAIL
+ 2023-12-15 10:02:56 App\Notifications\NewSubmission ................ RUNNING
+ 2023-12-15 10:02:56 App\Notifications\NewSubmission ............ 7.30ms DONE
+ 2023-12-15 10:02:56 App\Notifications\NewSubmission ................ RUNNING
+ 2023-12-15 10:02:56 App\Notifications\NewSubmission ............ 8.88ms FAIL
+ 2023-12-15 10:02:56 App\Notifications\NewSubmission ................ RUNNING
+ 2023-12-15 10:02:56 App\Notifications\NewSubmission ............ 7.95ms DONE
+ 2023-12-15 10:02:56 App\Notifications\NewSubmission ................ RUNNING
+ 2023-12-15 10:02:56 App\Notifications\NewSubmission ............ 8.74ms FAIL
+ 2023-12-15 10:02:56 App\Notifications\NewSubmission ................ RUNNING
+ 2023-12-15 10:02:56 App\Notifications\NewSubmission ............ 6.90ms DONE
+ 2023-12-15 10:02:56 App\Notifications\NewSubmission ................ RUNNING
+ 2023-12-15 10:02:56 App\Notifications\NewSubmission ............ 8.45ms FAIL
+ 2023-12-15 10:02:56 App\Notifications\NewSubmission ................ RUNNING
+ 2023-12-15 10:02:56 App\Notifications\NewSubmission ............ 8.71ms DONE
+ 2023-12-15 10:02:56 App\Notifications\NewSubmission ................ RUNNING
+ 2023-12-15 10:02:56 App\Notifications\NewSubmission ............ 9.58ms FAIL
+ 2023-12-15 10:03:10 App\Notifications\AbstractAccepted ............. RUNNING
+ 2023-12-15 10:03:10 App\Notifications\AbstractAccepted ........ 93.59ms DONE
+ 2023-12-15 10:03:10 App\Notifications\AbstractAccepted ............. RUNNING
+ 2023-12-15 10:03:10 App\Notifications\AbstractAccepted ........ 14.39ms FAIL
From 7f03640136d9cc8e948743638c164f1ef7371fd6 Mon Sep 17 00:00:00 2001
From: Rahman Ramsi
Date: Tue, 19 Dec 2023 08:27:41 +0800
Subject: [PATCH 5/9] wip
---
app/Interfaces/PaymentDriver.php | 5 +-
app/Managers/PaymentManager.php | 20 ++-
app/Models/Concerns/InteractsWithPayment.php | 18 ++
app/Models/Conference.php | 5 +
app/Models/Enums/PaymentState.php | 3 +-
app/Models/Enums/SubmissionStage.php | 1 -
app/Models/Enums/SubmissionStatus.php | 3 +-
app/Models/Interfaces/HasPayment.php | 10 ++
app/Models/Payment.php | 30 +++-
.../Interfaces/SubmissionStateInterface.php | 2 -
.../States/Submission/BaseSubmissionState.php | 5 -
.../Submission/PaymentSubmissionState.php | 2 +
.../Submission/QueuedSubmissionState.php | 4 +-
app/Models/Submission.php | 8 +-
app/Models/SubmissionPaymentItem.php | 21 +++
app/Observers/ConferenceObserver.php | 2 +-
app/Panel/Livewire/Submissions/Payment.php | 47 +++++-
.../Pages/ViewSubmission.php | 157 +++++++++++++++---
app/Services/Payments/ManualPayment.php | 44 +++--
...023_12_12_112200_create_payments_table.php | 20 ++-
.../livewire/submissions/payment.blade.php | 13 +-
21 files changed, 356 insertions(+), 64 deletions(-)
create mode 100644 app/Models/Concerns/InteractsWithPayment.php
create mode 100644 app/Models/Interfaces/HasPayment.php
diff --git a/app/Interfaces/PaymentDriver.php b/app/Interfaces/PaymentDriver.php
index 835d30838..a4253efd3 100644
--- a/app/Interfaces/PaymentDriver.php
+++ b/app/Interfaces/PaymentDriver.php
@@ -2,6 +2,7 @@
namespace App\Interfaces;
+use App\Models\Payment;
use Filament\Forms\Form;
interface PaymentDriver
@@ -10,7 +11,7 @@ public function getName(): string;
public function pay($amount, $submission);
- public function getPaymentForm(Form $form): Form;
+ public function getPaymentFormSchema(): array;
public function getSettingFormSchema(): array;
@@ -18,5 +19,7 @@ public function getSettingFormFill(): array;
public function saveSetting(array $data): void;
+ public function handlePayment(Payment $payment);
+
// public function fillSettingForm(Form $form): void;
}
diff --git a/app/Managers/PaymentManager.php b/app/Managers/PaymentManager.php
index 5ae255e04..9ab81c0db 100644
--- a/app/Managers/PaymentManager.php
+++ b/app/Managers/PaymentManager.php
@@ -2,16 +2,19 @@
namespace App\Managers;
-use App\Models\Enums\PaymentType;
+use App\Models\Interfaces\HasPayment;
+use App\Models\Payment;
+use App\Models\User;
use App\Services\Payments\ManualPayment;
use Illuminate\Database\Eloquent\Model;
+use Illuminate\Support\Facades\App;
use Illuminate\Support\Manager;
class PaymentManager extends Manager
{
public function getDefaultDriver(): string
{
- return 'manual';
+ return App::getCurrentConference()?->getMeta('workflow.payment.payment_method') ?? 'manual';
}
public function createManualDriver()
@@ -19,8 +22,19 @@ public function createManualDriver()
return new ManualPayment;
}
- public function createPayment(PaymentType $type, Model $model)
+ public function createPayment(Model $model, User $user, float $amount, string $currencyId, ?string $paymentMethod = null)
{
+ $payment = $model->payment ?? new Payment;
+ $payment->amount = $amount;
+ $payment->currency_id = $currencyId;
+ $payment->payment_method = $paymentMethod ?? $this->getDefaultDriver();
+ if(!$payment->exists){
+ $payment->user()->associate($user);
+ $payment->payable()->associate($model);
+ }
+ $payment->save();
+
+ return $payment;
}
public function getAllDriverNames()
diff --git a/app/Models/Concerns/InteractsWithPayment.php b/app/Models/Concerns/InteractsWithPayment.php
new file mode 100644
index 000000000..dea760884
--- /dev/null
+++ b/app/Models/Concerns/InteractsWithPayment.php
@@ -0,0 +1,18 @@
+morphOne(Payment::class, 'payable');
+ }
+}
diff --git a/app/Models/Conference.php b/app/Models/Conference.php
index b175b8d76..81ed4dd8a 100644
--- a/app/Models/Conference.php
+++ b/app/Models/Conference.php
@@ -159,4 +159,9 @@ public function getHomeUrl(): string
default => route('livewirePageGroup.website.pages.home'),
};
}
+
+ public function getSupportedCurrencies(): array
+ {
+ return $this->getMeta('workflow.payment.supported_currencies') ?? ['usd'];
+ }
}
diff --git a/app/Models/Enums/PaymentState.php b/app/Models/Enums/PaymentState.php
index 9d89eec6a..eb2530981 100644
--- a/app/Models/Enums/PaymentState.php
+++ b/app/Models/Enums/PaymentState.php
@@ -10,7 +10,8 @@ enum PaymentState: string implements HasLabel
use UsefulEnums;
case Pending = 'Pending';
- case Confirmation = 'Confirmation';
+ case Processing = 'Processing';
+ case Waived = 'Waived';
case Paid = 'Paid';
public function getLabel(): ?string
diff --git a/app/Models/Enums/SubmissionStage.php b/app/Models/Enums/SubmissionStage.php
index 46d7d15ec..5b6c546db 100644
--- a/app/Models/Enums/SubmissionStage.php
+++ b/app/Models/Enums/SubmissionStage.php
@@ -11,7 +11,6 @@ enum SubmissionStage: string implements HasLabel
case Wizard = 'Wizard';
case CallforAbstract = 'Call for Abstract';
- case Payment = 'Payment';
case PeerReview = 'Peer Review';
case Editing = 'Editing';
case Proceeding = 'Proceeding';
diff --git a/app/Models/Enums/SubmissionStatus.php b/app/Models/Enums/SubmissionStatus.php
index 186723cfd..8a5532758 100644
--- a/app/Models/Enums/SubmissionStatus.php
+++ b/app/Models/Enums/SubmissionStatus.php
@@ -12,7 +12,6 @@ enum SubmissionStatus: string implements HasLabel, HasColor
case Incomplete = 'Incomplete';
case Queued = 'Queued';
- case Payment = 'Payment';
case OnReview = 'On Review';
case Editing = 'Editing';
case Published = 'Published';
@@ -30,7 +29,7 @@ public function getColor(): string | array | null
return match ($this) {
self::Declined, self::Withdrawn => 'danger',
self::OnReview => 'warning',
- self::Queued, self::Payment => 'primary',
+ self::Queued => 'primary',
self::Editing => 'info',
self::Published => 'success',
default => 'gray'
diff --git a/app/Models/Interfaces/HasPayment.php b/app/Models/Interfaces/HasPayment.php
new file mode 100644
index 000000000..a2e8e034f
--- /dev/null
+++ b/app/Models/Interfaces/HasPayment.php
@@ -0,0 +1,10 @@
+ PaymentState::class,
+ 'paid_at' => 'datetime',
];
+
+ public static function booted()
+ {
+ // static::saving(function (Model $model) {
+ // if($model->state === PaymentState::Paid){
+ // $model->paid_at = now();
+ // }
+ // });
+ }
+
+ public function payable(): MorphTo
+ {
+ return $this->morphTo();
+ }
+
+ public function user(): BelongsTo
+ {
+ return $this->belongsTo(User::class);
+ }
}
diff --git a/app/Models/States/Interfaces/SubmissionStateInterface.php b/app/Models/States/Interfaces/SubmissionStateInterface.php
index c9ba00b97..d25fc7495 100644
--- a/app/Models/States/Interfaces/SubmissionStateInterface.php
+++ b/app/Models/States/Interfaces/SubmissionStateInterface.php
@@ -8,8 +8,6 @@ public function fulfill(): void;
public function acceptAbstract(): void;
- public function pay(): void;
-
public function accept(): void;
public function publish(): void;
diff --git a/app/Models/States/Submission/BaseSubmissionState.php b/app/Models/States/Submission/BaseSubmissionState.php
index 971d5ab0d..b0e5bb185 100644
--- a/app/Models/States/Submission/BaseSubmissionState.php
+++ b/app/Models/States/Submission/BaseSubmissionState.php
@@ -21,11 +21,6 @@ public function acceptAbstract(): void
throw new \Exception('Cannot accept abstract');
}
- public function pay(): void
- {
- throw new \Exception('Cannot pay');
- }
-
public function accept(): void
{
throw new \Exception('Cannot accept');
diff --git a/app/Models/States/Submission/PaymentSubmissionState.php b/app/Models/States/Submission/PaymentSubmissionState.php
index 7630d541c..df9e75920 100644
--- a/app/Models/States/Submission/PaymentSubmissionState.php
+++ b/app/Models/States/Submission/PaymentSubmissionState.php
@@ -3,6 +3,7 @@
namespace App\Models\States\Submission;
use App\Actions\Submissions\SubmissionUpdateAction;
+use App\Managers\PaymentManager;
use App\Models\Enums\SubmissionStage;
use App\Models\Enums\SubmissionStatus;
@@ -14,6 +15,7 @@ public function pay(): void
'stage' => SubmissionStage::PeerReview,
'status' => SubmissionStatus::OnReview,
], $this->submission);
+
}
public function withdraw(): void
diff --git a/app/Models/States/Submission/QueuedSubmissionState.php b/app/Models/States/Submission/QueuedSubmissionState.php
index a12d6111b..3c9e9891f 100644
--- a/app/Models/States/Submission/QueuedSubmissionState.php
+++ b/app/Models/States/Submission/QueuedSubmissionState.php
@@ -11,8 +11,8 @@ class QueuedSubmissionState extends BaseSubmissionState
public function acceptAbstract(): void
{
SubmissionUpdateAction::run([
- 'stage' => SubmissionStage::Payment,
- 'status' => SubmissionStatus::Payment,
+ 'stage' => SubmissionStage::PeerReview,
+ 'status' => SubmissionStatus::OnReview,
], $this->submission);
}
diff --git a/app/Models/Submission.php b/app/Models/Submission.php
index 679f66a12..35be3f8e2 100644
--- a/app/Models/Submission.php
+++ b/app/Models/Submission.php
@@ -4,9 +4,11 @@
use App\Actions\User\CreateParticipantFromUserAction;
use App\Models\Concerns\HasTopics;
+use App\Models\Concerns\InteractsWithPayment;
use App\Models\Enums\SubmissionStage;
use App\Models\Enums\SubmissionStatus;
use App\Models\Enums\UserRole;
+use App\Models\Interfaces\HasPayment;
use App\Models\Meta\SubmissionMeta;
use App\Models\States\Submission\BaseSubmissionState;
use App\Models\States\Submission\DeclinedSubmissionState;
@@ -22,6 +24,7 @@
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\HasMany;
+use Illuminate\Database\Eloquent\Relations\MorphOne;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\Auth;
use Kra8\Snowflake\HasShortflakePrimary;
@@ -30,9 +33,9 @@
use Spatie\MediaLibrary\InteractsWithMedia;
use Spatie\Tags\HasTags;
-class Submission extends Model implements HasMedia
+class Submission extends Model implements HasMedia, HasPayment
{
- use Cachable, HasFactory, HasShortflakePrimary, HasTags, HasTopics, InteractsWithMedia, Metable;
+ use Cachable, HasFactory, HasShortflakePrimary, HasTags, HasTopics, InteractsWithMedia, Metable, InteractsWithPayment;
/**
* The attributes that are mass assignable.
@@ -190,7 +193,6 @@ public function state(): BaseSubmissionState
return match ($this->status) {
SubmissionStatus::Incomplete => new IncompleteSubmissionState($this),
SubmissionStatus::Queued => new QueuedSubmissionState($this),
- SubmissionStatus::Payment => new PaymentSubmissionState($this),
SubmissionStatus::OnReview => new OnReviewSubmissionState($this),
SubmissionStatus::Editing => new EditingSubmissionState($this),
SubmissionStatus::Published => new PublishedSubmissionState($this),
diff --git a/app/Models/SubmissionPaymentItem.php b/app/Models/SubmissionPaymentItem.php
index 5e2e65e17..4d6c1b0f5 100644
--- a/app/Models/SubmissionPaymentItem.php
+++ b/app/Models/SubmissionPaymentItem.php
@@ -2,10 +2,13 @@
namespace App\Models;
+use Akaunting\Money\Currency;
use App\Models\Concerns\BelongsToConference;
use Illuminate\Database\Eloquent\Model;
use Spatie\EloquentSortable\Sortable;
use Spatie\EloquentSortable\SortableTrait;
+use Akaunting\Money;
+
class SubmissionPaymentItem extends Model implements Sortable
{
@@ -30,4 +33,22 @@ class SubmissionPaymentItem extends Model implements Sortable
protected $casts = [
'fees' => 'array',
];
+
+ function getAmount($currencyId)
+ {
+ $fee = collect($this->fees)->firstWhere('currency_id', $currencyId);
+
+ if($fee === null) return null;
+
+ return $fee['fee'];
+ }
+
+ function getFormattedAmount($currencyId)
+ {
+ return (new Money\Money(
+ $this->getAmount($currencyId),
+ (new Money\Currency(strtoupper($currencyId))),
+ true
+ ))->formatWithoutZeroes();
+ }
}
diff --git a/app/Observers/ConferenceObserver.php b/app/Observers/ConferenceObserver.php
index 1191b38ff..13ea982b1 100644
--- a/app/Observers/ConferenceObserver.php
+++ b/app/Observers/ConferenceObserver.php
@@ -56,7 +56,7 @@ public function created(Conference $conference): void
]);
$conference->setMeta('page_footer', view('examples.footer')->render());
- $conference->setMeta('workflow.payment.supported_currencies', ['USD']);
+ $conference->setMeta('workflow.payment.supported_currencies', ['usd']);
$conference->save();
}
diff --git a/app/Panel/Livewire/Submissions/Payment.php b/app/Panel/Livewire/Submissions/Payment.php
index a178d9a72..09bdbbb8d 100644
--- a/app/Panel/Livewire/Submissions/Payment.php
+++ b/app/Panel/Livewire/Submissions/Payment.php
@@ -3,15 +3,23 @@
namespace App\Panel\Livewire\Submissions;
use App\Facades\Payment as PaymentFacade;
+use App\Models\Conference;
use App\Models\Submission;
+use App\Models\SubmissionPaymentItem;
use App\Panel\Livewire\Workflows\Classes\StageManager;
use App\Panel\Livewire\Workflows\Concerns\InteractWithTenant;
use Filament\Actions\Concerns\InteractsWithActions;
use Filament\Actions\Contracts\HasActions;
+use Filament\Forms\Components\CheckboxList;
+use Filament\Forms\Components\Section;
+use Filament\Forms\Components\Select;
use Filament\Forms\Concerns\InteractsWithForms;
use Filament\Forms\Contracts\HasForms;
use Filament\Forms\Form;
+use Filament\Forms\Get;
+use Illuminate\Support\Facades\App;
use Livewire\Component;
+use Squire\Models\Currency;
class Payment extends Component implements HasActions, HasForms
{
@@ -19,6 +27,13 @@ class Payment extends Component implements HasActions, HasForms
public Submission $submission;
+ public array $data = [];
+
+ public function mount()
+ {
+ $this->form->fill([]);
+ }
+
public function render()
{
return view('panel.livewire.submissions.payment', [
@@ -29,8 +44,36 @@ public function render()
public function form(Form $form)
{
// return PaymentFacade::getPaymentForm($form);
- return $form->schema([
+ return $form
+ ->statePath('data')
+ ->schema([
+ Section::make()
+ ->schema([
+ Select::make('currency_id')
+ ->label('Currency')
+ ->options(
+ Currency::query()
+ ->whereIn('id', App::getCurrentConference()->getSupportedCurrencies())
+ ->get()
+ ->mapWithKeys(fn (Currency $currency) => [$currency->id => $currency->name . ' (' . $currency->symbol_native . ')'])
+ )
+ ->required()
+ ->reactive(),
+ CheckboxList::make('items')
+ ->visible(fn (Get $get) => $get('currency_id'))
+ ->options(function (Get $get) {
+ return SubmissionPaymentItem::get()
+ ->filter(function (SubmissionPaymentItem $item) use ($get) : bool {
+ foreach ($item->fees as $fee) {
+ if(!array_key_exists('currency_id', $fee)) continue;
+ if($fee['currency_id'] === $get('currency_id')) return true;
+ }
- ]);
+ return false;
+ })
+ ->map(fn (SubmissionPaymentItem $item) : string => $item->name . ': ' . $item->getAmount($get('currency_id')));
+ }),
+ ])
+ ]);
}
}
diff --git a/app/Panel/Resources/SubmissionResource/Pages/ViewSubmission.php b/app/Panel/Resources/SubmissionResource/Pages/ViewSubmission.php
index b4f4b98e8..22fd2e74c 100644
--- a/app/Panel/Resources/SubmissionResource/Pages/ViewSubmission.php
+++ b/app/Panel/Resources/SubmissionResource/Pages/ViewSubmission.php
@@ -6,12 +6,15 @@
use App\Actions\Submissions\CancelWithdrawalAction;
use App\Actions\Submissions\RequestWithdrawalAction;
use App\Actions\Submissions\UnpublishSubmissionAction;
+use App\Facades\Payment as FacadesPayment;
use App\Infolists\Components\LivewireEntry;
use App\Infolists\Components\VerticalTabs\Tab as Tab;
use App\Infolists\Components\VerticalTabs\Tabs as Tabs;
+use App\Models\Enums\PaymentState;
use App\Models\Enums\SubmissionStage;
use App\Models\Enums\SubmissionStatus;
use App\Models\Enums\UserRole;
+use App\Models\SubmissionPaymentItem;
use App\Models\User;
use App\Notifications\SubmissionWithdrawn;
use App\Notifications\SubmissionWithdrawRequested;
@@ -28,10 +31,17 @@
use App\Panel\Resources\SubmissionResource;
use Awcodes\Shout\Components\ShoutEntry;
use Filament\Actions\Action;
+use Filament\Actions\StaticAction;
+use Filament\Forms\Components\CheckboxList;
+use Filament\Forms\Components\Grid;
+use Filament\Forms\Components\Radio;
+use Filament\Forms\Components\Select;
use Filament\Forms\Components\Textarea;
+use Filament\Forms\Components\TextInput;
use Filament\Forms\Concerns\InteractsWithForms;
use Filament\Forms\Contracts\HasForms;
use Filament\Forms\Form;
+use Filament\Forms\Get;
use Filament\Infolists\Components\Tabs as HorizontalTabs;
use Filament\Infolists\Components\Tabs\Tab as HorizontalTab;
use Filament\Infolists\Concerns\InteractsWithInfolists;
@@ -40,8 +50,10 @@
use Filament\Resources\Pages\Concerns\InteractsWithRecord;
use Filament\Resources\Pages\Page;
use Illuminate\Contracts\Support\Htmlable;
+use Illuminate\Support\Facades\App;
use Illuminate\Support\HtmlString;
use Illuminate\View\Compilers\BladeCompiler;
+use Squire\Models\Currency;
class ViewSubmission extends Page implements HasForms, HasInfolists
{
@@ -63,6 +75,104 @@ public function mount($record): void
protected function getHeaderActions(): array
{
return [
+ Action::make('payment')
+ ->model(Payment::class)
+ ->record(fn () => $this->record->payment)
+ ->icon('heroicon-o-currency-dollar')
+ ->color('primary')
+ ->when(
+ fn (Action $action): bool => !$action->getRecord() || $action->getRecord()?->state === PaymentState::Pending,
+ fn (Action $action): Action => $action
+ ->action(function (array $data, Form $form) {
+ $payment = FacadesPayment::createPayment(
+ $this->record,
+ auth()->user(),
+ collect($data['items'])->sum(),
+ $data['currency_id'],
+ );
+
+ $form->model($payment)->saveRelationships();
+
+ FacadesPayment::driver($this->record->payment?->payment_method)->handlePayment($payment);
+ })->mountUsing(function (Form $form) {
+ $payment = $this->record->payment;
+
+ $form->fill([
+ 'currency_id' => $payment?->currency_id,
+ ...FacadesPayment::getPaymentFormFill(),
+ ]);
+ })->form([
+ Select::make('currency_id')
+ ->label('Currency')
+ ->options(
+ Currency::query()
+ ->whereIn('id', App::getCurrentConference()->getSupportedCurrencies())
+ ->get()
+ ->mapWithKeys(fn (Currency $currency) => [$currency->id => $currency->name . ' (' . $currency->symbol_native . ')'])
+ )
+ ->required()
+ ->reactive(),
+ CheckboxList::make('items')
+ ->visible(fn (Get $get) => $get('currency_id'))
+ ->required()
+ ->options(function (Get $get) {
+ return SubmissionPaymentItem::get()
+ ->filter(function (SubmissionPaymentItem $item) use ($get): bool {
+ foreach ($item->fees as $fee) {
+ if (!array_key_exists('currency_id', $fee)) continue;
+ if ($fee['currency_id'] === $get('currency_id')) return true;
+ }
+
+ return false;
+ })
+ ->mapWithKeys(fn (SubmissionPaymentItem $item): array => [$item->getAmount($get('currency_id')) => $item->name . ': ' . $item->getFormattedAmount($get('currency_id'))]);
+ // ->mapWithKeys(fn (SubmissionPaymentItem $item): array => [$item->getKey() => $item->name . ': ' . $item->getFormattedAmount($get('currency_id'))]);
+ }),
+ ...FacadesPayment::driver($this->record->payment?->payment_method)->getPaymentFormSchema(),
+ ]),
+ )
+ ->when(
+ fn (Action $action): bool => $action->getRecord()?->state === PaymentState::Processing,
+ fn (Action $action): Action => $action
+ ->action(function (array $data, $record) {
+ $record->state = $data['decision'];
+ $record->save();
+ })
+ ->modalHeading('Payment Processing')
+ ->mountUsing(function (Form $form) {
+ $payment = $this->record->payment;
+
+ $form->fill([
+ 'currency_id' => $payment?->currency_id,
+ 'amount' => $payment?->amount,
+ ...FacadesPayment::getPaymentFormFill(),
+ ]);
+ })
+ ->form([
+ Grid::make(1)
+ ->schema([
+ Grid::make()
+ ->schema([
+ Select::make('currency_id')
+ ->label('Currency')
+ ->options(Currency::pluck('name', 'id')),
+ TextInput::make('amount')
+ ->prefix(fn (Get $get) => $get('currency_id') ? Currency::find($get('currency_id'))->symbol_native : null)
+ ->numeric(),
+ ]),
+
+ ...FacadesPayment::driver($this->record->payment?->payment_method)->getPaymentFormSchema(),
+ ])
+ ->disabled(),
+ Select::make('decision')
+ ->required()
+ ->options([
+ PaymentState::Pending->value => PaymentState::Pending->name,
+ PaymentState::Waived->value => PaymentState::Waived->name,
+ PaymentState::Paid->value => PaymentState::Paid->name,
+ ]),
+ ])
+ ),
Action::make('unpublish')
->icon('lineawesome-calendar-times-solid')
->color('danger')
@@ -71,11 +181,11 @@ protected function getHeaderActions(): array
->successNotificationTitle('Submission unpublished')
->action(function (Action $action) {
$this->record->state()->unpublish();
-
+
$action->successRedirectUrl(
static::getResource()::getUrl('view', [
'record' => $this->record,
- 'stage' => '-'.str($this->record->stage->value)->slug('-').'-tab',
+ 'stage' => '-' . str($this->record->stage->value)->slug('-') . '-tab',
])
);
@@ -124,7 +234,7 @@ protected function getHeaderActions(): array
$action->successRedirectUrl(
SubmissionResource::getUrl('view', [
'record' => $this->record,
- 'stage' => '-'.str($this->record->stage->value)->slug('-').'-tab',
+ 'stage' => '-' . str($this->record->stage->value)->slug('-') . '-tab',
]),
);
$action->success();
@@ -135,7 +245,7 @@ protected function getHeaderActions(): array
->color('danger')
->extraAttributes(function (Action $action) {
if (filled($this->record->withdrawn_reason)) {
- $attributeValue = '$nextTick(() => { $wire.mountAction(\''.$action->getName().'\') })';
+ $attributeValue = '$nextTick(() => { $wire.mountAction(\'' . $action->getName() . '\') })';
return [
'x-init' => new HtmlString($attributeValue),
@@ -159,7 +269,7 @@ protected function getHeaderActions(): array
])
->requiresConfirmation()
->modalHeading(function () {
- return $this->record->user->fullName.' has requested to withdraw this submission.';
+ return $this->record->user->fullName . ' has requested to withdraw this submission.';
})
->modalDescription("You can either reject the request or accept it, remember it can't be undone.")
->modalCancelActionLabel('Ignore')
@@ -174,7 +284,7 @@ protected function getHeaderActions(): array
$action->successRedirectUrl(
SubmissionResource::getUrl('view', [
'record' => $this->record,
- 'stage' => '-'.str($this->record->stage->value)->slug('-').'-tab',
+ 'stage' => '-' . str($this->record->stage->value)->slug('-') . '-tab',
]),
);
$action->successNotificationTitle('Withdrawal request rejected');
@@ -194,7 +304,7 @@ protected function getHeaderActions(): array
$action->successRedirectUrl(
SubmissionResource::getUrl('view', [
'record' => $this->record,
- 'stage' => '-'.str($this->record->stage->value)->slug('-').'-tab',
+ 'stage' => '-' . str($this->record->stage->value)->slug('-') . '-tab',
]),
);
$action->success();
@@ -206,14 +316,13 @@ protected function getHeaderActions(): array
public function getSubheading(): string|Htmlable|null
{
$badgeHtml = match ($this->record->status) {
- SubmissionStatus::Incomplete => ''.SubmissionStatus::Incomplete->value.'',
- SubmissionStatus::Queued => ''.SubmissionStatus::Queued->value.'',
- SubmissionStatus::Payment => ''.SubmissionStatus::Payment->value.'',
- SubmissionStatus::OnReview => ''.SubmissionStatus::OnReview->value.'',
- SubmissionStatus::Published => ''.SubmissionStatus::Published->value.'',
- SubmissionStatus::Editing => ''.SubmissionStatus::Editing->value.'',
- SubmissionStatus::Declined => ''.SubmissionStatus::Declined->value.'',
- SubmissionStatus::Withdrawn => ''.SubmissionStatus::Withdrawn->value.'',
+ SubmissionStatus::Incomplete => '' . SubmissionStatus::Incomplete->value . '',
+ SubmissionStatus::Queued => '' . SubmissionStatus::Queued->value . '',
+ SubmissionStatus::OnReview => '' . SubmissionStatus::OnReview->value . '',
+ SubmissionStatus::Published => '' . SubmissionStatus::Published->value . '',
+ SubmissionStatus::Editing => '' . SubmissionStatus::Editing->value . '',
+ SubmissionStatus::Declined => '' . SubmissionStatus::Declined->value . '',
+ SubmissionStatus::Withdrawn => '' . SubmissionStatus::Withdrawn->value . '',
default => null,
};
@@ -249,14 +358,14 @@ public function infolist(Infolist $infolist): Infolist
'submission' => $this->record,
]),
]),
- Tab::make('Payment')
- ->icon('heroicon-o-currency-dollar')
- ->schema([
- LivewireEntry::make('payment')
- ->livewire(Payment::class, [
- 'submission' => $this->record,
- ]),
- ]),
+ // Tab::make('Payment')
+ // ->icon('heroicon-o-currency-dollar')
+ // ->schema([
+ // LivewireEntry::make('payment')
+ // ->livewire(Payment::class, [
+ // 'submission' => $this->record,
+ // ]),
+ // ]),
Tab::make('Peer Review')
->visible(
fn (): bool => StageManager::peerReview()->isStageOpen()
@@ -309,7 +418,7 @@ public function infolist(Infolist $infolist): Infolist
LivewireEntry::make('contributors')
->livewire(ContributorList::class, [
'submission' => $this->record,
- 'viewOnly' => ! auth()->user()->can('editing', $this->record),
+ 'viewOnly' => !auth()->user()->can('editing', $this->record),
]),
]),
Tab::make('References')
diff --git a/app/Services/Payments/ManualPayment.php b/app/Services/Payments/ManualPayment.php
index 2e74d91c7..861f4b6c7 100644
--- a/app/Services/Payments/ManualPayment.php
+++ b/app/Services/Payments/ManualPayment.php
@@ -2,7 +2,10 @@
namespace App\Services\Payments;
+use App\Models\Enums\PaymentState;
+use App\Models\Payment;
use Filament\Forms\Components\Section;
+use Filament\Forms\Components\SpatieMediaLibraryFileUpload;
use Filament\Forms\Components\TextInput;
use Filament\Forms\Form;
use Illuminate\Support\Facades\App;
@@ -23,18 +26,37 @@ public function pay($amount, $submission)
]);
}
- public function getPaymentForm(Form $form): Form
+ public function handlePayment(Payment $payment)
{
- return $form->schema([
- Section::make('Payment')
- ->schema([
- TextInput::make('payment_amount')
- ->label('Payment Amount')
- ->placeholder('Payment Amount')
- ->required()
- ->rules('required', 'numeric'),
- ]),
- ]);
+ // Send information to Editor that user is paying the submission
+
+
+ // Change payment status to processing
+ $payment->state = PaymentState::Processing;
+ $payment->save();
+ }
+
+ public function getPaymentFormSchema(): array
+ {
+ return [
+ TinyEditor::make('instructions')
+ ->label('Payment Instruction')
+ ->disabled(),
+ SpatieMediaLibraryFileUpload::make('payment_proof')
+ ->collection('payment_proof')
+ ->label('Payment Proof')
+ ->required()
+ ->downloadable(),
+ ];
+ }
+
+ public function getPaymentFormFill(): array
+ {
+ $conference = App::getCurrentConference();
+
+ return [
+ 'instructions' => $conference->getMeta('manual_payment.instructions'),
+ ];
}
public function getSettingFormSchema(): array
diff --git a/database/migrations/2023_12_12_112200_create_payments_table.php b/database/migrations/2023_12_12_112200_create_payments_table.php
index ca5a89a38..335230253 100644
--- a/database/migrations/2023_12_12_112200_create_payments_table.php
+++ b/database/migrations/2023_12_12_112200_create_payments_table.php
@@ -3,6 +3,7 @@
use App\Models\Conference;
use App\Models\Enums\PaymentState;
use App\Models\Enums\PaymentType;
+use App\Models\User;
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
@@ -17,8 +18,9 @@ public function up(): void
Schema::create('payments', function (Blueprint $table) {
$table->id();
$table->foreignIdFor(Conference::class)->constrained();
- $table->morphs('model');
- $table->enum('type', PaymentType::array());
+ $table->morphs('payable');
+ $table->foreignIdFor(User::class)->constrained();
+ // $table->enum('type', PaymentType::array());
$table->enum('state', PaymentState::array())->default(PaymentState::Pending->value);
$table->double('amount');
$table->string('currency_id');
@@ -26,10 +28,22 @@ public function up(): void
$table->string('payment_method');
$table->timestamps();
- $table->index(['type']);
+ // $table->index(['type']);
$table->index(['state']);
});
+ Schema::create('payment_meta', function (Blueprint $table) {
+ $table->id();
+ $table->string('metable_type');
+ $table->unsignedBigInteger('metable_id');
+ $table->string('type')->default('null');
+ $table->string('key')->index();
+ $table->longtext('value');
+
+ $table->unique(['metable_type', 'metable_id', 'key']);
+ $table->index(['key', 'metable_type']);
+ });
+
Schema::create('submission_payment_items', function (Blueprint $table) {
$table->id();
$table->foreignIdFor(Conference::class)->constrained();
diff --git a/resources/views/panel/livewire/submissions/payment.blade.php b/resources/views/panel/livewire/submissions/payment.blade.php
index 38a477472..76d8b74c7 100644
--- a/resources/views/panel/livewire/submissions/payment.blade.php
+++ b/resources/views/panel/livewire/submissions/payment.blade.php
@@ -3,6 +3,15 @@
use App\Models\Enums\SubmissionStage;
use App\Constants\SubmissionFileCategory;
@endphp
+
- {{ $this->form }}
-
+
+
+ {{ $this->form }}
+
+
+ side
+
+
+
+
\ No newline at end of file
From 21611019f76f0b05211d3dcb3fc2288a5982f8ca Mon Sep 17 00:00:00 2001
From: Rahman Ramsi
Date: Tue, 19 Dec 2023 15:59:46 +0800
Subject: [PATCH 6/9] done
---
app/Application.php | 4 +-
app/Managers/PaymentManager.php | 40 +++++++----
app/Models/Conference.php | 2 +-
app/Models/Enums/Concern/UsefulEnums.php | 5 ++
app/Models/Enums/PaymentState.php | 2 +-
app/Models/Enums/PaymentType.php | 1 -
app/Models/Meta/PaymentMeta.php | 10 +++
app/Models/Payment.php | 14 +++-
...missionPaymentItem.php => PaymentItem.php} | 6 +-
app/Models/Submission.php | 9 +++
.../Livewire/Submissions/Forms/Publish.php | 66 ++++++++++++-------
app/Panel/Livewire/Submissions/Payment.php | 8 +--
...ems.php => SubmissionPaymentItemTable.php} | 31 +++++----
.../Livewire/Workflows/PaymentSetting.php | 54 ++++++++-------
app/Panel/Pages/Settings/Workflow.php | 8 +--
.../Pages/ManageSubmissions.php | 3 +-
.../Pages/ViewSubmission.php | 56 +++++++++++-----
...023_12_12_112200_create_payments_table.php | 18 ++---
public/build/manifest.json | 2 +-
.../workflows/payment-setting.blade.php | 6 --
.../pages/list-submission.blade.php | 21 ++++--
21 files changed, 236 insertions(+), 130 deletions(-)
create mode 100644 app/Models/Meta/PaymentMeta.php
rename app/Models/{SubmissionPaymentItem.php => PaymentItem.php} (88%)
rename app/Panel/Livewire/Workflows/Payment/Tables/{PaymentItems.php => SubmissionPaymentItemTable.php} (84%)
diff --git a/app/Application.php b/app/Application.php
index 0022c1b5d..ff4e41873 100644
--- a/app/Application.php
+++ b/app/Application.php
@@ -8,11 +8,11 @@
use App\Models\Conference;
use App\Models\Navigation;
use App\Models\ParticipantPosition;
+use App\Models\PaymentItem;
use App\Models\Scopes\ConferenceScope;
use App\Models\Site;
use App\Models\StaticPage;
use App\Models\Submission;
-use App\Models\SubmissionPaymentItem;
use App\Models\Timeline;
use App\Models\Topic;
use App\Models\Venue;
@@ -67,7 +67,7 @@ public function scopeCurrentConference(): void
Announcement::class,
StaticPage::class,
Timeline::class,
- SubmissionPaymentItem::class,
+ PaymentItem::class,
] as $model) {
$model::addGlobalScope(new ConferenceScope);
}
diff --git a/app/Managers/PaymentManager.php b/app/Managers/PaymentManager.php
index 9ab81c0db..d134d5351 100644
--- a/app/Managers/PaymentManager.php
+++ b/app/Managers/PaymentManager.php
@@ -2,12 +2,15 @@
namespace App\Managers;
+use App\Interfaces\PaymentDriver;
use App\Models\Interfaces\HasPayment;
use App\Models\Payment;
+use App\Models\PaymentItem;
use App\Models\User;
use App\Services\Payments\ManualPayment;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Facades\App;
+use Illuminate\Support\Facades\DB;
use Illuminate\Support\Manager;
class PaymentManager extends Manager
@@ -17,27 +20,42 @@ public function getDefaultDriver(): string
return App::getCurrentConference()?->getMeta('workflow.payment.payment_method') ?? 'manual';
}
- public function createManualDriver()
+ public function createManualDriver() : PaymentDriver
{
return new ManualPayment;
}
- public function createPayment(Model $model, User $user, float $amount, string $currencyId, ?string $paymentMethod = null)
+ public function createPayment(Model $model, User $user, string $currencyId, array $items, ?string $paymentMethod = null) : Payment
{
- $payment = $model->payment ?? new Payment;
- $payment->amount = $amount;
- $payment->currency_id = $currencyId;
- $payment->payment_method = $paymentMethod ?? $this->getDefaultDriver();
- if(!$payment->exists){
- $payment->user()->associate($user);
- $payment->payable()->associate($model);
+ try {
+ DB::beginTransaction();
+
+ $items = PaymentItem::whereIn('id', $items)->get();
+
+ $payment = $model->payment ?? new Payment;
+ $payment->amount = $items->sum(fn($item) => $item->getAmount($currencyId));
+ $payment->currency_id = $currencyId;
+ $payment->payment_method = $paymentMethod ?? $this->getDefaultDriver();
+ if(!$payment->exists){
+ $payment->user()->associate($user);
+ $payment->payable()->associate($model);
+ }
+ $payment->save();
+
+ $payment->setMeta('items', $items->map(fn($item) => $item->name . ': ' . $item->getFormattedAmount($currencyId)));
+
+ DB::commit();
+ } catch (\Throwable $th) {
+ DB::rollBack();
+
+ throw $th;
}
- $payment->save();
+
return $payment;
}
- public function getAllDriverNames()
+ public function getAllDriverNames() : \Illuminate\Support\Collection
{
return collect(['manual', ...$this->customCreators])->mapWithKeys(function ($driver) {
return [$driver => $this->driver($driver)->getName()];
diff --git a/app/Models/Conference.php b/app/Models/Conference.php
index 81ed4dd8a..5f43441a3 100644
--- a/app/Models/Conference.php
+++ b/app/Models/Conference.php
@@ -162,6 +162,6 @@ public function getHomeUrl(): string
public function getSupportedCurrencies(): array
{
- return $this->getMeta('workflow.payment.supported_currencies') ?? ['usd'];
+ return $this->getMeta('payment.supported_currencies') ?? ['usd'];
}
}
diff --git a/app/Models/Enums/Concern/UsefulEnums.php b/app/Models/Enums/Concern/UsefulEnums.php
index a40569ba3..111a21b61 100644
--- a/app/Models/Enums/Concern/UsefulEnums.php
+++ b/app/Models/Enums/Concern/UsefulEnums.php
@@ -23,4 +23,9 @@ public static function random(): static
{
return self::from(self::values()[array_rand(self::values())]);
}
+
+ public function isOneOf(mixed ...$values): bool
+ {
+ return in_array($this, $values);
+ }
}
diff --git a/app/Models/Enums/PaymentState.php b/app/Models/Enums/PaymentState.php
index eb2530981..366bb2806 100644
--- a/app/Models/Enums/PaymentState.php
+++ b/app/Models/Enums/PaymentState.php
@@ -9,7 +9,7 @@ enum PaymentState: string implements HasLabel
{
use UsefulEnums;
- case Pending = 'Pending';
+ case Unpaid = 'Unpaid';
case Processing = 'Processing';
case Waived = 'Waived';
case Paid = 'Paid';
diff --git a/app/Models/Enums/PaymentType.php b/app/Models/Enums/PaymentType.php
index 3daaff98c..2e5aceaa5 100644
--- a/app/Models/Enums/PaymentType.php
+++ b/app/Models/Enums/PaymentType.php
@@ -9,5 +9,4 @@ enum PaymentType: string
use UsefulEnums;
case Submission = 'Submission';
- case Participant = 'Participant';
}
diff --git a/app/Models/Meta/PaymentMeta.php b/app/Models/Meta/PaymentMeta.php
new file mode 100644
index 000000000..d0f36ef1b
--- /dev/null
+++ b/app/Models/Meta/PaymentMeta.php
@@ -0,0 +1,10 @@
+ PaymentState::Pending,
+ 'state' => PaymentState::Unpaid,
];
/**
@@ -52,4 +53,15 @@ public function user(): BelongsTo
{
return $this->belongsTo(User::class);
}
+
+ protected function getMetaClassName(): string
+ {
+ return PaymentMeta::class;
+ }
+
+ public function isCompleted(): bool
+ {
+ return $this->state->isOneOf(PaymentState::Paid, PaymentState::Waived);
+ }
+
}
diff --git a/app/Models/SubmissionPaymentItem.php b/app/Models/PaymentItem.php
similarity index 88%
rename from app/Models/SubmissionPaymentItem.php
rename to app/Models/PaymentItem.php
index 4d6c1b0f5..471f8fdbc 100644
--- a/app/Models/SubmissionPaymentItem.php
+++ b/app/Models/PaymentItem.php
@@ -8,9 +8,9 @@
use Spatie\EloquentSortable\Sortable;
use Spatie\EloquentSortable\SortableTrait;
use Akaunting\Money;
+use App\Models\Enums\PaymentType;
-
-class SubmissionPaymentItem extends Model implements Sortable
+class PaymentItem extends Model implements Sortable
{
use BelongsToConference, SortableTrait;
@@ -23,6 +23,7 @@ class SubmissionPaymentItem extends Model implements Sortable
'name',
'description',
'fees',
+ 'type',
];
/**
@@ -32,6 +33,7 @@ class SubmissionPaymentItem extends Model implements Sortable
*/
protected $casts = [
'fees' => 'array',
+ 'type' => PaymentType::class,
];
function getAmount($currencyId)
diff --git a/app/Models/Submission.php b/app/Models/Submission.php
index 35be3f8e2..0e5284693 100644
--- a/app/Models/Submission.php
+++ b/app/Models/Submission.php
@@ -201,4 +201,13 @@ public function state(): BaseSubmissionState
default => throw new \Exception('Invalid submission status'),
};
}
+
+ public function hasPaymentProcess() : bool
+ {
+ return $this->conference->getMeta('payment.enabled') && match ($this->status) {
+ SubmissionStatus::OnReview, SubmissionStatus::Editing, SubmissionStatus::Published => true,
+ SubmissionStatus::Incomplete, SubmissionStatus::Queued, SubmissionStatus::Withdrawn, SubmissionStatus::Declined => false,
+ default => false,
+ };
+ }
}
diff --git a/app/Panel/Livewire/Submissions/Forms/Publish.php b/app/Panel/Livewire/Submissions/Forms/Publish.php
index 20d614dfc..69ad78d84 100644
--- a/app/Panel/Livewire/Submissions/Forms/Publish.php
+++ b/app/Panel/Livewire/Submissions/Forms/Publish.php
@@ -24,7 +24,9 @@
use Filament\Infolists\Concerns\InteractsWithInfolists;
use Filament\Infolists\Contracts\HasInfolists;
use Filament\Infolists\Infolist;
+use HTML5;
use Illuminate\Support\Facades\Mail;
+use Illuminate\Support\HtmlString;
use Mohamedsabil83\FilamentFormsTinyeditor\Components\TinyEditor;
class Publish extends \Livewire\Component implements HasActions, HasForms, HasInfolists
@@ -76,31 +78,45 @@ public function publishAction()
->authorize('publish', $this->submission)
->icon('iconpark-check')
->label('Send to Proceeding')
- ->successNotificationTitle('Submission published successfully')
- ->mountUsing(function (Form $form) {
- $mailTemplate = MailTemplate::where('mailable', PublishSubmissionMail::class)->first();
- $form->fill([
- 'email' => $this->submission->user->email,
- 'subject' => $mailTemplate ? $mailTemplate->subject : '',
- 'message' => $mailTemplate ? $mailTemplate->html_template : '',
- ]);
- })
- ->form([
- Fieldset::make('Notification')
- ->columns(1)
- ->schema([
- TextInput::make('email')
- ->disabled()
- ->dehydrated(),
- TextInput::make('subject')
- ->required(),
- TinyEditor::make('message')
- ->minHeight(300),
- Checkbox::make('do-not-notify-author')
- ->label("Don't Send Notification to Author"),
- ]),
- ])
- ->action(fn (Action $action, array $data) => $this->handlePublishAction($action, $data));
+ ->when(
+ fn() => $this->submission->hasPaymentProcess() && !$this->submission->payment?->isCompleted(),
+ fn (Action $action): Action => $action
+ ->modalContent(new HtmlString(<<Submission fee has not been paid, please notify the author.
+ HTML))
+ ->modalWidth('xl')
+ ->modalSubmitAction(false)
+ )
+ ->when(
+ // true,
+ fn() => !$this->submission->hasPaymentProcess() || $this->submission->payment?->isCompleted(),
+ fn (Action $action): Action => $action
+ ->successNotificationTitle('Submission published successfully')
+ ->mountUsing(function (Form $form) {
+ $mailTemplate = MailTemplate::where('mailable', PublishSubmissionMail::class)->first();
+ $form->fill([
+ 'email' => $this->submission->user->email,
+ 'subject' => $mailTemplate ? $mailTemplate->subject : '',
+ 'message' => $mailTemplate ? $mailTemplate->html_template : '',
+ ]);
+ })
+ ->form([
+ Fieldset::make('Notification')
+ ->columns(1)
+ ->schema([
+ TextInput::make('email')
+ ->disabled()
+ ->dehydrated(),
+ TextInput::make('subject')
+ ->required(),
+ TinyEditor::make('message')
+ ->minHeight(300),
+ Checkbox::make('do-not-notify-author')
+ ->label("Don't Send Notification to Author"),
+ ]),
+ ])
+ ->action(fn (Action $action, array $data) => $this->handlePublishAction($action, $data))
+ );
}
public function infolist(Infolist $infolist): Infolist
diff --git a/app/Panel/Livewire/Submissions/Payment.php b/app/Panel/Livewire/Submissions/Payment.php
index 09bdbbb8d..5569e17e9 100644
--- a/app/Panel/Livewire/Submissions/Payment.php
+++ b/app/Panel/Livewire/Submissions/Payment.php
@@ -5,7 +5,7 @@
use App\Facades\Payment as PaymentFacade;
use App\Models\Conference;
use App\Models\Submission;
-use App\Models\SubmissionPaymentItem;
+use App\Models\PaymentItem;
use App\Panel\Livewire\Workflows\Classes\StageManager;
use App\Panel\Livewire\Workflows\Concerns\InteractWithTenant;
use Filament\Actions\Concerns\InteractsWithActions;
@@ -62,8 +62,8 @@ public function form(Form $form)
CheckboxList::make('items')
->visible(fn (Get $get) => $get('currency_id'))
->options(function (Get $get) {
- return SubmissionPaymentItem::get()
- ->filter(function (SubmissionPaymentItem $item) use ($get) : bool {
+ return PaymentItem::get()
+ ->filter(function (PaymentItem $item) use ($get) : bool {
foreach ($item->fees as $fee) {
if(!array_key_exists('currency_id', $fee)) continue;
if($fee['currency_id'] === $get('currency_id')) return true;
@@ -71,7 +71,7 @@ public function form(Form $form)
return false;
})
- ->map(fn (SubmissionPaymentItem $item) : string => $item->name . ': ' . $item->getAmount($get('currency_id')));
+ ->map(fn (PaymentItem $item) : string => $item->name . ': ' . $item->getAmount($get('currency_id')));
}),
])
]);
diff --git a/app/Panel/Livewire/Workflows/Payment/Tables/PaymentItems.php b/app/Panel/Livewire/Workflows/Payment/Tables/SubmissionPaymentItemTable.php
similarity index 84%
rename from app/Panel/Livewire/Workflows/Payment/Tables/PaymentItems.php
rename to app/Panel/Livewire/Workflows/Payment/Tables/SubmissionPaymentItemTable.php
index 7259c4f60..06e0f2488 100644
--- a/app/Panel/Livewire/Workflows/Payment/Tables/PaymentItems.php
+++ b/app/Panel/Livewire/Workflows/Payment/Tables/SubmissionPaymentItemTable.php
@@ -2,9 +2,11 @@
namespace App\Panel\Livewire\Workflows\Payment\Tables;
-use App\Models\SubmissionPaymentItem;
+use App\Models\Enums\PaymentType;
+use App\Models\PaymentItem;
use App\Tables\Columns\IndexColumn;
use Filament\Forms\Components\Grid;
+use Filament\Forms\Components\Hidden;
use Filament\Forms\Components\Repeater;
use Filament\Forms\Components\Select;
use Filament\Forms\Components\Textarea;
@@ -23,7 +25,7 @@
use Illuminate\Support\Facades\App;
use Squire\Models\Currency;
-class PaymentItems extends \Livewire\Component implements HasForms, HasTable
+class SubmissionPaymentItemTable extends \Livewire\Component implements HasForms, HasTable
{
use InteractsWithForms;
use InteractsWithTable;
@@ -36,6 +38,7 @@ public function render()
public function table(Table $table): Table
{
$formField = [
+ Hidden::make('type'),
TextInput::make('name')
->required(),
Textarea::make('description')
@@ -51,7 +54,6 @@ public function table(Table $table): Table
->required()
->disabled()
->dehydrated(true)
- // ->options(Currency::whereIn('id', App::getCurrentConference()->getMeta('workflow.payment.supported_currencies') ?? [])->pluck('name', 'id'))
->options(Currency::pluck('name', 'id'))
->optionsLimit(250)
->distinct(),
@@ -64,15 +66,17 @@ public function table(Table $table): Table
])
->deletable(false)
->reorderable(false)
- // ->reorderableWithButtons()
->addable(false)
->addActionLabel('Add Fee'),
];
return $table
- ->query(SubmissionPaymentItem::query())
+ ->query(
+ PaymentItem::query()
+ ->where('type', PaymentType::Submission)
+ ->orderBy('order_column')
+ )
->reorderable('order_column')
- ->heading('Payment Items')
->paginated(false)
->columns([
IndexColumn::make('no'),
@@ -86,17 +90,18 @@ public function table(Table $table): Table
CreateAction::make()
->label('New Payment Item')
->mountUsing(function (Form $form) {
- $fees = collect(App::getCurrentConference()->getMeta('workflow.payment.supported_currencies'))->map(function ($currency) {
- return [
+ $fees = collect(App::getCurrentConference()->getMeta('payment.supported_currencies'))
+ ->map(fn ($currency) => [
'currency_id' => $currency,
'fee' => 0,
- ];
- })->toArray();
+ ]);
+
$form->fill([
- 'fees' => $fees,
+ 'fees' => $fees->toArray(),
+ 'type' => PaymentType::Submission,
]);
})
- ->model(SubmissionPaymentItem::class)
+ ->model(PaymentItem::class)
->modalWidth('2xl')
->form($formField),
])
@@ -106,7 +111,7 @@ public function table(Table $table): Table
->actions([
EditAction::make()
->mutateRecordDataUsing(function ($data) {
- $supportedCurrencies = App::getCurrentConference()->getMeta('workflow.payment.supported_currencies') ?? [];
+ $supportedCurrencies = App::getCurrentConference()->getMeta('payment.supported_currencies') ?? [];
$fees = collect($supportedCurrencies)
->map(fn ($currency) => ['currency_id' => $currency, 'fee' => 0])
->keyBy('currency_id')
diff --git a/app/Panel/Livewire/Workflows/PaymentSetting.php b/app/Panel/Livewire/Workflows/PaymentSetting.php
index c3139eb08..d3f1c2a64 100644
--- a/app/Panel/Livewire/Workflows/PaymentSetting.php
+++ b/app/Panel/Livewire/Workflows/PaymentSetting.php
@@ -10,10 +10,12 @@
use Filament\Actions\Contracts\HasActions;
use Filament\Forms\Components\Grid;
use Filament\Forms\Components\Select;
+use Filament\Forms\Components\Toggle;
use Filament\Forms\Concerns\InteractsWithForms;
use Filament\Forms\Contracts\HasForms;
use Filament\Forms\Form;
use Filament\Forms\Get;
+use Illuminate\Support\Arr;
use Illuminate\Support\Facades\Log;
use Squire\Models\Currency;
@@ -30,9 +32,10 @@ class PaymentSetting extends WorkflowStage implements HasActions, HasForms
public function mount()
{
$this->form->fill([
- 'settings' => [
- 'payment_method' => $this->getSetting('payment_method', 'manual'),
- 'supported_currencies' => $this->getSetting('supported_currencies'),
+ 'payment' => [
+ 'enabled' => $this->conference->getMeta('payment.enabled'),
+ 'method' => $this->conference->getMeta('payment.method', 'manual'),
+ 'supported_currencies' => $this->conference->getMeta('payment.supported_currencies', ['usd']),
],
...Payment::getAllDriverNames()->map(fn ($name, $key) => Payment::driver($key)->getSettingFormFill())->toArray(),
]);
@@ -50,14 +53,15 @@ public function submitAction()
try {
$data = $this->form->getState();
- foreach ($data['settings'] as $key => $value) {
- $this->updateSetting($key, $value);
+
+ foreach ($data['payment'] as $key => $value) {
+ $this->conference->setMeta('payment.' . $key, $value);
}
- Payment::driver($data['settings']['payment_method'])
- ->saveSetting(data_get($data, $data['settings']['payment_method'], []));
+ Payment::driver($this->conference->getMeta('payment.method'))
+ ->saveSetting(data_get($data, $this->conference->getMeta('payment.method'), []));
} catch (\Throwable $th) {
- //throw $th;
+
Log::error($th);
$action->failure();
@@ -73,24 +77,26 @@ public function form(Form $form): Form
return $form
->statePath('data')
->schema([
- Shout::make('stage-closed')
- ->hidden(fn (): bool => $this->isStageOpen())
- ->color('warning')
- ->content('The payment stage is not open yet, Start now or schedule opening'),
- Select::make('settings.payment_method')
- ->label('Payment Method')
- ->required()
- ->options(Payment::getAllDriverNames())
+ Toggle::make('payment.enabled')
->reactive(),
- Select::make('settings.supported_currencies')
- ->searchable()
- ->required()
- ->multiple()
- ->options(Currency::query()->get()->mapWithKeys(fn (Currency $currency) => [$currency->id => $currency->name.' ('.$currency->symbol_native.')'])->toArray())
- ->optionsLimit(250),
Grid::make(1)
- ->hidden(fn (Get $get) => ! $get('settings.payment_method'))
- ->schema(fn (Get $get) => Payment::driver($get('payment_method'))->getSettingFormSchema()),
+ ->hidden(fn (Get $get) => ! $get('payment.enabled'))
+ ->schema([
+ Select::make('payment.method')
+ ->label('Payment Method')
+ ->required()
+ ->options(Payment::getAllDriverNames())
+ ->reactive(),
+ Select::make('payment.supported_currencies')
+ ->searchable()
+ ->required()
+ ->multiple()
+ ->options(Currency::query()->get()->mapWithKeys(fn (Currency $currency) => [$currency->id => $currency->name.' ('.$currency->symbol_native.')'])->toArray())
+ ->optionsLimit(250),
+ Grid::make(1)
+ ->hidden(fn (Get $get) => !$get('payment.method'))
+ ->schema(fn (Get $get) => Payment::driver($get('payment.method'))->getSettingFormSchema()),
+ ])
]);
}
diff --git a/app/Panel/Pages/Settings/Workflow.php b/app/Panel/Pages/Settings/Workflow.php
index 2b0b466d5..07538a72a 100644
--- a/app/Panel/Pages/Settings/Workflow.php
+++ b/app/Panel/Pages/Settings/Workflow.php
@@ -7,7 +7,7 @@
use App\Infolists\Components\VerticalTabs\Tabs;
use App\Panel\Livewire\Workflows\AbstractSetting;
use App\Panel\Livewire\Workflows\EditingSetting;
-use App\Panel\Livewire\Workflows\Payment\Tables\PaymentItems;
+use App\Panel\Livewire\Workflows\Payment\Tables\SubmissionPaymentItemTable;
use App\Panel\Livewire\Workflows\PaymentSetting;
use App\Panel\Livewire\Workflows\PeerReview\Forms\Guidelines;
use App\Panel\Livewire\Workflows\PeerReviewSetting;
@@ -35,7 +35,7 @@ class Workflow extends Page implements HasForms, HasInfolists
public function booted(): void
{
- abort_if(! static::canView(), 403);
+ abort_if(!static::canView(), 403);
}
public static function shouldRegisterNavigation(): bool
@@ -77,10 +77,10 @@ public function infolist(Infolist $infolist): Infolist
LivewireEntry::make('payment-setting')
->livewire(PaymentSetting::class),
]),
- HorizontalTab::make('Items')
+ HorizontalTab::make('Submission Payment Items')
->schema([
LivewireEntry::make('payment-items')
- ->livewire(PaymentItems::class),
+ ->livewire(SubmissionPaymentItemTable::class),
]),
]),
diff --git a/app/Panel/Resources/SubmissionResource/Pages/ManageSubmissions.php b/app/Panel/Resources/SubmissionResource/Pages/ManageSubmissions.php
index 901b07256..5e4bcb2ad 100644
--- a/app/Panel/Resources/SubmissionResource/Pages/ManageSubmissions.php
+++ b/app/Panel/Resources/SubmissionResource/Pages/ManageSubmissions.php
@@ -10,12 +10,13 @@
use Awcodes\Shout\Components\ShoutEntry;
use Filament\Actions\Action;
use Filament\Infolists\Infolist;
-use Filament\Resources\Pages\ListRecords\Tab;
+use Filament\Resources\Components\Tab;
use Filament\Resources\Pages\ManageRecords;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\HtmlString;
+
class ManageSubmissions extends ManageRecords
{
protected static string $resource = SubmissionResource::class;
diff --git a/app/Panel/Resources/SubmissionResource/Pages/ViewSubmission.php b/app/Panel/Resources/SubmissionResource/Pages/ViewSubmission.php
index 2efcd26f8..1e7ed8834 100644
--- a/app/Panel/Resources/SubmissionResource/Pages/ViewSubmission.php
+++ b/app/Panel/Resources/SubmissionResource/Pages/ViewSubmission.php
@@ -14,7 +14,7 @@
use App\Models\Enums\SubmissionStage;
use App\Models\Enums\SubmissionStatus;
use App\Models\Enums\UserRole;
-use App\Models\SubmissionPaymentItem;
+use App\Models\PaymentItem;
use App\Models\User;
use App\Notifications\SubmissionWithdrawn;
use App\Notifications\SubmissionWithdrawRequested;
@@ -76,19 +76,22 @@ protected function getHeaderActions(): array
{
return [
Action::make('payment')
- ->model(Payment::class)
+ ->visible($this->record->hasPaymentProcess())
->record(fn () => $this->record->payment)
+ ->model(Payment::class)
->icon('heroicon-o-currency-dollar')
->color('primary')
+ ->modalHeading('Submission Payment')
->when(
- fn (Action $action): bool => !$action->getRecord() || $action->getRecord()?->state === PaymentState::Pending,
+ fn (Action $action): bool => !$action->getRecord() || $action->getRecord()?->state->isOneOf(PaymentState::Unpaid),
fn (Action $action): Action => $action
->action(function (array $data, Form $form) {
+
$payment = FacadesPayment::createPayment(
$this->record,
auth()->user(),
- collect($data['items'])->sum(),
$data['currency_id'],
+ $data['items'],
);
$form->model($payment)->saveRelationships();
@@ -116,8 +119,8 @@ protected function getHeaderActions(): array
->visible(fn (Get $get) => $get('currency_id'))
->required()
->options(function (Get $get) {
- return SubmissionPaymentItem::get()
- ->filter(function (SubmissionPaymentItem $item) use ($get): bool {
+ return PaymentItem::get()
+ ->filter(function (PaymentItem $item) use ($get): bool {
foreach ($item->fees as $fee) {
if (!array_key_exists('currency_id', $fee)) continue;
if ($fee['currency_id'] === $get('currency_id')) return true;
@@ -125,26 +128,28 @@ protected function getHeaderActions(): array
return false;
})
- ->mapWithKeys(fn (SubmissionPaymentItem $item): array => [$item->getAmount($get('currency_id')) => $item->name . ': ' . $item->getFormattedAmount($get('currency_id'))]);
- // ->mapWithKeys(fn (SubmissionPaymentItem $item): array => [$item->getKey() => $item->name . ': ' . $item->getFormattedAmount($get('currency_id'))]);
+ // ->mapWithKeys(fn (PaymentItem $item): array => [$item->getAmount($get('currency_id')) => $item->name . ': ' . $item->getFormattedAmount($get('currency_id'))]);
+ ->mapWithKeys(fn (PaymentItem $item): array => [$item->id => $item->name . ': ' . $item->getFormattedAmount($get('currency_id'))]);
}),
...FacadesPayment::driver($this->record->payment?->payment_method)->getPaymentFormSchema(),
]),
)
->when(
- fn (Action $action): bool => $action->getRecord()?->state === PaymentState::Processing,
+ fn (Action $action): bool => $action->getRecord()?->state->isOneOf(PaymentState::Processing, PaymentState::Paid, PaymentState::Waived) ?? false,
fn (Action $action): Action => $action
->action(function (array $data, $record) {
$record->state = $data['decision'];
$record->save();
})
- ->modalHeading('Payment Processing')
+ ->modalSubmitAction(fn(StaticAction $action) => $action->hidden($this->record->payment?->isCompleted()))
+ ->modalCancelAction(fn(StaticAction $action) => $action->hidden($this->record->payment?->isCompleted()))
->mountUsing(function (Form $form) {
$payment = $this->record->payment;
$form->fill([
'currency_id' => $payment?->currency_id,
'amount' => $payment?->amount,
+ 'items' => array_keys($payment?->getMeta('items') ?? []),
...FacadesPayment::getPaymentFormFill(),
]);
})
@@ -160,14 +165,17 @@ protected function getHeaderActions(): array
->prefix(fn (Get $get) => $get('currency_id') ? Currency::find($get('currency_id'))->symbol_native : null)
->numeric(),
]),
+ CheckboxList::make('items')
+ ->options($this->record->payment?->getMeta('items')),
...FacadesPayment::driver($this->record->payment?->payment_method)->getPaymentFormSchema(),
])
->disabled(),
Select::make('decision')
->required()
+ ->hidden(fn() => $this->record->payment?->isCompleted())
->options([
- PaymentState::Pending->value => PaymentState::Pending->name,
+ PaymentState::Unpaid->value => PaymentState::Unpaid->name,
PaymentState::Waived->value => PaymentState::Waived->name,
PaymentState::Paid->value => PaymentState::Paid->name,
]),
@@ -221,7 +229,9 @@ protected function getHeaderActions(): array
fn ($manager) => $manager->notify(new SubmissionWithdrawRequested($this->record))
);
- $this->record->getEditors()
+ $this
+ ->record
+ ->getEditors()
->each(function (User $editor) {
$editor->notify(new SubmissionWithdrawRequested($this->record));
});
@@ -311,7 +321,9 @@ protected function getHeaderActions(): array
public function getSubheading(): string|Htmlable|null
{
- $badgeHtml = match ($this->record->status) {
+ $badgeHtml = '';
+
+ $badgeHtml .= match ($this->record->status) {
SubmissionStatus::Incomplete => '' . SubmissionStatus::Incomplete->value . '',
SubmissionStatus::Queued => '' . SubmissionStatus::Queued->value . '',
SubmissionStatus::OnReview => '' . SubmissionStatus::OnReview->value . '',
@@ -322,6 +334,18 @@ public function getSubheading(): string|Htmlable|null
default => null,
};
+ if ($this->record->hasPaymentProcess()) {
+ $badgeHtml .= match ($this->record->payment?->state) {
+ PaymentState::Unpaid => 'Unpaid',
+ PaymentState::Processing => 'Payment Processing',
+ PaymentState::Paid => 'Paid',
+ PaymentState::Waived => 'Payment Waived',
+ default => 'Unpaid',
+ };
+ }
+
+ $badgeHtml .= '
';
+
return new HtmlString(
BladeCompiler::render($badgeHtml)
);
@@ -357,7 +381,7 @@ public function infolist(Infolist $infolist): Infolist
Tab::make('Call for Abstract')
->icon('heroicon-o-information-circle')
->schema(function () {
- if (! StageManager::callForAbstract()->isStageOpen() && ! $this->record->isPublished()) {
+ if (!StageManager::callForAbstract()->isStageOpen() && !$this->record->isPublished()) {
return [
ShoutEntry::make('call-for-abstract-closed')
->type('warning')
@@ -376,7 +400,7 @@ public function infolist(Infolist $infolist): Infolist
Tab::make('Peer Review')
->icon('iconpark-checklist-o')
->schema(function (): array {
- if (! StageManager::peerReview()->isStageOpen() && ! $this->record->isPublished()) {
+ if (!StageManager::peerReview()->isStageOpen() && !$this->record->isPublished()) {
return [
ShoutEntry::make('peer-review-closed')
->type('warning')
@@ -395,7 +419,7 @@ public function infolist(Infolist $infolist): Infolist
Tab::make('Editing')
->icon('heroicon-o-pencil')
->schema(function () {
- if (! StageManager::editing()->isStageOpen() && ! $this->record->isPublished()) {
+ if (!StageManager::editing()->isStageOpen() && !$this->record->isPublished()) {
return [
ShoutEntry::make('editing-closed')
->type('warning')
diff --git a/database/migrations/2023_12_12_112200_create_payments_table.php b/database/migrations/2023_12_12_112200_create_payments_table.php
index 335230253..6e909f5b3 100644
--- a/database/migrations/2023_12_12_112200_create_payments_table.php
+++ b/database/migrations/2023_12_12_112200_create_payments_table.php
@@ -20,15 +20,15 @@ public function up(): void
$table->foreignIdFor(Conference::class)->constrained();
$table->morphs('payable');
$table->foreignIdFor(User::class)->constrained();
- // $table->enum('type', PaymentType::array());
- $table->enum('state', PaymentState::array())->default(PaymentState::Pending->value);
+ $table->enum('type', PaymentType::array());
+ $table->enum('state', PaymentState::array())->default(PaymentState::Unpaid->value);
$table->double('amount');
$table->string('currency_id');
$table->timestamp('paid_at')->nullable();
$table->string('payment_method');
$table->timestamps();
- // $table->index(['type']);
+ $table->index(['type']);
$table->index(['state']);
});
@@ -44,25 +44,17 @@ public function up(): void
$table->index(['key', 'metable_type']);
});
- Schema::create('submission_payment_items', function (Blueprint $table) {
+ Schema::create('payment_items', function (Blueprint $table) {
$table->id();
$table->foreignIdFor(Conference::class)->constrained();
$table->string('name');
+ $table->enum('type', PaymentType::array());
$table->text('description')->nullable();
$table->integer('order_column')->nullable();
$table->json('fees');
$table->boolean('active')->default(true);
$table->timestamps();
});
-
- // Schema::create('submission_payment_items_details', function (Blueprint $table){
- // $table->id();
- // $table->foreignId('submission_payment_item_id')->constrained('submission_payment_items', indexName:'items_details_item_id_foreign')->cascadeOnDelete();
- // $table->string('currency_id');
- // $table->double('fee');
- // $table->integer('order_column')->nullable();
- // $table->timestamps();
- // });
}
/**
diff --git a/public/build/manifest.json b/public/build/manifest.json
index f3e3596e9..e72c1d415 100644
--- a/public/build/manifest.json
+++ b/public/build/manifest.json
@@ -4,7 +4,7 @@
"src": "resources/assets/images/logo.png"
},
"resources/panel/css/panel.css": {
- "file": "assets/panel-df6f1873.css",
+ "file": "assets/panel-c1c13b63.css",
"isEntry": true,
"src": "resources/panel/css/panel.css"
},
diff --git a/resources/views/panel/livewire/workflows/payment-setting.blade.php b/resources/views/panel/livewire/workflows/payment-setting.blade.php
index 268bc8199..39a7451e8 100644
--- a/resources/views/panel/livewire/workflows/payment-setting.blade.php
+++ b/resources/views/panel/livewire/workflows/payment-setting.blade.php
@@ -4,13 +4,7 @@
Payment
- @if ($this->isStageOpen())
- Open
- @else
- Close
- @endif
- @livewire(App\Panel\Livewire\Workflows\Components\StageSchedule::class, ['stage' => $this->getStage()])