Skip to content

Commit

Permalink
wip
Browse files Browse the repository at this point in the history
  • Loading branch information
duncanmcclean committed Jan 28, 2025
1 parent 56a956a commit f0decd5
Show file tree
Hide file tree
Showing 22 changed files with 214 additions and 140 deletions.
20 changes: 10 additions & 10 deletions config/simple-commerce.php
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
Calculator\ApplyCouponDiscounts::class,
Calculator\ApplyShipping::class,
Calculator\CalculateTaxes::class,
Calculator\CalculateGrandTotal::class,
Calculator\CalculateTotals::class,
],
],

Expand Down Expand Up @@ -59,17 +59,17 @@
'dummy' => [
//
],
//
// 'stripe' => [
// 'key' => env('STRIPE_KEY'),
// 'secret' => env('STRIPE_SECRET'),
// 'webhook_secret' => env('STRIPE_WEBHOOK_SECRET'),
// ],

'stripe' => [
'key' => env('STRIPE_KEY'),
'secret' => env('STRIPE_SECRET'),
'webhook_secret' => env('STRIPE_WEBHOOK_SECRET'),
'mollie' => [
'api_key' => env('MOLLIE_KEY'),
'profile_id' => env('MOLLIE_PROFILE_ID'),
],

// 'mollie' => [
// 'api_key' => env('MOLLIE_KEY'),
// 'profile_id' => env('MOLLIE_PROFILE_ID'),
// ],
],
],

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
</div>
<div>{{ lineItem.unit_price }}</div>
<div>{{ lineItem.quantity }}</div>
<div>{{ lineItem.total }}</div>
<div>{{ lineItem.sub_total }}</div>

<inline-edit-form
v-if="isEditing"
Expand Down
18 changes: 0 additions & 18 deletions src/Cart/Calculator/CalculateGrandTotal.php

This file was deleted.

5 changes: 2 additions & 3 deletions src/Cart/Calculator/CalculateLineItems.php
Original file line number Diff line number Diff line change
Expand Up @@ -23,13 +23,12 @@ public function handle(Cart $cart, Closure $next)
};

$lineItem->unitPrice($price);
$lineItem->total($price * $lineItem->quantity());
$lineItem->subTotal($price * $lineItem->quantity());
$lineItem->total($lineItem->subTotal());

return $lineItem;
});

$cart->subTotal($cart->lineItems()->map->total()->sum());

return $next($cart);
}
}
34 changes: 34 additions & 0 deletions src/Cart/Calculator/CalculateTotals.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
<?php

namespace DuncanMcClean\SimpleCommerce\Cart\Calculator;

use Closure;
use DuncanMcClean\SimpleCommerce\Cart\Cart;

class CalculateTotals
{
public function handle(Cart $cart, Closure $next)
{
$pricesIncludeTax = config('statamic.simple-commerce.taxes.price_includes_tax');

// Calculate the subtotal by summing the line item subtotals (totals without additional taxes)
$cart->subTotal($cart->lineItems()->map->subTotal()->sum());

// Calculate the total (subtotal + taxes if they aren't included in the prices)
$total = $cart->subTotal();

if (! $pricesIncludeTax) {
$total += $cart->lineItems()->map->taxTotal()->sum();
}

// Apply any discounts to the total before adding shipping.
$total = $total - $cart->discountTotal();

// Add shipping costs to the total
$total += $cart->shippingTotal();

$cart->grandTotal($total);

return $next($cart);
}
}
3 changes: 2 additions & 1 deletion src/Cart/Calculator/ResetTotals.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,10 @@ public function handle(Cart $cart, Closure $next)
$cart->remove('shipping_tax_breakdown');

