Page MenuHomePhorge

D1366.1775165160.diff
No OneTemporary

Authored By
Unknown
Size
19 KB
Referenced Files
None
Subscribers
None

D1366.1775165160.diff

diff --git a/src/app/Console/Commands/WalletTransactions.php b/src/app/Console/Commands/WalletTransactions.php
--- a/src/app/Console/Commands/WalletTransactions.php
+++ b/src/app/Console/Commands/WalletTransactions.php
@@ -60,9 +60,8 @@
foreach ($elements as $element) {
$this->info(
sprintf(
- " + %s: %s %s",
+ " + %s: %s",
$element->id,
- $element->created_at,
$element->toString()
)
);
diff --git a/src/app/Entitlement.php b/src/app/Entitlement.php
--- a/src/app/Entitlement.php
+++ b/src/app/Entitlement.php
@@ -85,7 +85,6 @@
{
$transaction = \App\Transaction::create(
[
- 'user_email' => \App\Utils::userEmailOrNull(),
'object_id' => $this->id,
'object_type' => \App\Entitlement::class,
'type' => $type,
@@ -106,6 +105,22 @@
return $this->morphTo()->withTrashed();
}
+ /**
+ * Returns entitleable object title (e.g. email or domain name).
+ *
+ * @return string|null An object title/name
+ */
+ public function entitleableTitle(): ?string
+ {
+ if ($this->entitleable instanceof \App\User) {
+ return $this->entitleable->email;
+ }
+
+ if ($this->entitleable instanceof \App\Domain) {
+ return $this->entitleable->namespace;
+ }
+ }
+
/**
* The SKU concerned.
*
diff --git a/src/app/Observers/TransactionObserver.php b/src/app/Observers/TransactionObserver.php
--- a/src/app/Observers/TransactionObserver.php
+++ b/src/app/Observers/TransactionObserver.php
@@ -22,5 +22,9 @@
break;
}
}
+
+ if (!isset($transaction->user_email)) {
+ $transaction->user_email = \App\Utils::userEmailOrNull();
+ }
}
}
diff --git a/src/app/Transaction.php b/src/app/Transaction.php
--- a/src/app/Transaction.php
+++ b/src/app/Transaction.php
@@ -2,6 +2,8 @@
namespace App;
+use App\Entitlement;
+use App\Wallet;
use Illuminate\Database\Eloquent\Model;
/**
@@ -18,6 +20,15 @@
*/
class Transaction extends Model
{
+ public const ENTITLEMENT_BILLED = 'billed';
+ public const ENTITLEMENT_CREATED = 'created';
+ public const ENTITLEMENT_DELETED = 'deleted';
+
+ public const WALLET_AWARD = 'award';
+ public const WALLET_CREDIT = 'credit';
+ public const WALLET_DEBIT = 'debit';
+ public const WALLET_PENALTY = 'penalty';
+
protected $fillable = [
// actor, if any
'user_email',
@@ -49,25 +60,27 @@
/** @var string The type of the primary key */
protected $keyType = 'string';
- public const ENTITLEMENT_BILLED = 'billed';
- public const ENTITLEMENT_CREATED = 'created';
- public const ENTITLEMENT_DELETED = 'deleted';
- public const WALLET_AWARD = 'award';
- public const WALLET_CREDIT = 'credit';
- public const WALLET_DEBIT = 'debit';
- public const WALLET_PENALTY = 'penalty';
-
- public function entitlement()
+ /**
+ * Returns the entitlement to which the transaction is assigned (if any)
+ *
+ * @return \App\Entitlement|null The entitlement
+ */
+ public function entitlement(): ?Entitlement
{
- if ($this->object_type !== \App\Entitlement::class) {
+ if ($this->object_type !== Entitlement::class) {
return null;
}
- return \App\Entitlement::withTrashed()->where('id', $this->object_id)->first();
+ return Entitlement::withTrashed()->find($this->object_id);
}
- public function setTypeAttribute($value)
+ /**
+ * Transaction type mutator
+ *
+ * @throws \Exception
+ */
+ public function setTypeAttribute($value): void
{
switch ($value) {
case self::ENTITLEMENT_BILLED:
@@ -90,120 +103,72 @@
}
}
- public function toArray()
- {
- $result = [
- 'user_email' => $this->user_email,
- 'entitlement_cost' => $this->getEntitlementCost(),
- 'object_email' => $this->getEntitlementObjectEmail(),
- 'sku_title' => $this->getEntitlementSkuTitle(),
- 'wallet_description' => $this->getWalletDescription(),
- 'description' => $this->{'description'},
- 'amount' => $this->amount
- ];
-
- return $result;
- }
-
- public function toString()
- {
- $label = $this->objectTypeToLabelString() . '-' . $this->{'type'};
-
- return \trans("transactions.{$label}", $this->toArray());
- }
-
- public function shortDescription()
- {
- $label = $this->objectTypeToLabelString() . '-' . $this->{'type'} . '-short';
-
- return \trans("transactions.{$label}", $this->toArray());
- }
-
- public function wallet()
- {
- if ($this->object_type !== \App\Wallet::class) {
- return null;
- }
-
- return \App\Wallet::where('id', $this->object_id)->first();
- }
-
/**
- * Return the costs for this entitlement.
+ * Returns a short text describing the transaction.
*
- * @return int|null
+ * @return string The description
*/
- private function getEntitlementCost(): ?int
+ public function shortDescription(): string
{
- if (!$this->entitlement()) {
- return null;
- }
-
- // FIXME: without wallet discount
- // FIXME: in cents
- // FIXME: without wallet currency
- $cost = $this->entitlement()->cost;
-
- $discount = $this->entitlement()->wallet->getDiscountRate();
+ $label = $this->objectTypeToLabelString() . '-' . $this->{'type'} . '-short';
- return $cost * $discount;
+ return \trans("transactions.{$label}", $this->descriptionParams());
}
/**
- * Return the object email if any. This is the email for the target user entitlement.
+ * Returns a text describing the transaction.
*
- * @return string|null
+ * @return string The description
*/
- private function getEntitlementObjectEmail(): ?string
+ public function toString(): string
{
- $entitlement = $this->entitlement();
-
- if (!$entitlement) {
- return null;
- }
-
- $entitleable = $entitlement->entitleable;
-
- if (!$entitleable) {
- \Log::debug("No entitleable for {$entitlement->id} ?");
- return null;
- }
+ $label = $this->objectTypeToLabelString() . '-' . $this->{'type'};
- return $entitleable->email;
+ return \trans("transactions.{$label}", $this->descriptionParams());
}
/**
- * Return the title for the SKU this entitlement is for.
+ * Returns a wallet to which the transaction is assigned (if any)
*
- * @return string|null
+ * @return \App\Wallet|null The wallet
*/
- private function getEntitlementSkuTitle(): ?string
+ public function wallet(): ?Wallet
{
- if (!$this->entitlement()) {
+ if ($this->object_type !== Wallet::class) {
return null;
}
- return $this->entitlement()->sku->{'title'};
+ return Wallet::find($this->object_id);
}
/**
- * Return the description for the wallet, if any, or 'default wallet'.
+ * Collect transaction parameters used in (localized) descriptions
*
- * @return string
+ * @return array Parameters
*/
- public function getWalletDescription()
+ private function descriptionParams(): array
{
- $description = null;
+ $result = [
+ 'user_email' => $this->user_email,
+ 'description' => $this->{'description'},
+ ];
if ($entitlement = $this->entitlement()) {
- $description = $entitlement->wallet->{'description'};
+ $wallet = $entitlement->wallet;
+ $cost = $entitlement->cost;
+ $discount = $entitlement->wallet->getDiscountRate();
+
+ $result['entitlement_cost'] = $cost * $discount;
+ $result['object'] = $entitlement->entitleableTitle();
+ $result['sku_title'] = $entitlement->sku->{'title'};
+ } else {
+ $wallet = $this->wallet();
}
- if ($wallet = $this->wallet()) {
- $description = $wallet->{'description'};
- }
+ $result['wallet'] = $wallet->{'description'} ?: 'Default wallet';
+ $result['amount'] = $wallet->money($this->amount);
- return $description ?: 'Default wallet';
+ return $result;
}
/**
@@ -213,11 +178,11 @@
*/
private function objectTypeToLabelString(): ?string
{
- if ($this->object_type == \App\Entitlement::class) {
+ if ($this->object_type == Entitlement::class) {
return 'entitlement';
}
- if ($this->object_type == \App\Wallet::class) {
+ if ($this->object_type == Wallet::class) {
return 'wallet';
}
diff --git a/src/app/Wallet.php b/src/app/Wallet.php
--- a/src/app/Wallet.php
+++ b/src/app/Wallet.php
@@ -211,7 +211,6 @@
\App\Transaction::create(
[
- 'user_email' => \App\Utils::userEmailOrNull(),
'object_id' => $this->id,
'object_type' => \App\Wallet::class,
'type' => \App\Transaction::WALLET_CREDIT,
@@ -243,7 +242,6 @@
$transaction = \App\Transaction::create(
[
- 'user_email' => \App\Utils::userEmailOrNull(),
'object_id' => $this->id,
'object_type' => \App\Wallet::class,
'type' => \App\Transaction::WALLET_DEBIT,
diff --git a/src/resources/lang/en/transactions.php b/src/resources/lang/en/transactions.php
--- a/src/resources/lang/en/transactions.php
+++ b/src/resources/lang/en/transactions.php
@@ -1,18 +1,18 @@
<?php
return [
- 'entitlement-created' => ':user_email created :sku_title for :object_email',
- 'entitlement-billed' => ':sku_title for :object_email is billed at :amount',
- 'entitlement-deleted' => ':user_email deleted :sku_title for :object_email',
+ 'entitlement-created' => ':user_email created :sku_title for :object',
+ 'entitlement-billed' => ':sku_title for :object is billed at :amount',
+ 'entitlement-deleted' => ':user_email deleted :sku_title for :object',
- 'wallet-award' => 'Bonus of :amount awarded to :wallet_description; :description',
- 'wallet-credit' => ':amount was added to the balance of :wallet_description',
- 'wallet-debit' => ':amount was deducted from the balance of :wallet_description',
- 'wallet-penalty' => 'The balance of wallet :wallet_description was reduced by :amount; :description',
+ 'wallet-award' => 'Bonus of :amount awarded to :wallet; :description',
+ 'wallet-credit' => ':amount was added to the balance of :wallet',
+ 'wallet-debit' => ':amount was deducted from the balance of :wallet',
+ 'wallet-penalty' => 'The balance of :wallet was reduced by :amount; :description',
- 'entitlement-created-short' => 'Added :sku_title for :object_email',
- 'entitlement-billed-short' => 'Billed :sku_title for :object_email',
- 'entitlement-deleted-short' => 'Deleted :sku_title for :object_email',
+ 'entitlement-created-short' => 'Added :sku_title for :object',
+ 'entitlement-billed-short' => 'Billed :sku_title for :object',
+ 'entitlement-deleted-short' => 'Deleted :sku_title for :object',
'wallet-award-short' => 'Bonus: :description',
'wallet-credit-short' => 'Payment',
diff --git a/src/tests/Unit/TransactionTest.php b/src/tests/Unit/TransactionTest.php
--- a/src/tests/Unit/TransactionTest.php
+++ b/src/tests/Unit/TransactionTest.php
@@ -2,58 +2,180 @@
namespace Tests\Unit;
+use App\Entitlement;
+use App\Sku;
use App\Transaction;
+use App\Wallet;
use Tests\TestCase;
class TransactionTest extends TestCase
{
- public function setUp(): void
+ /**
+ * Test transaction short and long labels
+ */
+ public function testLabels(): void
{
- parent::setUp();
- }
+ // Prepare test environment
+ Transaction::where('amount', '<', 20)->delete();
+ $user = $this->getTestUser('jane@kolabnow.com');
+ $wallet = $user->wallets()->first();
- public function tearDown(): void
- {
- parent::tearDown();
- }
+ // Create transactions
- public function testLabel()
- {
- $transactions = Transaction::limit(20)->get();
+ $transaction = Transaction::create([
+ 'object_id' => $wallet->id,
+ 'object_type' => Wallet::class,
+ 'type' => Transaction::WALLET_PENALTY,
+ 'amount' => 9,
+ 'description' => "A test penalty"
+ ]);
- foreach ($transactions as $transaction) {
- $this->assertNotNull($transaction->toString());
- }
- }
+ $transaction = Transaction::create([
+ 'object_id' => $wallet->id,
+ 'object_type' => Wallet::class,
+ 'type' => Transaction::WALLET_DEBIT,
+ 'amount' => 10
+ ]);
- public function testWalletPenalty()
- {
- $user = $this->getTestUser('jane@kolabnow.com');
- $wallet = $user->wallets()->first();
+ $transaction = Transaction::create([
+ 'object_id' => $wallet->id,
+ 'object_type' => Wallet::class,
+ 'type' => Transaction::WALLET_CREDIT,
+ 'amount' => 11
+ ]);
- $transaction = Transaction::create(
- [
+ $transaction = Transaction::create([
'object_id' => $wallet->id,
- 'object_type' => \App\Wallet::class,
- 'type' => Transaction::WALLET_PENALTY,
- 'amount' => 9
- ]
+ 'object_type' => Wallet::class,
+ 'type' => Transaction::WALLET_AWARD,
+ 'amount' => 12,
+ 'description' => "A test award"
+ ]);
+
+ $sku = Sku::where('title', 'mailbox')->first();
+ $entitlement = Entitlement::where('sku_id', $sku->id)->first();
+ $transaction = Transaction::create([
+ 'user_email' => 'test@test.com',
+ 'object_id' => $entitlement->id,
+ 'object_type' => Entitlement::class,
+ 'type' => Transaction::ENTITLEMENT_CREATED,
+ 'amount' => 13
+ ]);
+
+ $sku = Sku::where('title', 'domain-hosting')->first();
+ $entitlement = Entitlement::where('sku_id', $sku->id)->first();
+ $transaction = Transaction::create([
+ 'user_email' => 'test@test.com',
+ 'object_id' => $entitlement->id,
+ 'object_type' => Entitlement::class,
+ 'type' => Transaction::ENTITLEMENT_BILLED,
+ 'amount' => 14
+ ]);
+
+ $sku = Sku::where('title', 'storage')->first();
+ $entitlement = Entitlement::where('sku_id', $sku->id)->first();
+ $transaction = Transaction::create([
+ 'user_email' => 'test@test.com',
+ 'object_id' => $entitlement->id,
+ 'object_type' => Entitlement::class,
+ 'type' => Transaction::ENTITLEMENT_DELETED,
+ 'amount' => 15
+ ]);
+
+ $transactions = Transaction::where('amount', '<', 20)->orderBy('amount')->get();
+
+ $this->assertSame(9, $transactions[0]->amount);
+ $this->assertSame(Transaction::WALLET_PENALTY, $transactions[0]->type);
+ $this->assertSame(
+ "The balance of Default wallet was reduced by 0,09 CHF; A test penalty",
+ $transactions[0]->toString()
+ );
+ $this->assertSame(
+ "Charge: A test penalty",
+ $transactions[0]->shortDescription()
+ );
+
+ $this->assertSame(10, $transactions[1]->amount);
+ $this->assertSame(Transaction::WALLET_DEBIT, $transactions[1]->type);
+ $this->assertSame(
+ "0,10 CHF was deducted from the balance of Default wallet",
+ $transactions[1]->toString()
+ );
+ $this->assertSame(
+ "Deduction",
+ $transactions[1]->shortDescription()
+ );
+
+ $this->assertSame(11, $transactions[2]->amount);
+ $this->assertSame(Transaction::WALLET_CREDIT, $transactions[2]->type);
+ $this->assertSame(
+ "0,11 CHF was added to the balance of Default wallet",
+ $transactions[2]->toString()
+ );
+ $this->assertSame(
+ "Payment",
+ $transactions[2]->shortDescription()
+ );
+
+ $this->assertSame(12, $transactions[3]->amount);
+ $this->assertSame(Transaction::WALLET_AWARD, $transactions[3]->type);
+ $this->assertSame(
+ "Bonus of 0,12 CHF awarded to Default wallet; A test award",
+ $transactions[3]->toString()
+ );
+ $this->assertSame(
+ "Bonus: A test award",
+ $transactions[3]->shortDescription()
);
- $this->assertEquals($transaction->{'type'}, Transaction::WALLET_PENALTY);
+ $ent = $transactions[4]->entitlement();
+ $this->assertSame(13, $transactions[4]->amount);
+ $this->assertSame(Transaction::ENTITLEMENT_CREATED, $transactions[4]->type);
+ $this->assertSame(
+ "test@test.com created mailbox for " . $ent->entitleableTitle(),
+ $transactions[4]->toString()
+ );
+ $this->assertSame(
+ "Added mailbox for " . $ent->entitleableTitle(),
+ $transactions[4]->shortDescription()
+ );
+
+ $ent = $transactions[5]->entitlement();
+ $this->assertSame(14, $transactions[5]->amount);
+ $this->assertSame(Transaction::ENTITLEMENT_BILLED, $transactions[5]->type);
+ $this->assertSame(
+ sprintf("%s for %s is billed at 0,14 CHF", $ent->sku->title, $ent->entitleableTitle()),
+ $transactions[5]->toString()
+ );
+ $this->assertSame(
+ sprintf("Billed %s for %s", $ent->sku->title, $ent->entitleableTitle()),
+ $transactions[5]->shortDescription()
+ );
+
+ $ent = $transactions[6]->entitlement();
+ $this->assertSame(15, $transactions[6]->amount);
+ $this->assertSame(Transaction::ENTITLEMENT_DELETED, $transactions[6]->type);
+ $this->assertSame(
+ sprintf("test@test.com deleted %s for %s", $ent->sku->title, $ent->entitleableTitle()),
+ $transactions[6]->toString()
+ );
+ $this->assertSame(
+ sprintf("Deleted %s for %s", $ent->sku->title, $ent->entitleableTitle()),
+ $transactions[6]->shortDescription()
+ );
}
- public function testInvalidType()
+ /**
+ * Test that an exception is being thrown on invalid type
+ */
+ public function testInvalidType(): void
{
- $user = $this->getTestUser('jane@kolabnow.com');
- $wallet = $user->wallets()->first();
-
$this->expectException(\Exception::class);
$transaction = Transaction::create(
[
- 'object_id' => $wallet->id,
- 'object_type' => \App\Wallet::class,
+ 'object_id' => 'fake-id',
+ 'object_type' => Wallet::class,
'type' => 'invalid',
'amount' => 9
]

File Metadata

Mime Type
text/plain
Expires
Thu, Apr 2, 9:26 PM (3 d, 1 h ago)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
18820959
Default Alt Text
D1366.1775165160.diff (19 KB)

Event Timeline