/home/brandsfa/annurbd.com/app/Services/ProductService.php
<?php
namespace App\Services;
use App\Enums\UserRole;
use App\Enums\ViewPaths\Admin\Product;
use App\Models\Color;
use App\Traits\FileManagerTrait;
use Illuminate\Support\Str;
use Rap2hpoutre\FastExcel\FastExcel;
class ProductService
{
use FileManagerTrait;
public function __construct(private readonly Color $color)
{
}
public function getProcessedImages(object $request): array
{
$colorImageSerial = [];
$imageNames = [];
if ($request->has('colors_active') && $request->has('colors') && count($request['colors']) > 0) {
foreach ($request['colors'] as $color) {
$color_ = Str::replace('#', '', $color);
$img = 'color_image_' . $color_;
if ($request->file($img)) {
$image = $this->upload(dir: 'product/', format: 'webp', image: $request->file($img));
$colorImageSerial[] = [
'color' => $color_,
'image_name' => $image,
];
$imageNames[] = $image;
}
}
}
if ($request->file('images')) {
foreach ($request->file('images') as $image) {
$images = $this->upload(dir: 'product/', format: 'webp', image: $image);
$imageNames[] = $images;
if($request->has('colors_active') && $request->has('colors') && count($request['colors']) > 0){
$colorImageSerial[] = [
'color' => null,
'image_name' => $images,
];
}
}
}
return [
'image_names' => $imageNames ?? [],
'colored_image_names' => $colorImageSerial ?? []
];
}
public function getProcessedUpdateImages(object $request, object $product): array
{
$productImages = json_decode($product->images);
$colorImageArray = [];
if ($request->has('colors_active') && $request->has('colors') && count($request->colors) > 0) {
$dbColorImage = $product->color_image ? json_decode($product->color_image, true) : [];
if (!$dbColorImage) {
foreach ($productImages as $image) {
$dbColorImage[] = [
'color' => null,
'image_name' => $image,
];
}
}
$dbColorImageFinal = [];
if ($dbColorImage) {
foreach ($dbColorImage as $colorImage) {
if ($colorImage['color']) {
$dbColorImageFinal[] = $colorImage['color'];
}
}
}
$inputColors = [];
foreach ($request->colors as $color) {
$inputColors[] = str_replace('#', '', $color);
}
$colorImageArray = $dbColorImage;
foreach ($inputColors as $color) {
if (!in_array($color, $dbColorImageFinal)) {
$image = 'color_image_' . $color;
if ($request->file($image)) {
$imageName = $this->upload(dir: 'product/', format: 'webp', image: $request->file($image));
$productImages[] = $imageName;
$colorImages = [
'color' => $color,
'image_name' => $imageName,
];
$colorImageArray[] = $colorImages;
}
}
}
}
if ($request->file('images')) {
foreach ($request->file('images') as $image) {
$imageName = $this->upload(dir: 'product/', format: 'webp', image: $image);
$productImages[] = $imageName;
if ($request->has('colors_active') && $request->has('colors') && count($request->colors) > 0) {
$colorImageArray[] = [
'color' => null,
'image_name' => $imageName,
];
}
}
}
return [
'image_names' => $productImages ?? [],
'colored_image_names' => $colorImageArray ?? []
];
}
public function getCategoriesArray(object $request): array
{
$category = [];
if ($request['category_id'] != null) {
$category[] = [
'id' => $request['category_id'],
'position' => 1,
];
}
if ($request['sub_category_id'] != null) {
$category[] = [
'id' => $request['sub_category_id'],
'position' => 2,
];
}
if ($request['sub_sub_category_id'] != null) {
$category[] = [
'id' => $request['sub_sub_category_id'],
'position' => 3,
];
}
return $category;
}
public function getColorsObject(object $request): bool|string
{
if ($request->has('colors_active') && $request->has('colors') && count($request['colors']) > 0) {
$colors = $request['product_type'] == 'physical' ? json_encode($request['colors']) : json_encode([]);
} else {
$colors = json_encode([]);
}
return $colors;
}
public function getSlug(object $request): string
{
return Str::slug($request['name'][array_search('en', $request['lang'])], '-') . '-' . Str::random(6);
}
public function getChoiceOptions(object $request): array
{
$choice_options = [];
if ($request->has('choice')) {
foreach ($request->choice_no as $key => $no) {
$str = 'choice_options_' . $no;
$item['name'] = 'choice_' . $no;
$item['title'] = $request->choice[$key];
$item['options'] = explode(',', implode('|', $request[$str]));
$choice_options[] = $item;
}
}
return $choice_options;
}
public function getOptions(object $request): array
{
$options = [];
if ($request->has('colors_active') && $request->has('colors') && count($request->colors) > 0) {
$options[] = $request->colors;
}
if ($request->has('choice_no')) {
foreach ($request->choice_no as $no) {
$name = 'choice_options_' . $no;
$my_str = implode('|', $request[$name]);
$options[] = explode(',', $my_str);
}
}
return $options;
}
public function getCombinations(array $arrays): array
{
$result = [[]];
foreach ($arrays as $property => $property_values) {
$tmp = [];
foreach ($result as $result_item) {
foreach ($property_values as $property_value) {
$tmp[] = array_merge($result_item, [$property => $property_value]);
}
}
$result = $tmp;
}
return $result;
}
public function getSkuCombinationView(object $request): string
{
$colorsActive = ($request->has('colors_active') && $request->has('colors') && count($request['colors']) > 0) ? 1 : 0;
$unitPrice = $request['unit_price'];
$productName = $request['name'][array_search('en', $request['lang'])];
$options = $this->getOptions(request: $request);
$combinations = $this->getCombinations(arrays: $options);
return view(Product::SKU_COMBINATION[VIEW], compact('combinations', 'unitPrice', 'colorsActive', 'productName'))->render();
}
public function getVariations(object $request, array $combinations): array
{
$variations = [];
if (count($combinations[0]) > 0) {
foreach ($combinations as $combination) {
$str = '';
foreach ($combination as $k => $item) {
if ($k > 0) {
$str .= '-' . str_replace(' ', '', $item);
} else {
if ($request->has('colors_active') && $request->has('colors') && count($request['colors']) > 0) {
$color_name = $this->color->where('code', $item)->first()->name;
$str .= $color_name;
} else {
$str .= str_replace(' ', '', $item);
}
}
}
$item = [];
$item['type'] = $str;
$item['price'] = currencyConverter(abs($request['price_' . str_replace('.', '_', $str)]));
$item['sku'] = $request['sku_' . str_replace('.', '_', $str)];
$item['qty'] = abs($request['qty_' . str_replace('.', '_', $str)]);
$variations[] = $item;
}
}
return $variations;
}
public function getTotalQuantity(array $variations): int
{
$sum = 0;
foreach ($variations as $item) {
if (isset($item['qty'])) {
$sum += $item['qty'];
}
}
return $sum;
}
public function getCategoryDropdown(object $request, object $categories): string
{
$dropdown = '<option value="' . 0 . '" disabled selected>---'.translate("Select").'---</option>';
foreach ($categories as $row) {
if ($row->id == $request['sub_category']) {
$dropdown .= '<option value="' . $row->id . '" selected >' . $row->defaultName . '</option>';
} else {
$dropdown .= '<option value="' . $row->id . '">' . $row->defaultName . '</option>';
}
}
return $dropdown;
}
public function deleteImages(object $product): bool
{
foreach (json_decode($product['images']) as $image) {
$this->delete(filePath: '/product/' . $image);
}
$this->delete(filePath: '/product/thumbnail/' . $product['thumbnail']);
return true;
}
public function deleteImage(object $request, object $product): array
{
$colors = json_decode($product['colors']);
$color_image = json_decode($product['color_image']);
$images = [];
$color_images = [];
if($colors && $color_image){
foreach($color_image as $img){
if($img->color != $request['color'] && $img->image_name != $request['name']){
$color_images[] = [
'color' =>$img->color!=null ? $img->color:null,
'image_name' =>$img->image_name,
];
}
}
}
foreach (json_decode($product['images']) as $image) {
if ($image != $request['name']) {
$images[] = $image;
}
}
return [
'images' => $images,
'color_images' => $color_images
];
}
public function getAddProductData(object $request, string $addedBy): array
{
$processedImages = $this->getProcessedImages(request: $request); //once the images are processed do not call this function again just use the variable
$combinations = $this->getCombinations($this->getOptions(request: $request));
$variations = $this->getVariations(request: $request, combinations: $combinations);
$stockCount = count($combinations[0]) > 0 ? $this->getTotalQuantity(variations: $variations) : (integer)$request['current_stock'];
$digitalFile = '';
if ($request['product_type'] == 'digital' && $request['digital_product_type'] == 'ready_product') {
$digitalFile = $this->fileUpload(dir: 'product/digital-product/', format: $request['digital_file_ready']->getClientOriginalExtension(), file: $request['digital_file_ready']);
}
return [
'added_by' => $addedBy,
'user_id' => $addedBy == 'admin' ? auth('admin')->id() : auth('seller')->id(),
'name' => $request['name'][array_search('en', $request['lang'])],
'code' => $request['code'],
'slug' => $this->getSlug($request),
'category_ids' => json_encode($this->getCategoriesArray(request: $request)),
'category_id' => $request['category_id'],
'sub_category_id' => $request['sub_category_id'],
'sub_sub_category_id' => $request['sub_sub_category_id'],
'brand_id' => $request['brand_id'],
'unit' => $request['product_type'] == 'physical' ? $request['unit'] : null,
'digital_product_type' => $request['product_type'] == 'digital' ? $request['digital_product_type'] : null,
'product_type' => $request['product_type'],
'details' => $request['description'][array_search('en', $request['lang'])],
'colors' => $this->getColorsObject(request: $request),
'choice_options' => $request['product_type'] == 'physical' ? json_encode($this->getChoiceOptions(request: $request)) : json_encode([]),
'variation' => $request['product_type'] == 'physical' ? json_encode($variations) : json_encode([]),
'unit_price' => currencyConverter(amount: $request['unit_price']),
'purchase_price' => 0,
'tax' => $request['tax_type'] == 'flat' ? currencyConverter(amount: $request['tax']) : $request['tax'],
'tax_type' => $request['tax_type'],
'tax_model' => $request['tax_model'],
'discount' => $request['discount_type'] == 'flat' ? currencyConverter(amount: $request['discount']) : $request['discount'],
'discount_type' => $request['discount_type'],
'attributes' => $request['product_type'] == 'physical' ? json_encode($request['choice_attributes']) : json_encode([]),
'current_stock' => $request['product_type'] == 'physical' ? abs($stockCount) : 0,
'minimum_order_qty' => $request['minimum_order_qty'],
'video_provider' => 'youtube',
'video_url' => $request['video_url'],
'status' => $addedBy == 'admin' ? 1 : 0,
'request_status' => $addedBy == 'admin' ? 1 : (getWebConfig(name: 'new_product_approval') == 1 ? 0 : 1),
'shipping_cost' => $request['product_type'] == 'physical' ? currencyConverter(amount: $request['shipping_cost']) : 0,
'free_shipping' => ($request['product_type'] == 'physical') ? ($request['free_shipping'] == 'on' ? 1 : 0) : 0, //to be changed in form free_shipping
'multiply_qty' => ($request['product_type'] == 'physical') ? ($request['multiply_qty'] == 'on' ? 1 : 0) : 0, //to be changed in form multiply_qty
'color_image' => json_encode($processedImages['colored_image_names']),
'images' => json_encode($processedImages['image_names']),
'thumbnail' => $this->upload(dir: 'product/thumbnail/', format: 'png', image: $request['image']),
'digital_file_ready' => $digitalFile,
'meta_title' => $request['meta_title'],
'meta_description' => $request['meta_description'],
'meta_image' => $this->upload(dir: 'product/meta/', format: 'png', image: $request['meta_image']),
];
}
public function getUpdateProductData(object $request, object $product, string $updateBy): array
{
$processedImages = $this->getProcessedUpdateImages(request: $request, product: $product);
$combinations = $this->getCombinations($this->getOptions(request: $request));
$variations = $this->getVariations(request: $request, combinations: $combinations);
$stockCount = count($combinations[0]) > 0 ? $this->getTotalQuantity(variations: $variations) : (integer)$request['current_stock'];
$digitalFile = null;
if ($request['product_type'] == 'digital') {
if ($request['digital_product_type'] == 'ready_product' && $request->hasFile('digital_file_ready')) {
$digitalFile = $this->update(dir: 'product/digital-product/', oldImage: $product['digital_file_ready'], format: $request['digital_file_ready']->getClientOriginalExtension(), image: $request['digital_file_ready'], fileType: 'file');
} elseif (($request['digital_product_type'] == 'ready_after_sell') && $product['digital_file_ready']) {
$this->delete(filePath: 'product/digital-product/' . $product['digital_file_ready']);
}
} elseif ($request['product_type'] == 'physical' && $product['digital_file_ready']) {
$this->delete(filePath: 'product/digital-product/' . $product['digital_file_ready']);
}
$dataArray = [
'name' => $request['name'][array_search('en', $request['lang'])],
'code' => $request['code'],
'product_type' => $request['product_type'],
'category_ids' => json_encode($this->getCategoriesArray(request: $request)),
'category_id' => $request['category_id'],
'sub_category_id' => $request['sub_category_id'],
'sub_sub_category_id' => $request['sub_sub_category_id'],
'brand_id' => $request['brand_id'],
'unit' => $request['product_type'] == 'physical' ? $request['unit'] : null,
'digital_product_type' => $request['product_type'] == 'digital' ? $request['digital_product_type'] : null,
'details' => $request['description'][array_search('en', $request['lang'])],
'colors' => $this->getColorsObject(request: $request),
'choice_options' => $request['product_type'] == 'physical' ? json_encode($this->getChoiceOptions(request: $request)) : json_encode([]),
'variation' => $request['product_type'] == 'physical' ? json_encode($variations) : json_encode([]),
'unit_price' => currencyConverter(amount: $request['unit_price']),
'purchase_price' => 0,
'tax' => $request['tax_type'] == 'flat' ? currencyConverter(amount: $request['tax']) : $request['tax'],
'tax_type' => $request['tax_type'],
'tax_model' => $request['tax_model'],
'discount' => $request['discount_type'] == 'flat' ? currencyConverter(amount: $request['discount']) : $request['discount'],
'discount_type' => $request['discount_type'],
'attributes' => $request['product_type'] == 'physical' ? json_encode($request['choice_attributes']) : json_encode([]),
'current_stock' => $request['product_type'] == 'physical' ? abs($stockCount) : 0,
'minimum_order_qty' => $request['minimum_order_qty'],
'video_provider' => 'youtube',
'video_url' => $request['video_url'],
'shipping_cost' => $request['product_type'] == 'physical' ? (getWebConfig(name: 'product_wise_shipping_cost_approval')==1 && $product->shipping_cost != currencyConverter($request->shipping_cost) ? $product->shipping_cost : currencyConverter(amount: $request['shipping_cost'])) : 0,
'free_shipping' => ($request['product_type'] == 'physical') ? ($request['free_shipping'] == 'on' ? 1 : 0) : 0, //to be changed in form free_shipping
'multiply_qty' => ($request['product_type'] == 'physical') ? ($request['multiply_qty'] == 'on' ? 1 : 0) : 0,
'color_image' => json_encode($processedImages['colored_image_names']),
'images' => json_encode($processedImages['image_names']),
'digital_file_ready' => $digitalFile,
'meta_title' => $request['meta_title'],
'meta_description' => $request['meta_description'],
'meta_image' => $request->file('meta_image') ? $this->update(dir: 'product/meta/', oldImage: $product['meta_image'], format: 'png', image: $request['meta_image']) : $product['meta_image'],
];
if ($request->file('image')) {
$dataArray += [
'thumbnail' => $this->update(dir: 'product/thumbnail/', oldImage: $product['thumbnail'], format: 'webp', image: $request['image'], fileType: 'image')
];
}
if($updateBy=='seller' && getWebConfig(name: 'product_wise_shipping_cost_approval')==1 && $product->shipping_cost != currencyConverter($request->shipping_cost))
{
$dataArray += [
'temp_shipping_cost' => currencyConverter($request->shipping_cost),
'is_shipping_cost_updated' => 0
];
}
if($updateBy=='seller' && $product->request_status == 2){
$dataArray += [
'request_status' => 0
];
}
if($updateBy=='admin' && $product->added_by == 'seller' && $product->request_status == 2){
$dataArray += [
'request_status' => 1
];
}
return $dataArray;
}
public function getImportBulkProductData(object $request, string $addedBy): array
{
try {
$collections = (new FastExcel)->import($request->file('products_file'));
} catch (\Exception $exception) {
return [
'status' => false,
'message' => translate('you_have_uploaded_a_wrong_format_file') . ',' . translate('please_upload_the_right_file'),
'products' => []
];
}
$columnKey = [
'name',
'category_id',
'sub_category_id',
'sub_sub_category_id',
'brand_id', 'unit',
'minimum_order_qty',
'refundable',
'youtube_video_url',
'unit_price',
// 'purchase_price',
'tax',
'discount',
'discount_type',
'current_stock',
'details',
'thumbnail'
];
$skip = ['youtube_video_url', 'details', 'thumbnail'];
if (count($collections) <= 0) {
return [
'status' => false,
'message' => translate('you_need_to_upload_with_proper_data'),
'products' => []
];
}
$products = [];
foreach ($collections as $collection) {
foreach ($collection as $key => $value) {
if ($key != "" && !in_array($key, $columnKey)) {
return [
'status' => false,
'message' => translate('Please_upload_the_correct_format_file'),
'products' => []
];
}
if ($key != "" && $value === "" && !in_array($key, $skip)) {
return [
'status' => false,
'message' => translate('Please fill ' . $key . ' fields'),
'products' => []
];
}
}
$thumbnail = explode('/', $collection['thumbnail']);
$products[] = [
'name' => $collection['name'],
'slug' => Str::slug($collection['name'], '-') . '-' . Str::random(6),
'category_ids' => json_encode([['id' => (string)$collection['category_id'], 'position' => 1], ['id' => (string)$collection['sub_category_id'], 'position' => 2], ['id' => (string)$collection['sub_sub_category_id'], 'position' => 3]]),
'category_id' => $collection['category_id'],
'sub_category_id' => $collection['sub_category_id'],
'sub_sub_category_id' => $collection['sub_sub_category_id'],
'brand_id' => $collection['brand_id'],
'unit' => $collection['unit'],
'minimum_order_qty' => $collection['minimum_order_qty'],
'refundable' => $collection['refundable'],
'unit_price' => $collection['unit_price'],
'purchase_price' => 0,
'tax' => $collection['tax'],
'discount' => $collection['discount'],
'discount_type' => $collection['discount_type'],
'shipping_cost' => 0,
'current_stock' => $collection['current_stock'],
'details' => $collection['details'],
'video_provider' => 'youtube',
'video_url' => $collection['youtube_video_url'],
'images' => json_encode(['def.png']),
'thumbnail' => $thumbnail[1] ?? $thumbnail[0],
'status' => 0,
'request_status' => 1,
'colors' => json_encode([]),
'attributes' => json_encode([]),
'choice_options' => json_encode([]),
'variation' => json_encode([]),
'featured_status' => 0,
'added_by' => $addedBy,
'user_id' => $addedBy == 'admin' ? auth('admin')->id() : auth('seller')->id(),
'created_at' => now(),
];
}
return [
'status' => true,
'message' => count($products) . ' - ' . translate('products_imported_successfully'),
'products' => $products
];
}
}