Skip to content

Commit

Permalink
Merge pull request #164 from OpenSynergic/157-submission-payment
Browse files Browse the repository at this point in the history
157 submission payment
  • Loading branch information
thisnugroho authored Dec 21, 2023
2 parents fd7654f + a2796a5 commit 7e43796
Show file tree
Hide file tree
Showing 60 changed files with 2,053 additions and 173 deletions.
22 changes: 0 additions & 22 deletions app/Actions/Submissions/UnpublishSubmissionAction.php

This file was deleted.

2 changes: 2 additions & 0 deletions app/Application.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
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;
Expand Down Expand Up @@ -66,6 +67,7 @@ public function scopeCurrentConference(): void
Announcement::class,
StaticPage::class,
Timeline::class,
PaymentItem::class,
] as $model) {
$model::addGlobalScope(new ConferenceScope);
}
Expand Down
14 changes: 14 additions & 0 deletions app/Facades/Payment.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<?php

namespace App\Facades;

use App\Managers\PaymentManager;
use Illuminate\Support\Facades\Facade;

class Payment extends Facade
{
protected static function getFacadeAccessor()
{
return PaymentManager::class;
}
}
23 changes: 23 additions & 0 deletions app/Interfaces/PaymentDriver.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<?php

namespace App\Interfaces;

use App\Models\Payment;
use Filament\Forms\Form;

interface PaymentDriver
{
public function getName(): string;

public function getPaymentFormSchema(): array;

public function getSettingFormSchema(): array;

public function getSettingFormFill(): array;

public function saveSetting(array $data): void;

public function handlePayment(Payment $payment);

// public function fillSettingForm(Form $form): void;
}
79 changes: 79 additions & 0 deletions app/Managers/PaymentManager.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
<?php

namespace App\Managers;

use App\Interfaces\PaymentDriver;
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
{
public function getDefaultDriver(): string
{
return App::getCurrentConference()?->getMeta('payment.method') ?? 'manual';
}

public function createManualDriver(): PaymentDriver
{
return new ManualPayment;
}

public function createPayment(Model $model, User $user, string $currencyId, array $items, ?string $paymentMethod = null): Payment
{
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;
}

return $payment;
}

public function getAllDriverNames(): \Illuminate\Support\Collection
{
return collect(['manual' => 'manual', ...$this->customCreators])->mapWithKeys(function ($driver, $key) {
return [$key => $this->driver($key)->getName()];
});
}

/**
* Create a new driver instance.
*
* @param string $driver
* @return mixed
*
* @throws \InvalidArgumentException
*/
protected function createDriver($driver)
{
try {
return parent::createDriver($driver);
} catch (\Throwable $th) {
return null;
}
}
}
14 changes: 14 additions & 0 deletions app/Models/Concerns/InteractsWithPayment.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<?php

namespace App\Models\Concerns;

use App\Models\Payment;
use Illuminate\Database\Eloquent\Relations\MorphOne;

trait InteractsWithPayment
{
public function payment(): MorphOne
{
return $this->morphOne(Payment::class, 'payable');
}
}
5 changes: 5 additions & 0 deletions app/Models/Conference.php
Original file line number Diff line number Diff line change
Expand Up @@ -159,4 +159,9 @@ public function getHomeUrl(): string
default => route('livewirePageGroup.website.pages.home'),
};
}

public function getSupportedCurrencies(): array
{
return $this->getMeta('payment.supported_currencies') ?? ['usd'];
}
}
5 changes: 5 additions & 0 deletions app/Models/Enums/Concern/UsefulEnums.php
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
}
21 changes: 21 additions & 0 deletions app/Models/Enums/PaymentState.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<?php

namespace App\Models\Enums;

use App\Models\Enums\Concern\UsefulEnums;
use Filament\Support\Contracts\HasLabel;

enum PaymentState: string implements HasLabel
{
use UsefulEnums;

case Unpaid = 'Unpaid';
case Processing = 'Processing';
case Waived = 'Waived';
case Paid = 'Paid';

public function getLabel(): ?string
{
return $this->name;
}
}
12 changes: 12 additions & 0 deletions app/Models/Enums/PaymentType.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<?php

namespace App\Models\Enums;

use App\Models\Enums\Concern\UsefulEnums;

enum PaymentType: string
{
use UsefulEnums;

case Submission = 'Submission';
}
15 changes: 14 additions & 1 deletion app/Models/Enums/SubmissionStatus.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,10 @@
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 HasColor, HasLabel
{
use UsefulEnums;

Expand All @@ -22,4 +23,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 => 'primary',
self::Editing => 'info',
self::Published => 'success',
default => 'gray'
};
}
}
10 changes: 10 additions & 0 deletions app/Models/Interfaces/HasPayment.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<?php

namespace App\Models\Interfaces;

use Illuminate\Database\Eloquent\Relations\MorphOne;

interface HasPayment
{
public function payment(): MorphOne;
}
10 changes: 10 additions & 0 deletions app/Models/Meta/PaymentMeta.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<?php

namespace App\Models\Meta;

use App\Models\Meta;

class PaymentMeta extends Meta
{
protected $table = 'payment_meta';
}
66 changes: 66 additions & 0 deletions app/Models/Payment.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
<?php

namespace App\Models;

use App\Models\Concerns\BelongsToConference;
use App\Models\Enums\PaymentState;
use App\Models\Meta\PaymentMeta;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\MorphTo;
use Plank\Metable\Metable;
use Spatie\MediaLibrary\HasMedia;
use Spatie\MediaLibrary\InteractsWithMedia;

class Payment extends Model implements HasMedia
{
use BelongsToConference, InteractsWithMedia, Metable;

/**
* The model's default values for attributes.
*
* @var array
*/
protected $attributes = [
'state' => PaymentState::Unpaid,
];

/**
* The attributes that should be cast.
*
* @var array
*/
protected $casts = [
'state' => 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);
}

protected function getMetaClassName(): string
{
return PaymentMeta::class;
}

public function isCompleted(): bool
{
return $this->state->isOneOf(PaymentState::Paid, PaymentState::Waived);
}
}
Loading

0 comments on commit 7e43796

Please sign in to comment.