-
Notifications
You must be signed in to change notification settings - Fork 473
Updated Price Model TaxIncl methods & Cart Item TaxIncl properties to actually provide Tax inclusive values. #2411
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: 1.x
Are you sure you want to change the base?
Changes from all commits
8ba3f7f
736a39a
e1c15f0
8113180
20efc01
e16575b
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -41,6 +41,8 @@ | |
| use Lunar\Exceptions\FingerprintMismatchException; | ||
| use Lunar\Facades\DB; | ||
| use Lunar\Facades\ShippingManifest; | ||
| use Lunar\Models\TaxZone; | ||
| use Spatie\LaravelBlink\BlinkFacade as Blink; | ||
| use Lunar\Pipelines\Cart\Calculate; | ||
| use Lunar\Validation\Cart\ValidateCartForOrderCreation; | ||
| use Lunar\Validation\CartLine\CartLineStock; | ||
|
|
@@ -67,6 +69,22 @@ class Cart extends BaseModel implements Contracts\Cart | |
| use LogsActivity; | ||
| use SoftDeletes; | ||
|
|
||
| /** Restore the tax zone override from the cart's meta JSON column whenever a Cart is loaded from the database. */ | ||
| protected static function booted(): void | ||
| { | ||
| parent::booted(); | ||
|
|
||
| static::retrieved(function (Cart $cart) { | ||
| $taxZoneId = $cart->meta['tax_zone_id'] ?? null; | ||
| if ($taxZoneId) { | ||
| $cart->taxZone = Blink::once( | ||
| 'cart_tax_zone_'.$taxZoneId, | ||
| fn () => TaxZone::find($taxZoneId) | ||
| ); | ||
| } | ||
| }); | ||
| } | ||
|
|
||
| /** | ||
| * Array of cachable class properties. | ||
| * | ||
|
|
@@ -138,6 +156,15 @@ class Cart extends BaseModel implements Contracts\Cart | |
| */ | ||
| public ?ShippingOption $shippingOptionOverride = null; | ||
|
|
||
| /** | ||
| * The tax zone override for this cart. | ||
| * When set, this zone will be used instead of resolving a zone from the | ||
| * shipping address, enabling middleware to enforce the correct geographic | ||
| * tax treatment based on IP geo-location or customer-provided country | ||
| * before a full shipping address is known. | ||
| */ | ||
| public ?TaxZone $taxZone = null; | ||
|
|
||
| /** | ||
| * Additional shipping estimate meta data. | ||
| */ | ||
|
|
@@ -617,4 +644,29 @@ public function getEstimatedShipping(array $params, bool $setOverride = false): | |
|
|
||
| return $option; | ||
| } | ||
|
|
||
| /** | ||
| * Set the tax zone override for this cart. | ||
| * | ||
| * When set, all tax calculations will use this zone instead of resolving one from the shipping address. | ||
| * Pass null to clear the override and fall back to the address-derived (or default) zone. | ||
| * | ||
| * The zone ID is mirrored into the cart's `meta` JSON column so the choice survives across requests. | ||
| * Call `->save()` afterwards to persist it to the database; the `booted()` retrieved-event listener | ||
| * will then restore the zone automatically on every subsequent page load. | ||
| */ | ||
| public function setTaxZone(?TaxZone $taxZone): Cart | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Although it would cause a breaking change, this should be added to the |
||
| { | ||
| $this->taxZone = $taxZone; | ||
| $meta = $this->meta ?? new \ArrayObject; | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The meta column is cast with The issue is that |
||
|
|
||
| if ($taxZone) { | ||
| $meta['tax_zone_id'] = $taxZone->id; | ||
| } else { | ||
| unset($meta['tax_zone_id']); | ||
| } | ||
|
|
||
| $this->meta = $meta; | ||
| return $this; | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -4,6 +4,7 @@ | |
|
|
||
| use Illuminate\Database\Eloquent\Relations\BelongsTo; | ||
| use Illuminate\Database\Eloquent\Relations\MorphTo; | ||
| use Lunar\Models\TaxZone; | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We should be using the contract here. |
||
|
|
||
| interface Price | ||
| { | ||
|
|
@@ -24,11 +25,22 @@ public function customerGroup(): BelongsTo; | |
|
|
||
| /** | ||
| * Return the price exclusive of tax. | ||
| * | ||
| * @param TaxZone|null $taxZone | ||
| */ | ||
| public function priceExTax(): \Lunar\DataTypes\Price; | ||
| public function priceExTax(?TaxZone $taxZone = null): \Lunar\DataTypes\Price; | ||
|
|
||
| /** | ||
| * Return the price inclusive of tax. | ||
| * | ||
| * @param TaxZone|null $taxZone | ||
| */ | ||
| public function priceIncTax(): int|\Lunar\DataTypes\Price; | ||
| public function priceIncTax(?TaxZone $taxZone = null): int|\Lunar\DataTypes\Price; | ||
|
|
||
| /** | ||
| * Return the compare price inclusive of tax. | ||
| * | ||
| * @param TaxZone|null $taxZone | ||
| */ | ||
| public function comparePriceIncTax(?TaxZone $taxZone = null): int|\Lunar\DataTypes\Price; | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -7,6 +7,7 @@ | |
| use Lunar\DataTypes\Price; | ||
| use Lunar\Models\Cart; | ||
| use Lunar\Models\Contracts\Cart as CartContract; | ||
| use Spatie\LaravelBlink\BlinkFacade as Blink; | ||
|
|
||
| class CalculateLines | ||
| { | ||
|
|
@@ -18,6 +19,14 @@ class CalculateLines | |
| public function handle(CartContract $cart, Closure $next): mixed | ||
| { | ||
| /** @var Cart $cart */ | ||
|
|
||
| // Cache the TaxZone so that price model taxInc methods accounts for it in computation. | ||
| if ($cart->taxZone) { | ||
| Blink::put('lunar_cart_tax_zone', $cart->taxZone); | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If application code calculates two carts in the same request (e.g. comparing shipping options across accounts, or a queue job processing multiple carts in the same process), the second cart's Recommendation: Key the Blink entry by cart ID: 'lunar_cart_tax_zone_'.$cart->id, and have |
||
| } else { | ||
| Blink::forget('lunar_cart_tax_zone'); | ||
| } | ||
|
|
||
| foreach ($cart->lines as $line) { | ||
| $cartLine = app(Pipeline::class) | ||
| ->send($line) | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ensure we reference the contracts and not concrete classes.