diff --git a/backend/app/DomainObjects/ProductPriceDomainObject.php b/backend/app/DomainObjects/ProductPriceDomainObject.php index 0919781ec1..97ee5ee23b 100644 --- a/backend/app/DomainObjects/ProductPriceDomainObject.php +++ b/backend/app/DomainObjects/ProductPriceDomainObject.php @@ -113,4 +113,9 @@ public function getOffSaleReason(): ?string { return $this->offSaleReason; } + + public function isFree(): bool + { + return $this->getPrice() === 0.00; + } } diff --git a/backend/app/Services/Domain/Order/OrderItemProcessingService.php b/backend/app/Services/Domain/Order/OrderItemProcessingService.php index f0b784b556..d047f78d1e 100644 --- a/backend/app/Services/Domain/Order/OrderItemProcessingService.php +++ b/backend/app/Services/Domain/Order/OrderItemProcessingService.php @@ -19,13 +19,13 @@ use Illuminate\Support\Collection; use Symfony\Component\Routing\Exception\ResourceNotFoundException; -readonly class OrderItemProcessingService +class OrderItemProcessingService { public function __construct( - private OrderRepositoryInterface $orderRepository, - private ProductRepositoryInterface $productRepository, - private TaxAndFeeCalculationService $taxCalculationService, - private ProductPriceService $productPriceService, + private readonly OrderRepositoryInterface $orderRepository, + private readonly ProductRepositoryInterface $productRepository, + private readonly TaxAndFeeCalculationService $taxCalculationService, + private readonly ProductPriceService $productPriceService, ) { } diff --git a/backend/app/Services/Domain/Product/ProductFilterService.php b/backend/app/Services/Domain/Product/ProductFilterService.php index 099cdb7845..f8dcd8f1b3 100644 --- a/backend/app/Services/Domain/Product/ProductFilterService.php +++ b/backend/app/Services/Domain/Product/ProductFilterService.php @@ -162,12 +162,15 @@ private function filterProduct( private function processProductPrice(ProductDomainObject $product, ProductPriceDomainObject $price): void { - $taxAndFees = $this->taxCalculationService - ->calculateTaxAndFeesForProductPrice($product, $price); - - $price - ->setTaxTotal(Currency::round($taxAndFees->taxTotal)) - ->setFeeTotal(Currency::round($taxAndFees->feeTotal)); + // If the product is free of charge, we don't charge service fees or taxes + if (!$price->isFree()) { + $taxAndFees = $this->taxCalculationService + ->calculateTaxAndFeesForProductPrice($product, $price); + + $price + ->setTaxTotal(Currency::round($taxAndFees->taxTotal)) + ->setFeeTotal(Currency::round($taxAndFees->feeTotal)); + } $price->setIsAvailable($this->getPriceAvailability($price, $product)); } diff --git a/backend/app/Services/Domain/Tax/TaxAndFeeCalculationService.php b/backend/app/Services/Domain/Tax/TaxAndFeeCalculationService.php index f3343269bf..ac9c11da4f 100644 --- a/backend/app/Services/Domain/Tax/TaxAndFeeCalculationService.php +++ b/backend/app/Services/Domain/Tax/TaxAndFeeCalculationService.php @@ -3,9 +3,9 @@ namespace HiEvents\Services\Domain\Tax; use HiEvents\DomainObjects\Enums\TaxCalculationType; -use HiEvents\DomainObjects\TaxAndFeesDomainObject; use HiEvents\DomainObjects\ProductDomainObject; use HiEvents\DomainObjects\ProductPriceDomainObject; +use HiEvents\DomainObjects\TaxAndFeesDomainObject; use HiEvents\Services\Domain\Tax\DTO\TaxCalculationResponse; use InvalidArgumentException; @@ -49,6 +49,13 @@ public function calculateTaxAndFeesForProduct( private function calculateFee(TaxAndFeesDomainObject $taxOrFee, float $price, int $quantity): float { + // We do not charge a tax or fee on items which are free of charge + if ($price === 0.00) { + $this->taxRollupService->addToRollUp($taxOrFee, 0); + + return 0.00; + } + $amount = match ($taxOrFee->getCalculationType()) { TaxCalculationType::FIXED->name => $taxOrFee->getRate(), TaxCalculationType::PERCENTAGE->name => ($price * $taxOrFee->getRate()) / 100,