Page Menu
Home
Phorge
Search
Configure Global Search
Log In
Files
F117944530
D1249.1775482101.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Flag For Later
Award Token
Authored By
Unknown
Size
10 KB
Referenced Files
None
Subscribers
None
D1249.1775482101.diff
View Options
diff --git a/src/app/Console/Commands/WalletCharge.php b/src/app/Console/Commands/WalletCharge.php
--- a/src/app/Console/Commands/WalletCharge.php
+++ b/src/app/Console/Commands/WalletCharge.php
@@ -2,11 +2,7 @@
namespace App\Console\Commands;
-use App\Domain;
-use App\User;
-use Carbon\Carbon;
use Illuminate\Console\Command;
-use Illuminate\Support\Facades\DB;
class WalletCharge extends Command
{
@@ -44,19 +40,16 @@
$wallets = \App\Wallet::all();
foreach ($wallets as $wallet) {
- $charge = $wallet->expectedCharges();
+ $charge = $wallet->chargeEntitlements();
if ($charge > 0) {
$this->info(
- "charging wallet {$wallet->id} for user {$wallet->owner->email} with {$charge}"
+ "Charged wallet {$wallet->id} for user {$wallet->owner->email} with {$charge}"
);
- $wallet->chargeEntitlements();
-
- if ($wallet->balance < 0) {
- // Disabled for now
- // \App\Jobs\WalletPayment::dispatch($wallet);
- }
+ // Top-up the wallet if auto-payment enabled for the wallet
+ // And send the notification email to the user
+ \App\Jobs\WalletCharge::dispatch($wallet, $wallet->balance, $charge);
}
}
}
diff --git a/src/app/Jobs/WalletCharge.php b/src/app/Jobs/WalletCharge.php
new file mode 100644
--- /dev/null
+++ b/src/app/Jobs/WalletCharge.php
@@ -0,0 +1,116 @@
+<?php
+
+namespace App\Jobs;
+
+use App\Mail\WalletCharge as WalletChargeMail;
+use App\Wallet;
+use App\Http\Controllers\API\V4\PaymentsController;
+use Illuminate\Bus\Queueable;
+use Illuminate\Contracts\Queue\ShouldQueue;
+use Illuminate\Foundation\Bus\Dispatchable;
+use Illuminate\Queue\InteractsWithQueue;
+use Illuminate\Queue\SerializesModels;
+
+class WalletCharge implements ShouldQueue
+{
+ use Dispatchable;
+ use InteractsWithQueue;
+ use Queueable;
+ use SerializesModels;
+
+ /** @var \App\Wallet A wallet object */
+ protected $wallet;
+
+ /** @var int A current wallet balance */
+ protected $balance;
+
+ /** @var int A charged value */
+ protected $charge;
+
+ /** @var int The number of seconds to wait before retrying the job. */
+ public $retryAfter = 10;
+
+ /** @var int How many times retry the job if it fails. */
+ public $tries = 5;
+
+ /** @var bool Delete the job if the wallet no longer exist. */
+ public $deleteWhenMissingModels = true;
+
+
+ /**
+ * Create a new job instance.
+ *
+ * @param \App\Wallet $wallet The wallet that has been charged.
+ * @param int $balance The wallet balance just after the charge
+ * @param int $charge The charged value
+ *
+ * @return void
+ */
+ public function __construct(Wallet $wallet, int $balance, int $charge)
+ {
+ $this->wallet = $wallet;
+ $this->balance = $balance;
+ $this->charge = $charge;
+ }
+
+ /**
+ * Execute the job.
+ *
+ * @return void
+ */
+ public function handle()
+ {
+ $min_balance = (int) (floatval($this->wallet->getSetting('mandate_balance')) * 100);
+ $balance = $this->wallet->balance;
+
+ // The wallet balance is greater than the auto-payment threshold
+ // Only notify the user about the charge
+ if ($balance > $min_balance) {
+ $this->sendMail(WalletChargeMail::TOPUP_NONE);
+ return;
+ }
+
+ $amount = (int) (floatval($this->wallet->getSetting('mandate_amount')) * 100);
+
+ $result = PaymentsController::directCharge($this->wallet, $amount);
+
+ // There actually is no active auto-payment mandate
+ if (!$result) {
+ $this->sendMail(WalletChargeMail::TOPUP_NONE);
+ return;
+ }
+
+ // The defined top-up amount is not enough
+ // Disable auto-payment and notify the user
+ if ($balance - $amount < 0) {
+ $this->sendMail(WalletChargeMail::TOPUP_NOTENOUGH);
+ return;
+ }
+
+ // The top-up request has been registered at payment provider,
+ // but this is an async process
+ $this->sendMail(WalletChargeMail::TOPUP_INIT);
+ }
+
+ /**
+ * Send the notification email
+ *
+ * @return void
+ */
+ protected function sendMail(int $type = 0)
+ {
+ $params = [
+ // The notification (content) type
+ 'type' => $type,
+ // The wallet balance immediately after the charge (before top-up)
+ 'balance' => $this->balance,
+ // The charged value
+ 'charged' => $this->charge,
+ ];
+
+ // We're sending the email in a separate process, so when it fails
+ // it will not retry the current job (hoping that dispatch() itself
+ // does not throw an exception)
+ WalletChargeEmail::dispatch($this->wallet, $params);
+ }
+}
diff --git a/src/app/Jobs/WalletChargeEmail.php b/src/app/Jobs/WalletChargeEmail.php
new file mode 100644
--- /dev/null
+++ b/src/app/Jobs/WalletChargeEmail.php
@@ -0,0 +1,64 @@
+<?php
+
+namespace App\Jobs;
+
+use App\Mail\WalletCharge;
+use App\Wallet;
+use Illuminate\Bus\Queueable;
+use Illuminate\Contracts\Queue\ShouldQueue;
+use Illuminate\Foundation\Bus\Dispatchable;
+use Illuminate\Support\Facades\Mail;
+use Illuminate\Queue\SerializesModels;
+use Illuminate\Queue\InteractsWithQueue;
+
+class WalletChargeEmail implements ShouldQueue
+{
+ use Dispatchable;
+ use InteractsWithQueue;
+ use Queueable;
+ use SerializesModels;
+
+ /** @var int The number of times the job may be attempted. */
+ public $tries = 2;
+
+ /** @var \App\Wallet A wallet object */
+ protected $wallet;
+
+ /** @var array Parameters */
+ protected $params;
+
+ /** @var int The number of seconds to wait before retrying the job. */
+ public $retryAfter = 10;
+
+ /** @var bool Delete the job if the wallet no longer exist. */
+ public $deleteWhenMissingModels = true;
+
+ /**
+ * Create a new job instance.
+ *
+ * @param \App\Wallet $wallet A wallet object
+ * @param array $params Email parameters
+ *
+ * @return void
+ */
+ public function __construct(Wallet $wallet, array $params = [])
+ {
+ $this->wallet = $wallet;
+ $this->params = $params;
+ }
+
+ /**
+ * Execute the job.
+ *
+ * @return void
+ */
+ public function handle()
+ {
+ $user = $this->wallet->owner;
+ $ext_email = $user->getSetting('external_email');
+
+ $mail = new WalletCharge($this->wallet, $this->params);
+
+ Mail::to($user->email)->cc([$ext_email])->send($mail);
+ }
+}
diff --git a/src/app/Jobs/WalletPayment.php b/src/app/Jobs/WalletPayment.php
deleted file mode 100644
--- a/src/app/Jobs/WalletPayment.php
+++ /dev/null
@@ -1,51 +0,0 @@
-<?php
-
-namespace App\Jobs;
-
-use App\Wallet;
-use App\Http\Controllers\API\V4\PaymentsController;
-use Illuminate\Bus\Queueable;
-use Illuminate\Contracts\Queue\ShouldQueue;
-use Illuminate\Foundation\Bus\Dispatchable;
-use Illuminate\Queue\InteractsWithQueue;
-use Illuminate\Queue\SerializesModels;
-
-class WalletPayment implements ShouldQueue
-{
- use Dispatchable;
- use InteractsWithQueue;
- use Queueable;
- use SerializesModels;
-
- protected $wallet;
-
- public $tries = 5;
-
- /** @var bool Delete the job if its models no longer exist. */
- public $deleteWhenMissingModels = true;
-
-
- /**
- * Create a new job instance.
- *
- * @param \App\Wallet $wallet The wallet to charge.
- *
- * @return void
- */
- public function __construct(Wallet $wallet)
- {
- $this->wallet = $wallet;
- }
-
- /**
- * Execute the job.
- *
- * @return void
- */
- public function handle()
- {
- if ($this->wallet->balance < 0) {
- PaymentsController::directCharge($this->wallet, $this->wallet->balance * -1);
- }
- }
-}
diff --git a/src/app/Mail/WalletCharge.php b/src/app/Mail/WalletCharge.php
new file mode 100644
--- /dev/null
+++ b/src/app/Mail/WalletCharge.php
@@ -0,0 +1,73 @@
+<?php
+
+namespace App\Mail;
+
+use App\Wallet;
+use Illuminate\Bus\Queueable;
+use Illuminate\Mail\Mailable;
+use Illuminate\Queue\SerializesModels;
+
+class WalletCharge extends Mailable
+{
+ use Queueable;
+ use SerializesModels;
+
+ public const TOPUP_NONE = 0;
+ public const TOPUP_INIT = 1;
+ public const TOPUP_NOTENOUGH = 2;
+
+ /** @var Wallet A wallet that has been charged */
+ protected $wallet;
+
+ /** @var array Additional parameters */
+ protected $params;
+
+
+ /**
+ * Create a new message instance.
+ *
+ * @param \App\Wallet $wallet A wallet that has been charged
+ * @param array $params Additional parameters
+ *
+ * @return void
+ */
+ public function __construct(Wallet $wallet, array $params = [])
+ {
+ $this->wallet = $wallet;
+ $this->params = $params;
+ }
+
+ /**
+ * Build the message.
+ *
+ * @return $this
+ */
+ public function build()
+ {
+ $user = $this->wallet->owner;
+
+ $subject = \trans('mail.walletcharge-subject', ['site' => \config('app.name')]);
+
+ $view = 'emails.walletcharge';
+
+ switch ($this->params['type'] ?? self::TOPUP_NONE) {
+ case self::TOPUP_INIT:
+ $view = 'emails.walletcharge-topup-init';
+ break;
+ case self::TOPUP_NOTENOUGH:
+ $view = 'emails.walletcharge-topup-notenough';
+ break;
+ }
+
+ $this->view($view)
+ ->subject($subject)
+ ->with([
+ 'site' => \config('app.name'),
+ 'username' => $user->name(true),
+ 'balance' => $this->wallet->money($this->params['balance'] ?? 0),
+ 'charged' => $this->wallet->money($this->params['charged'] ?? 0),
+ ]);
+
+ return $this;
+ }
+}
diff --git a/src/app/Wallet.php b/src/app/Wallet.php
--- a/src/app/Wallet.php
+++ b/src/app/Wallet.php
@@ -118,6 +118,28 @@
return $this->chargeEntitlements(false);
}
+ /**
+ * A helper to display human-readable amount of money using
+ * the wallet currency and specified locale.
+ *
+ * @param int $amount A amount of money (in cents)
+ * @param string $locale A locale for the output
+ *
+ * @return string String representation, e.g. "9.99 CHF"
+ */
+ public function money(int $amount, $locale = 'de_DE')
+ {
+ $amount = round($amount / 100, 2);
+
+ // Prefer intl extension's number formatter
+ if (class_exists('NumberFormatter')) {
+ $nf = new \NumberFormatter($locale, \NumberFormatter::DECIMAL);
+ return $nf->formatCurrency($amount, $this->currency);
+ }
+
+ return sprintf('%.2f %s', $amount, $this->currency);
+ }
+
/**
* Remove a controller from this wallet.
*
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Mon, Apr 6, 1:28 PM (8 h, 20 m ago)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
18837648
Default Alt Text
D1249.1775482101.diff (10 KB)
Attached To
Mode
D1249: Wallet charge: top-ups and notifications
Attached
Detach File
Event Timeline