$cart->lineItems()->transform(function (LineItem $lineItem) {
$lineItem->total(0);
$lineItem->unitPrice(0);
$lineItem->taxTotal(0);
$lineItem->subTotal(0);
$lineItem->total(0);

$lineItem->remove('tax_breakdown');

Expand Down
2 changes: 1 addition & 1 deletion src/Cart/Cart.php
Original file line number Diff line number Diff line change
Expand Up @@ -265,7 +265,7 @@ public function fingerprint(): string
'taxable_state' => $this->taxableAddress()?->state,
'taxable_country' => $this->taxableAddress()?->country,
'taxable_post_code' => $this->taxableAddress()?->postcode,
'config' => config('statamic.simple-commerce.taxes'),
'tax_config' => config('statamic.simple-commerce.taxes'),
];

return sha1(json_encode($payload));
Expand Down
1 change: 1 addition & 0 deletions src/Fieldtypes/OrderReceiptFieldtype.php
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ public function preProcess($data)
] : null,
'unit_price' => Money::format($lineItem->unitPrice(), Site::selected()),
'quantity' => $lineItem->quantity(),
'sub_total' => Money::format($lineItem->subTotal(), Site::selected()),
'total' => Money::format($lineItem->total(), Site::selected()),
])->all(),
'coupon' => $order->coupon() ? [
Expand Down
4 changes: 2 additions & 2 deletions src/Orders/AugmentedLineItem.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@

namespace DuncanMcClean\SimpleCommerce\Orders;

use DuncanMcClean\SimpleCommerce\Fieldtypes\MoneyFieldtype;
use Statamic\Data\AbstractAugmented;
use Statamic\Fields\Value;
use Statamic\Support\Arr;
use Statamic\Support\Str;

class AugmentedLineItem extends AbstractAugmented
Expand Down Expand Up @@ -35,7 +35,7 @@ public function get($handle): Value
{
// These fields have methods on the LineItem class. However, we don't want to call those methods,
// we want to use the underlying properties.
if (in_array($handle, ['product', 'quantity', 'unit_price', 'total', 'tax_total'])) {
if (in_array($handle, ['product', 'quantity', 'unit_price', 'sub_total', 'tax_total', 'total'])) {
$value = new Value(
fn () => $this->data->{Str::camel($handle)},
$handle,
Expand Down
10 changes: 10 additions & 0 deletions src/Orders/AugmentedOrder.php
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ private function commonKeys(): array
'customer',
'coupon',
'shipping_method',
'shipping_option',
'tax_breakdown',
];

Expand Down Expand Up @@ -68,6 +69,15 @@ public function shippingMethod()
];
}

public function shippingOption()
{
if (! $this->data->shippingOption()) {
return null;
}

return $this->data->shippingOption()->toAugmentedArray();
}

public function status()
{
if (! $this->data instanceof Order) {
Expand Down
19 changes: 14 additions & 5 deletions src/Orders/LineItem.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,9 @@ class LineItem
public $variant;
public $quantity;
public $unitPrice;
public $total;
public $subTotal;
public $taxTotal;
public $total;

public function __construct()
{
Expand Down Expand Up @@ -91,10 +92,10 @@ public function unitPrice()
->args(func_get_args());
}

public function total($total = null)
public function subTotal()
{
return $this
->fluentlyGetOrSet('total')
->fluentlyGetOrSet('subTotal')
->args(func_get_args());
}

Expand All @@ -105,14 +106,21 @@ public function taxTotal($taxTotal = null)
->args(func_get_args());
}

public function total($total = null)
{
return $this
->fluentlyGetOrSet('total')
->args(func_get_args());
}

public function defaultAugmentedArrayKeys()
{
return [];
}

public function shallowAugmentedArrayKeys()
{
return ['id', 'product', 'variant', 'quantity', 'unit_price', 'total', 'tax_total'];
return ['id', 'product', 'variant', 'quantity', 'unit_price', 'sub_total', 'tax_total', 'total'];
}

public function newAugmentedInstance(): Augmented
Expand All @@ -133,8 +141,9 @@ public function fileData(): array
'variant' => $this->variant,
'quantity' => $this->quantity,
'unit_price' => $this->unitPrice,
'total' => $this->total,
'sub_total' => $this->subTotal,
'tax_total' => $this->taxTotal,
'total' => $this->total,
])->filter()->all();
}
}
2 changes: 2 additions & 0 deletions src/Orders/LineItemBlueprint.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ public function __invoke(): StatamicBlueprint
'variant' => ['type' => 'text'],
'quantity' => ['type' => 'integer'],
'unit_price' => ['type' => 'money', 'save_zero_value' => true],
'sub_total' => ['type' => 'money', 'save_zero_value' => true],
'tax_total' => ['type' => 'money', 'save_zero_value' => true],
'total' => ['type' => 'money', 'save_zero_value' => true],
])->setHandle('line_item');
}
Expand Down
3 changes: 2 additions & 1 deletion src/Orders/LineItems.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,9 @@ public function create(array $data): self
->variant(Arr::pull($data, 'variant'))
->quantity((int) Arr::pull($data, 'quantity'))
->unitPrice(Arr::pull($data, 'unit_price'))
->total(Arr::pull($data, 'total', 0))
->subTotal(Arr::pull($data, 'sub_total', 0))
->taxTotal(Arr::pull($data, 'tax_total', 0))
->total(Arr::pull($data, 'total', 0))
->data(collect($data));

