Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion composer.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "fleetbase/core-api",
"version": "1.6.52",
"version": "1.6.53",
"description": "Core Framework and Resources for Fleetbase API",
"keywords": [
"fleetbase",
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
<?php

use Fleetbase\Models\Transaction;
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Schema;

return new class extends Migration {
public function up(): void
{
Schema::table('transactions', function (Blueprint $table) {
if (!Schema::hasColumn('transactions', 'settlement_status')) {
$table->string('settlement_status', 32)
->default(Transaction::SETTLEMENT_STATUS_UNPAID)
->after('status')
->index('transactions_settlement_status_index');
}
});

DB::table('transactions')
->whereNull('settlement_status')
->update(['settlement_status' => Transaction::SETTLEMENT_STATUS_UNPAID]);

DB::table('transactions')
->where('status', 'completed')
->update(['status' => Transaction::STATUS_SUCCESS]);

DB::table('transactions')
->where('status', 'paid')
->update([
'status' => Transaction::STATUS_SUCCESS,
'settlement_status' => Transaction::SETTLEMENT_STATUS_PAID,
'settled_at' => DB::raw('COALESCE(settled_at, updated_at, created_at)'),
]);

DB::table('transactions')
->whereIn('type', [
Transaction::TYPE_INVOICE_PAYMENT,
Transaction::TYPE_WALLET_DEPOSIT,
Transaction::TYPE_WALLET_WITHDRAWAL,
Transaction::TYPE_WALLET_TRANSFER_IN,
Transaction::TYPE_WALLET_TRANSFER_OUT,
'deposit',
'withdrawal',
'transfer_in',
'transfer_out',
])
->where('status', Transaction::STATUS_SUCCESS)
->where('settlement_status', Transaction::SETTLEMENT_STATUS_UNPAID)
->update([
'settlement_status' => Transaction::SETTLEMENT_STATUS_PAID,
'settled_at' => DB::raw('COALESCE(settled_at, updated_at, created_at)'),
]);
}

public function down(): void
{
Schema::table('transactions', function (Blueprint $table) {
if (Schema::hasColumn('transactions', 'settlement_status')) {
$table->dropIndex('transactions_settlement_status_index');
$table->dropColumn('settlement_status');
}
});
}
};
48 changes: 47 additions & 1 deletion src/Models/Transaction.php
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ class Transaction extends Model
'type',
'direction',
'status',
'settlement_status',

// Monetary (all in smallest currency unit / cents)
'amount',
Expand Down Expand Up @@ -190,6 +191,16 @@ class Transaction extends Model
public const STATUS_VOIDED = 'voided';
public const STATUS_EXPIRED = 'expired';

// =========================================================================
// Settlement Status Constants
// =========================================================================

public const SETTLEMENT_STATUS_UNPAID = 'unpaid';
public const SETTLEMENT_STATUS_PARTIALLY_PAID = 'partially_paid';
public const SETTLEMENT_STATUS_PAID = 'paid';
public const SETTLEMENT_STATUS_PARTIALLY_REFUNDED = 'partially_refunded';
public const SETTLEMENT_STATUS_REFUNDED = 'refunded';

// =========================================================================
// Type Constants — Platform-wide taxonomy
// =========================================================================
Expand Down Expand Up @@ -352,6 +363,14 @@ public function scopeFailed($query)
return $query->where('status', self::STATUS_FAILED);
}

/**
* Scope to paid or otherwise settled transactions.
*/
public function scopeSettled($query)
{
return $query->where('settlement_status', self::SETTLEMENT_STATUS_PAID);
}

/**
* Scope to a specific transaction type.
*/
Expand Down Expand Up @@ -485,7 +504,34 @@ public function isReversed(): bool
*/
public function isSettled(): bool
{
return $this->settled_at !== null;
return $this->settlement_status === self::SETTLEMENT_STATUS_PAID || $this->settled_at !== null;
}

/**
* Whether this transaction has not been settled.
*/
public function isUnpaid(): bool
{
return $this->settlement_status === self::SETTLEMENT_STATUS_UNPAID;
}

/**
* Whether this transaction has been partially settled.
*/
public function isPartiallyPaid(): bool
{
return $this->settlement_status === self::SETTLEMENT_STATUS_PARTIALLY_PAID;
}

/**
* Whether this transaction has been partially or fully refunded.
*/
public function isRefunded(): bool
{
return in_array($this->settlement_status, [
self::SETTLEMENT_STATUS_PARTIALLY_REFUNDED,
self::SETTLEMENT_STATUS_REFUNDED,
], true);
}

/**
Expand Down
Loading