Skip to content

Commit

Permalink
Merge in 0.5.5 updates #1262
Browse files Browse the repository at this point in the history
  • Loading branch information
alecritson authored Sep 21, 2023
2 parents bc58dfa + 9b2599b commit 21a3b2a
Show file tree
Hide file tree
Showing 10 changed files with 291 additions and 6 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -76,10 +76,16 @@ public function create()
$handle = Str::handle("{$this->typeHandle}_{$this->attributeGroup->translate('name')}");
$this->attributeGroup->handle = $handle;

$uniquenessConstraint = 'unique:' . get_class($this->attributeGroup) . ',handle';
if ($this->attributeGroup->id) {
$uniquenessConstraint .= ',' . $this->attributeGroup->id;
}

$this->validate([
'attributeGroup.handle' => 'unique:'.get_class($this->attributeGroup).',handle,'.$this->attributeGroup->id,
'attributeGroup.handle' => $uniquenessConstraint,
]);


if ($this->attributeGroup->id) {
$this->attributeGroup->save();
$this->emit('attribute-group-edit.updated', $this->attributeGroup->id);
Expand Down
7 changes: 7 additions & 0 deletions packages/core/src/Actions/Taxes/GetTaxZone.php
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,13 @@ public function execute(Addressable $address = null)
}
}

if ($address && $address->country_id) {
$countryZone = app(GetTaxZoneCountry::class)->execute($address->country_id);
if ($countryZone) {
return $countryZone->taxZone;
}
}

return TaxZone::getDefault();
}
}
32 changes: 32 additions & 0 deletions packages/core/src/Actions/Taxes/GetTaxZoneCountry.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
<?php

namespace Lunar\Actions\Taxes;

use Lunar\Models\TaxZoneCountry;

class GetTaxZoneCountry
{
public function execute($countryId)
{
$taxZone = $this->getZone($countryId);

if ($taxZone instanceof TaxZoneCountry) {
return $taxZone;
}

if (!$taxZone) {
return null;
}
}

/**
* Return the zone or zones which match this country.
*
* @param int $countryId
* @return TaxZoneCountry|null
*/
protected function getZone(int $countryId)
{
return TaxZoneCountry::whereCountryId($countryId)->first();
}
}
2 changes: 1 addition & 1 deletion packages/core/src/Managers/DiscountManager.php
Original file line number Diff line number Diff line change
Expand Up @@ -183,7 +183,7 @@ public function getApplied(): Collection

