Skip to content

Commit 4718ed3

Browse files
committed
feat: add global charges and discounts
1 parent 9772263 commit 4718ed3

File tree

4 files changed

+88
-7
lines changed

4 files changed

+88
-7
lines changed

src/Carts/SnapshotCart.php

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77

88
namespace Vaened\SwiftCart\Carts;
99

10+
use Vaened\PriceEngine\AdjustmentManager;
1011
use Vaened\SwiftCart\Entities\Identifiable;
1112
use Vaened\SwiftCart\Entities\TradedCommercialTransaction;
1213
use Vaened\SwiftCart\Items\ImmutableCartItem;
@@ -18,12 +19,18 @@ final class SnapshotCart extends SwiftCart
1819
{
1920
private readonly ImmutableCartItems $immutables;
2021

21-
private ImmutableCartItems $items;
22+
private readonly ImmutableCartItems $items;
23+
24+
private readonly AdjustmentManager $charges;
25+
26+
private readonly AdjustmentManager $discounts;
2227

2328
public function __construct(TradedCommercialTransaction $transaction)
2429
{
2530
$this->immutables = $transaction->items()->toImmutables();
2631
$this->items = new ImmutableCartItems([]);
32+
$this->charges = $this->createManagerOf($transaction->charges());
33+
$this->discounts = $this->createManagerOf($transaction->discounts());
2734
}
2835

2936
public function locate(Identifiable $identifiable): ?ImmutableCartItem
@@ -57,6 +64,16 @@ protected function staging(): ImmutableCartItems
5764
return $this->items;
5865
}
5966

67+
protected function globalChargesManager(): AdjustmentManager
68+
{
69+
return $this->charges;
70+
}
71+
72+
protected function globalDiscountsManager(): AdjustmentManager
73+
{
74+
return $this->discounts;
75+
}
76+
6077
private function ensureValidItem(?ImmutableCartItem $item): void
6178
{
6279
if (null === $item) {

src/Carts/SwiftCart.php

Lines changed: 35 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,22 +7,41 @@
77

88
namespace Vaened\SwiftCart\Carts;
99

10+
use Vaened\PriceEngine\AdjustmentManager;
11+
use Vaened\PriceEngine\Adjustments;
12+
use Vaened\PriceEngine\Adjustments\Adjusters;
1013
use Vaened\Support\Types\ArrayList;
1114
use Vaened\SwiftCart\Entities\Identifiable;
12-
use Vaened\SwiftCart\Items\CartItem;
13-
use Vaened\SwiftCart\Items\CartItems;
15+
use Vaened\SwiftCart\Items\{CartItem, CartItems};
1416
use Vaened\SwiftCart\Summary;
1517
use Vaened\SwiftCart\Totalizer;
1618

1719
abstract class SwiftCart
1820
{
19-
abstract public function summary(): Summary;
21+
abstract public function locate(Identifiable $identifiable): ?CartItem;
2022

2123
abstract protected function staging(): CartItems;
2224

23-
public function locate(Identifiable $identifiable): ?CartItem
25+
abstract protected function globalChargesManager(): AdjustmentManager;
26+
27+
abstract protected function globalDiscountsManager(): AdjustmentManager;
28+
29+
public function globalCharges(): Adjustments
30+
{
31+
return $this->syncAdjustments($this->globalChargesManager());
32+
}
33+
34+
public function globalDiscounts(): Adjustments
2435
{
25-
return $this->staging()->locate($identifiable);
36+
return $this->syncAdjustments($this->globalDiscountsManager());
37+
}
38+
39+
public function summary(): Summary
40+
{
41+
return $this->totalizer()->summary(
42+
additionalCharges : $this->globalCharges()->total(),
43+
additionalDiscounts: $this->globalDiscounts()->total(),
44+
);
2645
}
2746

2847
public function has(Identifiable $identifiable): bool
@@ -42,8 +61,19 @@ public function items(): ArrayList
4261
);
4362
}
4463

64+
protected function createManagerOf(Adjusters $adjusters): AdjustmentManager
65+
{
66+
return new AdjustmentManager($adjusters, $this->totalizer()->total(), quantity: 1);
67+
}
68+
4569
protected function totalizer(): Totalizer
4670
{
4771
return $this->staging()->totalizer();
4872
}
73+
74+
private function syncAdjustments(AdjustmentManager $manager): Adjustments
75+
{
76+
$manager->revalue($this->totalizer()->total());
77+
return $manager->adjustments();
78+
}
4979
}

src/Entities/TradedCommercialTransaction.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77

88
namespace Vaened\SwiftCart\Entities;
99

10-
interface TradedCommercialTransaction
10+
interface TradedCommercialTransaction extends Discountable, Chargeable
1111
{
1212
public function items(): TradedCommercialTransactionItems;
1313
}

tests/Utils/Billing/Invoice.php

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,26 +7,60 @@
77

88
namespace Vaened\SwiftCart\Tests\Utils\Billing;
99

10+
use Vaened\PriceEngine\Adjustments\Adjusters;
11+
use Vaened\PriceEngine\Adjustments\Charge;
12+
use Vaened\PriceEngine\Adjustments\Discount;
1013
use Vaened\SwiftCart\Entities\TradedCommercialTransaction;
1114
use Vaened\SwiftCart\Entities\TradedCommercialTransactionItems;
1215

16+
use function Lambdish\Phunctional\each;
17+
1318
final class Invoice implements TradedCommercialTransaction
1419
{
20+
private readonly Adjusters $charges;
21+
22+
private readonly Adjusters $discounts;
23+
1524
public function __construct(
1625
private readonly InvoiceDetailItems $items,
1726
)
1827
{
28+
$this->charges = Adjusters::empty();
29+
$this->discounts = Adjusters::empty();
1930
}
2031

2132
public static function create(InvoiceDetailItems $items): self
2233
{
2334
return new self($items);
2435
}
2536

37+
public function with(Discount|Charge ...$adjusters): self
38+
{
39+
each(function (Discount|Charge $adjuster) {
40+
if ($adjuster instanceof Discount) {
41+
$this->discounts->push($adjuster);
42+
} else {
43+
$this->charges->push($adjuster);
44+
}
45+
}, $adjusters);
46+
47+
return $this;
48+
}
49+
2650
public function items(): TradedCommercialTransactionItems
2751
{
2852
return new TradedCommercialTransactionItems(
2953
$this->items->values()
3054
);
3155
}
56+
57+
public function charges(): Adjusters
58+
{
59+
return $this->charges;
60+
}
61+
62+
public function discounts(): Adjusters
63+
{
64+
return $this->discounts;
65+
}
3266
}

0 commit comments

Comments
 (0)