Compare commits

...

22 Commits

Author SHA1 Message Date
5e98841eea Update app/Models/Ecommerce/Product/Category/Category.php 2026-03-04 23:28:31 +05:00
2b8f9aa314 wip 2026-03-02 07:30:59 +05:00
cb63c54c39 wip 2026-03-02 07:08:57 +05:00
b7bc192e6f wip 2026-03-02 07:01:14 +05:00
06617a0005 wip 2026-02-25 19:24:49 +05:00
da2645fae9 add provinces seeder 2026-02-25 19:07:35 +05:00
066f4d6a53 ignore data dir in db 2026-02-25 19:04:00 +05:00
Mekan1206
1e84ceab3c Refactor code for consistency and clarity; update seeder comments, enhance error handling, and improve API routes. Added 'original' field to ProductMediaResource and adjusted various formatting issues across multiple files. 2026-02-20 15:33:29 +05:00
Mekan1206
a8599d9c79 WIP 2026-02-19 18:11:13 +05:00
Mekan1206
78ef14b99b WIP 2026-02-19 17:57:01 +05:00
Mekan1206
1a63c52106 WIP 2026-02-19 17:55:45 +05:00
Mekan1206
75a6af68eb WIP 2026-02-19 17:49:32 +05:00
Mekan1206
58c1915413 image 2026-02-19 06:22:37 +05:00
Mekan1206
ba537b7868 WIP 2026-02-19 01:08:52 +05:00
Mekan1206
bf69d6733b WIP 2026-02-19 00:47:22 +05:00
Mekan1206
9107d3118d WIP 2026-02-19 00:38:32 +05:00
Mekan1206
fac624b2a5 WIP 2026-02-19 00:35:01 +05:00
Mekan1206
9071c9a4c6 WIP 2026-02-18 23:38:01 +05:00
Mekan1206
18e510674a WIP 2026-02-18 23:37:02 +05:00
Mekan1206
073bbd497b only 400, 800, 1200 image resolutions remained 2026-02-18 23:32:00 +05:00
Mekan1206
ab3e69e831 WIP 2026-02-18 04:23:36 +05:00
Mekan1206
18401b908f WIP 2026-02-18 04:20:05 +05:00
60 changed files with 1173 additions and 156 deletions

View File

@@ -20,7 +20,7 @@ class Kernel extends ConsoleKernel
$schedule->call(new PruneStaleAttachments)->daily();
// IF any warnings unresolved warnings exists, send notify me
$schedule->call(new WarnDev)->dailyAt('16:00');
$schedule->call(new WarnDev)->dailyAt('16:00');
}
/**

View File

@@ -22,4 +22,4 @@ class WarnDev extends Command
sendSMS('61929248', 'Warnings: '.$warnings->count());
}
}
}

View File

@@ -3,7 +3,9 @@
namespace App\Exceptions;
use Illuminate\Foundation\Exceptions\Handler as ExceptionHandler;
use Symfony\Component\HttpKernel\Exception\HttpException;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
use Throwable;
class Handler extends ExceptionHandler
{
@@ -29,5 +31,25 @@ class Handler extends ExceptionHandler
return response()->noContent(404);
}
});
$this->reportable(function (Throwable $e) {
$statusCode = $e instanceof HttpException ? $e->getStatusCode() : 500;
// only real server errors
if ($statusCode < 500) {
return;
}
try {
warn(
message: get_class($e),
content: $e->getMessage(),
where: $e->getFile().':'.$e->getLine(),
notes: substr($e->getTraceAsString(), 0, 65000),
);
} catch (Throwable $ignored) {
// logging must never crash the app
}
});
}
}

View File

@@ -390,7 +390,7 @@ function createHalkbankOrder($price = 123): array
];
}
/**
/**
* Warn brother
*/
function warn(string $message, string $content = '', string $where = '', string $notes = ''): void
@@ -401,4 +401,4 @@ function warn(string $message, string $content = '', string $where = '', string
'where' => $where,
'notes' => $notes,
]);
}
}

View File

