Files
backend-mm/app/Repositories/Ecommerce/Product/NovaProductRepository.php
2025-09-25 03:03:31 +05:00

254 lines
7.8 KiB
PHP

<?php
namespace App\Repositories\Ecommerce\Product;
use App\Models\Ecommerce\Product\Inventory\Inventory;
use App\Models\Ecommerce\Product\Product\Product;
use App\Models\Ecommerce\Product\Property\Attribute;
use App\Models\Ecommerce\Product\Property\ProductAttributeValue;
use App\Repositories\System\Cache\CacheRepository;
use Closure;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\DB;
class NovaProductRepository
{
/**
* inventory dependsOn
*/
public static function inventoryDependsOn(string $resource_attribute): Closure
{
return function ($field, $request, $formData) {
$user = $request->user();
if ($user->isEntrepreneur()) {
$field->options(Inventory::where(function ($query) use ($user) {
$query
->where('channel_id', $user->channel()->id)
->orWhere('shareable', true);
})->pluck('name', 'id'));
}
if ($user->isAdmin()) {
$field->options(Inventory::pluck('name', 'id'));
}
};
}
/**
* Price amount dependsOn
*/
public static function priceAmountDependsOn($categories = []): Closure
{
return function ($field, $request, $formData) use ($categories) {
if (! $formData->cost_amount) {
return;
}
if (count($categories) > 0) {
static::setPriceAmount($field, $categories, $formData->cost_amount);
return;
}
if ($formData->categories && is_array($formData->categories)) {
static::setPriceAmount($field, $formData->categories, $formData->cost_amount);
return;
}
if ($request->isNotFilled('categories')) {
return;
}
// For update request, if there are already categories, tackle it
$categories = is_string($request->input('categories'))
? json_decode($request->input('categories'))
: $request->input('categories');
if (! empty($categories)) {
static::setPriceAmount($field, $categories, $formData->cost_amount);
return;
}
};
}
/**
* Attributes Depends On (create request)
*/
public static function createRequestAttributesDependsOn($resource): Closure
{
return function ($field, $request, $formData) {
$categories = is_string($formData->categories)
? json_decode($formData->categories)
: $formData->categories;
if (! $categories) {
return;
}
session(['product_categories' => $categories]);
$field->fields(static::attributeFields($categories));
};
}
/**
* Attributes Depends On (update request)
*/
public static function updateRequestAttributesDependsOn($resource): Closure
{
return function ($field, $request, $formData) use ($resource) {
$categories = is_string($formData->categories)
? json_decode($formData->categories)
: $formData->categories;
$field->fields(
static::attributeFieldsWithValues($categories, $resource)
);
};
}
/**
* Create request variations depends on
*/
public static function createRequestVariationsDependsOn(): Closure
{
return function ($field, $request, $formData) {
$categories = is_string($formData->categories)
? json_decode($formData->categories)
: $formData->categories;
if (! $categories) {
return;
}
$field->show();
};
}
/**
* Set field's price amount
*
* @param array $categories
* @param int|float|string $cost_amount
*/
public static function setPriceAmount($field, array|Collection $categories, $cost_amount): void
{
$tax = productTaxForCategory($categories);
$field->value = ProductRepository::calculatePrice(
floatval($cost_amount),
$tax
);
}
/**
* Attribute fields
*/
public static function attributeFields($categories): array
{
$attribute_categories = DB::table('attribute_category')
->whereIntegerInRaw('category_id', $categories)
->distinct('attribute_id')
->pluck('attribute_id');
$attributes = Attribute::with('values')
->whereIntegerInRaw('id', $attribute_categories)
->get()
->map(
fn ($attribute) => [
'label' => $attribute->name,
'name' => $attribute->slug,
'type' => $attribute->type,
'required' => $attribute->is_required,
'options' => $attribute->values
->map(
fn ($value) => [
'label' => $value->value,
'value' => $value->id,
]
)
->toArray(),
]
);
return $attributes->toArray();
}
/**
* Attribute fields with values
*/
public static function attributeFieldsWithValues(
$categories,
$resource
): array {
if (is_null($categories) || is_null($resource)) {
return [];
}
$attribute_categories = DB::table('attribute_category')
->whereIntegerInRaw('category_id', $categories)
->distinct('attribute_id')
->pluck('attribute_id');
$product_attributes = DB::table('product_attributes')
->where('product_id', $resource->id)
->whereIntegerInRaw('attribute_id', $attribute_categories)
->get(['id', 'attribute_id']);
$product_attribute_values = ProductAttributeValue::whereIntegerInRaw(
column: 'product_attribute_id',
values: $product_attributes->pluck('id')
)->get();
$attributes = Attribute::with('values')
->whereIntegerInRaw('id', $attribute_categories)
->get()
->map(
fn ($attribute) => [
'label' => $attribute->name,
'name' => $attribute->slug,
'type' => $attribute->type,
'required' => false,
'default' => $product_attribute_values
->firstWhere(
key: 'product_attribute_id',
operator: '=',
value: $product_attributes->firstWhere(
'attribute_id',
'=',
$attribute->id
)?->id
)
?->valueForForms(),
'options' => $attribute->values
->map(
fn ($value) => [
'label' => $value->value,
'value' => $value->id,
]
)
->toArray(),
]
);
return $attributes->toArray();
}
/**
* Get products
*/
public static function values(): array
{
return CacheRepository::make(
name: 'cs-nova-models-products',
value: fn () => Product::where('products.is_visible', true)
->where('products.stock', '>', 0)
->pluck('name', 'id')
->toArray()
);
}
}