Merge pull request #5190 from AbdullahFaqeir/master

- Refactoring to Laravel 8 Class Model Factories.
This commit is contained in:
Glenn Hermans 2021-10-07 12:02:32 +02:00 committed by GitHub
commit 916cd184b6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
101 changed files with 3904 additions and 2446 deletions

View File

@ -29,7 +29,6 @@
"khaled.alshamaa/ar-php": "^6.0.0",
"konekt/concord": "^1.2",
"laravel/framework": "^8.0",
"laravel/legacy-factories": "^1.1",
"laravel/scout": "^8.0",
"laravel/socialite": "^5.0",
"laravel/tinker": "^2.0",
@ -43,7 +42,7 @@
"codeception/codeception": "^4.1",
"codeception/module-asserts": "^1.1",
"codeception/module-filesystem": "^1.0",
"codeception/module-laravel5": "^1.0",
"codeception/module-laravel": "^2.0",
"codeception/module-webdriver": "^1.0",
"filp/whoops": "^2.0",
"mockery/mockery": "^1.3.1",

1645
composer.lock generated

File diff suppressed because it is too large Load Diff

View File

@ -1,23 +1,47 @@
<?php
use Faker\Generator as Faker;
namespace Database\Factories;
/*
|--------------------------------------------------------------------------
| Model Factories
|--------------------------------------------------------------------------
|
| This directory should contain each of the model factory definitions for
| your application. Factories provide a convenient way to generate new
| model instances for testing / seeding your application's database.
|
*/
use App\Models\User;
use Illuminate\Database\Eloquent\Factories\Factory;
use Illuminate\Support\Str;
$factory->define(App\User::class, function (Faker $faker) {
return [
'name' => $faker->name,
'email' => $faker->unique()->safeEmail,
'password' => '$2y$10$TKh8H1.PfQx37YgCzwiKb.KjNyWgaHb9cbcoQgdIVFlYg7B77UdFm', // secret
'remember_token' => str_random(10),
];
});
class UserFactory extends Factory
{
/**
* The name of the factory's corresponding model.
*
* @var string
*/
protected $model = User::class;
/**
* Define the model's default state.
*
* @return array
*/
public function definition()
{
return [
'name' => $this->faker->name(),
'email' => $this->faker->unique()->safeEmail(),
'email_verified_at' => now(),
'password' => '$2y$10$92IXUNpkjO0rOQ5byMi.Ye4oKoEa3Ro9llC/.og/at2.uheWG/igi', // password
'remember_token' => Str::random(10),
];
}
/**
* Indicate that the model's email address should be unverified.
*
* @return \Illuminate\Database\Eloquent\Factories\Factory
*/
public function unverified()
{
return $this->state(function (array $attributes) {
return [
'email_verified_at' => null,
];
});
}
}

View File

