diff --git a/packages/Webkul/API/Http/Resources/Catalog/Product.php b/packages/Webkul/API/Http/Resources/Catalog/Product.php index 765baa131..5f51b99e7 100644 --- a/packages/Webkul/API/Http/Resources/Catalog/Product.php +++ b/packages/Webkul/API/Http/Resources/Catalog/Product.php @@ -3,7 +3,6 @@ namespace Webkul\API\Http\Resources\Catalog; use Illuminate\Http\Resources\Json\JsonResource; -use Webkul\Product\Helpers\ProductType; class Product extends JsonResource { @@ -14,11 +13,13 @@ class Product extends JsonResource */ public function __construct($resource) { + parent::__construct($resource); + $this->productImageHelper = app('Webkul\Product\Helpers\ProductImage'); $this->productReviewHelper = app('Webkul\Product\Helpers\Review'); - parent::__construct($resource); + $this->wishlistHelper = app('Webkul\Customer\Helpers\Wishlist'); } /** @@ -29,52 +30,264 @@ class Product extends JsonResource */ public function toArray($request) { + /* assign product */ $product = $this->product ? $this->product : $this; - $prices = $product->getTypeInstance()->getProductPrices(); + /* get type instance */ + $productTypeInstance = $product->getTypeInstance(); + /* generating resource */ return [ + /* product's information */ 'id' => $product->id, + 'sku' => $product->sku, 'type' => $product->type, - 'name' => $this->name, - 'url_key' => $this->url_key, - 'price' => $product->getTypeInstance()->getMinimalPrice(), - 'formated_price' => core()->currency($product->getTypeInstance()->getMinimalPrice()), - 'short_description' => $this->short_description, - 'description' => $this->description, - 'sku' => $this->sku, + 'name' => $product->name, + 'url_key' => $product->url_key, + 'price' => $productTypeInstance->getMinimalPrice(), + 'formated_price' => core()->currency($productTypeInstance->getMinimalPrice()), + 'short_description' => $product->short_description, + 'description' => $product->description, 'images' => ProductImage::collection($product->images), 'base_image' => $this->productImageHelper->getProductBaseImage($product), - 'variants' => Self::collection($this->variants), - 'in_stock' => $product->haveSufficientQuantity(1), - $this->mergeWhen($product->getTypeInstance()->isComposite(), [ - 'super_attributes' => Attribute::collection($product->super_attributes), - ]), - 'special_price' => $this->when( - $product->getTypeInstance()->haveSpecialPrice(), - $product->getTypeInstance()->getSpecialPrice() - ), - 'formated_special_price' => $this->when( - $product->getTypeInstance()->haveSpecialPrice(), - core()->currency($product->getTypeInstance()->getSpecialPrice()) - ), - 'regular_price' => $this->when( - $product->getTypeInstance()->haveSpecialPrice(), - data_get($prices, 'regular_price.price') - ), - 'formated_regular_price' => $this->when( - $product->getTypeInstance()->haveSpecialPrice(), - data_get($prices, 'regular_price.formated_price') - ), + 'created_at' => $product->created_at, + 'updated_at' => $product->updated_at, + + /* product's reviews */ 'reviews' => [ 'total' => $total = $this->productReviewHelper->getTotalReviews($product), 'total_rating' => $total ? $this->productReviewHelper->getTotalRating($product) : 0, 'average_rating' => $total ? $this->productReviewHelper->getAverageRating($product) : 0, 'percentage' => $total ? json_encode($this->productReviewHelper->getPercentageRating($product)) : [], ], + + /* product's checks */ + 'in_stock' => $product->haveSufficientQuantity(1), 'is_saved' => false, - 'created_at' => $this->created_at, - 'updated_at' => $this->updated_at, + 'is_wishlisted' => $this->wishlistHelper->getWishlistProduct($product), + 'is_item_in_cart' => \Cart::hasProduct($product), + 'show_quantity_changer' => $this->when( + $product->type !== 'grouped', + $product->getTypeInstance()->showQuantityBox() + ), + + /* product's extra information */ + $this->merge($this->allProductExtraInfo()), + + /* special price cases */ + $this->merge($this->specialPriceInfo()), + + /* super attributes */ + $this->mergeWhen($productTypeInstance->isComposite(), [ + 'super_attributes' => Attribute::collection($product->super_attributes), + ]), ]; } + + /** + * Get special price information. + * + * @return array + */ + private function specialPriceInfo() + { + $product = $this->product ? $this->product : $this; + + $productTypeInstance = $product->getTypeInstance(); + + return [ + 'special_price' => $this->when( + $productTypeInstance->haveSpecialPrice(), + $productTypeInstance->getSpecialPrice() + ), + 'formated_special_price' => $this->when( + $productTypeInstance->haveSpecialPrice(), + core()->currency($productTypeInstance->getSpecialPrice()) + ), + 'regular_price' => $this->when( + $productTypeInstance->haveSpecialPrice(), + data_get($productTypeInstance->getProductPrices(), 'regular_price.price') + ), + 'formated_regular_price' => $this->when( + $productTypeInstance->haveSpecialPrice(), + data_get($productTypeInstance->getProductPrices(), 'regular_price.formated_price') + ), + ]; + } + + /** + * Get all product's extra information. + * + * @return array + */ + private function allProductExtraInfo() + { + $product = $this->product ? $this->product : $this; + + $productTypeInstance = $product->getTypeInstance(); + + return [ + /* grouped product */ + $this->mergeWhen( + $productTypeInstance instanceof \Webkul\Product\Type\Grouped, + $product->type == 'grouped' + ? $this->getGroupedProductInfo($product) + : null + ), + + /* bundle product */ + $this->mergeWhen( + $productTypeInstance instanceof \Webkul\Product\Type\Bundle, + $product->type == 'bundle' + ? $this->getBundleProductInfo($product) + : null + ), + + /* configurable product */ + $this->mergeWhen( + $productTypeInstance instanceof \Webkul\Product\Type\Configurable, + $product->type == 'configurable' + ? $this->getConfigurableProductInfo($product) + : null + ), + + /* downloadable product */ + $this->mergeWhen( + $productTypeInstance instanceof \Webkul\Product\Type\Downloadable, + $product->type == 'downloadable' + ? $this->getDownloadableProductInfo($product) + : null + ), + + /* booking product */ + $this->mergeWhen( + $product->type == 'booking', + $product->type == 'booking' + ? $this->getBookingProductInfo($product) + : null + ), + ]; + } + + /** + * Get grouped product's extra information. + * + * @param \Webkul\Product\Models\Product + * @return array + */ + private function getGroupedProductInfo($product) + { + return [ + 'grouped_products' => $product->grouped_products->map(function($groupedProduct) { + $associatedProduct = $groupedProduct->associated_product; + + $data = $associatedProduct->toArray(); + + return array_merge($data, [ + 'qty' => $groupedProduct->qty, + 'isSaleable' => $associatedProduct->getTypeInstance()->isSaleable(), + 'formated_price' => $associatedProduct->getTypeInstance()->getPriceHtml(), + 'show_quantity_changer' => $associatedProduct->getTypeInstance()->showQuantityBox(), + ]); + }) + ]; + } + + /** + * Get bundle product's extra information. + * + * @param \Webkul\Product\Models\Product + * @return array + */ + private function getBundleProductInfo($product) + { + return [ + 'currency_options' => core()->getAccountJsSymbols(), + 'bundle_options' => app('Webkul\Product\Helpers\BundleOption')->getBundleConfig($product) + ]; + } + + /** + * Get configurable product's extra information. + * + * @param \Webkul\Product\Models\Product + * @return array + */ + private function getConfigurableProductInfo($product) + { + return [ + 'variants' => $product->variants + ]; + } + + /** + * Get downloadable product's extra information. + * + * @param \Webkul\Product\Models\Product + * @return array + */ + private function getDownloadableProductInfo($product) + { + return [ + 'downloadable_links' => $product->downloadable_links->map(function ($downloadableLink) { + $data = $downloadableLink->toArray(); + + if (isset($data['sample_file'])) { + $data['price'] = core()->currency($downloadableLink->price); + $data['sample_download_url'] = route('shop.downloadable.download_sample', ['type' => 'link', 'id' => $downloadableLink['id']]); + } + + return $data; + }), + + 'downloadable_samples' => $product->downloadable_samples->map(function ($downloadableSample) { + $sample = $downloadableSample->toArray(); + $data = $sample; + $data['download_url'] = route('shop.downloadable.download_sample', ['type' => 'sample', 'id' => $sample['id']]); + return $data; + }) + ]; + } + + /** + * Get booking product's extra information. + * + * @param \Webkul\Product\Models\Product + * @return array + */ + private function getBookingProductInfo($product) + { + $bookingProduct = app('\Webkul\BookingProduct\Repositories\BookingProductRepository')->findOneByField('product_id', $product->id); + + $data['slot_index_route'] = route('booking_product.slots.index', $bookingProduct->id); + + if ($bookingProduct->type == 'appointment') { + $bookingSlotHelper = app('\Webkul\BookingProduct\Helpers\AppointmentSlot'); + + $data['today_slots_html'] = $bookingSlotHelper->getTodaySlotsHtml($bookingProduct); + $data['week_slot_durations'] = $bookingSlotHelper->getWeekSlotDurations($bookingProduct); + $data['appointment_slot'] = $bookingProduct->appointment_slot; + } + + if ($bookingProduct->type == 'event') { + $bookingSlotHelper = app('\Webkul\BookingProduct\Helpers\EventTicket'); + + $data['tickets'] = $bookingSlotHelper->getTickets($bookingProduct); + $data['event_date'] = $bookingSlotHelper->getEventDate($bookingProduct); + } + + if ($bookingProduct->type == 'rental') { + $data['renting_type'] = $bookingProduct->rental_slot->renting_type; + } + + if ($bookingProduct->type == 'table') { + $bookingSlotHelper = app('\Webkul\BookingProduct\Helpers\TableSlot'); + + $data['today_slots_html'] = $bookingSlotHelper->getTodaySlotsHtml($bookingProduct); + $data['week_slot_durations'] = $bookingSlotHelper->getWeekSlotDurations($bookingProduct); + $data['table_slot'] = $bookingProduct->table_slot; + } + + return $data; + } } diff --git a/packages/Webkul/Checkout/src/Cart.php b/packages/Webkul/Checkout/src/Cart.php index f6ea7abab..42ba51e18 100755 --- a/packages/Webkul/Checkout/src/Cart.php +++ b/packages/Webkul/Checkout/src/Cart.php @@ -20,7 +20,6 @@ use Webkul\Customer\Repositories\CustomerAddressRepository; class Cart { - /** * CartRepository instance * @@ -1290,6 +1289,25 @@ class Cart } } + /** + * Check whether cart has product. + * + * @param \Webkul\Product\Models\Product $product + * @return bool + */ + public function hasProduct($product): bool + { + $cart = \Cart::getCart(); + + if (! $cart) { + return false; + } + + $count = $cart->all_items()->where('product_id', $product->id)->count(); + + return $count > 0 ? true : false; + } + /** * Check minimum order. *