File: /home/armgroup/libs/app/Http/Livewire/Admin/Product/Create.php
<?php
namespace App\Http\Livewire\Admin\Product;
use App\Models\Tag;
use App\Models\Brand;
use App\Models\Option;
use App\Models\Product;
use Livewire\Component;
use App\Models\Category;
use App\Models\Attribute;
use App\Models\Organization;
use App\Http\Livewire\General;
use App\Models\AttributeGroup;
use Illuminate\Support\Facades\DB;
use App\Http\Livewire\ConvertEmptyStringsToNull;
class Create extends Component
{
use ConvertEmptyStringsToNull, General;
public $name;
public $latin_name;
public $slug;
public $weight;
public $image;
public $short_description;
public $description;
public $code;
public $stock;
public $status = 1;
public $price;
public $category;
public $sort_order;
public $suggest = 0;
public $best_seller = 0;
public $country_code;
// public $slider_text;
// public $slider_video;
public $items = [];
public $attributes;
public $selectedAttributes = [];
public $faq = [];
public $sending_days;
public $brands;
public $brand_id;
public $items2 = [];
public $meta_title;
public $can_change_status;
public $tag_id = [];
public $tags;
public $categories;
public $category_id = [];
public $options = [];
public $allOptions;
public $selected_option_id = null;
public $productSelectedOptions = [];
public $countries;
public $organizations;
public $specials = [];
protected $listeners = ['imageChanged', 'multiImageChanged', 'videoChanged'];
public function updatedName($value)
{
$this->slug = slug($value);
}
public function addSpecial()
{
array_push($this->specials, [
'organization_id' => null,
// 'price' => null,
'special' => null,
'special_started_at' => null,
'special_ended_at' => null,
]);
$this->emit('addedSpecial', count($this->specials) - 1);
}
public function removeSpecial($index)
{
unset($this->specials[$index]);
}
public function multiImageChanged($index, $imagePath)
{
$this->items[$index]['path'] = ltrim(parse_url($imagePath, PHP_URL_PATH), '/');
}
public function addItem($type)
{
if ($type == 1) {
$this->items[] = [
'path' => null,
'sort_order' => null,
];
$this->emit('addedItem');
} elseif ($type == 2) {
$this->items2[] = [
'option_id' => $this->selected_option_id,
'value_id' => null,
'price' => null,
'stock' => 0,
'special' => null,
'special_started_at' => null,
'special_ended_at' => null,
'code' => null,
];
} else {
$this->faq[] = [
'question' => null,
'answer' => null,
];
}
}
public function removeItem($index, $type)
{
if ($type == 1) {
unset($this->items[$index]);
} elseif ($type == 2) {
unset($this->items2[$index]);
} else {
unset($this->faq[$index]);
}
}
public function mount($category)
{
$this->countries = config('countries');
$this->category = $category;
$this->tags = Tag::all();
$this->organizations = Organization::query()->get(['id', 'name']);
$this->categories = Category::query()->where('type', Product::class)->where('id', '<>', $category->id)->get(['id', 'name']);
$this->brands = Brand::query()->select('id', 'name')->get();
$attribute_ids = AttributeGroup::whereRelation('categories', 'id', $category->id)->orWhereDoesntHave('categories')->pluck('id')->toArray();
$this->attributes = Attribute::whereIn('group_id', $attribute_ids)->has('values')->with('values')->get();
$this->can_change_status = auth()->user()->can('change status');
$this->allOptions = Option::with('values:id,option_id,name')->get(['id', 'name']);
$this->addItem(2);
}
public function render()
{
return view('livewire.admin.product.create');
}
protected function rules()
{
$data = [
'name' => 'required|max:250',
'latin_name' => 'nullable|max:250',
'meta_title' => 'nullable|max:250',
'slug' => 'required|max:250|alpha_dash|unique:products',
'image' => 'required|max:250',
'short_description' => 'nullable|max:250',
'description' => 'nullable|max:65000',
'weight' => 'nullable|integer|min:0|max:999999999999999',
'sort_order' => 'nullable|integer|min:0|max:999999999',
'sending_days' => 'nullable|integer|min:0|max:30',
'status' => 'required|in:0,1',
'suggest' => 'required|in:0,1',
'best_seller' => 'required|in:0,1',
'country_code' => 'nullable|string',
// 'slider_text' => 'nullable|required_if:show_in_slider,1|max:500',
// 'slider_video' => 'nullable|required_if:show_in_slider,1|max:250',
'brand_id' => 'nullable|exists:brands,id',
'tag_id' => 'nullable|array',
'tag_id.*' => 'required|exists:tags,id',
'category_id' => 'nullable|array',
'category_id.*' => 'required|exists:categories,id',
'selectedAttributes.*' => 'nullable|exists:attribute_values,id',
'items.*.path' => 'required|max:250',
'items.*.sort_order' => 'nullable|integer|min:0|max:999999999',
'faq.*.question' => 'required|max:250',
'faq.*.answer' => 'required|max:250',
'items2.*.option_id' => 'nullable',
'items2.*.value_id' => 'nullable',
'items2.*.price' => 'nullable|integer|min:0|max:999999999999999',
'items2.*.stock' => 'required|integer|min:0|max:10000',
'items2.*.code' => 'nullable|max:50',
'code' => 'nullable|max:50',
'stock' => 'required|integer|min:0|max:10000',
'price' => 'nullable|integer|min:0|max:999999999999999',
'items2.*.special' => 'nullable|integer|min:0|max:999999999999998|lt:items2.*.price',
'items2.*.special_started_at' => 'nullable|date|required_with:items2.*.special',
'items2.*.special_ended_at' => 'nullable|date|after:items2.*.special_started_at|required_with:items2.*.special',
'specials.*.organization_id' => 'nullable|distinct|exists:organizations,id',
// 'specials.*.price' => 'required|integer|min:0|max:999999999999998',
'specials.*.special' => 'nullable|integer|min:0|max:999999999999998|lt:price',
'specials.*.special_started_at'=> 'nullable|date',
'specials.*.special_ended_at' => 'nullable|date|after:specials.*.special_started_at',
];
if ($this->selected_option_id) {
$data['items2.*.option_id'] = 'required|in:'.$this->selected_option_id;
$data['items2.*.value_id'] = 'required|exists:option_values,id|distinct';
}
return $data;
}
protected $validationAttributes = [
'items.*.path' => 'تصویر',
'items.*.sort_order' => 'ترتیب',
'image' => 'تصویر شاخص',
'selectedAttributes.*' => 'ویژگی',
'items2.*.option_id' => 'گزینه',
'items2.*.value_id' => 'مقدار',
'items2.*.price' => 'قیمت',
'items2.*.stock' => 'موجودی',
'items2.*.code' => 'کد',
// 'items2.*.special' => 'قیمت ویژه',
// 'items2.*.special_started_at' => 'تاریخ شروع',
// 'items2.*.special_ended_at' => 'تاریخ پایان',
'faq.*.question' => 'سوال',
'faq.*.answer' => 'جواب',
'specials.*.organization_id' => 'سازمان',
// 'specials.*.price' => 'قیمت',
'specials.*.special' => 'قیمت ویژه',
'specials.*.special_started_at'=> 'تاریخ شروع',
'specials.*.special_ended_at' => 'تاریخ پایان',
];
public function store()
{
$data = $this->validate();
$stock = 0;
foreach ($this->items2 as $value) {
$stock += $value['stock'];
}
$collectItems2 = collect($this->items2);
// $data['stock'] = $collectItems2->sum('stock');
// if (! $this->selected_option_id) {
// $data['code'] = $collectItems2->first()['code'];
// }
// $lowestPriceOption = $collectItems2->sortBy('price')
// ->sortBy(fn ($item) => $item['special'] ?: PHP_INT_MAX)
// ->first() ?:
// $collectItems2->sortBy('price')->sortBy(fn ($item) => $item['special'] ?: PHP_INT_MAX)->first();
// $data['price'] = $lowestPriceOption['price'];
// $data['special'] = $lowestPriceOption['special'] ?: null;
// $data['special_started_at'] = $lowestPriceOption['special'] ? $lowestPriceOption['special_started_at'] : null;
// $data['special_ended_at'] = $lowestPriceOption['special'] ? $lowestPriceOption['special_ended_at'] : null;
$data['user_id'] = auth()->id();
if (! $this->can_change_status) {
$data['status'] = 0;
}
$data['faq'] = count($this->faq) ? $this->faq : null;
DB::transaction(function () use ($data, $stock) {
$product = Product::create($data);
if(count($this->items2)) {
$data['stock'] = $stock;
}
if($this->specials) {
foreach($this->specials as $i => $s) {
$this->specials[$i]['product_id'] = $product->id;
}
DB::table('organization_product')->insert($this->specials);
}
$categories = [
$this->category->id => ['is_main' => true],
];
foreach ($this->category_id as $category) {
$categories[$category] = ['is_main' => false];
}
$product->categories()->attach($categories);
if (count($this->tags)) {
$product->tags()->attach($this->tag_id);
}
if (count($this->items)) {
$product->images()->createMany($this->items);
}
if ($this->selected_option_id) {
foreach ($this->items2 as $key => $item) {
$this->items2[$key]['product_id'] = $product->id;
}
DB::table('option_product')->insert($this->items2);
}
$selectedAttributes = array_filter($this->selectedAttributes, static function ($var) {
return $var !== null;
});
if (count($selectedAttributes)) {
$attributes_data = [];
foreach ($selectedAttributes as $attribute => $value) {
$attributes_data[] = [
'product_id' => $product->id,
'attribute_id' => $attribute,
'value_id' => $value,
];
}
DB::table('attribute_product')->insert($attributes_data);
}
saveActivity("محصول {$this->name} ایجاد شد.", $product);
});
$this->doneMessage("{$this->name} با موفقیت ایجاد شد");
return redirect()->route('admin.products.index');
}
public function imageChanged($imagePath)
{
$this->image = ltrim(parse_url($imagePath, PHP_URL_PATH), '/');
}
public function videoChanged($videoPath)
{
// $this->resetValidation('slider_video');
// $this->slider_video = null;
// $extension = pathinfo($videoPath, PATHINFO_EXTENSION);
// if (strtolower($extension) != 'mp4') {
// $this->addError('slider_video', 'فرمت باید mp4 باشد.');
// return;
// }
// $this->slider_video = ltrim(parse_url($videoPath, PHP_URL_PATH), '/');
}
public function setProductOptions()
{
$this->productSelectedOptions = array_filter($this->productSelectedOptions);
if (count($this->productSelectedOptions) > 1) {
$this->ajaxDoneMessage('حداکثر یک گزینه میتوانید انتخاب کنید.', 'warning');
return;
}
$option_ids = array_keys($this->productSelectedOptions);
$value_ids = array_merge(...$this->productSelectedOptions);
$this->options = Option::query()
->whereIn('id', $option_ids)
->with(['values' => function ($query) use ($value_ids) {
return $query->whereIn('id', $value_ids)->select('id', 'option_id', 'name');
}])
->get(['id', 'name']);
$this->items2 = [];
$this->selected_option_id = null;
$count = count($this->options);
if ($count == 0) {
$this->items2[] = [
'option_id' => null,
'value_id' => null,
'price' => null,
'code' => null,
'stock' => 0,
// 'special' => null,
// 'special_started_at' => null,
// 'special_ended_at' => null,
];
} elseif ($count == 1) {
foreach ($this->options[0]->values as $value) {
$this->selected_option_id = $value->option_id;
$this->items2[] = [
'option_id' => $value->option_id,
'value_id' => $value->id,
'price' => null,
'code' => null,
'stock' => 0,
// 'special' => null,
// 'special_started_at' => null,
// 'special_ended_at' => null,
];
}
}
}
}