Skip to content

Commit

Permalink
wip
Browse files Browse the repository at this point in the history
  • Loading branch information
iamgergo committed Sep 26, 2024
1 parent 95db1b6 commit dfd2c56
Show file tree
Hide file tree
Showing 10 changed files with 94 additions and 67 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ public function up(): void
Schema::create('bazar_taxes', static function (Blueprint $table): void {
$table->id();
$table->foreignId('tax_rate_id')->nullable()->constrained('bazar_tax_rates')->nullOnDelete();
$table->morphs('taxable');
$table->uuidMorphs('taxable');
$table->float('value')->unsigned();
$table->timestamps();

Expand Down
14 changes: 8 additions & 6 deletions src/Cart/Driver.php
Original file line number Diff line number Diff line change
Expand Up @@ -111,12 +111,12 @@ public function addItem(Buyable $buyable, float $quantity = 1, array $properties
public function removeItem(string $id): void
{
if ($item = $this->getItem($id)) {
$item->delete();

$key = $this->getItems()->search(static function (Item $item) use ($id) {
return $item->getKey() === $id;
});

$item->delete();

$this->getItems()->forget($key);

$this->sync();
Expand Down Expand Up @@ -147,7 +147,8 @@ public function removeItems(array $ids): void
public function updateItem(string $id, array $properties = []): void
{
if ($item = $this->getItem($id)) {
$item->fill($properties)->calculateTaxes();
$item->fill($properties)->save();
$item->calculateTaxes();

$this->sync();
}
Expand All @@ -161,7 +162,8 @@ public function updateItems(array $data): void
$items = $this->getItems()->whereIn('id', array_keys($data));

$items->each(static function (Item $item) use ($data): void {
$item->fill($data[$item->getKey()])->calculateTaxes();
$item->fill($data[$item->getKey()])->save();
$item->calculateTaxes();
});

if ($items->isNotEmpty()) {
Expand All @@ -174,7 +176,7 @@ public function updateItems(array $data): void
*/
public function getItems(): Collection
{
return $this->getModel()->items;
return $this->getModel()->getItems();
}

/**
Expand Down Expand Up @@ -276,7 +278,7 @@ public function sync(): void
{
$this->getShipping()->calculateFee();

$this->getShipping()->calculateTaxes();
$this->getModel()->calculateTax();

$this->getModel()->calculateDiscount();
}
Expand Down
21 changes: 21 additions & 0 deletions src/Interfaces/Checkoutable.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
use Cone\Bazar\Models\Item;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\MorphMany;
use Illuminate\Support\Collection;

interface Checkoutable extends Shippable
{
Expand All @@ -18,6 +19,26 @@ public function user(): BelongsTo;
*/
public function items(): MorphMany;

/**
* Get the checkoutable items.
*/
public function getItems(): Collection;

/**
* Get the checkoutable taxable items.
*/
public function getTaxables(): Collection;

/**
* Get the checkoutable fee items.
*/
public function getFees(): Collection;

/**
* Get the checkoutable line items.
*/
public function getLineItems(): Collection;

/**
* Get the currency.
*/
Expand Down
4 changes: 3 additions & 1 deletion src/Models/Cart.php
Original file line number Diff line number Diff line change
Expand Up @@ -189,7 +189,7 @@ public function scopeExpired(Builder $query): Builder
*/
public function toOrder(): Order
{
$this->lineItems->each(function (Item $item): void {
$this->getLineItems()->each(function (Item $item): void {
if (! $item->buyable->buyable($this->order)) {
throw new CartException(sprintf('Unable to add [%s] item to the order.', get_class($item->buyable)));
}
Expand All @@ -211,6 +211,8 @@ public function toOrder(): Order
$this->order->shipping->address->fill($this->shipping->address->toArray())->save();
}

$this->order->calculateTax();

return $this->order;
}
}
12 changes: 1 addition & 11 deletions src/Models/Item.php
Original file line number Diff line number Diff line change
Expand Up @@ -83,16 +83,6 @@ class Item extends Model implements Contract
*/
protected $table = 'bazar_items';

/**
* The "booted" method of the model.
*/
protected static function booted(): void
{
static::deleting(static function (self $item): void {
$item->taxes()->delete();
});
}

/**
* Get the proxied interface.
*/
Expand Down Expand Up @@ -300,6 +290,6 @@ public function calculateTaxes(): float

$this->taxes()->sync($taxes);

return $taxes->sum('value');
return $this->getTaxTotal();
}
}
2 changes: 1 addition & 1 deletion src/Models/Shipping.php
Original file line number Diff line number Diff line change
Expand Up @@ -300,6 +300,6 @@ public function calculateTaxes(): float

$this->taxes()->sync($taxes);

return $taxes->sum('value');
return $this->getTaxTotal();
}
}
4 changes: 2 additions & 2 deletions src/Traits/HasProperties.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,15 +14,15 @@ trait HasProperties
*/
public function propertyValues(): MorphToMany
{
return $this->morphToMany(PropertyValue::class, 'buyable', 'bazar_buyable_property_value');
return $this->morphToMany(PropertyValue::getProxiedClass(), 'buyable', 'bazar_buyable_property_value');
}

/**
* Get the properties for the model.
*/
public function properties(): HasManyThrough
{
return $this->hasManyThrough(Property::class, PropertyValue::class, 'bazar_buyable_property_value.buyable_id', 'id', 'id', 'property_id')
return $this->hasManyThrough(Property::getProxiedClass(), PropertyValue::getProxiedClass(), 'bazar_buyable_property_value.buyable_id', 'id', 'id', 'property_id')
->join('bazar_buyable_property_value', 'bazar_buyable_property_value.property_value_id', '=', 'bazar_property_values.id')
->where('bazar_buyable_property_value.buyable_type', static::class);
}
Expand Down
76 changes: 37 additions & 39 deletions src/Traits/InteractsWithItems.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
use Cone\Bazar\Bazar;
use Cone\Bazar\Interfaces\Inventoryable;
use Cone\Bazar\Interfaces\LineItem;
use Cone\Bazar\Interfaces\Taxable;
use Cone\Bazar\Models\Item;
use Cone\Bazar\Models\Shipping;
use Cone\Bazar\Support\Currency;
Expand All @@ -28,8 +29,8 @@ public static function bootInteractsWithItems(): void
{
static::deleting(static function (self $model): void {
if (! in_array(SoftDeletes::class, class_uses_recursive($model)) || $model->forceDeleting) {
$model->items()->delete();
$model->shipping()->delete();
$model->items->each->delete();
$model->shipping->delete();
}
});
}
Expand Down Expand Up @@ -75,47 +76,37 @@ protected function currency(): Attribute
}

/**
* Get the line items attribute.
*
* @return \Illuminate\Database\Eloquent\Casts\Attribute<\Illuminate\Support\Collection, never>
* Get the items.
*/
protected function lineItems(): Attribute
public function getItems(): Collection
{
return new Attribute(
get: function (): Collection {
return $this->items->filter->isLineItem();
}
);
return $this->items;
}

/**
* Get the fees attribute.
*
* @return \Illuminate\Database\Eloquent\Casts\Attribute<\Illuminate\Support\Collection, never>
* Get the line items.
*/
protected function fees(): Attribute
public function getLineItems(): Collection
{
return new Attribute(
get: function (): Collection {
return $this->items->filter->isFee();
}
);
return $this->getItems()->filter->isLineItem();
}

/**
* Get the taxables attribute.
*
* @return \Illuminate\Database\Eloquent\Casts\Attribute<\Illuminate\Support\Collection, never>
* Get the fees.
*/
protected function taxables(): Attribute
public function getFees(): Collection
{
return new Attribute(
get: function (): Collection {
return $this->items->when($this->needsShipping(), function (Collection $items): Collection {
return $items->merge([$this->shipping]);
});
}
);
return $this->getItems()->filter->isFee();
}

/**
* Get the taxables.
*/
public function getTaxables(): Collection
{
return $this->getItems()->when($this->needsShipping(), function (Collection $items): Collection {
return $items->merge([$this->shipping]);
});
}

/**
Expand Down Expand Up @@ -227,10 +218,12 @@ public function getCurrency(): string
*/
public function getTotal(): float
{
$value = $this->taxables->sum(static function (LineItem $item): float {
$value = $this->items->sum(static function (Item $item): float {
return $item->getTotal();
});

$value += $this->needsShipping() ? $this->shipping->getTotal() : 0;

$value -= $this->discount;

return round($value < 0 ? 0 : $value, 2);
Expand All @@ -249,7 +242,7 @@ public function getFormattedTotal(): string
*/
public function getSubtotal(): float
{
$value = $this->lineItems->sum(static function (LineItem $item): float {
$value = $this->getLineItems()->sum(static function (LineItem $item): float {
return $item->getSubtotal();
});

Expand All @@ -269,7 +262,7 @@ public function getFormattedSubtotal(): string
*/
public function getFeeTotal(): float
{
$value = $this->fees->sum(static function (LineItem $item): float {
$value = $this->getFees()->sum(static function (LineItem $item): float {
return $item->getSubtotal();
});

Expand All @@ -289,8 +282,8 @@ public function getFormattedFeeTotal(): string
*/
public function getTax(): float
{
$value = $this->taxables->sum(static function (LineItem $item): float {
return $item->getTaxTotal() * $item->getQuantity();
$value = $this->getTaxables()->sum(static function (Taxable $item): float {
return $item->getTaxTotal();
});

return round($value, 2);
Expand All @@ -309,9 +302,13 @@ public function getFormattedTax(): string
*/
public function calculateTax(): float
{
return $this->taxables->sum(static function (LineItem $item): float {
return $item->calculateTaxes() * $item->getQuantity();
$value = $this->getTaxables()->each(static function (Taxable $item): void {
$item->calculateTaxes();
})->sum(static function (Taxable $item): float {
return $item->getTaxTotal();
});

return round($value, 2);
}

/**
Expand Down Expand Up @@ -365,7 +362,8 @@ public function syncItems(): void
if ($item->isLineItem() && ! is_null($item->checkoutable)) {
$data = $item->buyable->toItem($item->checkoutable, $item->only('properties'))->only('price');

$item->fill($data)->calculateTaxes();
$item->fill($data)->save();
$item->calculateTaxes();
}
});
}
Expand Down
15 changes: 14 additions & 1 deletion src/Traits/InteractsWithTaxes.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,22 @@
use Cone\Bazar\Models\TaxRate;
use Illuminate\Database\Eloquent\Casts\Attribute;
use Illuminate\Database\Eloquent\Relations\MorphToMany;
use Illuminate\Database\Eloquent\SoftDeletes;

trait InteractsWithTaxes
{
/**
* Boot the trait.
*/
public static function bootInteractsWithTaxes(): void
{
static::deleting(static function (self $model): void {
if (! in_array(SoftDeletes::class, class_uses_recursive($model)) || $model->forceDeleting) {
$model->taxes()->detach();
}
});
}

/**
* Get the taxes for the model.
*/
Expand Down Expand Up @@ -50,6 +63,6 @@ protected function formattedTaxTotal(): Attribute
*/
public function getTaxTotal(): float
{
return $this->taxes->sum('tax.value');
return $this->taxes->sum('tax.value') * $this->getQuantity();
}
}
11 changes: 6 additions & 5 deletions tests/Cart/ManagerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
use Cone\Bazar\Models\Property;
use Cone\Bazar\Models\PropertyValue;
use Cone\Bazar\Models\Shipping;
use Cone\Bazar\Models\TaxRate;
use Cone\Bazar\Models\Variant;
use Cone\Bazar\Support\Facades\Cart as CartFacade;
use Cone\Bazar\Tests\TestCase;
Expand Down Expand Up @@ -44,6 +45,10 @@ public function setUp(): void
$this->product->propertyValues()->attach($property->values);
$this->variant->propertyValues()->attach($property->values->where('value', 'S'));

$taxRate = TaxRate::factory()->create();

$this->product->taxRates()->attach($taxRate);

$this->manager->addItem($this->product, 2, ['size' => 'L']);
$this->manager->addItem($this->product, 1, ['size' => 'S']);
}
Expand Down Expand Up @@ -97,6 +102,7 @@ public function test_cart_can_remove_items(): void
$item = $this->manager->getModel()->findItem([
'properties' => ['size' => 'L'],
]);

$this->manager->removeItem($item->id);

$this->assertEquals(1, $this->manager->count());
Expand Down Expand Up @@ -186,9 +192,4 @@ public function test_cart_can_checkout(): void

Event::assertDispatched(CheckoutProcessed::class);
}

public function test_cart_can_sync_items(): void
{
$this->assertEquals($this->product->price * 2 + $this->variant->price, $this->manager->getTotal());
}
}

0 comments on commit dfd2c56

Please sign in to comment.