$this->push($lineItem);
Expand Down
53 changes: 26 additions & 27 deletions src/Payments/Gateways/Mollie.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
use DuncanMcClean\SimpleCommerce\Contracts\Cart\Cart;
use DuncanMcClean\SimpleCommerce\Contracts\Orders\Order;
use DuncanMcClean\SimpleCommerce\Orders\LineItem;
use DuncanMcClean\SimpleCommerce\Shipping\ShippingOption;
use DuncanMcClean\SimpleCommerce\SimpleCommerce;
use Illuminate\Http\Request;
use Illuminate\Http\Response;
Expand Down Expand Up @@ -38,25 +39,31 @@ public function __construct()
public function setup(Cart $cart): array
{
// todo: ensure the existing payment has the correct totals, if not, they should be updated.
// if ($cart->get('mollie_payment_id')) {
// $payment = $this->mollie->payments->get($cart->get('mollie_payment_id'));
//
// return ['checkout_url' => $payment->getCheckoutUrl()];
// }
// if ($cart->get('mollie_payment_id')) {
// $payment = $this->mollie->payments->get($cart->get('mollie_payment_id'));
//
// return ['checkout_url' => $payment->getCheckoutUrl()];
// }

// dd($cart);
//

$payment = $this->mollie->payments->create([
'description' => config('app.name').' '.$cart->id(), // todo: this is visible to the customer, but the order doesn't exist yet, so we have to use the cart ID
'description' => "Pending Order: {$cart->id()}",
'amount' => $this->formatAmount(site: $cart->site(), amount: $cart->grandTotal()),
'redirectUrl' => $this->checkoutUrl(),
// 'webhookUrl' => $this->webhookUrl(),
'lines' => $cart->lineItems()
->map(function (LineItem $lineItem) use ($cart) {
// Mollie expects the unit price to include taxes. However, we only apply taxes to the line item total.
// So, we need to do some calculations to figure out what the unit price would be including tax.
$unitPrice = ($lineItem->total() + $lineItem->get('discount_amount', 0)) / $lineItem->quantity();

return [
'type' => 'physical', // todo: digital products
'type' => 'physical',
'description' => $lineItem->product()->get('title'),
'quantity' => $lineItem->quantity(),
// todo: make sure this amount is INCLUDING taxes
'unitPrice' => $this->formatAmount(site: $cart->site(), amount: $lineItem->unitPrice()),
'unitPrice' => $this->formatAmount(site: $cart->site(), amount: $unitPrice),
'discountAmount' => $lineItem->has('discount_amount')
? $this->formatAmount(site: $cart->site(), amount: $lineItem->get('discount_amount'))
: null,
Expand All @@ -66,33 +73,32 @@ public function setup(Cart $cart): array
'productUrl' => $lineItem->product()->absoluteUrl(),
];
})
->when($cart->shippingOption(), function ($lines, $shippingOption) use ($cart) {
// todo: handle shipping taxes here
->when($cart->shippingOption(), function ($lines, ShippingOption $shippingOption) use ($cart) {
return $lines->push([
'type' => 'shipping_fee',
'description' => $shippingOption->name(),
'quantity' => 1,
'unitPrice' => $this->formatAmount(site: $cart->site(), amount: $shippingOption->price()),
'totalAmount' => $this->formatAmount(site: $cart->site(), amount: $shippingOption->price()),
// 'vatRate' => 0,
// 'vatAmount' => $this->formatAmount(site: $cart->site(), amount: 0),
'unitPrice' => $this->formatAmount(site: $cart->site(), amount: $cart->shippingTotal()),
'totalAmount' => $this->formatAmount(site: $cart->site(), amount: $cart->shippingTotal()),
'vatRate' => collect($cart->get('shipping_tax_breakdown'))->sum('rate'),
'vatAmount' => $this->formatAmount(site: $cart->site(), amount: $cart->get('shipping_tax_total', 0)),
]);
})
->values()->all(),
'billingAddress' => array_filter([
'billingAddress' => $cart->hasBillingAddress() ? array_filter([
'streetAndNumber' => $cart->billingAddress()?->line1,
'streetAdditional' => $cart->billingAddress()?->line2,
'postalCode' => $cart->billingAddress()?->postcode,
'city' => $cart->billingAddress()?->city,
'country' => Arr::get($cart->billingAddress()?->country()?->data(), 'iso2'),
]),
'shippingAddress' => array_filter([
]) : null,
'shippingAddress' => $cart->hasShippingAddress() ? array_filter([
'streetAndNumber' => $cart->shippingAddress()?->line1,
'streetAdditional' => $cart->shippingAddress()?->line2,
'postalCode' => $cart->shippingAddress()?->postcode,
'city' => $cart->shippingAddress()?->city,
'country' => Arr::get($cart->shippingAddress()?->country()?->data(), 'iso2'),
]),
]) : null,
'locale' => $cart->site()->locale(),
'metadata' => [
'cart_id' => $cart->id(),
Expand All @@ -105,13 +111,6 @@ public function setup(Cart $cart): array
return ['checkout_url' => $payment->getCheckoutUrl()];
}

public function afterRecalculating(Cart $cart): void
{
if ($cart->get('mollie_payment_id')) {
$this->setup($cart);
}
}

public function process(Order $order): void
{
$order->set('payment_gateway', static::handle())->save();
Expand Down Expand Up @@ -149,7 +148,7 @@ private function formatAmount(Site $site, int $amount): array
{
return [
'currency' => Str::upper($site->attribute('currency')),
'value' => (string) substr_replace($amount, '.', -2, 0),
'value' => (string) number_format($amount / 100, 2, '.', ''),
];
}
}
5 changes: 0 additions & 5 deletions src/Payments/Gateways/PaymentGateway.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,6 @@ abstract class PaymentGateway

abstract public function setup(Cart $cart): array;

public function afterRecalculating(Cart $cart): void
{
//
}

abstract public function process(Order $order): void;

abstract public function capture(Order $order): void;
Expand Down
Loading

0 comments on commit f0decd5

Please sign in to comment.