@ -12,7 +12,7 @@ class Attribute extends JsonResource
* @param \Illuminate\Http\Request
* @return array
*/
public function toArray($request)
public function toArray($request): array
{
return [
'id' => $this->id,

View File

@ -12,13 +12,13 @@ class AttributeOption extends JsonResource
* @param \Illuminate\Http\Request
* @return array
*/
public function toArray($request)
public function toArray($request): array
{
return [
'id' => $this->id,
'admin_name' => $this->admin_name,
'label' => $this->label,
'swatch_value' => $this->swatch_value
'swatch_value' => $this->swatch_value,
];
}
}

View File

@ -1,84 +1,142 @@
<?php
/** @var \Illuminate\Database\Eloquent\Factory $factory */
namespace Webkul\Attribute\Database\Factories;
use Faker\Generator as Faker;
use Webkul\Attribute\Models\Attribute;
use Webkul\Core\Models\Locale;
use Illuminate\Database\Eloquent\Factories\Factory;
$factory->define(Attribute::class, function (Faker $faker, array $attributes) {
$types = [
'text',
'textarea',
'price',
'boolean',
'select',
'multiselect',
'datetime',
'date',
'image',
'file',
'checkbox',
class AttributeFactory extends Factory
{
/**
* The name of the factory's corresponding model.
*
* @var string
*/
protected $model = Attribute::class;
/**
* @var array
*/
protected $states = [
'validation_numeric',
'validation_email',
'validation_decimal',
'validation_url',
'required',
'unique',
'filterable',
'configurable',
];
$locales = Locale::pluck('code')->all();
/**
* Define the model's default state.
*
* @return array
*/
public function definition(): array
{
$types = [
'text',
'textarea',
'price',
'boolean',
'select',
'multiselect',
'datetime',
'date',
'image',
'file',
'checkbox',
];
// array $attributes does not contain any locale code
if (count(array_diff_key(array_flip($locales), $attributes) ) === count($locales)) {
$localeCode = $locales[0];
$attributes[$localeCode] = [
'name' => $faker->word,
return [
'admin_name' => $this->faker->word,
'code' => $this->faker->word,
'type' => array_rand($types),
'validation' => '',
'position' => $this->faker->randomDigit,
'is_required' => false,
'is_unique' => false,
'value_per_locale' => false,
'value_per_channel' => false,
'is_filterable' => false,
'is_configurable' => false,
'is_user_defined' => true,
'is_visible_on_front' => true,
'swatch_type' => null,
'use_in_flat' => true,
];
}
return [
'admin_name' => $faker->word,
'code' => $faker->word,
'type' => array_rand($types),
'validation' => '',
'position' => $faker->randomDigit,
'is_required' => false,
'is_unique' => false,
'value_per_locale' => false,
'value_per_channel' => false,
'is_filterable' => false,
'is_configurable' => false,
'is_user_defined' => true,
'is_visible_on_front' => true,
'swatch_type' => null,
'use_in_flat' => true,
];
});
public function validation_numeric(): AttributeFactory
{
return $this->state(function (array $attributes) {
return [
'validation' => 'numeric',
];
});
}
$factory->state(Attribute::class, 'validation_numeric', [
'validation' => 'numeric',
]);
public function validation_email(): AttributeFactory
{
return $this->state(function (array $attributes) {
return [
'validation' => 'email',
];
});
}
$factory->state(Attribute::class, 'validation_email', [
'validation' => 'email',
]);
public function validation_decimal(): AttributeFactory
{
return $this->state(function (array $attributes) {
return [
'validation' => 'decimal',
];
});
}
$factory->state(Attribute::class, 'validation_decimal', [
'validation' => 'decimal',
]);
public function validation_url(): AttributeFactory
{
return $this->state(function (array $attributes) {
return [
'validation' => 'url',
];
});
}
$factory->state(Attribute::class, 'validation_url', [
'validation' => 'url',
]);
public function required(): AttributeFactory
{
return $this->state(function (array $attributes) {
return [
'is_required' => true,
];
});
}
$factory->state(Attribute::class, 'required', [
'is_required' => true,
]);
public function unique(): AttributeFactory
{
return $this->state(function (array $attributes) {
return [
'is_unique' => true,
];
});
}
$factory->state(Attribute::class, 'unique', [
'is_unique' => true,
]);
public function filterable(): AttributeFactory
{
return $this->state(function (array $attributes) {
return [
'is_filterable' => true,
];
});
}
$factory->state(Attribute::class, 'filterable', [
'is_filterable' => true,
]);
$factory->state(Attribute::class, 'configurable', [
'is_configurable' => true,
]);
public function configurable(): AttributeFactory
{
return $this->state(function (array $attributes) {
return [
'is_configurable' => true,
];
});
}
}

View File

@ -1,15 +1,32 @@
<?php
/** @var \Illuminate\Database\Eloquent\Factory $factory */
namespace Webkul\Attribute\Database\Factories;
use Faker\Generator as Faker;
use Webkul\Attribute\Models\AttributeFamily;
use Illuminate\Database\Eloquent\Factories\Factory;
$factory->define(AttributeFamily::class, function (Faker $faker) {
return [
'name' => $faker->word(),
'code' => $faker->word(),
'is_user_defined' => rand(0, 1),
'status' => 0,
];
});
class AttributeFamilyFactory extends Factory
{
/**
* The name of the factory's corresponding model.
*
* @var string
*/
protected $model = AttributeFamily::class;
/**
* Define the model's default state.
*
* @return array
* @throws \Exception
*/
public function definition(): array
{
return [
'name' => $this->faker->word(),
'code' => $this->faker->word(),
'is_user_defined' => random_int(0, 1),
'status' => 0,
];
}
}

View File

@ -1,83 +1,32 @@
<?php
/** @var \Illuminate\Database\Eloquent\Factory $factory */
namespace Webkul\Attribute\Database\Factories;
use Faker\Generator as Faker;
use Webkul\Attribute\Models\Attribute;
use Webkul\Attribute\Models\AttributeOption;
use Webkul\Core\Models\Locale;
use Illuminate\Database\Eloquent\Factories\Factory;
$factory->define(AttributeOption::class, function (Faker $faker, array $attributes) {
class AttributeOptionFactory extends Factory
{
/**
* The name of the factory's corresponding model.
*
* @var string
*/
protected $model = AttributeOption::class;
$locales = Locale::pluck('code')->all();
// array $attributes does not contain any locale code
if (count(array_diff_key(array_flip($locales), $attributes) ) === count($locales)) {
$localeCode = $locales[0];
$attributes[$localeCode] = [
'label' => $faker->word,
/**
* Define the model's default state.
*
* @return array
*/
public function definition(): array
{
return [
'admin_name' => $this->faker->word,
'sort_order' => $this->faker->randomDigit(),
'attribute_id' => Attribute::factory(['swatch_type' => 'text']),
'swatch_value' => null,
];
}
return [
'admin_name' => $faker->word,
'sort_order' => $faker->randomDigit,
'attribute_id' => function () {
return factory(Attribute::class)->create()->id;
},
'swatch_value' => null,
];
});
$factory->define(AttributeOption::class, function (Faker $faker, array $attributes) {
return [
'admin_name' => $faker->word,
'sort_order' => $faker->randomDigit,
'attribute_id' => function () {
return factory(Attribute::class)
->create(['swatch_type' => 'color'])
->id;
},
'swatch_value' => $faker->hexColor,
];
});
$factory->define(AttributeOption::class, function (Faker $faker, array $attributes) {
return [
'admin_name' => $faker->word,
'sort_order' => $faker->randomDigit,
'attribute_id' => function () {
return factory(Attribute::class)
->create(['swatch_type' => 'image'])
->id;
},
'swatch_value' => '/tests/_data/ProductImageExampleForUpload.jpg',
];
});
$factory->define(AttributeOption::class, function (Faker $faker, array $attributes) {
return [
'admin_name' => $faker->word,
'sort_order' => $faker->randomDigit,
'attribute_id' => function () {
return factory(Attribute::class)
->create(['swatch_type' => 'dropdown'])
->id;
},
'swatch_value' => null,
];
});
$factory->define(AttributeOption::class, function (Faker $faker, array $attributes) {
return [
'admin_name' => $faker->word,
'sort_order' => $faker->randomDigit,
'attribute_id' => function () {
return factory(Attribute::class)
->create(['swatch_type' => 'text'])
->id;
},
'swatch_value' => null,
];
});
}

View File

@ -2,11 +2,17 @@
namespace Webkul\Attribute\Models;
use Illuminate\Database\Eloquent\Builder;
use Webkul\Core\Eloquent\TranslatableModel;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Webkul\Attribute\Database\Factories\AttributeFactory;
use Webkul\Attribute\Contracts\Attribute as AttributeContract;
class Attribute extends TranslatableModel implements AttributeContract
{
use HasFactory;
public $translatedAttributes = ['name'];
protected $fillable = [
@ -33,7 +39,7 @@ class Attribute extends TranslatableModel implements AttributeContract
/**
* Get the options.
*/
public function options()
public function options(): HasMany
{
return $this->hasMany(AttributeOptionProxy::modelClass());
}
@ -41,11 +47,24 @@ class Attribute extends TranslatableModel implements AttributeContract
/**
* Scope a query to only include popular users.
*
* @param \Illuminate\Database\Eloquent\Builder $query
* @param \Illuminate\Database\Eloquent\Builder $query
*
* @return \Illuminate\Database\Eloquent\Builder
*/
public function scopeFilterableAttributes($query)
public function scopeFilterableAttributes(Builder $query): Builder
{
return $query->where('is_filterable', 1)->where('swatch_type', '<>', 'image')->orderBy('position');
return $query->where('is_filterable', 1)
->where('swatch_type', '<>', 'image')
->orderBy('position');
}
/**
* Create a new factory instance for the model
*
* @return AttributeFactory
*/
protected static function newFactory(): AttributeFactory
{
return AttributeFactory::new();
}
}

View File

@ -4,65 +4,86 @@ namespace Webkul\Attribute\Models;
use Illuminate\Database\Eloquent\Model;
use Webkul\Product\Models\ProductProxy;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Webkul\Attribute\Database\Factories\AttributeFamilyFactory;
use Webkul\Attribute\Contracts\AttributeFamily as AttributeFamilyContract;
class AttributeFamily extends Model implements AttributeFamilyContract
{
use HasFactory;
public $timestamps = false;
protected $fillable = ['code', 'name'];
protected $fillable = [
'code',
'name',
];
/**
* Get all of the attributes for the attribute groups.
* Get all the attributes for the attribute groups.
*/
public function custom_attributes()
{
return (AttributeProxy::modelClass())::join('attribute_group_mappings', 'attributes.id', '=', 'attribute_group_mappings.attribute_id')
->join('attribute_groups', 'attribute_group_mappings.attribute_group_id', '=', 'attribute_groups.id')
->join('attribute_families', 'attribute_groups.attribute_family_id', '=', 'attribute_families.id')
->where('attribute_families.id', $this->id)
->select('attributes.*');
->join('attribute_groups', 'attribute_group_mappings.attribute_group_id', '=', 'attribute_groups.id')
->join('attribute_families', 'attribute_groups.attribute_family_id', '=', 'attribute_families.id')
->where('attribute_families.id', $this->id)
->select('attributes.*');
}
/**
* Get all of the comparable attributes which belongs to attribute family.
* Get all the comparable attributes which belongs to attribute family.
*/
public function getComparableAttributesBelongsToFamily()
{
return (AttributeProxy::modelClass())::join('attribute_group_mappings', 'attribute_group_mappings.attribute_id', '=', 'attributes.id')
->select('attributes.*')->where('attributes.is_comparable', 1)->distinct()->get();
->select('attributes.*')
->where('attributes.is_comparable', 1)
->distinct()
->get();
}
/**
* Get all of the attributes for the attribute groups.
* Get all the attributes for the attribute groups.
*/
public function getCustomAttributesAttribute()
{
return $this->custom_attributes()->get();
return $this->custom_attributes()
->get();
}
/**
* Get all of the attribute groups.
* Get all the attribute groups.
*/
public function attribute_groups()
public function attribute_groups(): HasMany
{
return $this->hasMany(AttributeGroupProxy::modelClass())->orderBy('position');
return $this->hasMany(AttributeGroupProxy::modelClass())
->orderBy('position');
}
/**
* Get all of the attributes for the attribute groups.
* Get all the attributes for the attribute groups.
*/
public function getConfigurableAttributesAttribute()
{
return $this->custom_attributes()->where('attributes.is_configurable', 1)->where('attributes.type', 'select')->get();
return $this->custom_attributes()
->where('attributes.is_configurable', 1)
->where('attributes.type', 'select')
->get();
}
/**
* Get all of the products.
* Get all the products.
*/
public function products()
public function products(): HasMany
{
return $this->hasMany(ProductProxy::modelClass());
}
protected static function newFactory(): AttributeFamilyFactory
{
return AttributeFamilyFactory::new();
}
}

View File

@ -2,12 +2,16 @@
namespace Webkul\Attribute\Models;
use Illuminate\Support\Facades\Storage;
use Webkul\Core\Eloquent\TranslatableModel;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Webkul\Attribute\Database\Factories\AttributeOptionFactory;
use Webkul\Attribute\Contracts\AttributeOption as AttributeOptionContract;
class AttributeOption extends TranslatableModel implements AttributeOptionContract
{
use HasFactory;
public $timestamps = false;
public $translatedAttributes = ['label'];
@ -22,7 +26,7 @@ class AttributeOption extends TranslatableModel implements AttributeOptionContra
/**
* Get the attribute that owns the attribute option.
*/
public function attribute()
public function attribute(): BelongsTo
{
return $this->belongsTo(AttributeProxy::modelClass());
}
@ -33,10 +37,10 @@ class AttributeOption extends TranslatableModel implements AttributeOptionContra
public function swatch_value_url()
{
if ($this->swatch_value && $this->attribute->swatch_type == 'image') {
return url('cache/small/'.$this->swatch_value);
return url('cache/small/' . $this->swatch_value);
}
return;
return null;
}
/**
@ -46,4 +50,9 @@ class AttributeOption extends TranslatableModel implements AttributeOptionContra
{
return $this->swatch_value_url();
}
protected static function newFactory(): AttributeOptionFactory
{
return AttributeOptionFactory::new();
}
}

View File

@ -2,7 +2,6 @@
namespace Webkul\Attribute\Providers;
use Illuminate\Database\Eloquent\Factory as EloquentFactory;
use Illuminate\Support\ServiceProvider;
class AttributeServiceProvider extends ServiceProvider
@ -12,10 +11,8 @@ class AttributeServiceProvider extends ServiceProvider
*
* @return void
*/
public function boot()
public function boot(): void
{
$this->loadMigrationsFrom(__DIR__ . '/../Database/Migrations');
$this->app->make(EloquentFactory::class)->load(__DIR__ . '/../Database/Factories');
$this->loadMigrationsFrom(__DIR__.'/../Database/Migrations');
}
}

View File

@ -1,17 +1,31 @@
<?php
/** @var \Illuminate\Database\Eloquent\Factory $factory */
namespace Webkul\BookingProduct\Database\Factories;
use Faker\Generator as Faker;
use Webkul\BookingProduct\Models\BookingProduct;
use Illuminate\Database\Eloquent\Factories\Factory;
use Webkul\BookingProduct\Models\BookingProductEventTicket;
$factory->define(BookingProductEventTicket::class, static function (Faker $faker, array $attributes) {
return [
'price' => $faker->randomFloat(4, 3, 900),
'qty' => $faker->numberBetween(100, 1000),
'booking_product_id' => static function () {
return factory(BookingProduct::class)->create(['type' => 'event'])->id;
}
];
});
class BookingProductEventTicketFactory extends Factory
{
/**
* The name of the factory's corresponding model.
*
* @var string
*/
protected $model = BookingProductEventTicket::class;
/**
* Define the model's default state.
*
* @return array
*/
public function definition(): array
{
return [
'price' => $this->faker->randomFloat(4, 3, 900),
'qty' => $this->faker->numberBetween(100, 1000),
'booking_product_id' => BookingProduct::factory(),
];
}
}

View File

@ -1,22 +1,36 @@
<?php
/** @var \Illuminate\Database\Eloquent\Factory $factory */
namespace Webkul\BookingProduct\Database\Factories;
use Carbon\Carbon;
use Faker\Generator as Faker;
use Webkul\BookingProduct\Models\BookingProduct;
use Webkul\Product\Models\Product;
use Illuminate\Database\Eloquent\Factories\Factory;
$factory->define(BookingProduct::class, function (Faker $faker, array $attributes) {
$bookingTypes = ['event'];
class BookingProductFactory extends Factory
{
/**
* The name of the factory's corresponding model.
*
* @var string
*/
protected $model = BookingProduct::class;
return [
'type' => $bookingTypes[array_rand(['event'])],
'qty' => $faker->randomNumber(2),
'available_from' => Carbon::yesterday(),
'available_to' => Carbon::tomorrow(),
'product_id' => function () {
return factory(Product::class)->create(['type' => 'booking'])->id;
}
];
});
/**
* Define the model's default state.
*
* @return array
*/
public function definition(): array
{
$bookingTypes = ['event'];
return [
'type' => $bookingTypes[array_rand(['event'])],
'qty' => $this->faker->randomNumber(2),
'available_from' => Carbon::yesterday(),
'available_to' => Carbon::tomorrow(),
'product_id' => Product::factory(['type' => 'booking']),
];
}
}

View File

@ -3,11 +3,14 @@
namespace Webkul\BookingProduct\Models;
use Illuminate\Database\Eloquent\Model;
use Webkul\Product\Models\ProductProxy;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Webkul\BookingProduct\Database\Factories\BookingProductFactory;
use Webkul\BookingProduct\Contracts\BookingProduct as BookingProductContract;
class BookingProduct extends Model implements BookingProductContract
{
use HasFactory;
protected $fillable = [
'location',
'show_location',
@ -19,7 +22,13 @@ class BookingProduct extends Model implements BookingProductContract
'product_id',
];
protected $with = ['default_slot', 'appointment_slot', 'event_tickets', 'rental_slot', 'table_slot'];
protected $with = [
'default_slot',
'appointment_slot',
'event_tickets',
'rental_slot',
'table_slot',
];
protected $casts = [
'available_from' => 'datetime',
@ -29,7 +38,7 @@ class BookingProduct extends Model implements BookingProductContract
/**
* The Product Default Booking that belong to the product booking.
*/
public function default_slot()
public function default_slot(): \Illuminate\Database\Eloquent\Relations\HasOne
{
return $this->hasOne(BookingProductDefaultSlotProxy::modelClass());
}
@ -37,7 +46,7 @@ class BookingProduct extends Model implements BookingProductContract
/**
* The Product Appointment Booking that belong to the product booking.
*/
public function appointment_slot()
public function appointment_slot(): \Illuminate\Database\Eloquent\Relations\HasOne
{
return $this->hasOne(BookingProductAppointmentSlotProxy::modelClass());
}
@ -45,7 +54,7 @@ class BookingProduct extends Model implements BookingProductContract
/**
* The Product Event Booking that belong to the product booking.
*/
public function event_tickets()
public function event_tickets(): \Illuminate\Database\Eloquent\Relations\HasMany
{
return $this->hasMany(BookingProductEventTicketProxy::modelClass());
}
@ -53,7 +62,7 @@ class BookingProduct extends Model implements BookingProductContract
/**
* The Product Rental Booking that belong to the product booking.
*/
public function rental_slot()
public function rental_slot(): \Illuminate\Database\Eloquent\Relations\HasOne
{
return $this->hasOne(BookingProductRentalSlotProxy::modelClass());
}
@ -61,8 +70,18 @@ class BookingProduct extends Model implements BookingProductContract
/**
* The Product Table Booking that belong to the product booking.
*/
public function table_slot()
public function table_slot(): \Illuminate\Database\Eloquent\Relations\HasOne
{
return $this->hasOne(BookingProductTableSlotProxy::modelClass());
}
/**
* Create a new factory instance for the model.
*
* @return BookingProductFactory
*/
protected static function newFactory(): BookingProductFactory
{
return BookingProductFactory::new();
}
}

View File

@ -3,13 +3,20 @@
namespace Webkul\BookingProduct\Models;
use Webkul\Core\Eloquent\TranslatableModel;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Webkul\BookingProduct\Database\Factories\BookingProductEventTicketFactory;
use Webkul\BookingProduct\Contracts\BookingProductEventTicket as BookingProductEventTicketContract;
class BookingProductEventTicket extends TranslatableModel implements BookingProductEventTicketContract
{
use HasFactory;
public $timestamps = false;
public $translatedAttributes = ['name', 'description'];
public $translatedAttributes = [
'name',
'description',
];
protected $fillable = [
'price',
@ -19,4 +26,14 @@ class BookingProductEventTicket extends TranslatableModel implements BookingProd
'special_price_to',
'booking_product_id',
];
/**
* Create a new factory instance for the model.
*
* @return BookingProductEventTicketFactory
*/
protected static function newFactory(): BookingProductEventTicketFactory
{
return BookingProductEventTicketFactory::new();
}
}

View File

@ -2,7 +2,6 @@
namespace Webkul\BookingProduct\Providers;
use Illuminate\Database\Eloquent\Factory as EloquentFactory;
use Illuminate\Support\ServiceProvider;
class BookingProductServiceProvider extends ServiceProvider
@ -11,7 +10,6 @@ class BookingProductServiceProvider extends ServiceProvider
* Bootstrap services.
*
* @return void
* @throws \Illuminate\Contracts\Container\BindingResolutionException
*/
public function boot(): void
{
@ -28,8 +26,6 @@ class BookingProductServiceProvider extends ServiceProvider
], 'public');
$this->app->register(EventServiceProvider::class);
$this->app->make(EloquentFactory::class)->load(__DIR__ . '/../Database/Factories');
}
/**
@ -39,8 +35,6 @@ class BookingProductServiceProvider extends ServiceProvider
*/
public function register(): void
{
$this->mergeConfigFrom(
dirname(__DIR__) . '/Config/product_types.php', 'product_types'
);
$this->mergeConfigFrom(dirname(__DIR__) . '/Config/product_types.php', 'product_types');
}
}

View File

@ -3,12 +3,16 @@
namespace Webkul\CartRule\Models;
use Illuminate\Database\Eloquent\Model;
use Webkul\Core\Database\Factories\CartRuleFactory;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Webkul\CartRule\Contracts\CartRule as CartRuleContract;
use Webkul\Core\Models\ChannelProxy;
use Webkul\Customer\Models\CustomerGroupProxy;
class CartRule extends Model implements CartRuleContract
{
use HasFactory;
protected $fillable = [
'name',
'description',
@ -105,7 +109,8 @@ class CartRule extends Model implements CartRuleContract
*/
public function coupon_code(): \Illuminate\Database\Eloquent\Relations\HasOne
{
return $this->cart_rule_coupon()->where('is_primary', 1);
return $this->cart_rule_coupon()
->where('is_primary', 1);
}
/**
@ -115,12 +120,23 @@ class CartRule extends Model implements CartRuleContract
*/
public function getCouponCodeAttribute()
{
$coupon = $this->coupon_code()->first();
$coupon = $this->coupon_code()
->first();
if (! $coupon) {
if (!$coupon) {
return;
}
return $coupon->code;
}
/**
* Create a new factory instance for the model.
*
* @return CartRuleFactory
*/
protected static function newFactory(): CartRuleFactory
{
return CartRuleFactory::new();
}
}

View File

@ -3,10 +3,15 @@
namespace Webkul\CartRule\Models;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Webkul\Core\Database\Factories\CartRuleCouponFactory;
use Webkul\CartRule\Contracts\CartRuleCoupon as CartRuleCouponContract;
class CartRuleCoupon extends Model implements CartRuleCouponContract
{
use HasFactory;
protected $fillable = [
'code',
'usage_limit',
@ -21,8 +26,18 @@ class CartRuleCoupon extends Model implements CartRuleCouponContract
/**
* Get the cart rule that owns the cart rule coupon.
*/
public function cart_rule()
public function cart_rule(): BelongsTo
{
return $this->belongsTo(CartRuleProxy::modelClass());
}
/**
* Create a new factory instance for the model
*
* @return CartRuleCouponFactory
*/
protected static function newFactory(): CartRuleCouponFactory
{
return CartRuleCouponFactory::new();
}
}

View File

@ -1,18 +1,62 @@
<?php
use Faker\Generator as Faker;
namespace Webkul\Category\Database\Factories;
use Webkul\Category\Models\Category;
use Illuminate\Database\Eloquent\Factories\Factory;
/** @var \Illuminate\Database\Eloquent\Factory $factory */
$factory->define(Category::class, function (Faker $faker, array $attributes) {
class CategoryFactory extends Factory
{
/**
* The name of the factory's corresponding model.
*
* @var string
*/
protected $model = Category::class;
return [
'status' => 1,
'position' => $faker->randomDigit,
'parent_id' => 1,
/**
* @var string[]
*/
protected $states = [
'inactive',
'rtl',
];
});
$factory->state(Category::class, 'inactive', [
'status' => 0,
]);
/**
* Define the model's default state.
*
* @return array
*/
public function definition(): array
{
return [
'status' => 1,
'position' => $this->faker->randomDigit(),
'parent_id' => 1,
];
}
/**
*
*/
public function inactive(): CategoryFactory
{
return $this->state(function (array $attributes) {
return [
'status' => 0,
];
});
}
/**
* Handle rtl state
*/
public function rtl(): CategoryFactory
{
return $this->state(function (array $attributes) {
return [
'direction' => 'rtl',
];
});
}
}

View File

@ -5,6 +5,9 @@ namespace Webkul\Category\Models;
use Webkul\Core\Eloquent\TranslatableModel;
use Kalnoy\Nestedset\NodeTrait;
use Illuminate\Support\Facades\Storage;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Webkul\Category\Database\Factories\CategoryFactory;
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
use Webkul\Category\Contracts\Category as CategoryContract;
use Webkul\Attribute\Models\AttributeProxy;
@ -20,7 +23,7 @@ use Webkul\Product\Models\ProductProxy;
*/
class Category extends TranslatableModel implements CategoryContract
{
use NodeTrait;
use NodeTrait, HasFactory;
public $translatedAttributes = [
'name',
@ -47,8 +50,9 @@ class Category extends TranslatableModel implements CategoryContract
*/
public function image_url()
{
if (! $this->image)
if (!$this->image) {
return;
}
return Storage::url($this->image);
}
@ -61,28 +65,45 @@ class Category extends TranslatableModel implements CategoryContract
return $this->image_url();
}
/**
/**
* The filterable attributes that belong to the category.
*/
public function filterableAttributes()
public function filterableAttributes(): BelongsToMany
{
return $this->belongsToMany(AttributeProxy::modelClass(), 'category_filterable_attributes')->with(['options' => function($query) {
$query->orderBy('sort_order');
}]);
return $this->belongsToMany(AttributeProxy::modelClass(), 'category_filterable_attributes')
->with([
'options' => function ($query) {
$query->orderBy('sort_order');
},
]);
}
/**
* Getting the root category of a category
*
* @return Category
* @return \Illuminate\Database\Eloquent\Builder|\Illuminate\Database\Eloquent\Model|object
*/
public function getRootCategory(): Category
public function getRootCategory()
{
return Category::where([
['parent_id', '=', null],
['_lft', '<=', $this->_lft],
['_rgt', '>=', $this->_rgt],
])->first();
return self::query()
->where([
[
'parent_id',
'=',
null,
],
[
'_lft',
'<=',
$this->_lft,
],
[
'_rgt',
'>=',
$this->_rgt,
],
])
->first();
}
/**
@ -97,7 +118,7 @@ class Category extends TranslatableModel implements CategoryContract
$categories = [$category];
while (isset($category->parent)) {
$category = $category->parent;
$category = $category->parent;
$categories[] = $category;
}
@ -109,18 +130,19 @@ class Category extends TranslatableModel implements CategoryContract
* will search in root category by default
* is used to minimize the numbers of sql queries for it only uses the already cached tree
*
* @param Category[] $categoryTree
* @param Category[] $categoryTree
*
* @return Category
*/
public function findInTree($categoryTree = null): Category
{
if (! $categoryTree) {
if (!$categoryTree) {
$categoryTree = app(CategoryRepository::class)->getVisibleCategoryTree($this->getRootCategory()->id);
}
$category = $categoryTree->first();
if (! $category) {
if (!$category) {
throw new NotFoundHttpException('category not found in tree');
}
@ -134,8 +156,18 @@ class Category extends TranslatableModel implements CategoryContract
/**
* The products that belong to the category.
*/
public function products()
public function products(): BelongsToMany
{
return $this->belongsToMany(ProductProxy::modelClass(), 'product_categories');
}
/**
* Create a new factory instance for the model.
*
* @return CategoryFactory
*/
protected static function newFactory(): CategoryFactory
{
return CategoryFactory::new();
}
}

View File

@ -2,7 +2,6 @@
namespace Webkul\Category\Providers;
use Illuminate\Database\Eloquent\Factory as EloquentFactory;
use Illuminate\Support\ServiceProvider;
use Webkul\Category\Models\CategoryProxy;
use Webkul\Category\Observers\CategoryObserver;
@ -14,23 +13,10 @@ class CategoryServiceProvider extends ServiceProvider
*
* @return void
*/
public function boot()
public function boot(): void
{
$this->loadMigrationsFrom(__DIR__ . '/../Database/Migrations');
CategoryProxy::observe(CategoryObserver::class);
$this->registerEloquentFactoriesFrom(__DIR__ . '/../Database/Factories');
}
/**
* Register factories.
*
* @param string $path
* @return void
*/
protected function registerEloquentFactoriesFrom($path): void
{
$this->app->make(EloquentFactory::class)->load($path);
}
}

View File

@ -1,15 +1,31 @@
<?php
/** @var \Illuminate\Database\Eloquent\Factory $factory */
namespace Webkul\Checkout\Database\Factories;
use Faker\Generator as Faker;
use Webkul\Checkout\Models\CartAddress;
use Illuminate\Database\Eloquent\Factories\Factory;
$factory->define(CartAddress::class, function (Faker $faker) {
return [
'first_name' => $faker->firstName(),
'last_name' => $faker->lastName,
'email' => $faker->email,
'address_type' => CartAddress::ADDRESS_TYPE_BILLING,
];
});
class CartAddressFactory extends Factory
{
/**
* The name of the factory's corresponding model.
*
* @var string
*/
protected $model = CartAddress::class;
/**
* Define the model's default state.
*
* @return array
*/
public function definition(): array
{
return [
'first_name' => $this->faker->firstName(),
'last_name' => $this->faker->lastName,
'email' => $this->faker->email,
'address_type' => CartAddress::ADDRESS_TYPE_BILLING,
];
}
}

View File

@ -1,41 +1,57 @@
<?php
/** @var \Illuminate\Database\Eloquent\Factory $factory */
namespace Webkul\Checkout\Database\Factories;
use Faker\Generator as Faker;
use Illuminate\Support\Facades\DB;
use Webkul\Customer\Models\Customer;
use Webkul\Checkout\Models\Cart;
use Webkul\Checkout\Models\CartAddress;
use Illuminate\Database\Eloquent\Factories\Factory;
$factory->define(Cart::class, function (Faker $faker) {
$now = date("Y-m-d H:i:s");
class CartFactory extends Factory
{
/**
* The name of the factory's corresponding model.
*
* @var string
*/
protected $model = Cart::class;
$lastOrder = DB::table('orders')
->orderBy('id', 'desc')
->select('id')
->first();
/**
* Define the model's default state.
*
* @return array
*/
public function definition(): array
{
$now = date("Y-m-d H:i:s");
$customer = factory(Customer::class)->create();
$cartAddress = factory(CartAddress::class)->create();
$lastOrder = DB::table('orders')
->orderBy('id', 'desc')
->select('id')
->first();
$customer = Customer::factory()
->create();
return [
'is_guest' => 0,
'is_active' => 1,
'customer_id' => $customer->id,
'customer_email' => $customer->email,
'customer_first_name' => $customer->first_name,
'customer_last_name' => $customer->last_name,
'is_gift' => 0,
'base_currency_code' => 'EUR',
'channel_currency_code' => 'EUR',
'grand_total' => 0.0000,
'base_grand_total' => 0.0000,
'sub_total' => 0.0000,
'base_sub_total' => 0.0000,
'channel_id' => 1,
'created_at' => $now,
'updated_at' => $now,
];
}
}
return [
'is_guest' => 0,
'is_active' => 1,
'customer_id' => $customer->id,
'customer_email' => $customer->email,
'customer_first_name' => $customer->first_name,
'customer_last_name' => $customer->last_name,
'is_gift' => 0,
'base_currency_code' => 'EUR',
'channel_currency_code' => 'EUR',
'grand_total' => 0.0000,
'base_grand_total' => 0.0000,
'sub_total' => 0.0000,
'base_sub_total' => 0.0000,
'channel_id' => 1,
'created_at' => $now,
'updated_at' => $now,
];
});

View File

@ -1,38 +1,55 @@
<?php
/** @var \Illuminate\Database\Eloquent\Factory $factory */
namespace Webkul\Checkout\Database\Factories;
use Faker\Generator as Faker;
use Webkul\Checkout\Models\Cart;
use Webkul\Checkout\Models\CartItem;
use Webkul\Product\Models\Product;
use Illuminate\Database\Eloquent\Factories\Factory;
$factory->define(CartItem::class, function (Faker $faker, array $attributes) {
$now = date("Y-m-d H:i:s");
class CartItemFactory extends Factory
{
/**
* The name of the factory's corresponding model.
*
* @var string
*/
protected $model = CartItem::class;
if (isset($attributes['product_id'])) {
$product = Product::where('id', $attributes['product_id'])->first();
} else {
$product = factory(Product::class)->create();
/**
* Define the model's default state.
*
* @return array
*/
public function definition(): array
{
$now = date("Y-m-d H:i:s");
if (isset($attributes['product_id'])) {
$product = Product::query()
->where('id', $attributes['product_id'])
->first();
} else {
$product = Product::factory()
->create();
}
$fallbackPrice = $this->faker->randomFloat(4, 0, 1000);
return [
'quantity' => 1,
'sku' => $product->sku,
'type' => $product->type,
'name' => $product->name,
'price' => $product->price ?? $fallbackPrice,
'base_price' => $product->price ?? $fallbackPrice,
'total' => $product->price ?? $fallbackPrice,
'base_total' => $product->price ?? $fallbackPrice,
'product_id' => $product->id,
'cart_id' => Cart::factory(),
'created_at' => $now,
'updated_at' => $now,
];
}
$fallbackPrice = $faker->randomFloat(4, 0, 1000);
return [
'quantity' => 1,
'sku' => $product->sku,
'type' => $product->type,
'name' => $product->name,
'price' => $product->price ?? $fallbackPrice,
'base_price' => $product->price ?? $fallbackPrice,
'total' => $product->price ?? $fallbackPrice,
'base_total' => $product->price ?? $fallbackPrice,
'product_id' => $product->id,
'cart_id' => function () {
return factory(Cart::class)->create()->id;
},
'created_at' => $now,
'updated_at' => $now,
];
});
}

View File

@ -1,16 +1,34 @@
<?php
/** @var \Illuminate\Database\Eloquent\Factory $factory */
namespace Webkul\Checkout\Database\Factories;
use Faker\Generator as Faker;
use Webkul\Checkout\Models\CartPayment;
use Illuminate\Database\Eloquent\Factories\Factory;
$factory->define(CartPayment::class, function (Faker $faker) {
$now = date("Y-m-d H:i:s");
class CartPaymentFactory extends Factory
{
/**
* The name of the factory's corresponding model.
*
* @var string
*/
protected $model = CartPayment::class;
/**
* Define the model's default state.
*
* @return array
*/
public function definition(): array
{
$now = date("Y-m-d H:i:s");
return [
'created_at' => $now,
'updated_at' => $now,
];
}
}
return [
'created_at' => $now,
'updated_at' => $now,
];
});

View File

@ -4,9 +4,13 @@ namespace Webkul\Checkout\Models;
use Illuminate\Database\Eloquent\Model;
use Webkul\Checkout\Contracts\Cart as CartContract;
use Webkul\Checkout\Database\Factories\CartFactory;
use Illuminate\Database\Eloquent\Factories\HasFactory;
class Cart extends Model implements CartContract
{
use HasFactory;
protected $table = 'cart';
protected $guarded = [
@ -23,31 +27,35 @@ class Cart extends Model implements CartContract
/**
* To get relevant associated items with the cart instance
*/
public function items() {
return $this->hasMany(CartItemProxy::modelClass())->whereNull('parent_id');
public function items(): \Illuminate\Database\Eloquent\Relations\HasMany
{
return $this->hasMany(CartItemProxy::modelClass())
->whereNull('parent_id');
}
/**
* To get all the associated items with the cart instance even the parent and child items of configurable products
*/
public function all_items() {
public function all_items(): \Illuminate\Database\Eloquent\Relations\HasMany
{
return $this->hasMany(CartItemProxy::modelClass());
}
/**
* Get the addresses for the cart.
*/
public function addresses()
public function addresses(): \Illuminate\Database\Eloquent\Relations\HasMany
{
return $this->hasMany(CartAddressProxy::modelClass());
}
/**
* Get the biling address for the cart.
* Get the billing address for the cart.
*/
public function billing_address()
public function billing_address(): \Illuminate\Database\Eloquent\Relations\HasMany
{
return $this->addresses()->where('address_type', CartAddress::ADDRESS_TYPE_BILLING);
return $this->addresses()
->where('address_type', CartAddress::ADDRESS_TYPE_BILLING);
}
/**
@ -55,15 +63,17 @@ class Cart extends Model implements CartContract
*/
public function getBillingAddressAttribute()
{
return $this->billing_address()->first();
return $this->billing_address()
->first();
}
/**
* Get the shipping address for the cart.
*/
public function shipping_address()
public function shipping_address(): \Illuminate\Database\Eloquent\Relations\HasMany
{
return $this->addresses()->where('address_type', CartAddress::ADDRESS_TYPE_SHIPPING);
return $this->addresses()
->where('address_type', CartAddress::ADDRESS_TYPE_SHIPPING);
}
/**
@ -71,37 +81,41 @@ class Cart extends Model implements CartContract
*/
public function getShippingAddressAttribute()
{
return $this->shipping_address()->first();
return $this->shipping_address()
->first();
}
/**
* Get the shipping rates for the cart.
*/
public function shipping_rates()
public function shipping_rates(): \Illuminate\Database\Eloquent\Relations\HasManyThrough
{
return $this->hasManyThrough(CartShippingRateProxy::modelClass(), CartAddressProxy::modelClass(), 'cart_id', 'cart_address_id');
}
/**
* Get all of the attributes for the attribute groups.
* Get all the attributes for the attribute groups.
*/
public function selected_shipping_rate()
public function selected_shipping_rate(): \Illuminate\Database\Eloquent\Relations\HasManyThrough
{
return $this->shipping_rates()->where('method', $this->shipping_method);
return $this->shipping_rates()
->where('method', $this->shipping_method);
}
/**
* Get all of the attributes for the attribute groups.
* Get all the attributes for the attribute groups.
*/
public function getSelectedShippingRateAttribute()
{
return $this->selected_shipping_rate()->where('method', $this->shipping_method)->first();
return $this->selected_shipping_rate()
->where('method', $this->shipping_method)
->first();
}
/**
* Get the payment associated with the cart.
*/
public function payment()
public function payment(): \Illuminate\Database\Eloquent\Relations\HasOne
{
return $this->hasOne(CartPaymentProxy::modelClass());
}
@ -111,7 +125,7 @@ class Cart extends Model implements CartContract
*
* @return boolean
*/
public function haveStockableItems()
public function haveStockableItems(): bool
{
foreach ($this->items as $item) {
if ($item->product->isStockable()) {
@ -127,10 +141,10 @@ class Cart extends Model implements CartContract
*
* @return boolean
*/
public function hasDownloadableItems()
public function hasDownloadableItems(): bool
{
foreach ($this->items as $item) {
if (stristr($item->type,'downloadable') !== false) {
if (stristr($item->type, 'downloadable') !== false) {
return true;
}
}
@ -141,12 +155,14 @@ class Cart extends Model implements CartContract
/**
* Returns true if cart contains one or many products with quantity box.
* (for example: simple, configurable, virtual)
*
* @return bool
*/
public function hasProductsWithQuantityBox(): bool
{
foreach ($this->items as $item) {
if ($item->product->getTypeInstance()->showQuantityBox() === true) {
if ($item->product->getTypeInstance()
->showQuantityBox() === true) {
return true;
}
}
@ -158,7 +174,7 @@ class Cart extends Model implements CartContract
*
* @return boolean
*/
public function hasGuestCheckoutItems()
public function hasGuestCheckoutItems(): bool
{
foreach ($this->items as $item) {
if ($item->product->getAttribute('guest_checkout') === 0) {
@ -176,10 +192,21 @@ class Cart extends Model implements CartContract
*/
public function checkMinimumOrder(): bool
{
$minimumOrderAmount = (float) core()->getConfigData('sales.orderSettings.minimum-order.minimum_order_amount') ?? 0;
$minimumOrderAmount = (float)(core()->getConfigData('sales.orderSettings.minimum-order.minimum_order_amount') ?? 0);
$cartBaseSubTotal = (float) $this->base_sub_total;
$cartBaseSubTotal = (float)$this->base_sub_total;
return $cartBaseSubTotal >= $minimumOrderAmount;
}
/**
* Create a new factory instance for the model
*
* @return CartFactory
*/
protected static function newFactory(): CartFactory
{
return CartFactory::new();
}
}

View File

@ -3,20 +3,28 @@
namespace Webkul\Checkout\Models;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Webkul\Checkout\Database\Factories\CartAddressFactory;
use Webkul\Checkout\Contracts\CartAddress as CartAddressContract;
use Webkul\Core\Models\Address;
/**
* Class CartAddress
*
* @package Webkul\Checkout\Models
*
* @property integer $cart_id
* @property Cart $cart
* @property Cart $cart
*
*/
class CartAddress extends Address implements CartAddressContract
{
use HasFactory;
public const ADDRESS_TYPE_SHIPPING = 'cart_shipping';
public const ADDRESS_TYPE_BILLING = 'cart_billing';
/**
@ -31,12 +39,12 @@ class CartAddress extends Address implements CartAddressContract
*
* @return void
*/
protected static function boot()
protected static function boot(): void
{
static::addGlobalScope('address_type', static function (Builder $builder) {
$builder->whereIn('address_type', [
self::ADDRESS_TYPE_BILLING,
self::ADDRESS_TYPE_SHIPPING
self::ADDRESS_TYPE_SHIPPING,
]);
});
@ -46,7 +54,7 @@ class CartAddress extends Address implements CartAddressContract
/**
* Get the shipping rates for the cart address.
*/
public function shipping_rates()
public function shipping_rates(): HasMany
{
return $this->hasMany(CartShippingRateProxy::modelClass());
}
@ -54,8 +62,18 @@ class CartAddress extends Address implements CartAddressContract
/**
* Get the cart record associated with the address.
*/
public function cart()
public function cart(): BelongsTo
{
return $this->belongsTo(Cart::class);
}
/**
* Create a new factory instance for the model
*
* @return CartAddressFactory
*/
protected static function newFactory(): CartAddressFactory
{
return CartAddressFactory::new();
}
}

View File

@ -5,11 +5,18 @@ namespace Webkul\Checkout\Models;
use Illuminate\Database\Eloquent\Model;
use Webkul\Product\Models\ProductProxy;
use Webkul\Product\Models\ProductFlatProxy;
use Illuminate\Database\Eloquent\Relations\HasOne;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Webkul\Checkout\Database\Factories\CartItemFactory;
use Webkul\Checkout\Contracts\CartItem as CartItemContract;
class CartItem extends Model implements CartItemContract
{
use HasFactory;
protected $table = 'cart_items';
protected $casts = [
@ -22,7 +29,7 @@ class CartItem extends Model implements CartItemContract
'updated_at',
];
public function product()
public function product(): HasOne
{
return $this->hasOne(ProductProxy::modelClass(), 'id', 'product_id');
}
@ -32,22 +39,22 @@ class CartItem extends Model implements CartItemContract
*/
public function product_flat()
{
return (ProductFlatProxy::modelClass())
::where('product_flat.product_id', $this->product_id)
->where('product_flat.locale', app()->getLocale())
->where('product_flat.channel', core()->getCurrentChannelCode())
->select('product_flat.*');
return (ProductFlatProxy::modelClass())::where('product_flat.product_id', $this->product_id)
->where('product_flat.locale', app()->getLocale())
->where('product_flat.channel', core()->getCurrentChannelCode())
->select('product_flat.*');
}
/**
* Get all of the attributes for the attribute groups.
* Get all the attributes for the attribute groups.
*/
public function getProductFlatAttribute()
{
return $this->product_flat()->first();
return $this->product_flat()
->first();
}
public function cart()
public function cart(): HasOne
{
return $this->hasOne(CartProxy::modelClass(), 'id', 'cart_id');
}
@ -55,7 +62,7 @@ class CartItem extends Model implements CartItemContract
/**
* Get the child item.
*/
public function child()
public function child(): BelongsTo
{
return $this->belongsTo(static::class, 'id', 'parent_id');
}
@ -63,7 +70,7 @@ class CartItem extends Model implements CartItemContract
/**
* Get the parent item record associated with the cart item.
*/
public function parent()
public function parent(): BelongsTo
{
return $this->belongsTo(self::class, 'parent_id');
}
@ -71,8 +78,18 @@ class CartItem extends Model implements CartItemContract
/**
* Get the children items.
*/
public function children()
public function children(): HasMany
{
return $this->hasMany(self::class, 'parent_id');
}
/**
* Create a new factory instance for the model
*
* @return CartItemFactory
*/
protected static function newFactory(): CartItemFactory
{
return CartItemFactory::new();
}
}

View File

@ -3,9 +3,23 @@
namespace Webkul\Checkout\Models;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Webkul\Checkout\Database\Factories\CartPaymentFactory;
use Webkul\Checkout\Contracts\CartPayment as CartPaymentContract;
class CartPayment extends Model implements CartPaymentContract
{
use HasFactory;
protected $table = 'cart_payment';
/**
* Create a new factory instance for the model
*
* @return CartPaymentFactory
*/
protected static function newFactory(): CartPaymentFactory
{
return CartPaymentFactory::new();
}
}

View File

@ -5,11 +5,10 @@ namespace Webkul\Checkout\Providers;
use Illuminate\Support\ServiceProvider;
use Illuminate\Foundation\AliasLoader;
use Webkul\Checkout\Facades\Cart;
use Illuminate\Database\Eloquent\Factory as EloquentFactory;
class CheckoutServiceProvider extends ServiceProvider
{
public function boot()
public function boot(): void
{
include __DIR__ . '/../Http/helpers.php';
@ -18,8 +17,6 @@ class CheckoutServiceProvider extends ServiceProvider
$this->app->register(ModuleServiceProvider::class);
$this->app->register(EventServiceProvider::class);
$this->registerEloquentFactoriesFrom(__DIR__ . '/../Database/Factories');
}
/**
@ -27,7 +24,7 @@ class CheckoutServiceProvider extends ServiceProvider
*
* @return void
*/
public function register()
public function register(): void
{
$this->registerFacades();
}
@ -37,7 +34,7 @@ class CheckoutServiceProvider extends ServiceProvider
*
* @return void
*/
protected function registerFacades()
protected function registerFacades(): void
{
//to make the cart facade and bind the
//alias to the class needed to be called.
@ -51,16 +48,4 @@ class CheckoutServiceProvider extends ServiceProvider
$this->app->bind('cart', 'Webkul\Checkout\Cart');
}
/**
* Register factories.
*
* @param string $path
*
* @return void
*/
protected function registerEloquentFactoriesFrom($path): void
{
$this->app->make(EloquentFactory::class)->load($path);
}
}

View File

@ -145,7 +145,7 @@ class Core
}
/**
* Returns currenct channel models.
* Returns current channel models.
*
* @return \Webkul\Core\Contracts\Channel
*/

View File

@ -1,20 +1,35 @@
<?php
/** @var \Illuminate\Database\Eloquent\Factory $factory */
namespace Webkul\Core\Database\Factories;
use Faker\Generator as Faker;
use Illuminate\Support\Str;
use Webkul\CartRule\Models\CartRule;
use Webkul\CartRule\Models\CartRuleCoupon;
use Illuminate\Database\Eloquent\Factories\Factory;
$factory->define(CartRuleCoupon::class, function (Faker $faker) {
return [
'code' => $faker->uuid(),
'usage_limit' => 100,
'usage_per_customer' => 100,
'type' => 0,
'is_primary' => 1,
'cart_rule_id' => static function () {
return factory(CartRule::class)->create()->id;
},
];
});
class CartRuleCouponFactory extends Factory
{
/**
* The name of the factory's corresponding model.
*
* @var string
*/
protected $model = CartRuleCoupon::class;
/**
* Define the model's default state.
*
* @return array
*/
public function definition(): array
{
return [
'code' => Str::uuid(),
'usage_limit' => 100,
'usage_per_customer' => 100,
'type' => 0,
'is_primary' => 1,
'cart_rule_id' => CartRule::factory(),
];
}
}

View File

@ -1,30 +1,47 @@
<?php
/** @var \Illuminate\Database\Eloquent\Factory $factory */
namespace Webkul\Core\Database\Factories;
use Faker\Generator as Faker;
use Illuminate\Support\Str;
use Webkul\CartRule\Models\CartRule;
use Illuminate\Database\Eloquent\Factories\Factory;
$factory->define(CartRule::class, function (Faker $faker) {
return [
'name' => $faker->uuid,
'description' => $faker->sentence(),
'starts_from' => null,
'ends_till' => null,
'coupon_type' => '1',
'use_auto_generation' => '0',
'usage_per_customer' => '100',
'uses_per_coupon' => '100',
'times_used' => '0',
'condition_type' => '2',
'end_other_rules' => '0',
'uses_attribute_conditions' => '0',
'discount_quantity' => '0',
'discount_step' => '0',
'apply_to_shipping' => '0',
'free_shipping' => '0',
'sort_order' => '0',
'status' => '1',
'conditions' => null,
];
});
class CartRuleFactory extends Factory
{
/**
* The name of the factory's corresponding model.
*
* @var string
*/
protected $model = CartRule::class;
/**
* Define the model's default state.
*
* @return array
*/
public function definition(): array
{
return [
'name' => Str::uuid(),
'description' => $this->faker->sentence(),
'starts_from' => null,
'ends_till' => null,
'coupon_type' => '1',
'use_auto_generation' => '0',
'usage_per_customer' => '100',
'uses_per_coupon' => '100',
'times_used' => '0',
'condition_type' => '2',
'end_other_rules' => '0',
'uses_attribute_conditions' => '0',
'discount_quantity' => '0',
'discount_step' => '0',
'apply_to_shipping' => '0',
'free_shipping' => '0',
'sort_order' => '0',
'status' => '1',
'conditions' => null,
];
}
}

View File

@ -1,39 +1,48 @@
<?php
namespace Webkul\Core\Database\Factories;
use Faker\Generator as Faker;
use Webkul\Category\Models\Category;
use Webkul\Core\Models\Channel;
use Webkul\Core\Models\Currency;
use Webkul\Core\Models\Locale;
use Illuminate\Database\Eloquent\Factories\Factory;
/** @var \Illuminate\Database\Eloquent\Factory $factory */
$factory->define(Channel::class, function (Faker $faker, array $attributes) {
class ChannelFactory extends Factory
{
/**
* The name of the factory's corresponding model.
*
* @var string
*/
protected $model = Channel::class;
$seoTitle = $attributes['seo_title'] ?? $faker->word;
$seoDescription = $attributes['seo_description'] ?? $faker->words(10, true);
$seoKeywords = $attributes['seo_keywords'] ?? $faker->words(3, true);
/**
* Define the model's default state.
*
* @return array
* @throws \JsonException
*/
public function definition(): array
{
$seoTitle = $this->faker->word;
$seoDescription = $this->faker->words(10, true);
$seoKeywords = $this->faker->words(3, true);
$seoData = [
'meta_title' => $seoTitle,
'meta_description' => $seoDescription,
'meta_keywords' => $seoKeywords,
];
$seoData = [
'meta_title' => $seoTitle,
'meta_description' => $seoDescription,
'meta_keywords' => $seoKeywords,
];
unset($attributes['seo_title'], $attributes['seo_description'], $attributes['seo_keywords']);
return [
'code' => $faker->unique()->word,
'name' => $faker->word,
'default_locale_id' => function () {
return factory(Locale::class)->create()->id;
},
'base_currency_id' => function () {
return factory(Currency::class)->create()->id;
},
'root_category_id' => function () {
return factory(Category::class)->create()->id;
},
'home_seo' => json_encode($seoData),
];
});
return [
'code' => $this->faker->unique()->word,
'name' => $this->faker->word,
'default_locale_id' => Locale::factory(),
'base_currency_id' => Currency::factory(),
'root_category_id' => Category::factory(),
'home_seo' => json_encode($seoData, JSON_THROW_ON_ERROR),
];
}
}

View File

@ -1,10 +1,28 @@
<?php
/** @var \Illuminate\Database\Eloquent\Factory $factory */
namespace Webkul\Core\Database\Factories;
$factory->define('channel_inventory_sources', function () {
return [
'channel_id' => core()->getCurrentChannel()->id,
'inventory_source_id' => 1,
];
});
use Illuminate\Database\Eloquent\Factories\Factory;
class ChannelInventorySourceFactory extends Factory
{
/**
* The name of the factory's corresponding model.
*
* @var string
*/
protected $model = 'channel_inventory_sources';
/**
* Define the model's default state.
*
* @return array
*/
public function definition(): array
{
return [
'channel_id' => core()->getCurrentChannel()->id,
'inventory_source_id' => 1,
];
}
}

View File

@ -1,14 +1,30 @@
<?php
namespace Webkul\Core\Database\Factories;
use Faker\Generator as Faker;
use Webkul\Core\Models\Currency;
use Illuminate\Database\Eloquent\Factories\Factory;
/** @var \Illuminate\Database\Eloquent\Factory $factory */
$factory->define(Currency::class, function (Faker $faker, array $attributes) {
class CurrencyFactory extends Factory
{
/**
* The name of the factory's corresponding model.
*
* @var string
*/
protected $model = Currency::class;
return [
'code' => $faker->unique()->currencyCode,
'name' => $faker->word,
];
});
/**
* Define the model's default state.
*
* @return array
*/
public function definition(): array
{
return [
'code' => $this->faker->unique()->currencyCode,
'name' => $this->faker->word,
];
}
}

View File

@ -1,22 +1,52 @@
<?php
use Faker\Generator as Faker;
namespace Webkul\Core\Database\Factories;
use Webkul\Core\Models\Locale;
use Illuminate\Database\Eloquent\Factories\Factory;
/** @var \Illuminate\Database\Eloquent\Factory $factory */
$factory->define(Locale::class, function (Faker $faker, array $attributes) {
class LocaleFactory extends Factory
{
/**
* The name of the factory's corresponding model.
*
* @var string
*/
protected $model = Locale::class;
do {
$languageCode = $faker->languageCode;
} while (Locale::query()->where('code', $languageCode)->exists());
return [
'code' => $languageCode,
'name' => $faker->country,
'direction' => 'ltr',
/**
* @var string[]
*/
protected $states = [
'rtl',
];
});
$factory->state(Category::class, 'rtl', [
'direction' => 'rtl',
]);
/**
* Define the model's default state.
*
* @return array
*/
public function definition(): array
{
do {
$languageCode = $this->faker->languageCode;
} while (Locale::query()
->where('code', $languageCode)
->exists());
return [
'code' => $languageCode,
'name' => $this->faker->country,
'direction' => 'ltr',
];
}
public function rtl(): LocaleFactory
{
return $this->state(function (array $attributes) {
return [
'direction' => 'rtl',
];
});
}
}

View File

@ -1,14 +1,31 @@
<?php
/** @var \Illuminate\Database\Eloquent\Factory $factory */
namespace Webkul\Core\Database\Factories;
use Faker\Generator as Faker;
use Webkul\Core\Models\SubscribersList;
use Illuminate\Database\Eloquent\Factories\Factory;
class SubscriberListFactory extends Factory
{
/**
* The name of the factory's corresponding model.
*
* @var string
*/
protected $model = SubscribersList::class;
/**
* Define the model's default state.
*
* @return array
*/
public function definition(): array
{
return [
'email' => $this->faker->safeEmail,
'is_subscribed' => $this->faker->boolean,
'channel_id' => 1,
];
}
}
$factory->define(SubscribersList::class, function (Faker $faker) {
return [
'email' => $faker->safeEmail,
'is_subscribed' => $faker->boolean,
'channel_id' => 1,
];
});

View File

@ -7,7 +7,7 @@ namespace Webkul\Core\Helpers;
use StdClass;
use Faker\Factory;
use Codeception\Module\Laravel5;
use Codeception\Module\Laravel;
use Webkul\Checkout\Models\Cart;
use Webkul\Product\Models\Product;
use Illuminate\Support\Facades\DB;
@ -30,18 +30,21 @@ use Webkul\Product\Models\ProductDownloadableLinkTranslation;
*
* @package Webkul\Core\Helpers
*/
class Laravel5Helper extends Laravel5
class Laravel5Helper extends Laravel
{
public const SIMPLE_PRODUCT = 1;
public const VIRTUAL_PRODUCT = 2;
public const DOWNLOADABLE_PRODUCT = 3;
public const BOOKING_EVENT_PRODUCT = 4;
/**
* Returns the field name of the given attribute in which a value should be saved inside
* the 'product_attribute_values' table. Depends on the type.
*
* @param string $type
* @param string $type
*
* @return string|null
* @part ORM
@ -146,7 +149,7 @@ class Laravel5Helper extends Laravel5
/**
* Set all session with the given key and value in the array.
*
* @param array $keyValue
* @param array $keyValue
*/
public function setSession(array $keyValue): void
{
@ -169,9 +172,9 @@ class Laravel5Helper extends Laravel5
* By default, the product will be generated as saleable, this means it has a price,
* weight, is active and has a positive inventory stock, if necessary.
*
* @param int $productType see constants in this class for usage
* @param array $configs
* @param array $productStates
* @param int $productType see constants in this class for usage
* @param array $configs
* @param array $productStates
*
* @return \Webkul\Product\Models\Product
* @part ORM
@ -271,7 +274,13 @@ class Laravel5Helper extends Laravel5
private function createProduct(array $attributes = [], array $states = []): Product
{
return factory(Product::class)->states($states)->create($attributes);
return Product::factory()
->state(function () use ($states) {
return [
'type' => $states[0],
];
})
->create($attributes);
}
private function createInventory(int $productId, array $inventoryConfig = []): void
@ -314,17 +323,16 @@ class Laravel5Helper extends Laravel5
$faker = Factory::create();
$brand = Attribute::query()
->where(['code' => 'brand'])
->firstOrFail(); // usually 25
->where(['code' => 'brand'])
->firstOrFail(); // usually 25
if (! AttributeOption::query()
->where(['attribute_id' => $brand->id])
->exists()) {
if (!AttributeOption::query()
->where(['attribute_id' => $brand->id])
->exists()) {
AttributeOption::create([
'admin_name' => 'Webkul Demo Brand (c) 2020',
'attribute_id' => $brand->id,
]);
}
/**
@ -345,17 +353,19 @@ class Laravel5Helper extends Laravel5
'special_price_to' => null,
'special_price' => null,
'price' => $faker->randomFloat(2, 1, 1000),
'weight' => '1.00', // necessary for shipping
'brand' => AttributeOption::query()->firstWhere('attribute_id', $brand->id)->id,
'weight' => '1.00',
// necessary for shipping
'brand' => AttributeOption::query()
->firstWhere('attribute_id', $brand->id)->id,
];
$attributeValues = array_merge($defaultAttributeValues, $attributeValues);
/** @var array $possibleAttributeValues list of the possible attributes a product can have */
$possibleAttributeValues = DB::table('attributes')
->select('id', 'code', 'type')
->get()
->toArray();
->select('id', 'code', 'type')
->get()
->toArray();
foreach ($possibleAttributeValues as $attributeSet) {
$data = [
@ -374,8 +384,8 @@ class Laravel5Helper extends Laravel5
}
/**
* @param string $attributeCode
* @param array $data
* @param string $attributeCode
* @param array $data
*
* @return array
*/
@ -389,7 +399,7 @@ class Laravel5Helper extends Laravel5
'locale',
'channel',
],
'tax_category_id' => [
'tax_category_id' => [
'channel',
],
'short_description' => [
@ -440,5 +450,4 @@ class Laravel5Helper extends Laravel5
return $data;
}
}

View File

@ -1,9 +1,7 @@
<?php
namespace Webkul\Core\Models;
use Carbon\Carbon;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
@ -14,28 +12,28 @@ use Webkul\Core\Contracts\Address as AddressContract;
* Class Address
* @package Webkul\Core\Models
*
* @property string $address_type
* @property integer $customer_id
* @property Customer $customer
* @property string $first_name
* @property string $last_name
* @property string $gender
* @property string $company_name
* @property string $address1
* @property string $address2
* @property string $postcode
* @property string $city
* @property string $state
* @property string $country
* @property string $email
* @property string $phone
* @property boolean $default_address
* @property array $additional
* @property string $address_type
* @property integer $customer_id
* @property Customer $customer
* @property string $first_name
* @property string $last_name
* @property string $gender
* @property string $company_name
* @property string $address1
* @property string $address2
* @property string $postcode
* @property string $city
* @property string $state
* @property string $country
* @property string $email
* @property string $phone
* @property boolean $default_address
* @property array $additional
*
* @property-read integer $id
* @property-read string $name
* @property-read Carbon $created_at
* @property-read Carbon $updated_at
* @property-read string $name
* @property-read Carbon $created_at
* @property-read Carbon $updated_at
*
*/
abstract class Address extends Model implements AddressContract
@ -71,12 +69,12 @@ abstract class Address extends Model implements AddressContract
];
protected $casts = [
'additional' => 'array',
'additional' => 'array',
'default_address' => 'boolean',
];
/**
* Get all of the attributes for the attribute groups.
* Get all the attributes for the attribute groups.
*/
public function getNameAttribute(): string
{

View File

@ -6,10 +6,16 @@ use Illuminate\Support\Facades\Storage;
use Webkul\Category\Models\CategoryProxy;
use Webkul\Core\Eloquent\TranslatableModel;
use Webkul\Inventory\Models\InventorySourceProxy;
use Webkul\Core\Database\Factories\ChannelFactory;
use Webkul\Core\Contracts\Channel as ChannelContract;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
class Channel extends TranslatableModel implements ChannelContract
{
use HasFactory;
protected $fillable = [
'code',
'name',
@ -24,7 +30,7 @@ class Channel extends TranslatableModel implements ChannelContract
'home_seo',
'is_maintenance_on',
'maintenance_mode_text',
'allowed_ips'
'allowed_ips',
];
public $translatedAttributes = [
@ -39,7 +45,7 @@ class Channel extends TranslatableModel implements ChannelContract
/**
* Get the channel locales.
*/
public function locales()
public function locales(): BelongsToMany
{
return $this->belongsToMany(LocaleProxy::modelClass(), 'channel_locales');
}
@ -47,7 +53,7 @@ class Channel extends TranslatableModel implements ChannelContract
/**
* Get the default locale
*/
public function default_locale()
public function default_locale(): BelongsTo
{
return $this->belongsTo(LocaleProxy::modelClass());
}
@ -55,7 +61,7 @@ class Channel extends TranslatableModel implements ChannelContract
/**
* Get the channel locales.
*/
public function currencies()
public function currencies(): BelongsToMany
{
return $this->belongsToMany(CurrencyProxy::modelClass(), 'channel_currencies');
}
@ -63,7 +69,7 @@ class Channel extends TranslatableModel implements ChannelContract
/**
* Get the channel inventory sources.
*/
public function inventory_sources()
public function inventory_sources(): BelongsToMany
{
return $this->belongsToMany(InventorySourceProxy::modelClass(), 'channel_inventory_sources');
}
@ -71,7 +77,7 @@ class Channel extends TranslatableModel implements ChannelContract
/**
* Get the base currency
*/
public function base_currency()
public function base_currency(): BelongsTo
{
return $this->belongsTo(CurrencyProxy::modelClass());
}
@ -79,7 +85,7 @@ class Channel extends TranslatableModel implements ChannelContract
/**
* Get the base currency
*/
public function root_category()
public function root_category(): BelongsTo
{
return $this->belongsTo(CategoryProxy::modelClass(), 'root_category_id');
}
@ -123,4 +129,14 @@ class Channel extends TranslatableModel implements ChannelContract
{
return $this->favicon_url();
}
/**
* Create a new factory instance for the model
*
* @return ChannelFactory
*/
protected static function newFactory(): ChannelFactory
{
return ChannelFactory::new();
}
}

View File

@ -3,10 +3,15 @@
namespace Webkul\Core\Models;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\HasOne;
use Webkul\Core\Database\Factories\CurrencyFactory;
use Webkul\Core\Contracts\Currency as CurrencyContract;
use Illuminate\Database\Eloquent\Factories\HasFactory;
class Currency extends Model implements CurrencyContract
{
use HasFactory;
/**
* The attributes that are mass assignable.
*
@ -21,10 +26,11 @@ class Currency extends Model implements CurrencyContract
/**
* Set currency code in capital
*
* @param string $value
* @param $code
*
* @return void
*/
public function setCodeAttribute($code)
public function setCodeAttribute($code): void
{
$this->attributes['code'] = strtoupper($code);
}
@ -32,8 +38,18 @@ class Currency extends Model implements CurrencyContract
/**
* Get the exchange rate associated with the currency.
*/
public function exchange_rate()
public function exchange_rate(): HasOne
{
return $this->hasOne(CurrencyExchangeRateProxy::modelClass(), 'target_currency');
}
/**
* Create a new factory instance for the model.
*
* @return CurrencyFactory
*/
protected static function newFactory(): CurrencyFactory
{
return CurrencyFactory::new();
}
}

View File

@ -3,10 +3,14 @@
namespace Webkul\Core\Models;
use Illuminate\Database\Eloquent\Model;
use Webkul\Core\Database\Factories\LocaleFactory;
use Webkul\Core\Contracts\Locale as LocaleContract;
use Illuminate\Database\Eloquent\Factories\HasFactory;
class Locale extends Model implements LocaleContract
{
use HasFactory;
/**
* The attributes that are mass assignable.
*
@ -17,4 +21,14 @@ class Locale extends Model implements LocaleContract
'name',
'direction',
];
/**
* Create a new factory instance for the model.
*
* @return LocaleFactory
*/
protected static function newFactory(): LocaleFactory
{
return LocaleFactory::new();
}
}

View File

@ -4,10 +4,15 @@ namespace Webkul\Core\Models;
use Illuminate\Database\Eloquent\Model;
use Webkul\Customer\Models\CustomerProxy;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Webkul\Core\Database\Factories\SubscriberListFactory;
use Webkul\Core\Contracts\SubscribersList as SubscribersListContract;
class SubscribersList extends Model implements SubscribersListContract
{
use HasFactory;
/**
* The attributes that are mass assignable.
*
@ -29,8 +34,18 @@ class SubscribersList extends Model implements SubscribersListContract
/**
* Get the customer associated with the subscription.
*/
public function customer()
public function customer(): BelongsTo
{
return $this->belongsTo(CustomerProxy::modelClass());
}
/**
* Create a new factory instance for the model.
*
* @return SubscriberListFactory
*/
protected static function newFactory(): SubscriberListFactory
{
return SubscriberListFactory::new();
}
}

View File

@ -6,7 +6,7 @@ use Konekt\Concord\BaseModuleServiceProvider;
class CoreModuleServiceProvider extends BaseModuleServiceProvider
{
public function boot()
public function boot(): void
{
if ($this->areMigrationsEnabled()) {
$this->registerMigrations();

View File

@ -3,7 +3,6 @@
namespace Webkul\Core\Providers;
use Illuminate\Contracts\Debug\ExceptionHandler;
use Illuminate\Database\Eloquent\Factory as EloquentFactory;
use Illuminate\Foundation\AliasLoader;
use Illuminate\Support\Facades\Event;
use Illuminate\Support\Facades\Validator;
@ -22,16 +21,13 @@ class CoreServiceProvider extends ServiceProvider
* Bootstrap services.
*
* @return void
* @throws \Illuminate\Contracts\Container\BindingResolutionException
*/
public function boot()
public function boot(): void
{
include __DIR__ . '/../Http/helpers.php';
$this->loadMigrationsFrom(__DIR__ . '/../Database/Migrations');
$this->registerEloquentFactoriesFrom(__DIR__ . '/../Database/Factories');
$this->loadTranslationsFrom(__DIR__ . '/../Resources/lang', 'core');
Validator::extend('slug', 'Webkul\Core\Contracts\Validations\Slug@passes');
@ -42,13 +38,10 @@ class CoreServiceProvider extends ServiceProvider
$this->publishes([
dirname(__DIR__) . '/Config/concord.php' => config_path('concord.php'),
dirname(__DIR__) . '/Config/scout.php' => config_path('scout.php'),
dirname(__DIR__) . '/Config/scout.php' => config_path('scout.php'),
]);
$this->app->bind(
ExceptionHandler::class,
Handler::class
);
$this->app->bind(ExceptionHandler::class, Handler::class);
SliderProxy::observe(SliderObserver::class);
@ -76,7 +69,7 @@ class CoreServiceProvider extends ServiceProvider
*
* @return void
*/
public function register()
public function register(): void
{
$this->registerFacades();
@ -90,7 +83,7 @@ class CoreServiceProvider extends ServiceProvider
*
* @return void
*/
protected function registerFacades()
protected function registerFacades(): void
{
$loader = AliasLoader::getInstance();
$loader->alias('core', CoreFacade::class);
@ -122,24 +115,12 @@ class CoreServiceProvider extends ServiceProvider
]);
}
/**
* Register factories.
*
* @param string $path
* @return void
* @throws \Illuminate\Contracts\Container\BindingResolutionException
*/
protected function registerEloquentFactoriesFrom($path): void
{
$this->app->make(EloquentFactory::class)->load($path);
}
/**
* Register the Blade compiler implementation.
*
* @return void
*/
public function registerBladeCompiler()
public function registerBladeCompiler(): void
{
$this->app->singleton('blade.compiler', function ($app) {
return new BladeCompiler($app['files'], $app['config']['view.compiled']);

View File

@ -1,34 +1,52 @@
<?php
/** @var \Illuminate\Database\Eloquent\Factory $factory */
namespace Webkul\Customer\Database\Factories;
use Faker\Generator as Faker;
use Webkul\Customer\Models\Customer;
use Illuminate\Support\Arr;
use Webkul\Customer\Models\CustomerAddress;
use Illuminate\Database\Eloquent\Factories\Factory;
$factory->define(CustomerAddress::class, function (Faker $faker) {
// use an locale from a country in europe so the vat id can be generated
$fakerIt = \Faker\Factory::create('it_IT');
class CustomerAddressFactory extends Factory
{
/**
* The name of the factory's corresponding model.
*
* @var string
*/
protected $model = CustomerAddress::class;
/**
* Define the model's default state.
*
* @return array
* @throws \Exception
*/
public function definition(): array
{
$fakerIt = \Faker\Factory::create('it_IT');
return [
'customer_id' => Customer::factory(),
'company_name' => $this->faker->company,
'vat_id' => $fakerIt->vatId(),
'first_name' => $this->faker->firstName,
'last_name' => $this->faker->lastName,
'address1' => $this->faker->streetAddress,
'country' => $this->faker->countryCode,
'state' => $this->faker->state,
'city' => $this->faker->city,
'postcode' => $this->faker->postcode,
'phone' => $this->faker->e164PhoneNumber,
'default_address' => Arr::random([
0,
1,
]),
'address_type' => CustomerAddress::ADDRESS_TYPE,
];
}
}
return [
'customer_id' => function () {
return factory(Customer::class)->create()->id;
},
'company_name' => $faker->company,
'vat_id' => $fakerIt->vatId(),
'first_name' => $faker->firstName,
'last_name' => $faker->lastName,
'address1' => $faker->streetAddress,
'country' => $faker->countryCode,
'state' => $faker->state,
'city' => $faker->city,
'postcode' => $faker->postcode,
'phone' => $faker->e164PhoneNumber,
'default_address' => Arr::random([0, 1]),
'address_type' => CustomerAddress::ADDRESS_TYPE,
];
});

View File

@ -1,35 +1,74 @@
<?php
/** @var \Illuminate\Database\Eloquent\Factory $factory */
namespace Webkul\Customer\Database\Factories;
use Faker\Generator as Faker;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Arr;
use Webkul\Customer\Models\Customer;
use Illuminate\Database\Eloquent\Factories\Factory;
$factory->define(Customer::class, function (Faker $faker) {
$now = date("Y-m-d H:i:s");
$password = $faker->password;
return [
'first_name' => $faker->firstName(),
'last_name' => $faker->lastName,
'gender' => Arr::random(['male', 'female', 'other']),
'email' => $faker->email,
'status' => 1,
'password' => Hash::make($password),
'customer_group_id' => 2,
'is_verified' => 1,
'created_at' => $now,
'updated_at' => $now,
'notes' => json_encode(['plain_password' => $password]),
class CustomerFactory extends Factory
{
/**
* The name of the factory's corresponding model.
*
* @var string
*/
protected $model = Customer::class;
/**
* @var array
*/
protected $states = [
'male',
'female',
];
});
$factory->state(Customer::class, 'male', [
'gender' => 'Male',
]);
/**
* Define the model's default state.
*
* @return array
* @throws \Exception
*/
public function definition(): array
{
$now = date("Y-m-d H:i:s");
$password = $this->faker->password;
$factory->state(Customer::class, 'female', [
'gender' => 'Female',
]);
return [
'first_name' => $this->faker->firstName(),
'last_name' => $this->faker->lastName,
'gender' => Arr::random([
'male',
'female',
'other',
]),
'email' => $this->faker->email,
'status' => 1,
'password' => Hash::make($password),
'customer_group_id' => 2,
'is_verified' => 1,
'created_at' => $now,
'updated_at' => $now,
'notes' => json_encode(['plain_password' => $password], JSON_THROW_ON_ERROR),
];
}
public function male(): CustomerFactory
{
return $this->state(function (array $attributes) {
return [
'gender' => 'Male',
];
});
}
public function female(): CustomerFactory
{
return $this->state(function (array $attributes) {
return [
'gender' => 'Female',
];
});
}
}

View File

@ -1,16 +1,33 @@
<?php
/** @var \Illuminate\Database\Eloquent\Factory $factory */
namespace Webkul\Customer\Database\Factories;
use Faker\Generator as Faker;
use Webkul\Customer\Models\CustomerGroup;
use Illuminate\Database\Eloquent\Factories\Factory;
$factory->define(CustomerGroup::class, function (Faker $faker) {
$name = ucfirst($faker->word);
return [
'name' => $name,
'is_user_defined' => $faker->boolean,
'code' => lcfirst($name),
];
});
class CustomerGroupFactory extends Factory
{
/**
* The name of the factory's corresponding model.
*
* @var string
*/
protected $model = CustomerGroup::class;
/**
* Define the model's default state.
*
* @return array
* @throws \Exception
*/
public function definition(): array
{
$name = ucfirst($this->faker->word);
return [
'name' => $name,
'is_user_defined' => $this->faker->boolean,
'code' => lcfirst($name),
];
}
}

View File

@ -3,18 +3,24 @@
namespace Webkul\Customer\Models;
use Illuminate\Notifications\Notifiable;
use Illuminate\Database\Eloquent\Relations\HasOne;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Tymon\JWTAuth\Contracts\JWTSubject;
use Webkul\Checkout\Models\CartProxy;
use Webkul\Sales\Models\OrderProxy;
use Webkul\Core\Models\SubscribersListProxy;
use Webkul\Product\Models\ProductReviewProxy;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Webkul\Customer\Database\Factories\CustomerFactory;
use Webkul\Customer\Notifications\CustomerResetPassword;
use Webkul\Customer\Contracts\Customer as CustomerContract;
use Webkul\Customer\Database\Factories\CustomerAddressFactory;
class Customer extends Authenticatable implements CustomerContract, JWTSubject
{
use Notifiable;
use Notifiable, HasFactory;
protected $table = 'customers';
@ -35,12 +41,16 @@ class Customer extends Authenticatable implements CustomerContract, JWTSubject
'status',
];
protected $hidden = ['password', 'api_token', 'remember_token'];
protected $hidden = [
'password',
'api_token',
'remember_token',
];
/**
* Get the customer full name.
*/
public function getNameAttribute()
public function getNameAttribute(): string
{
return ucfirst($this->first_name) . ' ' . ucfirst($this->last_name);
}
@ -48,32 +58,33 @@ class Customer extends Authenticatable implements CustomerContract, JWTSubject
/**
* Email exists or not
*/
public function emailExists($email)
public function emailExists($email): bool
{
$results = $this->where('email', $email);
$results = $this->where('email', $email);
if ($results->count() == 0) {
if ($results->count() === 0) {
return false;
} else {
return true;
}
return true;
}
/**
* Get the customer group that owns the customer.
*/
public function group()
public function group(): BelongsTo
{
return $this->belongsTo(CustomerGroupProxy::modelClass(), 'customer_group_id');
}
/**
* Send the password reset notification.
*
* @param string $token
* @return void
*/
public function sendPasswordResetNotification($token)
* Send the password reset notification.
*
* @param string $token
*
* @return void
*/
public function sendPasswordResetNotification($token): void
{
$this->notify(new CustomerResetPassword($token));
}
@ -81,7 +92,7 @@ class Customer extends Authenticatable implements CustomerContract, JWTSubject
/**
* Get the customer address that owns the customer.
*/
public function addresses()
public function addresses(): HasMany
{
return $this->hasMany(CustomerAddressProxy::modelClass(), 'customer_id');
}
@ -89,15 +100,16 @@ class Customer extends Authenticatable implements CustomerContract, JWTSubject
/**
* Get default customer address that owns the customer.
*/
public function default_address()
public function default_address(): HasOne
{
return $this->hasOne(CustomerAddressProxy::modelClass(), 'customer_id')->where('default_address', 1);
return $this->hasOne(CustomerAddressProxy::modelClass(), 'customer_id')
->where('default_address', 1);
}
/**
* Customer's relation with wishlist items
*/
public function wishlist_items()
public function wishlist_items(): HasMany
{
return $this->hasMany(WishlistProxy::modelClass(), 'customer_id');
}
@ -105,31 +117,33 @@ class Customer extends Authenticatable implements CustomerContract, JWTSubject
/**
* get all cart inactive cart instance of a customer
*/
public function all_carts()
public function all_carts(): HasMany
{
return $this->hasMany(CartProxy::modelClass(), 'customer_id');
}
/**
* get inactive cart inactive cart instance of a customer
* get inactive cart instance of a customer
*/
public function inactive_carts()
public function inactive_carts(): HasMany
{
return $this->hasMany(CartProxy::modelClass(), 'customer_id')->where('is_active', 0);
return $this->hasMany(CartProxy::modelClass(), 'customer_id')
->where('is_active', 0);
}
/**
* get active cart inactive cart instance of a customer
*/
public function active_carts()
public function active_carts(): HasMany
{
return $this->hasMany(CartProxy::modelClass(), 'customer_id')->where('is_active', 1);
return $this->hasMany(CartProxy::modelClass(), 'customer_id')
->where('is_active', 1);
}
/**
* get all reviews of a customer
*/
public function all_reviews()
*/
public function all_reviews(): HasMany
{
return $this->hasMany(ProductReviewProxy::modelClass(), 'customer_id');
}
@ -137,7 +151,7 @@ class Customer extends Authenticatable implements CustomerContract, JWTSubject
/**
* get all orders of a customer
*/
public function all_orders()
public function all_orders(): HasMany
{
return $this->hasMany(OrderProxy::modelClass(), 'customer_id');
}
@ -157,7 +171,7 @@ class Customer extends Authenticatable implements CustomerContract, JWTSubject
*
* @return array
*/
public function getJWTCustomClaims()
public function getJWTCustomClaims(): array
{
return [];
}
@ -165,8 +179,18 @@ class Customer extends Authenticatable implements CustomerContract, JWTSubject
/**
* Get the customer's subscription.
*/
public function subscription()
public function subscription(): HasOne
{
return $this->hasOne(SubscribersListProxy::modelClass(), 'customer_id');
}
/**
* Create a new factory instance for the model
*
* @return CustomerFactory
*/
protected static function newFactory(): CustomerFactory
{
return CustomerFactory::new();
}
}

View File

@ -4,10 +4,14 @@ namespace Webkul\Customer\Models;
use Illuminate\Database\Eloquent\Builder;
use Webkul\Core\Models\Address;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Webkul\Customer\Database\Factories\CustomerAddressFactory;
use Webkul\Customer\Contracts\CustomerAddress as CustomerAddressContract;
class CustomerAddress extends Address implements CustomerAddressContract
{
use HasFactory;
public const ADDRESS_TYPE = 'customer';
/**
@ -22,7 +26,7 @@ class CustomerAddress extends Address implements CustomerAddressContract
*
* @return void
*/
protected static function boot()
protected static function boot(): void
{
static::addGlobalScope('address_type', static function (Builder $builder) {
$builder->where('address_type', self::ADDRESS_TYPE);
@ -30,4 +34,14 @@ class CustomerAddress extends Address implements CustomerAddressContract
parent::boot();
}
/**
* Create a new factory instance for the model
*
* @return CustomerAddressFactory
*/
protected static function newFactory(): CustomerAddressFactory
{
return CustomerAddressFactory::new();
}
}

View File

@ -1,20 +1,40 @@
<?php
namespace Webkul\Customer\Models;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Webkul\Customer\Database\Factories\CustomerGroupFactory;
use Webkul\Customer\Contracts\CustomerGroup as CustomerGroupContract;
class CustomerGroup extends Model implements CustomerGroupContract
{
use HasFactory;
protected $table = 'customer_groups';
protected $fillable = ['name', 'code', 'is_user_defined'];
protected $fillable = [
'name',
'code',
'is_user_defined',
];
/**
* Get the customers for this group.
*/
public function customers()
*/
public function customers(): HasMany
{
return $this->hasMany(CustomerProxy::modelClass());
}
/**
* Create a new factory instance for the model
*
* @return CustomerGroupFactory
*/
protected static function newFactory(): CustomerGroupFactory
{
return CustomerGroupFactory::new();
}
}

View File

@ -2,10 +2,10 @@
namespace Webkul\Customer\Providers;
use Illuminate\Database\Eloquent\Factory as EloquentFactory;
use Illuminate\Routing\Router;
use Illuminate\Support\ServiceProvider;
use Webkul\Customer\Captcha;
use Illuminate\Database\Eloquent\Factories\Factory;
use Webkul\Customer\Http\Middleware\RedirectIfNotCustomer;
class CustomerServiceProvider extends ServiceProvider
@ -13,9 +13,10 @@ class CustomerServiceProvider extends ServiceProvider
/**
* Bootstrap application services.
*
* @param \Illuminate\Routing\Router $router
* @return void
*/
public function boot(Router $router)
public function boot(Router $router): void
{
$router->aliasMiddleware('customer', RedirectIfNotCustomer::class);
@ -34,41 +35,23 @@ class CustomerServiceProvider extends ServiceProvider
* Register services.
*
* @return void
* @throws \Illuminate\Contracts\Container\BindingResolutionException
*/
public function register()
public function register(): void
{
$this->registerConfig();
$this->registerEloquentFactoriesFrom(__DIR__ . '/../Database/Factories');
$this->app->singleton('captcha', function ($app) {
return new Captcha();
});
}
/**
* Register factories.
*
* @param string $path
* @return void
* @throws \Illuminate\Contracts\Container\BindingResolutionException
*/
protected function registerEloquentFactoriesFrom($path): void
{
$this->app->make(EloquentFactory::class)->load($path);
}
/**
* Register package config.
*
* @return void
*/
protected function registerConfig()
protected function registerConfig(): void
{
$this->mergeConfigFrom(
dirname(__DIR__) . '/Config/system.php',
'core'
);
$this->mergeConfigFrom(dirname(__DIR__) . '/Config/system.php', 'core');
}
}

View File

@ -1,28 +1,44 @@
<?php
/** @var \Illuminate\Database\Eloquent\Factory $factory */
use Faker\Generator as Faker;
use Webkul\Inventory\Models\InventorySource;
namespace Webkul\Inventory\Database\Factories;
$factory->define(InventorySource::class, function (Faker $faker) {
$now = date("Y-m-d H:i:s");
$code = $faker->unique()->word;
return [
'code' => $faker->unique()->word,
'name' => $code,
'description' => $faker->sentence,
'contact_name' => $faker->name,
'contact_email' => $faker->safeEmail,
'contact_number' => $faker->phoneNumber,
'country' => $faker->countryCode,
'state' => $faker->state,
'city' => $faker->city,
'street' => $faker->streetAddress,
'postcode' => $faker->postcode,
'priority' => 0,
'status' => 1,
'created_at' => $now,
'updated_at' => $now,
];
});
use Webkul\Inventory\Models\InventorySource;
use Illuminate\Database\Eloquent\Factories\Factory;
class InventorySourceFactory extends Factory
{
/**
* The name of the factory's corresponding model.
*
* @var string
*/
protected $model = InventorySource::class;
/**
* Define the model's default state.
*
* @return array
*/
public function definition(): array
{
$now = date("Y-m-d H:i:s");
$code = $this->faker->unique()->word;
return [
'code' => $this->faker->unique()->word,
'name' => $code,
'description' => $this->faker->sentence,
'contact_name' => $this->faker->name,
'contact_email' => $this->faker->safeEmail,
'contact_number' => $this->faker->phoneNumber,
'country' => $this->faker->countryCode,
'state' => $this->faker->state,
'city' => $this->faker->city,
'street' => $this->faker->streetAddress,
'postcode' => $this->faker->postcode,
'priority' => 0,
'status' => 1,
'created_at' => $now,
'updated_at' => $now,
];
}
}

View File

@ -3,9 +3,23 @@
namespace Webkul\Inventory\Models;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Webkul\Inventory\Database\Factories\InventorySourceFactory;
use Webkul\Inventory\Contracts\InventorySource as InventorySourceContract;
class InventorySource extends Model implements InventorySourceContract
{
use HasFactory;
protected $guarded = ['_token'];
/**
* Create a new factory instance for the model.
*
* @return InventorySourceFactory
*/
protected static function newFactory(): InventorySourceFactory
{
return InventorySourceFactory::new();
}
}

View File

@ -3,7 +3,6 @@
namespace Webkul\Inventory\Providers;
use Illuminate\Support\ServiceProvider;
use Illuminate\Database\Eloquent\Factory as EloquentFactory;
class InventoryServiceProvider extends ServiceProvider
{
@ -12,11 +11,9 @@ class InventoryServiceProvider extends ServiceProvider
*
* @return void
*/
public function boot()
public function boot(): void
{
$this->loadMigrationsFrom(__DIR__ . '/../Database/Migrations');
$this->app->make(EloquentFactory::class)->load(__DIR__ . '/../Database/Factories');
}
/**
@ -24,7 +21,7 @@ class InventoryServiceProvider extends ServiceProvider
*
* @return void
*/
public function register()
public function register(): void
{
}
}

View File

@ -1,17 +1,31 @@
<?php
/** @var \Illuminate\Database\Eloquent\Factory $factory */
namespace Webkul\Product\Database\Factories;
use Faker\Generator as Faker;
use Webkul\Product\Models\Product;
use Webkul\Product\Models\ProductAttributeValue;
use Illuminate\Database\Eloquent\Factories\Factory;
$factory->define(ProductAttributeValue::class, function (Faker $faker) {
return [
'product_id' => function () {
return factory(Product::class)->create()->id;
},
'locale' => 'en',
'channel' => 'default',
];
});
class ProductAttributeValueFactory extends Factory
{
/**
* The name of the factory's corresponding model.
*
* @var string
*/
protected $model = ProductAttributeValue::class;
/**
* Define the model's default state.
*
* @return array
*/
public function definition(): array
{
return [
//'product_id' => Product::factory(),
'locale' => 'en',
'channel' => 'default',
];
}
}

View File

@ -1,35 +1,41 @@
<?php
/** @var \Illuminate\Database\Eloquent\Factory $factory */
namespace Webkul\Product\Database\Factories;
use Faker\Generator as Faker;
use Webkul\Product\Models\Product;
use Webkul\Product\Models\ProductDownloadableLink;
use Webkul\Product\Models\ProductDownloadableLinkTranslation;
use Illuminate\Database\Eloquent\Factories\Factory;
$factory->define(ProductDownloadableLink::class, function (Faker $faker) {
$now = date("Y-m-d H:i:s");
$filename = 'ProductImageExampleForUpload.jpg';
$filepath = '/tests/_data/';
return [
'url' => '',
'file' => $filepath . $filename,
'file_name' => $filename,
'type' => 'file',
'price' => 0.0000,
'downloads' => $faker->randomNumber(1),
'product_id' => function () {
return factory(Product::class)->create()->id;
},
'created_at' => $now,
'updated_at' => $now,
];
});
class ProductDownloadableLinkFactory extends Factory
{
/**
* The name of the factory's corresponding model.
*
* @var string
*/
protected $model = ProductDownloadableLink::class;
$factory->define(ProductDownloadableLinkTranslation::class, function (Faker $faker) {
return [
'locale' => 'en',
'title' => $faker->word,
];
});
/**
* Define the model's default state.
*
* @return array
*/
public function definition(): array
{
$now = date("Y-m-d H:i:s");
$filename = 'ProductImageExampleForUpload.jpg';
$filepath = '/tests/_data/';
return [
'url' => '',
'file' => $filepath . $filename,
'file_name' => $filename,
'type' => 'file',
'price' => 0.0000,
'downloads' => $this->faker->randomNumber(1),
'product_id' => Product::factory(),
'created_at' => $now,
'updated_at' => $now,
];
}
}

View File

@ -1,17 +0,0 @@
<?php
/** @var \Illuminate\Database\Eloquent\Factory $factory */
use Faker\Generator as Faker;
use Webkul\Product\Models\ProductDownloadableLink;
use Webkul\Product\Models\ProductDownloadableLinkTranslation;
$factory->define(ProductDownloadableLinkTranslation::class, function (Faker $faker) {
return [
'locale' => 'en',
'title' => $faker->word,
'product_downloadable_link_id' => function () {
return factory(ProductDownloadableLink::class)->create()->id;
},
];
});

View File

@ -0,0 +1,31 @@
<?php
namespace Webkul\Product\Database\Factories;
use Webkul\Product\Models\ProductDownloadableLink;
use Illuminate\Database\Eloquent\Factories\Factory;
use Webkul\Product\Models\ProductDownloadableLinkTranslation;
class ProductDownloadableLinkTranslationFactory extends Factory
{
/**
* The name of the factory's corresponding model.
*
* @var string
*/
protected $model = ProductDownloadableLinkTranslation::class;
/**
* Define the model's default state.
*
* @return array
*/
public function definition(): array
{
return [
'locale' => 'en',
'title' => $this->faker->word,
'product_downloadable_link_id' => ProductDownloadableLink::factory(),
];
}
}

View File

@ -1,29 +1,75 @@
<?php
/** @var \Illuminate\Database\Eloquent\Factory $factory */
namespace Webkul\Product\Database\Factories;
use Faker\Generator as Faker;
use Webkul\Product\Models\Product;
use Illuminate\Database\Eloquent\Factories\Factory;
$factory->define(Product::class, function (Faker $faker) {
return [
'sku' => $faker->uuid,
'attribute_family_id' => 1,
class ProductFactory extends Factory
{
/**
* The name of the factory's corresponding model.
*
* @var string
*/
protected $model = Product::class;
/**
* @var string[]
*/
protected $states = [
'simple',
'virtual',
'downloadable',
'booking',
];
});
$factory->state(Product::class, 'simple', [
'type' => 'simple',
]);
/**
* Define the model's default state.
*
* @return array
*/
public function definition(): array
{
return [
'sku' => $this->faker->uuid,
'attribute_family_id' => 1,
];
}
$factory->state(Product::class, 'virtual', [
'type' => 'virtual',
]);
public function simple(): ProductFactory
{
return $this->state(function (array $attributes) {
return [
'type' => 'simple',
];
});
}
$factory->state(Product::class, 'downloadable', [
'type' => 'downloadable',
]);
public function virtual(): ProductFactory
{
return $this->state(function (array $attributes) {
return [
'type' => 'virtual',
];
});
}
$factory->state(Product::class, 'booking', [
'type' => 'booking',
]);
public function downloadable(): ProductFactory
{
return $this->state(function (array $attributes) {
return [
'type' => 'downloadable',
];
});
}
public function booking(): ProductFactory
{
return $this->state(function (array $attributes) {
return [
'type' => 'booking',
];
});
}
}

View File

@ -1,20 +1,32 @@
<?php
/** @var \Illuminate\Database\Eloquent\Factory $factory */
namespace Webkul\Product\Database\Factories;
use Faker\Generator as Faker;
use Webkul\Inventory\Models\InventorySource;
use Webkul\Product\Models\Product;
use Webkul\Product\Models\ProductInventory;
use Illuminate\Database\Eloquent\Factories\Factory;
$factory->define(ProductInventory::class, function (Faker $faker) {
return [
'qty' => $faker->numberBetween(100, 200),
'product_id' => function () {
return factory(Product::class)->create()->id;
},
'inventory_source_id' => function () {
return factory(InventorySource::class)->create()->id;
},
];
});
class ProductInventoryFactory extends Factory
{
/**
* The name of the factory's corresponding model.
*
* @var string
*/
protected $model = ProductInventory::class;
/**
* Define the model's default state.
*
* @return array
*/
public function definition(): array
{
return [
'qty' => $this->faker->numberBetween(100, 200),
'product_id' => Product::factory(),
'inventory_source_id' => InventorySource::factory(),
];
}
}

View File

@ -1,20 +1,33 @@
<?php
/** @var \Illuminate\Database\Eloquent\Factory $factory */
namespace Webkul\Product\Database\Factories;
use Faker\Generator as Faker;
use Webkul\Product\Models\Product;
use Webkul\Product\Models\ProductReview;
use Illuminate\Database\Eloquent\Factories\Factory;
$factory->define(ProductReview::class, function (Faker $faker, array $attributes) {
if (! array_key_exists('product_id', $attributes)) {
throw new InvalidArgumentException('product_id must be provided. You may use $I->haveProduct() to generate a product');
class ProductReviewFactory extends Factory
{
/**
* The name of the factory's corresponding model.
*
* @var string
*/
protected $model = ProductReview::class;
/**
* Define the model's default state.
*
* @return array
*/
public function definition(): array
{
return [
'title' => $this->faker->words(5, true),
'rating' => $this->faker->numberBetween(0, 10),
'status' => 1,
'comment' => $this->faker->sentence(20),
'product_id' => Product::factory(),
];
}
return [
'title' => $faker->words(5, true),
'rating' => $faker->numberBetween(0, 10),
'status' => 1,
'comment' => $faker->sentence(20),
'product_id' => $attributes['product_id'],
];
});
}

View File

@ -1,14 +1,14 @@
<?php
namespace Webkul\Category\Database\Seeders;
namespace Webkul\Product\Database\Seeders;
use Illuminate\Support\Facades\DB;
use Illuminate\Database\Seeder;
class ProductTableSeeder extends Seeder
{
public function run()
public function run(): void
{
dd('running');
//dd('running');
}
}

View File

@ -17,21 +17,21 @@ class GenerateProduct
{
/**
* Product Repository instance
*
*
* @var \Webkul\Product\Repositories\ProductRepository
*/
protected $productRepository;
/**
* AttributeFamily Repository instance
*
*
* @var \Webkul\Product\Repositories\AttributeFamilyRepository
*/
protected $attributeFamilyRepository;
/**
* Product Attribute Types
*
*
* @var array
*/
protected $types;
@ -70,7 +70,7 @@ class GenerateProduct
/**
* This brand option needs to be available so that the generated product
* can be linked to the order_brands table after checkout.
*
*
* @return void
*/
public function generateDemoBrand()

View File

@ -3,18 +3,26 @@
namespace Webkul\Product\Models;
use Exception;
use Illuminate\Support\Collection;
use Illuminate\Database\Eloquent\Model;
use Webkul\Attribute\Models\AttributeFamilyProxy;
use Webkul\Attribute\Models\AttributeProxy;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Webkul\Product\Database\Factories\ProductFactory;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Webkul\Attribute\Repositories\AttributeRepository;
use Webkul\Category\Models\CategoryProxy;
use Webkul\Inventory\Models\InventorySourceProxy;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Webkul\Product\Contracts\Product as ProductContract;
use Webkul\Product\Database\Eloquent\Builder;
use Webkul\Product\Type\AbstractType;
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
class Product extends Model implements ProductContract
{
use HasFactory;
/**
* The attributes that are mass assignable.
*
@ -33,7 +41,7 @@ class Product extends Model implements ProductContract
* @var $casts
*/
protected $casts = [
'additional' => 'array'
'additional' => 'array',
];
/**
@ -55,7 +63,7 @@ class Product extends Model implements ProductContract
*
* @return void
*/
protected static function booted()
protected static function booted(): void
{
parent::boot();
@ -77,7 +85,7 @@ class Product extends Model implements ProductContract
*
* @return void
*/
public function refreshloadedAttributeValues()
public function refreshloadedAttributeValues(): void
{
self::$loadedAttributeValues = [];
}
@ -85,7 +93,7 @@ class Product extends Model implements ProductContract
/**
* Get the product attribute family that owns the product.
*/
public function attribute_family()
public function attribute_family(): BelongsTo
{
return $this->belongsTo(AttributeFamilyProxy::modelClass());
}
@ -93,7 +101,7 @@ class Product extends Model implements ProductContract
/**
* Get the product attribute values that owns the product.
*/
public function attribute_values()
public function attribute_values(): HasMany
{
return $this->hasMany(ProductAttributeValueProxy::modelClass());
}
@ -102,7 +110,7 @@ class Product extends Model implements ProductContract
* Get the product flat entries that are associated with product.
* May be one for each locale and each channel.
*/
public function product_flats()
public function product_flats(): HasMany
{
return $this->hasMany(ProductFlatProxy::modelClass(), 'product_id');
}
@ -110,7 +118,7 @@ class Product extends Model implements ProductContract
/**
* Get the product variants that owns the product.
*/
public function variants()
public function variants(): HasMany
{
return $this->hasMany(static::class, 'parent_id');
}
@ -118,7 +126,7 @@ class Product extends Model implements ProductContract
/**
* Get the product reviews that owns the product.
*/
public function reviews()
public function reviews(): HasMany
{
return $this->hasMany(ProductReviewProxy::modelClass());
}
@ -126,7 +134,7 @@ class Product extends Model implements ProductContract
/**
* Get the product that owns the product.
*/
public function parent()
public function parent(): BelongsTo
{
return $this->belongsTo(static::class, 'parent_id');
}
@ -134,7 +142,7 @@ class Product extends Model implements ProductContract
/**
* The categories that belong to the product.
*/
public function categories()
public function categories(): BelongsToMany
{
return $this->belongsToMany(CategoryProxy::modelClass(), 'product_categories');
}
@ -142,7 +150,7 @@ class Product extends Model implements ProductContract
/**
* The inventories that belong to the product.
*/
public function inventories()
public function inventories(): HasMany
{
return $this->hasMany(ProductInventoryProxy::modelClass(), 'product_id');
}
@ -150,7 +158,7 @@ class Product extends Model implements ProductContract
/**
* The ordered inventories that belong to the product.
*/
public function ordered_inventories()
public function ordered_inventories(): HasMany
{
return $this->hasMany(ProductOrderedInventoryProxy::modelClass(), 'product_id');
}
@ -158,15 +166,16 @@ class Product extends Model implements ProductContract
/**
* The inventory sources that belong to the product.
*/
public function inventory_sources()
public function inventory_sources(): BelongsToMany
{
return $this->belongsToMany(InventorySourceProxy::modelClass(), 'product_inventories')->withPivot('id', 'qty');
return $this->belongsToMany(InventorySourceProxy::modelClass(), 'product_inventories')
->withPivot('id', 'qty');
}
/**
* The super attributes that belong to the product.
*/
public function super_attributes()
public function super_attributes(): BelongsToMany
{
return $this->belongsToMany(AttributeProxy::modelClass(), 'product_super_attributes');
}
@ -174,7 +183,7 @@ class Product extends Model implements ProductContract
/**
* The images that belong to the product.
*/
public function images()
public function images(): HasMany
{
return $this->hasMany(ProductImageProxy::modelClass(), 'product_id');
}
@ -182,7 +191,7 @@ class Product extends Model implements ProductContract
/**
* The videos that belong to the product.
*/
public function videos()
public function videos(): HasMany
{
return $this->hasMany(ProductVideoProxy::modelClass(), 'product_id');
}
@ -192,39 +201,43 @@ class Product extends Model implements ProductContract
*/
public function getBaseImageUrlAttribute()
{
$image = $this->images()->first();
$image = $this->images()
->first();
return $image ? $image->url : null;
return $image->url ?? null;
}
/**
* The related products that belong to the product.
*/
public function related_products()
public function related_products(): BelongsToMany
{
return $this->belongsToMany(static::class, 'product_relations', 'parent_id', 'child_id')->limit(4);
return $this->belongsToMany(static::class, 'product_relations', 'parent_id', 'child_id')
->limit(4);
}
/**
* The up sells that belong to the product.
*/
public function up_sells()
public function up_sells(): BelongsToMany
{
return $this->belongsToMany(static::class, 'product_up_sells', 'parent_id', 'child_id')->limit(4);
return $this->belongsToMany(static::class, 'product_up_sells', 'parent_id', 'child_id')
->limit(4);
}
/**
* The cross sells that belong to the product.
*/
public function cross_sells()
public function cross_sells(): BelongsToMany
{
return $this->belongsToMany(static::class, 'product_cross_sells', 'parent_id', 'child_id')->limit(4);
return $this->belongsToMany(static::class, 'product_cross_sells', 'parent_id', 'child_id')
->limit(4);
}
/**
* The images that belong to the product.
*/
public function downloadable_samples()
public function downloadable_samples(): HasMany
{
return $this->hasMany(ProductDownloadableSampleProxy::modelClass());
}
@ -232,7 +245,7 @@ class Product extends Model implements ProductContract
/**
* The images that belong to the product.
*/
public function downloadable_links()
public function downloadable_links(): HasMany
{
return $this->hasMany(ProductDownloadableLinkProxy::modelClass());
}
@ -240,7 +253,7 @@ class Product extends Model implements ProductContract
/**
* Get the grouped products that owns the product.
*/
public function grouped_products()
public function grouped_products(): HasMany
{
return $this->hasMany(ProductGroupedProductProxy::modelClass());
}
@ -248,7 +261,7 @@ class Product extends Model implements ProductContract
/**
* Get the bundle options that owns the product.
*/
public function bundle_options()
public function bundle_options(): HasMany
{
return $this->hasMany(ProductBundleOptionProxy::modelClass());
}
@ -256,7 +269,7 @@ class Product extends Model implements ProductContract
/**
* Get the product customer group prices that owns the product.
*/
public function customer_group_prices()
public function customer_group_prices(): HasMany
{
return $this->hasMany(ProductCustomerGroupPriceProxy::modelClass());
}
@ -264,22 +277,24 @@ class Product extends Model implements ProductContract
/**
* Get inventory source quantity.
*
* @param integer $qty
* @param $inventorySourceId
*
* @return bool
*/
public function inventory_source_qty($inventorySourceId)
public function inventory_source_qty($inventorySourceId): bool
{
return $this->inventories()
->where('inventory_source_id', $inventorySourceId)
->sum('qty');
->where('inventory_source_id', $inventorySourceId)
->sum('qty');
}
/**
* Get type instance.
*
* @return AbstractType
* @throws \Exception
*/
public function getTypeInstance()
public function getTypeInstance(): AbstractType
{
if ($this->typeInstance) {
return $this->typeInstance;
@ -288,9 +303,7 @@ class Product extends Model implements ProductContract
$this->typeInstance = app(config('product_types.' . $this->type . '.class'));
if (! $this->typeInstance instanceof AbstractType) {
throw new Exception(
"Please ensure the product type '{$this->type}' is configured in your application."
);
throw new Exception("Please ensure the product type '{$this->type}' is configured in your application.");
}
$this->typeInstance->setProduct($this);
@ -301,61 +314,76 @@ class Product extends Model implements ProductContract
/**
* Is saleable.
*
* @param string $key
* @param string $key
*
* @return bool
* @throws \Exception
*/
public function isSaleable()
public function isSaleable(): bool
{
return $this->getTypeInstance()->isSaleable();
return $this->getTypeInstance()
->isSaleable();
}
/**
* Total quantity.
*
* @return integer
* @throws \Exception
*/
public function totalQuantity()
public function totalQuantity(): int
{
return $this->getTypeInstance()->totalQuantity();
return $this->getTypeInstance()
->totalQuantity();
}
/**
* Have sufficient quantity.
*
* @param int $qty
* @param int $qty
*
* @return bool
* @throws \Exception
*/
public function haveSufficientQuantity(int $qty): bool
{
return $this->getTypeInstance()->haveSufficientQuantity($qty);
return $this->getTypeInstance()
->haveSufficientQuantity($qty);
}
/**
* Is stockable.
*
* @return bool
* @throws \Exception
*/
public function isStockable()
public function isStockable(): bool
{
return $this->getTypeInstance()->isStockable();
return $this->getTypeInstance()
->isStockable();
}
/**
* Get an attribute from the model.
*
* @param string $key
* @param string $key
*
* @return mixed
*/
public function getAttribute($key)
{
if (! method_exists(static::class, $key)
&& ! in_array($key, ['pivot', 'parent_id', 'attribute_family_id'])
&& ! isset($this->attributes[$key])
) {
&& ! in_array($key, [
'pivot',
'parent_id',
'attribute_family_id',
])
&& ! isset($this->attributes[$key])) {
if (isset($this->id)) {
$this->attributes[$key] = '';
$attribute = core()->getSingletonInstance(AttributeRepository::class)
$attribute = core()
->getSingletonInstance(AttributeRepository::class)
->getAttributeByCode($key);
$this->attributes[$key] = $this->getCustomAttributeValue($attribute);
@ -370,14 +398,16 @@ class Product extends Model implements ProductContract
/**
* Retrieve product attributes.
*
* @param Group $group
* @param bool $skipSuperAttribute
* @param Group $group
* @param bool $skipSuperAttribute
*
* @return Collection
* @return \Illuminate\Support\Collection
* @throws \Exception
*/
public function getEditableAttributes($group = null, $skipSuperAttribute = true)
public function getEditableAttributes($group = null, $skipSuperAttribute = true): Collection
{
return $this->getTypeInstance()->getEditableAttributes($group, $skipSuperAttribute);
return $this->getTypeInstance()
->getEditableAttributes($group, $skipSuperAttribute);
}
/**
@ -394,24 +424,34 @@ class Product extends Model implements ProductContract
$locale = core()->checkRequestedLocaleCodeInRequestedChannel();
$channel = core()->getRequestedChannelCode();
if (
array_key_exists($this->id, self::$loadedAttributeValues)
&& array_key_exists($attribute->id, self::$loadedAttributeValues[$this->id])
) {
if (array_key_exists($this->id, self::$loadedAttributeValues)
&& array_key_exists($attribute->id, self::$loadedAttributeValues[$this->id])) {
return self::$loadedAttributeValues[$this->id][$attribute->id];
}
if ($attribute->value_per_channel) {
if ($attribute->value_per_locale) {
$attributeValue = $this->attribute_values()->where('channel', $channel)->where('locale', $locale)->where('attribute_id', $attribute->id)->first();
$attributeValue = $this->attribute_values()
->where('channel', $channel)
->where('locale', $locale)
->where('attribute_id', $attribute->id)
->first();
} else {
$attributeValue = $this->attribute_values()->where('channel', $channel)->where('attribute_id', $attribute->id)->first();
$attributeValue = $this->attribute_values()
->where('channel', $channel)
->where('attribute_id', $attribute->id)
->first();
}
} else {
if ($attribute->value_per_locale) {
$attributeValue = $this->attribute_values()->where('locale', $locale)->where('attribute_id', $attribute->id)->first();
$attributeValue = $this->attribute_values()
->where('locale', $locale)
->where('attribute_id', $attribute->id)
->first();
} else {
$attributeValue = $this->attribute_values()->where('attribute_id', $attribute->id)->first();
$attributeValue = $this->attribute_values()
->where('attribute_id', $attribute->id)
->first();
}
}
@ -423,7 +463,7 @@ class Product extends Model implements ProductContract
*
* @return array
*/
public function attributesToArray()
public function attributesToArray(): array
{
$attributes = parent::attributesToArray();
@ -448,6 +488,7 @@ class Product extends Model implements ProductContract
* Overrides the default Eloquent query builder.
*
* @param \Illuminate\Database\Query\Builder $query
*
* @return \Webkul\Product\Database\Eloquent\Builder
*/
public function newEloquentBuilder($query)
@ -476,7 +517,7 @@ class Product extends Model implements ProductContract
*
* @return object
*/
public function checkInLoadedFamilyAttributes()
public function checkInLoadedFamilyAttributes(): object
{
static $loadedFamilyAttributes = [];
@ -484,7 +525,18 @@ class Product extends Model implements ProductContract
return $loadedFamilyAttributes[$this->attribute_family_id];
}
return $loadedFamilyAttributes[$this->attribute_family_id] = core()->getSingletonInstance(AttributeRepository::class)
return $loadedFamilyAttributes[$this->attribute_family_id] = core()
->getSingletonInstance(AttributeRepository::class)
->getFamilyAttributes($this->attribute_family);
}
/**
* Create a new factory instance for the model.
*
* @return ProductFactory
*/
protected static function newFactory(): ProductFactory
{
return ProductFactory::new();
}
}

View File

@ -4,10 +4,15 @@ namespace Webkul\Product\Models;
use Illuminate\Database\Eloquent\Model;
use Webkul\Attribute\Models\AttributeProxy;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Webkul\Product\Database\Factories\ProductAttributeValueFactory;
use Webkul\Product\Contracts\ProductAttributeValue as ProductAttributeValueContract;
class ProductAttributeValue extends Model implements ProductAttributeValueContract
{
use HasFactory;
/**
* Indicates if the model should be timestamped.
*
@ -21,17 +26,17 @@ class ProductAttributeValue extends Model implements ProductAttributeValueContra
* @var array
*/
public static $attributeTypeFields = [
'text' => 'text_value',
'textarea' => 'text_value',
'price' => 'float_value',
'boolean' => 'boolean_value',
'select' => 'integer_value',
'text' => 'text_value',
'textarea' => 'text_value',
'price' => 'float_value',
'boolean' => 'boolean_value',
'select' => 'integer_value',
'multiselect' => 'text_value',
'datetime' => 'datetime_value',
'date' => 'date_value',
'file' => 'text_value',
'image' => 'text_value',
'checkbox' => 'text_value',
'datetime' => 'datetime_value',
'date' => 'date_value',
'file' => 'text_value',
'image' => 'text_value',
'checkbox' => 'text_value',
];
/**
@ -56,7 +61,7 @@ class ProductAttributeValue extends Model implements ProductAttributeValueContra
/**
* Get the attribute that owns the attribute value.
*/
public function attribute()
public function attribute(): BelongsTo
{
return $this->belongsTo(AttributeProxy::modelClass());
}
@ -64,8 +69,18 @@ class ProductAttributeValue extends Model implements ProductAttributeValueContra
/**
* Get the product that owns the attribute value.
*/
public function product()
public function product(): BelongsTo
{
return $this->belongsTo(ProductProxy::modelClass());
}
/**
* Create a new factory instance for the model.
*
* @return ProductAttributeValueFactory
*/
protected static function newFactory(): ProductAttributeValueFactory
{
return ProductAttributeValueFactory::new();
}
}

View File

@ -4,10 +4,14 @@ namespace Webkul\Product\Models;
use Webkul\Core\Eloquent\TranslatableModel;
use Illuminate\Support\Facades\Storage;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Webkul\Product\Database\Factories\ProductDownloadableLinkFactory;
use Webkul\Product\Contracts\ProductDownloadableLink as ProductDownloadableLinkContract;
class ProductDownloadableLink extends TranslatableModel implements ProductDownloadableLinkContract
{
use HasFactory;
public $translatedAttributes = ['title'];
protected $fillable = [
@ -31,7 +35,7 @@ class ProductDownloadableLink extends TranslatableModel implements ProductDownlo
/**
* Get the product that owns the image.
*/
public function product()
public function product(): \Illuminate\Database\Eloquent\Relations\BelongsTo
{
return $this->belongsTo(ProductProxy::modelClass());
}
@ -39,7 +43,7 @@ class ProductDownloadableLink extends TranslatableModel implements ProductDownlo
/**
* Get image url for the file.
*/
public function file_url()
public function file_url(): string
{
return Storage::url($this->path);
}
@ -47,7 +51,7 @@ class ProductDownloadableLink extends TranslatableModel implements ProductDownlo
/**
* Get image url for the file.
*/
public function getFileUrlAttribute()
public function getFileUrlAttribute(): string
{
return $this->file_url();
}
@ -55,7 +59,7 @@ class ProductDownloadableLink extends TranslatableModel implements ProductDownlo
/**
* Get image url for the sample file.
*/
public function sample_file_url()
public function sample_file_url(): string
{
return Storage::url($this->path);
}
@ -63,7 +67,7 @@ class ProductDownloadableLink extends TranslatableModel implements ProductDownlo
/**
* Get image url for the sample file.
*/
public function getSampleFileUrlAttribute()
public function getSampleFileUrlAttribute(): string
{
return $this->sample_file_url();
}
@ -71,13 +75,13 @@ class ProductDownloadableLink extends TranslatableModel implements ProductDownlo
/**
* @return array
*/
public function toArray()
public function toArray(): array
{
$array = parent::toArray();
$translation = $this->translate(core()->getRequestedLocaleCode());
$array['title'] = $translation ? $translation->title : '';
$array['title'] = $translation->title ?? '';
$array['file_url'] = $this->file ? Storage::url($this->file) : null;
@ -85,4 +89,14 @@ class ProductDownloadableLink extends TranslatableModel implements ProductDownlo
return $array;
}
/**
* Create a new factory instance for the model.
*
* @return ProductDownloadableLinkFactory
*/
protected static function newFactory(): ProductDownloadableLinkFactory
{
return ProductDownloadableLinkFactory::new();
}
}

View File

@ -3,11 +3,25 @@
namespace Webkul\Product\Models;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Webkul\Product\Database\Factories\ProductDownloadableLinkTranslationFactory;
use Webkul\Product\Contracts\ProductDownloadableLinkTranslation as ProductDownloadableLinkTranslationContract;
class ProductDownloadableLinkTranslation extends Model implements ProductDownloadableLinkTranslationContract
{
use HasFactory;
public $timestamps = false;
protected $fillable = ['title'];
/**
* Create a new factory instance for the model.
*
* @return ProductDownloadableLinkTranslationFactory
*/
protected static function newFactory(): ProductDownloadableLinkTranslationFactory
{
return ProductDownloadableLinkTranslationFactory::new();
}
}

View File

@ -4,10 +4,15 @@ namespace Webkul\Product\Models;
use Illuminate\Database\Eloquent\Model;
use Webkul\Inventory\Models\InventorySourceProxy;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Webkul\Product\Database\Factories\ProductInventoryFactory;
use Webkul\Product\Contracts\ProductInventory as ProductInventoryContract;
class ProductInventory extends Model implements ProductInventoryContract
{
use HasFactory;
public $timestamps = false;
protected $fillable = [
@ -20,7 +25,7 @@ class ProductInventory extends Model implements ProductInventoryContract
/**
* Get the product attribute family that owns the product.
*/
public function inventory_source()
public function inventory_source(): BelongsTo
{
return $this->belongsTo(InventorySourceProxy::modelClass());
}
@ -28,8 +33,18 @@ class ProductInventory extends Model implements ProductInventoryContract
/**
* Get the product that owns the product inventory.
*/
public function product()
public function product(): BelongsTo
{
return $this->belongsTo(ProductProxy::modelClass());
}
/**
* Create a new factory instance for the model.
*
* @return ProductInventoryFactory
*/
protected static function newFactory(): ProductInventoryFactory
{
return ProductInventoryFactory::new();
}
}

View File

@ -4,11 +4,16 @@ namespace Webkul\Product\Models;
use Illuminate\Database\Eloquent\Model;
use Webkul\Customer\Models\CustomerProxy;
use Webkul\Product\Models\Product;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Webkul\Product\Database\Factories\ProductReviewFactory;
use Webkul\Product\Contracts\ProductReview as ProductReviewContract;
class ProductReview extends Model implements ProductReviewContract
{
use HasFactory;
protected $fillable = [
'comment',
'title',
@ -22,7 +27,7 @@ class ProductReview extends Model implements ProductReviewContract
/**
* Get the product attribute family that owns the product.
*/
public function customer()
public function customer(): BelongsTo
{
return $this->belongsTo(CustomerProxy::modelClass());
}
@ -30,7 +35,7 @@ class ProductReview extends Model implements ProductReviewContract
/**
* Get the product.
*/
public function product()
public function product(): BelongsTo
{
return $this->belongsTo(ProductProxy::modelClass());
}
@ -38,8 +43,18 @@ class ProductReview extends Model implements ProductReviewContract
/**
* The images that belong to the review.
*/
public function images()
public function images(): HasMany
{
return $this->hasMany(ProductReviewImageProxy::modelClass(), 'review_id');
}
/**
* Create a new factory instance for the model.
*
* @return ProductReviewFactory
*/
protected static function newFactory(): ProductReviewFactory
{
return ProductReviewFactory::new();
}
}

View File

@ -2,7 +2,6 @@
namespace Webkul\Product\Providers;
use Illuminate\Database\Eloquent\Factory as EloquentFactory;
use Illuminate\Support\ServiceProvider;
use Webkul\Product\Models\ProductProxy;
@ -23,14 +22,12 @@ class ProductServiceProvider extends ServiceProvider
*
* @return void
*/
public function boot()
public function boot(): void
{
include __DIR__ . '/../Http/helpers.php';
$this->loadMigrationsFrom(__DIR__ . '/../Database/Migrations');
$this->app->make(EloquentFactory::class)->load(__DIR__ . '/../Database/Factories');
$this->app->register(EventServiceProvider::class);
$this->publishes([
@ -52,8 +49,6 @@ class ProductServiceProvider extends ServiceProvider
$this->registerCommands();
$this->registerFacades();
$this->registerEloquentFactoriesFrom(__DIR__ . '/../Database/Factories');
}
/**
@ -63,9 +58,7 @@ class ProductServiceProvider extends ServiceProvider
*/
public function registerConfig(): void
{
$this->mergeConfigFrom(
dirname(__DIR__) . '/Config/product_types.php', 'product_types'
);
$this->mergeConfigFrom(dirname(__DIR__) . '/Config/product_types.php', 'product_types');
}
/**
@ -80,24 +73,12 @@ class ProductServiceProvider extends ServiceProvider
}
}
/**
* Register factories.
*
* @param string $path
* @return void
*/
protected function registerEloquentFactoriesFrom($path): void
{
$this->app->make(EloquentFactory::class)->load($path);
}
/**
* Register Bouncer as a singleton.
*
* @return void
*/
protected function registerFacades()
protected function registerFacades(): void
{
// Product image
$loader = AliasLoader::getInstance();

View File

@ -1,26 +0,0 @@
<?php
/** @var \Illuminate\Database\Eloquent\Factory $factory */
use Faker\Generator as Faker;
use Webkul\Inventory\Models\InventorySource;
$factory->define(InventorySource::class, function (Faker $faker) {
$code = $faker->unique()->word;
return [
'code' => $faker->unique()->word,
'name' => $code,
'description' => $faker->sentence,
'contact_name' => $faker->name,
'contact_email' => $faker->safeEmail,
'contact_number' => $faker->phoneNumber,
'country' => $faker->countryCode,
'state' => $faker->state,
'city' => $faker->city,
'street' => $faker->streetAddress,
'postcode' => $faker->postcode,
'priority' => 0,
'status' => 1,
];
});

View File

@ -1,61 +1,94 @@
<?php
/** @var \Illuminate\Database\Eloquent\Factory $factory */
namespace Webkul\Sales\Database\Factories;
use Faker\Generator as Faker;
use Webkul\Sales\Models\Invoice;
use Webkul\Sales\Models\Order;
use Webkul\Sales\Models\OrderAddress;
use Illuminate\Database\Eloquent\Factories\Factory;
$factory->define(Invoice::class, function (Faker $faker, array $attributes) {
$subTotal = $faker->randomFloat(2);
$shippingAmount = $faker->randomFloat(2);
$taxAmount = $faker->randomFloat(2);
class InvoiceFactory extends Factory
{
/**
* The name of the factory's corresponding model.
*
* @var string
*/
protected $model = Invoice::class;
if (! isset($attributes['order_id'])) {
$attributes['order_id'] = function () {
return factory(Order::class)->create()->id;
};
}
if (! isset($attributes['order_address_id'])) {
$attributes['order_address_id'] = function () use ($attributes) {
return factory(OrderAddress::class)
->create(['order_id' => $attributes['order_id']])
->id;
};
}
return [
'email_sent' => 0,
'total_qty' => $faker->randomNumber(),
'base_currency_code' => 'EUR',
'channel_currency_code' => 'EUR',
'order_currency_code' => 'EUR',
'sub_total' => $subTotal,
'base_sub_total' => $subTotal,
'grand_total' => $subTotal,
'base_grand_total' => $subTotal,
'shipping_amount' => $shippingAmount,
'base_shipping_amount' => $shippingAmount,
'tax_amount' => $taxAmount,
'base_tax_amount' => $taxAmount,
'discount_amount' => 0,
'base_discount_amount' => 0,
'order_id' => $attributes['order_id'],
'order_address_id' => $attributes['order_address_id'],
/**
* @var array
*/
protected $states = [
'pending',
'paid',
'refunded',
];
});
$factory->state(Invoice::class, 'pending', [
'status' => 'pending',
]);
/**
* Define the model's default state.
*
* @return array
*/
public function definition(): array
{
$subTotal = $this->faker->randomFloat(2);
$shippingAmount = $this->faker->randomFloat(2);
$taxAmount = $this->faker->randomFloat(2);
$factory->state(Invoice::class, 'paid', [
'status' => 'paid',
]);
if (!isset($attributes['order_id'])) {
$attributes['order_id'] = Order::factory();
}
$factory->state(Invoice::class, 'refunded', [
'status' => 'refunded',
]);
if (!isset($attributes['order_address_id'])) {
$attributes['order_address_id'] = OrderAddress::factory();
}
return [
'email_sent' => 0,
'total_qty' => $this->faker->randomNumber(),
'base_currency_code' => 'EUR',
'channel_currency_code' => 'EUR',
'order_currency_code' => 'EUR',
'sub_total' => $subTotal,
'base_sub_total' => $subTotal,
'grand_total' => $subTotal,
'base_grand_total' => $subTotal,
'shipping_amount' => $shippingAmount,
'base_shipping_amount' => $shippingAmount,
'tax_amount' => $taxAmount,
'base_tax_amount' => $taxAmount,
'discount_amount' => 0,
'base_discount_amount' => 0,
'order_id' => $attributes['order_id'],
'order_address_id' => $attributes['order_address_id'],
];
}
public function pending(): InvoiceFactory
{
return $this->state(function (array $attributes) {
return [
'status' => 'pending',
];
});
}
public function paid(): InvoiceFactory
{
return $this->state(function (array $attributes) {
return [
'status' => 'paid',
];
});
}
public function refunded(): InvoiceFactory
{
return $this->state(function (array $attributes) {
return [
'status' => 'refunded',
];
});
}
}

View File

@ -1,41 +1,52 @@
<?php
/** @var \Illuminate\Database\Eloquent\Factory $factory */
namespace Webkul\Sales\Database\Factories;
use Faker\Generator as Faker;
use Webkul\Product\Models\Product;
use Webkul\Sales\Models\Invoice;
use Webkul\Sales\Models\InvoiceItem;
use Webkul\Sales\Models\OrderItem;
use Illuminate\Database\Eloquent\Factories\Factory;
$factory->define(InvoiceItem::class, function (Faker $faker, array $attributes) {
class InvoiceItemFactory extends Factory
{
/**
* The name of the factory's corresponding model.
*
* @var string
*/
protected $model = InvoiceItem::class;
$basePrice = $faker->randomFloat(2);
$quantity = $faker->randomNumber();
/**
* Define the model's default state.
*
* @return array
*/
public function definition(): array
{
$basePrice = $this->faker->randomFloat(2);
$quantity = $this->faker->randomNumber();
if (! $attributes['order_item_id']) {
$attributes['order_item_id'] = function () {
return factory(OrderItem::class)->create()->id;
};
if (!isset($attributes['order_item_id'])) {
$attributes['order_item_id'] = OrderItem::factory();
}
$orderItem = OrderItem::query()
->find($attributes['order_item_id']);
return [
'name' => $this->faker->word,
'sku' => $this->faker->unique()->ean13,
'qty' => $quantity,
'price' => $basePrice,
'base_price' => $basePrice,
'total' => $quantity * $basePrice,
'base_total' => $quantity * $basePrice,
'tax_amount' => 0,
'base_tax_amount' => 0,
'product_id' => $orderItem->product_id,
'product_type' => $orderItem->product_type,
'order_item_id' => $attributes['order_item_id'],
'invoice_id' => Invoice::factory(),
];
}
$orderItem = OrderItem::find($attributes['order_item_id']);
return [
'name' => $faker->word,
'sku' => $faker->unique()->ean13,
'qty' => $quantity,
'price' => $basePrice,
'base_price' => $basePrice,
'total' => $quantity * $basePrice,
'base_total' => $quantity * $basePrice,
'tax_amount' => 0,
'base_tax_amount' => 0,
'product_id' => $orderItem->product_id,
'product_type' => $orderItem->product_type,
'order_item_id' => $attributes['order_item_id'],
'invoice_id' => function () {
return factory(Invoice::class)->create()->id;
},
];
});
}

View File

@ -1,34 +1,62 @@
<?php
/** @var \Illuminate\Database\Eloquent\Factory $factory */
namespace Webkul\Sales\Database\Factories;
use Faker\Generator as Faker;
use Webkul\Customer\Models\Customer;
use Webkul\Customer\Models\CustomerAddress;
use Webkul\Sales\Models\Order;
use Webkul\Sales\Models\OrderAddress;
use Illuminate\Database\Eloquent\Factories\Factory;
$factory->define(OrderAddress::class, function (Faker $faker) {
$customer = factory(Customer::class)->create();
$customerAddress = factory(CustomerAddress::class)->make();
class OrderAddressFactory extends Factory
{
/**
* The name of the factory's corresponding model.
*
* @var string
*/
protected $model = OrderAddress::class;
return [
'first_name' => $customer->first_name,
'last_name' => $customer->last_name,
'email' => $customer->email,
'address1' => $customerAddress->address1,
'country' => $customerAddress->country,
'state' => $customerAddress->state,
'city' => $customerAddress->city,
'postcode' => $customerAddress->postcode,
'phone' => $customerAddress->phone,
'address_type' => OrderAddress::ADDRESS_TYPE_BILLING,
'order_id' => function () {
return factory(Order::class)->create()->id;
},
/**
* @var string[]
*/
protected $states = [
'shipping',
];
});
$factory->state(OrderAddress::class, 'shipping', [
'address_type' => OrderAddress::ADDRESS_TYPE_SHIPPING,
]);
/**
* Define the model's default state.
*
* @return array
*/
public function definition(): array
{
$customer = Customer::factory()
->create();
$customerAddress = CustomerAddress::factory()
->make();
return [
'first_name' => $customer->first_name,
'last_name' => $customer->last_name,
'email' => $customer->email,
'address1' => $customerAddress->address1,
'country' => $customerAddress->country,
'state' => $customerAddress->state,
'city' => $customerAddress->city,
'postcode' => $customerAddress->postcode,
'phone' => $customerAddress->phone,
'address_type' => OrderAddress::ADDRESS_TYPE_BILLING,
'order_id' => Order::factory(),
];
}
public function shipping(): void
{
$this->state(function (array $attributes) {
return [
'address_type' => OrderAddress::ADDRESS_TYPE_SHIPPING,
];
});
}
}

View File

@ -1,67 +1,107 @@
<?php
/** @var \Illuminate\Database\Eloquent\Factory $factory */
namespace Webkul\Sales\Database\Factories;
use Faker\Generator as Faker;
use Illuminate\Support\Facades\DB;
use Webkul\Core\Models\Channel;
use Webkul\Customer\Models\Customer;
use Webkul\Sales\Models\Order;
use Illuminate\Database\Eloquent\Factories\Factory;
$factory->define(Order::class, function (Faker $faker) {
$lastOrder = DB::table('orders')
->orderBy('id', 'desc')
->select('id')
->first()
->id ?? 0;
class OrderFactory extends Factory
{
/**
* The name of the factory's corresponding model.
*
* @var string
*/
protected $model = Order::class;
$customer = factory(Customer::class)->create();
return [
'increment_id' => $lastOrder + 1,
'status' => 'pending',
'channel_name' => 'Default',
'is_guest' => 0,
'customer_id' => $customer->id,
'customer_email' => $customer->email,
'customer_first_name' => $customer->first_name,
'customer_last_name' => $customer->last_name,
'is_gift' => 0,
'total_item_count' => 1,
'total_qty_ordered' => 1,
'base_currency_code' => 'EUR',
'channel_currency_code' => 'EUR',
'order_currency_code' => 'EUR',
'grand_total' => 0.0000,
'base_grand_total' => 0.0000,
'grand_total_invoiced' => 0.0000,
'base_grand_total_invoiced' => 0.0000,
'grand_total_refunded' => 0.0000,
'base_grand_total_refunded' => 0.0000,
'sub_total' => 0.0000,
'base_sub_total' => 0.0000,
'sub_total_invoiced' => 0.0000,
'base_sub_total_invoiced' => 0.0000,
'sub_total_refunded' => 0.0000,
'base_sub_total_refunded' => 0.0000,
'customer_type' => Customer::class,
'channel_id' => 1,
'channel_type' => Channel::class,
'cart_id' => 0,
'shipping_method' => 'free_free',
'shipping_title' => 'Free Shipping',
/**
* @var string[]
*/
protected $states = [
'pending',
'completed',
'closed',
];
});
$factory->state(Order::class, 'pending', [
'status' => 'pending',
]);
/**
* Define the model's default state.
*
* @return array
*/
public function definition(): array
{
$lastOrder = DB::table('orders')
->orderBy('id', 'desc')
->select('id')
->first()->id ?? 0;
$factory->state(Order::class, 'completed', [
'status' => 'completed',
]);
$factory->state(Order::class, 'closed', [
'status' => 'closed',
]);
$customer = Customer::factory()
->create();
return [
'increment_id' => $lastOrder + 1,
'status' => 'pending',
'channel_name' => 'Default',
'is_guest' => 0,
'customer_id' => $customer->id,
'customer_email' => $customer->email,
'customer_first_name' => $customer->first_name,
'customer_last_name' => $customer->last_name,
'is_gift' => 0,
'total_item_count' => 1,
'total_qty_ordered' => 1,
'base_currency_code' => 'EUR',
'channel_currency_code' => 'EUR',
'order_currency_code' => 'EUR',
'grand_total' => 0.0000,
'base_grand_total' => 0.0000,
'grand_total_invoiced' => 0.0000,
'base_grand_total_invoiced' => 0.0000,
'grand_total_refunded' => 0.0000,
'base_grand_total_refunded' => 0.0000,
'sub_total' => 0.0000,
'base_sub_total' => 0.0000,
'sub_total_invoiced' => 0.0000,
'base_sub_total_invoiced' => 0.0000,
'sub_total_refunded' => 0.0000,
'base_sub_total_refunded' => 0.0000,
'customer_type' => Customer::class,
'channel_id' => 1,
'channel_type' => Channel::class,
'cart_id' => 0,
'shipping_method' => 'free_free',
'shipping_title' => 'Free Shipping',
];
}
public function pending(): OrderFactory
{
return $this->state(function (array $attributes) {
return [
'status' => 'pending',
];
});
}
public function completed(): OrderFactory
{
return $this->state(function (array $attributes) {
return [
'status' => 'completed',
];
});
}
public function closed(): OrderFactory
{
return $this->state(function (array $attributes) {
return [
'status' => 'closed',
];
});
}
}

View File

@ -1,43 +1,61 @@
<?php
/** @var \Illuminate\Database\Eloquent\Factory $factory */
namespace Webkul\Sales\Database\Factories;
use Faker\Generator as Faker;
use Webkul\Sales\Models\Order;
use Webkul\Product\Models\Product;
use Webkul\Sales\Models\OrderItem;
use Illuminate\Database\Eloquent\Factories\Factory;
$factory->define(OrderItem::class, function (Faker $faker, array $attributes) {
$now = date("Y-m-d H:i:s");
class OrderItemFactory extends Factory
{
/**
* The name of the factory's corresponding model.
*
* @var string
*/
protected $model = OrderItem::class;
if (isset($attributes['product_id'])) {
$product = Product::where('id', $attributes['product_id'])->first();
} else {
$product = factory(Product::class)->create();
/**
* Define the model's default state.
*
* @return array
*/
public function definition(): array
{
$now = date("Y-m-d H:i:s");
if (isset($attributes['product_id'])) {
$product = Product::query()
->where('id', $attributes['product_id'])
->first();
} else {
$product = Product::factory()
->simple()
->create();
}
$fallbackPrice = $this->faker->randomFloat(4, 0, 1000);
return [
'sku' => $product->sku,
'type' => $product->type,
'name' => $product->name,
'price' => $product->price ?? $fallbackPrice,
'base_price' => $product->price ?? $fallbackPrice,
'total' => $product->price ?? $fallbackPrice,
'base_total' => $product->price ?? $fallbackPrice,
'product_id' => $product->id,
'qty_ordered' => 1,
'qty_shipped' => 0,
'qty_invoiced' => 0,
'qty_canceled' => 0,
'qty_refunded' => 0,
'additional' => [],
'order_id' => Order::factory(),
'created_at' => $now,
'updated_at' => $now,
'product_type' => Product::class,
];
}
$fallbackPrice = $faker->randomFloat(4, 0, 1000);
return [
'sku' => $product->sku,
'type' => $product->type,
'name' => $product->name,
'price' => $product->price ?? $fallbackPrice,
'base_price' => $product->price ?? $fallbackPrice,
'total' => $product->price ?? $fallbackPrice,
'base_total' => $product->price ?? $fallbackPrice,
'product_id' => $product->id,
'qty_ordered' => 1,
'qty_shipped' => 0,
'qty_invoiced' => 0,
'qty_canceled' => 0,
'qty_refunded' => 0,
'additional' => [],
'order_id' => function () {
return factory(Order::class)->create()->id;
},
'created_at' => $now,
'updated_at' => $now,
'product_type' => Product::class,
];
});
}

View File

@ -1,19 +1,29 @@
<?php
/** @var \Illuminate\Database\Eloquent\Factory $factory */
namespace Webkul\Sales\Database\Factories;
use Faker\Generator as Faker;
use Illuminate\Support\Facades\DB;
use Webkul\Sales\Models\OrderPayment;
use Illuminate\Database\Eloquent\Factories\Factory;
$factory->define(OrderPayment::class, function (Faker $faker, array $attributes) {
class OrderPaymentFactory extends Factory
{
/**
* The name of the factory's corresponding model.
*
* @var string
*/
protected $model = OrderPayment::class;
if (!array_key_exists('order_id', $attributes)) {
throw new InvalidArgumentException('order_id must be provided.');
/**
* Define the model's default state.
*
* @return array
*/
public function definition(): array
{
return [
'method' => 'cashondelivery',
];
}
return [
'method' => 'cashondelivery',
];
});
}

View File

@ -1,16 +1,30 @@
<?php
/** @var \Illuminate\Database\Eloquent\Factory $factory */
namespace Webkul\Sales\Database\Factories;
use Faker\Generator as Faker;
use Webkul\Sales\Models\Order;
use Webkul\Sales\Models\Refund;
use Illuminate\Database\Eloquent\Factories\Factory;
$factory->define(Refund::class, function (Faker $faker, array $attributes) {
return [
'order_id' => function () {
return factory(Order::class)->create()->id;
},
];
});
class RefundFactory extends Factory
{
/**
* The name of the factory's corresponding model.
*
* @var string
*/
protected $model = Refund::class;
/**
* Define the model's default state.
*
* @return array
*/
public function definition(): array
{
return [
'order_id' => Order::factory(),
];
}
}

View File

@ -1,22 +1,37 @@
<?php
/** @var \Illuminate\Database\Eloquent\Factory $factory */
namespace Webkul\Sales\Database\Factories;
use Faker\Generator as Faker;
use Webkul\Inventory\Models\InventorySource;
use Webkul\Sales\Models\OrderAddress;
use Webkul\Sales\Models\Shipment;
use Illuminate\Database\Eloquent\Factories\Factory;
$factory->define(Shipment::class, function (Faker $faker) {
$address = factory(OrderAddress::class)->create();
class ShipmentFactory extends Factory
{
/**
* The name of the factory's corresponding model.
*
* @var string
*/
protected $model = Shipment::class;
return [
'total_qty' => $faker->numberBetween(1, 20),
'order_id' => $address->order_id,
'order_address_id' => $address->id,
'inventory_source_id' => function () {
return factory(InventorySource::class)->create()->id;
},
];
});
/**
* Define the model's default state.
*
* @return array
*/
public function definition(): array
{
$address = OrderAddress::factory()
->create();
return [
'total_qty' => $this->faker->numberBetween(1, 20),
'order_id' => $address->order_id,
'order_address_id' => $address->id,
'inventory_source_id' => InventorySource::factory(),
];
}
}

View File

@ -3,19 +3,28 @@
namespace Webkul\Sales\Models;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\MorphTo;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Webkul\Sales\Contracts\Invoice as InvoiceContract;
use Webkul\Sales\Traits\PaymentTerm;
use Webkul\Sales\Database\Factories\InvoiceFactory;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Factories\HasFactory;
class Invoice extends Model implements InvoiceContract
{
use PaymentTerm;
use PaymentTerm, HasFactory;
/**
* The attributes that aren't mass assignable.
*
* @var string[]|bool
*/
protected $guarded = ['id', 'created_at', 'updated_at'];
protected $guarded = [
'id',
'created_at',
'updated_at',
];
/**
* Invoice status.
@ -23,8 +32,8 @@ class Invoice extends Model implements InvoiceContract
* @var array
*/
protected $statusLabel = [
'pending' => 'Pending',
'paid' => 'Paid',
'pending' => 'Pending',
'paid' => 'Paid',
'refunded' => 'Refunded',
];
@ -33,13 +42,13 @@ class Invoice extends Model implements InvoiceContract
*/
public function getStatusLabelAttribute()
{
return isset($this->statusLabel[$this->state]) ? $this->statusLabel[$this->state] : '';
return $this->statusLabel[$this->state] ?? '';
}
/**
* Get the order that belongs to the invoice.
*/
public function order()
public function order(): BelongsTo
{
return $this->belongsTo(OrderProxy::modelClass());
}
@ -47,15 +56,16 @@ class Invoice extends Model implements InvoiceContract
/**
* Get the invoice items record associated with the invoice.
*/
public function items()
public function items(): HasMany
{
return $this->hasMany(InvoiceItemProxy::modelClass())->whereNull('parent_id');
return $this->hasMany(InvoiceItemProxy::modelClass())
->whereNull('parent_id');
}
/**
* Get the customer record associated with the invoice.
*/
public function customer()
public function customer(): MorphTo
{
return $this->morphTo();
}
@ -63,7 +73,7 @@ class Invoice extends Model implements InvoiceContract
/**
* Get the channel record associated with the invoice.
*/
public function channel()
public function channel(): MorphTo
{
return $this->morphTo();
}
@ -71,9 +81,19 @@ class Invoice extends Model implements InvoiceContract
/**
* Get the address for the invoice.
*/
public function address()
public function address(): BelongsTo
{
return $this->belongsTo(OrderAddressProxy::modelClass(), 'order_address_id')
->where('address_type', OrderAddress::ADDRESS_TYPE_BILLING);
->where('address_type', OrderAddress::ADDRESS_TYPE_BILLING);
}
/**
* Create a new factory instance for the model.
*
* @return InvoiceFactory
*/
protected static function newFactory(): InvoiceFactory
{
return InvoiceFactory::new();
}
}

View File

@ -2,12 +2,25 @@
namespace Webkul\Sales\Models;
use Webkul\Product\Type\AbstractType;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\HasOne;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Database\Eloquent\Relations\MorphTo;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Webkul\Sales\Database\Factories\InvoiceItemFactory;
use Webkul\Sales\Contracts\InvoiceItem as InvoiceItemContract;
class InvoiceItem extends Model implements InvoiceItemContract
{
protected $guarded = ['id', 'created_at', 'updated_at'];
use HasFactory;
protected $guarded = [
'id',
'created_at',
'updated_at',
];
protected $casts = [
'additional' => 'array',
@ -18,15 +31,15 @@ class InvoiceItem extends Model implements InvoiceItemContract
*
* @return AbstractType
*/
public function getTypeInstance()
public function getTypeInstance(): AbstractType
{
return $this->order_item->getTypeInstance();
}
/**
* Get the invoice record associated with the invoice item.
*/
public function invoice()
public function invoice(): BelongsTo
{
return $this->belongsTo(InvoiceProxy::modelClass());
}
@ -34,7 +47,7 @@ class InvoiceItem extends Model implements InvoiceItemContract
/**
* Get the order item record associated with the invoice item.
*/
public function order_item()
public function order_item(): BelongsTo
{
return $this->belongsTo(OrderItemProxy::modelClass());
}
@ -42,7 +55,7 @@ class InvoiceItem extends Model implements InvoiceItemContract
/**
* Get the invoice record associated with the invoice item.
*/
public function product()
public function product(): MorphTo
{
return $this->morphTo();
}
@ -50,7 +63,7 @@ class InvoiceItem extends Model implements InvoiceItemContract
/**
* Get the child item record associated with the invoice item.
*/
public function child()
public function child(): HasOne
{
return $this->hasOne(InvoiceItemProxy::modelClass(), 'parent_id');
}
@ -58,7 +71,7 @@ class InvoiceItem extends Model implements InvoiceItemContract
/**
* Get the children items.
*/
public function children()
public function children(): HasMany
{
return $this->hasMany(self::class, 'parent_id');
}
@ -70,4 +83,14 @@ class InvoiceItem extends Model implements InvoiceItemContract
{
return $this->order_item->type;
}
/**
* Create a new factory instance for the model.
*
* @return InvoiceItemFactory
*/
protected static function newFactory(): InvoiceItemFactory
{
return InvoiceItemFactory::new();
}
}

View File

@ -5,15 +5,29 @@ namespace Webkul\Sales\Models;
use Webkul\Checkout\Models\CartProxy;
use Illuminate\Database\Eloquent\Model;
use Webkul\Sales\Contracts\Order as OrderContract;
use Webkul\Sales\Database\Factories\OrderFactory;
use Illuminate\Database\Eloquent\Relations\HasOne;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Database\Eloquent\Relations\MorphTo;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Factories\HasFactory;
class Order extends Model implements OrderContract
{
use HasFactory;
public const STATUS_PENDING = 'pending';
public const STATUS_PENDING_PAYMENT = 'pending_payment';
public const STATUS_PROCESSING = 'processing';
public const STATUS_COMPLETED = 'completed';
public const STATUS_CANCELED = 'canceled';
public const STATUS_CLOSED = 'closed';
public const STATUS_FRAUD = 'fraud';
protected $guarded = [
@ -29,19 +43,19 @@ class Order extends Model implements OrderContract
];
protected $statusLabel = [
self::STATUS_PENDING => 'Pending',
self::STATUS_PENDING => 'Pending',
self::STATUS_PENDING_PAYMENT => 'Pending Payment',
self::STATUS_PROCESSING => 'Processing',
self::STATUS_COMPLETED => 'Completed',
self::STATUS_CANCELED => 'Canceled',
self::STATUS_CLOSED => 'Closed',
self::STATUS_FRAUD => 'Fraud',
self::STATUS_PROCESSING => 'Processing',
self::STATUS_COMPLETED => 'Completed',
self::STATUS_CANCELED => 'Canceled',
self::STATUS_CLOSED => 'Closed',
self::STATUS_FRAUD => 'Fraud',
];
/**
* Get the order items record associated with the order.
*/
public function getCustomerFullNameAttribute()
public function getCustomerFullNameAttribute(): string
{
return $this->customer_first_name . ' ' . $this->customer_last_name;
}
@ -73,7 +87,7 @@ class Order extends Model implements OrderContract
/**
* Get the associated cart that was used to create this order.
*/
public function cart()
public function cart(): BelongsTo
{
return $this->belongsTo(CartProxy::modelClass());
}
@ -81,15 +95,16 @@ class Order extends Model implements OrderContract
/**
* Get the order items record associated with the order.
*/
public function items()
public function items(): HasMany
{
return $this->hasMany(OrderItemProxy::modelClass())->whereNull('parent_id');
return $this->hasMany(OrderItemProxy::modelClass())
->whereNull('parent_id');
}
/**
* Get the comments record associated with the order.
*/
public function comments()
public function comments(): HasMany
{
return $this->hasMany(OrderCommentProxy::modelClass());
}
@ -97,7 +112,7 @@ class Order extends Model implements OrderContract
/**
* Get the order items record associated with the order.
*/
public function all_items()
public function all_items(): HasMany
{
return $this->hasMany(OrderItemProxy::modelClass());
}
@ -105,7 +120,7 @@ class Order extends Model implements OrderContract
/**
* Get the order shipments record associated with the order.
*/
public function shipments()
public function shipments(): HasMany
{
return $this->hasMany(ShipmentProxy::modelClass());
}
@ -113,7 +128,7 @@ class Order extends Model implements OrderContract
/**
* Get the order invoices record associated with the order.
*/
public function invoices()
public function invoices(): HasMany
{
return $this->hasMany(InvoiceProxy::modelClass());
}
@ -121,7 +136,7 @@ class Order extends Model implements OrderContract
/**
* Get the order refunds record associated with the order.
*/
public function refunds()
public function refunds(): HasMany
{
return $this->hasMany(RefundProxy::modelClass());
}
@ -129,7 +144,7 @@ class Order extends Model implements OrderContract
/**
* Get the order transactions record associated with the order.
*/
public function transactions()
public function transactions(): HasMany
{
return $this->hasMany(OrderTransactionProxy::modelClass());
}
@ -137,7 +152,7 @@ class Order extends Model implements OrderContract
/**
* Get the customer record associated with the order.
*/
public function customer()
public function customer(): MorphTo
{
return $this->morphTo();
}
@ -145,7 +160,7 @@ class Order extends Model implements OrderContract
/**
* Get the addresses for the order.
*/
public function addresses()
public function addresses(): HasMany
{
return $this->hasMany(OrderAddressProxy::modelClass());
}
@ -153,17 +168,18 @@ class Order extends Model implements OrderContract
/**
* Get the payment for the order.
*/
public function payment()
public function payment(): HasOne
{
return $this->hasOne(OrderPaymentProxy::modelClass());
}
/**
* Get the biling address for the order.
* Get the billing address for the order.
*/
public function billing_address()
public function billing_address(): HasMany
{
return $this->addresses()->where('address_type', OrderAddress::ADDRESS_TYPE_BILLING);
return $this->addresses()
->where('address_type', OrderAddress::ADDRESS_TYPE_BILLING);
}
/**
@ -171,15 +187,17 @@ class Order extends Model implements OrderContract
*/
public function getBillingAddressAttribute()
{
return $this->billing_address()->first();
return $this->billing_address()
->first();
}
/**
* Get the shipping address for the order.
*/
public function shipping_address()
public function shipping_address(): HasMany
{
return $this->addresses()->where('address_type', OrderAddress::ADDRESS_TYPE_SHIPPING);
return $this->addresses()
->where('address_type', OrderAddress::ADDRESS_TYPE_SHIPPING);
}
/**
@ -187,7 +205,8 @@ class Order extends Model implements OrderContract
*/
public function getShippingAddressAttribute()
{
return $this->shipping_address()->first();
return $this->shipping_address()
->first();
}
/**
@ -206,7 +225,8 @@ class Order extends Model implements OrderContract
public function haveStockableItems(): bool
{
foreach ($this->items as $item) {
if ($item->getTypeInstance()->isStockable()) {
if ($item->getTypeInstance()
->isStockable()) {
return true;
}
}
@ -268,12 +288,13 @@ class Order extends Model implements OrderContract
if ($this->payment->method == 'moneytransfer' && core()->getConfigData('sales.paymentmethods.moneytransfer.generate_invoice')) {
return false;
}
if ($this->status === self::STATUS_FRAUD) {
return false;
}
$pendingInvoice = $this->invoices->where('state', 'pending')->first();
$pendingInvoice = $this->invoices->where('state', 'pending')
->first();
if ($pendingInvoice) {
return true;
}
@ -297,8 +318,9 @@ class Order extends Model implements OrderContract
if ($this->status === self::STATUS_FRAUD) {
return false;
}
$pendingInvoice = $this->invoices->where('state', 'pending')->first();
$pendingInvoice = $this->invoices->where('state', 'pending')
->first();
if ($pendingInvoice) {
return false;
}
@ -309,10 +331,21 @@ class Order extends Model implements OrderContract
}
}
if ($this->base_grand_total_invoiced - $this->base_grand_total_refunded - $this->refunds()->sum('base_adjustment_fee') > 0) {
if ($this->base_grand_total_invoiced - $this->base_grand_total_refunded - $this->refunds()
->sum('base_adjustment_fee') > 0) {
return true;
}
return false;
}
/**
* Create a new factory instance for the model.
*
* @return OrderFactory
*/
protected static function newFactory(): OrderFactory
{
return OrderFactory::new();
}
}

View File

@ -4,20 +4,27 @@ namespace Webkul\Sales\Models;
use Webkul\Checkout\Models\CartAddress;
use Webkul\Core\Models\Address;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Webkul\Sales\Database\Factories\OrderAddressFactory;
use Webkul\Sales\Contracts\OrderAddress as OrderAddressContract;
use Illuminate\Database\Eloquent\Builder;
/**
* Class OrderAddress
*
* @package Webkul\Sales\Models
*
* @property integer $order_id
* @property Order $order
* @property Order $order
*
*/
class OrderAddress extends Address implements OrderAddressContract
{
use HasFactory;
public const ADDRESS_TYPE_SHIPPING = 'order_shipping';
public const ADDRESS_TYPE_BILLING = 'order_billing';
/**
@ -32,12 +39,12 @@ class OrderAddress extends Address implements OrderAddressContract
*
* @return void
*/
protected static function boot()
protected static function boot(): void
{
static::addGlobalScope('address_type', function (Builder $builder) {
$builder->whereIn('address_type', [
self::ADDRESS_TYPE_BILLING,
self::ADDRESS_TYPE_SHIPPING
self::ADDRESS_TYPE_SHIPPING,
]);
});
@ -58,8 +65,18 @@ class OrderAddress extends Address implements OrderAddressContract
/**
* Get the order record associated with the address.
*/
public function order()
public function order(): BelongsTo
{
return $this->belongsTo(Order::class);
}
/**
* Create a new factory instance for the model.
*
* @return OrderAddressFactory
*/
protected static function newFactory(): OrderAddressFactory
{
return OrderAddressFactory::new();
}
}

View File

@ -2,12 +2,20 @@
namespace Webkul\Sales\Models;
use Webkul\Product\Type\AbstractType;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\HasOne;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Database\Eloquent\Relations\MorphTo;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Webkul\Sales\Database\Factories\OrderItemFactory;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Webkul\Sales\Contracts\OrderItem as OrderItemContract;
use Webkul\Product\Models\Product;
class OrderItem extends Model implements OrderItemContract
{
use HasFactory;
protected $guarded = [
'id',
'child',
@ -27,7 +35,7 @@ class OrderItem extends Model implements OrderItemContract
*
* @return AbstractType
*/
public function getTypeInstance()
public function getTypeInstance(): AbstractType
{
if ($this->typeInstance) {
return $this->typeInstance;
@ -45,17 +53,18 @@ class OrderItem extends Model implements OrderItemContract
/**
* @return bool
*/
public function isStockable()
public function isStockable(): bool
{
return $this->getTypeInstance()->isStockable();
return $this->getTypeInstance()
->isStockable();
}
/**
* Checks if new shipment is allow or not
* Checks if new shipment is allowed or not
*/
public function canShip()
public function canShip(): bool
{
if (! $this->isStockable()) {
if (!$this->isStockable()) {
return false;
}
@ -71,7 +80,7 @@ class OrderItem extends Model implements OrderItemContract
*/
public function getQtyToShipAttribute()
{
if (! $this->isStockable()) {
if (!$this->isStockable()) {
return 0;
}
@ -101,13 +110,9 @@ class OrderItem extends Model implements OrderItemContract
/**
* Checks if new cancel is allow or not
*/
public function canCancel()
public function canCancel(): bool
{
if ($this->qty_to_cancel > 0) {
return true;
}
return false;
return $this->qty_to_cancel > 0;
}
/**
@ -129,7 +134,7 @@ class OrderItem extends Model implements OrderItemContract
/**
* Get the order record associated with the order item.
*/
public function order()
public function order(): BelongsTo
{
return $this->belongsTo(OrderProxy::modelClass());
}
@ -137,7 +142,7 @@ class OrderItem extends Model implements OrderItemContract
/**
* Get the product record associated with the order item.
*/
public function product()
public function product(): MorphTo
{
return $this->morphTo();
}
@ -145,7 +150,7 @@ class OrderItem extends Model implements OrderItemContract
/**
* Get the child item record associated with the order item.
*/
public function child()
public function child(): HasOne
{
return $this->hasOne(OrderItemProxy::modelClass(), 'parent_id');
}
@ -153,7 +158,7 @@ class OrderItem extends Model implements OrderItemContract
/**
* Get the parent item record associated with the order item.
*/
public function parent()
public function parent(): BelongsTo
{
return $this->belongsTo(self::class, 'parent_id');
}
@ -161,7 +166,7 @@ class OrderItem extends Model implements OrderItemContract
/**
* Get the children items.
*/
public function children()
public function children(): HasMany
{
return $this->hasMany(self::class, 'parent_id');
}
@ -169,7 +174,7 @@ class OrderItem extends Model implements OrderItemContract
/**
* Get the invoice items record associated with the order item.
*/
public function invoice_items()
public function invoice_items(): HasMany
{
return $this->hasMany(InvoiceItemProxy::modelClass());
}
@ -177,7 +182,7 @@ class OrderItem extends Model implements OrderItemContract
/**
* Get the shipment items record associated with the order item.
*/
public function shipment_items()
public function shipment_items(): HasMany
{
return $this->hasMany(ShipmentItemProxy::modelClass());
}
@ -185,7 +190,7 @@ class OrderItem extends Model implements OrderItemContract
/**
* Get the refund items record associated with the order item.
*/
public function refund_items()
public function refund_items(): HasMany
{
return $this->hasMany(RefundItemProxy::modelClass());
}
@ -193,7 +198,7 @@ class OrderItem extends Model implements OrderItemContract
/**
* Returns configurable option html
*/
public function downloadable_link_purchased()
public function downloadable_link_purchased(): HasMany
{
return $this->hasMany(DownloadableLinkPurchasedProxy::modelClass());
}
@ -201,7 +206,7 @@ class OrderItem extends Model implements OrderItemContract
/**
* @return array
*/
public function toArray()
public function toArray(): array
{
$array = parent::toArray();
@ -217,4 +222,14 @@ class OrderItem extends Model implements OrderItemContract
return $array;
}
/**
* Create a new factory instance for the model.
*
* @return OrderItemFactory
*/
protected static function newFactory(): OrderItemFactory
{
return OrderItemFactory::new();
}
}

View File

@ -3,10 +3,14 @@
namespace Webkul\Sales\Models;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Webkul\Sales\Database\Factories\OrderPaymentFactory;
use Webkul\Sales\Contracts\OrderPayment as OrderPaymentContract;
class OrderPayment extends Model implements OrderPaymentContract
{
use HasFactory;
protected $table = 'order_payment';
protected $guarded = [
@ -16,6 +20,16 @@ class OrderPayment extends Model implements OrderPaymentContract
];
protected $casts = [
'additional' => 'array'
'additional' => 'array',
];
/**
* Create a new factory instance for the model.
*
* @return OrderPaymentFactory
*/
protected static function newFactory(): OrderPaymentFactory
{
return OrderPaymentFactory::new();
}
}

View File

@ -3,31 +3,37 @@
namespace Webkul\Sales\Models;
use Illuminate\Database\Eloquent\Model;
use Webkul\Sales\Database\Factories\RefundFactory;
use Webkul\Sales\Contracts\Refund as RefundContract;
use Illuminate\Database\Eloquent\Relations\MorphTo;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Factories\HasFactory;
class Refund extends Model implements RefundContract
{
use HasFactory;
protected $guarded = [
'id',
'created_at',
'updated_at',
];
protected $statusLabel = [
];
protected $statusLabel = [];
/**
* Returns the status label from status code
*/
public function getStatusLabelAttribute()
{
return isset($this->statusLabel[$this->state]) ? $this->statusLabel[$this->state] : '';
return $this->statusLabel[$this->state] ?? '';
}
/**
* Get the order that belongs to the Refund.
*/
public function order()
public function order(): BelongsTo
{
return $this->belongsTo(OrderProxy::modelClass());
}
@ -35,14 +41,16 @@ class Refund extends Model implements RefundContract
/**
* Get the Refund items record associated with the Refund.
*/
public function items() {
return $this->hasMany(RefundItemProxy::modelClass())->whereNull('parent_id');
public function items(): HasMany
{
return $this->hasMany(RefundItemProxy::modelClass())
->whereNull('parent_id');
}
/**
* Get the customer record associated with the Refund.
*/
public function customer()
public function customer(): MorphTo
{
return $this->morphTo();
}
@ -50,7 +58,7 @@ class Refund extends Model implements RefundContract
/**
* Get the channel record associated with the Refund.
*/
public function channel()
public function channel(): MorphTo
{
return $this->morphTo();
}
@ -58,8 +66,18 @@ class Refund extends Model implements RefundContract
/**
* Get the addresses for the shipment.
*/
public function address()
public function address(): BelongsTo
{
return $this->belongsTo(OrderAddressProxy::modelClass(), 'order_address_id');
}
/**
* Create a new factory instance for the model.
*
* @return RefundFactory
*/
protected static function newFactory(): RefundFactory
{
return RefundFactory::new();
}
}

View File

@ -4,10 +4,17 @@ namespace Webkul\Sales\Models;
use Illuminate\Database\Eloquent\Model;
use Webkul\Inventory\Models\InventorySource;
use Illuminate\Database\Eloquent\Relations\MorphTo;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Webkul\Sales\Database\Factories\ShipmentFactory;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Webkul\Sales\Contracts\Shipment as ShipmentContract;
class Shipment extends Model implements ShipmentContract
{
use HasFactory;
protected $guarded = [
'id',
'created_at',
@ -17,7 +24,7 @@ class Shipment extends Model implements ShipmentContract
/**
* Get the order that belongs to the invoice.
*/
public function order()
public function order(): BelongsTo
{
return $this->belongsTo(OrderProxy::modelClass());
}
@ -25,7 +32,7 @@ class Shipment extends Model implements ShipmentContract
/**
* Get the shipment items record associated with the shipment.
*/
public function items()
public function items(): HasMany
{
return $this->hasMany(ShipmentItemProxy::modelClass());
}
@ -33,7 +40,7 @@ class Shipment extends Model implements ShipmentContract
/**
* Get the inventory source associated with the shipment.
*/
public function inventory_source()
public function inventory_source(): BelongsTo
{
return $this->belongsTo(InventorySource::class, 'inventory_source_id');
}
@ -41,7 +48,7 @@ class Shipment extends Model implements ShipmentContract
/**
* Get the customer record associated with the shipment.
*/
public function customer()
public function customer(): MorphTo
{
return $this->morphTo();
}
@ -49,9 +56,19 @@ class Shipment extends Model implements ShipmentContract
/**
* Get the address for the shipment.
*/
public function address()
public function address(): BelongsTo
{
return $this->belongsTo(OrderAddressProxy::modelClass(), 'order_address_id')
->where('address_type', OrderAddress::ADDRESS_TYPE_SHIPPING);
->where('address_type', OrderAddress::ADDRESS_TYPE_SHIPPING);
}
/**
* Create a new factory instance for the model.
*
* @return ShipmentFactory
*/
protected static function newFactory(): ShipmentFactory
{
return ShipmentFactory::new();
}
}

View File

@ -2,12 +2,11 @@
namespace Webkul\Sales\Providers;
use Illuminate\Database\Eloquent\Factory as EloquentFactory;
use Illuminate\Support\ServiceProvider;
class SalesServiceProvider extends ServiceProvider
{
public function boot()
public function boot(): void
{
$this->loadMigrationsFrom(__DIR__ . '/../Database/Migrations');
}
@ -16,27 +15,9 @@ class SalesServiceProvider extends ServiceProvider
* Register services.
*
* @return void
* @throws \Illuminate\Contracts\Container\BindingResolutionException
*/
public function register()
public function register(): void
{
$this->registerEloquentFactoriesFrom(__DIR__ . '/../Database/Factories');
$this->mergeConfigFrom(
dirname(__DIR__) . '/Config/system.php', 'core'
);
}
/**
* Register factories.
*
* @param string $path
*
* @return void
* @throws \Illuminate\Contracts\Container\BindingResolutionException
*/
protected function registerEloquentFactoriesFrom($path): void
{
$this->app->make(EloquentFactory::class)->load($path);
$this->mergeConfigFrom(dirname(__DIR__) . '/Config/system.php', 'core');
}
}

View File

@ -1,14 +1,30 @@
<?php
/** @var \Illuminate\Database\Eloquent\Factory $factory */
namespace Webkul\Tax\Database\Factories;
use Faker\Generator as Faker;
use Webkul\Tax\Models\TaxCategory;
use Illuminate\Database\Eloquent\Factories\Factory;
$factory->define(TaxCategory::class, function (Faker $faker) {
return [
'code' => $faker->uuid,
'name' => $faker->words(2, true),
'description' => $faker->sentence(10),
];
});
class TaxCategoryFactory extends Factory
{
/**
* The name of the factory's corresponding model.
*
* @var string
*/
protected $model = TaxCategory::class;
/**
* Define the model's default state.
*
* @return array
*/
public function definition(): array
{
return [
'code' => $this->faker->uuid,
'name' => $this->faker->words(2, true),
'description' => $this->faker->sentence(10),
];
}
}

View File

@ -1,19 +1,32 @@
<?php
/** @var \Illuminate\Database\Eloquent\Factory $factory */
namespace Webkul\Tax\Database\Factories;
use Faker\Generator as Faker;
use Webkul\Tax\Models\TaxMap;
use Webkul\Tax\Models\TaxRate;
use Webkul\Tax\Models\TaxCategory;
use Illuminate\Database\Eloquent\Factories\Factory;
class TaxMapFactory extends Factory
{
/**
* The name of the factory's corresponding model.
*
* @var string
*/
protected $model = TaxMap::class;
/**
* Define the model's default state.
*
* @return array
*/
public function definition(): array
{
return [
'tax_category_id' => TaxCategory::factory(),
'tax_rate_id' => TaxRate::factory(),
];
}
}
$factory->define(TaxMap::class, function (Faker $faker) {
return [
'tax_category_id' => function () {
return factory(TaxCategory::class)->create()->id;
},
'tax_rate_id' => function () {
return factory(TaxRate::class)->create()->id;
},
];
});

View File

@ -1,19 +1,35 @@
<?php
/** @var \Illuminate\Database\Eloquent\Factory $factory */
namespace Webkul\Tax\Database\Factories;
use Faker\Generator as Faker;
use Webkul\Tax\Models\TaxRate;
use Illuminate\Database\Eloquent\Factories\Factory;
$factory->define(TaxRate::class, function (Faker $faker) {
return [
'identifier' => $faker->uuid,
'is_zip' => 0,
'zip_code' => '*',
'zip_from' => null,
'zip_to' => null,
'state' => '',
'country' => $faker->countryCode,
'tax_rate' => $faker->randomFloat(2, 3, 25),
];
});
class TaxRateFactory extends Factory
{
/**
* The name of the factory's corresponding model.
*
* @var string
*/
protected $model = TaxRate::class;
/**
* Define the model's default state.
*
* @return array
*/
public function definition(): array
{
return [
'identifier' => $this->faker->uuid,
'is_zip' => 0,
'zip_code' => '*',
'zip_from' => null,
'zip_to' => null,
'state' => '',
'country' => $this->faker->countryCode,
'tax_rate' => $this->faker->randomFloat(2, 3, 25),
];
}
}

View File

@ -3,10 +3,15 @@
namespace Webkul\Tax\Models;
use Illuminate\Database\Eloquent\Model;
use Webkul\Tax\Database\Factories\TaxCategoryFactory;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
use Webkul\Tax\Contracts\TaxCategory as TaxCategoryContract;
class TaxCategory extends Model implements TaxCategoryContract
{
use HasFactory;
/**
* The attributes that are mass assignable.
*
@ -16,14 +21,25 @@ class TaxCategory extends Model implements TaxCategoryContract
protected $table = 'tax_categories';
protected $fillable = [
'code',
'name',
'description',
'code',
'name',
'description',
];
//for joining the two way pivot table
public function tax_rates()
public function tax_rates(): BelongsToMany
{
return $this->belongsToMany(TaxRateProxy::modelClass(), 'tax_categories_tax_rates', 'tax_category_id')->withPivot('id');
return $this->belongsToMany(TaxRateProxy::modelClass(), 'tax_categories_tax_rates', 'tax_category_id')
->withPivot('id');
}
/**
* Create a new factory instance for the model.
*
* @return TaxCategoryFactory
*/
protected static function newFactory(): TaxCategoryFactory
{
return TaxCategoryFactory::new();
}
}

View File

@ -3,12 +3,14 @@
namespace Webkul\Tax\Models;
use Illuminate\Database\Eloquent\Model;
use Webkul\Tax\Models\TaxCategory;
use Webkul\Tax\Models\TaxRate;
use Webkul\Tax\Database\Factories\TaxMapFactory;
use Webkul\Tax\Contracts\TaxMap as TaxMapContract;
use Illuminate\Database\Eloquent\Factories\HasFactory;
class TaxMap extends Model implements TaxMapContract
{
use HasFactory;
/**
* The attributes that are mass assignable.
*
@ -22,4 +24,13 @@ class TaxMap extends Model implements TaxMapContract
'tax_rate_id',
];
/**
* Create a new factory instance for the model.
*
* @return TaxMapFactory
*/
protected static function newFactory(): TaxMapFactory
{
return TaxMapFactory::new();
}
}

View File

@ -3,11 +3,15 @@
namespace Webkul\Tax\Models;
use Illuminate\Database\Eloquent\Model;
use Webkul\Tax\Models\TaxCategory;
use Webkul\Tax\Database\Factories\TaxRateFactory;
use Webkul\Tax\Contracts\TaxRate as TaxRateContract;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
class TaxRate extends Model implements TaxRateContract
{
use HasFactory;
/**
* The attributes that are mass assignable.
*
@ -27,8 +31,18 @@ class TaxRate extends Model implements TaxRateContract
'tax_rate',
];
public function tax_categories()
public function tax_categories(): BelongsToMany
{
return $this->belongsToMany(TaxCategoryProxy::modelClass(), 'tax_categories_tax_rates', 'tax_rate_id', 'id');
}
/**
* Create a new factory instance for the model.
*
* @return TaxRateFactory
*/
protected static function newFactory(): TaxRateFactory
{
return TaxRateFactory::new();
}
}

View File

@ -8,7 +8,7 @@ modules:
- Asserts
- Filesystem
- \Helper\Unit
- Laravel5:
- Laravel:
environment_file: .env.testing
run_database_migrations: true
run_database_seeder: true

View File

@ -15,6 +15,7 @@ class DatabaseLogicCest
/** @var Locale $localeEn */
private $localeEn;
/** @var Locale $localeDe */
private $localeDe;
@ -40,6 +41,7 @@ class DatabaseLogicCest
'slug' => 'root',
'locale' => 'en',
]);
$rootCategory = $I->grabRecord(Category::class, [
'id' => $rootCategoryTranslation->category_id,
]);
@ -47,9 +49,9 @@ class DatabaseLogicCest
$parentCategoryName = $this->faker->word;
$parentCategoryAttributes = [
'parent_id' => $rootCategory->id,
'position' => 1,
'status' => 1,
'parent_id' => $rootCategory->id,
'position' => 1,
'status' => 1,
$this->localeEn->code => [
'name' => $parentCategoryName,
'slug' => strtolower($parentCategoryName),
@ -64,15 +66,16 @@ class DatabaseLogicCest
],
];
$parentCategory = $I->make(Category::class, $parentCategoryAttributes)->first();
$parentCategory = $I->make(Category::class, $parentCategoryAttributes)
->first();
$rootCategory->prependNode($parentCategory);
$I->assertNotNull($parentCategory);
$categoryName = $this->faker->word;
$categoryAttributes = [
'position' => 1,
'status' => 1,
'parent_id' => $parentCategory->id,
'position' => 1,
'status' => 1,
'parent_id' => $parentCategory->id,
$this->localeEn->code => [
'name' => $categoryName,
'slug' => strtolower($categoryName),
@ -87,7 +90,8 @@ class DatabaseLogicCest
],
];
$category = $I->make(Category::class, $categoryAttributes)->first();
$category = $I->make(Category::class, $categoryAttributes)
->first();
$parentCategory->prependNode($category);
$I->assertNotNull($category);
@ -110,16 +114,17 @@ class DatabaseLogicCest
$I->assertEquals($expectedUrlPath, $urlPathQueryResult->url_path);
$root2Category = $I->make(Category::class, [
'position' => 1,
'status' => 1,
'parent_id' => null,
'position' => 1,
'status' => 1,
'parent_id' => null,
$this->localeEn->code => [
'name' => $this->faker->word,
'slug' => strtolower($this->faker->word),
'description' => $this->faker->word,
'locale_id' => $this->localeEn->id,
],
])->first();
])
->first();
$root2Category->save();
$I->assertNull($root2Category->refresh()->parent_id);

View File

@ -13,23 +13,33 @@ class TriggerCest
private $faker;
private $parentCategory;
private $category;
private $root2Category;
private $childOfRoot2Category;
private $parentCategoryAttributes;
private $categoryAttributes;
private $root2CategoryAttributes;
private $childOfRoot2CategoryAttributes;
private $parentCategoryName;
private $categoryName;
private $root2CategoryName;
private $childOfRoot2CategoryName;
/** @var Locale $localeEn */
private $localeEn;
/** @var Locale $localeDe */
private $localeDe;
@ -59,9 +69,9 @@ class TriggerCest
]);
$this->parentCategoryAttributes = [
'parent_id' => $rootCategory->id,
'position' => 1,
'status' => 1,
'parent_id' => $rootCategory->id,
'position' => 1,
'status' => 1,
$this->localeEn->code => [
'name' => $this->parentCategoryName,
'slug' => strtolower($this->parentCategoryName),
@ -76,14 +86,15 @@ class TriggerCest
],
];
$this->parentCategory = $I->make(Category::class, $this->parentCategoryAttributes)->first();
$this->parentCategory = $I->make(Category::class, $this->parentCategoryAttributes)
->first();
$rootCategory->appendNode($this->parentCategory);
$I->assertNotNull($this->parentCategory);
$this->categoryAttributes = [
'position' => 1,
'status' => 1,
'parent_id' => $this->parentCategory->id,
'position' => 1,
'status' => 1,
'parent_id' => $this->parentCategory->id,
$this->localeEn->code => [
'name' => $this->categoryName,
'slug' => strtolower($this->categoryName),
@ -98,15 +109,16 @@ class TriggerCest
],
];
$this->category = $I->make(Category::class, $this->categoryAttributes)->first();
$this->category = $I->make(Category::class, $this->categoryAttributes)
->first();
$this->parentCategory->appendNode($this->category);
$I->assertNotNull($this->category);
$this->root2CategoryAttributes = [
'position' => 1,
'status' => 1,
'parent_id' => null,
'position' => 1,
'status' => 1,
'parent_id' => null,
$this->localeEn->code => [
'name' => $this->root2CategoryName,
'slug' => strtolower($this->root2CategoryName),
@ -121,7 +133,8 @@ class TriggerCest
],
];
$this->root2Category = $I->make(Category::class, $this->root2CategoryAttributes)->first();
$this->root2Category = $I->make(Category::class, $this->root2CategoryAttributes)
->first();
$this->root2Category->save();
$I->assertNotNull($this->root2Category);
@ -129,9 +142,9 @@ class TriggerCest
$I->assertGreaterThan($rootCategory->_rgt, $this->root2Category->_lft);
$this->childOfRoot2CategoryAttributes = [
'position' => 1,
'status' => 1,
'parent_id' => $this->root2Category->id,
'position' => 1,
'status' => 1,
'parent_id' => $this->root2Category->id,
$this->localeEn->code => [
'name' => $this->childOfRoot2CategoryName,
'slug' => strtolower($this->childOfRoot2CategoryName),
@ -146,7 +159,8 @@ class TriggerCest
],
];
$this->childOfRoot2Category = $I->make(Category::class, $this->childOfRoot2CategoryAttributes)->first();
$this->childOfRoot2Category = $I->make(Category::class, $this->childOfRoot2CategoryAttributes)
->first();
$this->root2Category->appendNode($this->childOfRoot2Category);
$I->assertNotNull($this->childOfRoot2Category);
@ -158,26 +172,26 @@ class TriggerCest
'category_id' => $this->parentCategory->id,
'name' => $this->parentCategoryName,
'locale' => $this->localeEn->code,
'url_path' => strtolower($this->parentCategoryName)
'url_path' => strtolower($this->parentCategoryName),
]);
$I->seeRecord(CategoryTranslation::class, [
'category_id' => $this->parentCategory->id,
'name' => $this->parentCategoryName,
'locale' => $this->localeDe->code,
'url_path' => strtolower($this->parentCategoryName)
'url_path' => strtolower($this->parentCategoryName),
]);
$I->seeRecord(CategoryTranslation::class, [
'category_id' => $this->category->id,
'name' => $this->categoryName,
'locale' => $this->localeEn->code,
'url_path' => strtolower($this->parentCategoryName) . '/' . strtolower($this->categoryName)
'url_path' => strtolower($this->parentCategoryName) . '/' . strtolower($this->categoryName),
]);
$I->seeRecord(CategoryTranslation::class, [
'category_id' => $this->category->id,
'name' => $this->categoryName,
'locale' => $this->localeDe->code,
'url_path' => strtolower($this->parentCategoryName) . '/' . strtolower($this->categoryName)
'url_path' => strtolower($this->parentCategoryName) . '/' . strtolower($this->categoryName),
]);
$I->seeRecord(CategoryTranslation::class, [
'category_id' => $this->root2Category->id,
@ -190,13 +204,13 @@ class TriggerCest
'category_id' => $this->childOfRoot2Category->id,
'name' => $this->childOfRoot2CategoryName,
'locale' => $this->localeDe->code,
'url_path' => strtolower($this->childOfRoot2CategoryName)
'url_path' => strtolower($this->childOfRoot2CategoryName),
]);
$I->seeRecord(CategoryTranslation::class, [
'category_id' => $this->childOfRoot2Category->id,
'name' => $this->childOfRoot2CategoryName,
'locale' => $this->localeEn->code,
'url_path' => strtolower($this->childOfRoot2CategoryName)
'url_path' => strtolower($this->childOfRoot2CategoryName),
]);
}
@ -295,9 +309,7 @@ class TriggerCest
$I->assertTrue($this->category->update($this->categoryAttributes));
$this->category->refresh();
$expectedUrlPath = strtolower($this->parentCategoryName) . '/'
. strtolower($category2Name) . '/'
. strtolower($this->categoryName);
$expectedUrlPath = strtolower($this->parentCategoryName) . '/' . strtolower($category2Name) . '/' . strtolower($this->categoryName);
$I->seeRecord(CategoryTranslation::class, [
'category_id' => $this->category->id,
'name' => $this->categoryName,

Some files were not shown because too many files have changed in this diff Show More