From 3aeb0c75df01837d5f7e9213caf109b3c9207de1 Mon Sep 17 00:00:00 2001 From: Herbert Maschke Date: Mon, 10 Aug 2020 17:24:36 +0200 Subject: [PATCH] ability to define if a product type can be copied in AbstractType.php --- config/products.php | 2 +- .../Admin/src/Resources/lang/ar/app.php | 2 +- .../Admin/src/Resources/lang/de/app.php | 2 +- .../Admin/src/Resources/lang/en/app.php | 2 +- .../BookingProduct/src/Type/Booking.php | 39 ++++++------ .../Http/Controllers/ProductController.php | 4 +- .../src/Repositories/ProductRepository.php | 4 +- .../Webkul/Product/src/Type/AbstractType.php | 63 ++++++++++++------- tests/functional/Product/ProductCopyCest.php | 3 + 9 files changed, 71 insertions(+), 50 deletions(-) diff --git a/config/products.php b/config/products.php index b11a76d0a..6eb93e2fd 100644 --- a/config/products.php +++ b/config/products.php @@ -10,5 +10,5 @@ return [ ], // Make the original and source product 'related' via the 'product_relations' table - 'linkProductsOnCopy' => true, + 'linkProductsOnCopy' => false, ]; \ No newline at end of file diff --git a/packages/Webkul/Admin/src/Resources/lang/ar/app.php b/packages/Webkul/Admin/src/Resources/lang/ar/app.php index 760907ce1..7ee6d855b 100644 --- a/packages/Webkul/Admin/src/Resources/lang/ar/app.php +++ b/packages/Webkul/Admin/src/Resources/lang/ar/app.php @@ -1207,7 +1207,7 @@ return [ 'being-used' => ':source في :name يتم استخدام هذا المورد', 'product-copied' => 'تم نسخ المنتج', 'error-while-copying' => 'خطأ في نسخ المنتج', - 'booking-can-not-be-copied' => 'لا يمكن نسخ منتجات الحجز', + 'product-can-not-be-copied' => 'لا يمكن نسخ منتجات الحجز', 'cannot-delete-default' => 'لا يمكن حذف القناة الافتراضية', 'create-success' => 'إنشاء الاسم بنجاح:name', 'update-success' => 'تحديث الاسم بنجاح :name ', diff --git a/packages/Webkul/Admin/src/Resources/lang/de/app.php b/packages/Webkul/Admin/src/Resources/lang/de/app.php index 612607ba4..c024a5d0e 100755 --- a/packages/Webkul/Admin/src/Resources/lang/de/app.php +++ b/packages/Webkul/Admin/src/Resources/lang/de/app.php @@ -1218,7 +1218,7 @@ return [ 'being-used' => 'Diese Ressource :name wird verwendet in :source', 'product-copied' => 'Das Produkt wurde kopiert', 'error-while-copying' => 'Fehler beim Kopieren des Produkts', - 'booking-can-not-be-copied' => 'Booking Produkte können nicht kopiert werden.', + 'product-can-not-be-copied' => 'Produkte vom Typ :type können nicht kopiert werden.', 'cannot-delete-default' => 'Der Standardkanal kann nicht gelöscht werden', 'create-success' => ':name erfolgreich erstellt.', 'update-success' => ':name erfolgreich aktualisiert.', diff --git a/packages/Webkul/Admin/src/Resources/lang/en/app.php b/packages/Webkul/Admin/src/Resources/lang/en/app.php index d23dc046c..6c2cbe9cb 100755 --- a/packages/Webkul/Admin/src/Resources/lang/en/app.php +++ b/packages/Webkul/Admin/src/Resources/lang/en/app.php @@ -1213,7 +1213,7 @@ return [ 'being-used' => 'This resource :name is getting used in :source', 'product-copied' => 'The Product has been copied', 'error-while-copying' => 'Something went wrong while trying to copy the product', - 'booking-can-not-be-copied' => 'Booking Products can not be copied .', + 'product-can-not-be-copied' => 'Products of type :type can not be copied', 'cannot-delete-default' => 'Cannot delete the default channel', 'create-success' => ':name created successfully.', 'update-success' => ':name updated successfully.', diff --git a/packages/Webkul/BookingProduct/src/Type/Booking.php b/packages/Webkul/BookingProduct/src/Type/Booking.php index bc5c55485..68278dcf6 100644 --- a/packages/Webkul/BookingProduct/src/Type/Booking.php +++ b/packages/Webkul/BookingProduct/src/Type/Booking.php @@ -2,17 +2,17 @@ namespace Webkul\BookingProduct\Type; -use Illuminate\Support\Arr; -use Webkul\Attribute\Repositories\AttributeRepository; -use Webkul\Product\Repositories\ProductRepository; -use Webkul\Product\Repositories\ProductAttributeValueRepository; -use Webkul\Product\Repositories\ProductInventoryRepository; -use Webkul\Product\Repositories\ProductImageRepository; -use Webkul\Product\Helpers\ProductImage; -use Webkul\BookingProduct\Repositories\BookingProductRepository; -use Webkul\BookingProduct\Helpers\Booking as BookingHelper; -use Webkul\Product\Type\Virtual; use Carbon\Carbon; +use Illuminate\Support\Arr; +use Webkul\Product\Type\Virtual; +use Webkul\Product\Helpers\ProductImage; +use Webkul\Product\Repositories\ProductRepository; +use Webkul\Attribute\Repositories\AttributeRepository; +use Webkul\Product\Repositories\ProductImageRepository; +use Webkul\BookingProduct\Helpers\Booking as BookingHelper; +use Webkul\Product\Repositories\ProductInventoryRepository; +use Webkul\Product\Repositories\ProductAttributeValueRepository; +use Webkul\BookingProduct\Repositories\BookingProductRepository; class Booking extends Virtual { @@ -30,6 +30,9 @@ class Booking extends Virtual */ protected $bookingHelper; + /** @var bool do not allow booking products to be copied, it would be too complicated. */ + protected $canBeCopied = false; + /** * @var array */ @@ -44,11 +47,11 @@ class Booking extends Virtual /** * Create a new product type instance. * - * @param \Webkul\Attribute\Repositories\AttributeRepository $attributeRepository - * @param \Webkul\Product\Repositories\ProductRepository $productRepository - * @param \Webkul\Product\Repositories\ProductAttributeValueRepository $attributeValueRepository - * @param \Webkul\Product\Repositories\ProductInventoryRepository $productInventoryRepository - * @param \Webkul\Product\Repositories\ProductImageRepository $productImageRepository + * @param \Webkul\Attribute\Repositories\AttributeRepository $attributeRepository + * @param \Webkul\Product\Repositories\ProductRepository $productRepository + * @param \Webkul\Product\Repositories\ProductAttributeValueRepository $attributeValueRepository + * @param \Webkul\Product\Repositories\ProductInventoryRepository $productInventoryRepository + * @param \Webkul\Product\Repositories\ProductImageRepository $productImageRepository * @param \Webkul\Product\Helpers\ProductImage $productImageHelper * @param \Webkul\BookingProduct\Repositories\BookingProductRepository $bookingProductRepository * @param \Webkul\BookingProduct\Helpers\BookingHelper $bookingHelper @@ -133,7 +136,7 @@ class Booking extends Virtual if (! $bookingProduct) { return false; } - + if (in_array($bookingProduct->type, ['default', 'rental', 'table'])) { return true; } @@ -180,7 +183,7 @@ class Booking extends Virtual if ($bookingProduct->type == 'event') { if (Carbon::now() > $bookingProduct->available_from && Carbon::now() > $bookingProduct->available_to) { return trans('shop::app.checkout.cart.event.expired'); - } + } $filtered = Arr::where($data['booking']['qty'], function ($qty, $key) { return $qty != 0; @@ -206,7 +209,7 @@ class Booking extends Virtual if (is_string($cartProducts)) { return $cartProducts; } - + $products = array_merge($products, $cartProducts); } } else { diff --git a/packages/Webkul/Product/src/Http/Controllers/ProductController.php b/packages/Webkul/Product/src/Http/Controllers/ProductController.php index a410ccf51..ed6bf6932 100755 --- a/packages/Webkul/Product/src/Http/Controllers/ProductController.php +++ b/packages/Webkul/Product/src/Http/Controllers/ProductController.php @@ -249,8 +249,8 @@ class ProductController extends Controller { $originalProduct = $this->productRepository->findOrFail($productId); - if ($originalProduct->type === 'booking') { - session()->flash('error', trans('admin::app.response.booking-can-not-be-copied')); + if (! $originalProduct->getTypeInstance()->canBeCopied()) { + session()->flash('error', trans('admin::app.response.product-can-not-be-copied', ['type' => $originalProduct->type])); return redirect()->to(route('admin.catalog.products.index')); } diff --git a/packages/Webkul/Product/src/Repositories/ProductRepository.php b/packages/Webkul/Product/src/Repositories/ProductRepository.php index e7e4571e4..2afa8ccb5 100755 --- a/packages/Webkul/Product/src/Repositories/ProductRepository.php +++ b/packages/Webkul/Product/src/Repositories/ProductRepository.php @@ -481,8 +481,8 @@ class ProductRepository extends Repository { $this->fillOriginalProduct($originalProduct); - if ($originalProduct->type === 'booking') { - throw new Exception(trans('admin::app.response.booking-can-not-be-copied')); + if (! $originalProduct->getTypeInstance()->canBeCopied() === 'booking') { + throw new Exception(trans('admin::app.response.product-can-not-be-copied', ['type' => $originalProduct->type])); } DB::beginTransaction(); diff --git a/packages/Webkul/Product/src/Type/AbstractType.php b/packages/Webkul/Product/src/Type/AbstractType.php index d17637f55..1b94109a5 100644 --- a/packages/Webkul/Product/src/Type/AbstractType.php +++ b/packages/Webkul/Product/src/Type/AbstractType.php @@ -2,16 +2,15 @@ namespace Webkul\Product\Type; -use Illuminate\Support\Facades\Storage; -use phpDocumentor\Reflection\Types\Boolean; -use Webkul\Attribute\Repositories\AttributeRepository; -use Webkul\Product\Repositories\ProductRepository; -use Webkul\Product\Repositories\ProductAttributeValueRepository; -use Webkul\Product\Repositories\ProductInventoryRepository; -use Webkul\Product\Repositories\ProductImageRepository; -use Webkul\Product\Models\ProductAttributeValue; -use Webkul\Product\Helpers\ProductImage; use Webkul\Checkout\Facades\Cart; +use Illuminate\Support\Facades\Storage; +use Webkul\Product\Helpers\ProductImage; +use Webkul\Product\Models\ProductAttributeValue; +use Webkul\Product\Repositories\ProductRepository; +use Webkul\Attribute\Repositories\AttributeRepository; +use Webkul\Product\Repositories\ProductImageRepository; +use Webkul\Product\Repositories\ProductInventoryRepository; +use Webkul\Product\Repositories\ProductAttributeValueRepository; abstract class AbstractType { @@ -54,7 +53,7 @@ abstract class AbstractType * Product Image helper instance * * @var \Webkul\Product\Helpers\ProductImage - */ + */ protected $productImageHelper; /** @@ -99,6 +98,13 @@ abstract class AbstractType */ protected $canBeMovedFromWishlistToCart = true; + /** + * Products of this type can be copied in the admin backend? + * + * @var bool + */ + protected $canBeCopied = true; + /** * Has child products aka variants * @@ -152,7 +158,16 @@ abstract class AbstractType } /** - * @param array $data + * Is the administrator able to copy products of this type in the admin backend? + */ + public function canBeCopied(): bool + { + return $this->canBeCopied; + } + + /** + * @param array $data + * * @return \Webkul\Product\Contracts\Product */ public function create(array $data) @@ -162,8 +177,8 @@ abstract class AbstractType /** * @param array $data - * @param int $id - * @param string $attribute + * @param int $id + * @param string $attribute * @return \Webkul\Product\Contracts\Product */ public function update(array $data, $id, $attribute = "id") @@ -197,8 +212,8 @@ abstract class AbstractType if ($attribute->type == 'image' || $attribute->type == 'file') { $data[$attribute->code] = gettype($data[$attribute->code]) == 'object' - ? request()->file($attribute->code)->store('product/' . $product->id) - : NULL; + ? request()->file($attribute->code)->store('product/' . $product->id) + : NULL; } $attributeValue = $this->attributeValueRepository->findOneWhere([ @@ -219,7 +234,7 @@ abstract class AbstractType } else { $this->attributeValueRepository->update([ ProductAttributeValue::$attributeTypeFields[$attribute->type] => $data[$attribute->code] - ], $attributeValue->id + ], $attributeValue->id ); if ($attribute->type == 'image' || $attribute->type == 'file') { @@ -376,9 +391,9 @@ abstract class AbstractType $total = 0; $channelInventorySourceIds = core()->getCurrentChannel() - ->inventory_sources() - ->where('status', 1) - ->pluck('id'); + ->inventory_sources() + ->where('status', 1) + ->pluck('id'); foreach ($this->product->inventories as $inventory) { if (is_numeric($index = $channelInventorySourceIds->search($inventory->inventory_source_id))) { @@ -387,8 +402,8 @@ abstract class AbstractType } $orderedInventory = $this->product->ordered_inventories() - ->where('channel_id', core()->getCurrentChannel()->id) - ->first(); + ->where('channel_id', core()->getCurrentChannel()->id) + ->first(); if ($orderedInventory) { $total -= $orderedInventory->qty; @@ -542,7 +557,7 @@ abstract class AbstractType if ($customerGroupPrice != $this->product->price) { $haveSpecialPrice = true; $this->product->special_price = $customerGroupPrice; - } + } } return $haveSpecialPrice; @@ -573,8 +588,8 @@ abstract class AbstractType $customerGroupPrices = $product->customer_group_prices()->where(function ($query) use ($customerGroupId) { $query->where('customer_group_id', $customerGroupId) - ->orWhereNull('customer_group_id'); - } + ->orWhereNull('customer_group_id'); + } )->get(); if (! $customerGroupPrices->count()) { diff --git a/tests/functional/Product/ProductCopyCest.php b/tests/functional/Product/ProductCopyCest.php index 4ecab0f97..fc7638a83 100644 --- a/tests/functional/Product/ProductCopyCest.php +++ b/tests/functional/Product/ProductCopyCest.php @@ -46,6 +46,9 @@ class ProductCopyCest { $I->loginAsAdmin(); + // set this config value to true to make it testable. It defaults to false. + config(['products.linkProductsOnCopy' => true]); + $originalName = $I->fake()->name; $original = $I->haveProduct(Laravel5Helper::SIMPLE_PRODUCT, [