2021-12-22 15:53:36 +00:00
< ? php
namespace Sarga\API\Repositories ;
use Illuminate\Container\Container as App ;
use Illuminate\Support\Arr ;
2022-01-12 07:35:04 +00:00
use Illuminate\Support\Facades\DB ;
2021-12-22 15:53:36 +00:00
use Illuminate\Support\Facades\Event ;
2022-01-12 07:35:04 +00:00
use Illuminate\Support\Facades\Log ;
2021-12-22 15:53:36 +00:00
use Webkul\Attribute\Repositories\AttributeGroupRepository ;
use Webkul\Attribute\Repositories\AttributeOptionRepository ;
use Webkul\Attribute\Repositories\AttributeRepository ;
2022-01-19 14:04:47 +00:00
use Webkul\Product\Models\ProductAttributeValueProxy ;
2022-01-12 07:35:04 +00:00
use Webkul\Product\Repositories\ProductAttributeValueRepository ;
use Webkul\Product\Repositories\ProductFlatRepository ;
use Webkul\Product\Repositories\ProductImageRepository ;
2021-12-22 15:53:36 +00:00
use Webkul\Product\Repositories\ProductRepository as WProductRepository ;
class ProductRepository extends WProductRepository
{
protected $attributeGroupRepo ;
protected $optionRepository ;
2022-01-12 07:35:04 +00:00
protected $productFlatRepository ;
protected $attributeValueRepository ;
protected $imageRepository ;
protected $fillableTypes = [ 'sku' , 'name' , 'url_key' , 'short_description' , 'description' , 'price' , 'weight' , 'status' ];
2021-12-22 15:53:36 +00:00
public function __construct ( AttributeRepository $attributeRepository ,
App $app ,
AttributeGroupRepository $attributeGroupRepo ,
2022-01-12 07:35:04 +00:00
ProductFlatRepository $productFlatRepository ,
ProductAttributeValueRepository $productAttributeValueRepository ,
ProductImageRepository $productImageRepository ,
2021-12-22 15:53:36 +00:00
AttributeOptionRepository $optionRepository )
{
$this -> attributeGroupRepo = $attributeGroupRepo ;
$this -> optionRepository = $optionRepository ;
2022-01-12 07:35:04 +00:00
$this -> attributeValueRepository = $productAttributeValueRepository ;
$this -> productFlatRepository = $productFlatRepository ;
$this -> imageRepository = $productImageRepository ;
2021-12-22 15:53:36 +00:00
parent :: __construct ( $attributeRepository , $app );
}
public function create ( $data ){
$product [ 'sku' ] = $data [ 'sku' ];
2022-01-12 07:35:04 +00:00
// return array_map(fn($value): int => $value * 2, range(1, 5));
2021-12-22 15:53:36 +00:00
$product [ 'type' ] = ( ! empty ( $data [ 'color_variants' ]) || ! empty ( $data [ 'size_variants' ])) ? 'configurable' : 'simple' ;
2022-01-12 07:35:04 +00:00
$attributes = Arr :: only ( $data ,[ 'brand' , 'cinsiyet' ]);
try {
DB :: beginTransaction ();
if ( array_key_exists ( 'attributes' , $data )) {
$attributes [] = Arr :: collapse ( $data [ 'attributes' ]);
$grp = $this -> getAttributeFamily ( array_keys ( $attributes ));
2021-12-22 15:53:36 +00:00
2022-01-12 07:35:04 +00:00
$product [ 'attribute_family_id' ] = $grp ? $grp -> attribute_family_id :
(( $product [ 'type' ] == 'configurable' ) ? 2 : 1 ); //default_configurable_product: default_simple_prodcut
} else
$product [ 'attribute_family_id' ] = $product [ 'type' ] == 'configurable' ? 2 : 1 ;
2021-12-22 15:53:36 +00:00
2022-01-12 07:35:04 +00:00
//create product
$parentProduct = $this -> getModel () -> create ( $product );
$this -> assignAttributes ( $parentProduct , [
'sku' => $parentProduct -> sku ,
'name' => $data [ 'name' ],
'weight' => 0 ,
'status' => 1 ,
2022-01-12 08:04:46 +00:00
'visible_individually' => 1 ,
2022-01-12 07:35:04 +00:00
'url_key' => $parentProduct -> sku ,
'short_description' => $data [ 'url_key' ],
'description' => implode ( array_map ( fn ( $value ) : string => '<p>' . $value [ 'description' ] . '</p>' , $data [ 'descriptions' ]))
]);
2021-12-22 15:53:36 +00:00
2022-01-12 07:35:04 +00:00
if ( ! empty ( $data [ 'images' ])) {
$this -> assignImages ( $parentProduct , $data [ 'images' ]);
2021-12-22 15:53:36 +00:00
}
2022-01-12 07:35:04 +00:00
if ( ! empty ( $data [ 'categories' ])){
$parentProduct -> categories () -> attach ( $data [ 'categories' ]);
2021-12-22 15:53:36 +00:00
}
2022-01-12 07:35:04 +00:00
if ( $product [ 'type' ] == 'configurable' ) {
//create variants color
if ( ! empty ( $data [ 'color_variants' ])) {
$attribute = $this -> attributeRepository -> findOneByField ( 'code' , 'color' );
$parentProduct -> super_attributes () -> attach ( $attribute -> id );
foreach ( $data [ 'color_variants' ] as $colorVariant ) {
$description = implode ( array_map ( fn ( $value ) : string => '<p>' . $value [ 'description' ] . '</p>' , $colorVariant [ 'descriptions' ]));
if ( ! empty ( $colorVariant [ 'size_variants' ])) {
foreach ( $colorVariant [ 'size_variants' ] as $sizeVariant ) {
$variant = $this -> createVariant ( $parentProduct , $colorVariant [ 'product_number' ] . $sizeVariant [ 'size' ]);
2021-12-22 15:53:36 +00:00
2022-01-12 07:35:04 +00:00
$this -> assignImages ( $variant , $colorVariant [ 'images' ]);
$this -> assignAttributes ( $variant , [
'sku' => $variant -> sku ,
'color' => $this -> getAttributeOptionId ( 'color' , $colorVariant [ 'color' ]),
'name' => $colorVariant [ 'name' ],
'size' => $this -> getAttributeOptionId ( 'size' , $sizeVariant [ 'size' ]),
'price' => $sizeVariant [ 'price' ],
'weight' => 0 ,
'status' => 1 ,
2022-01-12 08:04:46 +00:00
'visible_individually' => 1 ,
2022-01-12 07:35:04 +00:00
'url_key' => $variant -> sku ,
'short_description' => $colorVariant [ 'url_key' ],
'description' => $description
]);
}
} else {
$variant = $this -> createVariant ( $parentProduct , $colorVariant [ 'product_number' ]);
$this -> assignImages ( $variant , $colorVariant [ 'images' ]);
$this -> assignAttributes ( $variant , [
'sku' => $variant -> sku ,
'color' => $this -> getAttributeOptionId ( 'color' , $colorVariant [ 'color' ]),
'name' => $colorVariant [ 'name' ],
'price' => Arr :: get ( $colorVariant , 'price.discountedPrice.value' ),
'weight' => 0 ,
'status' => 1 ,
2022-01-12 08:04:46 +00:00
'visible_individually' => 1 ,
2022-01-12 07:35:04 +00:00
'url_key' => $variant -> sku ,
'short_description' => $colorVariant [ 'url_key' ],
'description' => $description
]);
}
}
}
if ( ! empty ( $data [ 'size_variants' ])) {
$attribute = $this -> attributeRepository -> findOneByField ( 'code' , 'size' );
$parentProduct -> super_attributes () -> attach ( $attribute -> id );
foreach ( $data [ 'size_variants' ] as $sizeVariant ) {
$variant = $this -> createVariant ( $parentProduct , $data [ 'product_number' ] . $sizeVariant [ 'size' ]);
$this -> assignImages ( $variant , $data [ 'images' ]);
$attributes = [
'sku' => $variant -> sku ,
'size' => $this -> getAttributeOptionId ( 'size' , $sizeVariant [ 'size' ]),
'name' => $data [ 'name' ],
'price' => $sizeVariant [ 'price' ],
'weight' => 0 ,
'status' => 1 ,
2022-01-12 08:04:46 +00:00
'visible_individually' => 1 ,
2022-01-12 07:35:04 +00:00
'url_key' => $variant -> sku ,
'short_description' => $data [ 'url_key' ],
'description' => implode ( array_map ( fn ( $value ) : string => '<p>' . $value [ 'description' ] . '</p>' , $data [ 'descriptions' ]))
];
if ( ! empty ( $data [ 'color' ])) {
$attributes [ 'color' ] = $this -> getAttributeOptionId ( 'color' , $data [ 'color' ]);
}
$this -> assignAttributes ( $variant , $attributes );
}
}
//todo default_variant_id
}
// assign attributes
// $this->assignCustomAttributes($parentProduct,$attributes);
Event :: dispatch ( 'catalog.product.create.after' , $parentProduct );
DB :: commit ();
2022-01-19 08:32:04 +00:00
return $parentProduct ;
2022-01-12 07:35:04 +00:00
}
catch ( \Exception $ex ){
DB :: rollBack ();
Log :: error ( $ex );
return false ;
2021-12-22 15:53:36 +00:00
}
2022-01-12 07:35:04 +00:00
}
2021-12-22 15:53:36 +00:00
2022-01-19 14:04:47 +00:00
/**
* Returns the all products of the seller
*
* @ param integer $seller
* @ return Collection
*/
public function findAllBySeller ( $seller_id , $category_id = null )
{
$params = request () -> input ();
$results = app ( 'Webkul\Product\Repositories\ProductFlatRepository' ) -> scopeQuery ( function ( $query ) use ( $seller_id , $params , $category_id ) {
$channel = request () -> get ( 'channel' ) ? : ( core () -> getCurrentChannelCode () ? : core () -> getDefaultChannelCode ());
$locale = request () -> get ( 'locale' ) ? : app () -> getLocale ();
$qb = $query -> distinct ()
-> addSelect ( 'product_flat.*' )
-> join ( 'product_flat as variants' , 'product_flat.id' , '=' , DB :: raw ( 'COALESCE(' . DB :: getTablePrefix () . 'variants.parent_id, ' . DB :: getTablePrefix () . 'variants.id)' ))
-> leftJoin ( 'product_categories' , 'product_categories.product_id' , '=' , 'product_flat.product_id' )
-> leftJoin ( 'product_attribute_values' , 'product_attribute_values.product_id' , '=' , 'variants.product_id' )
-> addSelect ( DB :: raw ( ' IF ( product_flat . special_price_from IS NOT NULL
AND product_flat . special_price_to IS NOT NULL , IF ( NOW ( ) >= product_flat . special_price_from
AND NOW ( ) <= product_flat . special_price_to , IF ( product_flat . special_price IS NULL OR product_flat . special_price = 0 , product_flat . price , LEAST ( product_flat . special_price , product_flat . price ) ) , product_flat . price ) , IF ( product_flat . special_price_from IS NULL , IF ( product_flat . special_price_to IS NULL , IF ( product_flat . special_price IS NULL OR product_flat . special_price = 0 , product_flat . price , LEAST ( product_flat . special_price , product_flat . price ) ) , IF ( NOW ( ) <= product_flat . special_price_to , IF ( product_flat . special_price IS NULL OR product_flat . special_price = 0 , product_flat . price , LEAST ( product_flat . special_price , product_flat . price ) ) , product_flat . price ) ) , IF ( product_flat . special_price_to IS NULL , IF ( NOW ( ) >= product_flat . special_price_from , IF ( product_flat . special_price IS NULL OR product_flat . special_price = 0 , product_flat . price , LEAST ( product_flat . special_price , product_flat . price ) ) , product_flat . price ) , product_flat . price ) ) ) AS price1 ' ))
-> leftJoin ( 'products' , 'product_flat.product_id' , '=' , 'products.id' )
-> leftJoin ( 'marketplace_products' , 'product_flat.product_id' , '=' , 'marketplace_products.product_id' )
-> where ( 'product_flat.visible_individually' , 1 )
-> where ( 'product_flat.status' , 1 )
-> where ( 'product_flat.channel' , $channel )
-> where ( 'product_flat.locale' , $locale )
-> whereNotNull ( 'product_flat.url_key' )
-> where ( 'marketplace_products.marketplace_seller_id' , $seller_id )
-> where ( 'marketplace_products.is_approved' , 1 );
$qb -> addSelect ( DB :: raw ( '(CASE WHEN marketplace_products.is_owner = 0 THEN marketplace_products.price ELSE product_flat.price END) AS price2' ));
if ( $category_id ) {
$qb -> whereIn ( 'product_categories.category_id' , explode ( ',' , $category_id ));
}
$queryBuilder = $qb -> leftJoin ( 'product_flat as flat_variants' , function ( $qb ) use ( $channel , $locale ) {
$qb -> on ( 'product_flat.id' , '=' , 'flat_variants.parent_id' )
-> where ( 'flat_variants.channel' , $channel )
-> where ( 'flat_variants.locale' , $locale );
});
if ( isset ( $params [ 'sort' ])) {
$attribute = $this -> attributeRepository -> findOneByField ( 'code' , $params [ 'sort' ]);
if ( $params [ 'sort' ] == 'price' ) {
$qb -> orderBy ( $attribute -> code , $params [ 'order' ]);
} else {
$qb -> orderBy ( $params [ 'sort' ] == 'created_at' ? 'product_flat.created_at' : $attribute -> code , $params [ 'order' ]);
}
}
//brand attribute added code
$attributeFilters = $this -> attributeRepository
-> getProductDefaultAttributes ( array_keys (
request () -> input ()
));
if ( count ( $attributeFilters ) > 0 ) {
$qb = $qb -> where ( function ( $filterQuery ) use ( $attributeFilters ) {
foreach ( $attributeFilters as $attribute ) {
$filterQuery -> orWhere ( function ( $attributeQuery ) use ( $attribute ) {
$column = DB :: getTablePrefix () . 'product_attribute_values.' . ProductAttributeValueProxy :: modelClass () :: $attributeTypeFields [ $attribute -> type ];
$filterInputValues = explode ( ',' , request () -> get ( $attribute -> code ));
# define the attribute we are filtering
$attributeQuery = $attributeQuery -> where ( 'product_attribute_values.attribute_id' , $attribute -> id );
# apply the filter values to the correct column for this type of attribute.
if ( $attribute -> type != 'price' ) {
$attributeQuery -> where ( function ( $attributeValueQuery ) use ( $column , $filterInputValues ) {
foreach ( $filterInputValues as $filterValue ) {
if ( ! is_numeric ( $filterValue )) {
continue ;
}
$attributeValueQuery -> orWhereRaw ( " find_in_set(?, { $column } ) " , [ $filterValue ]);
}
});
} else {
$attributeQuery -> where ( $column , '>=' , core () -> convertToBasePrice ( current ( $filterInputValues )))
-> where ( $column , '<=' , core () -> convertToBasePrice ( end ( $filterInputValues )));
}
});
}
});
$qb -> groupBy ( 'variants.id' );
$qb -> havingRaw ( 'COUNT(*) = ' . count ( $attributeFilters ));
}
return $qb -> groupBy ( 'product_flat.id' );
}) -> paginate ( isset ( $params [ 'limit' ]) ? $params [ 'limit' ] : 9 );
return $results ;
}
2022-01-19 08:32:04 +00:00
public function createSellerProduct ( $product , $seller_id ){
Event :: dispatch ( 'marketplace.catalog.product.create.before' );
$sellerProduct = parent :: create ([
'marketplace_seller_id' => $seller_id ,
'is_approved' => 1 ,
'condition' => 'new' ,
'description' => 'scraped product' ,
'is_owner' => 1 ,
'product_id' => $product -> id ,
]);
foreach ( $sellerProduct -> product -> variants as $baseVariant ) {
parent :: create ([
'parent_id' => $sellerProduct -> id ,
'product_id' => $baseVariant -> id ,
'is_owner' => 1 ,
'marketplace_seller_id' => $seller_id ,
'is_approved' => 1 ,
'condition' => 'new' ,
]);
}
Event :: dispatch ( 'marketplace.catalog.product.create.after' , $sellerProduct );
return $sellerProduct ;
}
2022-01-12 07:35:04 +00:00
private function assignImages ( $product , $images ){
foreach ( $images as $image ){
$this -> imageRepository -> create ([
'type' => 'cdn' ,
'path' => $image ,
'product_id' => $product -> id ,
]);
}
}
private function assignAttributes ( $product , $attributes , $check_option_values = false ){
foreach ( $attributes as $code => $value ){
$attribute = $this -> attributeRepository -> findOneByField ( 'code' , $code );
2021-12-22 15:53:36 +00:00
2022-01-12 07:35:04 +00:00
if ( $attribute -> value_per_channel ) {
if ( $attribute -> value_per_locale ) {
foreach ( core () -> getAllChannels () as $channel ) {
foreach ( core () -> getAllLocales () as $locale ) {
$this -> attributeValueRepository -> create ([
'product_id' => $product -> id ,
'attribute_id' => $attribute -> id ,
'channel' => $channel -> code ,
'locale' => $locale -> code ,
'value' => $value ,
]);
}
}
} else {
foreach ( core () -> getAllChannels () as $channel ) {
$this -> attributeValueRepository -> create ([
'product_id' => $product -> id ,
'attribute_id' => $attribute -> id ,
'channel' => $channel -> code ,
'value' => $value ,
]);
}
}
} else {
if ( $attribute -> value_per_locale ) {
foreach ( core () -> getAllLocales () as $locale ) {
$this -> attributeValueRepository -> create ([
'product_id' => $product -> id ,
'attribute_id' => $attribute -> id ,
'locale' => $locale -> code ,
'value' => $value ,
]);
}
} else {
$this -> attributeValueRepository -> create ([
'product_id' => $product -> id ,
'attribute_id' => $attribute -> id ,
'value' => $value ,
]);
}
}
2021-12-22 15:53:36 +00:00
}
2022-01-12 07:35:04 +00:00
}
2021-12-22 15:53:36 +00:00
2022-01-12 07:35:04 +00:00
private function createVariant ( $product , $sku ){
return $this -> getModel () -> create ([
'parent_id' => $product -> id ,
'type' => 'simple' ,
'attribute_family_id' => $product -> attribute_family_id ,
'sku' => $sku ,
]);
}
private function createFlat ( $product ){
$channel = core () -> getDefaultChannel ();
foreach ( $channel -> locales as $locale ){
$productFlat = $this -> productFlatRepository -> findOneWhere ([
'product_id' => $product -> id ,
'channel' => $channel -> code ,
'locale' => $locale -> code ,
]);
if ( ! $productFlat ) {
$productFlat = $this -> productFlatRepository -> create ([
'product_id' => $product -> id ,
'channel' => $channel -> code ,
'locale' => $locale -> code ,
]);
}
}
2021-12-22 15:53:36 +00:00
}
private function attributeValues ( $values , $attributeCode ){
$attribute = $this -> attributeRepository -> getAttributeByCode ( $attributeCode );
$all_options = $attribute -> options ()
-> orderBy ( 'sort_order' , 'asc' )
-> get ();
$options = $all_options -> whereIn ( 'admin_name' , $values ) -> pluck ( 'admin_name' ) -> toArray ();
//create new options if doesn exist
if ( count ( $values ) != count ( $options )
&& $new_options = array_diff ( $values , $options )){
$order = $all_options -> last () -> sort_order ? ? 0 ;
foreach ( $new_options as $new_option ){
$order ++ ;
$this -> optionRepository -> create ([
'admin_name' => $new_option ,
'sort_order' => $order ,
'attribute_id' => $attribute -> id
]);
}
$options = array_merge ( $options , $new_options );
}
return $options ;
}
2022-01-12 07:35:04 +00:00
private function getAttributeOptionId ( $attr , $value ){
$attribute_id = $this -> attributeRepository -> getAttributeByCode ( $attr ) -> id ;
$option = $this -> optionRepository -> findOneWhere ([ 'attribute_id' => $attribute_id , 'admin_name' => $value ]);
if ( ! $option ){
$option = $this -> optionRepository -> create ([ 'attribute_id' => $attribute_id , 'admin_name' => $value ]);
}
return $option -> id ;
}
2021-12-22 15:53:36 +00:00
//find attribute family
private function getAttributeFamily ( $attrubetCodes ){
$count = count ( $attrubetCodes );
$str = " ' " . implode ( " ',' " , $attrubetCodes ) . " ' " ;
$grups = $this -> attributeGroupRepo -> leftJoin ( 'attribute_group_mappings' , 'attribute_groups.id' , '=' , 'attribute_group_mappings.attribute_group_id' )
-> leftJoin ( 'attributes' , function ( $join ) use ( $attrubetCodes ) {
$join -> on ( 'attributes.id' , '=' , 'attribute_group_mappings.attribute_id' )
-> whereIn ( 'code' , $attrubetCodes );
})
-> groupBy ( 'attribute_groups.id' )
-> havingRaw ( " SUM(IF(attributes.code IN( $str ),1,0)) = $count " )
-> select ( 'attribute_groups.attribute_family_id' )
-> first ();
return $grups ;
}
}