Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 4 additions & 9 deletions config/bazar.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

declare(strict_types=1);

use Cone\Bazar\Enums\Currency;

return [

/*
Expand All @@ -16,15 +18,8 @@
*/

'currencies' => [
'default' => strtolower(env('BAZAR_CURRENCY', 'USD')),
'available' => [
'USD' => [
'precision' => 2,
],
'EUR' => [
'precision' => 2,
],
],
'default' => env('BAZAR_CURRENCY', 'USD'),
'available' => [Currency::USD, Currency::EUR],
],

/*
Expand Down
1 change: 0 additions & 1 deletion database/factories/CartFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,6 @@ public function modelName(): string
public function definition(): array
{
return [
'discount' => 0,
'currency' => Bazar::getCurrency(),
];
}
Expand Down
46 changes: 46 additions & 0 deletions database/factories/CouponFactory.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
<?php

declare(strict_types=1);

namespace Cone\Bazar\Database\Factories;

use Cone\Bazar\Enums\CouponType;
use Cone\Bazar\Models\Coupon;
use Illuminate\Database\Eloquent\Factories\Factory;
use Illuminate\Support\Str;

class CouponFactory extends Factory
{
/**
* The name of the factory's corresponding model.
*
* @var class-string<\Illuminate\Database\Eloquent\Model>
*/
protected $model = Coupon::class;

/**
* Get the name of the model that is generated by the factory.
*
* @return class-string<\Illuminate\Database\Eloquent\Model|TModel>
*/
public function modelName(): string
{
return $this->model::getProxiedClass();
}

/**
* Define the model's default state.
*/
public function definition(): array
{
return [
'active' => true,
'expires_at' => null,
'rules' => [],
'stackable' => false,
'type' => CouponType::FIX,
'value' => mt_rand(5, 50),
'code' => Str::upper(Str::random(8)),
];
}
}
1 change: 0 additions & 1 deletion database/factories/OrderFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,6 @@ public function modelName(): string
public function definition(): array
{
return [
'discount' => 0,
'currency' => Bazar::getCurrency(),
];
}
Expand Down
2 changes: 1 addition & 1 deletion database/factories/ProductFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ public function configure(): static
{
return $this->afterMaking(static function (Product $product): void {
$product->setRelation('metaData', $product->metaData()->makeMany([
['key' => 'price_'.strtolower(Bazar::getCurrency()), 'value' => mt_rand(10, 100)],
['key' => 'price_'.Bazar::getCurrency()->key(), 'value' => mt_rand(10, 100)],
]));
})->afterCreating(static function (Product $product): void {
$product->metaData->each(static function (Meta $meta) use ($product) {
Expand Down
2 changes: 1 addition & 1 deletion database/factories/VariantFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ public function configure(): static
{
return $this->afterMaking(static function (Variant $variant): void {
$variant->setRelation('metaData', $variant->metaData()->makeMany([
['key' => 'price_'.strtolower(Bazar::getCurrency()), 'value' => mt_rand(10, 100)],
['key' => 'price_'.Bazar::getCurrency()->key(), 'value' => mt_rand(10, 100)],
]));
})->afterCreating(static function (Variant $variant): void {
$variant->metaData->each(static function (Meta $meta) use ($variant) {
Expand Down
30 changes: 30 additions & 0 deletions database/migrations/2025_12_14_201347_alter_bazar_orders_table.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
<?php

declare(strict_types=1);

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::table('bazar_orders', static function (Blueprint $table): void {
$table->dropColumn(['discount']);
});
}

/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::table('bazar_orders', static function (Blueprint $table): void {
$table->float('discount')->unsigned()->default(0)->after('currency');
});
}
};
30 changes: 30 additions & 0 deletions database/migrations/2025_12_14_201359_alter_bazar_carts_table.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
<?php

declare(strict_types=1);

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::table('bazar_carts', static function (Blueprint $table): void {
$table->dropColumn(['discount']);
});
}

/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::table('bazar_carts', static function (Blueprint $table): void {
$table->float('discount')->unsigned()->default(0)->after('currency');
});
}
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
<?php

declare(strict_types=1);

use Cone\Bazar\Enums\CouponType;
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::create('bazar_coupons', static function (Blueprint $table): void {
$table->id();
$table->string('code')->unique();
$table->float('value', 10, 2)->unsigned();
$table->enum('type', CouponType::cases())->default(CouponType::FIX->value);
$table->json('rules')->nullable();
$table->boolean('active')->default(true);
$table->boolean('stackable')->default(false);
$table->timestamp('expires_at')->nullable();
$table->timestamps();
});
}

/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::dropIfExists('bazar_coupons');
}
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
<?php

declare(strict_types=1);

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::create('bazar_couponables', static function (Blueprint $table): void {
$table->id();
$table->foreignId('coupon_id')->nullable()->constrained('bazar_coupons')->nullOnDelete();
$table->morphs('couponable');
$table->float('value', 10, 2)->unsigned();
$table->timestamps();
});
}

/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::dropIfExists('bazar_couponables');
}
};
4 changes: 2 additions & 2 deletions resources/views/mail/order-details.blade.php
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<x-mail::message>
# Hello, {{ $order->address->name }}!
# {{ __('Hello') }}, {{ $order->address->name }}!

## Thank you for your order!
## {{ __('Thank you for your order!') }}

