Skip to content

Commit 075d1ca

Browse files
authored
Feature: Platform fee updates (#958)
1 parent 7c8d10b commit 075d1ca

File tree

46 files changed

+3129
-1230
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

46 files changed

+3129
-1230
lines changed

backend/app/Services/Domain/Order/OrderItemProcessingService.php

Lines changed: 89 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,20 @@
22

33
namespace HiEvents\Services\Domain\Order;
44

5+
use HiEvents\DomainObjects\AccountConfigurationDomainObject;
6+
use HiEvents\DomainObjects\Enums\TaxCalculationType;
57
use HiEvents\DomainObjects\EventDomainObject;
8+
use HiEvents\DomainObjects\EventSettingDomainObject;
69
use HiEvents\DomainObjects\Generated\ProductDomainObjectAbstract;
710
use HiEvents\DomainObjects\OrderDomainObject;
811
use HiEvents\DomainObjects\ProductDomainObject;
912
use HiEvents\DomainObjects\ProductPriceDomainObject;
1013
use HiEvents\DomainObjects\PromoCodeDomainObject;
1114
use HiEvents\DomainObjects\TaxAndFeesDomainObject;
1215
use HiEvents\Helper\Currency;
16+
use HiEvents\Repository\Eloquent\Value\Relationship;
17+
use HiEvents\Repository\Interfaces\AccountRepositoryInterface;
18+
use HiEvents\Repository\Interfaces\EventRepositoryInterface;
1319
use HiEvents\Repository\Interfaces\OrderRepositoryInterface;
1420
use HiEvents\Repository\Interfaces\ProductRepositoryInterface;
1521
use HiEvents\Services\Application\Handlers\Order\DTO\ProductOrderDetailsDTO;
@@ -21,11 +27,17 @@
2127

2228
class OrderItemProcessingService
2329
{
30+
private ?AccountConfigurationDomainObject $accountConfiguration = null;
31+
private ?EventSettingDomainObject $eventSettings = null;
32+
2433
public function __construct(
25-
private readonly OrderRepositoryInterface $orderRepository,
26-
private readonly ProductRepositoryInterface $productRepository,
27-
private readonly TaxAndFeeCalculationService $taxCalculationService,
28-
private readonly ProductPriceService $productPriceService,
34+
private readonly OrderRepositoryInterface $orderRepository,
35+
private readonly ProductRepositoryInterface $productRepository,
36+
private readonly TaxAndFeeCalculationService $taxCalculationService,
37+
private readonly ProductPriceService $productPriceService,
38+
private readonly OrderPlatformFeePassThroughService $platformFeeService,
39+
private readonly AccountRepositoryInterface $accountRepository,
40+
private readonly EventRepositoryInterface $eventRepository,
2941
)
3042
{
3143
}
@@ -44,6 +56,8 @@ public function process(
4456
?PromoCodeDomainObject $promoCode
4557
): Collection
4658
{
59+
$this->loadPlatformFeeConfiguration($event->getId());
60+
4761
$orderItems = collect();
4862

4963
foreach ($productsOrderDetails as $productOrderDetail) {
@@ -61,23 +75,42 @@ public function process(
6175
);
6276
}
6377

64-
$productOrderDetail->quantities->each(function (OrderProductPriceDTO $productPrice) use ($promoCode, $order, $orderItems, $product) {
78+
$productOrderDetail->quantities->each(function (OrderProductPriceDTO $productPrice) use ($promoCode, $order, $orderItems, $product, $event) {
6579
if ($productPrice->quantity === 0) {
6680
return;
6781
}
68-
$orderItemData = $this->calculateOrderItemData($product, $productPrice, $order, $promoCode);
82+
$orderItemData = $this->calculateOrderItemData($product, $productPrice, $order, $promoCode, $event->getCurrency());
6983
$orderItems->push($this->orderRepository->addOrderItem($orderItemData));
7084
});
7185
}
7286

7387
return $orderItems;
7488
}
7589

90+
private function loadPlatformFeeConfiguration(int $eventId): void
91+
{
92+
$account = $this->accountRepository
93+
->loadRelation(new Relationship(
94+
domainObject: AccountConfigurationDomainObject::class,
95+
name: 'configuration',
96+
))
97+
->findByEventId($eventId);
98+
99+
$this->accountConfiguration = $account->getConfiguration();
100+
101+
$event = $this->eventRepository
102+
->loadRelation(EventSettingDomainObject::class)
103+
->findById($eventId);
104+
105+
$this->eventSettings = $event->getEventSettings();
106+
}
107+
76108
private function calculateOrderItemData(
77109
ProductDomainObject $product,
78110
OrderProductPriceDTO $productPriceDetails,
79111
OrderDomainObject $order,
80-
?PromoCodeDomainObject $promoCode
112+
?PromoCodeDomainObject $promoCode,
113+
string $currency
81114
): array
82115
{
83116
$prices = $this->productPriceService->getPrice($product, $productPriceDetails, $promoCode);
@@ -92,6 +125,23 @@ private function calculateOrderItemData(
92125
quantity: $productPriceDetails->quantity
93126
);
94127

128+
$totalTax = $taxesAndFees->taxTotal;
129+
$totalFee = $taxesAndFees->feeTotal;
130+
$rollUp = $taxesAndFees->rollUp;
131+
132+
$platformFee = $this->calculatePlatformFee(
133+
$itemTotalWithDiscount + $taxesAndFees->feeTotal + $taxesAndFees->taxTotal,
134+
$productPriceDetails->quantity,
135+
$currency
136+
);
137+
138+
if ($platformFee > 0) {
139+
$totalFee += $platformFee;
140+
$rollUp = $this->addPlatformFeeToRollup($rollUp, $platformFee);
141+
}
142+
143+
$totalGross = Currency::round($itemTotalWithDiscount + $totalTax + $totalFee);
144+
95145
return [
96146
'product_type' => $product->getProductType(),
97147
'product_id' => $product->getId(),
@@ -102,13 +152,41 @@ private function calculateOrderItemData(
102152
'price' => $priceWithDiscount,
103153
'order_id' => $order->getId(),
104154
'item_name' => $this->getOrderItemLabel($product, $productPriceDetails->price_id),
105-
'total_tax' => $taxesAndFees->taxTotal,
106-
'total_service_fee' => $taxesAndFees->feeTotal,
107-
'total_gross' => Currency::round($itemTotalWithDiscount + $taxesAndFees->taxTotal + $taxesAndFees->feeTotal),
108-
'taxes_and_fees_rollup' => $taxesAndFees->rollUp,
155+
'total_tax' => $totalTax,
156+
'total_service_fee' => $totalFee,
157+
'total_gross' => $totalGross,
158+
'taxes_and_fees_rollup' => $rollUp,
109159
];
110160
}
111161

162+
private function calculatePlatformFee(float $total, int $quantity, string $currency): float
163+
{
164+
if ($this->accountConfiguration === null || $this->eventSettings === null) {
165+
return 0.0;
166+
}
167+
168+
return $this->platformFeeService->calculatePlatformFee(
169+
$this->accountConfiguration,
170+
$this->eventSettings,
171+
$total,
172+
$quantity,
173+
$currency,
174+
);
175+
}
176+
177+
private function addPlatformFeeToRollup(array $rollUp, float $platformFee): array
178+
{
179+
$rollUp['fees'] ??= [];
180+
$rollUp['fees'][] = [
181+
'name' => OrderPlatformFeePassThroughService::getPlatformFeeName(),
182+
'rate' => $platformFee,
183+
'type' => TaxCalculationType::FIXED->name,
184+
'value' => $platformFee,
185+
];
186+
187+
return $rollUp;
188+
}
189+
112190
private function getOrderItemLabel(ProductDomainObject $product, int $priceId): string
113191
{
114192
if ($product->isTieredType()) {

backend/app/Services/Domain/Order/OrderManagementService.php

Lines changed: 5 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -3,32 +3,23 @@
33
namespace HiEvents\Services\Domain\Order;
44

55
use Carbon\Carbon;
6-
use HiEvents\DomainObjects\AccountConfigurationDomainObject;
76
use HiEvents\DomainObjects\AffiliateDomainObject;
8-
use HiEvents\DomainObjects\Enums\TaxCalculationType;
97
use HiEvents\DomainObjects\EventDomainObject;
10-
use HiEvents\DomainObjects\EventSettingDomainObject;
118
use HiEvents\DomainObjects\Generated\OrderDomainObjectAbstract;
129
use HiEvents\DomainObjects\OrderDomainObject;
1310
use HiEvents\DomainObjects\OrderItemDomainObject;
1411
use HiEvents\DomainObjects\PromoCodeDomainObject;
1512
use HiEvents\DomainObjects\Status\OrderStatus;
1613
use HiEvents\Helper\IdHelper;
17-
use HiEvents\Repository\Eloquent\Value\Relationship;
18-
use HiEvents\Repository\Interfaces\AccountRepositoryInterface;
19-
use HiEvents\Repository\Interfaces\EventRepositoryInterface;
2014
use HiEvents\Repository\Interfaces\OrderRepositoryInterface;
2115
use HiEvents\Services\Domain\Tax\TaxAndFeeOrderRollupService;
2216
use Illuminate\Support\Collection;
2317

2418
class OrderManagementService
2519
{
2620
public function __construct(
27-
readonly private OrderRepositoryInterface $orderRepository,
28-
readonly private TaxAndFeeOrderRollupService $taxAndFeeOrderRollupService,
29-
readonly private OrderPlatformFeePassThroughService $platformFeeService,
30-
readonly private AccountRepositoryInterface $accountRepository,
31-
readonly private EventRepositoryInterface $eventRepository,
21+
readonly private OrderRepositoryInterface $orderRepository,
22+
readonly private TaxAndFeeOrderRollupService $taxAndFeeOrderRollupService,
3223
)
3324
{
3425
}
@@ -70,6 +61,9 @@ public function createNewOrder(
7061
}
7162

7263
/**
64+
* Update order totals by summing up all order items.
65+
* Platform fee and its tax are included at the item level.
66+
*
7367
* @param OrderDomainObject $order
7468
* @param Collection<OrderItemDomainObject> $orderItems
7569
* @return OrderDomainObject
@@ -90,21 +84,6 @@ public function updateOrderTotals(OrderDomainObject $order, Collection $orderIte
9084

9185
$rollup = $this->taxAndFeeOrderRollupService->rollup($orderItems);
9286

93-
$platformFee = $order->getIsManuallyCreated()
94-
? 0.0
95-
: $this->calculatePlatformFee($order->getEventId(), $orderItems, $order->getCurrency());
96-
97-
if ($platformFee > 0) {
98-
$rollup['fees'][] = [
99-
'name' => OrderPlatformFeePassThroughService::getPlatformFeeName(),
100-
'rate' => $platformFee,
101-
'type' => TaxCalculationType::FIXED->name,
102-
'value' => $platformFee,
103-
];
104-
$totalFee += $platformFee;
105-
$totalGross += $platformFee;
106-
}
107-
10887
$this->orderRepository->updateFromArray($order->getId(), [
10988
'total_before_additions' => $totalBeforeAdditions,
11089
'total_tax' => $totalTax,
@@ -117,38 +96,4 @@ public function updateOrderTotals(OrderDomainObject $order, Collection $orderIte
11796
->loadRelation(OrderItemDomainObject::class)
11897
->findById($order->getId());
11998
}
120-
121-
/**
122-
* @param Collection<OrderItemDomainObject> $orderItems
123-
*/
124-
private function calculatePlatformFee(int $eventId, Collection $orderItems, string $currency): float
125-
{
126-
$account = $this->accountRepository
127-
->loadRelation(new Relationship(
128-
domainObject: AccountConfigurationDomainObject::class,
129-
name: 'configuration',
130-
))
131-
->findByEventId($eventId);
132-
133-
$accountConfiguration = $account->getConfiguration();
134-
if ($accountConfiguration === null) {
135-
return 0.0;
136-
}
137-
138-
$event = $this->eventRepository
139-
->loadRelation(EventSettingDomainObject::class)
140-
->findById($eventId);
141-
142-
$eventSettings = $event->getEventSettings();
143-
if ($eventSettings === null) {
144-
return 0.0;
145-
}
146-
147-
return $this->platformFeeService->calculateForOrder(
148-
accountConfiguration: $accountConfiguration,
149-
eventSettings: $eventSettings,
150-
orderItems: $orderItems,
151-
currency: $currency,
152-
);
153-
}
15499
}

0 commit comments

Comments
 (0)