public function apply(Cart $cart): Cart
{
if (! $this->discounts) {
if (! $this->discounts || $this->discounts?->isEmpty()) {
$this->discounts = $this->getDiscounts($cart);
}

Expand Down
1 change: 1 addition & 0 deletions packages/core/src/Pipelines/Cart/ApplyDiscounts.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ final class ApplyDiscounts
*/
public function handle(Cart $cart, Closure $next)
{
$cart->discounts = collect([]);
$cart->discountBreakdown = collect([]);

Discounts::apply($cart);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
/**
* @group lunar.actions
*/
class SortProductsByPriceTest extends TestCase
class GenerateOrderReferenceTest extends TestCase
{
use RefreshDatabase;

Expand Down
61 changes: 61 additions & 0 deletions packages/core/tests/Unit/Actions/Taxes/GetTaxZoneCountryTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
<?php

namespace Lunar\Tests\Unit\Actions\Taxes;

use Illuminate\Foundation\Testing\RefreshDatabase;
use Lunar\Actions\Taxes\GetTaxZoneCountry;
use Lunar\Models\Country;
use Lunar\Models\TaxZoneCountry;
use Lunar\Tests\TestCase;

/**
* @group lunar.actions
*/
class GetTaxZoneCountryTest extends TestCase
{
use RefreshDatabase;

/** @test */
public function can_match_country_id()
{
$belgium = Country::factory()->create([
'name' => 'Belgium',
]);

$uk = Country::factory()->create([
'name' => 'United Kingdom',
]);

$taxZoneBelgium = TaxZoneCountry::factory()->create([
'country_id' => $belgium->id,
]);

$taxZoneUk = TaxZoneCountry::factory()->create([
'country_id' => $uk->id,
]);

$zone = app(GetTaxZoneCountry::class)->execute($uk->id);

$this->assertEquals($taxZoneUk->id, $zone->id);
}

/** @test */
public function can_mismatch_country_id()
{
$belgium = Country::factory()->create([
'name' => 'Belgium',
]);

$uk = Country::factory()->create([
'name' => 'United Kingdom',
]);

$taxZoneBelgium = TaxZoneCountry::factory()->create([
'country_id' => $belgium->id,
]);

$zone = app(GetTaxZoneCountry::class)->execute($uk->id);

$this->assertNull($zone);
}
}
99 changes: 99 additions & 0 deletions packages/core/tests/Unit/Actions/Taxes/GetTaxZoneTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
<?php

namespace Lunar\Tests\Unit\Actions\Taxes;

use Illuminate\Foundation\Testing\RefreshDatabase;
use Lunar\Actions\Taxes\GetTaxZone;
use Lunar\Actions\Taxes\GetTaxZoneCountry;
use Lunar\Models\Address;
use Lunar\Models\Country;
use Lunar\Models\State;
use Lunar\Models\TaxZone;
use Lunar\Models\TaxZoneCountry;
use Lunar\Models\TaxZonePostcode;
use Lunar\Models\TaxZoneState;
use Lunar\Tests\TestCase;

/**
* @group lunar.actions
*/
class GetTaxZoneTest extends TestCase
{
use RefreshDatabase;

/** @test */
public function can_prioritize_taxzones()
{
$postcode = 'SW1A 0AA';

$state = State::factory()->create([
'code' => 'AL',
'name' => 'Alabama',
]);

$country = Country::factory()->create([
'name' => 'Belgium',
]);

$taxZonePostcode = TaxZonePostcode::factory()->create([
'tax_zone_id' => TaxZone::factory(['default' => false]),
'postcode' => $postcode,
]);

$taxZoneState = TaxZoneState::factory()->create([
'tax_zone_id' => TaxZone::factory(['default' => false]),
'state_id' => $state->id,
]);

$taxZoneCountry = TaxZoneCountry::factory()->create([
'tax_zone_id' => TaxZone::factory(['default' => false]),
'country_id' => $country->id,
]);

$defaultTaxZone = TaxZone::factory(['default' => true])->create();

// postcode, state and country match => postcode tax zone should be returned
$addressWithAllMatching = Address::factory()->create([
'postcode' => $postcode,
'state' => $state->name,
'country_id' => $country->id,
]);

$zone1 = app(GetTaxZone::class)->execute($addressWithAllMatching);

$this->assertEquals($taxZonePostcode->tax_zone_id, $zone1->id);

// only state and country match => state tax zone should be returned
$addressWithOnlyStateAndCountryMatching = Address::factory()->create([
'postcode' => '1234AB',
'state' => $state->name,
'country_id' => $country->id,
]);

$zone2 = app(GetTaxZone::class)->execute($addressWithOnlyStateAndCountryMatching);

$this->assertEquals($taxZoneState->tax_zone_id, $zone2->id);

// only country matches => country tax zone should be returned
$addressWithOnlyCountryMatching = Address::factory()->create([
'postcode' => '1234AB',
'state' => 'Alaska',
'country_id' => $country->id,
]);

$zone3 = app(GetTaxZone::class)->execute($addressWithOnlyCountryMatching);

$this->assertEquals($taxZoneCountry->tax_zone_id, $zone3->id);

// nothing matches => default tax zone should be returned
$addressWithOnlyCountryMatching = Address::factory()->create([
'postcode' => '1234AB',
'state' => 'Alaska',
'country_id' => 123,
]);

$zone3 = app(GetTaxZone::class)->execute($addressWithOnlyCountryMatching);

$this->assertEquals($defaultTaxZone->id, $zone3->id);
}
}
85 changes: 82 additions & 3 deletions packages/core/tests/Unit/DiscountTypes/AmountOffTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

use Illuminate\Foundation\Testing\RefreshDatabase;
use Lunar\DiscountTypes\AmountOff;
use Lunar\Facades\CartSession;
use Lunar\Models\Brand;
use Lunar\Models\Cart;
use Lunar\Models\Channel;
Expand Down Expand Up @@ -704,7 +705,7 @@ public function cannot_apply_discount_coupon_without_coupon_code()
$this->assertEquals(0, $cart->discountTotal->value);
$this->assertEquals(2400, $cart->total->value);
$this->assertEquals(400, $cart->taxTotal->value);
$this->assertNull($cart->discounts);
$this->assertTrue($cart->discounts->isEmpty());
}

/**
Expand Down Expand Up @@ -982,7 +983,7 @@ public function cannot_apply_discount_with_min_spend()
$this->assertEquals(2000, $cart->subTotal->value);
$this->assertEquals(2400, $cart->total->value);
$this->assertEquals(400, $cart->taxTotal->value);
$this->assertNull($cart->discounts);
$this->assertTrue($cart->discounts->isEmpty());
}

/**
Expand Down Expand Up @@ -1221,7 +1222,7 @@ public function cannot_apply_discount_with_max_user_uses()
$this->assertEquals(2400, $cart->total->value);
$this->assertEquals(2000, $cart->subTotal->value);
}

/**
* @test
*/
Expand Down Expand Up @@ -1362,4 +1363,82 @@ public function fixed_amount_discount_distributes_across_cart_lines_with_differe
$this->assertEquals(357, $lastLine->discountTotal->value);
$this->assertEquals(1500, $cart->discountTotal->value);
}

/**
* @test
*/
public function can_apply_discount_dynamically()
{
$currency = Currency::getDefault();

$customerGroup = CustomerGroup::getDefault();

$channel = Channel::getDefault();

$cart = Cart::factory()->create([
'currency_id' => $currency->id,
'channel_id' => $channel->id,
]);

$purchasableA = ProductVariant::factory()->create();

Price::factory()->create([
'price' => 1000, // £10
'tier' => 1,
'currency_id' => $currency->id,
'priceable_type' => get_class($purchasableA),
'priceable_id' => $purchasableA->id,
]);

$cart->lines()->create([
'purchasable_type' => get_class($purchasableA),
'purchasable_id' => $purchasableA->id,
'quantity' => 2,
]);

$discount = Discount::factory()->create([
'type' => AmountOff::class,
'name' => 'Test Coupon',
'coupon' => '10OFF',
'data' => [
'fixed_value' => true,
'fixed_values' => [
'GBP' => 10.5,
],
],
]);

$discount->customerGroups()->sync([
$customerGroup->id => [
'enabled' => true,
'starts_at' => now(),
],
]);

$discount->channels()->sync([
$channel->id => [
'enabled' => true,
'starts_at' => now()->subHour(),
],
]);

// Calculate method called for the first time
CartSession::use($cart)->calculate();

// Update cart with coupon code
$cart->update([
'coupon_code' => '10OFF',
]);

// Get current cart which runs the calculate method for the second time
$cart = CartSession::current();

// Calculate method called for the third time
$cart = $cart->calculate();

$this->assertEquals(1050, $cart->discountTotal->value);
$this->assertEquals(1140, $cart->total->value);
$this->assertEquals(190, $cart->taxTotal->value);
$this->assertCount(1, $cart->discounts);
}
}

0 comments on commit 21a3b2a

Please sign in to comment.