@@ -15,9 +15,8 @@ class BrandMediaResource extends JsonResource
public function toArray(Request $request): array
{
return [
'thumbnail' => $this->getUrl('thumb200x200'),
'thumbnail' => $this->getUrl('thumb400x400'),
'images_400x400' => $this->getUrl('thumb400x400'),
'images_720x720' => $this->getUrl('thumb720x720'),
'images_800x800' => $this->getUrl('thumb800x800'),
'images_1200x1200' => $this->getUrl('thumb1200x1200'),
];

View File

@@ -55,7 +55,7 @@ class CategoryController extends Controller
}
/**
* Brands (products)
* Categories (products)
*/
public function products(BasicProductIndexRequest $request, Category $category): JsonResponse
{

View File

@@ -17,7 +17,6 @@ class CategoryMediaResource extends JsonResource
return [
'thumbnail' => $this->getUrl(),
'images_400x400' => $this->getUrl('thumb400x400'),
'images_720x720' => $this->getUrl('thumb720x720'),
'images_800x800' => $this->getUrl('thumb800x800'),
'images_1200x1200' => $this->getUrl('thumb1200x1200'),
];

View File

@@ -0,0 +1,25 @@
<?php
namespace App\Http\Controllers\Api\V1\Category\Resources;
use Illuminate\Http\Request;
use Illuminate\Http\Resources\Json\JsonResource;
class SelectedCategoryResource extends JsonResource
{
/**
* Transform the resource into an array.
*
* @return array<string, mixed>
*/
public function toArray(Request $request): array
{
return [
'id' => $this->id,
'name' => $this->name,
'description' => $this->description,
'is_visible' => $this->is_visible,
'categories' => CategoryResource::collection($this->whenLoaded('categories')),
];
}
}

View File

@@ -0,0 +1,37 @@
<?php
namespace App\Http\Controllers\Api\V1\Category;
use App\Http\Controllers\Api\V1\Category\Resources\SelectedCategoryResource;
use App\Http\Controllers\Controller;
use App\Models\Ecommerce\Product\Category\SelectedCategory;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
class SelectedCategoryController extends Controller
{
/**
* Selected Categories (index)
*/
public function index(Request $request): JsonResponse
{
$selectedCategories = SelectedCategory::query()
->where('is_visible', true)
->with(['categories' => function ($query) {
$query->where('is_visible', true)->ordered()->with(['media']);
}])
->get();
return response()->json(SelectedCategoryResource::collection($selectedCategories));
}
/**
* Selected Categories (show)
*/
public function show(SelectedCategory $selectedCategory): JsonResponse
{
$selectedCategory->load('categories');
return response()->json(new SelectedCategoryResource($selectedCategory));
}
}

View File

@@ -14,7 +14,7 @@ class OrderPaymentController extends Controller
public function index(): JsonResponse
{
return response()->rest(
PaymentType::all(['id', 'name'])
PaymentType::query()->where('is_enabled', true)->get(['id', 'name'])
->map(fn ($paymentType) => [
'id' => $paymentType->id,
'name' => $paymentType->name,

View File

@@ -6,6 +6,7 @@ use App\Http\Controllers\Controller;
use App\Http\Requests\CheckoutOrderRequest;
use App\Http\Resources\Api\V1\Order\OrderIndexResource;
use App\Models\Ecommerce\Product\Order\Order;
use App\Models\Ecommerce\Product\Order\Shipping\OrderShipping;
use App\Repositories\Ecommerce\Order\OrderRepository;
use App\Services\Order\CreateOrderService;
use Illuminate\Http\JsonResponse;
@@ -33,6 +34,27 @@ class OrderController extends Controller
return response()->rest(OrderRepository::availableTimes());
}
/**
* Order deliveries
*/
public function deliveries(): JsonResponse
{
return response()->rest([
[
'name' => OrderShipping::STANDART,
'price' => 20,
],
[
'name' => OrderShipping::SELF_PICKUP,
'price' => 0
],
[
'name' => OrderShipping::REGION,
'price' => 40,
],
]);
}
/**
* (*) Store order
*/

View File

@@ -15,9 +15,9 @@ class ProductMediaResource extends JsonResource
public function toArray(Request $request): array
{
return [
'thumbnail' => $this->getUrl('thumb288x431'),
'original' => $this->getUrl(),
'thumbnail' => $this->getUrl('thumb400x400'),
'images_400x400' => $this->getUrl('thumb400x400'),
'images_720x720' => $this->getUrl('thumb720x720'),
'images_800x800' => $this->getUrl('thumb800x800'),
'images_1200x1200' => $this->getUrl('thumb1200x1200'),
];

View File

@@ -40,6 +40,7 @@ class CheckoutOrderRequest extends FormRequest
'customer_address' => ['required', 'string', 'max:255'],
'shipping_method' => ['required', 'string', 'max:255', Rule::in(array_keys(OrderShipping::values()))],
'shipping_price' => ['nullable', 'numeric'],
'payment_type_id' => ['required', Rule::in(array_keys(OrderPayment::values()))],
'notes' => ['nullable', 'string', 'max:255'],
@@ -65,7 +66,7 @@ class CheckoutOrderRequest extends FormRequest
'user_id' => auth()->id(),
'notes' => $this->notes ?: null,
'province_id' => $this->province_id ?: null,
'shipping_price' => OrderShipping::priceFor($this->shipping_method),
'shipping_price' => $this->shipping_price ?: OrderShipping::priceFor($this->shipping_method),
'delivery_time' => $this->delivery_time ?: OrderShipping::MORNING,
'delivery_at' => $this->delivery_at ?: date('Y-m-d'),
'source' => $this->source ?: OS::MOBILE_APP,

View File

@@ -17,7 +17,6 @@ class ChannelMediaResource extends JsonResource
return [
'thumbnail' => $this->getUrl(),
'images_400x400' => $this->getUrl('thumb400x400'),
'images_720x720' => $this->getUrl('thumb720x720'),
'images_800x800' => $this->getUrl('thumb800x800'),
'images_1200x1200' => $this->getUrl('thumb1200x1200'),
];

View File

@@ -15,9 +15,8 @@ class MediaResource extends JsonResource
public function toArray(Request $request): array
{
return [
'thumbnail' => $this->getUrl('thumb720x720'),
'thumbnail' => $this->getUrl('thumb400x400'),
'images_400x400' => $this->getUrl('thumb400x400'),
'images_720x720' => $this->getUrl('thumb720x720'),
'images_800x800' => $this->getUrl('thumb800x800'),
'images_1200x1200' => $this->getUrl('thumb1200x1200'),
];

View File

@@ -106,24 +106,15 @@ class Banner extends Model implements HasMedia
*/
public function registerMediaConversions(?Media $media = null): void
{
$this->addMediaConversion('thumb200x200')
->fit(Manipulations::FIT_CONTAIN, 200, 200);
$this->addMediaConversion('thumb400x400')
->fit(Manipulations::FIT_CONTAIN, 400, 400);
$this->addMediaConversion('thumb350x350')
->fit(Manipulations::FIT_CONTAIN, 350, 350);
$this->addMediaConversion('thumb720x720')
->fit(Manipulations::FIT_CONTAIN, 720, 720);
$this->addMediaConversion('thumb800x800')
->fit(Manipulations::FIT_CONTAIN, 800, 800);
$this->addMediaConversion('thumb1200x1200')
->fit(Manipulations::FIT_CONTAIN, 1200, 1200);
$this->addMediaConversion('thumb288x431')
->fit(Manipulations::FIT_CONTAIN, 288, 431);

View File

@@ -109,29 +109,14 @@ class Channel extends Model implements HasMedia, Sortable
*/
public function registerMediaConversions(?Media $media = null): void
{
$this->addMediaConversion('thumb150x150')
->fit(Manipulations::FIT_CONTAIN, 150, 150);
$this->addMediaConversion('thumb200x200')
->fit(Manipulations::FIT_CONTAIN, 200, 200);
$this->addMediaConversion('thumb400x400')
->fit(Manipulations::FIT_CONTAIN, 400, 400);
$this->addMediaConversion('thumb720x720')
->fit(Manipulations::FIT_CONTAIN, 720, 720);
$this->addMediaConversion('thumb800x800')
->fit(Manipulations::FIT_CONTAIN, 800, 800);
$this->addMediaConversion('thumb1200x1200')
->fit(Manipulations::FIT_CONTAIN, 1200, 1200);
$this->addMediaConversion('thumb288x431')
->fit(Manipulations::FIT_CONTAIN, 288, 431);
$this->addMediaConversion('thumb270x350')
->fit(Manipulations::FIT_CONTAIN, 270, 350);
}
/**

View File

@@ -85,26 +85,14 @@ class Brand extends Model implements HasMedia, Sortable
*/
public function registerMediaConversions(?Media $media = null): void
{
$this->addMediaConversion('thumb200x200')
->fit(Manipulations::FIT_CONTAIN, 200, 200);
$this->addMediaConversion('thumb400x400')
->fit(Manipulations::FIT_CONTAIN, 400, 400);
$this->addMediaConversion('thumb720x720')
->fit(Manipulations::FIT_CONTAIN, 720, 720);
$this->addMediaConversion('thumb800x800')
->fit(Manipulations::FIT_CONTAIN, 800, 800);
$this->addMediaConversion('thumb1200x1200')
->fit(Manipulations::FIT_CONTAIN, 1200, 1200);
$this->addMediaConversion('thumb288x431')
->fit(Manipulations::FIT_CONTAIN, 288, 431);
$this->addMediaConversion('thumb270x350')
->fit(Manipulations::FIT_CONTAIN, 270, 350);
}
/**

View File

@@ -82,7 +82,6 @@ class Category extends Model implements HasMedia, Sortable
{
$this->addMediaCollection('uploads')
->singleFile()
->acceptsMimeTypes(['image/jpg', 'image/jpeg', 'image/png'])
->useFallbackUrl(
sprintf('%s/logo-space.png', config('app.url'))
);
@@ -93,29 +92,14 @@ class Category extends Model implements HasMedia, Sortable
*/
public function registerMediaConversions(?Media $media = null): void
{
$this->addMediaConversion('thumb200x200')
->fit(Manipulations::FIT_CONTAIN, 200, 200);
$this->addMediaConversion('thumb400x400')
->fit(Manipulations::FIT_CONTAIN, 400, 400);
$this->addMediaConversion('thumb720x720')
->fit(Manipulations::FIT_CONTAIN, 720, 720);
$this->addMediaConversion('thumb800x800')
->fit(Manipulations::FIT_CONTAIN, 800, 800);
$this->addMediaConversion('thumb1200x1200')
->fit(Manipulations::FIT_CONTAIN, 1200, 1200);
$this->addMediaConversion('thumb288x431')
->fit(Manipulations::FIT_CONTAIN, 288, 431);
$this->addMediaConversion('thumb270x350')
->fit(Manipulations::FIT_CONTAIN, 270, 350);
$this->addMediaConversion('thumb657x230')
->fit(Manipulations::FIT_CROP, 657, 230);
}
/**

View File

@@ -0,0 +1,31 @@
<?php
namespace App\Models\Ecommerce\Product\Category;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
use Spatie\Translatable\HasTranslations;
class SelectedCategory extends Model
{
use HasFactory;
use HasTranslations;
protected $fillable = [
'name',
'description',
'is_visible',
];
public $translatable = ['name', 'description'];
protected $casts = [
'is_visible' => 'boolean',
];
public function categories(): BelongsToMany
{
return $this->belongsToMany(Category::class, 'category_selected_category');
}
}

View File

@@ -84,26 +84,14 @@ class Collection extends Model implements HasMedia, Sortable
*/
public function registerMediaConversions(?Media $media = null): void
{
$this->addMediaConversion('thumb200x200')
->fit(Manipulations::FIT_CONTAIN, 200, 200);
$this->addMediaConversion('thumb400x400')
->fit(Manipulations::FIT_CONTAIN, 400, 400);
$this->addMediaConversion('thumb720x720')
->fit(Manipulations::FIT_CONTAIN, 720, 720);
$this->addMediaConversion('thumb800x800')
->fit(Manipulations::FIT_CONTAIN, 800, 800);
$this->addMediaConversion('thumb1200x1200')
->fit(Manipulations::FIT_CONTAIN, 1200, 1200);
$this->addMediaConversion('thumb288x431')
->fit(Manipulations::FIT_CONTAIN, 288, 431);
$this->addMediaConversion('thumb270x350')
->fit(Manipulations::FIT_CONTAIN, 270, 350);
}
/**

View File

@@ -2,11 +2,11 @@
namespace App\Models\Ecommerce\Product\Order;
use App\Models\Concerns\HasSchemalessAttributes;
use App\Models\Ecommerce\Product\Order\Concerns\HasPayments;
use App\Models\Ecommerce\Product\Order\Concerns\HasShipping;
use App\Models\Ecommerce\Product\Order\Concerns\HasStatus;
use App\Models\Ecommerce\Product\Order\Status\OrderStatus;
use App\Models\Concerns\HasSchemalessAttributes;
use App\Models\System\Settings\Location\Province;
use App\Models\System\Settings\Payments\PaymentType;
use App\Models\User;
@@ -20,10 +20,10 @@ class Order extends Model
{
use HasFactory;
use HasPayments;
use HasSchemalessAttributes;
use HasShipping;
use HasStatus;
use SoftDeletes;
use HasSchemalessAttributes;
/**
* The attributes that are mass assignable.

View File

@@ -2,7 +2,6 @@
namespace App\Models\Ecommerce\Product\Product\Concerns;
use Illuminate\Support\Str;
use Spatie\Image\Manipulations;
use Spatie\MediaLibrary\MediaCollections\Models\Media;
@@ -22,30 +21,20 @@ trait ProductMedia
*/
public function registerMediaConversions(?Media $media = null): void
{
$conversions = [
'thumb200x200' => [200, 200],
'thumb400x400' => [400, 400],
'thumb720x720' => [720, 720],
'thumb800x800' => [800, 800],
'thumb1200x1200' => [1200, 1200],
'thumb288x431' => [288, 431],
'thumb270x350' => [270, 350],
];
$this->addMediaConversion('thumb400x400')
->fit(Manipulations::FIT_CONTAIN, 400, 400);
foreach ($conversions as $name => [$width, $height]) {
$this->addMediaConversion($name)
->fit(Manipulations::FIT_CONTAIN, $width, $height)
->useFileName(function (Media $media) use ($name) {
// generate short random name for the conversion
return Str::random(12) . '--' . $name . '.' . $media->getClientOriginalExtension();
});
}
$this->addMediaConversion('thumb800x800')
->fit(Manipulations::FIT_CONTAIN, 800, 800);
$this->addMediaConversion('thumb1200x1200')
->fit(Manipulations::FIT_CONTAIN, 1200, 1200);
}
/**
* Thumbnail
*/
public function thumbnail(string $size = '200x200'): string
public function thumbnail(string $size = '400x400'): string
{
return $this->getFirstMediaUrl('uploads', 'thumb'.$size);
}
@@ -53,7 +42,7 @@ trait ProductMedia
/**
* Get image when hovered (returns second image)
*/
public function getHoverImage(string $size = '270x350'): string
public function getHoverImage(string $size = '400x400'): string
{
$media = $this->getMedia('uploads');
$image_count = $media->count();

View File

@@ -62,7 +62,7 @@ class MostSoldProducts extends Lens
{
return [
ID::make(__('ID'), 'id')->sortable(),
Images::make(__('Image'), 'uploads')->conversionOnIndexView('thumb200x200'),
Images::make(__('Image'), 'uploads')->conversionOnIndexView('thumb400x400'),
Text::make(__('Name'), 'name')->sortable(),
Number::make(__('Price'), 'price_amount')->sortable(),

View File

@@ -81,7 +81,7 @@ class Banner extends Resource
ID::make()->sortable(),
Images::make(__('Image'), 'main')
->conversionOnIndexView('thumb200x200')
->conversionOnIndexView('thumb400x400')
->rules('required')
->required(),

View File

@@ -90,7 +90,7 @@ class Channel extends Resource
ID::make()->sortable(),
Images::make(__('Image'), 'uploads')
->conversionOnIndexView('thumb200x200')
->conversionOnIndexView('thumb400x400')
->rules('required')
->required(),

View File

@@ -18,7 +18,7 @@ class ChannelFieldsForIndex
ID::make()->hidden(),
Images::make(__('Image'), 'uploads')
->conversionOnIndexView('thumb200x200'),
->conversionOnIndexView('thumb400x400'),
Text::make(__('Name'), 'name')
->sortable(),

View File

@@ -96,7 +96,7 @@ class Brand extends Resource
ID::make()->sortable(),
Images::make(__('Image'), 'uploads')
->conversionOnIndexView('thumb200x200')
->conversionOnIndexView('thumb400x400')
->rules('required')
->required(),

View File

@@ -83,7 +83,7 @@ class Category extends Resource
ID::make()->sortable(),
Images::make(__('Image'), 'uploads')
->conversionOnIndexView('thumb200x200')
->conversionOnIndexView('thumb400x400')
->rules('required')
->required(),

View File

@@ -0,0 +1,120 @@
<?php
namespace App\Nova\Resources\Ecommerce\Product\Category;
use App\Models\Ecommerce\Product\Category\SelectedCategory as SelectedCategoryModel;
use App\Nova\Resource;
use Laravel\Nova\Fields\BelongsToMany;
use Laravel\Nova\Fields\ID;
use Laravel\Nova\Fields\Text;
use Laravel\Nova\Fields\Textarea;
use Laravel\Nova\Http\Requests\NovaRequest;
use Trin4ik\NovaSwitcher\NovaSwitcher;
class SelectedCategory extends Resource
{
/**
* The model the resource corresponds to.
*
* @var class-string<SelectedCategoryModel>
*/
public static $model = SelectedCategoryModel::class;
/**
* The single value that should be used to represent the resource when being displayed.
*
* @var string
*/
public static $title = 'name';
/**
* The columns that should be searched.
*
* @var array
*/
public static $search = [
'id', 'name',
];
/**
* Get the displayable label of the resource.
*/
public static function label(): string
{
return __('Sections');
}
/**
* Get the displayable singular label of the resource.
*/
public static function singularLabel(): string
{
return __('Section');
}
/**
* Get the fields displayed by the resource.
*
* @return array
*/
public function fields(NovaRequest $request)
{
return [
ID::make()->sortable(),
Text::make(__('Name'), 'name')
->sortable()
->translatable()
->rules('required'),
Textarea::make(__('Description'), 'description')
->translatable()
->nullable(),
NovaSwitcher::make(__('Is Visible'), 'is_visible')
->default(true),
BelongsToMany::make(__('Categories'), 'categories', Category::class),
];
}
/**
* Get the cards available for the request.
*
* @return array
*/
public function cards(NovaRequest $request)
{
return [];
}
/**
* Get the filters available for the resource.
*
* @return array
*/
public function filters(NovaRequest $request)
{
return [];
}
/**
* Get the lenses available for the resource.
*
* @return array
*/
public function lenses(NovaRequest $request)
{
return [];
}
/**
* Get the actions available for the resource.
*
* @return array
*/
public function actions(NovaRequest $request)
{
return [];
}
}

View File

@@ -76,7 +76,7 @@ class Collection extends Resource
ID::make()->sortable(),
Images::make(__('Image'), 'uploads')
->conversionOnIndexView('thumb200x200')
->conversionOnIndexView('thumb400x400')
->rules('required')
->required(),

View File

@@ -81,7 +81,7 @@ class ProductResource extends Resource
{
return [
ID::make()->sortable(),
Images::make(__('Image'), 'uploads')->conversionOnIndexView('thumb200x200'),
Images::make(__('Image'), 'uploads')->conversionOnIndexView('thumb400x400'),
Text::make(__('Name'), fn () => $this->novaDetailPage())
->displayUsing(FieldHelpers::asLink(
link: $this->novaDetailPage(),

View File

@@ -27,7 +27,7 @@ class OrderFieldsForCreate
return [
Hidden::make('number')->default(Str::random(30)),
Hidden::make('user_id')->default($request->user()->id),
Hidden::make('source_app')->default(OS::ADMIN),
Hidden::make('source')->default(OS::ADMIN),
ID::make(),

View File

@@ -67,7 +67,7 @@ class OrderFieldsForDetail
)
->asHtml(),
Select::make(__('App'), 'source_app')
Select::make(__('App'), 'source')
->displayUsingLabels()
->options(OS::apps())
->sortable(),

View File

@@ -55,7 +55,7 @@ class OrderFieldsForIndex
->default(OrderShipping::default())
->sortable(),
Select::make(__('Source'), 'source_app')
Select::make(__('Source'), 'source')
->displayUsingLabels()
->options(OS::apps())
->sortable(),

View File

@@ -93,7 +93,7 @@ class ProductFieldsForCreate
->rules('nullable', 'string'),
Images::make(__('Image'), 'uploads')
->conversionOnIndexView('thumb200x200')
->conversionOnIndexView('thumb400x400')
->rules('required')
->setFileName(NovaForm::fillMediaFileName())
->required(),

View File

@@ -53,7 +53,7 @@ class ProductFieldsForDetail
Text::make(__('Name'), 'name'),
Images::make(__('Image'), 'uploads')
->conversionOnIndexView('thumb200x200'),
->conversionOnIndexView('thumb400x400'),
Trix::make(__('Description'), 'description')->withFiles('public')->alwaysShow(),
Text::make(__('Price'), 'cost_amount'),

View File

@@ -26,7 +26,7 @@ class ProductFieldsForIndex
return [
ID::make()->sortable(),
Images::make(__('Image'), 'uploads')->conversionOnIndexView('thumb200x200'),
Images::make(__('Image'), 'uploads')->conversionOnIndexView('thumb400x400'),
Text::make(__('Name'), 'name')->sortable(),
BelongsTo::make(__('Brand'), 'brand', Brand::class)

View File

@@ -32,7 +32,7 @@ class VariantFieldsForDetail
BelongsTo::make(__('Parent'), 'parent', Product::class),
Images::make(__('Image'), 'uploads')
->conversionOnIndexView('thumb200x200'),
->conversionOnIndexView('thumb400x400'),
Text::make(__('Price'), 'cost_amount')
->rules('required', 'numeric'),

View File

@@ -20,7 +20,7 @@ class VariantFieldsForIndex
ID::make()->sortable(),
Images::make(__('Image'), 'uploads')
->conversionOnIndexView('thumb200x200'),
->conversionOnIndexView('thumb400x400'),
Text::make(__('Price'), 'cost_amount')
->rules('required', 'numeric'),

View File

@@ -64,8 +64,8 @@ class ChannelPolicy
*/
public function update(User $user, Channel $channel): Response
{
if ($user->hasRole(['admin'])) {
return $this->allow();
if (tmpostChannel()->slug === $channel->slug) {
return $this->deny();
}
return $this->deny();

View File

@@ -15,6 +15,7 @@ use App\Nova\Resources\Ecommerce\Payout\PayoutResource;
use App\Nova\Resources\Ecommerce\Product\Attribute\Attribute;
use App\Nova\Resources\Ecommerce\Product\Brand\Brand;
use App\Nova\Resources\Ecommerce\Product\Category\Category;
use App\Nova\Resources\Ecommerce\Product\Category\SelectedCategory;
use App\Nova\Resources\Ecommerce\Product\Collection\Collection;
use App\Nova\Resources\Ecommerce\Product\Coupon\Coupon;
use App\Nova\Resources\Ecommerce\Product\Inventory\Inventory;
@@ -158,6 +159,7 @@ class NovaServiceProvider extends NovaApplicationServiceProvider
MenuItem::resource(Category::class),
MenuItem::resource(Brand::class),
MenuItem::resource(Attribute::class),
MenuItem::resource(SelectedCategory::class),
])->icon('color-swatch'),
])->icon('shopping-bag')->collapsedByDefault(),

View File

@@ -3,7 +3,6 @@
namespace App\Repositories\Ecommerce\Product\Category;
use App\Models\Ecommerce\Product\Category\Category;
use App\Repositories\System\Cache\CacheRepository;
use Illuminate\Http\Request;
class CategoryRepository

View File

@@ -52,10 +52,10 @@ class CreateOrderService
'stock' => $stock,
]);
} else {
warn('Product has no inventory record', json_encode([
'product_id' => $cart->product_id,
'order_id' => $order->id,
]));
warn('Product has no inventory record', json_encode([
'product_id' => $cart->product_id,
'order_id' => $order->id,
]));
}
});

View File

@@ -0,0 +1,28 @@
<?php
namespace App\Support;
use Illuminate\Support\Str;
use Spatie\MediaLibrary\Conversions\Conversion;
use Spatie\MediaLibrary\Support\FileNamer\FileNamer;
class ShortFileNamer extends FileNamer
{
/**
* Generate a short random name for the original file.
*/
public function originalFileName(string $fileName): string
{
return Str::random(10);
}
public function conversionFileName(string $fileName, Conversion $conversion): string
{
return $conversion->getName();
}
public function responsiveFileName(string $fileName): string
{
return 'res';
}
}

View File

@@ -58,7 +58,7 @@ return [
/*
* This is the class that is responsible for naming generated files.
*/
'file_namer' => Spatie\MediaLibrary\Support\FileNamer\DefaultFileNamer::class,
'file_namer' => App\Support\ShortFileNamer::class,
/*
* The class that contains the strategy for determining a media file's path.

3
database/data/.gitignore vendored Normal file
View File

@@ -0,0 +1,3 @@
*
!provinces.json
!.gitignore

View File

@@ -0,0 +1,716 @@
[
{
"id": 1,
"region": "ah",
"name": "{\"en\": \"Ak bugday\", \"ru\": \"Ак бугдай\", \"tk\": \"Ak bugdaý\"}",
"created_at": "2022-11-15 14:24:55",
"updated_at": "2022-11-15 14:24:55"
},
{
"id": 2,
"region": "ah",
"name": "{\"en\": \"Tejen\", \"ru\": \"Теджен\", \"tk\": \"Tejen\"}",
"created_at": "2022-11-15 14:26:35",
"updated_at": "2022-11-15 14:26:35"
},
{
"id": 3,
"region": "ah",
"name": "{\"en\": \"Kaka\", \"ru\": \"Кака\", \"tk\": \"Kaka\"}",
"created_at": "2022-11-15 14:28:01",
"updated_at": "2022-11-15 14:28:01"
},
{
"id": 4,
"region": "ag",
"name": "{\"en\": \"Bagtyyarlyk\", \"ru\": \"Багтыярлык\", \"tk\": \"Bagtyýarlyk\"}",
"created_at": "2022-11-15 15:08:49",
"updated_at": "2022-11-15 15:08:49"
},
{
"id": 5,
"region": "ag",
"name": "{\"en\": \"Kopetdag\", \"ru\": \"Копетдаг\", \"tk\": \"Köpetdag\"}",
"created_at": "2022-11-15 15:10:33",
"updated_at": "2022-11-15 15:10:33"
},
{
"id": 6,
"region": "ag",
"name": "{\"en\": \"Berkararlyk\", \"ru\": \"Беркарарлык\", \"tk\": \"Berkararlyk\"}",
"created_at": "2022-11-15 15:11:56",
"updated_at": "2022-11-15 15:11:56"
},
{
"id": 7,
"region": "ag",
"name": "{\"en\": \"Buzmeyin\", \"ru\": \"Бузмеин\", \"tk\": \"Büzmeýin\"}",
"created_at": "2022-11-15 15:13:11",
"updated_at": "2022-11-15 15:13:11"
},
{
"id": 8,
"region": "ah",
"name": "{\"en\": \"Babadayhan\", \"ru\": \"Бабадайхан\", \"tk\": \"Babadaýhan\"}",
"created_at": "2022-11-15 15:18:43",
"updated_at": "2022-11-15 15:18:43"
},
{
"id": 9,
"region": "ah",
"name": "{\"en\": \"Gokdepe\", \"ru\": \"Геёкдепе\", \"tk\": \"Gökdepe\"}",
"created_at": "2022-11-15 15:20:02",
"updated_at": "2022-11-15 15:20:02"
},
{
"id": 10,
"region": "ah",
"name": "{\"en\": \"Baherden\", \"ru\": \"Бахерден\", \"tk\": \"Bäherden\"}",
"created_at": "2022-11-15 15:21:20",
"updated_at": "2022-11-15 15:21:20"
},
{
"id": 11,
"region": "ah",
"name": "{\"en\": \"Sarahs\", \"ru\": \"Сарахс\", \"tk\": \"Sarahs\"}",
"created_at": "2022-11-15 15:23:04",
"updated_at": "2022-11-15 15:23:04"
},
{
"id": 12,
"region": "mr",
"name": "{\"en\": \"Mary\", \"ru\": \"Мары\", \"tk\": \"Mary\"}",
"created_at": "2022-11-15 15:24:10",
"updated_at": "2022-11-15 15:24:10"
},
{
"id": 13,
"region": "mr",
"name": "{\"en\": \"Garagum\", \"ru\": \"Гарагум\", \"tk\": \"Garagum\"}",
"created_at": "2022-11-15 15:25:22",
"updated_at": "2022-11-15 15:25:22"
},
{
"id": 14,
"region": "mr",
"name": "{\"en\": \"Vekilbazar\", \"ru\": \"Векилбазар\", \"tk\": \"Wekilbazar\"}",
"created_at": "2022-11-15 15:26:42",
"updated_at": "2022-11-15 15:26:42"
},
{
"id": 15,
"region": "mr",
"name": "{\"en\": \"Yoloten\", \"ru\": \"Ёлотен\", \"tk\": \"Yolöten\"}",
"created_at": "2022-11-15 15:27:45",
"updated_at": "2022-11-15 15:27:45"
},
{
"id": 16,
"region": "mr",
"name": "{\"en\": \"Bayramaly\", \"ru\": \"Байрамалы\", \"tk\": \"Baýramaly\"}",
"created_at": "2022-11-15 15:28:49",
"updated_at": "2022-11-15 15:28:49"
},
{
"id": 17,
"region": "mr",
"name": "{\"en\": \"Murgap\", \"ru\": \"Мургап\", \"tk\": \"Murgap\"}",
"created_at": "2022-11-15 15:30:27",
"updated_at": "2022-11-15 15:30:27"
},
{
"id": 18,
"region": "mr",
"name": "{\"en\": \"Sakarchage\", \"ru\": \"Сакарчаге\", \"tk\": \"Sakarçäge\"}",
"created_at": "2022-11-15 15:31:42",
"updated_at": "2022-11-15 15:31:42"
},
{
"id": 19,
"region": "mr",
"name": "{\"en\": \"Tagtabazar\", \"ru\": \"Тагтабазар\", \"tk\": \"Tagtabazar\"}",
"created_at": "2022-11-15 15:32:53",
"updated_at": "2022-11-15 15:32:53"
},
{
"id": 20,
"region": "mr",
"name": "{\"en\": \"Turkmengala\", \"ru\": \"Туркменгала\", \"tk\": \"Türkmengala\"}",
"created_at": "2022-11-15 15:33:59",
"updated_at": "2022-11-15 15:33:59"
},
{
"id": 21,
"region": "bn",
"name": "{\"en\": \"Etrek\", \"ru\": \"Етрек\", \"tk\": \"Etrek\"}",
"created_at": "2022-11-15 15:35:37",
"updated_at": "2022-11-15 15:35:37"
},
{
"id": 22,
"region": "bn",
"name": "{\"en\": \"Turkmenbashy\", \"ru\": \"Туркменбащы\", \"tk\": \"Türkmenbaşy\"}",
"created_at": "2022-11-15 15:38:29",
"updated_at": "2022-11-15 15:38:29"
},
{
"id": 23,
"region": "bn",
"name": "{\"en\": \"Esenguly\", \"ru\": \"Эсенгулы\", \"tk\": \"Esenguly\"}",
"created_at": "2022-11-15 15:39:37",
"updated_at": "2022-11-15 15:39:37"
},
{
"id": 24,
"region": "bn",
"name": "{\"en\": \"Gyzylarbat\", \"ru\": \"Гызыларбат\", \"tk\": \"Gyzylarbat\"}",
"created_at": "2022-11-15 15:40:50",
"updated_at": "2022-11-15 15:40:50"
},
{
"id": 25,
"region": "bn",
"name": "{\"en\": \"Bereket\", \"ru\": \"Берекет\", \"tk\": \"Bereket\"}",
"created_at": "2022-11-15 15:41:39",
"updated_at": "2022-11-15 15:41:39"
},
{
"id": 26,
"region": "bn",
"name": "{\"en\": \"Magtymguly\", \"ru\": \"Магтымгулы\", \"tk\": \"Magtymguly\"}",
"created_at": "2022-11-15 15:42:46",
"updated_at": "2022-11-15 15:42:46"
},
{
"id": 27,
"region": "dz",
"name": "{\"en\": \"Gorogly\", \"ru\": \"Гёроглы\", \"tk\": \"Görogly\"}",
"created_at": "2022-11-15 15:44:05",
"updated_at": "2022-11-15 15:44:05"
},
{
"id": 28,
"region": "dz",
"name": "{\"en\": \"Akdepe\", \"ru\": \"Aкдепе\", \"tk\": \"Akdepe\"}",
"created_at": "2022-11-15 15:44:53",
"updated_at": "2022-11-15 15:44:53"
},
{
"id": 29,
"region": "dz",
"name": "{\"en\": \"Ruhybelent\", \"ru\": \"Рухыбелент\", \"tk\": \"Ruhybelent\"}",
"created_at": "2022-11-15 15:45:43",
"updated_at": "2022-11-15 15:45:43"
},
{
"id": 30,
"region": "dz",
"name": "{\"en\": \"Boldumsaz\", \"ru\": \"Болдумсаз\", \"tk\": \"Boldumsaz\"}",
"created_at": "2022-11-15 15:46:38",
"updated_at": "2022-11-15 15:46:38"
},
{
"id": 31,
"region": "dz",
"name": "{\"en\": \"Koneurgench\", \"ru\": \"Конеугенч\", \"tk\": \"Köneürgenç\"}",
"created_at": "2022-11-15 15:48:00",
"updated_at": "2022-11-15 15:48:00"
},
{
"id": 32,
"region": "dz",
"name": "{\"en\": \"Shabat\", \"ru\": \"Шабать\", \"tk\": \"Gubadag\"}",
"created_at": "2022-11-15 15:48:46",
"updated_at": "2022-12-03 10:08:32"
},
{
"id": 33,
"region": "dz",
"name": "{\"en\": \"S.Turkmenbashy\", \"ru\": \"С.Туркменбащы\", \"tk\": \"S.Türkmenbaşy\"}",
"created_at": "2022-11-15 15:50:34",
"updated_at": "2022-12-03 10:13:38"
},
{
"id": 34,
"region": "lb",
"name": "{\"en\": \"Charjev\", \"ru\": \"Чарджев\", \"tk\": \"Çärjew\"}",
"created_at": "2022-11-15 15:52:33",
"updated_at": "2022-11-15 15:52:33"
},
{
"id": 35,
"region": "lb",
"name": "{\"en\": \"Halach\", \"ru\": \"Халач\", \"tk\": \"Halaç\"}",
"created_at": "2022-11-15 15:53:16",
"updated_at": "2022-11-15 15:53:16"
},
{
"id": 36,
"region": "lb",
"name": "{\"en\": \"Hojambaz\", \"ru\": \"Ходжамбаз\", \"tk\": \"Hojambaz\"}",
"created_at": "2022-11-15 15:54:20",
"updated_at": "2022-11-15 15:54:20"
},
{
"id": 37,
"region": "lb",
"name": "{\"en\": \"Kerki\", \"ru\": \"Керки\", \"tk\": \"Kerki\"}",
"created_at": "2022-11-15 15:55:09",
"updated_at": "2022-11-15 15:55:09"
},
{
"id": 38,
"region": "lb",
"name": "{\"en\": \"Darganata\", \"ru\": \"Дарганата\", \"tk\": \"Darganata\"}",
"created_at": "2022-11-15 15:56:01",
"updated_at": "2022-11-15 15:56:01"
},
{
"id": 39,
"region": "lb",
"name": "{\"en\": \"Danev\", \"ru\": \"Данев\", \"tk\": \"Dänew\"}",
"created_at": "2022-11-15 15:57:20",
"updated_at": "2022-11-15 15:57:20"
},
{
"id": 40,
"region": "lb",
"name": "{\"en\": \"Sayat\", \"ru\": \"Саят\", \"tk\": \"Saýat\"}",
"created_at": "2022-11-15 15:58:08",
"updated_at": "2022-11-15 15:58:08"
},
{
"id": 41,
"region": "lb",
"name": "{\"en\": \"Koytendag\", \"ru\": \"Койтендаг\", \"tk\": \"Köýtendag\"}",
"created_at": "2022-11-15 15:58:58",
"updated_at": "2022-11-15 15:58:58"
},
{
"id": 42,
"region": "ah",
"name": "{\"en\": \"Altyn asyr c.\", \"ru\": \"Aлтын асыр г.\", \"tk\": \"Altyn asyr ş.\"}",
"created_at": "2022-11-15 16:44:54",
"updated_at": "2022-11-15 16:47:40"
},
{
"id": 43,
"region": "ah",
"name": "{\"en\": \"Anev c.\", \"ru\": \"Аннау г.\", \"tk\": \"Änew ş.\"}",
"created_at": "2022-11-15 16:46:43",
"updated_at": "2022-11-15 16:46:43"
},
{
"id": 44,
"region": "ah",
"name": "{\"en\": \"Dushak c.\", \"ru\": \"Душак г.\", \"tk\": \"Duşak ş.\"}",
"created_at": "2022-11-15 16:49:47",
"updated_at": "2022-11-15 16:50:26"
},
{
"id": 45,
"region": "bn",
"name": "{\"en\": \"Balkanaabat c.\", \"ru\": \"Балканабат г.\", \"tk\": \"Balkanabat ş.\"}",
"created_at": "2022-11-15 16:51:48",
"updated_at": "2022-11-15 16:51:48"
},
{
"id": 46,
"region": "bn",
"name": "{\"en\": \"Gumdag c.\", \"ru\": \"Гумдаг г.\", \"tk\": \"Gumdag ş.\"}",
"created_at": "2022-11-15 16:53:07",
"updated_at": "2022-11-15 16:53:07"
},
{
"id": 47,
"region": "bn",
"name": "{\"en\": \"Garabogaz c.\", \"ru\": \"Гарабогаз г.\", \"tk\": \"Garabogaz ş.\"}",
"created_at": "2022-11-15 16:54:31",
"updated_at": "2022-11-15 16:54:31"
},
{
"id": 48,
"region": "bn",
"name": "{\"en\": \"Hazar c.\", \"ru\": \"Хазар г.\", \"tk\": \"Hazar ş.\"}",
"created_at": "2022-11-15 16:55:40",
"updated_at": "2022-11-15 16:55:40"
},
{
"id": 49,
"region": "lb",
"name": "{\"en\": \"Sakar c.\", \"ru\": \"Cакар г.\", \"tk\": \"Sakar ş\"}",
"created_at": "2022-11-15 17:06:13",
"updated_at": "2022-11-15 17:06:13"
},
{
"id": 50,
"region": "lb",
"name": "{\"en\": \"Seydi c.\", \"ru\": \"Сейди г.\", \"tk\": \"Seýdi ş.\"}",
"created_at": "2022-11-15 17:07:17",
"updated_at": "2022-11-15 17:07:17"
},
{
"id": 51,
"region": "lb",
"name": "{\"en\": \"Dostlyk c.\", \"ru\": \"Достлык г.\", \"tk\": \"Dostluk ş.\"}",
"created_at": "2022-11-15 17:08:27",
"updated_at": "2022-11-15 17:08:27"
},
{
"id": 52,
"region": "mr",
"name": "{\"en\": \"Murgap\", \"ru\": \"Мургап\", \"tk\": \"Murgap\"}",
"created_at": "2022-11-15 17:09:29",
"updated_at": "2022-11-15 17:09:29"
},
{
"id": 53,
"region": "lb",
"name": "{\"en\": \"Garabekrevul c.\", \"ru\": \"Гарабекевул г.\", \"tk\": \"Garabekewül ş.\"}",
"created_at": "2022-11-15 17:11:41",
"updated_at": "2022-11-16 09:02:15"
},
{
"id": 54,
"region": "dz",
"name": "{\"en\": \"Gurbansoltan Eje\", \"ru\": \"Гурбансолтан эдже\", \"tk\": \"Gurbansoltan Eje\"}",
"created_at": "2022-12-03 10:10:57",
"updated_at": "2022-12-03 10:10:57"
},
{
"id": 55,
"region": "dz",
"name": "{\"en\": \"S.Nyýazow\", \"ru\": \"С,Ныязов\", \"tk\": \"S.Nyýazow\"}",
"created_at": "2022-12-03 10:12:31",
"updated_at": "2022-12-03 10:12:31"
},
{
"id": 56,
"region": "dz",
"name": "{\"en\": \"Dashoguz s.\", \"ru\": \"Дашогуз г.\", \"tk\": \"Daşoguz ş.\"}",
"created_at": "2023-01-18 11:00:24",
"updated_at": "2023-01-18 11:00:24"
},
{
"id": 58,
"region": "ah",
"name": "{\"en\": \"Watan f/u\", \"ru\": \"Ватан с/ф\", \"tk\": \"Watan d/b\"}",
"created_at": "2023-05-23 14:31:44",
"updated_at": "2023-05-23 14:45:56"
},
{
"id": 59,
"region": "ah",
"name": "{\"en\": \"A blessed town\", \"ru\": \"Берекет г.\", \"tk\": \"Bereket ş.\"}",
"created_at": "2023-05-23 15:47:26",
"updated_at": "2023-05-23 15:47:26"
},
{
"id": 60,
"region": "ah",
"name": "{\"en\": \"Youth town\", \"ru\": \"Яшлик г.\", \"tk\": \"Ýaşlyk ş.\"}",
"created_at": "2023-05-23 15:59:14",
"updated_at": "2023-05-23 15:59:57"
},
{
"id": 61,
"region": "ah",
"name": "{\"en\": \"Altyn asyr ş.\", \"ru\": \"Altyn asyr ş.\", \"tk\": \"Altyn asyr ş.\"}",
"created_at": "2023-05-23 16:09:54",
"updated_at": "2023-05-23 16:09:54"
},
{
"id": 62,
"region": "ah",
"name": "{\"en\": \"Small brother village\", \"ru\": \"Деревня младшего брата\", \"tk\": \"Kiçi aga obasy\"}",
"created_at": "2023-05-23 16:22:25",
"updated_at": "2023-05-23 16:22:25"
},
{
"id": 63,
"region": "ah",
"name": "{\"en\": \"Truth Farmers Union\", \"ru\": \"Правда с/ф\", \"tk\": \"Hakykat d/b\"}",
"created_at": "2023-05-23 16:45:22",
"updated_at": "2023-05-23 16:45:22"
},
{
"id": 64,
"region": "ah",
"name": "{\"en\": \"Bed City\", \"ru\": \"Бед Сити\", \"tk\": \"Duşak ş.\"}",
"created_at": "2023-05-23 16:49:30",
"updated_at": "2023-05-23 16:49:30"
},
{
"id": 65,
"region": "ah",
"name": "{\"en\": \"White Gold Consulting\", \"ru\": \"Консалтинг Белого Золота\", \"tk\": \"Ak Altyn g.\"}",
"created_at": "2023-05-23 17:02:49",
"updated_at": "2023-05-23 17:02:49"
},
{
"id": 66,
"region": "ah",
"name": "{\"en\": \"\\\"Hasyl\\\" f/a\", \"ru\": \"«Хасыл» a/ф\", \"tk\": \"Hasyl d/b\"}",
"created_at": "2023-05-23 17:11:00",
"updated_at": "2023-05-23 17:11:00"
},
{
"id": 67,
"region": "ah",
"name": "{\"en\": \"Zahmet Farmers Union\", \"ru\": \"Захмет c/ф\", \"tk\": \"Zähmet d/b\"}",
"created_at": "2023-05-23 17:16:37",
"updated_at": "2023-05-23 17:16:37"
},
{
"id": 68,
"region": "bn",
"name": "{\"en\": \"Jebel t.\", \"ru\": \"Джебель ш.\", \"tk\": \"Jebel ş.\"}",
"created_at": "2023-05-24 16:33:15",
"updated_at": "2023-05-24 16:39:39"
},
{
"id": 69,
"region": "bn",
"name": "{\"en\": \"Edge\", \"ru\": \"Кенар\", \"tk\": \"Kenar\"}",
"created_at": "2023-05-24 17:23:40",
"updated_at": "2023-05-24 17:23:40"
},
{
"id": 70,
"region": "bn",
"name": "{\"en\": \"Serdar\", \"ru\": \"Сердар\", \"tk\": \"Serdar\"}",
"created_at": "2023-05-25 16:36:42",
"updated_at": "2023-05-25 16:36:42"
},
{
"id": 71,
"region": "bn",
"name": "{\"en\": \"Ekerem şäherçe\", \"ru\": \"Экерем ш.\", \"tk\": \"Ekerem şäherçe\"}",
"created_at": "2023-05-25 16:53:18",
"updated_at": "2023-05-25 16:53:18"
},
{
"id": 72,
"region": "bn",
"name": "{\"en\": \"Garadepe ş.\", \"ru\": \"Гарадепе ш.\", \"tk\": \"Garadepe ş.\"}",
"created_at": "2023-05-25 17:09:27",
"updated_at": "2023-05-25 17:09:27"
},
{
"id": 73,
"region": "dz",
"name": "{\"en\": \"Bagtyýar zaman oba\", \"ru\": \"Багтыйар заман село\", \"tk\": \"Bagtyýar zaman oba\"}",
"created_at": "2023-05-26 15:15:20",
"updated_at": "2023-05-26 15:15:20"
},
{
"id": 74,
"region": "dz",
"name": "{\"en\": \"Al Horezmi\", \"ru\": \"Ал Хорезми\", \"tk\": \"Al Horezmi\"}",
"created_at": "2023-05-26 15:37:43",
"updated_at": "2023-05-26 15:37:43"
},
{
"id": 75,
"region": "dz",
"name": "{\"en\": \"Jeýhun\", \"ru\": \"Джейхун\", \"tk\": \"Jeýhun\"}",
"created_at": "2023-05-26 15:58:35",
"updated_at": "2023-05-26 15:58:35"
},
{
"id": 76,
"region": "dz",
"name": "{\"en\": \"Azady\", \"ru\": \"Азады\", \"tk\": \"Azady\"}",
"created_at": "2023-05-26 16:12:52",
"updated_at": "2023-05-26 16:12:52"
},
{
"id": 77,
"region": "dz",
"name": "{\"en\": \"Baýramhan\", \"ru\": \"Байрамхан\", \"tk\": \"Baýramhan\"}",
"created_at": "2023-05-26 16:21:31",
"updated_at": "2023-05-26 16:21:31"
},
{
"id": 78,
"region": "dz",
"name": "{\"en\": \"Ruhnama\", \"ru\": \"Рухнама\", \"tk\": \"Ruhnama\"}",
"created_at": "2023-05-29 14:53:11",
"updated_at": "2023-05-29 14:53:11"
},
{
"id": 79,
"region": "dz",
"name": "{\"en\": \"Magtymguly\", \"ru\": \"Махтумкули\", \"tk\": \"Magtymguly\"}",
"created_at": "2023-05-29 14:58:36",
"updated_at": "2023-05-29 14:58:36"
},
{
"id": 80,
"region": "dz",
"name": "{\"en\": \"Ýalkym\", \"ru\": \"Ялкым\", \"tk\": \"Ýalkym\"}",
"created_at": "2023-05-29 15:03:57",
"updated_at": "2023-05-29 15:03:57"
},
{
"id": 81,
"region": "dz",
"name": "{\"en\": \"Türkmenbaşy şaýoly\", \"ru\": \"Туркменбаши шайолы\", \"tk\": \"Türkmenbaşy şaýoly\"}",
"created_at": "2023-05-29 15:26:24",
"updated_at": "2023-05-29 15:28:05"
},
{
"id": 82,
"region": "dz",
"name": "{\"en\": \"Oguzhan\", \"ru\": \"Огузхан\", \"tk\": \"Oguzhan\"}",
"created_at": "2023-05-29 15:36:50",
"updated_at": "2023-05-29 15:36:50"
},
{
"id": 83,
"region": "lb",
"name": "{\"en\": \"Türkmenabat ş\", \"ru\": \"Туркменабат ш\", \"tk\": \"Türkmenabat ş\"}",
"created_at": "2023-05-29 15:55:51",
"updated_at": "2023-05-29 15:55:51"
},
{
"id": 84,
"region": "lb",
"name": "{\"en\": \"Farap\", \"ru\": \"Фарап\", \"tk\": \"Farap\"}",
"created_at": "2023-05-30 15:09:46",
"updated_at": "2023-05-30 15:09:46"
},
{
"id": 85,
"region": "lb",
"name": "{\"en\": \"Döwletli\", \"ru\": \"Довлетли\", \"tk\": \"Döwletli\"}",
"created_at": "2023-05-30 17:34:41",
"updated_at": "2023-05-30 17:34:41"
},
{
"id": 86,
"region": "mr",
"name": "{\"en\": \"Mollanepes k.\", \"ru\": \"Молланепес к.\", \"tk\": \"Mollanepes k.\"}",
"created_at": "2023-06-01 14:46:03",
"updated_at": "2023-06-01 14:46:03"
},
{
"id": 87,
"region": "mr",
"name": "{\"en\": \"Parahatlyk k.\", \"ru\": \"Парахатлык к.\", \"tk\": \"Parahatlyk k.\"}",
"created_at": "2023-06-01 14:49:45",
"updated_at": "2023-06-01 14:49:45"
},
{
"id": 88,
"region": "mr",
"name": "{\"en\": \"Kemine k.\", \"ru\": \"Кемине к.\", \"tk\": \"Kemine k.\"}",
"created_at": "2023-06-01 14:56:09",
"updated_at": "2023-06-01 14:56:09"
},
{
"id": 89,
"region": "mr",
"name": "{\"en\": \"Bagtyýarlyk k.\", \"ru\": \"Багтыярлык к.\", \"tk\": \"Bagtyýarlyk k.\"}",
"created_at": "2023-06-01 15:03:22",
"updated_at": "2023-06-01 15:03:22"
},
{
"id": 90,
"region": "mr",
"name": "{\"en\": \"Güneş ş.\", \"ru\": \"Гюнеш ш.\", \"tk\": \"Güneş ş.\"}",
"created_at": "2023-06-01 15:14:30",
"updated_at": "2023-06-01 15:14:30"
},
{
"id": 91,
"region": "mr",
"name": "{\"en\": \"Türkmenbaşy ş.\", \"ru\": \"Туркменбаши ш.\", \"tk\": \"Türkmenbaşy ş.\"}",
"created_at": "2023-06-01 15:24:42",
"updated_at": "2023-06-01 15:24:42"
},
{
"id": 92,
"region": "mr",
"name": "{\"en\": \"Şatlyk ş\", \"ru\": \"Шатлык ш\", \"tk\": \"Şatlyk ş\"}",
"created_at": "2023-06-01 15:40:12",
"updated_at": "2023-06-01 15:40:12"
},
{
"id": 93,
"region": "mr",
"name": "{\"en\": \"Oguzhan ş.\", \"ru\": \"Огузхан ш.\", \"tk\": \"Oguzhan ş.\"}",
"created_at": "2023-06-01 16:25:28",
"updated_at": "2023-06-01 16:25:28"
},
{
"id": 94,
"region": "mr",
"name": "{\"en\": \"Oguzhan\", \"ru\": \"Огузхан\", \"tk\": \"Oguzhan\"}",
"created_at": "2023-06-01 16:31:14",
"updated_at": "2023-06-01 16:31:14"
},
{
"id": 95,
"region": "mr",
"name": "{\"en\": \"Hakykat d/b\", \"ru\": \"Хакукат д/б\", \"tk\": \"Hakykat d/b\"}",
"created_at": "2023-06-01 16:37:04",
"updated_at": "2023-06-01 16:37:04"
},
{
"id": 96,
"region": "mr",
"name": "{\"en\": \"Peşanaly ş.\", \"ru\": \"Пешаналы ш.\", \"tk\": \"Peşanaly ş.\"}",
"created_at": "2023-06-01 16:48:10",
"updated_at": "2023-06-01 16:48:10"
},
{
"id": 97,
"region": "mr",
"name": "{\"en\": \"Türkmengala ş\", \"ru\": \"Туркменгала ш.\", \"tk\": \"Türkmengala ş\"}",
"created_at": "2023-06-02 15:09:50",
"updated_at": "2023-06-02 15:09:50"
},
{
"id": 98,
"region": "mr",
"name": "{\"en\": \"Nurana Gurbanmyradow d/b\", \"ru\": \"Нурана Гурбанмурадов д/б\", \"tk\": \"Nurana Gurbanmyradow d/b\"}",
"created_at": "2023-06-02 15:34:15",
"updated_at": "2023-06-02 15:34:15"
},
{
"id": 99,
"region": "mr",
"name": "{\"en\": \"746470 +993 632 8-41-68\", \"ru\": \"Сариязи д/б\", \"tk\": \"Saryýazy d/b\"}",
"created_at": "2023-06-02 16:33:22",
"updated_at": "2023-06-02 16:33:22"
},
{
"id": 100,
"region": "mr",
"name": "{\"en\": \"746500 +993 624 5-43-97\", \"ru\": \"Сариджа\", \"tk\": \"Saryja\"}",
"created_at": "2023-06-02 16:36:09",
"updated_at": "2023-06-02 16:36:09"
},
{
"id": 101,
"region": "mr",
"name": "{\"en\": \"Serhatabat ş.\", \"ru\": \"Серхетабат ш.\", \"tk\": \"Serhatabat ş.\"}",
"created_at": "2023-06-02 16:48:42",
"updated_at": "2023-06-02 16:48:42"
},
{
"id": 102,
"region": "mr",
"name": "{\"en\": \"Ýeňiş d/b\", \"ru\": \"Йениш д/б\", \"tk\": \"Ýeňiş d/b\"}",
"created_at": "2023-06-02 16:52:04",
"updated_at": "2023-06-02 16:52:04"
},
{
"id": 103,
"region": "mr",
"name": "{\"en\": \"Serhetabat etr\", \"ru\": \"Серхетабат\", \"tk\": \"Serhetabat etr\"}",
"created_at": "2023-06-02 16:56:52",
"updated_at": "2023-06-02 16:56:52"
}
]

View File

@@ -0,0 +1,24 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
public function up(): void
{
Schema::create('selected_categories', function (Blueprint $table) {
$table->id();
$table->jsonb('name');
$table->jsonb('description')->nullable();
$table->boolean('is_visible')->default(true);
$table->timestamps();
});
}
public function down(): void
{
Schema::dropIfExists('selected_categories');
}
};

View File

@@ -0,0 +1,23 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
public function up(): void
{
Schema::create('category_selected_category', function (Blueprint $table) {
$table->id();
$table->foreignId('selected_category_id')->constrained()->cascadeOnDelete();
$table->foreignId('category_id')->constrained()->cascadeOnDelete();
$table->timestamps();
});
}
public function down(): void
{
Schema::dropIfExists('category_selected_category');
}
};

View File

@@ -33,26 +33,27 @@ class DatabaseSeeder extends Seeder
public function run(): void
{
$this->call([
PaymentTypeSeeder::class,
UsersTableSeeder::class,
BrandsSeeder::class,
CustomersTableSeeder::class,
SellersTableSeeder::class,
ProductsTableSeeder::class,
ProductPricesSeeder::class,
CategoriesTableSeeder::class,
AddressSeeder::class,
PropertiesTableSeeder::class,
FavoritesSeeder::class,
SectionsSeeder::class,
ProductCategoryRelationshipsSeeder::class,
ProductBarcodesSeeder::class,
ProductPropertiesSeeder::class,
ProductPropertyValuesSeeder::class,
ProductStocksSeeder::class,
MediaSeeder::class,
OrderSeeder::class,
OrderAddressSeeder::class,
// ProvincesTableSeeder::class,
// PaymentTypeSeeder::class,
// UsersTableSeeder::class,
// BrandsSeeder::class,
// CustomersTableSeeder::class,
// SellersTableSeeder::class,
// ProductsTableSeeder::class,
// ProductPricesSeeder::class,
// CategoriesTableSeeder::class,
// AddressSeeder::class,
// PropertiesTableSeeder::class,
// FavoritesSeeder::class,
// SectionsSeeder::class,
// ProductCategoryRelationshipsSeeder::class,
// ProductBarcodesSeeder::class,
// ProductPropertiesSeeder::class,
// ProductPropertyValuesSeeder::class,
// ProductStocksSeeder::class,
// MediaSeeder::class,
// OrderSeeder::class,
// OrderAddressSeeder::class,
]);
}
}

View File

@@ -5,7 +5,6 @@ namespace Database\Seeders;
use App\Models\System\Settings\Payments\PaymentType;
use Illuminate\Database\Seeder;
class PaymentTypeSeeder extends Seeder
{
/**
@@ -38,6 +37,6 @@ class PaymentTypeSeeder extends Seeder
'is_enabled' => true,
'options' => null,
],
])->each(fn($data) => PaymentType::create($data));
])->each(fn ($data) => PaymentType::create($data));
}
}
}

View File

@@ -0,0 +1,38 @@
<?php
namespace Database\Seeders;
use Exception;
use Illuminate\Database\Seeder;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\File;
class ProvincesTableSeeder extends Seeder
{
/**
* Run the database seeds.
*/
public function run(): void
{
$datas = json_decode(File::get('database/data/provinces.json'));
$table = 'provinces';
foreach ($datas as $data) {
try {
DB::table($table)->insert([
'id' => $data->id,
'region' => $data->region,
'name' => $data->name,
'created_at' => $data->created_at,
'updated_at' => $data->updated_at,
]);
} catch (Exception $e) {
info(['province db erorr: ' => $e->getMessage()]);
}
}
DB::statement("
SELECT setval('{$table}_id_seq', (SELECT MAX(id) from {$table}))
");
}
}

View File

@@ -24,7 +24,7 @@ class UsersTableSeeder extends Seeder
*/
public function seedStarterKit(): void
{
$this->seedRoles();
// $this->seedRoles();
collect([
[
@@ -39,7 +39,7 @@ class UsersTableSeeder extends Seeder
$user->assignRole('admin');
});
$this->createChannels();
// $this->createChannels();
}
public function seedRoles(): void

View File

@@ -35,7 +35,7 @@ class MediaSeeder extends Seeder
}
DB::table($table)->insert([
"id" => $data['id'],
'id' => $data['id'],
'model_type' => $modelType,
'model_id' => $data['model_id'],
'uuid' => $data['uuid'],
@@ -61,4 +61,4 @@ class MediaSeeder extends Seeder
");
});
}
}
}

View File

@@ -2,7 +2,6 @@
namespace Database\Seeders\New;
use Illuminate\Database\Console\Seeds\WithoutModelEvents;
use Illuminate\Database\Seeder;
use Illuminate\Support\Facades\DB;
use JsonMachine\Items;

View File

@@ -2,7 +2,6 @@
namespace Database\Seeders\New;
use App\Models\Ecommerce\Product\Order\Payment\OrderPayment;
use App\Models\Ecommerce\Product\Order\Shipping\OrderShipping;
use App\Models\Ecommerce\Product\Order\Status\OrderStatus;
use Illuminate\Database\Seeder;
@@ -117,4 +116,4 @@ class OrderSeeder extends Seeder
default => 1,
};
}
}
}

View File

@@ -36,4 +36,4 @@ class ProductStocksSeeder extends Seeder
");
});
}
}
}