Your order has been received and now being processed. Your orders are shown below for your reference:
**Order #{{ $order->getKey() }}**
Expand Down
32 changes: 19 additions & 13 deletions src/Bazar.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

namespace Cone\Bazar;

use Cone\Bazar\Exceptions\InvalidCurrencyException;
use Cone\Bazar\Enums\Currency;
use Illuminate\Support\Facades\Config;

abstract class Bazar
Expand All @@ -14,40 +14,46 @@ abstract class Bazar
*
* @var string
*/
public const VERSION = '1.3.0';
public const VERSION = '1.4.0';

/**
* The currency in use.
*/
protected static ?string $currency = null;
protected static ?Currency $currency = null;

/**
* Get all the available currencies.
*/
public static function getCurrencies(): array
{
return array_keys(Config::get('bazar.currencies.available', []));
$currencies = array_filter(Currency::cases(), static function (Currency $currency): bool {
return $currency->available();
});

return array_values($currencies);
}

/**
* Get the default currency.
*/
public static function getDefaultCurrency(): Currency
{
return Currency::tryFrom(Config::get('bazar.currencies.default', 'USD')) ?: Currency::USD;
}

/**
* Get the currency in use.
*/
public static function getCurrency(): string
public static function getCurrency(): Currency
{
return strtoupper(static::$currency ?: Config::get('bazar.currencies.default', 'USD'));
return static::$currency ??= static::getDefaultCurrency();
}

/**
* Set the currency in use.
*/
public static function setCurrency(string $currency): void
public static function setCurrency(Currency $currency): void
{
$currency = strtoupper($currency);

if (! in_array($currency, static::getCurrencies())) {
throw new InvalidCurrencyException("The [{$currency}] currency is not registered.");
}

static::$currency = $currency;
}
}
3 changes: 2 additions & 1 deletion src/BazarServiceProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ class BazarServiceProvider extends ServiceProvider
Interfaces\Models\Address::class => Models\Address::class,
Interfaces\Models\Cart::class => Models\Cart::class,
Interfaces\Models\Category::class => Models\Category::class,
Interfaces\Models\Coupon::class => Models\Coupon::class,
Interfaces\Models\Item::class => Models\Item::class,
Interfaces\Models\Order::class => Models\Order::class,
Interfaces\Models\Product::class => Models\Product::class,
Expand All @@ -36,7 +37,6 @@ class BazarServiceProvider extends ServiceProvider
public array $singletons = [
Interfaces\Cart\Manager::class => Cart\Manager::class,
Interfaces\Gateway\Manager::class => Gateway\Manager::class,
Interfaces\Repositories\DiscountRepository::class => Repositories\DiscountRepository::class,
Interfaces\Shipping\Manager::class => Shipping\Manager::class,
];

Expand Down Expand Up @@ -100,6 +100,7 @@ protected function registerPublishes(): void
$this->publishes([
__DIR__.'/../stubs/BazarServiceProvider.stub' => $this->app->basePath('app/Providers/BazarServiceProvider.php'),
__DIR__.'/../stubs/CategoryResource.stub' => $this->app->basePath('app/Root/Resources/CategoryResource.php'),
__DIR__.'/../stubs/CouponResource.stub' => $this->app->basePath('app/Root/Resources/CouponResource.php'),
__DIR__.'/../stubs/OrderResource.stub' => $this->app->basePath('app/Root/Resources/OrderResource.php'),
__DIR__.'/../stubs/ProductResource.stub' => $this->app->basePath('app/Root/Resources/ProductResource.php'),
__DIR__.'/../stubs/PropertyResource.stub' => $this->app->basePath('app/Root/Resources/PropertyResource.php'),
Expand Down
14 changes: 12 additions & 2 deletions src/Cart/Driver.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
use Cone\Bazar\Interfaces\Buyable;
use Cone\Bazar\Models\Address;
use Cone\Bazar\Models\Cart;
use Cone\Bazar\Models\Coupon;
use Cone\Bazar\Models\Item;
use Cone\Bazar\Models\Shipping;
use Cone\Bazar\Support\Facades\Gateway;
Expand Down Expand Up @@ -51,7 +52,7 @@ protected function resolved(Request $request, Cart $cart): void
$cart->user()->associate($request->user())->save();
}

$cart->loadMissing(['items', 'items.buyable']);
$cart->loadMissing(['items', 'items.buyable', 'coupons']);
}

/**
Expand All @@ -73,7 +74,7 @@ public function getModel(): Cart
$cart->syncItems();
$cart->shipping->calculateFee();
$cart->shipping->calculateTaxes();
$cart->calculateDiscount();
$cart->getModel()->calculateDiscount();
}
});
}
Expand Down Expand Up @@ -230,6 +231,7 @@ public function updateShipping(array $attributes = [], ?string $driver = null):
*/
public function empty(): void
{
$this->getModel()->coupons()->detach();
$this->getModel()->items()->delete();
$this->getModel()->setRelation('items', $this->getModel()->items()->getRelated()->newCollection());

Expand Down Expand Up @@ -265,6 +267,14 @@ public function checkout(string $driver): Response
});
}

/**
* Apply the given coupon.
*/
public function applyCoupon(string|Coupon $coupon): void
{
$this->getModel()->applyCoupon($coupon);
}

/**
* Determine if the cart is not empty.
*/
Expand Down
Loading