Page Menu
Home
Phorge
Search
Configure Global Search
Log In
Files
F117741796
D1366.1775165160.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Flag For Later
Award Token
Authored By
Unknown
Size
19 KB
Referenced Files
None
Subscribers
None
D1366.1775165160.diff
View Options
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
Details
Attached
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)
Attached To
Mode
D1366: Fix transaction description for domain entitlements
Attached
Detach File
Event Timeline