Skip to content

Commit

Permalink
Update core system
Browse files Browse the repository at this point in the history
  • Loading branch information
Yvan Ngalle committed Nov 23, 2024
1 parent 4551e4f commit 20fb41c
Show file tree
Hide file tree
Showing 10 changed files with 92 additions and 36 deletions.
26 changes: 20 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ Publish migration file and config
```shell
php artisan vendor:publish --provider="NYCorp\Finance\FinanceServiceProvider"
```

Run migration

```shell
Expand All @@ -43,7 +44,7 @@ return User::first()->setThreshold(100)
For deposit

```php
return User::first()->deposit($request)
return User::first()->deposit(DefaultPaymentProvider::getId(), 12, $description)
```

Get balance
Expand All @@ -55,32 +56,45 @@ return User::first()->balance
For withdrawal

```php
return User::first()->withdrawal($request)
return User::first()->withdrawal(DefaultPaymentProvider::getId(), 12, $description)
```

Set model currency by adding this method

```php
public function getCurrency()
{
// Implement your logic to get currency here
return \NYCorp\Finance\Http\Core\ConfigReader::getDefaultCurrency();
}
```

Check if user can make transaction if his finance account is not disabled

```php
return Company::first()->canMakeTransaction() ? Company::first()->withdrawal($request) : 'Your account is disabled';
return Company::first()->canMakeTransaction() ? Company::first()->withdrawal(DefaultPaymentProvider::getId(), 12, $description) : 'Your account is disabled';
```

Check if user can make transaction if his finance account has enough balance base on threshold use true to force balance calculation
Check if user can make transaction if his finance account has enough balance base on threshold use true to force balance
calculation

```php
return Company::first()->canWithdraw(100,true) ? Company::first()->withdrawal($request) : 'Insufficient balance';
return Company::first()->canWithdraw(100,true) ? Company::first()->withdrawal(DefaultPaymentProvider::getId(), 12, $description) : 'Insufficient balance';
```

Response handle

```php
$response = \Nycorp\LiteApi\Response\DefResponse::parse(User::first()->withdrawal($request));
$response = \Nycorp\LiteApi\Response\DefResponse::parse(User::first()->withdrawal(DefaultPaymentProvider::getId(), 12, $description));
$response->getBody(); // get the body of the response
$response->isSuccess(); // get the success state as boolean
$response->getMessage(); // get response message
```

[ico-version]: https://img.shields.io/packagist/v/nycorp/finance.svg?style=flat-square

[ico-downloads]: https://img.shields.io/packagist/dt/nycorp/finance.svg?style=flat-square

[link-packagist]: https://packagist.org/packages/nycorp/finance

[link-downloads]: https://packagist.org/packages/nycorp/finance
14 changes: 7 additions & 7 deletions composer.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions config/config.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
'default_payment_provider_id' => 'LOCAL_PROVIDER',
'default_payment_provider_name' => env('APP_NAME')."'s Local Provider",
'default_threshold' => 0,
'default_currency' => 'USD',
'refresh_account_ttl' => 60, #in minute


Expand Down
1 change: 1 addition & 0 deletions database/migrations/create_finance_accounts_table.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ public function up()
$table->id();
$table->decimal('credibility',13,5)->index();
$table->decimal('threshold', 13, 5)->nullable();
$table->string('currency')->index();
$table->dateTime('last_verification_at')->index();
$table->boolean('is_account_active')->default(true)->index();
$table->longText('account_logs');
Expand Down
1 change: 1 addition & 0 deletions database/migrations/create_finance_transactions_table.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ public function up()
Schema::create('finance_transactions', function (Blueprint $table) {
$table->string('id')->primary(); // Primary key for the transaction
$table->decimal('amount', 13, 5)->index(); // Amount of the transaction with high precision
$table->string('currency')->index(); // Amount of the transaction with high precision
$table->timestamp('verify_at')->nullable()->index(); // Timestamp for when the transaction was verified
$table->longText('start_log'); // Log details of when the transaction started
$table->longText('end_log')->nullable(); // Log details of when the transaction ended (nullable)
Expand Down
2 changes: 2 additions & 0 deletions src/Http/Controllers/FinanceTransactionController.php
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ public static function init(Request $request, Model $accountable, string $moveme
private function store(Request $request, FinanceProvider $provider, string $financeMovement = FinanceTransaction::DEPOSIT_MOVEMENT): JsonResponse
{
$rawAmount = $request->get("amount");
$currency = $request->get("currency",ConfigReader::getDefaultCurrency());
$description = $request->get("description");

try {
Expand All @@ -77,6 +78,7 @@ private function store(Request $request, FinanceProvider $provider, string $fina

$data = [
FinanceTransaction::AMOUNT => $amount,
FinanceTransaction::CURRENCY => $currency,
FinanceTransaction::DESCRIPTION => $description,
FinanceTransaction::START_LOG => self::getHttpLog($request),
FinanceTransaction::FINANCE_PROVIDER_ID => $provider->id,
Expand Down
4 changes: 4 additions & 0 deletions src/Http/Core/ConfigReader.php
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,10 @@ public static function getDefaultThreshold()
{
return config(self::FINANCE_CONFIG . ".default_threshold");
}
public static function getDefaultCurrency()
{
return config(self::FINANCE_CONFIG . ".default_currency");
}

public static function getRefreshTtl()
{
Expand Down
3 changes: 3 additions & 0 deletions src/Models/FinanceAccount.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ class FinanceAccount extends Model
public const OWNER_ID = 'owner_id';
public const OWNER_TYPE = 'owner_type';
public const THRESHOLD = 'threshold';
public const CURRENCY = 'currency';


// Attributes that are mass assignable
protected $fillable = [
Expand All @@ -28,6 +30,7 @@ class FinanceAccount extends Model
self::OWNER_ID,
self::OWNER_TYPE,
self::THRESHOLD,
self::CURRENCY,
];

// Casts for data types
Expand Down
3 changes: 3 additions & 0 deletions src/Models/FinanceTransaction.php
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ class FinanceTransaction extends Model

public const ID = 'id';
public const AMOUNT = 'amount';
public const CURRENCY = 'currency';
public const VERIFY_AT = 'verify_at';
public const START_LOG = 'start_log';
public const END_LOG = 'end_log';
Expand Down Expand Up @@ -60,6 +61,7 @@ class FinanceTransaction extends Model
self::AMOUNT,
self::START_LOG,
self::START_SIGNATURE,
self::CURRENCY,
self::DESCRIPTION,
self::STATE,
self::FINANCE_PROVIDER_ID,
Expand Down Expand Up @@ -138,6 +140,7 @@ protected function getStartSignatureFields(): array
self::AMOUNT,
self::START_LOG,
self::STATE,
self::CURRENCY,
self::DESCRIPTION,
self::FINANCE_PROVIDER_ID,
];
Expand Down
73 changes: 50 additions & 23 deletions src/Traits/FinanceAccountTrait.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
use Illuminate\Database\Eloquent\Relations\HasOne;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Arr;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;
use NYCorp\Finance\Http\Controllers\FinanceTransactionController;
use NYCorp\Finance\Http\Controllers\FinanceWalletController;
Expand Down Expand Up @@ -49,41 +51,56 @@ public function balanceChecksum(bool $always = false): float
return $this->calculator();
}

public function calculator(): float
public function calculator(bool $verifyChecksum = false): float
{
$balance = 0;
$active = true;
$logs = [];

Log::debug("Forced balance calculation");
$transactions = FinanceTransaction::whereHas('wallet', function ($q) {
$q->where('owner_id', $this->getKey())->where('owner_type', __CLASS__);
})->get();

foreach ($transactions as $transaction) {
// Verify the checksum for each transaction
if ($active = $transaction->verifyChecksum()) {
// If checksum is valid, add the transaction amount to the balance
$balance += $transaction->amount;
} else {
$logs[] = ['reason' => 'Corrupted transaction id ', 'id' => $transaction->id];
// If checksum is invalid, lock the account and log the issue
break; // Stop further processing for invalid transactions

if ($verifyChecksum) {
Log::debug(__CLASS__ . " balance verification and calculation for " . $this->getKey());

$transactions = FinanceTransaction::whereHas('wallet', function ($q) {
$q->where('owner_id', $this->getKey())->where('owner_type', __CLASS__);
})->get();

foreach ($transactions as $transaction) {
// Verify the checksum for each transaction
if ($active = $transaction->verifyChecksum()) {
// If checksum is valid, add the transaction amount to the balance
$balance += $transaction->amount;
} else {
$logs[] = ['reason' => 'Corrupted transaction id ', 'id' => $transaction->id];
// If checksum is invalid, lock the account and log the issue
#break; // Stop further processing for invalid transactions
}
}
}

if (!$active) {
Log::critical("Wallet locked due to an invalid transaction checksum.", array_merge($logs, [
'transaction_id' => $transaction->id,
'owner_id' => $this->getKey(),
'owner_type' => __CLASS__,
]));
if (!$active) {
Log::critical("Wallet locked due to an invalid transaction checksum.", array_merge($logs, [
'transaction_id' => $transaction->id,
'owner_id' => $this->getKey(),
'owner_type' => __CLASS__,
]));
}
} else {
Log::debug(__CLASS__ . " balance calculation for " . $this->getKey());

$balances = FinanceTransaction::whereHas('wallet', function ($q) {
$q->where('owner_id', $this->getKey())->where('owner_type', __CLASS__);
})->select(FinanceTransaction::CURRENCY, DB::raw('SUM(amount) as total_balance'))
->groupBy(FinanceTransaction::CURRENCY)->pluck('total_balance', FinanceTransaction::CURRENCY)
->toArray();

$balance = Arr::get($balances, $this->getCurrency(),0);
}

FinanceAccount::updateOrCreate(
[
FinanceAccount::OWNER_TYPE => __CLASS__,
FinanceAccount::OWNER_ID => $this->getKey(),
FinanceAccount::CURRENCY => $this->getCurrency(),
],
[
FinanceAccount::IS_ACCOUNT_ACTIVE => $active,
Expand All @@ -96,6 +113,16 @@ public function calculator(): float
return $balance;
}

public function getCurrency()
{
return ConfigReader::getDefaultCurrency();
}

public function getBalancesAttribute(): float
{
return $this->balanceChecksum();
}

public function getClass(): string
{
return __CLASS__;
Expand Down Expand Up @@ -127,7 +154,7 @@ public function deposit(string $providerId, float $amount, string $description):

protected function makeTransaction(string $providerId, float $amount, string $description, string $movement): JsonResponse
{
$request = new Request(['provider_id' => $providerId, 'amount' => $amount, 'description' => $description]);
$request = new Request(['provider_id' => $providerId, FinanceTransaction::AMOUNT => $amount, FinanceTransaction::CURRENCY => $this->getCurrency(), FinanceTransaction::DESCRIPTION => $description,]);
try {
if (!$this->exists) {
throw new LiteResponseException(ResponseCode::REQUEST_NOT_AUTHORIZED, "This action can only be performed on an existing model.");
Expand Down

0 comments on commit 20fb41c

Please sign in to comment.