Skip to content

Commit

Permalink
More Transaction generation to Seeder (#422)
Browse files Browse the repository at this point in the history
* More Transaction generation to Seeder

* Fix bugs in seeding
  • Loading branch information
dmohns authored Dec 12, 2024
1 parent 925c99f commit 5f95e76
Show file tree
Hide file tree
Showing 4 changed files with 297 additions and 254 deletions.
7 changes: 3 additions & 4 deletions docs/development/development-environment.md
Original file line number Diff line number Diff line change
Expand Up @@ -68,16 +68,15 @@ password: 123123

The Demo Company protected page password of this company is `123123`.

## Generating transaction data
## Generating ticket data

To generate transaction and ticket for the Demo Company data, run:
To generate ticket for the Demo Company data, run:

```sh
php artisan demo:create-data 250
php artisan demo:create-data --type=ticket 25
```

This commands will create 250 transactions and 25 tickets within the past 30 days respectively.
This commands will generate 25 tickets within the past 365 days respectively.
It can be run multiple times to generate more data as required.

## Reseting the Demo data
Expand Down
253 changes: 4 additions & 249 deletions src/backend/app/Console/Commands/DemoDataCreator.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,43 +2,21 @@

namespace App\Console\Commands;

use App\Helpers\TokenGenerator;
use App\Models\MainSettings;
use App\Models\MaintenanceUsers;
use App\Models\Meter\Meter;
use App\Models\Meter\MeterToken;
use App\Models\Person\Person;
use App\Models\Token;
use App\Models\Transaction\AgentTransaction;
use App\Models\Transaction\AirtelTransaction;
use App\Models\Transaction\Transaction;
use App\Models\Transaction\VodacomTransaction;
use App\Models\User;
use Illuminate\Database\Eloquent\ModelNotFoundException;
use Illuminate\Console\View\Components\Warn;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Str;
use Inensus\CalinMeter\Models\CalinTransaction;
use Inensus\SwiftaPaymentProvider\Models\SwiftaTransaction;
use Inensus\Ticket\Models\Ticket;
use Inensus\Ticket\Models\TicketCategory;
use Inensus\Ticket\Models\TicketOutsource;
use Inensus\Ticket\Models\TicketUser;
use Inensus\WavecomPaymentProvider\Models\WaveComTransaction;
use Inensus\WaveMoneyPaymentProvider\Models\WaveMoneyTransaction;

class DemoDataCreator extends AbstractSharedCommand {
protected $signature = 'demo:create-data {amount} {--company-id=} {--type=}';
protected $description = 'Creates transaction and ticket data for Demo Company';

private $transactionTypes = [
SwiftaTransaction::class,
WaveComTransaction::class,
WaveMoneyTransaction::class,
AgentTransaction::class,
VodacomTransaction::class,
AirtelTransaction::class,
];

public function handle() {
$companyId = $this->option('company-id');
$type = $this->option('type') ?? 'transaction';
Expand All @@ -55,7 +33,9 @@ public function handle() {
try {
DB::connection('shard')->beginTransaction();
if ($type == 'transaction') {
$this->generateTransaction();
(new Warn($this->getOutput()))->render(
'Generating Transaction data using script is no longer supported. Use `artisan db:seed --TransactionSeeder` instead.`'
);
} else {
$this->generateTicket();
}
Expand All @@ -68,231 +48,6 @@ public function handle() {
}
}

private function generateTransaction(): void {
try {
// get randomly a user
$randomMeter = Meter::inRandomOrder()->with([
'device',
'tariff',
])->limit(1)->firstOrFail();
} catch (ModelNotFoundException $x) {
echo 'failed to find a random meter';

return;
} catch (\Exception $x) {
echo 'boom';

return;
}

$demoDate = date('Y-m-d', strtotime('-'.mt_rand(0, 365).' days'));

try {
$meterOwnerPhoneNumber = $randomMeter->device->person->addresses()->firstOrFail();
} catch (\Exception $x) {
echo 'failed to get meter owner address';

return;
}

try {
$amount = random_int(1000, 20000);
} catch (\Exception $e) {
$amount = 300;
}

$randomTransactionType = $this->getTransactionTypeRandomlyFromTransactionTypes();
$transactionType = app()->make($randomTransactionType);

$transaction = Transaction::query()->make([
'amount' => $amount,
'type' => 'energy',
'message' => $randomMeter['serial_number'],
'sender' => $meterOwnerPhoneNumber['phone'],
'created_at' => $demoDate,
'updated_at' => $demoDate,
]);
$subTransaction = null;

// FIXME: What is this?
$manufacturerTransaction = CalinTransaction::query()->create([]);

if ($transactionType instanceof AgentTransaction) {
$city = $randomMeter->device->person->addresses()->first()->city()->first();
$miniGrid = $city->miniGrid()->first();
$agent = $miniGrid->agent()->first();
$subTransaction = AgentTransaction::query()->create([
'agent_id' => $agent->id,
'device_id' => 'test-device',
'status' => 1,
'manufacturer_transaction_id' => $manufacturerTransaction->id,
'manufacturer_transaction_type' => 'calin_transaction',
'created_at' => $demoDate,
'updated_at' => $demoDate,
]);
}

if ($transactionType instanceof SwiftaTransaction) {
$subTransaction = SwiftaTransaction::query()->create([
'transaction_reference' => Str::random(10),
'status' => 1,
'amount' => $amount,
'cipher' => Str::random(10),
'timestamp' => strval(time()),
'manufacturer_transaction_id' => $manufacturerTransaction->id,
'manufacturer_transaction_type' => 'calin_transaction',
'created_at' => $demoDate,
'updated_at' => $demoDate,
]);
}

if ($transactionType instanceof WaveMoneyTransaction) {
$mainSettings = MainSettings::query()->first();
$subTransaction = WaveMoneyTransaction::query()->create([
'transaction_reference' => Str::random(10),
'status' => 1,
'amount' => $amount,
'order_id' => Str::random(10),
'reference_id' => Str::random(10),
'currency' => $mainSettings ? $mainSettings->currency : '$',
'customer_id' => $randomMeter->device->person->id,
'meter_serial' => $randomMeter['serial_number'],
'external_transaction_id' => Str::random(10),
'attempts' => 1,
'created_at' => $demoDate,
'updated_at' => $demoDate,
'manufacturer_transaction_id' => $manufacturerTransaction->id,
'manufacturer_transaction_type' => 'calin_transaction',
]);
}

if ($transactionType instanceof WaveComTransaction) {
$subTransaction = WaveComTransaction::query()->create([
'transaction_id' => Str::random(10),
'sender' => $meterOwnerPhoneNumber['phone'],
'message' => $randomMeter['serial_number'],
'status' => 1,
'amount' => $amount,
'manufacturer_transaction_id' => $manufacturerTransaction->id,
'manufacturer_transaction_type' => 'calin_transaction',
'created_at' => $demoDate,
'updated_at' => $demoDate,
]);
}

if ($transactionType instanceof VodacomTransaction) {
$subTransaction = VodacomTransaction::query()->create([
'conversation_id' => Str::random(20),
'originator_conversation_id' => Str::random(20),
'mpesa_receipt' => Str::random(10),
'transaction_date' => $demoDate,
'transaction_id' => Str::random(10),
'status' => 1,
'manufacturer_transaction_id' => $manufacturerTransaction->id,
'manufacturer_transaction_type' => 'calin_transaction',
'created_at' => $demoDate,
'updated_at' => $demoDate,
]);
}

if ($transactionType instanceof AirtelTransaction) {
$subTransaction = AirtelTransaction::query()->create([
'interface_id' => Str::random(20),
'business_number' => Str::random(20),
'trans_id' => Str::random(10),
'tr_id' => Str::random(10),
'status' => 1,
'manufacturer_transaction_id' => $manufacturerTransaction->id,
'manufacturer_transaction_type' => 'calin_transaction',
'created_at' => $demoDate,
'updated_at' => $demoDate,
]);
}

$transaction->originalTransaction()->associate($subTransaction);
$transaction->save();

try {
// create an object for the token job
$transactionData = \App\Misc\TransactionDataContainer::initialize($transaction);
} catch (\Exception $exception) {
event('transaction.failed', [$transaction, $exception->getMessage()]);
throw $exception;
}

// pay access rate
$accessRatePayer = resolve('AccessRatePayer');
$accessRatePayer->initialize($transactionData);
$transactionData = $accessRatePayer->pay();

// pay appliance installments
$applianceInstallmentPayer = resolve('ApplianceInstallmentPayer');
$applianceInstallmentPayer->initialize($transactionData);
$transactionData->transaction->amount = $applianceInstallmentPayer->payInstallments();
$transactionData->totalAmount = $transactionData->transaction->amount;
$transactionData->paidRates = $applianceInstallmentPayer->paidRates;
$transactionData->shsLoan = $applianceInstallmentPayer->shsLoan;

// generate random token
if ($transactionData->transaction->amount > 0) {
$tokenData = [
'token' => TokenGenerator::generate(),
'load' => round(
$transactionData->transaction->amount /
$randomMeter['tariff']['price'],
2
),
];
$token = Token::query()->make([
'token' => $tokenData['token'],
'load' => $tokenData['load'],
]);
$token->transaction()->associate($transaction);
$token->save();
$transactionData->token = $token;

// generate meter_token
$meterTokenData = [
'meter_id' => $randomMeter->id,
'token' => TokenGenerator::generate(),
'energy' => round(
$transactionData->transaction->amount /
$randomMeter['tariff']['price'],
2
),
'transaction_id' => $transaction->id,
];
$meterToken = MeterToken::query()->make([
'meter_id' => $meterTokenData['meter_id'],
'token' => $meterTokenData['token'],
'energy' => $meterTokenData['energy'],
'transaction_id' => $meterTokenData['transaction_id'],
]);
$meterToken->save();

// payment event
event(
'payment.successful',
[
'amount' => $transactionData->transaction->amount,
'paymentService' => $transactionData->transaction->original_transaction_type,
'paymentType' => 'energy',
'sender' => $transactionData->transaction->sender,
'paidFor' => $token,
'payer' => $transactionData->device->person,
'transaction' => $transactionData->transaction,
]
);

// TODO: This currently doesn't work, it throws error that SMS is not configured.
// event('transaction.successful', [$transactionData->transaction]);
}
}

private function getTransactionTypeRandomlyFromTransactionTypes() {
return $this->transactionTypes[array_rand($this->transactionTypes)];
}

private function generateTicket() {
$randomCategory = TicketCategory::query()->inRandomOrder()->first();
$fakeSentence = $this->generateFakeSentence();
Expand Down
3 changes: 2 additions & 1 deletion src/backend/database/seeders/DatabaseSeeder.php
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,9 @@ public function run() {
CustomerSeeder::class,
MeterSeeder::class,
SolarHomeSystemSeeder::class,
TicketSeeder::class,
AgentSeeder::class,
TicketSeeder::class,
TransactionSeeder::class,
]);
} else {
// If the database already includes the Demo data we don't throw an error,
Expand Down
Loading

0 comments on commit 5f95e76

Please sign in to comment.