View File

@@ -363,6 +363,7 @@
"Seller": "Satyjy",
"View products": "Harytlary gör",
"Sections": "Bölümler",
"Section": "Bölüm",
"Product count": "Haryt sany",
"Count": "Sany",
"Shipping rates": "Eltip bermek nyrhnamasy",

View File

@@ -6,6 +6,7 @@ use App\Http\Controllers\Api\V1\Brand\BrandController;
use App\Http\Controllers\Api\V1\Carousel\CarouselController;
use App\Http\Controllers\Api\V1\CartController;
use App\Http\Controllers\Api\V1\Category\CategoryController;
use App\Http\Controllers\Api\V1\Category\SelectedCategoryController;
use App\Http\Controllers\Api\V1\Channel\ChannelController;
use App\Http\Controllers\Api\V1\Collection\CollectionController;
use App\Http\Controllers\Api\V1\ContactMessageController;
@@ -64,6 +65,10 @@ Route::get('categories', [CategoryController::class, 'index']);
Route::get('categories/{category}', [CategoryController::class, 'show'])->where(['category' => '[0-9]+']);
Route::get('categories/{category}/products', [CategoryController::class, 'products'])->where(['category' => '[0-9]+']);
// Selected Categories...
Route::get('selected-categories', [SelectedCategoryController::class, 'index']);
Route::get('selected-categories/{selectedCategory}', [SelectedCategoryController::class, 'show'])->where(['selectedCategory' => '[0-9]+']);
// Collections...
Route::get('collections', [CollectionController::class, 'index']);
Route::get('collections-paginated', [CollectionController::class, 'paginated']);
@@ -87,6 +92,7 @@ Route::middleware('auth:sanctum')
// Order settings...
Route::get('order-time', [OrderController::class, 'time']);
Route::get('order-payments', [OrderPaymentController::class, 'index']);
Route::get('order-deliveries', [OrderController::class, 'deliveries']);
// Provinces...
Route::get('provinces', [ProvinceController::class, 'index']);