From 0509f45762e12d2cc6ebfc05db283b73422ea86f Mon Sep 17 00:00:00 2001 From: Herbert Maschke Date: Thu, 30 Jul 2020 14:15:54 +0200 Subject: [PATCH 001/120] introduce ability to copy an product --- .../Admin/src/DataGrids/ProductDataGrid.php | 7 + packages/Webkul/Admin/src/Http/routes.php | 4 + .../Admin/src/Resources/lang/de/app.php | 27 ++-- .../Admin/src/Resources/lang/en/app.php | 25 +-- .../Http/Controllers/ProductController.php | 148 ++++++++++++++---- .../Webkul/Product/src/Models/Product.php | 26 +-- tests/_support/FunctionalTester.php | 14 +- tests/functional/Product/ProductCopyCest.php | 86 ++++++++++ 8 files changed, 270 insertions(+), 67 deletions(-) create mode 100644 tests/functional/Product/ProductCopyCest.php diff --git a/packages/Webkul/Admin/src/DataGrids/ProductDataGrid.php b/packages/Webkul/Admin/src/DataGrids/ProductDataGrid.php index 57c65fc4d..e48dec856 100644 --- a/packages/Webkul/Admin/src/DataGrids/ProductDataGrid.php +++ b/packages/Webkul/Admin/src/DataGrids/ProductDataGrid.php @@ -181,6 +181,13 @@ class ProductDataGrid extends DataGrid public function prepareMassActions() { + $this->addAction([ + 'title' => trans('admin::app.datagrid.copy'), + 'method' => 'GET', + 'route' => 'admin.catalog.products.copy', + 'icon' => 'icon note-icon', + ]); + $this->addMassAction([ 'type' => 'delete', 'label' => trans('admin::app.datagrid.delete'), diff --git a/packages/Webkul/Admin/src/Http/routes.php b/packages/Webkul/Admin/src/Http/routes.php index b4f9cce62..b0db82981 100755 --- a/packages/Webkul/Admin/src/Http/routes.php +++ b/packages/Webkul/Admin/src/Http/routes.php @@ -269,6 +269,10 @@ Route::group(['middleware' => ['web']], function () { 'redirect' => 'admin.catalog.products.edit', ])->name('admin.catalog.products.store'); + Route::get('products/copy/{id}', 'Webkul\Product\Http\Controllers\ProductController@copy')->defaults('_config', [ + 'view' => 'admin::catalog.products.edit', + ])->name('admin.catalog.products.copy'); + Route::get('/products/edit/{id}', 'Webkul\Product\Http\Controllers\ProductController@edit')->defaults('_config', [ 'view' => 'admin::catalog.products.edit', ])->name('admin.catalog.products.edit'); diff --git a/packages/Webkul/Admin/src/Resources/lang/de/app.php b/packages/Webkul/Admin/src/Resources/lang/de/app.php index 881147964..ff96194d3 100755 --- a/packages/Webkul/Admin/src/Resources/lang/de/app.php +++ b/packages/Webkul/Admin/src/Resources/lang/de/app.php @@ -1,18 +1,19 @@ 'Speichern', - 'copy-of' => 'Kopie von', - 'create' => 'Erstellen', - 'update' => 'Update', - 'delete' => 'Löschen', - 'failed' => 'Fehlgeschlagen', - 'store' => 'Speichern', - 'image' => 'Bild', - 'no result' => 'Kein Ergebnis', - 'product' => 'Produkt', - 'attribute' => 'Attribut', - 'actions' => 'Aktionen', +return array( + 'save' => 'Speichern', + 'copy-of' => 'Kopie von', + 'copy-of-slug' => 'kopie-von', + 'create' => 'Erstellen', + 'update' => 'Update', + 'delete' => 'Löschen', + 'failed' => 'Fehlgeschlagen', + 'store' => 'Speichern', + 'image' => 'Bild', + 'no result' => 'Kein Ergebnis', + 'product' => 'Produkt', + 'attribute' => 'Attribut', + 'actions' => 'Aktionen', 'id' => 'Id', 'action' => 'Aktion', 'yes' => 'Ja', diff --git a/packages/Webkul/Admin/src/Resources/lang/en/app.php b/packages/Webkul/Admin/src/Resources/lang/en/app.php index ac7a8ad25..90dd8df36 100755 --- a/packages/Webkul/Admin/src/Resources/lang/en/app.php +++ b/packages/Webkul/Admin/src/Resources/lang/en/app.php @@ -1,18 +1,19 @@ 'Save', - 'copy-of' => 'Copy of', - 'create' => 'Create', - 'update' => 'Update', - 'delete' => 'Delete', - 'failed' => 'Failed', - 'store' => 'Store', - 'image' => 'Image', - 'no result' => 'No result', - 'product' => 'Product', - 'attribute' => 'Attribute', - 'actions' => 'Actions', + 'save' => 'Save', + 'copy-of' => 'Copy of', + 'copy-of-slug' => 'copy-of', + 'create' => 'Create', + 'update' => 'Update', + 'delete' => 'Delete', + 'failed' => 'Failed', + 'store' => 'Store', + 'image' => 'Image', + 'no result' => 'No result', + 'product' => 'Product', + 'attribute' => 'Attribute', + 'actions' => 'Actions', 'id' => 'ID', 'action' => 'action', 'yes' => 'Yes', diff --git a/packages/Webkul/Product/src/Http/Controllers/ProductController.php b/packages/Webkul/Product/src/Http/Controllers/ProductController.php index cab805178..a11ac38a4 100755 --- a/packages/Webkul/Product/src/Http/Controllers/ProductController.php +++ b/packages/Webkul/Product/src/Http/Controllers/ProductController.php @@ -2,16 +2,20 @@ namespace Webkul\Product\Http\Controllers; +use Exception; use Illuminate\Support\Facades\Event; -use Webkul\Product\Http\Requests\ProductForm; +use Webkul\Attribute\Models\Attribute; +use Webkul\Product\Models\ProductFlat; use Webkul\Product\Helpers\ProductType; -use Webkul\Category\Repositories\CategoryRepository; +use Illuminate\Support\Facades\Storage; +use Webkul\Core\Contracts\Validations\Slug; +use Webkul\Product\Http\Requests\ProductForm; use Webkul\Product\Repositories\ProductRepository; -use Webkul\Product\Repositories\ProductDownloadableLinkRepository; -use Webkul\Product\Repositories\ProductDownloadableSampleRepository; +use Webkul\Category\Repositories\CategoryRepository; use Webkul\Attribute\Repositories\AttributeFamilyRepository; use Webkul\Inventory\Repositories\InventorySourceRepository; -use Illuminate\Support\Facades\Storage; +use Webkul\Product\Repositories\ProductDownloadableLinkRepository; +use Webkul\Product\Repositories\ProductDownloadableSampleRepository; class ProductController extends Controller { @@ -67,12 +71,13 @@ class ProductController extends Controller /** * Create a new controller instance. * - * @param \Webkul\Category\Repositories\CategoryRepository $categoryRepository - * @param \Webkul\Product\Repositories\ProductRepository $productRepository - * @param \Webkul\Product\Repositories\ProductDownloadableLinkRepository $productDownloadableLinkRepository - * @param \Webkul\Product\Repositories\ProductDownloadableSampleRepository $productDownloadableSampleRepository - * @param \Webkul\Attribute\Repositories\AttributeFamilyRepository $attributeFamilyRepository - * @param \Webkul\Inventory\Repositories\InventorySourceRepository $inventorySourceRepository + * @param \Webkul\Category\Repositories\CategoryRepository $categoryRepository + * @param \Webkul\Product\Repositories\ProductRepository $productRepository + * @param \Webkul\Product\Repositories\ProductDownloadableLinkRepository $productDownloadableLinkRepository + * @param \Webkul\Product\Repositories\ProductDownloadableSampleRepository $productDownloadableSampleRepository + * @param \Webkul\Attribute\Repositories\AttributeFamilyRepository $attributeFamilyRepository + * @param \Webkul\Inventory\Repositories\InventorySourceRepository $inventorySourceRepository + * * @return void */ public function __construct( @@ -143,7 +148,7 @@ class ProductController extends Controller if (ProductType::hasVariants(request()->input('type')) && (! request()->has('super_attributes') - || ! count(request()->get('super_attributes'))) + || ! count(request()->get('super_attributes'))) ) { session()->flash('error', trans('admin::app.catalog.products.configurable-error')); @@ -153,7 +158,7 @@ class ProductController extends Controller $this->validate(request(), [ 'type' => 'required', 'attribute_family_id' => 'required', - 'sku' => ['required', 'unique:products,sku', new \Webkul\Core\Contracts\Validations\Slug], + 'sku' => ['required', 'unique:products,sku', new Slug], ]); $product = $this->productRepository->create(request()->all()); @@ -166,7 +171,8 @@ class ProductController extends Controller /** * Show the form for editing the specified resource. * - * @param int $id + * @param int $id + * * @return \Illuminate\View\View */ public function edit($id) @@ -183,8 +189,9 @@ class ProductController extends Controller /** * Update the specified resource in storage. * - * @param \Webkul\Product\Http\Requests\ProductForm $request - * @param int $id + * @param \Webkul\Product\Http\Requests\ProductForm $request + * @param int $id + * * @return \Illuminate\Http\Response */ public function update(ProductForm $request, $id) @@ -201,20 +208,20 @@ class ProductController extends Controller if (count($customAttributes)) { foreach ($customAttributes as $attribute) { if ($attribute->type == 'multiselect') { - array_push($multiselectAttributeCodes,$attribute->code); - } + array_push($multiselectAttributeCodes, $attribute->code); + } } } } if (count($multiselectAttributeCodes)) { foreach ($multiselectAttributeCodes as $multiselectAttributeCode) { - if(! isset($data[$multiselectAttributeCode])){ + if (! isset($data[$multiselectAttributeCode])) { $data[$multiselectAttributeCode] = array(); } - } + } } - + $product = $this->productRepository->update($data, $id); session()->flash('success', trans('admin::app.response.update-success', ['name' => 'Product'])); @@ -225,7 +232,8 @@ class ProductController extends Controller /** * Uploads downloadable file * - * @param int $id + * @param int $id + * * @return \Illuminate\Http\Response */ public function uploadLink($id) @@ -235,10 +243,92 @@ class ProductController extends Controller ); } + /** + * Copy a given Product. Do not copy the images. + * Always make the copy is inactive so the admin is able to configure it before setting it live. + */ + public function copy(int $productId) + { + $originalProduct = $this->productRepository + ->findOrFail($productId) + ->load('attribute_family') + ->load('categories') + ->load('customer_group_prices') + ->load('inventories') + ->load('inventory_sources'); + + $copiedProduct = $originalProduct + ->replicate() + ->fill([ + // the sku and url_key needs to be unique and should be entered again newly by the admin: + 'sku' => 'temporary-sku-' . substr(md5(microtime()), 0, 6), + ]); + + $copiedProduct->save(); + + $attributeName = Attribute::query()->where(['code' => 'name'])->firstOrFail(); + $attributeSku = Attribute::query()->where(['code' => 'sku'])->firstOrFail(); + $attributeStatus = Attribute::query()->where(['code' => 'status'])->firstOrFail(); + $attributeUrlKey = Attribute::query()->where(['code' => 'url_key'])->firstOrFail(); + + $newProductFlat = new ProductFlat(); + + // only obey copied locale and channel: + if (isset($originalProduct->product_flats[0])) { + $newProductFlat = $originalProduct->product_flats[0]->replicate(); + } + + $newProductFlat->product_id = $copiedProduct->id; + + foreach ($originalProduct->attribute_values as $oldValue) { + $newValue = $oldValue->replicate(); + + if ($oldValue->attribute_id === $attributeName->id) { + $newValue->text_value = __('admin::app.copy-of') . ' ' . $originalProduct->name; + $newProductFlat->name = __('admin::app.copy-of') . ' ' . $originalProduct->name; + } + + if ($oldValue->attribute_id === $attributeUrlKey->id) { + $newValue->text_value = __('admin::app.copy-of-slug') . '-' . $originalProduct->url_key; + $newProductFlat->url_key = __('admin::app.copy-of-slug') . '-' . $originalProduct->url_key; + } + + if ($oldValue->attribute_id === $attributeSku->id) { + $newValue->text_value = $copiedProduct->sku; + $newProductFlat->sku = $copiedProduct->sku; + } + + if ($oldValue->attribute_id === $attributeStatus->id) { + $newValue->boolean_value = 0; + $newProductFlat->status = 0; + } + + $copiedProduct->attribute_values()->save($newValue); + + } + + $newProductFlat->save(); + + foreach ($originalProduct->categories as $category) { + $copiedProduct->categories()->save($category); + } + + foreach ($originalProduct->inventories as $inventory) { + $copiedProduct->inventories()->save($inventory); + } + + foreach ($originalProduct->customer_group_prices as $customer_group_price) { + $copiedProduct->customer_group_prices()->save($customer_group_price); + } + + return redirect()->to(route('admin.catalog.products.edit', ['id' => $copiedProduct->id])); + } + /** * Uploads downloadable sample file * - * @param int $id + * @param int $id + * * @return \Illuminate\Http\Response */ public function uploadSample($id) @@ -251,7 +341,8 @@ class ProductController extends Controller /** * Remove the specified resource from storage. * - * @param int $id + * @param int $id + * * @return \Illuminate\Http\Response */ public function destroy($id) @@ -264,7 +355,7 @@ class ProductController extends Controller session()->flash('success', trans('admin::app.response.delete-success', ['name' => 'Product'])); return response()->json(['message' => true], 200); - } catch (\Exception $e) { + } catch (Exception $e) { report($e); session()->flash('error', trans('admin::app.response.delete-failed', ['name' => 'Product'])); @@ -363,11 +454,12 @@ class ProductController extends Controller } } - /** + /** * Download image or file * - * @param int $productId - * @param int $attributeId + * @param int $productId + * @param int $attributeId + * * @return \Illuminate\Http\Response */ public function download($productId, $attributeId) diff --git a/packages/Webkul/Product/src/Models/Product.php b/packages/Webkul/Product/src/Models/Product.php index 86acea5a1..7f92a4426 100755 --- a/packages/Webkul/Product/src/Models/Product.php +++ b/packages/Webkul/Product/src/Models/Product.php @@ -3,10 +3,12 @@ namespace Webkul\Product\Models; use Illuminate\Database\Eloquent\Model; -use Webkul\Attribute\Models\AttributeFamilyProxy; use Webkul\Category\Models\CategoryProxy; use Webkul\Attribute\Models\AttributeProxy; +use Webkul\Product\Database\Eloquent\Builder; +use Webkul\Attribute\Models\AttributeFamilyProxy; use Webkul\Inventory\Models\InventorySourceProxy; +use Webkul\Attribute\Repositories\AttributeRepository; use Webkul\Product\Contracts\Product as ProductContract; class Product extends Model implements ProductContract @@ -220,8 +222,8 @@ class Product extends Model implements ProductContract public function inventory_source_qty($inventorySourceId) { return $this->inventories() - ->where('inventory_source_id', $inventorySourceId) - ->sum('qty'); + ->where('inventory_source_id', $inventorySourceId) + ->sum('qty'); } /** @@ -283,6 +285,7 @@ class Product extends Model implements ProductContract * * @param Group $group * @param bool $skipSuperAttribute + * * @return Collection */ public function getEditableAttributes($group = null, $skipSuperAttribute = true) @@ -293,7 +296,8 @@ class Product extends Model implements ProductContract /** * Get an attribute from the model. * - * @param string $key + * @param string $key + * * @return mixed */ public function getAttribute($key) @@ -305,8 +309,8 @@ class Product extends Model implements ProductContract if (isset($this->id)) { $this->attributes[$key] = ''; - $attribute = core()->getSingletonInstance(\Webkul\Attribute\Repositories\AttributeRepository::class) - ->getAttributeByCode($key); + $attribute = core()->getSingletonInstance(AttributeRepository::class) + ->getAttributeByCode($key); $this->attributes[$key] = $this->getCustomAttributeValue($attribute); @@ -327,8 +331,9 @@ class Product extends Model implements ProductContract $hiddenAttributes = $this->getHidden(); if (isset($this->id)) { - $familyAttributes = core()->getSingletonInstance(\Webkul\Attribute\Repositories\AttributeRepository::class) - ->getFamilyAttributes($this->attribute_family); + $familyAttributes = core() + ->getSingletonInstance(AttributeRepository::class) + ->getFamilyAttributes($this->attribute_family); foreach ($familyAttributes as $attribute) { if (in_array($attribute->code, $hiddenAttributes)) { @@ -377,12 +382,13 @@ class Product extends Model implements ProductContract /** * Overrides the default Eloquent query builder * - * @param \Illuminate\Database\Eloquent\Builder $query + * @param \Illuminate\Database\Eloquent\Builder $query + * * @return \Illuminate\Database\Eloquent\Builder */ public function newEloquentBuilder($query) { - return new \Webkul\Product\Database\Eloquent\Builder($query); + return new Builder($query); } /** diff --git a/tests/_support/FunctionalTester.php b/tests/_support/FunctionalTester.php index 6d1e1f8b0..f89e14708 100644 --- a/tests/_support/FunctionalTester.php +++ b/tests/_support/FunctionalTester.php @@ -1,5 +1,6 @@ amOnRoute($name, $params); - $I->seeCurrentRouteIs($name); + + if ($routeCheck) { + $I->seeCurrentRouteIs($name); + } /** @var RouteCollection $routes */ $routes = Route::getRoutes(); diff --git a/tests/functional/Product/ProductCopyCest.php b/tests/functional/Product/ProductCopyCest.php new file mode 100644 index 000000000..81eb159de --- /dev/null +++ b/tests/functional/Product/ProductCopyCest.php @@ -0,0 +1,86 @@ +loginAsAdmin(); + + $originalName = $I->fake()->name; + + $original = $I->haveProduct(Laravel5Helper::SIMPLE_PRODUCT, [ + 'productInventory' => [ + 'qty' => 10, + ], + 'attributeValues' => [ + 'name' => $originalName, + ], + ]); + + $count = count(Product::all()); + + $I->amOnAdminRoute('admin.catalog.products.copy', ['id' => $original->id], false); + + $copiedProduct = $I->grabRecord(Product::class, [ + 'id' => $original->id + 1, + 'parent_id' => $original->parent_id, + 'attribute_family_id' => $original->attribute_family_id, + ]); + + $I->seeRecord(ProductAttributeValue::class, [ + 'attribute_id' => 2, + 'product_id' => $copiedProduct->id, + 'text_value' => 'Copy of ' . $originalName, + ]); + + // url_key + $I->seeRecord(ProductAttributeValue::class, [ + 'attribute_id' => 3, + 'product_id' => $copiedProduct->id, + 'text_value' => 'copy-of-' . $original->url_key, + ]); + + // sku + $I->seeRecord(ProductAttributeValue::class, [ + 'attribute_id' => 1, + 'product_id' => $copiedProduct->id, + ]); + + // sku + $I->dontSeeRecord(ProductAttributeValue::class, [ + 'attribute_id' => 1, + 'product_id' => $copiedProduct->id, + 'text_value' => $original->sku, + ]); + + // status + $I->seeRecord(ProductAttributeValue::class, [ + 'attribute_id' => 8, + 'boolean_value' => 0, + ]); + + $I->seeRecord(ProductInventory::class, [ + 'product_id' => $copiedProduct->id, + 'qty' => 10, + ]); + + $I->seeRecord(ProductFlat::class, [ + 'product_id' => $copiedProduct->id, + 'name' => 'Copy of ' . $originalName, + ]); + + $I->assertCount($count + 1, Product::all()); + + $I->seeResponseCodeIsSuccessful(); + } +} From bda810dd5aefa42b421395bdb006cd5efe19acee Mon Sep 17 00:00:00 2001 From: AuTN Date: Fri, 31 Jul 2020 17:37:29 +0700 Subject: [PATCH 002/120] Feat (CMS): Update cms_page_translations table field html_content from text to longtext --- ..._translations_table_field_html_content.php | 36 +++++++++++++++++++ 1 file changed, 36 insertions(+) create mode 100644 packages/Webkul/CMS/src/Database/Migrations/2020_07_31_142021_update_cms_page_translations_table_field_html_content.php diff --git a/packages/Webkul/CMS/src/Database/Migrations/2020_07_31_142021_update_cms_page_translations_table_field_html_content.php b/packages/Webkul/CMS/src/Database/Migrations/2020_07_31_142021_update_cms_page_translations_table_field_html_content.php new file mode 100644 index 000000000..d9a009cd7 --- /dev/null +++ b/packages/Webkul/CMS/src/Database/Migrations/2020_07_31_142021_update_cms_page_translations_table_field_html_content.php @@ -0,0 +1,36 @@ +longtext('html_content')->nullable()->change(); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::table('cms_page_translations', function (Blueprint $table) { + $table->text('html_content')->nullable()->change(); + }); + } +} From 5db479715849799a6700129cfb587961cec859ae Mon Sep 17 00:00:00 2001 From: Herbert Maschke Date: Mon, 3 Aug 2020 12:40:52 +0200 Subject: [PATCH 003/120] refactor copy() method if ProductController.php to be a lot smaller and split the logic into smaller functions for better readability --- .../Http/Controllers/ProductController.php | 74 +--- .../src/Repositories/ProductRepository.php | 321 +++++++++++++----- 2 files changed, 235 insertions(+), 160 deletions(-) diff --git a/packages/Webkul/Product/src/Http/Controllers/ProductController.php b/packages/Webkul/Product/src/Http/Controllers/ProductController.php index a11ac38a4..e70b4564d 100755 --- a/packages/Webkul/Product/src/Http/Controllers/ProductController.php +++ b/packages/Webkul/Product/src/Http/Controllers/ProductController.php @@ -4,8 +4,6 @@ namespace Webkul\Product\Http\Controllers; use Exception; use Illuminate\Support\Facades\Event; -use Webkul\Attribute\Models\Attribute; -use Webkul\Product\Models\ProductFlat; use Webkul\Product\Helpers\ProductType; use Illuminate\Support\Facades\Storage; use Webkul\Core\Contracts\Validations\Slug; @@ -249,77 +247,7 @@ class ProductController extends Controller */ public function copy(int $productId) { - $originalProduct = $this->productRepository - ->findOrFail($productId) - ->load('attribute_family') - ->load('categories') - ->load('customer_group_prices') - ->load('inventories') - ->load('inventory_sources'); - - $copiedProduct = $originalProduct - ->replicate() - ->fill([ - // the sku and url_key needs to be unique and should be entered again newly by the admin: - 'sku' => 'temporary-sku-' . substr(md5(microtime()), 0, 6), - ]); - - $copiedProduct->save(); - - $attributeName = Attribute::query()->where(['code' => 'name'])->firstOrFail(); - $attributeSku = Attribute::query()->where(['code' => 'sku'])->firstOrFail(); - $attributeStatus = Attribute::query()->where(['code' => 'status'])->firstOrFail(); - $attributeUrlKey = Attribute::query()->where(['code' => 'url_key'])->firstOrFail(); - - $newProductFlat = new ProductFlat(); - - // only obey copied locale and channel: - if (isset($originalProduct->product_flats[0])) { - $newProductFlat = $originalProduct->product_flats[0]->replicate(); - } - - $newProductFlat->product_id = $copiedProduct->id; - - foreach ($originalProduct->attribute_values as $oldValue) { - $newValue = $oldValue->replicate(); - - if ($oldValue->attribute_id === $attributeName->id) { - $newValue->text_value = __('admin::app.copy-of') . ' ' . $originalProduct->name; - $newProductFlat->name = __('admin::app.copy-of') . ' ' . $originalProduct->name; - } - - if ($oldValue->attribute_id === $attributeUrlKey->id) { - $newValue->text_value = __('admin::app.copy-of-slug') . '-' . $originalProduct->url_key; - $newProductFlat->url_key = __('admin::app.copy-of-slug') . '-' . $originalProduct->url_key; - } - - if ($oldValue->attribute_id === $attributeSku->id) { - $newValue->text_value = $copiedProduct->sku; - $newProductFlat->sku = $copiedProduct->sku; - } - - if ($oldValue->attribute_id === $attributeStatus->id) { - $newValue->boolean_value = 0; - $newProductFlat->status = 0; - } - - $copiedProduct->attribute_values()->save($newValue); - - } - - $newProductFlat->save(); - - foreach ($originalProduct->categories as $category) { - $copiedProduct->categories()->save($category); - } - - foreach ($originalProduct->inventories as $inventory) { - $copiedProduct->inventories()->save($inventory); - } - - foreach ($originalProduct->customer_group_prices as $customer_group_price) { - $copiedProduct->customer_group_prices()->save($customer_group_price); - } + $copiedProduct = $this->productRepository->copy($productId); return redirect()->to(route('admin.catalog.products.edit', ['id' => $copiedProduct->id])); } diff --git a/packages/Webkul/Product/src/Repositories/ProductRepository.php b/packages/Webkul/Product/src/Repositories/ProductRepository.php index 56225f1e7..131d5f883 100755 --- a/packages/Webkul/Product/src/Repositories/ProductRepository.php +++ b/packages/Webkul/Product/src/Repositories/ProductRepository.php @@ -2,14 +2,18 @@ namespace Webkul\Product\Repositories; -use Illuminate\Pagination\Paginator; +use Webkul\Product\Models\Product; use Illuminate\Support\Facades\DB; -use Illuminate\Container\Container as App; -use Illuminate\Support\Facades\Event; -use Illuminate\Database\Eloquent\ModelNotFoundException; -use Webkul\Attribute\Repositories\AttributeRepository; +use Illuminate\Pagination\Paginator; use Webkul\Core\Eloquent\Repository; +use Illuminate\Support\Facades\Event; +use Webkul\Attribute\Models\Attribute; +use Webkul\Product\Models\ProductFlat; +use Illuminate\Container\Container as App; +use Illuminate\Pagination\LengthAwarePaginator; use Webkul\Product\Models\ProductAttributeValueProxy; +use Webkul\Attribute\Repositories\AttributeRepository; +use Illuminate\Database\Eloquent\ModelNotFoundException; class ProductRepository extends Repository { @@ -23,8 +27,9 @@ class ProductRepository extends Repository /** * Create a new repository instance. * - * @param \Webkul\Attribute\Repositories\AttributeRepository $attributeRepository - * @param \Illuminate\Container\Container $app + * @param \Webkul\Attribute\Repositories\AttributeRepository $attributeRepository + * @param \Illuminate\Container\Container $app + * * @return void */ public function __construct( @@ -48,7 +53,8 @@ class ProductRepository extends Repository } /** - * @param array $data + * @param array $data + * * @return \Webkul\Product\Contracts\Product */ public function create(array $data) @@ -65,9 +71,10 @@ class ProductRepository extends Repository } /** - * @param array $data - * @param int $id - * @param string $attribute + * @param array $data + * @param int $id + * @param string $attribute + * * @return \Webkul\Product\Contracts\Product */ public function update(array $data, $id, $attribute = "id") @@ -88,7 +95,8 @@ class ProductRepository extends Repository } /** - * @param int $id + * @param int $id + * * @return void */ public function delete($id) @@ -101,7 +109,8 @@ class ProductRepository extends Repository } /** - * @param int $categoryId + * @param int $categoryId + * * @return \Illuminate\Support\Collection */ public function getAll($categoryId = null) @@ -111,21 +120,21 @@ class ProductRepository extends Repository if (core()->getConfigData('catalog.products.storefront.products_per_page')) { $pages = explode(',', core()->getConfigData('catalog.products.storefront.products_per_page')); - $perPage = isset($params['limit']) ? (!empty($params['limit']) ? $params['limit'] : 9) : current($pages); + $perPage = isset($params['limit']) ? (! empty($params['limit']) ? $params['limit'] : 9) : current($pages); } else { - $perPage = isset($params['limit']) && !empty($params['limit']) ? $params['limit'] : 9; + $perPage = isset($params['limit']) && ! empty($params['limit']) ? $params['limit'] : 9; } $page = Paginator::resolveCurrentPage('page'); - $repository = app(ProductFlatRepository::class)->scopeQuery(function($query) use($params, $categoryId) { + $repository = app(ProductFlatRepository::class)->scopeQuery(function ($query) use ($params, $categoryId) { $channel = request()->get('channel') ?: (core()->getCurrentChannelCode() ?: core()->getDefaultChannelCode()); $locale = request()->get('locale') ?: app()->getLocale(); $qb = $query->distinct() ->select('product_flat.*') - ->join('product_flat as variants', 'product_flat.id', '=', DB::raw('COALESCE('.DB::getTablePrefix().'variants.parent_id, '.DB::getTablePrefix().'variants.id)')) + ->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') ->where('product_flat.channel', $channel) @@ -149,25 +158,25 @@ class ProductRepository extends Repository # sort direction $orderDirection = 'asc'; - if( isset($params['order']) && in_array($params['order'], ['desc', 'asc']) ){ + if (isset($params['order']) && in_array($params['order'], ['desc', 'asc'])) { $orderDirection = $params['order']; } else { $sortOptions = $this->getDefaultSortByOption(); - $orderDirection = !empty($sortOptions) ? $sortOptions[1] : 'asc'; + $orderDirection = ! empty($sortOptions) ? $sortOptions[1] : 'asc'; } if (isset($params['sort'])) { $this->checkSortAttributeAndGenerateQuery($qb, $params['sort'], $orderDirection); } else { $sortOptions = $this->getDefaultSortByOption(); - if (!empty($sortOptions)) { + if (! empty($sortOptions)) { $this->checkSortAttributeAndGenerateQuery($qb, $sortOptions[0], $orderDirection); } } - if ( $priceFilter = request('price') ){ + if ($priceFilter = request('price')) { $priceRange = explode(',', $priceFilter); - if( count($priceRange) > 0 ) { + if (count($priceRange) > 0) { $qb->where('variants.min_price', '>=', core()->convertToBasePrice($priceRange[0])); $qb->where('variants.min_price', '<=', core()->convertToBasePrice(end($priceRange))); } @@ -178,8 +187,8 @@ class ProductRepository extends Repository request()->except(['price']) )); - if ( count($attributeFilters) > 0 ) { - $qb->where(function ($filterQuery) use($attributeFilters){ + if (count($attributeFilters) > 0) { + $qb->where(function ($filterQuery) use ($attributeFilters) { foreach ($attributeFilters as $attribute) { $filterQuery->orWhere(function ($attributeQuery) use ($attribute) { @@ -196,7 +205,7 @@ class ProductRepository extends Repository $attributeQuery->where(function ($attributeValueQuery) use ($column, $filterInputValues) { foreach ($filterInputValues as $filterValue) { - if (!is_numeric($filterValue)) { + if (! is_numeric($filterValue)) { continue; } $attributeValueQuery->orWhereRaw("find_in_set(?, {$column})", [$filterValue]); @@ -239,9 +248,9 @@ class ProductRepository extends Repository $items = []; } - $results = new \Illuminate\Pagination\LengthAwarePaginator($items, $count, $perPage, $page, [ + $results = new LengthAwarePaginator($items, $count, $perPage, $page, [ 'path' => request()->url(), - 'query' => request()->query() + 'query' => request()->query(), ]); return $results; @@ -250,8 +259,9 @@ class ProductRepository extends Repository /** * Retrive product from slug * - * @param string $slug - * @param string $columns + * @param string $slug + * @param string $columns + * * @return \Webkul\Product\Contracts\Product */ public function findBySlugOrFail($slug, $columns = null) @@ -274,7 +284,8 @@ class ProductRepository extends Repository /** * Retrieve product from slug without throwing an exception (might return null) * - * @param string $slug + * @param string $slug + * * @return \Webkul\Product\Contracts\ProductFlat */ public function findBySlug($slug) @@ -293,19 +304,19 @@ class ProductRepository extends Repository */ public function getNewProducts() { - $results = app(ProductFlatRepository::class)->scopeQuery(function($query) { + $results = app(ProductFlatRepository::class)->scopeQuery(function ($query) { $channel = request()->get('channel') ?: (core()->getCurrentChannelCode() ?: core()->getDefaultChannelCode()); $locale = request()->get('locale') ?: app()->getLocale(); return $query->distinct() - ->addSelect('product_flat.*') - ->where('product_flat.status', 1) - ->where('product_flat.visible_individually', 1) - ->where('product_flat.new', 1) - ->where('product_flat.channel', $channel) - ->where('product_flat.locale', $locale) - ->inRandomOrder(); + ->addSelect('product_flat.*') + ->where('product_flat.status', 1) + ->where('product_flat.visible_individually', 1) + ->where('product_flat.new', 1) + ->where('product_flat.channel', $channel) + ->where('product_flat.locale', $locale) + ->inRandomOrder(); })->paginate(4); return $results; @@ -318,19 +329,19 @@ class ProductRepository extends Repository */ public function getFeaturedProducts() { - $results = app(ProductFlatRepository::class)->scopeQuery(function($query) { + $results = app(ProductFlatRepository::class)->scopeQuery(function ($query) { $channel = request()->get('channel') ?: (core()->getCurrentChannelCode() ?: core()->getDefaultChannelCode()); $locale = request()->get('locale') ?: app()->getLocale(); return $query->distinct() - ->addSelect('product_flat.*') - ->where('product_flat.status', 1) - ->where('product_flat.visible_individually', 1) - ->where('product_flat.featured', 1) - ->where('product_flat.channel', $channel) - ->where('product_flat.locale', $locale) - ->inRandomOrder(); + ->addSelect('product_flat.*') + ->where('product_flat.status', 1) + ->where('product_flat.visible_individually', 1) + ->where('product_flat.featured', 1) + ->where('product_flat.channel', $channel) + ->where('product_flat.locale', $locale) + ->inRandomOrder(); })->paginate(4); return $results; @@ -339,7 +350,8 @@ class ProductRepository extends Repository /** * Search Product by Attribute * - * @param string $term + * @param string $term + * * @return \Illuminate\Support\Collection */ public function searchProductByAttribute($term) @@ -349,27 +361,27 @@ class ProductRepository extends Repository $locale = request()->get('locale') ?: app()->getLocale(); if (config('scout.driver') == 'algolia') { - $results = app(ProductFlatRepository::class)->getModel()::search('query', function ($searchDriver, string $query, array $options) use($term, $channel, $locale) { + $results = app(ProductFlatRepository::class)->getModel()::search('query', function ($searchDriver, string $query, array $options) use ($term, $channel, $locale) { $queries = explode('_', $term); $options['similarQuery'] = array_map('trim', $queries); $searchDriver->setSettings([ 'attributesForFaceting' => [ - "searchable(locale)", - "searchable(channel)" - ] + "searchable(locale)", + "searchable(channel)", + ], ]); - $options['facetFilters'] = ['locale:' . $locale, 'channel:' . $channel]; + $options['facetFilters'] = ['locale:' . $locale, 'channel:' . $channel]; return $searchDriver->search($query, $options); }) - ->where('status', 1) - ->where('visible_individually', 1) - ->orderBy('product_id', 'desc') - ->paginate(16); - } else if(config('scout.driver') == 'elastic') { + ->where('status', 1) + ->where('visible_individually', 1) + ->orderBy('product_id', 'desc') + ->paginate(16); + } else if (config('scout.driver') == 'elastic') { $queries = explode('_', $term); $results = app(ProductFlatRepository::class)->getModel()::search(implode(' OR ', $queries)) @@ -380,23 +392,23 @@ class ProductRepository extends Repository ->orderBy('product_id', 'desc') ->paginate(16); } else { - $results = app(ProductFlatRepository::class)->scopeQuery(function($query) use($term, $channel, $locale) { + $results = app(ProductFlatRepository::class)->scopeQuery(function ($query) use ($term, $channel, $locale) { return $query->distinct() - ->addSelect('product_flat.*') - ->where('product_flat.status', 1) - ->where('product_flat.visible_individually', 1) - ->where('product_flat.channel', $channel) - ->where('product_flat.locale', $locale) - ->whereNotNull('product_flat.url_key') - ->where(function($subQuery) use ($term) { - $queries = explode('_', $term); + ->addSelect('product_flat.*') + ->where('product_flat.status', 1) + ->where('product_flat.visible_individually', 1) + ->where('product_flat.channel', $channel) + ->where('product_flat.locale', $locale) + ->whereNotNull('product_flat.url_key') + ->where(function ($subQuery) use ($term) { + $queries = explode('_', $term); - foreach (array_map('trim', $queries) as $value) { - $subQuery->orWhere('product_flat.name', 'like', '%' . urldecode($value) . '%') - ->orWhere('product_flat.short_description', 'like', '%' . urldecode($value) . '%'); - } - }) - ->orderBy('product_id', 'desc'); + foreach (array_map('trim', $queries) as $value) { + $subQuery->orWhere('product_flat.name', 'like', '%' . urldecode($value) . '%') + ->orWhere('product_flat.short_description', 'like', '%' . urldecode($value) . '%'); + } + }) + ->orderBy('product_id', 'desc'); })->paginate(16); } @@ -406,7 +418,8 @@ class ProductRepository extends Repository /** * Returns product's super attribute with options * - * @param \Webkul\Product\Contracts\Product $product + * @param \Webkul\Product\Contracts\Product $product + * * @return \Illuminate\Support\Collection */ public function getSuperAttributes($product) @@ -432,35 +445,54 @@ class ProductRepository extends Repository /** * Search simple products for grouped product association * - * @param string $term + * @param string $term + * * @return \Illuminate\Support\Collection */ public function searchSimpleProducts($term) { - return app(ProductFlatRepository::class)->scopeQuery(function($query) use($term) { + return app(ProductFlatRepository::class)->scopeQuery(function ($query) use ($term) { $channel = request()->get('channel') ?: (core()->getCurrentChannelCode() ?: core()->getDefaultChannelCode()); $locale = request()->get('locale') ?: app()->getLocale(); return $query->distinct() - ->addSelect('product_flat.*') - ->addSelect('product_flat.product_id as id') - ->leftJoin('products', 'product_flat.product_id', '=', 'products.id') - ->where('products.type', 'simple') - ->where('product_flat.channel', $channel) - ->where('product_flat.locale', $locale) - ->where('product_flat.name', 'like', '%' . urldecode($term) . '%') - ->orderBy('product_id', 'desc'); + ->addSelect('product_flat.*') + ->addSelect('product_flat.product_id as id') + ->leftJoin('products', 'product_flat.product_id', '=', 'products.id') + ->where('products.type', 'simple') + ->where('product_flat.channel', $channel) + ->where('product_flat.locale', $locale) + ->where('product_flat.name', 'like', '%' . urldecode($term) . '%') + ->orderBy('product_id', 'desc'); })->get(); } + /** + * Copy a product. Is usually called by the copy() function of the ProductController. + * + * @param int $sourceProductId the id of the product that should be copied + */ + public function copy(int $sourceProductId): Product + { + $originalProduct = $this->loadOriginalProduct($sourceProductId); + + $copiedProduct = $this->persistCopiedProduct($originalProduct); + + $this->persistAttributeValues($originalProduct, $copiedProduct); + + $this->persistRelations($originalProduct, $copiedProduct); + + return $copiedProduct; + } + /** * Get default sort by option * * @return array */ private function getDefaultSortByOption() - { + { $value = core()->getConfigData('catalog.products.storefront.sort_by'); $config = $value ? $value : 'name-desc'; @@ -471,9 +503,10 @@ class ProductRepository extends Repository /** * Check sort attribute and generate query * - * @param object $query - * @param string $sort - * @param string $direction + * @param object $query + * @param string $sort + * @param string $direction + * * @return object */ private function checkSortAttributeAndGenerateQuery($query, $sort, $direction) @@ -490,4 +523,118 @@ class ProductRepository extends Repository return $query; } + + /** + * @param int $sourceProductId + * + * @return mixed + */ + private function loadOriginalProduct(int $sourceProductId) + { + $originalProduct = $this + ->findOrFail($sourceProductId) + ->load('attribute_family') + ->load('categories') + ->load('customer_group_prices') + ->load('inventories') + ->load('inventory_sources'); + return $originalProduct; + } + + /** + * @param $originalProduct + * + * @return mixed + */ + private function persistCopiedProduct($originalProduct) + { + $copiedProduct = $originalProduct + ->replicate() + ->fill([ + // the sku and url_key needs to be unique and should be entered again newly by the admin: + 'sku' => 'temporary-sku-' . substr(md5(microtime()), 0, 6), + ]); + + $copiedProduct->save(); + + return $copiedProduct; + } + + + /** + * Gather the ids of the necessary product attributes. + * Throw an Exception if one of these 'basic' attributes are missing for some reason. + */ + private function gatherAttributeIds(): array + { + $ids = []; + + foreach (['name', 'sku', 'status', 'url_key'] as $code) { + $ids[$code] = Attribute::query()->where(['code' => $code])->firstOrFail()->id; + } + + return $ids; + } + + private function persistAttributeValues(Product $originalProduct, Product $copiedProduct): void + { + $attributeIds = $this->gatherAttributeIds(); + + $newProductFlat = new ProductFlat(); + + // only obey copied locale and channel: + if (isset($originalProduct->product_flats[0])) { + $newProductFlat = $originalProduct->product_flats[0]->replicate(); + } + + $newProductFlat->product_id = $copiedProduct->id; + + foreach ($originalProduct->attribute_values as $oldValue) { + $newValue = $oldValue->replicate(); + + if ($oldValue->attribute_id === $attributeIds['name']) { + $newValue->text_value = __('admin::app.copy-of') . ' ' . $originalProduct->name; + $newProductFlat->name = __('admin::app.copy-of') . ' ' . $originalProduct->name; + } + + if ($oldValue->attribute_id === $attributeIds['url_key']) { + $newValue->text_value = __('admin::app.copy-of-slug') . '-' . $originalProduct->url_key; + $newProductFlat->url_key = __('admin::app.copy-of-slug') . '-' . $originalProduct->url_key; + } + + if ($oldValue->attribute_id === $attributeIds['sku']) { + $newValue->text_value = $copiedProduct->sku; + $newProductFlat->sku = $copiedProduct->sku; + } + + if ($oldValue->attribute_id === $attributeIds['status']) { + $newValue->boolean_value = 0; + $newProductFlat->status = 0; + } + + $copiedProduct->attribute_values()->save($newValue); + + } + + $newProductFlat->save(); + } + + /** + * @param $originalProduct + * @param $copiedProduct + */ + private function persistRelations($originalProduct, $copiedProduct): void + { + foreach ($originalProduct->categories as $category) { + $copiedProduct->categories()->save($category); + } + + foreach ($originalProduct->inventories as $inventory) { + $copiedProduct->inventories()->save($inventory); + } + + foreach ($originalProduct->customer_group_prices as $customer_group_price) { + $copiedProduct->customer_group_prices()->save($customer_group_price); + } + } } \ No newline at end of file From 80d2cda443a13b0a9c1f142fb18068c92bf4b725 Mon Sep 17 00:00:00 2001 From: Herbert Maschke Date: Mon, 3 Aug 2020 13:32:26 +0200 Subject: [PATCH 004/120] add ability to skip product attributes when doing a copy --- config/products.php | 11 +++++++++++ .../Product/src/Repositories/ProductRepository.php | 6 ++++++ 2 files changed, 17 insertions(+) create mode 100644 config/products.php diff --git a/config/products.php b/config/products.php new file mode 100644 index 000000000..f5d6d234f --- /dev/null +++ b/config/products.php @@ -0,0 +1,11 @@ +catalog->products->copy product) + // defaults to none (which means everything is copied) + 'skipAttributesOnCopy' => [ + + ], + +]; \ No newline at end of file diff --git a/packages/Webkul/Product/src/Repositories/ProductRepository.php b/packages/Webkul/Product/src/Repositories/ProductRepository.php index 131d5f883..65b87a1e7 100755 --- a/packages/Webkul/Product/src/Repositories/ProductRepository.php +++ b/packages/Webkul/Product/src/Repositories/ProductRepository.php @@ -589,7 +589,13 @@ class ProductRepository extends Repository $newProductFlat->product_id = $copiedProduct->id; + $attributesToSkip = config('products.skipAttributesOnCopy') ?? []; + foreach ($originalProduct->attribute_values as $oldValue) { + if (in_array($oldValue->attribute->code, $attributesToSkip)) { + continue; + } + $newValue = $oldValue->replicate(); if ($oldValue->attribute_id === $attributeIds['name']) { From b130bf68cd474d4f007999a7b46e41e388819822 Mon Sep 17 00:00:00 2001 From: Herbert Maschke Date: Mon, 3 Aug 2020 19:52:53 +0200 Subject: [PATCH 005/120] arabic translation of 'copy of' --- .../Admin/src/Resources/lang/ar/app.php | 30 ++++++++++--------- 1 file changed, 16 insertions(+), 14 deletions(-) diff --git a/packages/Webkul/Admin/src/Resources/lang/ar/app.php b/packages/Webkul/Admin/src/Resources/lang/ar/app.php index 0c941c43c..f02261eda 100644 --- a/packages/Webkul/Admin/src/Resources/lang/ar/app.php +++ b/packages/Webkul/Admin/src/Resources/lang/ar/app.php @@ -1,20 +1,22 @@ 'حفظ', - 'create' => 'خلق', - 'update' => 'تحديث', - 'delete' => 'حذف', - 'failed' => 'فشل', - 'store' => 'متجر', - 'image' => 'صورة', - 'no result' => 'لا نتيجة', - 'product' => 'المنتج', - 'attribute' => 'ينسب', - 'actions' => 'أجراءات', - 'id' => 'ID', - 'action' => 'عمل', - 'yes' => 'نعم', + 'save' => 'حفظ', + 'create' => 'خلق', + 'update' => 'تحديث', + 'delete' => 'حذف', + 'copy-of' => 'نسخة من', + 'copy-of-slug' => 'نسخة-من', + 'failed' => 'فشل', + 'store' => 'متجر', + 'image' => 'صورة', + 'no result' => 'لا نتيجة', + 'product' => 'المنتج', + 'attribute' => 'ينسب', + 'actions' => 'أجراءات', + 'id' => 'ID', + 'action' => 'عمل', + 'yes' => 'نعم', 'no' => 'لا', 'true' => 'صحيح', 'false' => 'خاطئة', From 4d9bbc138f0a01360f6653f7702c0c3d56bc7afd Mon Sep 17 00:00:00 2001 From: Herbert Maschke Date: Mon, 3 Aug 2020 19:53:08 +0200 Subject: [PATCH 006/120] also copy images, if not skipped --- .../src/Repositories/ProductRepository.php | 32 +++++++++++++------ 1 file changed, 23 insertions(+), 9 deletions(-) diff --git a/packages/Webkul/Product/src/Repositories/ProductRepository.php b/packages/Webkul/Product/src/Repositories/ProductRepository.php index 65b87a1e7..6ba6ea314 100755 --- a/packages/Webkul/Product/src/Repositories/ProductRepository.php +++ b/packages/Webkul/Product/src/Repositories/ProductRepository.php @@ -2,8 +2,8 @@ namespace Webkul\Product\Repositories; -use Webkul\Product\Models\Product; use Illuminate\Support\Facades\DB; +use Webkul\Product\Models\Product; use Illuminate\Pagination\Paginator; use Webkul\Core\Eloquent\Repository; use Illuminate\Support\Facades\Event; @@ -529,7 +529,7 @@ class ProductRepository extends Repository * * @return mixed */ - private function loadOriginalProduct(int $sourceProductId) + private function loadOriginalProduct(int $sourceProductId): Product { $originalProduct = $this ->findOrFail($sourceProductId) @@ -546,7 +546,7 @@ class ProductRepository extends Repository * * @return mixed */ - private function persistCopiedProduct($originalProduct) + private function persistCopiedProduct($originalProduct): Product { $copiedProduct = $originalProduct ->replicate() @@ -631,16 +631,30 @@ class ProductRepository extends Repository */ private function persistRelations($originalProduct, $copiedProduct): void { - foreach ($originalProduct->categories as $category) { - $copiedProduct->categories()->save($category); + $attributesToSkip = config('products.skipAttributesOnCopy') ?? []; + + if (! isset($attributesToSkip['categories'])) { + foreach ($originalProduct->categories as $category) { + $copiedProduct->categories()->save($category); + } } - foreach ($originalProduct->inventories as $inventory) { - $copiedProduct->inventories()->save($inventory); + if (! isset($attributesToSkip['inventories'])) { + foreach ($originalProduct->inventories as $inventory) { + $copiedProduct->inventories()->save($inventory); + } } - foreach ($originalProduct->customer_group_prices as $customer_group_price) { - $copiedProduct->customer_group_prices()->save($customer_group_price); + if (! isset($attributesToSkip['customer_group_prices'])) { + foreach ($originalProduct->customer_group_prices as $customer_group_price) { + $copiedProduct->customer_group_prices()->save($customer_group_price); + } + } + + if (! isset($attributesToSkip['images'])) { + foreach ($originalProduct->images as $image) { + $copiedProduct->images()->save($image); + } } } } \ No newline at end of file From d66dca2b13f9dd56da3e62c11f3c1c013373d724 Mon Sep 17 00:00:00 2001 From: Herbert Maschke Date: Mon, 3 Aug 2020 20:07:49 +0200 Subject: [PATCH 007/120] block the copying of products with the type 'booking' --- .../Admin/src/Resources/lang/ar/app.php | 24 +- .../Admin/src/Resources/lang/de/app.php | 2100 +++++++++-------- .../Admin/src/Resources/lang/en/app.php | 24 +- .../Http/Controllers/ProductController.php | 2 + .../Webkul/Product/src/Models/Product.php | 3 +- .../src/Repositories/ProductRepository.php | 11 + 6 files changed, 1092 insertions(+), 1072 deletions(-) diff --git a/packages/Webkul/Admin/src/Resources/lang/ar/app.php b/packages/Webkul/Admin/src/Resources/lang/ar/app.php index f02261eda..e8ffe9ae9 100644 --- a/packages/Webkul/Admin/src/Resources/lang/ar/app.php +++ b/packages/Webkul/Admin/src/Resources/lang/ar/app.php @@ -1203,17 +1203,19 @@ return [ ], 'response' => [ - 'being-used' => ':source في :name يتم استخدام هذا المورد', - 'cannot-delete-default' => 'لا يمكن حذف القناة الافتراضية', - 'create-success' => 'إنشاء الاسم بنجاح:name', - 'update-success' => 'تحديث الاسم بنجاح :name ', - 'delete-success' => 'حذف الاسم بنجاح :name', - 'delete-failed' => ':name حدث خطأ أثناء حذف', - 'last-delete-error' => 'مطلوب name: واحد على الأقل', - 'user-define-error' => 'لا يستطيع حذف نظام :name', - 'attribute-error' => 'في المنتجات القابلة للتكوين :name يستخدم ' , - 'attribute-product-error' => 'في المنتجات :name يستخدم ' , - 'customer-associate' => 'لا يمكن حذف :name لأن العميل مرتبط بهذه المجموعة.', + 'being-used' => ':source في :name يتم استخدام هذا المورد', + 'product-copied' => 'تم نسخ المنتج', + 'booking-can-not-be-copied' => 'لا يمكن نسخ منتجات الحجز', + 'cannot-delete-default' => 'لا يمكن حذف القناة الافتراضية', + 'create-success' => 'إنشاء الاسم بنجاح:name', + 'update-success' => 'تحديث الاسم بنجاح :name ', + 'delete-success' => 'حذف الاسم بنجاح :name', + 'delete-failed' => ':name حدث خطأ أثناء حذف', + 'last-delete-error' => 'مطلوب name: واحد على الأقل', + 'user-define-error' => 'لا يستطيع حذف نظام :name', + 'attribute-error' => 'في المنتجات القابلة للتكوين :name يستخدم ', + 'attribute-product-error' => 'في المنتجات :name يستخدم ', + 'customer-associate' => 'لا يمكن حذف :name لأن العميل مرتبط بهذه المجموعة.', 'currency-delete-error' => 'يتم تعيين هذه العملة كعملة أساسية القناة لذلك لا يمكن حذفها.', 'upload-success' => 'بنجاح :name تم تحميل', 'delete-category-root' => 'لا يستطيع حذف الجذر الفئة', diff --git a/packages/Webkul/Admin/src/Resources/lang/de/app.php b/packages/Webkul/Admin/src/Resources/lang/de/app.php index ff96194d3..2730b3770 100755 --- a/packages/Webkul/Admin/src/Resources/lang/de/app.php +++ b/packages/Webkul/Admin/src/Resources/lang/de/app.php @@ -1,171 +1,171 @@ 'Speichern', - 'copy-of' => 'Kopie von', - 'copy-of-slug' => 'kopie-von', - 'create' => 'Erstellen', - 'update' => 'Update', - 'delete' => 'Löschen', - 'failed' => 'Fehlgeschlagen', - 'store' => 'Speichern', - 'image' => 'Bild', - 'no result' => 'Kein Ergebnis', - 'product' => 'Produkt', - 'attribute' => 'Attribut', - 'actions' => 'Aktionen', - 'id' => 'Id', - 'action' => 'Aktion', - 'yes' => 'Ja', - 'no' => 'Nein', - 'true' => 'Wahr', - 'false' => 'Falsch', - 'apply' => 'Anwenden', - 'label' => 'Label', - 'name' => 'Name', - 'title' => 'Titel', - 'code' => 'Code', - 'type' => 'Typ', - 'required' => 'Erforderlich', - 'unique' => 'Einzigartig', - 'locale-based' => 'Sprachabhängig', +return [ + 'save' => 'Speichern', + 'copy-of' => 'Kopie von', + 'copy-of-slug' => 'kopie-von', + 'create' => 'Erstellen', + 'update' => 'Update', + 'delete' => 'Löschen', + 'failed' => 'Fehlgeschlagen', + 'store' => 'Speichern', + 'image' => 'Bild', + 'no result' => 'Kein Ergebnis', + 'product' => 'Produkt', + 'attribute' => 'Attribut', + 'actions' => 'Aktionen', + 'id' => 'Id', + 'action' => 'Aktion', + 'yes' => 'Ja', + 'no' => 'Nein', + 'true' => 'Wahr', + 'false' => 'Falsch', + 'apply' => 'Anwenden', + 'label' => 'Label', + 'name' => 'Name', + 'title' => 'Titel', + 'code' => 'Code', + 'type' => 'Typ', + 'required' => 'Erforderlich', + 'unique' => 'Einzigartig', + 'locale-based' => 'Sprachabhängig', 'channel-based' => 'Channelabhängig', - 'status' => 'Status', + 'status' => 'Status', 'select-option' => 'Wählen Sie eine Option', - 'category' => 'Kategorie', - 'common' => - array ( + 'category' => 'Kategorie', + 'common' => + [ 'no-result-found' => 'Wir konnten keine Aufzeichnungen finden.', - 'country' => 'Land', - 'state' => 'Staat', - 'true' => 'Wahr', - 'false' => 'Falsch', - ), - 'layouts' => - array ( - 'my-account' => 'Mein Konto', - 'logout' => 'Logout', - 'visit-shop' => 'Shop besuchen', - 'dashboard' => 'Dashboard', - 'sales' => 'Vertrieb', - 'orders' => 'Bestellungen', - 'shipments' => 'Sendungen', - 'invoices' => 'Rechnungen', - 'refunds' => 'Erstattungen', - 'catalog' => 'Katalog', - 'products' => 'Produkte', - 'categories' => 'Kategorien', - 'attributes' => 'Attribute', - 'attribute-families' => 'Attributgruppen', - 'customers' => 'Kunden', - 'groups' => 'Gruppen', - 'reviews' => 'Bewertungen', + 'country' => 'Land', + 'state' => 'Staat', + 'true' => 'Wahr', + 'false' => 'Falsch', + ], + 'layouts' => + [ + 'my-account' => 'Mein Konto', + 'logout' => 'Logout', + 'visit-shop' => 'Shop besuchen', + 'dashboard' => 'Dashboard', + 'sales' => 'Vertrieb', + 'orders' => 'Bestellungen', + 'shipments' => 'Sendungen', + 'invoices' => 'Rechnungen', + 'refunds' => 'Erstattungen', + 'catalog' => 'Katalog', + 'products' => 'Produkte', + 'categories' => 'Kategorien', + 'attributes' => 'Attribute', + 'attribute-families' => 'Attributgruppen', + 'customers' => 'Kunden', + 'groups' => 'Gruppen', + 'reviews' => 'Bewertungen', 'newsletter-subscriptions' => 'Newsletter-Abonnements', - 'configure' => 'Konfigurieren', - 'settings' => 'Einstellungen', - 'locales' => 'Sprachen', - 'currencies' => 'Währungen', - 'exchange-rates' => 'Wechselkurse', - 'inventory-sources' => 'Inventar-Quellen', - 'channels' => 'Kanäle', - 'users' => 'Benutzer', - 'roles' => 'Rollen', - 'sliders' => 'Slider', - 'taxes' => 'Steuern', - 'tax-categories' => 'Steuer-Kategorien', - 'tax-rates' => 'Steuersätze', - 'promotions' => 'Promotions', - 'discount' => 'Rabatt', - 'cms' => 'CMS', - ), - 'acl' => - array ( - 'dashboard' => 'Dashboard', - 'sales' => 'Vertrieb', - 'orders' => 'Bestellungen', - 'shipments' => 'Sendungen', - 'invoices' => 'Rechnungen', - 'catalog' => 'Katalog', - 'products' => 'Produkte', - 'categories' => 'Kategorien', - 'attributes' => 'Attribute', - 'attribute-families' => 'Attributgruppen', - 'customers' => 'Kunden', - 'groups' => 'Gruppen', - 'reviews' => 'Bewertungen', + 'configure' => 'Konfigurieren', + 'settings' => 'Einstellungen', + 'locales' => 'Sprachen', + 'currencies' => 'Währungen', + 'exchange-rates' => 'Wechselkurse', + 'inventory-sources' => 'Inventar-Quellen', + 'channels' => 'Kanäle', + 'users' => 'Benutzer', + 'roles' => 'Rollen', + 'sliders' => 'Slider', + 'taxes' => 'Steuern', + 'tax-categories' => 'Steuer-Kategorien', + 'tax-rates' => 'Steuersätze', + 'promotions' => 'Promotions', + 'discount' => 'Rabatt', + 'cms' => 'CMS', + ], + 'acl' => + [ + 'dashboard' => 'Dashboard', + 'sales' => 'Vertrieb', + 'orders' => 'Bestellungen', + 'shipments' => 'Sendungen', + 'invoices' => 'Rechnungen', + 'catalog' => 'Katalog', + 'products' => 'Produkte', + 'categories' => 'Kategorien', + 'attributes' => 'Attribute', + 'attribute-families' => 'Attributgruppen', + 'customers' => 'Kunden', + 'groups' => 'Gruppen', + 'reviews' => 'Bewertungen', 'newsletter-subscriptions' => 'Newsletter-Abonnements', - 'configure' => 'Konfigurieren', - 'settings' => 'Einstellungen', - 'locales' => 'Sprachen', - 'currencies' => 'Währungen', - 'exchange-rates' => 'Wechselkurse', - 'inventory-sources' => 'Inventarquellen', - 'channels' => 'Kanäle', - 'users' => 'Benutzer', - 'roles' => 'Rollen', - 'sliders' => 'Sliders', - 'taxes' => 'Steuern', - 'tax-categories' => 'Steuerkategorien', - 'tax-rates' => 'Steuersätze', - 'edit' => 'Bearbeiten', - 'create' => 'Hinzufügen', - 'delete' => 'Löschen', - 'promotions' => 'Promotions', - 'cart-rules' => 'Warenkorbregeln', - 'catalog-rules' => 'Katalogregeln', - ), - 'dashboard' => - array ( - 'title' => 'Dashboard', - 'from' => 'Von', - 'to' => 'An', - 'total-customers' => 'Anzahl Kunden', - 'total-orders' => 'Anzahl Aufträge', - 'total-sale' => 'Gesamterlös', - 'average-sale' => 'Durchschnitt pro Verkauf', - 'increased' => ':progress%', - 'decreased' => ':progress%', - 'sales' => 'Vertrieb', + 'configure' => 'Konfigurieren', + 'settings' => 'Einstellungen', + 'locales' => 'Sprachen', + 'currencies' => 'Währungen', + 'exchange-rates' => 'Wechselkurse', + 'inventory-sources' => 'Inventarquellen', + 'channels' => 'Kanäle', + 'users' => 'Benutzer', + 'roles' => 'Rollen', + 'sliders' => 'Sliders', + 'taxes' => 'Steuern', + 'tax-categories' => 'Steuerkategorien', + 'tax-rates' => 'Steuersätze', + 'edit' => 'Bearbeiten', + 'create' => 'Hinzufügen', + 'delete' => 'Löschen', + 'promotions' => 'Promotions', + 'cart-rules' => 'Warenkorbregeln', + 'catalog-rules' => 'Katalogregeln', + ], + 'dashboard' => + [ + 'title' => 'Dashboard', + 'from' => 'Von', + 'to' => 'An', + 'total-customers' => 'Anzahl Kunden', + 'total-orders' => 'Anzahl Aufträge', + 'total-sale' => 'Gesamterlös', + 'average-sale' => 'Durchschnitt pro Verkauf', + 'increased' => ':progress%', + 'decreased' => ':progress%', + 'sales' => 'Vertrieb', 'top-performing-categories' => 'Top Kategorien', - 'product-count' => ':count Produkte', - 'top-selling-products' => 'Top Produkte', - 'sale-count' => ':count Verkäufe', - 'customer-with-most-sales' => 'Kunden Mit Dem Meisten Umsatz', - 'order-count' => ':count Bestellungen', - 'revenue' => 'Einnahmen :total', - 'stock-threshold' => 'Lagerbestand', - 'qty-left' => ':qty Verbleibend', - ), - 'datagrid' => - array ( - 'mass-ops' => - array ( - 'method-error' => 'Fehler! Falsche Methode erkannt, überprüfen Sie die Konfiguration der Massenaktion', + 'product-count' => ':count Produkte', + 'top-selling-products' => 'Top Produkte', + 'sale-count' => ':count Verkäufe', + 'customer-with-most-sales' => 'Kunden Mit Dem Meisten Umsatz', + 'order-count' => ':count Bestellungen', + 'revenue' => 'Einnahmen :total', + 'stock-threshold' => 'Lagerbestand', + 'qty-left' => ':qty Verbleibend', + ], + 'datagrid' => + [ + 'mass-ops' => + [ + 'method-error' => 'Fehler! Falsche Methode erkannt, überprüfen Sie die Konfiguration der Massenaktion', 'delete-success' => 'Ausgewählte :resource wurden erfolgreich gelöscht', 'partial-action' => 'Einige Aktionen wurden nicht durchgeführt, aufgrund von System-Einschränkungen von :resource', 'update-success' => 'Ausgewählt :resource wurden erfolgreich aktualisiert', - 'no-resource' => 'Die bereitgestellte Ressource reicht für die Aktion nicht aus', - ), - 'id' => 'Id', - 'status' => 'Status', - 'code' => 'Code', - 'admin-name' => 'Name', - 'name' => 'Name', - 'direction' => 'Richtung', - 'fullname' => 'Vollständiger Name', - 'type' => 'Typ', - 'copy' => 'Kopieren', - 'required' => 'Erforderlich', - 'unique' => 'Einzigartig', - 'per-locale' => 'Sprach-basierend', - 'per-channel' => 'Channel-basierend', - 'position' => 'Position', - 'locale' => 'Sprache', - 'hostname' => 'Hostname', - 'email' => 'E-Mail', - 'group' => 'Gruppe', - 'phone' => 'Telefon', - 'gender' => 'Geschlecht', + 'no-resource' => 'Die bereitgestellte Ressource reicht für die Aktion nicht aus', + ], + 'id' => 'Id', + 'status' => 'Status', + 'code' => 'Code', + 'admin-name' => 'Name', + 'name' => 'Name', + 'direction' => 'Richtung', + 'fullname' => 'Vollständiger Name', + 'type' => 'Typ', + 'copy' => 'Kopieren', + 'required' => 'Erforderlich', + 'unique' => 'Einzigartig', + 'per-locale' => 'Sprach-basierend', + 'per-channel' => 'Channel-basierend', + 'position' => 'Position', + 'locale' => 'Sprache', + 'hostname' => 'Hostname', + 'email' => 'E-Mail', + 'group' => 'Gruppe', + 'phone' => 'Telefon', + 'gender' => 'Geschlecht', 'title' => 'Titel', 'layout' => 'Layout', 'url-key' => 'URL-Schlüssel', @@ -206,130 +206,130 @@ return array( 'for-guest' => 'Für Gäste', 'order_number' => 'Auftragsnummer', 'refund-date' => 'Rückerstattung Datum', - 'refunded' => 'Erstattet', - 'start' => 'Starten', - 'end' => 'Ende', - 'active' => 'Aktiv', - 'inactive' => 'Inaktiv', - 'true' => 'Wahr', - 'false' => 'Falsch', - 'approved' => 'Genehmigt', - 'pending' => 'Ausstehend', - 'disapproved' => 'Abgelehnt', - 'coupon-code' => 'Gutschein-Code', - 'times-used' => 'Mal Verwendet', - 'created-date' => 'Erstellt-Datum', + 'refunded' => 'Erstattet', + 'start' => 'Starten', + 'end' => 'Ende', + 'active' => 'Aktiv', + 'inactive' => 'Inaktiv', + 'true' => 'Wahr', + 'false' => 'Falsch', + 'approved' => 'Genehmigt', + 'pending' => 'Ausstehend', + 'disapproved' => 'Abgelehnt', + 'coupon-code' => 'Gutschein-Code', + 'times-used' => 'Mal Verwendet', + 'created-date' => 'Erstellt-Datum', 'expiration-date' => 'Ablaufdatum', - 'edit' => 'Bearbeiten', - 'delete' => 'Löschen', - 'view' => 'Anzeigen', - 'rtl' => 'RTL', - 'ltr' => 'LTR', - 'update-status' => 'Update-Status', - ), - 'account' => - array ( - 'title' => 'Mein Konto', - 'save-btn-title' => 'Speichern', - 'general' => 'Allgemein', - 'name' => 'Name', - 'email' => 'E-Mail', - 'password' => 'Passwort', + 'edit' => 'Bearbeiten', + 'delete' => 'Löschen', + 'view' => 'Anzeigen', + 'rtl' => 'RTL', + 'ltr' => 'LTR', + 'update-status' => 'Update-Status', + ], + 'account' => + [ + 'title' => 'Mein Konto', + 'save-btn-title' => 'Speichern', + 'general' => 'Allgemein', + 'name' => 'Name', + 'email' => 'E-Mail', + 'password' => 'Passwort', 'confirm-password' => 'Passwort bestätigen', - 'change-password' => 'Änderung des Account-Passworts', + 'change-password' => 'Änderung des Account-Passworts', 'current-password' => 'Aktuelles Passwort', - ), - 'users' => - array ( + ], + 'users' => + [ 'forget-password' => - array ( - 'title' => 'Passwort vergessen', - 'header-title' => 'Passwort wiederherstellen', - 'email' => 'Registrierte E-Mail-Adresse', - 'password' => 'Passwort', + [ + 'title' => 'Passwort vergessen', + 'header-title' => 'Passwort wiederherstellen', + 'email' => 'Registrierte E-Mail-Adresse', + 'password' => 'Passwort', 'confirm-password' => 'Passwort bestätigen', - 'back-link-title' => 'Zurück zur Anmeldung', + 'back-link-title' => 'Zurück zur Anmeldung', 'submit-btn-title' => 'E-Mail zum Zurücksetzen des Passworts senden', - ), - 'reset-password' => - array ( - 'title' => 'Passwort zurücksetzen', - 'email' => 'Registrierte E-Mail-Adresse', - 'password' => 'Passwort', + ], + 'reset-password' => + [ + 'title' => 'Passwort zurücksetzen', + 'email' => 'Registrierte E-Mail-Adresse', + 'password' => 'Passwort', 'confirm-password' => 'Passwort bestätigen', - 'back-link-title' => 'Zurück zur Anmeldung', + 'back-link-title' => 'Zurück zur Anmeldung', 'submit-btn-title' => 'Passwort Zurücksetzen', - ), - 'roles' => - array ( - 'title' => 'Rollen', - 'add-role-title' => 'Rolle hinzufügen', + ], + 'roles' => + [ + 'title' => 'Rollen', + 'add-role-title' => 'Rolle hinzufügen', 'edit-role-title' => 'Rolle bearbeiten', - 'save-btn-title' => 'Rolle speichern', - 'general' => 'Allgemein', - 'name' => 'Name', - 'description' => 'Beschreibung', - 'access-control' => 'Zugangskontrolle', - 'permissions' => 'Berechtigungen', - 'custom' => 'Benutzerdefiniert', - 'all' => 'Alle', - ), - 'users' => - array ( - 'title' => 'Benutzer', - 'add-user-title' => 'Benutzer hinzufügen', - 'edit-user-title' => 'Benutzer bearbeiten', - 'save-btn-title' => 'Benutzer speichern', - 'general' => 'Allgemein', - 'email' => 'E-Mail', - 'name' => 'Name', - 'password' => 'Passwort', - 'confirm-password' => 'Passwort bestätigen', - 'status-and-role' => 'Status und Rolle', - 'role' => 'Rolle', - 'status' => 'Status', - 'account-is-active' => 'Konto ist aktiv', - 'current-password' => 'Geben Sie das aktuelle Passwort ein', - 'confirm-delete' => 'Bestätigen Sie dieses Konto zu löschen', + 'save-btn-title' => 'Rolle speichern', + 'general' => 'Allgemein', + 'name' => 'Name', + 'description' => 'Beschreibung', + 'access-control' => 'Zugangskontrolle', + 'permissions' => 'Berechtigungen', + 'custom' => 'Benutzerdefiniert', + 'all' => 'Alle', + ], + 'users' => + [ + 'title' => 'Benutzer', + 'add-user-title' => 'Benutzer hinzufügen', + 'edit-user-title' => 'Benutzer bearbeiten', + 'save-btn-title' => 'Benutzer speichern', + 'general' => 'Allgemein', + 'email' => 'E-Mail', + 'name' => 'Name', + 'password' => 'Passwort', + 'confirm-password' => 'Passwort bestätigen', + 'status-and-role' => 'Status und Rolle', + 'role' => 'Rolle', + 'status' => 'Status', + 'account-is-active' => 'Konto ist aktiv', + 'current-password' => 'Geben Sie das aktuelle Passwort ein', + 'confirm-delete' => 'Bestätigen Sie dieses Konto zu löschen', 'confirm-delete-title' => 'Bestätigen Sie das Passwort vor dem Löschen', - 'delete-last' => 'Es ist mindestens ein Administrator erforderlich.', - 'delete-success' => 'Erfolg! Benutzer gelöscht', - 'incorrect-password' => 'Das von Ihnen eingegebene Passwort ist falsch', - 'password-match' => 'Aktuelle Passwörter stimmt nicht überein.', - 'account-save' => 'Konto-Änderungen erfolgreich gespeichert.', - 'login-error' => 'Bitte überprüfen Sie Ihre Anmeldeinformationen und versuchen Sie es erneut.', - 'activate-warning' => 'Ihr Konto ist noch nicht aktiviert, kontaktieren Sie bitte den Administrator.', - ), - 'sessions' => - array ( - 'title' => 'Anmelden', - 'email' => 'E-Mail', - 'password' => 'Passwort', + 'delete-last' => 'Es ist mindestens ein Administrator erforderlich.', + 'delete-success' => 'Erfolg! Benutzer gelöscht', + 'incorrect-password' => 'Das von Ihnen eingegebene Passwort ist falsch', + 'password-match' => 'Aktuelle Passwörter stimmt nicht überein.', + 'account-save' => 'Konto-Änderungen erfolgreich gespeichert.', + 'login-error' => 'Bitte überprüfen Sie Ihre Anmeldeinformationen und versuchen Sie es erneut.', + 'activate-warning' => 'Ihr Konto ist noch nicht aktiviert, kontaktieren Sie bitte den Administrator.', + ], + 'sessions' => + [ + 'title' => 'Anmelden', + 'email' => 'E-Mail', + 'password' => 'Passwort', 'forget-password-link-title' => 'Passwort vergessen?', - 'remember-me' => 'Anmeldung merken', - 'submit-btn-title' => 'Anmelden', - ), - ), - 'sales' => - array ( - 'orders' => - array ( - 'title' => 'Bestellungen', - 'view-title' => 'Bestellung #:order_id', - 'cancel-btn-title' => 'Abbrechen', - 'shipment-btn-title' => 'Sendung', - 'invoice-btn-title' => 'Rechnung', - 'info' => 'Informationen', - 'invoices' => 'Rechnungen', - 'shipments' => 'Sendungen', - 'order-and-account' => 'Bestellung und Rechnung', - 'order-info' => 'Bestellinformationen', - 'order-date' => 'Bestelldatum', - 'order-status' => 'Bestellstatus', + 'remember-me' => 'Anmeldung merken', + 'submit-btn-title' => 'Anmelden', + ], + ], + 'sales' => + [ + 'orders' => + [ + 'title' => 'Bestellungen', + 'view-title' => 'Bestellung #:order_id', + 'cancel-btn-title' => 'Abbrechen', + 'shipment-btn-title' => 'Sendung', + 'invoice-btn-title' => 'Rechnung', + 'info' => 'Informationen', + 'invoices' => 'Rechnungen', + 'shipments' => 'Sendungen', + 'order-and-account' => 'Bestellung und Rechnung', + 'order-info' => 'Bestellinformationen', + 'order-date' => 'Bestelldatum', + 'order-status' => 'Bestellstatus', 'order-status-canceled' => 'Abgebrochen', - 'order-status-closed' => 'Geschlossen', - 'order-status-fraud' => 'Betrug', - 'order-status-pending' => 'Ausstehend', + 'order-status-closed' => 'Geschlossen', + 'order-status-fraud' => 'Betrug', + 'order-status-pending' => 'Ausstehend', 'order-status-pending-payment' => 'Ausstehende Zahlung', 'order-status-processing' => 'Verarbeitung', 'order-status-success' => 'Abgeschlossen', @@ -354,121 +354,121 @@ return array( 'qty' => 'Menge', 'item-status' => 'Produktstatus', 'item-ordered' => 'Bestellt (:qty_ordered)', - 'item-invoice' => 'In Rechnung gestellt (:qty_invoiced)', - 'item-shipped' => 'Versand (:qty_shipped)', - 'item-canceled' => 'Abgebrochen (:qty_canceled)', - 'item-refunded' => 'Erstattet (:qty_refunded)', - 'price' => 'Preis', - 'total' => 'Insgesamt', - 'subtotal' => 'Zwischensumme', - 'shipping-handling' => 'Versand & Verpackungskosten', - 'discount' => 'Rabatt', - 'tax' => 'Umsatzsteuer', - 'tax-percent' => 'Umsatzsteuer Prozent', - 'tax-amount' => 'Umsatzsteuer Betrag', - 'discount-amount' => 'Rabatt Betrag', - 'grand-total' => 'Gesamtsumme', - 'total-paid' => 'Insgesamt Bezahlt', - 'total-refunded' => 'Insgesamt Erstattet', - 'total-due' => 'Insgesamt fällig', - 'cancel-confirm-msg' => 'Sind Sie sicher, dass Sie diese Bestellung stornieren möchten?', - 'refund-btn-title' => 'Rückerstattung', - 'refunds' => 'Erstattungen', - ), - 'invoices' => - array ( - 'title' => 'Rechnungen', - 'id' => 'Id', - 'invoice-id' => 'Rechnungsnummer', - 'date' => 'Rechnungsdatum', - 'order-id' => 'Auftragsnummer', - 'customer-name' => 'Name des Kunden', - 'status' => 'Status', - 'amount' => 'Betrag', - 'action' => 'Aktion', - 'add-title' => 'Rechnung erstellen', + 'item-invoice' => 'In Rechnung gestellt (:qty_invoiced)', + 'item-shipped' => 'Versand (:qty_shipped)', + 'item-canceled' => 'Abgebrochen (:qty_canceled)', + 'item-refunded' => 'Erstattet (:qty_refunded)', + 'price' => 'Preis', + 'total' => 'Insgesamt', + 'subtotal' => 'Zwischensumme', + 'shipping-handling' => 'Versand & Verpackungskosten', + 'discount' => 'Rabatt', + 'tax' => 'Umsatzsteuer', + 'tax-percent' => 'Umsatzsteuer Prozent', + 'tax-amount' => 'Umsatzsteuer Betrag', + 'discount-amount' => 'Rabatt Betrag', + 'grand-total' => 'Gesamtsumme', + 'total-paid' => 'Insgesamt Bezahlt', + 'total-refunded' => 'Insgesamt Erstattet', + 'total-due' => 'Insgesamt fällig', + 'cancel-confirm-msg' => 'Sind Sie sicher, dass Sie diese Bestellung stornieren möchten?', + 'refund-btn-title' => 'Rückerstattung', + 'refunds' => 'Erstattungen', + ], + 'invoices' => + [ + 'title' => 'Rechnungen', + 'id' => 'Id', + 'invoice-id' => 'Rechnungsnummer', + 'date' => 'Rechnungsdatum', + 'order-id' => 'Auftragsnummer', + 'customer-name' => 'Name des Kunden', + 'status' => 'Status', + 'amount' => 'Betrag', + 'action' => 'Aktion', + 'add-title' => 'Rechnung erstellen', 'save-btn-title' => 'Rechnung speichern', - 'qty' => 'Menge', - 'qty-ordered' => 'Bestellte Menge', + 'qty' => 'Menge', + 'qty-ordered' => 'Bestellte Menge', 'qty-to-invoice' => 'Menge in Rechnung zu stellen', - 'view-title' => 'Rechnung #:invoice_id', - 'bill-to' => 'Rechnung an', - 'ship-to' => 'Versenden an', - 'print' => 'Drucken', - 'order-date' => 'Bestell-Datum', + 'view-title' => 'Rechnung #:invoice_id', + 'bill-to' => 'Rechnung an', + 'ship-to' => 'Versenden an', + 'print' => 'Drucken', + 'order-date' => 'Bestell-Datum', 'creation-error' => 'Die Erstellung einer Bestellrechnung ist nicht zulässig.', - 'product-error' => 'Eine Rechnung kann nicht ohne Produkte erstellt werden.', - ), + 'product-error' => 'Eine Rechnung kann nicht ohne Produkte erstellt werden.', + ], 'shipments' => - array ( - 'title' => 'Sendungen', - 'id' => 'Id', - 'date' => 'Versanddatum', - 'order-id' => 'Auftragsnummer', - 'order-date' => 'Bestelldatum', - 'customer-name' => 'Name des Kunden', - 'total-qty' => 'Menge insgesamt', - 'action' => 'Aktion', - 'add-title' => 'Sendung anlegen', - 'save-btn-title' => 'Versandkosten sparen', - 'qty-ordered' => 'Bestellte Menge', - 'qty-to-ship' => 'Menge zu versenden', + [ + 'title' => 'Sendungen', + 'id' => 'Id', + 'date' => 'Versanddatum', + 'order-id' => 'Auftragsnummer', + 'order-date' => 'Bestelldatum', + 'customer-name' => 'Name des Kunden', + 'total-qty' => 'Menge insgesamt', + 'action' => 'Aktion', + 'add-title' => 'Sendung anlegen', + 'save-btn-title' => 'Versandkosten sparen', + 'qty-ordered' => 'Bestellte Menge', + 'qty-to-ship' => 'Menge zu versenden', 'available-sources' => 'Verfügbaren Quellen', - 'source' => 'Quelle', - 'select-source' => 'Bitte wählen sie die Quelle', - 'qty-available' => 'Menge verfügbar', - 'inventory-source' => 'Inventarquelle', - 'carrier-title' => 'Zulieferer', - 'tracking-number' => 'Tracking-Nummer', - 'view-title' => 'Versand #:shipment_id', - 'creation-error' => 'Für diese Bestellung kann kein Versand erstellt werden.', - 'order-error' => 'Die Erstellung von Auftragssendungen ist nicht zulässig.', - 'quantity-invalid' => 'Die angeforderte Menge ist ungültig oder nicht verfügbar.', - ), - 'refunds' => - array ( - 'title' => 'Erstattungen', - 'id' => 'Id', - 'add-title' => 'Erstattung erstellen', - 'save-btn-title' => 'Rückerstattung', - 'order-id' => 'Auftragsnummer', - 'qty-ordered' => 'Bestellte Menge', - 'qty-to-refund' => 'Menge zu erstatten', - 'refund-shipping' => 'Erstattung Versand', - 'adjustment-refund' => 'Rückerstattung anpassen', - 'adjustment-fee' => 'Gebühr anpassen', - 'update-qty' => 'Mengen anpassen', - 'invalid-qty' => 'Wir haben eine ungültige Menge gefunden, um Artikel zu erstatten.', - 'refund-limit-error' => 'Das meiste Geld, das zur Rückerstattung zur Verfügung steht, ist :Höhe.', - 'refunded' => 'Erstattet', - 'date' => 'Rückerstattungsdatum', - 'customer-name' => 'Name des Kunden', - 'status' => 'Status', - 'action' => 'Aktion', - 'view-title' => 'Rückerstattung #:refund_id', + 'source' => 'Quelle', + 'select-source' => 'Bitte wählen sie die Quelle', + 'qty-available' => 'Menge verfügbar', + 'inventory-source' => 'Inventarquelle', + 'carrier-title' => 'Zulieferer', + 'tracking-number' => 'Tracking-Nummer', + 'view-title' => 'Versand #:shipment_id', + 'creation-error' => 'Für diese Bestellung kann kein Versand erstellt werden.', + 'order-error' => 'Die Erstellung von Auftragssendungen ist nicht zulässig.', + 'quantity-invalid' => 'Die angeforderte Menge ist ungültig oder nicht verfügbar.', + ], + 'refunds' => + [ + 'title' => 'Erstattungen', + 'id' => 'Id', + 'add-title' => 'Erstattung erstellen', + 'save-btn-title' => 'Rückerstattung', + 'order-id' => 'Auftragsnummer', + 'qty-ordered' => 'Bestellte Menge', + 'qty-to-refund' => 'Menge zu erstatten', + 'refund-shipping' => 'Erstattung Versand', + 'adjustment-refund' => 'Rückerstattung anpassen', + 'adjustment-fee' => 'Gebühr anpassen', + 'update-qty' => 'Mengen anpassen', + 'invalid-qty' => 'Wir haben eine ungültige Menge gefunden, um Artikel zu erstatten.', + 'refund-limit-error' => 'Das meiste Geld, das zur Rückerstattung zur Verfügung steht, ist :Höhe.', + 'refunded' => 'Erstattet', + 'date' => 'Rückerstattungsdatum', + 'customer-name' => 'Name des Kunden', + 'status' => 'Status', + 'action' => 'Aktion', + 'view-title' => 'Rückerstattung #:refund_id', 'invalid-refund-amount-error' => 'Der Rückerstattungsbetrag sollte nicht Null sein.', - ), - ), - 'catalog' => - array ( - 'products' => - array ( - 'title' => 'Produkte', - 'add-product-btn-title' => 'Produkt hinzufügen', - 'add-title' => 'Produkt hinzufügen', - 'edit-title' => 'Produkt bearbeiten', - 'save-btn-title' => 'Produkt speichern', - 'general' => 'Allgemein', - 'product-type' => 'Produkttyp', - 'simple' => 'Einfach', - 'configurable' => 'Konfigurierbar', - 'familiy' => 'Attributgruppe', - 'sku' => 'SKU', + ], + ], + 'catalog' => + [ + 'products' => + [ + 'title' => 'Produkte', + 'add-product-btn-title' => 'Produkt hinzufügen', + 'add-title' => 'Produkt hinzufügen', + 'edit-title' => 'Produkt bearbeiten', + 'save-btn-title' => 'Produkt speichern', + 'general' => 'Allgemein', + 'product-type' => 'Produkttyp', + 'simple' => 'Einfach', + 'configurable' => 'Konfigurierbar', + 'familiy' => 'Attributgruppe', + 'sku' => 'SKU', 'configurable-attributes' => 'Konfigurierbare Attribute', - 'attribute-header' => 'Attribut(s)', + 'attribute-header' => 'Attribut(s)', 'attribute-option-header' => 'Attribut Option(s)', - 'no' => 'Nein', - 'yes' => 'Ja', + 'no' => 'Nein', + 'yes' => 'Ja', 'disabled' => 'Deaktiviert', 'enabled' => 'Aktiviert', 'add-variant-btn-title' => 'Variante hinzufügen', @@ -500,47 +500,47 @@ return array( 'sort-order' => 'Sortierreihenfolge', 'browse-file' => 'Datei durchsuchen', 'product-link' => 'Verlinkte Produkte', - 'cross-selling' => 'Cross-Selling', - 'up-selling' => 'Up Selling', - 'related-products' => 'Verwandte Produkte', - 'product-search-hint' => 'Geben Sie den Produktnamen ein', - 'no-result-found' => 'Produkte nicht mit demselben Namen gefunden.', - 'searching' => 'Suche ...', - 'grouped-products' => 'Gruppierte Produkte', - 'search-products' => 'Produkte suchen', - 'channel' => 'Kanäle', - 'bundle-items' => 'Artikel bündeln', - 'add-option-btn-title' => 'Option hinzufügen', - 'option-title' => 'Option Titel', - 'input-type' => 'Input Type', - 'is-required' => 'Ist erforderlich', - 'select' => 'Select', - 'radio' => 'Radio', - 'checkbox' => 'Checkbox', - 'multiselect' => 'Multiselect', - 'new-option' => 'Neue Option', - 'is-default' => 'Ist Standard', - ), + 'cross-selling' => 'Cross-Selling', + 'up-selling' => 'Up Selling', + 'related-products' => 'Verwandte Produkte', + 'product-search-hint' => 'Geben Sie den Produktnamen ein', + 'no-result-found' => 'Produkte nicht mit demselben Namen gefunden.', + 'searching' => 'Suche ...', + 'grouped-products' => 'Gruppierte Produkte', + 'search-products' => 'Produkte suchen', + 'channel' => 'Kanäle', + 'bundle-items' => 'Artikel bündeln', + 'add-option-btn-title' => 'Option hinzufügen', + 'option-title' => 'Option Titel', + 'input-type' => 'Input Type', + 'is-required' => 'Ist erforderlich', + 'select' => 'Select', + 'radio' => 'Radio', + 'checkbox' => 'Checkbox', + 'multiselect' => 'Multiselect', + 'new-option' => 'Neue Option', + 'is-default' => 'Ist Standard', + ], 'attributes' => - array ( - 'title' => 'Attribute', - 'add-title' => 'Attribut hinzufügen', - 'edit-title' => 'Attribut bearbeiten', - 'save-btn-title' => 'Attribut speichern', - 'general' => 'Allgemein', - 'code' => 'Attribut-Code', - 'type' => 'Attribut-Typ', - 'text' => 'Text', - 'textarea' => 'Textarea', - 'price' => 'Preis', - 'boolean' => 'Boolean', - 'select' => 'Select', - 'multiselect' => 'Multiselect', - 'datetime' => 'Datetime', - 'date' => 'Datum', - 'label' => 'Label', - 'admin' => 'Admin', - 'options' => 'Optionen', + [ + 'title' => 'Attribute', + 'add-title' => 'Attribut hinzufügen', + 'edit-title' => 'Attribut bearbeiten', + 'save-btn-title' => 'Attribut speichern', + 'general' => 'Allgemein', + 'code' => 'Attribut-Code', + 'type' => 'Attribut-Typ', + 'text' => 'Text', + 'textarea' => 'Textarea', + 'price' => 'Preis', + 'boolean' => 'Boolean', + 'select' => 'Select', + 'multiselect' => 'Multiselect', + 'datetime' => 'Datetime', + 'date' => 'Datum', + 'label' => 'Label', + 'admin' => 'Admin', + 'options' => 'Optionen', 'position' => 'Position', 'add-option-btn-title' => 'Option hinzufügen', 'validations' => 'Validierungen', @@ -553,456 +553,456 @@ return array( 'url' => 'URL', 'configuration' => 'Konfiguration', 'status' => 'Status', - 'yes' => 'Ja', - 'no' => 'Nein', - 'value_per_locale' => 'Wert pro Sprache', - 'value_per_channel' => 'Wert pro Kanal', - 'is_filterable' => 'Verwendung in der geschichteten Navigation', - 'is_configurable' => 'Verwenden Sie diese Option, um ein konfigurierbares Produkt zu erstellen', - 'admin_name' => 'Admin-Name', + 'yes' => 'Ja', + 'no' => 'Nein', + 'value_per_locale' => 'Wert pro Sprache', + 'value_per_channel' => 'Wert pro Kanal', + 'is_filterable' => 'Verwendung in der geschichteten Navigation', + 'is_configurable' => 'Verwenden Sie diese Option, um ein konfigurierbares Produkt zu erstellen', + 'admin_name' => 'Admin-Name', 'is_visible_on_front' => 'Sichtbar auf der Produktansichtseite im Frontend', - 'swatch_type' => 'Farbfeld-Typ', - 'dropdown' => 'Dropdown', - 'color-swatch' => 'Farbfeld', - 'image-swatch' => 'Bild Farbfeld', - 'text-swatch' => 'Text Farbfeld', - 'swatch' => 'Farbfeld', - 'image' => 'Bild', - 'file' => 'Datei', - 'checkbox' => 'Checkbox', - 'use_in_flat' => 'In Produkt Flat Tabelle erstellen', - 'is_comparable' => 'Attribut ist vergleichbar', + 'swatch_type' => 'Farbfeld-Typ', + 'dropdown' => 'Dropdown', + 'color-swatch' => 'Farbfeld', + 'image-swatch' => 'Bild Farbfeld', + 'text-swatch' => 'Text Farbfeld', + 'swatch' => 'Farbfeld', + 'image' => 'Bild', + 'file' => 'Datei', + 'checkbox' => 'Checkbox', + 'use_in_flat' => 'In Produkt Flat Tabelle erstellen', + 'is_comparable' => 'Attribut ist vergleichbar', 'default_null_option' => 'Erstellen Sie eine leere Standardoption', - ), - 'families' => - array ( - 'title' => 'Familien', + ], + 'families' => + [ + 'title' => 'Familien', 'add-family-btn-title' => 'Familie hinzufügen', - 'add-title' => 'Familie hinzufügen', - 'edit-title' => 'Familie bearbeiten', - 'save-btn-title' => 'Familie speichern', - 'general' => 'Allgemein', - 'code' => 'Familien Code', - 'name' => 'Name', - 'groups' => 'Gruppen', - 'add-group-title' => 'Gruppe hinzufügen', - 'position' => 'Position', - 'attribute-code' => 'Code', - 'type' => 'Typ', - 'add-attribute-title' => 'Attribut hinzufügen', - 'search' => 'Suche', - 'group-exist-error' => 'Eine gleichnamige Gruppe existiert bereits.', - ), + 'add-title' => 'Familie hinzufügen', + 'edit-title' => 'Familie bearbeiten', + 'save-btn-title' => 'Familie speichern', + 'general' => 'Allgemein', + 'code' => 'Familien Code', + 'name' => 'Name', + 'groups' => 'Gruppen', + 'add-group-title' => 'Gruppe hinzufügen', + 'position' => 'Position', + 'attribute-code' => 'Code', + 'type' => 'Typ', + 'add-attribute-title' => 'Attribut hinzufügen', + 'search' => 'Suche', + 'group-exist-error' => 'Eine gleichnamige Gruppe existiert bereits.', + ], 'categories' => - array ( - 'title' => 'Kategorien', - 'add-title' => 'Kategorie hinzufügen', - 'edit-title' => 'Kategorie bearbeiten', - 'save-btn-title' => 'Kategorie speichern', - 'general' => 'Allgemein', - 'name' => 'Name', - 'visible-in-menu' => 'Sichtbar im Menü', - 'yes' => 'Ja', - 'no' => 'Nein', - 'position' => 'Position', - 'display-mode' => 'Display-Modus', + [ + 'title' => 'Kategorien', + 'add-title' => 'Kategorie hinzufügen', + 'edit-title' => 'Kategorie bearbeiten', + 'save-btn-title' => 'Kategorie speichern', + 'general' => 'Allgemein', + 'name' => 'Name', + 'visible-in-menu' => 'Sichtbar im Menü', + 'yes' => 'Ja', + 'no' => 'Nein', + 'position' => 'Position', + 'display-mode' => 'Display-Modus', 'products-and-description' => 'Produkte und Beschreibung', - 'products-only' => 'Nur Produkte', - 'description-only' => 'Nur Beschreibungen', - 'description-and-images' => 'Beschreibung und Bilder', - 'description' => 'Beschreibung', - 'parent-category' => 'Übergeordnete Kategorie', - 'seo' => 'Suchmaschinen-Optimierung', - 'slug' => 'Slug', - 'meta_title' => 'Meta Titel', - 'meta_description' => 'Meta-Beschreibung', - 'meta_keywords' => 'Meta-Schlüsselworte', - 'image' => 'Bild', - 'filterable-attributes' => 'Filterbare Attribute', - 'attributes' => 'Attribute', - ), - ), + 'products-only' => 'Nur Produkte', + 'description-only' => 'Nur Beschreibungen', + 'description-and-images' => 'Beschreibung und Bilder', + 'description' => 'Beschreibung', + 'parent-category' => 'Übergeordnete Kategorie', + 'seo' => 'Suchmaschinen-Optimierung', + 'slug' => 'Slug', + 'meta_title' => 'Meta Titel', + 'meta_description' => 'Meta-Beschreibung', + 'meta_keywords' => 'Meta-Schlüsselworte', + 'image' => 'Bild', + 'filterable-attributes' => 'Filterbare Attribute', + 'attributes' => 'Attribute', + ], + ], 'configuration' => - array ( - 'title' => 'Konfiguration', + [ + 'title' => 'Konfiguration', 'save-btn-title' => 'Speichern', - 'save-message' => 'Konfiguration erfolgreich gespeichert', - 'yes' => 'Ja', - 'no' => 'Nein', - 'delete' => 'Löschen', + 'save-message' => 'Konfiguration erfolgreich gespeichert', + 'yes' => 'Ja', + 'no' => 'Nein', + 'delete' => 'Löschen', 'tax-categories' => - array ( - 'title' => 'Steuerkategorien', - 'add-title' => 'Steuerkategorie hinzufügen', - 'edit-title' => 'Steuerkategorie bearbeiten', - 'save-btn-title' => 'Steuerkategorie speichern', - 'general' => 'Steuerkategorie', - 'select-channel' => 'Wählen Sie einen Kanal', - 'name' => 'Name', - 'code' => 'Code', - 'description' => 'Beschreibung', + [ + 'title' => 'Steuerkategorien', + 'add-title' => 'Steuerkategorie hinzufügen', + 'edit-title' => 'Steuerkategorie bearbeiten', + 'save-btn-title' => 'Steuerkategorie speichern', + 'general' => 'Steuerkategorie', + 'select-channel' => 'Wählen Sie einen Kanal', + 'name' => 'Name', + 'code' => 'Code', + 'description' => 'Beschreibung', 'select-taxrates' => 'Wählen Sie die Steuersätze', - 'edit' => - array ( - 'title' => 'Steuerkategorie bearbeiten', + 'edit' => + [ + 'title' => 'Steuerkategorie bearbeiten', 'edit-button-title' => 'Steuerkategorie bearbeiten', - ), - ), - 'tax-rates' => - array ( - 'title' => 'Steuersätze', - 'add-title' => 'Steuersatz hinzufügen', - 'edit-title' => 'Steuersatz bearbeiten', + ], + ], + 'tax-rates' => + [ + 'title' => 'Steuersätze', + 'add-title' => 'Steuersatz hinzufügen', + 'edit-title' => 'Steuersatz bearbeiten', 'save-btn-title' => 'Steuersatz speichern', - 'general' => 'Steuersatz', - 'identifier' => 'Bezeichnung', - 'is_zip' => 'Postleitzahlen Reichweite aktivieren', - 'zip_from' => 'Postleitzahl von', - 'zip_to' => 'Postleitzahl bis', - 'state' => 'Staat', - 'select-state' => 'Wählen Sie eine Region, ein Bundesland oder eine Provinz aus.', - 'country' => 'Land', - 'tax_rate' => 'Rate', - 'edit' => - array ( - 'title' => 'Steuersatz bearbeiten', + 'general' => 'Steuersatz', + 'identifier' => 'Bezeichnung', + 'is_zip' => 'Postleitzahlen Reichweite aktivieren', + 'zip_from' => 'Postleitzahl von', + 'zip_to' => 'Postleitzahl bis', + 'state' => 'Staat', + 'select-state' => 'Wählen Sie eine Region, ein Bundesland oder eine Provinz aus.', + 'country' => 'Land', + 'tax_rate' => 'Rate', + 'edit' => + [ + 'title' => 'Steuersatz bearbeiten', 'edit-button-title' => 'Steuersatz bearbeiten', - ), - 'zip_code' => 'Postleitzahl', - ), - 'sales' => - array ( + ], + 'zip_code' => 'Postleitzahl', + ], + 'sales' => + [ 'shipping-method' => - array ( - 'title' => 'Versand-Methoden', + [ + 'title' => 'Versand-Methoden', 'save-btn-title' => 'Speichern', - 'description' => 'Bearbeiten', - 'active' => 'Aktiv', - 'status' => 'Status', - ), - ), - ), - 'settings' => - array ( - 'locales' => - array ( - 'title' => 'Sprachen', - 'add-title' => 'Sprache hinzufügen', - 'edit-title' => 'Sprache bearbeiten', - 'save-btn-title' => 'Sprache speichern', - 'general' => 'Allgemein', - 'code' => 'Code', - 'name' => 'Name', - 'direction' => 'Richtung', - 'create-success' => 'Sprache erfolgreich erstellt.', - 'update-success' => 'Sprache erfolgreich aktualisiert.', - 'delete-success' => 'Sprache erfolgreich gelöscht.', + 'description' => 'Bearbeiten', + 'active' => 'Aktiv', + 'status' => 'Status', + ], + ], + ], + 'settings' => + [ + 'locales' => + [ + 'title' => 'Sprachen', + 'add-title' => 'Sprache hinzufügen', + 'edit-title' => 'Sprache bearbeiten', + 'save-btn-title' => 'Sprache speichern', + 'general' => 'Allgemein', + 'code' => 'Code', + 'name' => 'Name', + 'direction' => 'Richtung', + 'create-success' => 'Sprache erfolgreich erstellt.', + 'update-success' => 'Sprache erfolgreich aktualisiert.', + 'delete-success' => 'Sprache erfolgreich gelöscht.', 'last-delete-error' => 'Mindestens eine Sprache ist erforderlich.', - ), - 'countries' => - array ( - 'title' => 'Länder', - 'add-title' => 'Land hinzufügen', + ], + 'countries' => + [ + 'title' => 'Länder', + 'add-title' => 'Land hinzufügen', 'save-btn-title' => 'Land speichern', - 'general' => 'Allgemein', - 'code' => 'Code', - 'name' => 'Name', - ), - 'currencies' => - array ( - 'title' => 'Währungen', - 'add-title' => 'Währung hinzufügen', - 'edit-title' => 'Währung bearbeiten', - 'save-btn-title' => 'Währung speichern', - 'general' => 'Allgemein', - 'code' => 'Code', - 'name' => 'Name', - 'symbol' => 'Symbol', - 'create-success' => 'Währung erfolgreich erstellt.', - 'update-success' => 'Währung erfolgreich aktualisiert.', - 'delete-success' => 'Währung erfolgreich gelöscht.', + 'general' => 'Allgemein', + 'code' => 'Code', + 'name' => 'Name', + ], + 'currencies' => + [ + 'title' => 'Währungen', + 'add-title' => 'Währung hinzufügen', + 'edit-title' => 'Währung bearbeiten', + 'save-btn-title' => 'Währung speichern', + 'general' => 'Allgemein', + 'code' => 'Code', + 'name' => 'Name', + 'symbol' => 'Symbol', + 'create-success' => 'Währung erfolgreich erstellt.', + 'update-success' => 'Währung erfolgreich aktualisiert.', + 'delete-success' => 'Währung erfolgreich gelöscht.', 'last-delete-error' => 'Mindestens eine Währung ist erforderlich.', - ), - 'exchange_rates' => - array ( - 'title' => 'Wechselkurse', - 'add-title' => 'Wechselkurs hinzufügen', - 'edit-title' => 'Wechselkurs bearbeiten', - 'save-btn-title' => 'Wechselkurs speichern', - 'general' => 'Allgemein', - 'source_currency' => 'Quell-Währung', - 'target_currency' => 'Ziel-Währung', - 'rate' => 'Rate', + ], + 'exchange_rates' => + [ + 'title' => 'Wechselkurse', + 'add-title' => 'Wechselkurs hinzufügen', + 'edit-title' => 'Wechselkurs bearbeiten', + 'save-btn-title' => 'Wechselkurs speichern', + 'general' => 'Allgemein', + 'source_currency' => 'Quell-Währung', + 'target_currency' => 'Ziel-Währung', + 'rate' => 'Rate', 'exchange-class-not-found' => ':service Wechselkursklasse nicht gefunden', - 'update-rates' => 'Rate aktualisieren mit :service', - 'create-success' => 'Wechselkurs erfolgreich erstellt.', - 'update-success' => 'Wechselkurse erfolgreichaktualisiert.', - 'delete-success' => 'Wechselkurs erfolgreich gelöscht.', - 'last-delete-error' => 'Mindestens ein Wechselkurs ist erforderlich.', - ), + 'update-rates' => 'Rate aktualisieren mit :service', + 'create-success' => 'Wechselkurs erfolgreich erstellt.', + 'update-success' => 'Wechselkurse erfolgreichaktualisiert.', + 'delete-success' => 'Wechselkurs erfolgreich gelöscht.', + 'last-delete-error' => 'Mindestens ein Wechselkurs ist erforderlich.', + ], 'inventory_sources' => - array ( - 'title' => 'Inventar-Quellen', - 'add-title' => 'Inventar Quelle hinzufügen', - 'edit-title' => 'Inventar Quelle bearbeiten', - 'save-btn-title' => 'Inventar Quelle speichern', - 'general' => 'Allgemein', - 'code' => 'Code', - 'name' => 'Name', - 'description' => 'Beschreibung', - 'source-is-active' => 'Quelle ist aktiv', - 'contact-info' => 'Kontakt-Informationen', - 'contact_name' => 'Name', - 'contact_email' => 'E-Mail', - 'contact_number' => 'Kontakt-Nummer', - 'contact_fax' => 'Fax', - 'address' => 'Quell-Adresse', - 'country' => 'Land', - 'state' => 'Staat', - 'city' => 'Stadt', - 'street' => 'Straße', - 'postcode' => 'Postleitzahl', - 'priority' => 'Priorität', - 'latitude' => 'Breite', - 'longitude' => 'Länge', - 'status' => 'Status', - 'create-success' => 'Inventar Quelle erfolgreich erstellt.', - 'update-success' => 'Inventar Quelle erfolgreich aktualisiert.', - 'delete-success' => 'Inventar Quelle erfolgreich gelöscht.', + [ + 'title' => 'Inventar-Quellen', + 'add-title' => 'Inventar Quelle hinzufügen', + 'edit-title' => 'Inventar Quelle bearbeiten', + 'save-btn-title' => 'Inventar Quelle speichern', + 'general' => 'Allgemein', + 'code' => 'Code', + 'name' => 'Name', + 'description' => 'Beschreibung', + 'source-is-active' => 'Quelle ist aktiv', + 'contact-info' => 'Kontakt-Informationen', + 'contact_name' => 'Name', + 'contact_email' => 'E-Mail', + 'contact_number' => 'Kontakt-Nummer', + 'contact_fax' => 'Fax', + 'address' => 'Quell-Adresse', + 'country' => 'Land', + 'state' => 'Staat', + 'city' => 'Stadt', + 'street' => 'Straße', + 'postcode' => 'Postleitzahl', + 'priority' => 'Priorität', + 'latitude' => 'Breite', + 'longitude' => 'Länge', + 'status' => 'Status', + 'create-success' => 'Inventar Quelle erfolgreich erstellt.', + 'update-success' => 'Inventar Quelle erfolgreich aktualisiert.', + 'delete-success' => 'Inventar Quelle erfolgreich gelöscht.', 'last-delete-error' => 'Mindestens eine Inventar-Quelle erforderlich ist.', - ), - 'channels' => - array ( - 'title' => 'Kanäle', - 'add-title' => 'Kanal hinzufügen', - 'edit-title' => 'Kanal bearbeiten', - 'save-btn-title' => 'Kanal speichern', - 'general' => 'Allgemein', - 'code' => 'Code', - 'name' => 'Name', - 'description' => 'Beschreibung', - 'hostname' => 'Hostname', + ], + 'channels' => + [ + 'title' => 'Kanäle', + 'add-title' => 'Kanal hinzufügen', + 'edit-title' => 'Kanal bearbeiten', + 'save-btn-title' => 'Kanal speichern', + 'general' => 'Allgemein', + 'code' => 'Code', + 'name' => 'Name', + 'description' => 'Beschreibung', + 'hostname' => 'Hostname', 'currencies-and-locales' => 'Währungen und Spachen', - 'locales' => 'Sprachen', - 'default-locale' => 'Standard-Sprache', - 'currencies' => 'Währungen', - 'base-currency' => 'Standard-Währung', - 'root-category' => 'Root-Kategorie', - 'inventory_sources' => 'Inventar-Quellen', - 'design' => 'Design', - 'theme' => 'Theme', - 'home_page_content' => 'Startseite Inhalt', - 'footer_content' => 'Fußzeile Inhalt', - 'logo' => 'Logo', - 'favicon' => 'Favicon', - 'create-success' => 'Kanal erfolgreich erstellt.', - 'update-success' => 'Kanal erfolgreich aktualisiert.', - 'delete-success' => 'Kanal erfolgreich gelöscht.', - 'last-delete-error' => 'Mindestens ein Kanal ist erforderlich.', - 'seo' => 'Home-Page-SEO', - 'seo-title' => 'Meta Titel', - 'seo-description' => 'Meta-Beschreibung', - 'seo-keywords' => 'Meta-keywords', - ), - 'sliders' => - array ( - 'title' => 'Sliders', - 'name' => 'Name', - 'add-title' => 'Slider erstellen', - 'edit-title' => 'Slider editieren', - 'save-btn-title' => 'Slider speichern', - 'general' => 'Allgemein', - 'image' => 'Bild', - 'content' => 'Inhalt', - 'channels' => 'Kanal', + 'locales' => 'Sprachen', + 'default-locale' => 'Standard-Sprache', + 'currencies' => 'Währungen', + 'base-currency' => 'Standard-Währung', + 'root-category' => 'Root-Kategorie', + 'inventory_sources' => 'Inventar-Quellen', + 'design' => 'Design', + 'theme' => 'Theme', + 'home_page_content' => 'Startseite Inhalt', + 'footer_content' => 'Fußzeile Inhalt', + 'logo' => 'Logo', + 'favicon' => 'Favicon', + 'create-success' => 'Kanal erfolgreich erstellt.', + 'update-success' => 'Kanal erfolgreich aktualisiert.', + 'delete-success' => 'Kanal erfolgreich gelöscht.', + 'last-delete-error' => 'Mindestens ein Kanal ist erforderlich.', + 'seo' => 'Home-Page-SEO', + 'seo-title' => 'Meta Titel', + 'seo-description' => 'Meta-Beschreibung', + 'seo-keywords' => 'Meta-keywords', + ], + 'sliders' => + [ + 'title' => 'Sliders', + 'name' => 'Name', + 'add-title' => 'Slider erstellen', + 'edit-title' => 'Slider editieren', + 'save-btn-title' => 'Slider speichern', + 'general' => 'Allgemein', + 'image' => 'Bild', + 'content' => 'Inhalt', + 'channels' => 'Kanal', 'created-success' => 'Slider erfolgreich erstellt', - 'created-fault' => 'Fehler beim Erstellen des Slider-Elements', - 'update-success' => 'Slider-Eintrag wurde erfolgreich aktualisiert', - 'update-fail' => 'Slider kann nicht aktualisiert werden', - 'delete-success' => 'Der letzte Slider kann nicht gelöscht werden', - 'delete-fail' => 'Slider erfolgreich gelöscht', - ), - 'tax-categories' => - array ( - 'title' => 'Steuerkategorien', - 'add-title' => 'Steuerkategorie erstellen', - 'edit-title' => 'Steuerkategorie bearbeiten', - 'save-btn-title' => 'Steuern-Kategorie speichern', - 'general' => 'Steuerkategorie', - 'select-channel' => 'Wählen Sie einen Kanal', - 'name' => 'Name', - 'code' => 'Code', - 'description' => 'Beschreibung', + 'created-fault' => 'Fehler beim Erstellen des Slider-Elements', + 'update-success' => 'Slider-Eintrag wurde erfolgreich aktualisiert', + 'update-fail' => 'Slider kann nicht aktualisiert werden', + 'delete-success' => 'Der letzte Slider kann nicht gelöscht werden', + 'delete-fail' => 'Slider erfolgreich gelöscht', + ], + 'tax-categories' => + [ + 'title' => 'Steuerkategorien', + 'add-title' => 'Steuerkategorie erstellen', + 'edit-title' => 'Steuerkategorie bearbeiten', + 'save-btn-title' => 'Steuern-Kategorie speichern', + 'general' => 'Steuerkategorie', + 'select-channel' => 'Wählen Sie einen Kanal', + 'name' => 'Name', + 'code' => 'Code', + 'description' => 'Beschreibung', 'select-taxrates' => 'Wählen Sie die Steuersätze', - 'edit' => - array ( - 'title' => 'Steuerkategorie bearbeiten', + 'edit' => + [ + 'title' => 'Steuerkategorie bearbeiten', 'edit-button-title' => 'Steuerkategorie bearbeiten', - ), - 'create-success' => 'Neue Steuerkategorie Angelegt', - 'create-error' => 'Fehler Bei Der Erstellung Der Steuerkategorie', - 'update-success' => 'Erfolgreich Aktualisiert, Steuerkategorie', - 'update-error' => 'Fehler Beim Update Der Steuerkategorie', - 'atleast-one' => 'Nicht Löschen Sie Die Letzte Steuerart', - 'delete' => 'Steuer Kategorie Wurde Erfolgreich Gelöscht', - ), - 'tax-rates' => - array ( - 'title' => 'Steuersätze', - 'add-title' => 'Steuersatz erstellen', - 'edit-title' => 'Steuersatz bearbeiten', + ], + 'create-success' => 'Neue Steuerkategorie Angelegt', + 'create-error' => 'Fehler Bei Der Erstellung Der Steuerkategorie', + 'update-success' => 'Erfolgreich Aktualisiert, Steuerkategorie', + 'update-error' => 'Fehler Beim Update Der Steuerkategorie', + 'atleast-one' => 'Nicht Löschen Sie Die Letzte Steuerart', + 'delete' => 'Steuer Kategorie Wurde Erfolgreich Gelöscht', + ], + 'tax-rates' => + [ + 'title' => 'Steuersätze', + 'add-title' => 'Steuersatz erstellen', + 'edit-title' => 'Steuersatz bearbeiten', 'save-btn-title' => 'Steuersatz speichern', - 'general' => 'Steuersatz', - 'identifier' => 'Bezeichner', - 'is_zip' => 'Postleitzahlen Reichweite aktivieren', - 'zip_from' => 'Postleitzahl von', - 'zip_to' => 'Postleitzahl bis', - 'state' => 'Staat', - 'select-state' => 'Wählen Sie eine Region, ein Bundesland oder eine Provinz aus.', - 'country' => 'Land', - 'tax_rate' => 'Rate', - 'edit' => - array ( - 'title' => 'Steuersatz bearbeiten', + 'general' => 'Steuersatz', + 'identifier' => 'Bezeichner', + 'is_zip' => 'Postleitzahlen Reichweite aktivieren', + 'zip_from' => 'Postleitzahl von', + 'zip_to' => 'Postleitzahl bis', + 'state' => 'Staat', + 'select-state' => 'Wählen Sie eine Region, ein Bundesland oder eine Provinz aus.', + 'country' => 'Land', + 'tax_rate' => 'Rate', + 'edit' => + [ + 'title' => 'Steuersatz bearbeiten', 'edit-button-title' => 'Steuersatz bearbeiten', - ), - 'zip_code' => 'Postleitzahl', + ], + 'zip_code' => 'Postleitzahl', 'create-success' => 'Steuersatz erfolgreich erstellt', - 'create-error' => 'Steuersatz kann nicht erstellt werden', + 'create-error' => 'Steuersatz kann nicht erstellt werden', 'update-success' => 'Steuersatz erfolgreich aktualisiert', - 'update-error' => 'Fehler! Steuersatz Kann nicht aktualisiert werden', - 'delete' => 'Steuersatz erfolgreich gelöscht', - 'atleast-one' => 'Letzter Steuersatz kann nicht gelöscht werden', - ), - 'development' => - array ( + 'update-error' => 'Fehler! Steuersatz Kann nicht aktualisiert werden', + 'delete' => 'Steuersatz erfolgreich gelöscht', + 'atleast-one' => 'Letzter Steuersatz kann nicht gelöscht werden', + ], + 'development' => + [ 'title' => 'Entwicklung', - ), - ), - 'customers' => - array ( - 'groups' => - array ( - 'add-title' => 'Gruppe hinzufügen', - 'edit-title' => 'Gruppe bearbeiten', - 'save-btn-title' => 'Gruppe speichern', - 'title' => 'Gruppen', - 'code' => 'Code', - 'name' => 'Name', + ], + ], + 'customers' => + [ + 'groups' => + [ + 'add-title' => 'Gruppe hinzufügen', + 'edit-title' => 'Gruppe bearbeiten', + 'save-btn-title' => 'Gruppe speichern', + 'title' => 'Gruppen', + 'code' => 'Code', + 'name' => 'Name', 'is_user_defined' => 'Benutzer definiert', - 'yes' => 'Ja', - ), - 'addresses' => - array ( - 'title' => ':customer_name\'s Adressen-Liste', - 'vat_id' => 'Umsatzsteuer-ID', - 'create-title' => 'Kunden-Adresse erstellen', - 'edit-title' => 'Kunden-Adresse bearbeiten', - 'title-orders' => ':customer_name Auftragsliste', - 'address-list' => 'Adressliste', - 'order-list' => 'Bestellliste', - 'address-id' => 'Adresse-ID', - 'address-1' => 'Adresse 1', - 'city' => 'Stadt', - 'state-name' => 'Staat', - 'country-name' => 'Land', - 'postcode' => 'Postleitzahl', - 'default-address' => 'Standard-Adresse', - 'yes' => 'Ja', - 'not-approved' => 'Nicht zugelassen', - 'no' => 'Nein', - 'dash' => '-', - 'delete' => 'Löschen', - 'create-btn-title' => 'Adresse hinzufügen', - 'save-btn-title' => 'Adresse speichern', - 'general' => 'Allgemein', - 'success-create' => 'Erfolg: Kunden-Adresse erstellt wurde.', - 'success-update' => 'Erfolg: Kunden-Adresse erfolgreich aktualisiert.', - 'success-delete' => 'Erfolg: Kunden-Adresse erfolgreich gelöscht.', + 'yes' => 'Ja', + ], + 'addresses' => + [ + 'title' => ':customer_name\'s Adressen-Liste', + 'vat_id' => 'Umsatzsteuer-ID', + 'create-title' => 'Kunden-Adresse erstellen', + 'edit-title' => 'Kunden-Adresse bearbeiten', + 'title-orders' => ':customer_name Auftragsliste', + 'address-list' => 'Adressliste', + 'order-list' => 'Bestellliste', + 'address-id' => 'Adresse-ID', + 'address-1' => 'Adresse 1', + 'city' => 'Stadt', + 'state-name' => 'Staat', + 'country-name' => 'Land', + 'postcode' => 'Postleitzahl', + 'default-address' => 'Standard-Adresse', + 'yes' => 'Ja', + 'not-approved' => 'Nicht zugelassen', + 'no' => 'Nein', + 'dash' => '-', + 'delete' => 'Löschen', + 'create-btn-title' => 'Adresse hinzufügen', + 'save-btn-title' => 'Adresse speichern', + 'general' => 'Allgemein', + 'success-create' => 'Erfolg: Kunden-Adresse erstellt wurde.', + 'success-update' => 'Erfolg: Kunden-Adresse erfolgreich aktualisiert.', + 'success-delete' => 'Erfolg: Kunden-Adresse erfolgreich gelöscht.', 'success-mass-delete' => 'Erfolg: Die ausgewählten Adressen wurden erfolgreich gelöscht.', - 'error-create' => 'Fehler: Kunde-Adresse nicht erstellt.', - ), - 'note' => - array ( - 'title' => 'Notiz hinzufügen', - 'save-note' => 'Notiz speichern', + 'error-create' => 'Fehler: Kunde-Adresse nicht erstellt.', + ], + 'note' => + [ + 'title' => 'Notiz hinzufügen', + 'save-note' => 'Notiz speichern', 'enter-note' => 'Hinweis eingeben', 'help-title' => 'Notiz zu diesem Kunden hinzufügen', - ), - 'customers' => - array ( - 'add-title' => 'Kunden hinzufügen', - 'edit-title' => 'Kunde bearbeiten', - 'title' => 'Kunden', - 'first_name' => 'Vorname', - 'last_name' => 'Nachname', - 'gender' => 'Geschlecht', - 'email' => 'E-Mail', - 'date_of_birth' => 'Geburtsdatum', - 'phone' => 'Telefon', - 'customer_group' => 'Kundengruppe', - 'save-btn-title' => 'Kunde speichern', - 'channel_name' => 'Kanalname', - 'state' => 'Staat', - 'select-state' => 'Wählen Sie eine Region, ein Bundesland, oder eine Provinz aus.', - 'country' => 'Land', - 'other' => 'Andere', - 'male' => 'Männlich', - 'female' => 'Weiblich', - 'group-default' => 'Die Standardgruppe kann nicht gelöscht werden.', - 'edit-help-title' => 'Kunde bearbeiten', - 'delete-help-title' => 'Kunde löschen', - 'addresses' => 'Adressen', + ], + 'customers' => + [ + 'add-title' => 'Kunden hinzufügen', + 'edit-title' => 'Kunde bearbeiten', + 'title' => 'Kunden', + 'first_name' => 'Vorname', + 'last_name' => 'Nachname', + 'gender' => 'Geschlecht', + 'email' => 'E-Mail', + 'date_of_birth' => 'Geburtsdatum', + 'phone' => 'Telefon', + 'customer_group' => 'Kundengruppe', + 'save-btn-title' => 'Kunde speichern', + 'channel_name' => 'Kanalname', + 'state' => 'Staat', + 'select-state' => 'Wählen Sie eine Region, ein Bundesland, oder eine Provinz aus.', + 'country' => 'Land', + 'other' => 'Andere', + 'male' => 'Männlich', + 'female' => 'Weiblich', + 'group-default' => 'Die Standardgruppe kann nicht gelöscht werden.', + 'edit-help-title' => 'Kunde bearbeiten', + 'delete-help-title' => 'Kunde löschen', + 'addresses' => 'Adressen', 'mass-destroy-success' => 'Kunden erfolgreich gelöscht', - 'mass-update-success' => 'Kunden erfolgreich aktualisiert', - 'status' => 'Status', - 'active' => 'Aktiv', - 'inactive' => 'Inaktiv', - ), - 'reviews' => - array ( - 'title' => 'Bewertungen', - 'edit-title' => 'Bewertung bearbeiten', - 'rating' => 'Bewertung', - 'status' => 'Status', - 'comment' => 'Kommentar', - 'pending' => 'Ausstehend', - 'approved' => 'Genehmigen', + 'mass-update-success' => 'Kunden erfolgreich aktualisiert', + 'status' => 'Status', + 'active' => 'Aktiv', + 'inactive' => 'Inaktiv', + ], + 'reviews' => + [ + 'title' => 'Bewertungen', + 'edit-title' => 'Bewertung bearbeiten', + 'rating' => 'Bewertung', + 'status' => 'Status', + 'comment' => 'Kommentar', + 'pending' => 'Ausstehend', + 'approved' => 'Genehmigen', 'disapproved' => 'Missbilligen', - ), + ], 'subscribers' => - array ( - 'title' => 'Newsletter-Abonnenten', - 'title-edit' => 'Newsletter-Abonnenten bearbeiten', - 'email' => 'E-Mail', - 'is_subscribed' => 'Abonniert', + [ + 'title' => 'Newsletter-Abonnenten', + 'title-edit' => 'Newsletter-Abonnenten bearbeiten', + 'email' => 'E-Mail', + 'is_subscribed' => 'Abonniert', 'edit-btn-title' => 'Abonnenten bearbeiten', 'update-success' => 'Der Abonnent wurde erfolgreich aktualisiert', - 'update-failed' => 'Fehler! Sie können den Abonnenten nicht kündigen', - 'delete' => 'Der Abonnent wurde erfolgreich gelöscht', - 'delete-failed' => 'Fehler! Abonnenten können nicht gelöscht werden', - ), - ), - 'promotions' => - array ( - 'cart-rules' => - array ( - 'title' => 'Warenkorbregeln', - 'add-title' => 'Warenkorbregel hinzufügen', - 'edit-title' => 'Warenkorbregel bearbeiten', - 'save-btn-title' => 'Warenkorbregel speichern', - 'rule-information' => 'Regelinformationen', - 'name' => 'Name', - 'description' => 'Beschreibung', - 'status' => 'Status', - 'is-active' => 'Warenkorbregel ist aktiv', - 'channels' => 'Kanäle', - 'customer-groups' => 'Kundengruppen', - 'coupon-type' => 'Gutscheintyp', - 'no-coupon' => 'Ohne Gutschein', - 'specific-coupon' => 'Gutscheintyp', - 'auto-generate-coupon' => 'Gutschein automatisch generieren', - 'no' => 'Nein', + 'update-failed' => 'Fehler! Sie können den Abonnenten nicht kündigen', + 'delete' => 'Der Abonnent wurde erfolgreich gelöscht', + 'delete-failed' => 'Fehler! Abonnenten können nicht gelöscht werden', + ], + ], + 'promotions' => + [ + 'cart-rules' => + [ + 'title' => 'Warenkorbregeln', + 'add-title' => 'Warenkorbregel hinzufügen', + 'edit-title' => 'Warenkorbregel bearbeiten', + 'save-btn-title' => 'Warenkorbregel speichern', + 'rule-information' => 'Regelinformationen', + 'name' => 'Name', + 'description' => 'Beschreibung', + 'status' => 'Status', + 'is-active' => 'Warenkorbregel ist aktiv', + 'channels' => 'Kanäle', + 'customer-groups' => 'Kundengruppen', + 'coupon-type' => 'Gutscheintyp', + 'no-coupon' => 'Ohne Gutschein', + 'specific-coupon' => 'Gutscheintyp', + 'auto-generate-coupon' => 'Gutschein automatisch generieren', + 'no' => 'Nein', 'yes' => 'Ja', 'coupon-code' => 'Gutscheincode', 'uses-per-coupon' => 'Verwendungen pro Gutschein', @@ -1050,47 +1050,47 @@ return array( 'buy-x-get-y-free' => 'Kaufen Sie X, erhalten Sie Y kostenfrei', 'discount-amount' => 'Rabattbetrag', 'discount-quantity' => 'Maximale Anzahl reduzierter Artikel', - 'discount-step' => 'Kaufe Sie Menge X', - 'free-shipping' => 'Kostenloser Versand', - 'apply-to-shipping' => 'Auf den Versand anwenden', - 'coupon-codes' => 'Gutschein-Codes', - 'coupon-qty' => 'Gutschein Menge', - 'code-length' => 'Code-Länge', - 'code-format' => 'Code-Format', - 'alphanumeric' => 'Alphanumerisch', - 'alphabetical' => 'Alphabetisch', - 'numeric' => 'Numerisch', - 'code-prefix' => 'Code-Präfix', - 'code-suffix' => 'Code Suffix', - 'generate' => 'Generieren', + 'discount-step' => 'Kaufe Sie Menge X', + 'free-shipping' => 'Kostenloser Versand', + 'apply-to-shipping' => 'Auf den Versand anwenden', + 'coupon-codes' => 'Gutschein-Codes', + 'coupon-qty' => 'Gutschein Menge', + 'code-length' => 'Code-Länge', + 'code-format' => 'Code-Format', + 'alphanumeric' => 'Alphanumerisch', + 'alphabetical' => 'Alphabetisch', + 'numeric' => 'Numerisch', + 'code-prefix' => 'Code-Präfix', + 'code-suffix' => 'Code Suffix', + 'generate' => 'Generieren', 'cart-rule-not-defind-error' => 'Warenkorb-Regel ist nicht definiert', - 'mass-delete-success' => 'Alle ausgewählten Gutscheine wurden erfolgreich gelöscht.', - 'end-other-rules' => 'Ende Andere Regeln', - 'children-categories' => 'Kategorien (Nur Kinder)', - 'parent-categories' => 'Kategorien (Nur Eltern)', - 'categories' => 'Kategorien', - 'attribute_family' => 'Attributgruppe', - ), + 'mass-delete-success' => 'Alle ausgewählten Gutscheine wurden erfolgreich gelöscht.', + 'end-other-rules' => 'Ende Andere Regeln', + 'children-categories' => 'Kategorien (Nur Kinder)', + 'parent-categories' => 'Kategorien (Nur Eltern)', + 'categories' => 'Kategorien', + 'attribute_family' => 'Attributgruppe', + ], 'catalog-rules' => - array ( - 'title' => 'Katalogregeln', - 'add-title' => 'Katalogregel hinzufügen', - 'edit-title' => 'Katalogregel bearbeiten', - 'save-btn-title' => 'Katalogregel speichern', - 'rule-information' => 'Regeliformationen', - 'name' => 'Name', - 'description' => 'Beschreibung', - 'status' => 'Status', - 'is-active' => 'Katalogregel ist aktiv', - 'channels' => 'Kanäle', - 'customer-groups' => 'Kundengruppen', - 'no' => 'Nein', - 'yes' => 'Ja', - 'from' => 'Von', - 'to' => 'An', - 'priority' => 'Priorität', - 'conditions' => 'Bedingungen', - 'condition-type' => 'Bedingungen Typ', + [ + 'title' => 'Katalogregeln', + 'add-title' => 'Katalogregel hinzufügen', + 'edit-title' => 'Katalogregel bearbeiten', + 'save-btn-title' => 'Katalogregel speichern', + 'rule-information' => 'Regeliformationen', + 'name' => 'Name', + 'description' => 'Beschreibung', + 'status' => 'Status', + 'is-active' => 'Katalogregel ist aktiv', + 'channels' => 'Kanäle', + 'customer-groups' => 'Kundengruppen', + 'no' => 'Nein', + 'yes' => 'Ja', + 'from' => 'Von', + 'to' => 'An', + 'priority' => 'Priorität', + 'conditions' => 'Bedingungen', + 'condition-type' => 'Bedingungen Typ', 'all-conditions-true' => 'Alle Bedingungen sind erfüllt', 'any-condition-true' => 'Jede Bedingung ist wahr', 'add-condition' => 'Bedingung hinzufügen', @@ -1098,181 +1098,183 @@ return array( 'product-attribute' => 'Produkt-Attribut', 'attribute-name-children-only' => ':attribute_name (Nur Kinder)', 'attribute-name-parent-only' => ':attribute_name (Nur Eltern)', - 'is-equal-to' => 'Gleich', - 'is-not-equal-to' => 'Ist nicht gleich', - 'equals-or-greater-than' => 'Gleich oder größer als', - 'equals-or-less-than' => 'Gleich oder weniger als', - 'greater-than' => 'Größer als', - 'less-than' => 'Weniger als', - 'contain' => 'Enthalten', - 'contains' => 'Enthält', - 'does-not-contain' => 'Nicht enthalten', - 'actions' => 'Aktionen', - 'action-type' => 'Aktion Typ', + 'is-equal-to' => 'Gleich', + 'is-not-equal-to' => 'Ist nicht gleich', + 'equals-or-greater-than' => 'Gleich oder größer als', + 'equals-or-less-than' => 'Gleich oder weniger als', + 'greater-than' => 'Größer als', + 'less-than' => 'Weniger als', + 'contain' => 'Enthalten', + 'contains' => 'Enthält', + 'does-not-contain' => 'Nicht enthalten', + 'actions' => 'Aktionen', + 'action-type' => 'Aktion Typ', 'percentage-product-price' => 'Prozentsatz des Produktpreises', - 'fixed-amount' => 'Fester Betrag', - 'fixed-amount-whole-cart' => 'Fester Betrag für gesamten Warenkob', - 'buy-x-get-y-free' => 'Kaufen Sie X, erhalten Sie Y kostenfrei', - 'discount-amount' => 'Rabatt-Betrag', - 'mass-delete-success' => 'Alle ausgewählten Gutscheine wurden erfolgreich gelöscht.', - 'end-other-rules' => 'Ende Andere Regeln', - 'categories' => 'Kategorien', - 'attribute_family' => 'Attributgruppe', - ), - ), - 'error' => - array ( - 'go-to-home' => 'HOME ÖFFNEN', + 'fixed-amount' => 'Fester Betrag', + 'fixed-amount-whole-cart' => 'Fester Betrag für gesamten Warenkob', + 'buy-x-get-y-free' => 'Kaufen Sie X, erhalten Sie Y kostenfrei', + 'discount-amount' => 'Rabatt-Betrag', + 'mass-delete-success' => 'Alle ausgewählten Gutscheine wurden erfolgreich gelöscht.', + 'end-other-rules' => 'Ende Andere Regeln', + 'categories' => 'Kategorien', + 'attribute_family' => 'Attributgruppe', + ], + ], + 'error' => + [ + 'go-to-home' => 'HOME ÖFFNEN', 'in-maitainace' => 'In Bearbeitung', - 'right-back' => 'Gleich wieder zurück', - 404 => - array ( + 'right-back' => 'Gleich wieder zurück', + 404 => + [ 'page-title' => '404-Seite nicht gefunden', - 'name' => '404', - 'title' => 'Seite nicht gefunden', - 'message' => 'Die gesuchte Seite existiert nicht oder wurde verschoben. Navigieren Sie mit dem Seitenmenü.', - ), - 403 => - array ( + 'name' => '404', + 'title' => 'Seite nicht gefunden', + 'message' => 'Die gesuchte Seite existiert nicht oder wurde verschoben. Navigieren Sie mit dem Seitenmenü.', + ], + 403 => + [ 'page-title' => '403 Verboten-Fehler', - 'name' => '403', - 'title' => 'Verboten-Fehler', - 'message' => 'Sie haben keine Berechtigung um auf diese Seite zuzugreifen.', - ), - 500 => - array ( + 'name' => '403', + 'title' => 'Verboten-Fehler', + 'message' => 'Sie haben keine Berechtigung um auf diese Seite zuzugreifen.', + ], + 500 => + [ 'page-title' => '500 Interner Serverfehler', - 'name' => '500', - 'title' => 'Interner Serverfehler', - 'message' => 'Der Server hat einen internen Fehler.', - ), - 401 => - array ( + 'name' => '500', + 'title' => 'Interner Serverfehler', + 'message' => 'Der Server hat einen internen Fehler.', + ], + 401 => + [ 'page-title' => '401 Unauthorisiert', - 'name' => '401', - 'title' => 'Unauthorisiert', - 'message' => 'Die Anforderung wurde nicht angewendet, da keine gültigen Authentifizierungsdaten für die Zielressource vorhanden sind.', - ), - ), - 'export' => - array ( - 'export' => 'Export', - 'import' => 'Import', - 'format' => 'Wählen Sie ein Format', - 'download' => 'Download', - 'upload' => 'Hochladen', - 'csv' => 'CSV', - 'xls' => 'XLS', - 'file' => 'Datei', - 'upload-error' => 'Die Datei muss von folgendem Typ sein: xls, xlsx, csv.', - 'duplicate-error' => 'Bezeichner müssen eindeutig sein, doppelte Bezeichner :identifier in Zeile :position.', + 'name' => '401', + 'title' => 'Unauthorisiert', + 'message' => 'Die Anforderung wurde nicht angewendet, da keine gültigen Authentifizierungsdaten für die Zielressource vorhanden sind.', + ], + ], + 'export' => + [ + 'export' => 'Export', + 'import' => 'Import', + 'format' => 'Wählen Sie ein Format', + 'download' => 'Download', + 'upload' => 'Hochladen', + 'csv' => 'CSV', + 'xls' => 'XLS', + 'file' => 'Datei', + 'upload-error' => 'Die Datei muss von folgendem Typ sein: xls, xlsx, csv.', + 'duplicate-error' => 'Bezeichner müssen eindeutig sein, doppelte Bezeichner :identifier in Zeile :position.', 'enough-row-error' => 'die Datei hat nicht genug Zeilen', - 'allowed-type' => 'Erlaubter Typ :', - 'file-type' => 'csv, xls, xlsx.', - 'no-records' => 'Nichts zu exportieren', - 'illegal-format' => 'Fehler! Diese Art von Format wird entweder nicht unterstützt oder ist unzulässig', - ), - 'cms' => - array ( + 'allowed-type' => 'Erlaubter Typ :', + 'file-type' => 'csv, xls, xlsx.', + 'no-records' => 'Nichts zu exportieren', + 'illegal-format' => 'Fehler! Diese Art von Format wird entweder nicht unterstützt oder ist unzulässig', + ], + 'cms' => + [ 'pages' => - array ( - 'general' => 'Allgemein', - 'seo' => 'SEO', - 'pages' => 'Seiten', - 'title' => 'Seiten', - 'add-title' => 'Seite hinzufügen', - 'content' => 'Inhalt', - 'url-key' => 'URL-Schlüssel', - 'channel' => 'Kanäle', - 'locale' => 'Sprachen', + [ + 'general' => 'Allgemein', + 'seo' => 'SEO', + 'pages' => 'Seiten', + 'title' => 'Seiten', + 'add-title' => 'Seite hinzufügen', + 'content' => 'Inhalt', + 'url-key' => 'URL-Schlüssel', + 'channel' => 'Kanäle', + 'locale' => 'Sprachen', 'create-btn-title' => 'Seite speichern', - 'edit-title' => 'Seite bearbeiten', - 'edit-btn-title' => 'Seite speichern', - 'create-success' => 'Seite erfolgreich erstellt', - 'create-partial' => 'Einige der angeforderten Seiten sind bereits vorhanden', - 'create-failure' => 'Alle angeforderten Seiten sind bereits vorhanden', - 'update-success' => 'Seite erfolgreich aktualisiert', - 'update-failure' => 'Die Seite kann nicht aktualisiert werden', - 'page-title' => 'Titel der Seite', - 'layout' => 'Layout', - 'meta_keywords' => 'Meta-Schlüsselworte', + 'edit-title' => 'Seite bearbeiten', + 'edit-btn-title' => 'Seite speichern', + 'create-success' => 'Seite erfolgreich erstellt', + 'create-partial' => 'Einige der angeforderten Seiten sind bereits vorhanden', + 'create-failure' => 'Alle angeforderten Seiten sind bereits vorhanden', + 'update-success' => 'Seite erfolgreich aktualisiert', + 'update-failure' => 'Die Seite kann nicht aktualisiert werden', + 'page-title' => 'Titel der Seite', + 'layout' => 'Layout', + 'meta_keywords' => 'Meta-Schlüsselworte', 'meta_description' => 'Meta-Beschreibung', - 'meta_title' => 'Meta Titel', - 'delete-success' => 'CMS-Seite erfolgreich gelöscht', - 'delete-failure' => 'CMS-Seite kann nicht gelöscht werden', - 'preview' => 'Vorschau', - 'one-col' => '
Use class: "static-container one-column" for one column layout.
', - 'two-col' => '
Use class: "static-container two-column" for two column layout.
', - 'three-col' => '
Use class: "static-container three-column" for three column layout.
', - 'helper-classes' => 'Helfer-Klassen', - ), - ), - 'response' => - array ( - 'being-used' => 'Diese Ressource :name wird verwendet in :source', - 'cannot-delete-default' => 'Der Standardkanal kann nicht gelöscht werden', - 'create-success' => ':name erfolgreich erstellt.', - 'update-success' => ':name erfolgreich aktualisiert.', - 'delete-success' => ':name erfolgreich gelöscht.', - 'delete-failed' => 'Fehler beim löschen von :name.', - 'last-delete-error' => 'Zumindest ein :name ist erforderlich.', - 'user-define-error' => 'System :name kann nicht gelöscht werden', - 'attribute-error' => ':name wird in konfigurierbaren Produkten verwendet.', - 'attribute-product-error' => ':name wird in Produkten verwendet.', - 'customer-associate' => ':name können nicht gelöscht werden, weil Kunden dieser Gruppe zugeordnet sind.', - 'currency-delete-error' => 'Diese Währung ist als Kanalbasiswährung festgelegt und kann daher nicht gelöscht werden.', - 'upload-success' => ':name erfolgreich hochgeladen.', - 'delete-category-root' => 'Die Root-Kategorie kann nicht gelöscht werden', - 'create-root-failure' => 'Kategorie mit dem Namen Root ist bereits vorhanden', - 'cancel-success' => ':name erfolgreich abgebrochen.', - 'cancel-error' => ':name können nicht storniert werden.', - 'already-taken' => 'Der :name wird bereits verwendet.', - 'order-pending' => 'Konto kann nicht gelöscht werden, da einige Bestellungen ausstehen oder verarbeitet werden.', - ), - 'footer' => - array ( + 'meta_title' => 'Meta Titel', + 'delete-success' => 'CMS-Seite erfolgreich gelöscht', + 'delete-failure' => 'CMS-Seite kann nicht gelöscht werden', + 'preview' => 'Vorschau', + 'one-col' => '
Use class: "static-container one-column" for one column layout.
', + 'two-col' => '
Use class: "static-container two-column" for two column layout.
', + 'three-col' => '
Use class: "static-container three-column" for three column layout.
', + 'helper-classes' => 'Helfer-Klassen', + ], + ], + 'response' => + [ + 'being-used' => 'Diese Ressource :name wird verwendet in :source', + 'product-copied' => 'Das Produkt wurde kopiert', + 'booking-can-not-be-copied' => 'Booking Produkte 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.', + 'delete-success' => ':name erfolgreich gelöscht.', + 'delete-failed' => 'Fehler beim löschen von :name.', + 'last-delete-error' => 'Zumindest ein :name ist erforderlich.', + 'user-define-error' => 'System :name kann nicht gelöscht werden', + 'attribute-error' => ':name wird in konfigurierbaren Produkten verwendet.', + 'attribute-product-error' => ':name wird in Produkten verwendet.', + 'customer-associate' => ':name können nicht gelöscht werden, weil Kunden dieser Gruppe zugeordnet sind.', + 'currency-delete-error' => 'Diese Währung ist als Kanalbasiswährung festgelegt und kann daher nicht gelöscht werden.', + 'upload-success' => ':name erfolgreich hochgeladen.', + 'delete-category-root' => 'Die Root-Kategorie kann nicht gelöscht werden', + 'create-root-failure' => 'Kategorie mit dem Namen Root ist bereits vorhanden', + 'cancel-success' => ':name erfolgreich abgebrochen.', + 'cancel-error' => ':name können nicht storniert werden.', + 'already-taken' => 'Der :name wird bereits verwendet.', + 'order-pending' => 'Konto kann nicht gelöscht werden, da einige Bestellungen ausstehen oder verarbeitet werden.', + ], + 'footer' => + [ 'copy-right' => 'Powered by Bagisto, A Community Project by Webkul', - ), - 'admin' => - array ( + ], + 'admin' => + [ 'emails' => - array ( - 'email' => 'E-Mail', + [ + 'email' => 'E-Mail', 'notification_label' => 'Benachrichtigungen', - 'notifications' => - array ( - 'verification' => 'Senden von Bestätigungs-E-Mails', - 'registration' => 'Senden von Anmeldungs-E-Mails', - 'customer' => 'Senden von Kunden-E-Mails', - 'new-order' => 'Senden von Auftragsbestätigungs-E-Mails', - 'new-admin' => 'Senden von Admin Einladungs-E-Mails', - 'new-invoice' => 'Senden von Rechnungs-Bestätigungs-E-Mails', - 'new-refund' => 'Senden von Erstattungs-Benachrichtigungs-E-Mails', - 'new-shipment' => 'Senden von Versand-Benachrichtigungs-E-Mails', + 'notifications' => + [ + 'verification' => 'Senden von Bestätigungs-E-Mails', + 'registration' => 'Senden von Anmeldungs-E-Mails', + 'customer' => 'Senden von Kunden-E-Mails', + 'new-order' => 'Senden von Auftragsbestätigungs-E-Mails', + 'new-admin' => 'Senden von Admin Einladungs-E-Mails', + 'new-invoice' => 'Senden von Rechnungs-Bestätigungs-E-Mails', + 'new-refund' => 'Senden von Erstattungs-Benachrichtigungs-E-Mails', + 'new-shipment' => 'Senden von Versand-Benachrichtigungs-E-Mails', 'new-inventory-source' => 'Senden von Inventar-Quellen-E-Mail-Benachrichtigungen', - 'cancel-order' => 'Senden von Abbrechen E-Mails eines Bestellvorgangs', - ), - ), + 'cancel-order' => 'Senden von Abbrechen E-Mails eines Bestellvorgangs', + ], + ], 'system' => - array ( - 'catalog' => 'Katalog', - 'products' => 'Produkte', - 'guest-checkout' => 'Gastbestellungen', - 'allow-guest-checkout' => 'Gastbestellungen erlauben', - 'allow-guest-checkout-hint' => 'Hinweis: Wenn diese Option aktiviert ist, kann sie für jedes Produkt einzeln konfiguriert werden.', - 'review' => 'Überprüfen', - 'allow-guest-review' => 'Gastbewertungen erlauben', - 'inventory' => 'Inventar', - 'stock-options' => 'Inventaroptionen', - 'allow-backorders' => 'Nachbestellungen zulassen', - 'customer' => 'Kunden', - 'settings' => 'Einstellungen', - 'address' => 'Adresse', - 'street-lines' => 'Adresszeilen (Standard: 1)', - 'sales' => 'Vertrieb', - 'shipping-methods' => 'Versand-Methoden', - 'free-shipping' => 'Kostenloser Versand', - 'flate-rate-shipping' => 'Pauschale Versandkosten', + [ + 'catalog' => 'Katalog', + 'products' => 'Produkte', + 'guest-checkout' => 'Gastbestellungen', + 'allow-guest-checkout' => 'Gastbestellungen erlauben', + 'allow-guest-checkout-hint' => 'Hinweis: Wenn diese Option aktiviert ist, kann sie für jedes Produkt einzeln konfiguriert werden.', + 'review' => 'Überprüfen', + 'allow-guest-review' => 'Gastbewertungen erlauben', + 'inventory' => 'Inventar', + 'stock-options' => 'Inventaroptionen', + 'allow-backorders' => 'Nachbestellungen zulassen', + 'customer' => 'Kunden', + 'settings' => 'Einstellungen', + 'address' => 'Adresse', + 'street-lines' => 'Adresszeilen (Standard: 1)', + 'sales' => 'Vertrieb', + 'shipping-methods' => 'Versand-Methoden', + 'free-shipping' => 'Kostenloser Versand', + 'flate-rate-shipping' => 'Pauschale Versandkosten', 'shipping' => 'Versand', 'origin' => 'Herkunft', 'country' => 'Land', @@ -1306,26 +1308,26 @@ return array( 'email-sender-name' => 'E-Mail-Adresse des Absenders', 'shop-email-from' => 'E-Mail-Adresse des Shops (bei Bestellungen, etc.)', 'admin-name' => 'Name des Admins', - 'admin-email' => 'E-Mail-Adresse des Admins', - 'admin-page-limit' => 'Elemente pro Seite (Admin)', - 'design' => 'Design', - 'admin-logo' => 'Admin-Logo', - 'logo-image' => 'Logo-Bild', - 'credit-max' => 'Kunden Kredit Max', - 'credit-max-value' => 'Kredit Max-Wert', - 'use-credit-max' => 'Verwendung von Kredit-Max', - 'order-settings' => 'Bestelleinstellungen', - 'orderNumber' => 'Auftragsnummer Einstellungen', - 'order-number-prefix' => 'Auftragsnummer Präfix', - 'order-number-length' => 'Auftragsnummer Länge', - 'order-number-suffix' => 'Auftragsnummer Suffix', + 'admin-email' => 'E-Mail-Adresse des Admins', + 'admin-page-limit' => 'Elemente pro Seite (Admin)', + 'design' => 'Design', + 'admin-logo' => 'Admin-Logo', + 'logo-image' => 'Logo-Bild', + 'credit-max' => 'Kunden Kredit Max', + 'credit-max-value' => 'Kredit Max-Wert', + 'use-credit-max' => 'Verwendung von Kredit-Max', + 'order-settings' => 'Bestelleinstellungen', + 'orderNumber' => 'Auftragsnummer Einstellungen', + 'order-number-prefix' => 'Auftragsnummer Präfix', + 'order-number-length' => 'Auftragsnummer Länge', + 'order-number-suffix' => 'Auftragsnummer Suffix', 'order-number-generator-class' => 'Bestell nummern generator', - 'default' => 'Standard', - 'sandbox' => 'Sandbox', - 'all-channels' => 'Alle', - 'all-locales' => 'Alle', - 'invoice-slip-design' => 'Rechnungsdesign', - 'logo' => 'Logo', - ), - ), -); \ No newline at end of file + 'default' => 'Standard', + 'sandbox' => 'Sandbox', + 'all-channels' => 'Alle', + 'all-locales' => 'Alle', + 'invoice-slip-design' => 'Rechnungsdesign', + 'logo' => 'Logo', + ], + ], +]; \ No newline at end of file diff --git a/packages/Webkul/Admin/src/Resources/lang/en/app.php b/packages/Webkul/Admin/src/Resources/lang/en/app.php index 90dd8df36..76fcf8270 100755 --- a/packages/Webkul/Admin/src/Resources/lang/en/app.php +++ b/packages/Webkul/Admin/src/Resources/lang/en/app.php @@ -1202,17 +1202,19 @@ return [ ], 'response' => [ - 'being-used' => 'This resource :name is getting used in :source', - 'cannot-delete-default' => 'Cannot delete the default channel', - 'create-success' => ':name created successfully.', - 'update-success' => ':name updated successfully.', - 'delete-success' => ':name deleted successfully.', - 'delete-failed' => 'Error encountered while deleting :name.', - 'last-delete-error' => 'At least one :name is required.', - 'user-define-error' => 'Can not delete system :name', - 'attribute-error' => ':name is used in configurable products.', - 'attribute-product-error' => ':name is used in products.', - 'customer-associate' => ':name can not be deleted because customer is associated with this group.', + 'being-used' => 'This resource :name is getting used in :source', + 'product-copied' => 'The Product has been copied', + 'booking-can-not-be-copied' => 'Booking Products can not be copied .', + 'cannot-delete-default' => 'Cannot delete the default channel', + 'create-success' => ':name created successfully.', + 'update-success' => ':name updated successfully.', + 'delete-success' => ':name deleted successfully.', + 'delete-failed' => 'Error encountered while deleting :name.', + 'last-delete-error' => 'At least one :name is required.', + 'user-define-error' => 'Can not delete system :name', + 'attribute-error' => ':name is used in configurable products.', + 'attribute-product-error' => ':name is used in products.', + 'customer-associate' => ':name can not be deleted because customer is associated with this group.', 'currency-delete-error' => 'This currency is set as channel base currency so it can not be deleted.', 'upload-success' => ':name uploaded successfully.', 'delete-category-root' => 'Cannot delete the root category', diff --git a/packages/Webkul/Product/src/Http/Controllers/ProductController.php b/packages/Webkul/Product/src/Http/Controllers/ProductController.php index e70b4564d..e09df902f 100755 --- a/packages/Webkul/Product/src/Http/Controllers/ProductController.php +++ b/packages/Webkul/Product/src/Http/Controllers/ProductController.php @@ -249,6 +249,8 @@ class ProductController extends Controller { $copiedProduct = $this->productRepository->copy($productId); + session()->flash('success', trans('admin::app.response.product-copied')); + return redirect()->to(route('admin.catalog.products.edit', ['id' => $copiedProduct->id])); } diff --git a/packages/Webkul/Product/src/Models/Product.php b/packages/Webkul/Product/src/Models/Product.php index 7f92a4426..e5102d5d0 100755 --- a/packages/Webkul/Product/src/Models/Product.php +++ b/packages/Webkul/Product/src/Models/Product.php @@ -61,7 +61,8 @@ class Product extends Model implements ProductContract } /** - * Get the product variants that owns the product. + * Get the product flat entries that are associated with product. + * May be one for each locale and each channel. */ public function product_flats() { diff --git a/packages/Webkul/Product/src/Repositories/ProductRepository.php b/packages/Webkul/Product/src/Repositories/ProductRepository.php index 6ba6ea314..21aa1f5ed 100755 --- a/packages/Webkul/Product/src/Repositories/ProductRepository.php +++ b/packages/Webkul/Product/src/Repositories/ProductRepository.php @@ -2,6 +2,7 @@ namespace Webkul\Product\Repositories; +use Exception; use Illuminate\Support\Facades\DB; use Webkul\Product\Models\Product; use Illuminate\Pagination\Paginator; @@ -477,6 +478,10 @@ class ProductRepository extends Repository { $originalProduct = $this->loadOriginalProduct($sourceProductId); + if ($originalProduct->type === 'booking') { + throw new Exception(trans('admin::app.response.booking-can-not-be-copied')); + } + $copiedProduct = $this->persistCopiedProduct($originalProduct); $this->persistAttributeValues($originalProduct, $copiedProduct); @@ -656,5 +661,11 @@ class ProductRepository extends Repository $copiedProduct->images()->save($image); } } + + if (! isset($attributesToSkip['variants'])) { + foreach ($originalProduct->variants as $variant) { + $this->copy($variant); + } + } } } \ No newline at end of file From 85ac0872ba02240d3ec459e78fd1737f1dd6a197 Mon Sep 17 00:00:00 2001 From: Herbert Maschke Date: Mon, 3 Aug 2020 20:21:11 +0200 Subject: [PATCH 008/120] one more translation --- .../Admin/src/Resources/lang/ar/app.php | 33 ++++++++++--------- 1 file changed, 17 insertions(+), 16 deletions(-) diff --git a/packages/Webkul/Admin/src/Resources/lang/ar/app.php b/packages/Webkul/Admin/src/Resources/lang/ar/app.php index e8ffe9ae9..efa568db4 100644 --- a/packages/Webkul/Admin/src/Resources/lang/ar/app.php +++ b/packages/Webkul/Admin/src/Resources/lang/ar/app.php @@ -140,27 +140,28 @@ return [ 'datagrid' => [ 'mass-ops' => [ - 'method-error' => 'خطأ! تم اكتشاف طريقة خاطئة ، الرجاء التحقق من تشكيل حركة الكتلة', + 'method-error' => 'خطأ! تم اكتشاف طريقة خاطئة ، الرجاء التحقق من تشكيل حركة الكتلة', 'delete-success' => "تم حذف المورد بنجاح :Selected", 'partial-action' => 'ولم تنفذ بعض الإجراءات بسبب القيود المفروضة على النظام :resource', 'update-success' => "تم تحديث المورد بنجاح :Selected", - 'no-resource' => 'المورد المقدم غير كاف للعمل' + 'no-resource' => 'المورد المقدم غير كاف للعمل', ], - 'id' => 'ID', - 'status' => 'الحالة', - 'code' => 'رمز', - 'admin-name' => 'اسم', - 'name' => 'اسم', - 'direction' => 'اتجاه', - 'fullname' => 'الاسم الكامل', - 'type' => 'النوع', - 'required' => 'مطلوب', - 'unique' => 'فريد', - 'per-locale' => 'على أساس اللغة', - 'per-channel' => 'قائم على القناة', - 'position' => 'موضع', - 'locale' => 'لغة', + 'id' => 'ID', + 'status' => 'الحالة', + 'code' => 'رمز', + 'admin-name' => 'اسم', + 'copy' => 'نسخ', + 'name' => 'اسم', + 'direction' => 'اتجاه', + 'fullname' => 'الاسم الكامل', + 'type' => 'النوع', + 'required' => 'مطلوب', + 'unique' => 'فريد', + 'per-locale' => 'على أساس اللغة', + 'per-channel' => 'قائم على القناة', + 'position' => 'موضع', + 'locale' => 'لغة', 'hostname' => 'اسم المضيف', 'email' => 'البريد الإلكتروني', 'group' => 'المجموعة', From 4fecc5011f4e4d2cc1352c942c80a3cb2baf3c7a Mon Sep 17 00:00:00 2001 From: Herbert Maschke Date: Mon, 3 Aug 2020 20:23:52 +0200 Subject: [PATCH 009/120] some more translations --- .../Admin/src/Resources/lang/it/app.php | 37 ++++++++++--------- .../Admin/src/Resources/lang/nl/app.php | 37 ++++++++++--------- 2 files changed, 38 insertions(+), 36 deletions(-) diff --git a/packages/Webkul/Admin/src/Resources/lang/it/app.php b/packages/Webkul/Admin/src/Resources/lang/it/app.php index 580ab92d2..fedd8f3ec 100644 --- a/packages/Webkul/Admin/src/Resources/lang/it/app.php +++ b/packages/Webkul/Admin/src/Resources/lang/it/app.php @@ -146,24 +146,25 @@ return [ 'no-resource' => 'The resource provided for insufficient for the action' ], - 'id' => 'ID', - 'status' => 'Stato', - 'code' => 'Codice', - 'admin-name' => 'Nome', - 'name' => 'Nome', - 'direction' => 'Direzione', - 'fullname' => 'Nome completo', - 'type' => 'Tipo', - 'required' => 'Richiesto', - 'unique' => 'Unico', - 'per-locale' => 'Basato su localizzazione', - 'per-channel' => 'Basato sul canale', - 'position' => 'Posizione', - 'locale' => 'Locale', - 'hostname' => 'Hostname', - 'email' => 'Email', - 'group' => 'Gruppo', - 'phone' => 'Telefono', + 'id' => 'ID', + 'status' => 'Stato', + 'code' => 'Codice', + 'admin-name' => 'Nome', + 'name' => 'Nome', + 'direction' => 'Direzione', + 'fullname' => 'Nome completo', + 'type' => 'Tipo', + 'copy' => 'Copia', + 'required' => 'Richiesto', + 'unique' => 'Unico', + 'per-locale' => 'Basato su localizzazione', + 'per-channel' => 'Basato sul canale', + 'position' => 'Posizione', + 'locale' => 'Locale', + 'hostname' => 'Hostname', + 'email' => 'Email', + 'group' => 'Gruppo', + 'phone' => 'Telefono', 'gender' => 'Sesso', 'title' => 'Titolo', 'layout' => 'Layout', diff --git a/packages/Webkul/Admin/src/Resources/lang/nl/app.php b/packages/Webkul/Admin/src/Resources/lang/nl/app.php index 3c67966f2..d1aae1efe 100644 --- a/packages/Webkul/Admin/src/Resources/lang/nl/app.php +++ b/packages/Webkul/Admin/src/Resources/lang/nl/app.php @@ -146,24 +146,25 @@ return [ 'no-resource' => 'The resource provided for insufficient for the action' ], - 'id' => 'ID', - 'status' => 'Status', - 'code' => 'Code', - 'admin-name' => 'Naam', - 'name' => 'Naam', - 'direction' => 'Richting', - 'fullname' => 'Volledige naam', - 'type' => 'Type', - 'required' => 'Verplicht', - 'unique' => 'Uniek', - 'per-locale' => 'Lokaal gebaseerd', - 'per-channel' => 'Kanaal gebaseerd', - 'position' => 'Position', - 'locale' => 'Locale', - 'hostname' => 'Hostnaam', - 'email' => 'Email', - 'group' => 'Groep', - 'phone' => 'Telefoon', + 'id' => 'ID', + 'status' => 'Status', + 'code' => 'Code', + 'admin-name' => 'Naam', + 'name' => 'Naam', + 'direction' => 'Richting', + 'fullname' => 'Volledige naam', + 'type' => 'Type', + 'copy' => 'kopiëren', + 'required' => 'Verplicht', + 'unique' => 'Uniek', + 'per-locale' => 'Lokaal gebaseerd', + 'per-channel' => 'Kanaal gebaseerd', + 'position' => 'Position', + 'locale' => 'Locale', + 'hostname' => 'Hostnaam', + 'email' => 'Email', + 'group' => 'Groep', + 'phone' => 'Telefoon', 'gender' => 'Geslacht', 'title' => 'Titel', 'layout' => 'Layout', From a9b79d7f4d7012a8f7deed9ee57ecdbaa69aa604 Mon Sep 17 00:00:00 2001 From: Herbert Maschke Date: Wed, 5 Aug 2020 08:26:01 +0200 Subject: [PATCH 010/120] improve error message that occurs when trying to copy an 'booking' product --- .../src/Http/Controllers/ProductController.php | 13 ++++++++++--- .../src/Repositories/ProductRepository.php | 17 ++++++----------- 2 files changed, 16 insertions(+), 14 deletions(-) diff --git a/packages/Webkul/Product/src/Http/Controllers/ProductController.php b/packages/Webkul/Product/src/Http/Controllers/ProductController.php index e09df902f..8fb1b3f32 100755 --- a/packages/Webkul/Product/src/Http/Controllers/ProductController.php +++ b/packages/Webkul/Product/src/Http/Controllers/ProductController.php @@ -242,12 +242,19 @@ class ProductController extends Controller } /** - * Copy a given Product. Do not copy the images. - * Always make the copy is inactive so the admin is able to configure it before setting it live. + * Copy a given Product. */ public function copy(int $productId) { - $copiedProduct = $this->productRepository->copy($productId); + $originalProduct = $this->productRepository->findOrFail($productId); + + if ($originalProduct->type === 'booking') { + session()->flash('error', trans('admin::app.response.booking-can-not-be-copied')); + + return redirect()->to(route('admin.catalog.products.index')); + } + + $copiedProduct = $this->productRepository->copy($originalProduct); session()->flash('success', trans('admin::app.response.product-copied')); diff --git a/packages/Webkul/Product/src/Repositories/ProductRepository.php b/packages/Webkul/Product/src/Repositories/ProductRepository.php index 21aa1f5ed..392675874 100755 --- a/packages/Webkul/Product/src/Repositories/ProductRepository.php +++ b/packages/Webkul/Product/src/Repositories/ProductRepository.php @@ -472,11 +472,13 @@ class ProductRepository extends Repository /** * Copy a product. Is usually called by the copy() function of the ProductController. * + * Always make the copy is inactive so the admin is able to configure it before setting it live. + * * @param int $sourceProductId the id of the product that should be copied */ - public function copy(int $sourceProductId): Product + public function copy(Product $originalProduct): Product { - $originalProduct = $this->loadOriginalProduct($sourceProductId); + $this->fillOriginalProduct($originalProduct); if ($originalProduct->type === 'booking') { throw new Exception(trans('admin::app.response.booking-can-not-be-copied')); @@ -529,21 +531,14 @@ class ProductRepository extends Repository return $query; } - /** - * @param int $sourceProductId - * - * @return mixed - */ - private function loadOriginalProduct(int $sourceProductId): Product + private function fillOriginalProduct(Product &$sourceProduct): void { - $originalProduct = $this - ->findOrFail($sourceProductId) + $sourceProduct ->load('attribute_family') ->load('categories') ->load('customer_group_prices') ->load('inventories') ->load('inventory_sources'); - return $originalProduct; } /** From f91533f47b563acd9fe5f6980be2a8babdc017a0 Mon Sep 17 00:00:00 2001 From: Herbert Maschke Date: Wed, 5 Aug 2020 10:52:13 +0200 Subject: [PATCH 011/120] add the ability to copy an configurable product --- .../products/accordians/variations.blade.php | 168 ++++++++++++------ .../Webkul/Product/src/Models/Product.php | 8 + .../src/Repositories/ProductRepository.php | 16 +- 3 files changed, 135 insertions(+), 57 deletions(-) diff --git a/packages/Webkul/Admin/src/Resources/views/catalog/products/accordians/variations.blade.php b/packages/Webkul/Admin/src/Resources/views/catalog/products/accordians/variations.blade.php index b596ff64d..e462c9099 100755 --- a/packages/Webkul/Admin/src/Resources/views/catalog/products/accordians/variations.blade.php +++ b/packages/Webkul/Admin/src/Resources/views/catalog/products/accordians/variations.blade.php @@ -4,12 +4,15 @@ .table th.price, .table th.weight { width: 100px; } + .table th.actions { width: 85px; } + .table td.actions .icon { margin-top: 8px; } + .table td.actions .icon.pencil-lg-icon { margin-right: 10px; } @@ -48,17 +51,31 @@ @parent From 38e7270ba9d05338ed360ee6e17cdc8202d736fd Mon Sep 17 00:00:00 2001 From: Shubham Mehrotra Date: Mon, 10 Aug 2020 19:46:59 +0530 Subject: [PATCH 029/120] #3486 --- .../Admin/src/DataGrids/ProductDataGrid.php | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/packages/Webkul/Admin/src/DataGrids/ProductDataGrid.php b/packages/Webkul/Admin/src/DataGrids/ProductDataGrid.php index 845acc865..c46bdf271 100644 --- a/packages/Webkul/Admin/src/DataGrids/ProductDataGrid.php +++ b/packages/Webkul/Admin/src/DataGrids/ProductDataGrid.php @@ -51,7 +51,7 @@ class ProductDataGrid extends DataGrid ->select( 'product_flat.locale', 'product_flat.channel', - 'product_flat.product_id', + 'product_flat.product_id as product_id', 'products.sku as product_sku', 'product_flat.name as product_name', 'products.type as product_type', @@ -61,9 +61,17 @@ class ProductDataGrid extends DataGrid DB::raw('SUM(DISTINCT ' . DB::getTablePrefix() . 'product_inventories.qty) as quantity') ); - $queryBuilder->groupBy('product_flat.product_id', 'product_flat.locale', 'product_flat.channel'); - $queryBuilder->where('locale', $this->locale !== 'all' ? $this->locale : 'en'); - $queryBuilder->where('channel', $this->channel !== 'all' ? $this->channel : 'default'); + if ($this->locale !== 'all') { + $queryBuilder->where('product_flat.locale', $this->locale); + } + + if ($this->channel !== 'all') { + $queryBuilder->where('product_flat.channel', $this->channel); + } + + $queryBuilder->groupBy('product_flat.product_id'); + $queryBuilder->having('locale', $this->locale !== 'all' ? $this->locale : 'en'); + $queryBuilder->having('channel', $this->channel !== 'all' ? $this->channel : 'default'); $this->addFilter('product_id', 'product_flat.product_id'); $this->addFilter('product_name', 'product_flat.name'); From 837c1e46a7b16fe0ff565e04dceb2de357f51c06 Mon Sep 17 00:00:00 2001 From: Devansh Date: Mon, 10 Aug 2020 19:57:36 +0530 Subject: [PATCH 030/120] Refund Exception Fixed --- .../views/sales/refunds/create.blade.php | 56 ++++++++++--------- 1 file changed, 30 insertions(+), 26 deletions(-) diff --git a/packages/Webkul/Admin/src/Resources/views/sales/refunds/create.blade.php b/packages/Webkul/Admin/src/Resources/views/sales/refunds/create.blade.php index b1bd7f539..e7d5d4f31 100755 --- a/packages/Webkul/Admin/src/Resources/views/sales/refunds/create.blade.php +++ b/packages/Webkul/Admin/src/Resources/views/sales/refunds/create.blade.php @@ -110,37 +110,41 @@ - -
+ @if ($order->billing_address || $order->shipping_address) + +
-
-
- {{ __('admin::app.sales.orders.billing-address') }} -
+ @if ($order->billing_address) +
+
+ {{ __('admin::app.sales.orders.billing-address') }} +
-
+
- @include ('admin::sales.address', ['address' => $order->billing_address]) + @include ('admin::sales.address', ['address' => $order->billing_address]) + +
+
+ @endif + + @if ($order->shipping_address) +
+
+ {{ __('admin::app.sales.orders.shipping-address') }} +
+ +
+ + @include ('admin::sales.address', ['address' => $order->shipping_address]) + +
+
+ @endif -
- - @if ($order->shipping_address) -
-
- {{ __('admin::app.sales.orders.shipping-address') }} -
- -
- - @include ('admin::sales.address', ['address' => $order->shipping_address]) - -
-
- @endif - -
-
+ + @endif
From 44a68c8dbb3cd9cbf9be9a034355fd4dc87c3896 Mon Sep 17 00:00:00 2001 From: Akhtar Khan Date: Mon, 10 Aug 2020 20:14:18 +0530 Subject: [PATCH 031/120] issued fixed #3688 --- .../Shop/src/Resources/assets/sass/app.scss | 68 ++----------------- .../checkout/onepage/customer-info.blade.php | 2 +- .../views/checkout/onepage/payment.blade.php | 4 +- 3 files changed, 8 insertions(+), 66 deletions(-) diff --git a/packages/Webkul/Shop/src/Resources/assets/sass/app.scss b/packages/Webkul/Shop/src/Resources/assets/sass/app.scss index 8d797aee1..1741a16e8 100755 --- a/packages/Webkul/Shop/src/Resources/assets/sass/app.scss +++ b/packages/Webkul/Shop/src/Resources/assets/sass/app.scss @@ -815,7 +815,7 @@ section.slider-block { img { display: none; } - + input { display: none; } @@ -3648,8 +3648,6 @@ section.review { height: 130px; float: right; border-collapse: collapse; - left: 3px; - position: relative; tr { @@ -4282,15 +4280,11 @@ section.review { } .checkbox { - margin: 10px 0 0px 0px; + margin: 10px 0px 5px 5px; + } - .checkbox-view { - height: 16px !important; - width: 16px !important; - float: left; - margin-right: 135px!important; - position: absolute; - } + span.checkmark.payment { + left: 163px; } .radio { @@ -4307,10 +4301,6 @@ section.review { } } - span.checkmark.checkbox-icon { - right: 150px; - } - @media only screen and (max-width: 770px) { .checkout-process .col-main { padding-left: 0px; @@ -4580,52 +4570,4 @@ section.review { } } } -} - -//compare page -body { - overflow-x: hidden; -} - -.comparison-component { - width: 100%; - padding-top: 20px; -} - -.comparison-component > h1 { - display: inline-block; -} - -td { - padding: 15px; - min-width: 25px; - max-width: 250px; - line-height: 30px; - vertical-align: top; - word-break: break-word; -} - -.icon.remove-product { - top: 5px; - float: right; - cursor: pointer; - position: relative; - background-color: black; -} - -.action > div { - display: inline-block; -} -.cart-wish-wrap .btn.btn-lg { - padding: 5px 10px; -} -.cart-wish-wrap { - display: flex; -} -.white-cross-sm-icon { - width: 24px; - height:24px; -} -.add-to-wishlist { - margin-left: 15px; } \ No newline at end of file diff --git a/packages/Webkul/Shop/src/Resources/views/checkout/onepage/customer-info.blade.php b/packages/Webkul/Shop/src/Resources/views/checkout/onepage/customer-info.blade.php index db391b96f..40fbcba67 100755 --- a/packages/Webkul/Shop/src/Resources/views/checkout/onepage/customer-info.blade.php +++ b/packages/Webkul/Shop/src/Resources/views/checkout/onepage/customer-info.blade.php @@ -13,7 +13,7 @@
    diff --git a/packages/Webkul/Shop/src/Resources/views/checkout/onepage/payment.blade.php b/packages/Webkul/Shop/src/Resources/views/checkout/onepage/payment.blade.php index ac34652ba..ffb48c1ea 100755 --- a/packages/Webkul/Shop/src/Resources/views/checkout/onepage/payment.blade.php +++ b/packages/Webkul/Shop/src/Resources/views/checkout/onepage/payment.blade.php @@ -14,10 +14,10 @@
    -