Merge branch 'master' into api_current_user_issue
Master Merged
This commit is contained in:
commit
f8521b9a53
|
|
@ -21,12 +21,10 @@
|
|||
"astrotomic/laravel-translatable": "^11.0.0",
|
||||
"babenkoivan/elastic-scout-driver": "^1.1",
|
||||
"bagistobrasil/bagisto-product-social-share": "^0.1.2",
|
||||
"barryvdh/laravel-debugbar": "^3.1",
|
||||
"barryvdh/laravel-dompdf": "0.8.6",
|
||||
"doctrine/dbal": "2.9.2",
|
||||
"fideloper/proxy": "^4.2",
|
||||
"flynsarmy/db-blade-compiler": "^5.5",
|
||||
"fzaninotto/faker": "^1.9.1",
|
||||
"guzzlehttp/guzzle": "~6.3",
|
||||
"intervention/image": "^2.4",
|
||||
"intervention/imagecache": "^2.3",
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
||||
"This file is @generated automatically"
|
||||
],
|
||||
"content-hash": "3332479a65fc6c67057c2946a27fe95e",
|
||||
"content-hash": "b02e22c84c5b91a32e9d1f50e8d14b7f",
|
||||
"packages": [
|
||||
{
|
||||
"name": "algolia/algoliasearch-client-php",
|
||||
|
|
@ -342,74 +342,6 @@
|
|||
],
|
||||
"time": "2020-08-04T12:36:28+00:00"
|
||||
},
|
||||
{
|
||||
"name": "barryvdh/laravel-debugbar",
|
||||
"version": "v3.3.3",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/barryvdh/laravel-debugbar.git",
|
||||
"reference": "57f2219f6d9efe41ed1bc880d86701c52f261bf5"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/barryvdh/laravel-debugbar/zipball/57f2219f6d9efe41ed1bc880d86701c52f261bf5",
|
||||
"reference": "57f2219f6d9efe41ed1bc880d86701c52f261bf5",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"illuminate/routing": "^5.5|^6|^7",
|
||||
"illuminate/session": "^5.5|^6|^7",
|
||||
"illuminate/support": "^5.5|^6|^7",
|
||||
"maximebf/debugbar": "^1.15.1",
|
||||
"php": ">=7.0",
|
||||
"symfony/debug": "^3|^4|^5",
|
||||
"symfony/finder": "^3|^4|^5"
|
||||
},
|
||||
"require-dev": {
|
||||
"laravel/framework": "5.5.x"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "3.2-dev"
|
||||
},
|
||||
"laravel": {
|
||||
"providers": [
|
||||
"Barryvdh\\Debugbar\\ServiceProvider"
|
||||
],
|
||||
"aliases": {
|
||||
"Debugbar": "Barryvdh\\Debugbar\\Facade"
|
||||
}
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Barryvdh\\Debugbar\\": "src/"
|
||||
},
|
||||
"files": [
|
||||
"src/helpers.php"
|
||||
]
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Barry vd. Heuvel",
|
||||
"email": "barryvdh@gmail.com"
|
||||
}
|
||||
],
|
||||
"description": "PHP Debugbar integration for Laravel",
|
||||
"keywords": [
|
||||
"debug",
|
||||
"debugbar",
|
||||
"laravel",
|
||||
"profiler",
|
||||
"webprofiler"
|
||||
],
|
||||
"time": "2020-05-05T10:53:32+00:00"
|
||||
},
|
||||
{
|
||||
"name": "barryvdh/laravel-dompdf",
|
||||
"version": "v0.8.6",
|
||||
|
|
@ -1378,56 +1310,6 @@
|
|||
],
|
||||
"time": "2019-07-28T22:19:29+00:00"
|
||||
},
|
||||
{
|
||||
"name": "fzaninotto/faker",
|
||||
"version": "v1.9.1",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/fzaninotto/Faker.git",
|
||||
"reference": "fc10d778e4b84d5bd315dad194661e091d307c6f"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/fzaninotto/Faker/zipball/fc10d778e4b84d5bd315dad194661e091d307c6f",
|
||||
"reference": "fc10d778e4b84d5bd315dad194661e091d307c6f",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": "^5.3.3 || ^7.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"ext-intl": "*",
|
||||
"phpunit/phpunit": "^4.8.35 || ^5.7",
|
||||
"squizlabs/php_codesniffer": "^2.9.2"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "1.9-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Faker\\": "src/Faker/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "François Zaninotto"
|
||||
}
|
||||
],
|
||||
"description": "Faker is a PHP library that generates fake data for you.",
|
||||
"keywords": [
|
||||
"data",
|
||||
"faker",
|
||||
"fixtures"
|
||||
],
|
||||
"time": "2019-12-12T13:22:17+00:00"
|
||||
},
|
||||
{
|
||||
"name": "guzzlehttp/guzzle",
|
||||
"version": "6.5.4",
|
||||
|
|
@ -3005,67 +2887,6 @@
|
|||
],
|
||||
"time": "2019-10-06T11:29:25+00:00"
|
||||
},
|
||||
{
|
||||
"name": "maximebf/debugbar",
|
||||
"version": "v1.16.3",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/maximebf/php-debugbar.git",
|
||||
"reference": "1a1605b8e9bacb34cc0c6278206d699772e1d372"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/maximebf/php-debugbar/zipball/1a1605b8e9bacb34cc0c6278206d699772e1d372",
|
||||
"reference": "1a1605b8e9bacb34cc0c6278206d699772e1d372",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": "^7.1",
|
||||
"psr/log": "^1.0",
|
||||
"symfony/var-dumper": "^2.6|^3|^4|^5"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "^5"
|
||||
},
|
||||
"suggest": {
|
||||
"kriswallsmith/assetic": "The best way to manage assets",
|
||||
"monolog/monolog": "Log using Monolog",
|
||||
"predis/predis": "Redis storage"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "1.16-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"DebugBar\\": "src/DebugBar/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Maxime Bouroumeau-Fuseau",
|
||||
"email": "maxime.bouroumeau@gmail.com",
|
||||
"homepage": "http://maximebf.com"
|
||||
},
|
||||
{
|
||||
"name": "Barry vd. Heuvel",
|
||||
"email": "barryvdh@gmail.com"
|
||||
}
|
||||
],
|
||||
"description": "Debug bar in the browser for php application",
|
||||
"homepage": "https://github.com/maximebf/php-debugbar",
|
||||
"keywords": [
|
||||
"debug",
|
||||
"debugbar"
|
||||
],
|
||||
"time": "2020-05-06T07:06:27+00:00"
|
||||
},
|
||||
{
|
||||
"name": "monolog/monolog",
|
||||
"version": "2.1.0",
|
||||
|
|
@ -4556,63 +4377,6 @@
|
|||
"homepage": "https://symfony.com",
|
||||
"time": "2020-05-20T17:43:50+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/debug",
|
||||
"version": "v4.4.9",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/debug.git",
|
||||
"reference": "28f92d08bb6d1fddf8158e02c194ad43870007e6"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/debug/zipball/28f92d08bb6d1fddf8158e02c194ad43870007e6",
|
||||
"reference": "28f92d08bb6d1fddf8158e02c194ad43870007e6",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=7.1.3",
|
||||
"psr/log": "~1.0",
|
||||
"symfony/polyfill-php80": "^1.15"
|
||||
},
|
||||
"conflict": {
|
||||
"symfony/http-kernel": "<3.4"
|
||||
},
|
||||
"require-dev": {
|
||||
"symfony/http-kernel": "^3.4|^4.0|^5.0"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "4.4-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Symfony\\Component\\Debug\\": ""
|
||||
},
|
||||
"exclude-from-classmap": [
|
||||
"/Tests/"
|
||||
]
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Fabien Potencier",
|
||||
"email": "fabien@symfony.com"
|
||||
},
|
||||
{
|
||||
"name": "Symfony Community",
|
||||
"homepage": "https://symfony.com/contributors"
|
||||
}
|
||||
],
|
||||
"description": "Symfony Debug Component",
|
||||
"homepage": "https://symfony.com",
|
||||
"time": "2020-05-24T08:33:35+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/deprecation-contracts",
|
||||
"version": "v2.1.2",
|
||||
|
|
@ -6467,6 +6231,74 @@
|
|||
}
|
||||
],
|
||||
"packages-dev": [
|
||||
{
|
||||
"name": "barryvdh/laravel-debugbar",
|
||||
"version": "v3.3.3",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/barryvdh/laravel-debugbar.git",
|
||||
"reference": "57f2219f6d9efe41ed1bc880d86701c52f261bf5"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/barryvdh/laravel-debugbar/zipball/57f2219f6d9efe41ed1bc880d86701c52f261bf5",
|
||||
"reference": "57f2219f6d9efe41ed1bc880d86701c52f261bf5",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"illuminate/routing": "^5.5|^6|^7",
|
||||
"illuminate/session": "^5.5|^6|^7",
|
||||
"illuminate/support": "^5.5|^6|^7",
|
||||
"maximebf/debugbar": "^1.15.1",
|
||||
"php": ">=7.0",
|
||||
"symfony/debug": "^3|^4|^5",
|
||||
"symfony/finder": "^3|^4|^5"
|
||||
},
|
||||
"require-dev": {
|
||||
"laravel/framework": "5.5.x"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "3.2-dev"
|
||||
},
|
||||
"laravel": {
|
||||
"providers": [
|
||||
"Barryvdh\\Debugbar\\ServiceProvider"
|
||||
],
|
||||
"aliases": {
|
||||
"Debugbar": "Barryvdh\\Debugbar\\Facade"
|
||||
}
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Barryvdh\\Debugbar\\": "src/"
|
||||
},
|
||||
"files": [
|
||||
"src/helpers.php"
|
||||
]
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Barry vd. Heuvel",
|
||||
"email": "barryvdh@gmail.com"
|
||||
}
|
||||
],
|
||||
"description": "PHP Debugbar integration for Laravel",
|
||||
"keywords": [
|
||||
"debug",
|
||||
"debugbar",
|
||||
"laravel",
|
||||
"profiler",
|
||||
"webprofiler"
|
||||
],
|
||||
"time": "2020-05-05T10:53:32+00:00"
|
||||
},
|
||||
{
|
||||
"name": "behat/gherkin",
|
||||
"version": "v4.6.2",
|
||||
|
|
@ -7152,6 +6984,56 @@
|
|||
],
|
||||
"time": "2020-05-05T12:28:07+00:00"
|
||||
},
|
||||
{
|
||||
"name": "fzaninotto/faker",
|
||||
"version": "v1.9.1",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/fzaninotto/Faker.git",
|
||||
"reference": "fc10d778e4b84d5bd315dad194661e091d307c6f"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/fzaninotto/Faker/zipball/fc10d778e4b84d5bd315dad194661e091d307c6f",
|
||||
"reference": "fc10d778e4b84d5bd315dad194661e091d307c6f",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": "^5.3.3 || ^7.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"ext-intl": "*",
|
||||
"phpunit/phpunit": "^4.8.35 || ^5.7",
|
||||
"squizlabs/php_codesniffer": "^2.9.2"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "1.9-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Faker\\": "src/Faker/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "François Zaninotto"
|
||||
}
|
||||
],
|
||||
"description": "Faker is a PHP library that generates fake data for you.",
|
||||
"keywords": [
|
||||
"data",
|
||||
"faker",
|
||||
"fixtures"
|
||||
],
|
||||
"time": "2019-12-12T13:22:17+00:00"
|
||||
},
|
||||
{
|
||||
"name": "hamcrest/hamcrest-php",
|
||||
"version": "v2.0.0",
|
||||
|
|
@ -7200,6 +7082,67 @@
|
|||
],
|
||||
"time": "2016-01-20T08:20:44+00:00"
|
||||
},
|
||||
{
|
||||
"name": "maximebf/debugbar",
|
||||
"version": "v1.16.3",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/maximebf/php-debugbar.git",
|
||||
"reference": "1a1605b8e9bacb34cc0c6278206d699772e1d372"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/maximebf/php-debugbar/zipball/1a1605b8e9bacb34cc0c6278206d699772e1d372",
|
||||
"reference": "1a1605b8e9bacb34cc0c6278206d699772e1d372",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": "^7.1",
|
||||
"psr/log": "^1.0",
|
||||
"symfony/var-dumper": "^2.6|^3|^4|^5"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "^5"
|
||||
},
|
||||
"suggest": {
|
||||
"kriswallsmith/assetic": "The best way to manage assets",
|
||||
"monolog/monolog": "Log using Monolog",
|
||||
"predis/predis": "Redis storage"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "1.16-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"DebugBar\\": "src/DebugBar/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Maxime Bouroumeau-Fuseau",
|
||||
"email": "maxime.bouroumeau@gmail.com",
|
||||
"homepage": "http://maximebf.com"
|
||||
},
|
||||
{
|
||||
"name": "Barry vd. Heuvel",
|
||||
"email": "barryvdh@gmail.com"
|
||||
}
|
||||
],
|
||||
"description": "Debug bar in the browser for php application",
|
||||
"homepage": "https://github.com/maximebf/php-debugbar",
|
||||
"keywords": [
|
||||
"debug",
|
||||
"debugbar"
|
||||
],
|
||||
"time": "2020-05-06T07:06:27+00:00"
|
||||
},
|
||||
{
|
||||
"name": "mockery/mockery",
|
||||
"version": "1.4.0",
|
||||
|
|
@ -8773,6 +8716,63 @@
|
|||
"homepage": "https://symfony.com",
|
||||
"time": "2020-05-23T13:13:03+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/debug",
|
||||
"version": "v4.4.9",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/debug.git",
|
||||
"reference": "28f92d08bb6d1fddf8158e02c194ad43870007e6"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/debug/zipball/28f92d08bb6d1fddf8158e02c194ad43870007e6",
|
||||
"reference": "28f92d08bb6d1fddf8158e02c194ad43870007e6",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=7.1.3",
|
||||
"psr/log": "~1.0",
|
||||
"symfony/polyfill-php80": "^1.15"
|
||||
},
|
||||
"conflict": {
|
||||
"symfony/http-kernel": "<3.4"
|
||||
},
|
||||
"require-dev": {
|
||||
"symfony/http-kernel": "^3.4|^4.0|^5.0"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "4.4-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Symfony\\Component\\Debug\\": ""
|
||||
},
|
||||
"exclude-from-classmap": [
|
||||
"/Tests/"
|
||||
]
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Fabien Potencier",
|
||||
"email": "fabien@symfony.com"
|
||||
},
|
||||
{
|
||||
"name": "Symfony Community",
|
||||
"homepage": "https://symfony.com/contributors"
|
||||
}
|
||||
],
|
||||
"description": "Symfony Debug Component",
|
||||
"homepage": "https://symfony.com",
|
||||
"time": "2020-05-24T08:33:35+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/dom-crawler",
|
||||
"version": "v5.1.0",
|
||||
|
|
|
|||
|
|
@ -1,188 +0,0 @@
|
|||
<?php
|
||||
|
||||
return [
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Module Namespace
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| Default module namespace.
|
||||
|
|
||||
*/
|
||||
|
||||
'namespace' => 'Modules',
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Module Stubs
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| Default module stubs.
|
||||
|
|
||||
*/
|
||||
|
||||
'stubs' => [
|
||||
'enabled' => false,
|
||||
'path' => base_path() . '/vendor/nwidart/laravel-modules/src/Commands/stubs',
|
||||
'files' => [
|
||||
'start' => 'start.php',
|
||||
'routes' => 'Http/routes.php',
|
||||
'views/index' => 'Resources/views/index.blade.php',
|
||||
'views/master' => 'Resources/views/layouts/master.blade.php',
|
||||
'scaffold/config' => 'Config/config.php',
|
||||
'composer' => 'composer.json',
|
||||
'assets/js/app' => 'Resources/assets/js/app.js',
|
||||
'assets/sass/app' => 'Resources/assets/sass/app.scss',
|
||||
'webpack' => 'webpack.mix.js',
|
||||
'package' => 'package.json',
|
||||
],
|
||||
'replacements' => [
|
||||
'start' => ['LOWER_NAME', 'ROUTES_LOCATION'],
|
||||
'routes' => ['LOWER_NAME', 'STUDLY_NAME', 'MODULE_NAMESPACE'],
|
||||
'webpack' => ['LOWER_NAME'],
|
||||
'json' => ['LOWER_NAME', 'STUDLY_NAME', 'MODULE_NAMESPACE'],
|
||||
'views/index' => ['LOWER_NAME'],
|
||||
'views/master' => ['LOWER_NAME', 'STUDLY_NAME'],
|
||||
'scaffold/config' => ['STUDLY_NAME'],
|
||||
'composer' => [
|
||||
'LOWER_NAME',
|
||||
'STUDLY_NAME',
|
||||
'VENDOR',
|
||||
'AUTHOR_NAME',
|
||||
'AUTHOR_EMAIL',
|
||||
'MODULE_NAMESPACE',
|
||||
],
|
||||
],
|
||||
'gitkeep' => true,
|
||||
],
|
||||
'paths' => [
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Modules path
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| This path used for save the generated module. This path also will be added
|
||||
| automatically to list of scanned folders.
|
||||
|
|
||||
*/
|
||||
|
||||
'modules' => base_path('Modules'),
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Modules assets path
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| Here you may update the modules assets path.
|
||||
|
|
||||
*/
|
||||
|
||||
'assets' => public_path('modules'),
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| The migrations path
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| Where you run 'module:publish-migration' command, where do you publish the
|
||||
| the migration files?
|
||||
|
|
||||
*/
|
||||
|
||||
'migration' => base_path('database/migrations'),
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Generator path
|
||||
|--------------------------------------------------------------------------
|
||||
| Customise the paths where the folders will be generated.
|
||||
| Set the generate key to false to not generate that folder
|
||||
*/
|
||||
'generator' => [
|
||||
'config' => ['path' => 'Config', 'generate' => true],
|
||||
'command' => ['path' => 'Console', 'generate' => true],
|
||||
'migration' => ['path' => 'Database/Migrations', 'generate' => true],
|
||||
'seeder' => ['path' => 'Database/Seeders', 'generate' => true],
|
||||
'factory' => ['path' => 'Database/factories', 'generate' => true],
|
||||
'model' => ['path' => 'Entities', 'generate' => true],
|
||||
'controller' => ['path' => 'Http/Controllers', 'generate' => true],
|
||||
'filter' => ['path' => 'Http/Middleware', 'generate' => true],
|
||||
'request' => ['path' => 'Http/Requests', 'generate' => true],
|
||||
'provider' => ['path' => 'Providers', 'generate' => true],
|
||||
'assets' => ['path' => 'Resources/assets', 'generate' => true],
|
||||
'lang' => ['path' => 'Resources/lang', 'generate' => true],
|
||||
'views' => ['path' => 'Resources/views', 'generate' => true],
|
||||
'test' => ['path' => 'Tests', 'generate' => true],
|
||||
'repository' => ['path' => 'Repositories', 'generate' => false],
|
||||
'event' => ['path' => 'Events', 'generate' => false],
|
||||
'listener' => ['path' => 'Listeners', 'generate' => false],
|
||||
'policies' => ['path' => 'Policies', 'generate' => false],
|
||||
'rules' => ['path' => 'Rules', 'generate' => false],
|
||||
'jobs' => ['path' => 'Jobs', 'generate' => false],
|
||||
'emails' => ['path' => 'Emails', 'generate' => false],
|
||||
'notifications' => ['path' => 'Notifications', 'generate' => false],
|
||||
'resource' => ['path' => 'Transformers', 'generate' => false],
|
||||
],
|
||||
],
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Scan Path
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| Here you define which folder will be scanned. By default will scan vendor
|
||||
| directory. This is useful if you host the package in packagist website.
|
||||
|
|
||||
*/
|
||||
|
||||
'scan' => [
|
||||
'enabled' => false,
|
||||
'paths' => [
|
||||
base_path('vendor/*/*'),
|
||||
],
|
||||
],
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Composer File Template
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| Here is the config for composer.json file, generated by this package
|
||||
|
|
||||
*/
|
||||
|
||||
'composer' => [
|
||||
'vendor' => 'nwidart',
|
||||
'author' => [
|
||||
'name' => 'Nicolas Widart',
|
||||
'email' => 'n.widart@gmail.com',
|
||||
],
|
||||
],
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Caching
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| Here is the config for setting up caching feature.
|
||||
|
|
||||
*/
|
||||
'cache' => [
|
||||
'enabled' => false,
|
||||
'key' => 'laravel-modules',
|
||||
'lifetime' => 60,
|
||||
],
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Choose what laravel-modules will register as custom namespaces.
|
||||
| Setting one to false will require you to register that part
|
||||
| in your own Service Provider class.
|
||||
|--------------------------------------------------------------------------
|
||||
*/
|
||||
'register' => [
|
||||
'translations' => true,
|
||||
/**
|
||||
* load files on boot or register method
|
||||
*
|
||||
* Note: boot not compatible with asgardcms
|
||||
*
|
||||
* @example boot|register
|
||||
*/
|
||||
'files' => 'register',
|
||||
],
|
||||
];
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
<?php
|
||||
|
||||
return [
|
||||
// use the 'code' of the 'attributes' table here to be able to control which attributes
|
||||
// should be skipped when doing a copy (admin->catalog->products->copy product).
|
||||
// you can also add every relation that should not be copied here to skip them.
|
||||
// defaults to none (which means everything is copied).
|
||||
'skipAttributesOnCopy' => [
|
||||
|
||||
],
|
||||
|
||||
// Make the original and source product 'related' via the 'product_relations' table
|
||||
'linkProductsOnCopy' => false,
|
||||
];
|
||||
|
|
@ -23,5 +23,15 @@ return [
|
|||
'name' => 'Velocity',
|
||||
'parent' => 'default'
|
||||
],
|
||||
],
|
||||
|
||||
'admin-default' => 'default',
|
||||
|
||||
'admin-themes' => [
|
||||
'default' => [
|
||||
'views_path' => 'resources/admin-themes/default/views',
|
||||
'assets_path' => 'public/admin-themes/default/assets',
|
||||
'name' => 'Default'
|
||||
]
|
||||
]
|
||||
];
|
||||
|
|
@ -25,7 +25,7 @@
|
|||
"extra": {
|
||||
"laravel": {
|
||||
"providers": [
|
||||
"Webkul\\API\\AdminServiceProvider"
|
||||
"Webkul\\API\\Providers\\APIServiceProvider"
|
||||
],
|
||||
"aliases": {}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@
|
|||
"extra": {
|
||||
"laravel": {
|
||||
"providers": [
|
||||
"Webkul\\Admin\\AdminServiceProvider"
|
||||
"Webkul\\Admin\\Providers\\AdminServiceProvider"
|
||||
],
|
||||
"aliases": {}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ return [
|
|||
'value' => 'kgs',
|
||||
],
|
||||
],
|
||||
'channel_based' => true,
|
||||
'channel_based' => true
|
||||
],
|
||||
],
|
||||
], [
|
||||
|
|
@ -41,24 +41,28 @@ return [
|
|||
'type' => 'text',
|
||||
'validation' => 'required|max:50',
|
||||
'channel_based' => true,
|
||||
'default_value' => config('mail.from.name'),
|
||||
], [
|
||||
'name' => 'shop_email_from',
|
||||
'title' => 'admin::app.admin.system.shop-email-from',
|
||||
'type' => 'text',
|
||||
'validation' => 'required|email',
|
||||
'channel_based' => true,
|
||||
'default_value' => config('mail.from.address'),
|
||||
], [
|
||||
'name' => 'admin_name',
|
||||
'title' => 'admin::app.admin.system.admin-name',
|
||||
'type' => 'text',
|
||||
'validation' => 'required|max:50',
|
||||
'channel_based' => true,
|
||||
'default_value' => config('mail.admin.name'),
|
||||
], [
|
||||
'name' => 'admin_email',
|
||||
'title' => 'admin::app.admin.system.admin-email',
|
||||
'type' => 'text',
|
||||
'validation' => 'required|email',
|
||||
'channel_based' => true,
|
||||
'default_value' => config('mail.admin.address'),
|
||||
],
|
||||
],
|
||||
], [
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ namespace Webkul\Admin\DataGrids;
|
|||
|
||||
use Webkul\Ui\DataGrid\DataGrid;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Webkul\Core\Models\Channel;
|
||||
|
||||
class ProductDataGrid extends DataGrid
|
||||
{
|
||||
|
|
@ -27,19 +28,30 @@ class ProductDataGrid extends DataGrid
|
|||
{
|
||||
parent::__construct();
|
||||
|
||||
/* locale */
|
||||
$this->locale = request()->get('locale') ?? 'all';
|
||||
|
||||
/* channel */
|
||||
$this->channel = request()->get('channel') ?? 'all';
|
||||
|
||||
/* finding channel name */
|
||||
if ($this->channel !== 'all') {
|
||||
$this->channel = Channel::find($this->channel);
|
||||
$this->channel = $this->channel ? $this->channel->code : 'all';
|
||||
}
|
||||
}
|
||||
|
||||
public function prepareQueryBuilder()
|
||||
{
|
||||
/* query builder */
|
||||
$queryBuilder = DB::table('product_flat')
|
||||
->leftJoin('products', 'product_flat.product_id', '=', 'products.id')
|
||||
->leftJoin('attribute_families', 'products.attribute_family_id', '=', 'attribute_families.id')
|
||||
->leftJoin('product_inventories', 'product_flat.product_id', '=', 'product_inventories.product_id')
|
||||
->select(
|
||||
'product_flat.product_id as product_id',
|
||||
'product_flat.locale',
|
||||
'product_flat.channel',
|
||||
'product_flat.product_id',
|
||||
'products.sku as product_sku',
|
||||
'product_flat.name as product_name',
|
||||
'products.type as product_type',
|
||||
|
|
@ -49,15 +61,9 @@ class ProductDataGrid extends DataGrid
|
|||
DB::raw('SUM(DISTINCT ' . DB::getTablePrefix() . 'product_inventories.qty) as quantity')
|
||||
);
|
||||
|
||||
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->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');
|
||||
|
||||
$this->addFilter('product_id', 'product_flat.product_id');
|
||||
$this->addFilter('product_name', 'product_flat.name');
|
||||
|
|
@ -181,6 +187,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'),
|
||||
|
|
|
|||
|
|
@ -206,6 +206,7 @@ class CustomerController extends Controller
|
|||
$this->customerRepository->delete($id);
|
||||
} else {
|
||||
|
||||
session()->flash('error', trans('admin::app.response.order-pending', ['name' => 'Customer']));
|
||||
return response()->json(['message' => false], 400);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -236,9 +236,10 @@ class DashboardController extends Controller
|
|||
public function getCustomerWithMostSales()
|
||||
{
|
||||
return $this->orderRepository->getModel()
|
||||
->select(DB::raw('SUM(base_grand_total) as total_base_grand_total'))
|
||||
->addSelect(DB::raw('COUNT(id) as total_orders'))
|
||||
->addSelect('id', 'customer_id', 'customer_email', 'customer_first_name', 'customer_last_name')
|
||||
->leftJoin('refunds', 'orders.id', 'refunds.order_id')
|
||||
->select(DB::raw('(SUM(orders.base_grand_total) - SUM(IFNULL(refunds.base_grand_total, 0))) as total_base_grand_total'))
|
||||
->addSelect(DB::raw('COUNT(orders.id) as total_orders'))
|
||||
->addSelect('orders.id', 'customer_id', 'customer_email', 'customer_first_name', 'customer_last_name')
|
||||
->where('orders.created_at', '>=', $this->startDate)
|
||||
->where('orders.created_at', '<=', $this->endDate)
|
||||
->where('orders.status', '<>', 'closed')
|
||||
|
|
|
|||
|
|
@ -273,6 +273,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');
|
||||
|
|
|
|||
|
|
@ -23,17 +23,19 @@ class Order
|
|||
*/
|
||||
public function sendNewOrderMail($order)
|
||||
{
|
||||
$customerLocale = $this->getLocale($order);
|
||||
|
||||
try {
|
||||
/* email to customer */
|
||||
$configKey = 'emails.general.notifications.emails.general.notifications.new-order';
|
||||
if (core()->getConfigData($configKey))
|
||||
Mail::queue(new NewOrderNotification($order));
|
||||
if (core()->getConfigData($configKey)) {
|
||||
$this->prepareMail($customerLocale, new NewOrderNotification($order));
|
||||
}
|
||||
|
||||
/* email to admin */
|
||||
$configKey = 'emails.general.notifications.emails.general.notifications.new-admin';
|
||||
if (core()->getConfigData($configKey)) {
|
||||
app()->setLocale(env('APP_LOCALE'));
|
||||
Mail::queue(new NewAdminNotification($order));
|
||||
$this->prepareMail(env('APP_LOCALE'), new NewAdminNotification($order));
|
||||
}
|
||||
} catch (\Exception $e) {
|
||||
report($e);
|
||||
|
|
@ -48,15 +50,17 @@ class Order
|
|||
*/
|
||||
public function sendNewInvoiceMail($invoice)
|
||||
{
|
||||
$customerLocale = $this->getLocale($invoice);
|
||||
|
||||
try {
|
||||
if ($invoice->email_sent) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* email to customer */
|
||||
$configKey = 'emails.general.notifications.emails.general.notifications.new-invoice';
|
||||
|
||||
if (core()->getConfigData($configKey)) {
|
||||
Mail::queue(new NewInvoiceNotification($invoice));
|
||||
$this->prepareMail($customerLocale, new NewInvoiceNotification($invoice));
|
||||
}
|
||||
} catch (\Exception $e) {
|
||||
report($e);
|
||||
|
|
@ -71,11 +75,13 @@ class Order
|
|||
*/
|
||||
public function sendNewRefundMail($refund)
|
||||
{
|
||||
try {
|
||||
$configKey = 'emails.general.notifications.emails.general.notifications.new-refund';
|
||||
$customerLocale = $this->getLocale($refund);
|
||||
|
||||
try {
|
||||
/* email to customer */
|
||||
$configKey = 'emails.general.notifications.emails.general.notifications.new-refund';
|
||||
if (core()->getConfigData($configKey)) {
|
||||
Mail::queue(new NewRefundNotification($refund));
|
||||
$this->prepareMail($customerLocale, new NewRefundNotification($refund));
|
||||
}
|
||||
} catch (\Exception $e) {
|
||||
report($e);
|
||||
|
|
@ -90,21 +96,23 @@ class Order
|
|||
*/
|
||||
public function sendNewShipmentMail($shipment)
|
||||
{
|
||||
$customerLocale = $this->getLocale($shipment);
|
||||
|
||||
try {
|
||||
if ($shipment->email_sent) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* email to customer */
|
||||
$configKey = 'emails.general.notifications.emails.general.notifications.new-shipment';
|
||||
|
||||
if (core()->getConfigData($configKey)) {
|
||||
Mail::queue(new NewShipmentNotification($shipment));
|
||||
$this->prepareMail($customerLocale, new NewShipmentNotification($shipment));
|
||||
}
|
||||
|
||||
/* email to admin */
|
||||
$configKey = 'emails.general.notifications.emails.general.notifications.new-inventory-source';
|
||||
|
||||
if (core()->getConfigData($configKey)) {
|
||||
Mail::queue(new NewInventorySourceNotification($shipment));
|
||||
$this->prepareMail(env('APP_LOCALE'), new NewInventorySourceNotification($shipment));
|
||||
}
|
||||
} catch (\Exception $e) {
|
||||
report($e);
|
||||
|
|
@ -117,18 +125,19 @@ class Order
|
|||
*/
|
||||
public function sendCancelOrderMail($order)
|
||||
{
|
||||
$customerLocale = $this->getLocale($order);
|
||||
|
||||
try {
|
||||
/* email to customer */
|
||||
$configKey = 'emails.general.notifications.emails.general.notifications.cancel-order';
|
||||
if (core()->getConfigData($configKey)) {
|
||||
Mail::queue(new CancelOrderNotification($order));
|
||||
$this->prepareMail($customerLocale, new CancelOrderNotification($order));
|
||||
}
|
||||
|
||||
/* email to admin */
|
||||
$configKey = 'emails.general.notifications.emails.general.notifications.new-admin';
|
||||
if (core()->getConfigData($configKey)) {
|
||||
app()->setLocale(env('APP_LOCALE'));
|
||||
Mail::queue(new CancelOrderAdminNotification($order));
|
||||
$this->prepareMail(env('APP_LOCALE'), new CancelOrderAdminNotification($order));
|
||||
}
|
||||
} catch (\Exception $e) {
|
||||
report($e);
|
||||
|
|
@ -141,14 +150,43 @@ class Order
|
|||
*/
|
||||
public function sendOrderCommentMail($comment)
|
||||
{
|
||||
$customerLocale = $this->getLocale($comment);
|
||||
|
||||
if (! $comment->customer_notified) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
Mail::queue(new OrderCommentNotification($comment));
|
||||
/* email to customer */
|
||||
$this->prepareMail($customerLocale, new OrderCommentNotification($comment));
|
||||
} catch (\Exception $e) {
|
||||
report($e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the locale of the customer if somehow item name changes then the english locale will pe provided.
|
||||
*
|
||||
* @param object \Webkul\Sales\Contracts\Order|\Webkul\Sales\Contracts\Invoice|\Webkul\Sales\Contracts\Refund|\Webkul\Sales\Contracts\Shipment|\Webkul\Sales\Contracts\OrderComment
|
||||
* @return string
|
||||
*/
|
||||
private function getLocale($object)
|
||||
{
|
||||
if ($object instanceof \Webkul\Sales\Contracts\OrderComment) {
|
||||
$object = $object->order;
|
||||
}
|
||||
|
||||
$objectFirstItem = $object->items->first();
|
||||
return isset($objectFirstItem->additional['locale']) ? $objectFirstItem->additional['locale'] : 'en';
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepare Mail.
|
||||
* @return void
|
||||
*/
|
||||
private function prepareMail($locale, $notification)
|
||||
{
|
||||
app()->setLocale($locale);
|
||||
Mail::queue($notification);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,20 +1,22 @@
|
|||
<?php
|
||||
|
||||
return [
|
||||
'save' => 'حفظ',
|
||||
'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' => 'خاطئة',
|
||||
|
|
@ -138,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' => 'المجموعة',
|
||||
|
|
@ -1201,17 +1204,20 @@ 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' => 'تم نسخ المنتج',
|
||||
'error-while-copying' => 'خطأ في نسخ المنتج',
|
||||
'product-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' => 'لا يستطيع حذف الجذر الفئة',
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -1,18 +1,19 @@
|
|||
<?php
|
||||
|
||||
return [
|
||||
'save' => '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',
|
||||
|
|
@ -1209,17 +1210,20 @@ 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',
|
||||
'error-while-copying' => 'Something went wrong while trying to copy the product',
|
||||
'product-can-not-be-copied' => 'Products of type :type can not be copied',
|
||||
'cannot-delete-default' => 'Cannot delete the default channel',
|
||||
'create-success' => ':name created successfully.',
|
||||
'update-success' => ':name updated successfully.',
|
||||
'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',
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -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',
|
||||
|
|
|
|||
|
|
@ -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',
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
<script type="text/x-template" id="variant-form-template">
|
||||
<form method="POST" action="{{ route('admin.catalog.products.store') }}" data-vv-scope="add-variant-form" @submit.prevent="addVariant('add-variant-form')">
|
||||
<form method="POST" action="{{ route('admin.catalog.products.store') }}"
|
||||
data-vv-scope="add-variant-form" @submit.prevent="addVariant('add-variant-form')">
|
||||
|
||||
<div class="page-content">
|
||||
<div class="form-container">
|
||||
|
||||
<div v-for='(attribute, index) in super_attributes' class="control-group" :class="[errors.has('add-variant-form.' + attribute.code) ? 'has-error' : '']">
|
||||
<label :for="attribute.code" class="required">@{{ attribute.admin_name }}</label>
|
||||
<select v-validate="'required'" v-model="variant[attribute.code]" class="control" :id="attribute.code" :name="attribute.code" :data-vv-as="'"' + attribute.admin_name + '"'">
|
||||
<option v-for='(option, index) in attribute.options' :value="option.id">@{{ option.admin_name }}</option>
|
||||
<div v-for='(attribute, index) in super_attributes' class="control-group"
|
||||
:class="[errors.has('add-variant-form.' + attribute.code) ? 'has-error' : '']"
|
||||
>
|
||||
<label :for="attribute.code" class="required">@{{ attribute.admin_name
|
||||
}}</label>
|
||||
<select
|
||||
v-validate="'required'"
|
||||
v-model="variant[attribute.code]"
|
||||
class="control"
|
||||
:id="attribute.code"
|
||||
:name="attribute.code"
|
||||
:data-vv-as="'"' + attribute.admin_name + '"'"
|
||||
>
|
||||
<option v-for='(option, index) in attribute.options' :value="option.id">
|
||||
@{{ option.admin_name }}
|
||||
</option>
|
||||
</select>
|
||||
<span class="control-error" v-if="errors.has('add-variant-form.' + attribute.code)">@{{ errors.first('add-variant-form.' + attribute.code) }}</span>
|
||||
<span class="control-error"
|
||||
v-if="errors.has('add-variant-form.' + attribute.code)">@{{ errors.first('add-variant-form.' + attribute.code) }}</span>
|
||||
</div>
|
||||
|
||||
<button type="submit" class="btn btn-lg btn-primary">
|
||||
|
|
@ -76,25 +93,28 @@
|
|||
<table>
|
||||
|
||||
<thead>
|
||||
<tr>
|
||||
<th class="sku">{{ __('admin::app.catalog.products.sku') }}</th>
|
||||
<th>{{ __('admin::app.catalog.products.name') }}</th>
|
||||
<tr>
|
||||
<th class="sku">{{ __('admin::app.catalog.products.sku') }}</th>
|
||||
<th>{{ __('admin::app.catalog.products.name') }}</th>
|
||||
|
||||
@foreach ($product->super_attributes as $attribute)
|
||||
<th class="{{ $attribute->code }}" style="width: 150px">{{ $attribute->admin_name }}</th>
|
||||
@endforeach
|
||||
@foreach ($product->super_attributes as $attribute)
|
||||
<th class="{{ $attribute->code }}"
|
||||
style="width: 150px">{{ $attribute->admin_name }}</th>
|
||||
@endforeach
|
||||
|
||||
<th class="qty">{{ __('admin::app.catalog.products.qty') }}</th>
|
||||
<th class="price">{{ __('admin::app.catalog.products.price') }}</th>
|
||||
<th class="weight">{{ __('admin::app.catalog.products.weight') }}</th>
|
||||
<th class="status">{{ __('admin::app.catalog.products.status') }}</th>
|
||||
<th class="actions"></th>
|
||||
</tr>
|
||||
<th class="qty">{{ __('admin::app.catalog.products.qty') }}</th>
|
||||
<th class="price">{{ __('admin::app.catalog.products.price') }}</th>
|
||||
<th class="weight">{{ __('admin::app.catalog.products.weight') }}</th>
|
||||
<th class="status">{{ __('admin::app.catalog.products.status') }}</th>
|
||||
<th class="actions"></th>
|
||||
</tr>
|
||||
</thead>
|
||||
|
||||
<tbody>
|
||||
|
||||
<variant-item v-for='(variant, index) in variants' :variant="variant" :key="index" :index="variant.id" @onRemoveVariant="removeVariant($event)"></variant-item>
|
||||
<variant-item v-for='(variant, index) in variants' :variant="variant" :key="index"
|
||||
:index="variant.id"
|
||||
@onRemoveVariant="removeVariant($event)"></variant-item>
|
||||
|
||||
</tbody>
|
||||
|
||||
|
|
@ -105,23 +125,32 @@
|
|||
<script type="text/x-template" id="variant-item-template">
|
||||
<tr>
|
||||
<td>
|
||||
<div class="control-group" :class="[errors.has(variantInputName + '[sku]') ? 'has-error' : '']">
|
||||
<input type="text" v-validate="'required'" v-model="variant.sku" :name="[variantInputName + '[sku]']" class="control" data-vv-as=""{{ __('admin::app.catalog.products.sku') }}"" v-slugify/>
|
||||
<div class="control-group"
|
||||
:class="[errors.has(variantInputName + '[sku]') ? 'has-error' : '']">
|
||||
<input type="text" v-validate="'required'" v-model="variant.sku"
|
||||
:name="[variantInputName + '[sku]']" class="control"
|
||||
data-vv-as=""{{ __('admin::app.catalog.products.sku') }}""
|
||||
v-slugify/>
|
||||
<span class="control-error" v-if="errors.has(variantInputName + '[sku]')">@{{ errors.first(variantInputName + '[sku]') }}</span>
|
||||
</div>
|
||||
</td>
|
||||
|
||||
<td>
|
||||
<div class="control-group" :class="[errors.has(variantInputName + '[name]') ? 'has-error' : '']">
|
||||
<input type="text" v-validate="'required'" v-model="variant.name" :name="[variantInputName + '[name]']" class="control" data-vv-as=""{{ __('admin::app.catalog.products.name') }}""/>
|
||||
<div class="control-group"
|
||||
:class="[errors.has(variantInputName + '[name]') ? 'has-error' : '']">
|
||||
<input type="text" v-validate="'required'" v-model="variant.name"
|
||||
:name="[variantInputName + '[name]']" class="control"
|
||||
data-vv-as=""{{ __('admin::app.catalog.products.name') }}""/>
|
||||
<span class="control-error" v-if="errors.has(variantInputName + '[name]')">@{{ errors.first(variantInputName + '[name]') }}</span>
|
||||
</div>
|
||||
</td>
|
||||
|
||||
<td v-for='(attribute, index) in superAttributes'>
|
||||
<div class="control-group">
|
||||
<input type="hidden" :name="[variantInputName + '[' + attribute.code + ']']" :value="variant[attribute.code]"/>
|
||||
<input type="text" class="control" :value="optionName(variant[attribute.code])" readonly/>
|
||||
<input type="hidden" :name="[variantInputName + '[' + attribute.code + ']']"
|
||||
:value="variant[attribute.code]"/>
|
||||
<input type="text" class="control" :value="optionName(variant[attribute.code])"
|
||||
readonly/>
|
||||
</div>
|
||||
</td>
|
||||
|
||||
|
|
@ -135,10 +164,16 @@
|
|||
<div class="dropdown-container">
|
||||
<ul>
|
||||
<li v-for='(inventorySource, index) in inventorySources'>
|
||||
<div class="control-group" :class="[errors.has(variantInputName + '[inventories][' + inventorySource.id + ']') ? 'has-error' : '']">
|
||||
<div class="control-group"
|
||||
:class="[errors.has(variantInputName + '[inventories][' + inventorySource.id + ']') ? 'has-error' : '']">
|
||||
<label>@{{ inventorySource.name }}</label>
|
||||
<input type="text" v-validate="'numeric|min:0'" :name="[variantInputName + '[inventories][' + inventorySource.id + ']']" v-model="inventories[inventorySource.id]" class="control" v-on:keyup="updateTotalQty()" :data-vv-as="'"' + inventorySource.name + '"'"/>
|
||||
<span class="control-error" v-if="errors.has(variantInputName + '[inventories][' + inventorySource.id + ']')">@{{ errors.first(variantInputName + '[inventories][' + inventorySource.id + ']') }}</span>
|
||||
<input type="text" v-validate="'numeric|min:0'"
|
||||
:name="[variantInputName + '[inventories][' + inventorySource.id + ']']"
|
||||
v-model="inventories[inventorySource.id]" class="control"
|
||||
v-on:keyup="updateTotalQty()"
|
||||
:data-vv-as="'"' + inventorySource.name + '"'"/>
|
||||
<span class="control-error"
|
||||
v-if="errors.has(variantInputName + '[inventories][' + inventorySource.id + ']')">@{{ errors.first(variantInputName + '[inventories][' + inventorySource.id + ']') }}</span>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
|
|
@ -147,30 +182,42 @@
|
|||
</td>
|
||||
|
||||
<td>
|
||||
<div class="control-group" :class="[errors.has(variantInputName + '[price]') ? 'has-error' : '']">
|
||||
<input type="number" v-validate="'required'" v-model="variant.price" :name="[variantInputName + '[price]']" class="control" data-vv-as=""{{ __('admin::app.catalog.products.price') }}"" step="any"/>
|
||||
<div class="control-group"
|
||||
:class="[errors.has(variantInputName + '[price]') ? 'has-error' : '']">
|
||||
<input type="number" v-validate="'required'" v-model="variant.price"
|
||||
:name="[variantInputName + '[price]']" class="control"
|
||||
data-vv-as=""{{ __('admin::app.catalog.products.price') }}""
|
||||
step="any"/>
|
||||
<span class="control-error" v-if="errors.has(variantInputName + '[price]')">@{{ errors.first(variantInputName + '[price]') }}</span>
|
||||
</div>
|
||||
</td>
|
||||
|
||||
<td>
|
||||
<div class="control-group" :class="[errors.has(variantInputName + '[weight]') ? 'has-error' : '']">
|
||||
<input type="number" v-validate="'required'" v-model="variant.weight" :name="[variantInputName + '[weight]']" class="control" data-vv-as=""{{ __('admin::app.catalog.products.weight') }}"" step="any"/>
|
||||
<div class="control-group"
|
||||
:class="[errors.has(variantInputName + '[weight]') ? 'has-error' : '']">
|
||||
<input type="number" v-validate="'required'" v-model="variant.weight"
|
||||
:name="[variantInputName + '[weight]']" class="control"
|
||||
data-vv-as=""{{ __('admin::app.catalog.products.weight') }}""
|
||||
step="any"/>
|
||||
<span class="control-error" v-if="errors.has(variantInputName + '[weight]')">@{{ errors.first(variantInputName + '[weight]') }}</span>
|
||||
</div>
|
||||
</td>
|
||||
|
||||
<td>
|
||||
<div class="control-group">
|
||||
<select type="text" v-model="variant.status" :name="[variantInputName + '[status]']" class="control">
|
||||
<option value="1" :selected="variant.status">{{ __('admin::app.catalog.products.enabled') }}</option>
|
||||
<option value="0" :selected="!variant.status">{{ __('admin::app.catalog.products.disabled') }}</option>
|
||||
<select type="text" v-model="variant.status"
|
||||
:name="[variantInputName + '[status]']" class="control">
|
||||
<option value="1"
|
||||
:selected="variant.status">{{ __('admin::app.catalog.products.enabled') }}</option>
|
||||
<option value="0"
|
||||
:selected="!variant.status">{{ __('admin::app.catalog.products.disabled') }}</option>
|
||||
</select>
|
||||
</div>
|
||||
</td>
|
||||
|
||||
<td class="actions">
|
||||
<a :href="['{{ route('admin.catalog.products.index') }}/edit/' + variant.id]"><i class="icon pencil-lg-icon"></i></a>
|
||||
<a :href="['{{ route('admin.catalog.products.index') }}/edit/' + variant.id]"><i
|
||||
class="icon pencil-lg-icon"></i></a>
|
||||
<i class="icon remove-icon" @click="removeVariant()"></i>
|
||||
</td>
|
||||
</tr>
|
||||
|
|
@ -190,7 +237,7 @@
|
|||
|
||||
Vue.component('variant-form', {
|
||||
|
||||
data: function() {
|
||||
data: function () {
|
||||
return {
|
||||
variant: {},
|
||||
super_attributes: super_attributes
|
||||
|
|
@ -209,7 +256,7 @@
|
|||
if (result) {
|
||||
var this_this = this;
|
||||
|
||||
var filteredVariants = variants.filter(function(variant) {
|
||||
var filteredVariants = variants.filter(function (variant) {
|
||||
var matchCount = 0;
|
||||
|
||||
for (var key in this_this.variant) {
|
||||
|
|
@ -224,7 +271,10 @@
|
|||
if (filteredVariants.length) {
|
||||
this.$parent.closeModal();
|
||||
|
||||
window.flashMessages = [{'type': 'alert-error', 'message': "{{ __('admin::app.catalog.products.variant-already-exist-message') }}" }];
|
||||
window.flashMessages = [{
|
||||
'type': 'alert-error',
|
||||
'message': "{{ __('admin::app.catalog.products.variant-already-exist-message') }}"
|
||||
}];
|
||||
|
||||
this.$root.addFlashMessages()
|
||||
} else {
|
||||
|
|
@ -234,12 +284,12 @@
|
|||
}
|
||||
|
||||
variants.push(Object.assign({
|
||||
sku: '{{ $product->sku }}' + '-variant-' + optionIds.join('-'),
|
||||
name: '',
|
||||
price: 0,
|
||||
weight: 0,
|
||||
status: 1
|
||||
}, this.variant));
|
||||
sku: '{{ $product->sku }}' + '-variant-' + optionIds.join('-'),
|
||||
name: '',
|
||||
price: 0,
|
||||
weight: 0,
|
||||
status: 1
|
||||
}, this.variant));
|
||||
|
||||
this.resetModel();
|
||||
|
||||
|
|
@ -252,7 +302,7 @@
|
|||
resetModel: function () {
|
||||
var this_this = this;
|
||||
|
||||
this.super_attributes.forEach(function(attribute) {
|
||||
this.super_attributes.forEach(function (attribute) {
|
||||
this_this.variant[attribute.code] = '';
|
||||
})
|
||||
}
|
||||
|
|
@ -265,7 +315,7 @@
|
|||
|
||||
inject: ['$validator'],
|
||||
|
||||
data: function() {
|
||||
data: function () {
|
||||
return {
|
||||
variants: variants,
|
||||
|
||||
|
|
@ -285,7 +335,10 @@
|
|||
var inventories = [];
|
||||
|
||||
for (var inventorySourceId in variant['inventories']) {
|
||||
inventories.push({'qty': variant['inventories'][inventorySourceId], 'inventory_source_id': inventorySourceId})
|
||||
inventories.push({
|
||||
'qty': variant['inventories'][inventorySourceId],
|
||||
'inventory_source_id': inventorySourceId
|
||||
})
|
||||
}
|
||||
|
||||
variant['inventories'] = inventories;
|
||||
|
|
@ -299,7 +352,10 @@
|
|||
variants[index][code] = [];
|
||||
|
||||
for (var inventorySourceId in variant[code]) {
|
||||
variants[index][code].push({'qty': variant[code][inventorySourceId], 'inventory_source_id': inventorySourceId})
|
||||
variants[index][code].push({
|
||||
'qty': variant[code][inventorySourceId],
|
||||
'inventory_source_id': inventorySourceId
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -310,7 +366,7 @@
|
|||
},
|
||||
|
||||
methods: {
|
||||
removeVariant: function(variant) {
|
||||
removeVariant: function (variant) {
|
||||
let index = this.variants.indexOf(variant)
|
||||
|
||||
this.variants.splice(index, 1)
|
||||
|
|
@ -327,7 +383,7 @@
|
|||
|
||||
inject: ['$validator'],
|
||||
|
||||
data: function() {
|
||||
data: function () {
|
||||
return {
|
||||
inventorySources: @json($inventorySources),
|
||||
inventories: {},
|
||||
|
|
@ -339,7 +395,7 @@
|
|||
created: function () {
|
||||
var this_this = this;
|
||||
|
||||
this.inventorySources.forEach(function(inventorySource) {
|
||||
this.inventorySources.forEach(function (inventorySource) {
|
||||
this_this.inventories[inventorySource.id] = this_this.sourceInventoryQty(inventorySource.id)
|
||||
this_this.totalQty += parseInt(this_this.inventories[inventorySource.id]);
|
||||
})
|
||||
|
|
@ -362,8 +418,8 @@
|
|||
optionName: function (optionId) {
|
||||
var optionName = '';
|
||||
|
||||
this.superAttributes.forEach(function(attribute) {
|
||||
attribute.options.forEach(function(option) {
|
||||
this.superAttributes.forEach(function (attribute) {
|
||||
attribute.options.forEach(function (option) {
|
||||
if (optionId == option.id) {
|
||||
optionName = option.admin_name;
|
||||
}
|
||||
|
|
@ -374,10 +430,10 @@
|
|||
},
|
||||
|
||||
sourceInventoryQty: function (inventorySourceId) {
|
||||
if (! Array.isArray(this.variant.inventories))
|
||||
if (!Array.isArray(this.variant.inventories))
|
||||
return 0;
|
||||
|
||||
var inventories = this.variant.inventories.filter(function(inventory) {
|
||||
var inventories = this.variant.inventories.filter(function (inventory) {
|
||||
return inventorySourceId === parseInt(inventory.inventory_source_id);
|
||||
})
|
||||
|
||||
|
|
|
|||
|
|
@ -94,7 +94,7 @@
|
|||
|
||||
@if ($field['type'] == 'text')
|
||||
|
||||
<input type="text" v-validate="'{{ $validations }}'" class="control" id="{{ $firstField }}[{{ $secondField }}][{{ $thirdField }}][{{ $field['name'] }}]" name="{{ $firstField }}[{{ $secondField }}][{{ $thirdField }}][{{ $field['name'] }}]" value="{{ old($name) ?: core()->getConfigData($name) }}" data-vv-as=""{{ trans($field['title']) }}"">
|
||||
<input type="text" v-validate="'{{ $validations }}'" class="control" id="{{ $firstField }}[{{ $secondField }}][{{ $thirdField }}][{{ $field['name'] }}]" name="{{ $firstField }}[{{ $secondField }}][{{ $thirdField }}][{{ $field['name'] }}]" value="{{ old($name) ?: (core()->getConfigData($name) ? core()->getConfigData($name) : (isset($field['default_value']) ? $field['default_value'] : '')) }}" data-vv-as=""{{ trans($field['title']) }}"">
|
||||
|
||||
@elseif ($field['type'] == 'password')
|
||||
|
||||
|
|
@ -212,7 +212,7 @@
|
|||
@elseif ($field['type'] == 'boolean')
|
||||
|
||||
<?php $selectedOption = core()->getConfigData($name) ?? ''; ?>
|
||||
|
||||
|
||||
<label class="switch">
|
||||
<input type="hidden" name="{{ $firstField }}[{{ $secondField }}][{{ $thirdField }}][{{ $field['name'] }}]" value="0" />
|
||||
<input type="checkbox" id="{{ $firstField }}[{{ $secondField }}][{{ $thirdField }}][{{ $field['name'] }}]" name="{{ $firstField }}[{{ $secondField }}][{{ $thirdField }}][{{ $field['name'] }}]" value="1" {{ $selectedOption ? 'checked' : '' }}>
|
||||
|
|
|
|||
|
|
@ -143,9 +143,9 @@
|
|||
<div class="control-group">
|
||||
<label for="theme">{{ __('admin::app.settings.channels.theme') }}</label>
|
||||
<select class="control" id="theme" name="theme">
|
||||
@foreach (themes()->all() as $theme)
|
||||
<option value="{{ $theme->code }}" {{ old('theme') == $theme->code ? 'selected' : '' }}>
|
||||
{{ $theme->name }}
|
||||
@foreach (config('themes.themes') as $themeCode => $theme)
|
||||
<option value="{{ $themeCode }}" {{ old('theme') == $themeCode ? 'selected' : '' }}>
|
||||
{{ $theme['name'] }}
|
||||
</option>
|
||||
@endforeach
|
||||
</select>
|
||||
|
|
|
|||
|
|
@ -154,9 +154,9 @@
|
|||
<?php $selectedOption = old('theme') ?: $channel->theme ?>
|
||||
|
||||
<select class="control" id="theme" name="theme">
|
||||
@foreach (themes()->all() as $theme)
|
||||
<option value="{{ $theme->code }}" {{ $selectedOption == $theme->code ? 'selected' : '' }}>
|
||||
{{ $theme->name }}
|
||||
@foreach (config('themes.themes') as $themeCode => $theme)
|
||||
<option value="{{ $themeCode }}" {{ $selectedOption == $themeCode ? 'selected' : '' }}>
|
||||
{{ $theme['name'] }}
|
||||
</option>
|
||||
@endforeach
|
||||
</select>
|
||||
|
|
|
|||
|
|
@ -159,8 +159,6 @@ class AttributeController extends Controller
|
|||
$suppressFlash = true;
|
||||
|
||||
$this->attributeRepository->delete($value);
|
||||
} else {
|
||||
session()->flash('error', trans('admin::app.response.user-define-error', ['name' => 'Attribute']));
|
||||
}
|
||||
} catch (\Exception $e) {
|
||||
report($e);
|
||||
|
|
@ -174,7 +172,7 @@ class AttributeController extends Controller
|
|||
if ($suppressFlash) {
|
||||
session()->flash('success', trans('admin::app.datagrid.mass-ops.delete-success', ['resource' => 'attributes']));
|
||||
} else {
|
||||
session()->flash('info', trans('admin::app.datagrid.mass-ops.partial-action', ['resource' => 'attributes']));
|
||||
session()->flash('error', trans('admin::app.response.user-define-error', ['name' => 'Attribute']));
|
||||
}
|
||||
|
||||
return redirect()->back();
|
||||
|
|
|
|||
|
|
@ -24,6 +24,16 @@ class AttributeFamily extends Model implements AttributeFamilyContract
|
|||
->select('attributes.*');
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get all of the comparable attributes which belongs to attribute family.
|
||||
*/
|
||||
public function getComparableAttributesBelongsToFamily()
|
||||
{
|
||||
return (AttributeProxy::modelClass())::join('attribute_group_mappings', 'attribute_group_mappings.attribute_id', '=', 'attributes.id')
|
||||
->select('attributes.*')->where('attributes.is_comparable', 1)->get();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all of the attributes for the attribute groups.
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -0,0 +1,30 @@
|
|||
{
|
||||
"name": "bagisto/laravel-booking-product",
|
||||
"license": "MIT",
|
||||
"authors": [
|
||||
{
|
||||
"name": "Jitendra Singh",
|
||||
"email": "jitendra@webkul.com"
|
||||
}
|
||||
],
|
||||
"require": {
|
||||
"bagisto/laravel-core": "dev-master",
|
||||
"bagisto/laravel-rule": "dev-master",
|
||||
"bagisto/laravel-sales": "dev-master",
|
||||
"bagisto/laravel-product": "dev-master"
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Webkul\\BookingProduct\\": "src/"
|
||||
}
|
||||
},
|
||||
"extra": {
|
||||
"laravel": {
|
||||
"providers": [
|
||||
"Webkul\\BookingProduct\\Providers\\BookingProductServiceProvider"
|
||||
],
|
||||
"aliases": {}
|
||||
}
|
||||
},
|
||||
"minimum-stability": "dev"
|
||||
}
|
||||
|
|
@ -2,17 +2,17 @@
|
|||
|
||||
namespace Webkul\BookingProduct\Type;
|
||||
|
||||
use Illuminate\Support\Arr;
|
||||
use Webkul\Attribute\Repositories\AttributeRepository;
|
||||
use Webkul\Product\Repositories\ProductRepository;
|
||||
use Webkul\Product\Repositories\ProductAttributeValueRepository;
|
||||
use Webkul\Product\Repositories\ProductInventoryRepository;
|
||||
use Webkul\Product\Repositories\ProductImageRepository;
|
||||
use Webkul\Product\Helpers\ProductImage;
|
||||
use Webkul\BookingProduct\Repositories\BookingProductRepository;
|
||||
use Webkul\BookingProduct\Helpers\Booking as BookingHelper;
|
||||
use Webkul\Product\Type\Virtual;
|
||||
use Carbon\Carbon;
|
||||
use Illuminate\Support\Arr;
|
||||
use Webkul\Product\Type\Virtual;
|
||||
use Webkul\Product\Helpers\ProductImage;
|
||||
use Webkul\Product\Repositories\ProductRepository;
|
||||
use Webkul\Attribute\Repositories\AttributeRepository;
|
||||
use Webkul\Product\Repositories\ProductImageRepository;
|
||||
use Webkul\BookingProduct\Helpers\Booking as BookingHelper;
|
||||
use Webkul\Product\Repositories\ProductInventoryRepository;
|
||||
use Webkul\Product\Repositories\ProductAttributeValueRepository;
|
||||
use Webkul\BookingProduct\Repositories\BookingProductRepository;
|
||||
|
||||
class Booking extends Virtual
|
||||
{
|
||||
|
|
@ -30,6 +30,9 @@ class Booking extends Virtual
|
|||
*/
|
||||
protected $bookingHelper;
|
||||
|
||||
/** @var bool do not allow booking products to be copied, it would be too complicated. */
|
||||
protected $canBeCopied = false;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
|
|
@ -44,11 +47,11 @@ class Booking extends Virtual
|
|||
/**
|
||||
* Create a new product type instance.
|
||||
*
|
||||
* @param \Webkul\Attribute\Repositories\AttributeRepository $attributeRepository
|
||||
* @param \Webkul\Product\Repositories\ProductRepository $productRepository
|
||||
* @param \Webkul\Product\Repositories\ProductAttributeValueRepository $attributeValueRepository
|
||||
* @param \Webkul\Product\Repositories\ProductInventoryRepository $productInventoryRepository
|
||||
* @param \Webkul\Product\Repositories\ProductImageRepository $productImageRepository
|
||||
* @param \Webkul\Attribute\Repositories\AttributeRepository $attributeRepository
|
||||
* @param \Webkul\Product\Repositories\ProductRepository $productRepository
|
||||
* @param \Webkul\Product\Repositories\ProductAttributeValueRepository $attributeValueRepository
|
||||
* @param \Webkul\Product\Repositories\ProductInventoryRepository $productInventoryRepository
|
||||
* @param \Webkul\Product\Repositories\ProductImageRepository $productImageRepository
|
||||
* @param \Webkul\Product\Helpers\ProductImage $productImageHelper
|
||||
* @param \Webkul\BookingProduct\Repositories\BookingProductRepository $bookingProductRepository
|
||||
* @param \Webkul\BookingProduct\Helpers\BookingHelper $bookingHelper
|
||||
|
|
@ -133,7 +136,7 @@ class Booking extends Virtual
|
|||
if (! $bookingProduct) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
if (in_array($bookingProduct->type, ['default', 'rental', 'table'])) {
|
||||
return true;
|
||||
}
|
||||
|
|
@ -180,7 +183,7 @@ class Booking extends Virtual
|
|||
if ($bookingProduct->type == 'event') {
|
||||
if (Carbon::now() > $bookingProduct->available_from && Carbon::now() > $bookingProduct->available_to) {
|
||||
return trans('shop::app.checkout.cart.event.expired');
|
||||
}
|
||||
}
|
||||
|
||||
$filtered = Arr::where($data['booking']['qty'], function ($qty, $key) {
|
||||
return $qty != 0;
|
||||
|
|
@ -206,7 +209,7 @@ class Booking extends Virtual
|
|||
if (is_string($cartProducts)) {
|
||||
return $cartProducts;
|
||||
}
|
||||
|
||||
|
||||
$products = array_merge($products, $cartProducts);
|
||||
}
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -0,0 +1,28 @@
|
|||
{
|
||||
"name": "bagisto/laravel-cart-rule",
|
||||
"license": "MIT",
|
||||
"authors": [
|
||||
{
|
||||
"name": "Jitendra Singh",
|
||||
"email": "jitendra@webkul.com"
|
||||
}
|
||||
],
|
||||
"require": {
|
||||
"bagisto/laravel-core": "dev-master",
|
||||
"bagisto/laravel-rule": "dev-master"
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Webkul\\CartRule\\": "src/"
|
||||
}
|
||||
},
|
||||
"extra": {
|
||||
"laravel": {
|
||||
"providers": [
|
||||
"Webkul\\CartRule\\Providers\\CartRuleServiceProvider"
|
||||
],
|
||||
"aliases": {}
|
||||
}
|
||||
},
|
||||
"minimum-stability": "dev"
|
||||
}
|
||||
|
|
@ -275,19 +275,23 @@ class CartRule
|
|||
break;
|
||||
|
||||
case 'cart_fixed':
|
||||
if ($this->itemTotals[$rule->id]['total_items'] <= 1) {
|
||||
$discountAmount = core()->convertPrice($rule->discount_amount);
|
||||
// if ($this->itemTotals[$rule->id]['total_items'] <= 1) {
|
||||
// $discountAmount = core()->convertPrice($rule->discount_amount);
|
||||
|
||||
$baseDiscountAmount = min($item->base_price * $quantity, $rule->discount_amount);
|
||||
} else {
|
||||
$discountRate = $item->base_price * $quantity / $this->itemTotals[$rule->id]['base_total_price'];
|
||||
// $baseDiscountAmount = min($item->base_price * $quantity, $rule->discount_amount);
|
||||
// } else {
|
||||
// $discountRate = $item->base_price * $quantity / $this->itemTotals[$rule->id]['base_total_price'];
|
||||
|
||||
$maxDiscount = $rule->discount_amount * $discountRate;
|
||||
// $maxDiscount = $rule->discount_amount * $discountRate;
|
||||
|
||||
$discountAmount = core()->convertPrice($maxDiscount);
|
||||
// $discountAmount = core()->convertPrice($maxDiscount);
|
||||
|
||||
$baseDiscountAmount = min($item->base_price * $quantity, $maxDiscount);
|
||||
}
|
||||
// $baseDiscountAmount = min($item->base_price * $quantity, $maxDiscount);
|
||||
// }
|
||||
|
||||
$discountAmount = core()->convertPrice($rule->discount_amount);
|
||||
|
||||
$baseDiscountAmount = min($item->base_price * $quantity, $rule->discount_amount);
|
||||
|
||||
$discountAmount = min($item->price * $quantity, $discountAmount);
|
||||
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
namespace Webkul\CartRule\Http\Controllers;
|
||||
|
||||
use Exception;
|
||||
use Illuminate\View\View;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Event;
|
||||
|
|
@ -87,7 +88,7 @@ class CartRuleController extends Controller
|
|||
->replicate()
|
||||
->fill([
|
||||
'status' => 0,
|
||||
'name' => __('admin::app.copy-of') . ' ' . $originalCartRule->name,
|
||||
'name' => __('admin::app.copy-of') . $originalCartRule->name,
|
||||
]);
|
||||
|
||||
$copiedCartRule->save();
|
||||
|
|
@ -209,7 +210,7 @@ class CartRuleController extends Controller
|
|||
session()->flash('success', trans('admin::app.response.delete-success', ['name' => 'Cart Rule']));
|
||||
|
||||
return response()->json(['message' => true], 200);
|
||||
} catch (\Exception $e) {
|
||||
} catch (Exception $e) {
|
||||
session()->flash('error', trans('admin::app.response.delete-failed', ['name' => 'Cart Rule']));
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,28 @@
|
|||
{
|
||||
"name": "bagisto/laravel-catalog-rule",
|
||||
"license": "MIT",
|
||||
"authors": [
|
||||
{
|
||||
"name": "Jitendra Singh",
|
||||
"email": "jitendra@webkul.com"
|
||||
}
|
||||
],
|
||||
"require": {
|
||||
"bagisto/laravel-core": "dev-master",
|
||||
"bagisto/laravel-rule": "dev-master"
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Webkul\\CatalogRule\\": "src/"
|
||||
}
|
||||
},
|
||||
"extra": {
|
||||
"laravel": {
|
||||
"providers": [
|
||||
"Webkul\\CatalogRule\\Providers\\CatalogRuleServiceProvider"
|
||||
],
|
||||
"aliases": {}
|
||||
}
|
||||
},
|
||||
"minimum-stability": "dev"
|
||||
}
|
||||
|
|
@ -16,7 +16,7 @@
|
|||
"extra": {
|
||||
"laravel": {
|
||||
"providers": [
|
||||
"Webkul\\Checkout\\CheckoutServiceProvider"
|
||||
"Webkul\\Checkout\\Providers\\CheckoutServiceProvider"
|
||||
]
|
||||
}
|
||||
},
|
||||
|
|
|
|||
|
|
@ -886,6 +886,8 @@ class Cart
|
|||
*/
|
||||
public function prepareDataForOrderItem($data): array
|
||||
{
|
||||
$locale = ['locale' => core()->getCurrentLocale()->code];
|
||||
|
||||
$finalData = [
|
||||
'product' => $this->productRepository->find($data['product_id']),
|
||||
'sku' => $data['sku'],
|
||||
|
|
@ -904,7 +906,7 @@ class Cart
|
|||
'discount_percent' => $data['discount_percent'],
|
||||
'discount_amount' => $data['discount_amount'],
|
||||
'base_discount_amount' => $data['base_discount_amount'],
|
||||
'additional' => $data['additional'],
|
||||
'additional' => is_array($data['additional']) ? array_merge($data['additional'], $locale) : $locale,
|
||||
];
|
||||
|
||||
if (isset($data['children']) && $data['children']) {
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@
|
|||
"extra": {
|
||||
"laravel": {
|
||||
"providers": [
|
||||
"Webkul\\Inventory\\InventoryServiceProvider"
|
||||
"Webkul\\Inventory\\Providers\\InventoryServiceProvider"
|
||||
],
|
||||
"aliases": {}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,25 @@
|
|||
{
|
||||
"name": "bagisto/laravel-paypal",
|
||||
"license": "MIT",
|
||||
"authors": [
|
||||
{
|
||||
"name": "Jitendra Singh",
|
||||
"email": "jitendra@webkul.com"
|
||||
}
|
||||
],
|
||||
"require": {},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Webkul\\Payment\\": "src/"
|
||||
}
|
||||
},
|
||||
"extra": {
|
||||
"laravel": {
|
||||
"providers": [
|
||||
"Webkul\\Paypal\\Providers\\PaypalServiceProvider"
|
||||
],
|
||||
"aliases": {}
|
||||
}
|
||||
},
|
||||
"minimum-stability": "dev"
|
||||
}
|
||||
|
|
@ -2,16 +2,20 @@
|
|||
|
||||
namespace Webkul\Product\Http\Controllers;
|
||||
|
||||
use Exception;
|
||||
use Webkul\Product\Models\Product;
|
||||
use Illuminate\Support\Facades\Event;
|
||||
use Webkul\Product\Http\Requests\ProductForm;
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
use Webkul\Product\Helpers\ProductType;
|
||||
use Webkul\Category\Repositories\CategoryRepository;
|
||||
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;
|
||||
use Webkul\Product\Repositories\ProductAttributeValueRepository;
|
||||
|
||||
class ProductController extends Controller
|
||||
{
|
||||
|
|
@ -64,15 +68,24 @@ class ProductController extends Controller
|
|||
*/
|
||||
protected $inventorySourceRepository;
|
||||
|
||||
/**
|
||||
* ProductAttributeValueRepository object
|
||||
*
|
||||
* @var \Webkul\Product\Repositories\ProductAttributeValueRepository
|
||||
*/
|
||||
protected $productAttributeValueRepository;
|
||||
|
||||
/**
|
||||
* 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
|
||||
* @param \Webkul\Product\Repositories\ProductAttributeValueRepository $productAttributeValueRepository
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct(
|
||||
|
|
@ -81,7 +94,8 @@ class ProductController extends Controller
|
|||
ProductDownloadableLinkRepository $productDownloadableLinkRepository,
|
||||
ProductDownloadableSampleRepository $productDownloadableSampleRepository,
|
||||
AttributeFamilyRepository $attributeFamilyRepository,
|
||||
InventorySourceRepository $inventorySourceRepository
|
||||
InventorySourceRepository $inventorySourceRepository,
|
||||
ProductAttributeValueRepository $productAttributeValueRepository
|
||||
)
|
||||
{
|
||||
$this->_config = request('_config');
|
||||
|
|
@ -97,6 +111,8 @@ class ProductController extends Controller
|
|||
$this->attributeFamilyRepository = $attributeFamilyRepository;
|
||||
|
||||
$this->inventorySourceRepository = $inventorySourceRepository;
|
||||
|
||||
$this->productAttributeValueRepository = $productAttributeValueRepository;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -143,7 +159,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 +169,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 +182,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 +200,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 +219,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 +243,8 @@ class ProductController extends Controller
|
|||
/**
|
||||
* Uploads downloadable file
|
||||
*
|
||||
* @param int $id
|
||||
* @param int $id
|
||||
*
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function uploadLink($id)
|
||||
|
|
@ -235,10 +254,45 @@ class ProductController extends Controller
|
|||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Copy a given Product.
|
||||
*/
|
||||
public function copy(int $productId)
|
||||
{
|
||||
$originalProduct = $this->productRepository->findOrFail($productId);
|
||||
|
||||
if (! $originalProduct->getTypeInstance()->canBeCopied()) {
|
||||
session()->flash('error',
|
||||
trans('admin::app.response.product-can-not-be-copied', [
|
||||
'type' => $originalProduct->type,
|
||||
]));
|
||||
|
||||
return redirect()->to(route('admin.catalog.products.index'));
|
||||
}
|
||||
|
||||
if ($originalProduct->parent_id) {
|
||||
session()->flash('error',
|
||||
trans('admin::app.catalog.products.variant-already-exist-message'));
|
||||
|
||||
return redirect()->to(route('admin.catalog.products.index'));
|
||||
}
|
||||
|
||||
$copiedProduct = $this->productRepository->copy($originalProduct);
|
||||
|
||||
if ($copiedProduct instanceof Product && $copiedProduct->id) {
|
||||
session()->flash('success', trans('admin::app.response.product-copied'));
|
||||
} else {
|
||||
session()->flash('error', trans('admin::app.response.error-while-copying'));
|
||||
}
|
||||
|
||||
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 +305,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 +319,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,16 +418,17 @@ 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)
|
||||
{
|
||||
$productAttribute = $this->productAttributeValue->findOneWhere([
|
||||
$productAttribute = $this->productAttributeValueRepository->findOneWhere([
|
||||
'product_id' => $productId,
|
||||
'attribute_id' => $attributeId,
|
||||
]);
|
||||
|
|
|
|||
|
|
@ -2,11 +2,15 @@
|
|||
|
||||
namespace Webkul\Product\Models;
|
||||
|
||||
use Exception;
|
||||
use Webkul\Product\Type\AbstractType;
|
||||
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
|
||||
|
|
@ -59,7 +63,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()
|
||||
{
|
||||
|
|
@ -220,8 +225,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');
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -237,6 +242,12 @@ class Product extends Model implements ProductContract
|
|||
|
||||
$this->typeInstance = app(config('product_types.' . $this->type . '.class'));
|
||||
|
||||
if (! $this->typeInstance instanceof AbstractType) {
|
||||
throw new Exception(
|
||||
"Please ensure the product type '{$this->type}' is configured in your application."
|
||||
);
|
||||
}
|
||||
|
||||
$this->typeInstance->setProduct($this);
|
||||
|
||||
return $this->typeInstance;
|
||||
|
|
@ -283,6 +294,7 @@ class Product extends Model implements ProductContract
|
|||
*
|
||||
* @param Group $group
|
||||
* @param bool $skipSuperAttribute
|
||||
*
|
||||
* @return Collection
|
||||
*/
|
||||
public function getEditableAttributes($group = null, $skipSuperAttribute = true)
|
||||
|
|
@ -293,7 +305,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 +318,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 +340,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 +391,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);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -2,14 +2,20 @@
|
|||
|
||||
namespace Webkul\Product\Repositories;
|
||||
|
||||
use Illuminate\Pagination\Paginator;
|
||||
use Exception;
|
||||
use Illuminate\Support\Str;
|
||||
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 Webkul\Product\Models\Product;
|
||||
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 +29,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 +55,8 @@ class ProductRepository extends Repository
|
|||
}
|
||||
|
||||
/**
|
||||
* @param array $data
|
||||
* @param array $data
|
||||
*
|
||||
* @return \Webkul\Product\Contracts\Product
|
||||
*/
|
||||
public function create(array $data)
|
||||
|
|
@ -65,9 +73,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 +97,8 @@ class ProductRepository extends Repository
|
|||
}
|
||||
|
||||
/**
|
||||
* @param int $id
|
||||
* @param int $id
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function delete($id)
|
||||
|
|
@ -101,7 +111,8 @@ class ProductRepository extends Repository
|
|||
}
|
||||
|
||||
/**
|
||||
* @param int $categoryId
|
||||
* @param int $categoryId
|
||||
*
|
||||
* @return \Illuminate\Support\Collection
|
||||
*/
|
||||
public function getAll($categoryId = null)
|
||||
|
|
@ -111,21 +122,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 +160,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 +189,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 +207,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 +250,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 +261,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 +286,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 +306,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 +331,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 +352,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 +363,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 +394,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 +420,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 +447,72 @@ 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.
|
||||
*
|
||||
* 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(Product $originalProduct): Product
|
||||
{
|
||||
$this->fillOriginalProduct($originalProduct);
|
||||
|
||||
if (! $originalProduct->getTypeInstance()->canBeCopied()) {
|
||||
throw new Exception(trans('admin::app.response.product-can-not-be-copied', ['type' => $originalProduct->type]));
|
||||
}
|
||||
|
||||
DB::beginTransaction();
|
||||
|
||||
try {
|
||||
$copiedProduct = $this->persistCopiedProduct($originalProduct);
|
||||
|
||||
$this->persistAttributeValues($originalProduct, $copiedProduct);
|
||||
|
||||
$this->persistRelations($originalProduct, $copiedProduct);
|
||||
} catch (Exception $e) {
|
||||
DB::rollBack();
|
||||
|
||||
report($e);
|
||||
|
||||
throw $e;
|
||||
}
|
||||
|
||||
DB::commit();
|
||||
|
||||
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 +523,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)
|
||||
|
|
@ -481,13 +534,188 @@ class ProductRepository extends Repository
|
|||
$attribute = $this->attributeRepository->findOneByField('code', $sort);
|
||||
|
||||
if ($attribute) {
|
||||
if ($attribute->code == 'price') {
|
||||
if ($attribute->code === 'price') {
|
||||
$query->orderBy('min_price', $direction);
|
||||
} else {
|
||||
$query->orderBy($sort == 'created_at' ? 'product_flat.created_at' : $attribute->code, $direction);
|
||||
$query->orderBy($sort === 'created_at' ? 'product_flat.created_at' : $attribute->code, $direction);
|
||||
}
|
||||
}
|
||||
|
||||
return $query;
|
||||
}
|
||||
|
||||
private function fillOriginalProduct(Product &$sourceProduct): void
|
||||
{
|
||||
$sourceProduct
|
||||
->load('attribute_family')
|
||||
->load('categories')
|
||||
->load('customer_group_prices')
|
||||
->load('inventories')
|
||||
->load('inventory_sources');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $originalProduct
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
private function persistCopiedProduct($originalProduct): Product
|
||||
{
|
||||
$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;
|
||||
|
||||
$attributesToSkip = config('products.skipAttributesOnCopy') ?? [];
|
||||
|
||||
$randomSuffix = substr(md5(microtime()), 0, 6);
|
||||
|
||||
foreach ($originalProduct->attribute_values as $oldValue) {
|
||||
if (in_array($oldValue->attribute->code, $attributesToSkip)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$newValue = $oldValue->replicate();
|
||||
|
||||
// change name of copied product
|
||||
if ($oldValue->attribute_id === $attributeIds['name']) {
|
||||
$copyOf = trans('admin::app.copy-of');
|
||||
$copiedName = sprintf('%s%s (%s)',
|
||||
Str::startsWith($originalProduct->name, $copyOf) ? '' : $copyOf,
|
||||
$originalProduct->name,
|
||||
$randomSuffix
|
||||
);
|
||||
$newValue->text_value = $copiedName;
|
||||
$newProductFlat->name = $copiedName;
|
||||
}
|
||||
|
||||
// change url_key of copied product
|
||||
if ($oldValue->attribute_id === $attributeIds['url_key']) {
|
||||
$copyOfSlug = trans('admin::app.copy-of-slug');
|
||||
$copiedSlug = sprintf('%s%s-%s',
|
||||
Str::startsWith($originalProduct->url_key, $copyOfSlug) ? '' : $copyOfSlug,
|
||||
$originalProduct->url_key,
|
||||
$randomSuffix
|
||||
);
|
||||
$newValue->text_value = $copiedSlug;
|
||||
$newProductFlat->url_key = $copiedSlug;
|
||||
}
|
||||
|
||||
// change sku of copied product
|
||||
if ($oldValue->attribute_id === $attributeIds['sku']) {
|
||||
$newValue->text_value = $copiedProduct->sku;
|
||||
$newProductFlat->sku = $copiedProduct->sku;
|
||||
}
|
||||
|
||||
// force the copied product to be inactive so the admin can adjust it before release
|
||||
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
|
||||
{
|
||||
$attributesToSkip = config('products.skipAttributesOnCopy') ?? [];
|
||||
|
||||
if (! in_array('categories', $attributesToSkip)) {
|
||||
foreach ($originalProduct->categories as $category) {
|
||||
DB::table('product_categories')->insert([
|
||||
'product_id' => $copiedProduct->id,
|
||||
'category_id' => $category->id,
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
if (! in_array('inventories', $attributesToSkip)) {
|
||||
foreach ($originalProduct->inventories as $inventory) {
|
||||
$copiedProduct->inventories()->save($inventory->replicate());
|
||||
}
|
||||
}
|
||||
|
||||
if (! in_array('customer_group_pricces', $attributesToSkip)) {
|
||||
foreach ($originalProduct->customer_group_prices as $customer_group_price) {
|
||||
$copiedProduct->customer_group_prices()->save($customer_group_price->replicate());
|
||||
}
|
||||
}
|
||||
|
||||
if (! in_array('images', $attributesToSkip)) {
|
||||
foreach ($originalProduct->images as $image) {
|
||||
$copiedProduct->images()->save($image->replicate());
|
||||
}
|
||||
}
|
||||
|
||||
if (! in_array('super_attributes', $attributesToSkip)) {
|
||||
foreach ($originalProduct->super_attributes as $super_attribute) {
|
||||
$copiedProduct->super_attributes()->save($super_attribute);
|
||||
}
|
||||
}
|
||||
|
||||
if (! in_array('bundle_options', $attributesToSkip)) {
|
||||
foreach ($originalProduct->bundle_options as $bundle_option) {
|
||||
$copiedProduct->bundle_options()->save($bundle_option->replicate());
|
||||
}
|
||||
}
|
||||
|
||||
if (! in_array('variants', $attributesToSkip)) {
|
||||
foreach ($originalProduct->variants as $variant) {
|
||||
$variant = $this->copy($variant);
|
||||
$variant->parent_id = $copiedProduct->id;
|
||||
$variant->save();
|
||||
}
|
||||
}
|
||||
|
||||
if (config('products.linkProductsOnCopy')) {
|
||||
DB::table('product_relations')->insert([
|
||||
'parent_id' => $originalProduct->id,
|
||||
'child_id' => $copiedProduct->id,
|
||||
]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -2,16 +2,15 @@
|
|||
|
||||
namespace Webkul\Product\Type;
|
||||
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
use phpDocumentor\Reflection\Types\Boolean;
|
||||
use Webkul\Attribute\Repositories\AttributeRepository;
|
||||
use Webkul\Product\Repositories\ProductRepository;
|
||||
use Webkul\Product\Repositories\ProductAttributeValueRepository;
|
||||
use Webkul\Product\Repositories\ProductInventoryRepository;
|
||||
use Webkul\Product\Repositories\ProductImageRepository;
|
||||
use Webkul\Product\Models\ProductAttributeValue;
|
||||
use Webkul\Product\Helpers\ProductImage;
|
||||
use Webkul\Checkout\Facades\Cart;
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
use Webkul\Product\Helpers\ProductImage;
|
||||
use Webkul\Product\Models\ProductAttributeValue;
|
||||
use Webkul\Product\Repositories\ProductRepository;
|
||||
use Webkul\Attribute\Repositories\AttributeRepository;
|
||||
use Webkul\Product\Repositories\ProductImageRepository;
|
||||
use Webkul\Product\Repositories\ProductInventoryRepository;
|
||||
use Webkul\Product\Repositories\ProductAttributeValueRepository;
|
||||
|
||||
abstract class AbstractType
|
||||
{
|
||||
|
|
@ -54,7 +53,7 @@ abstract class AbstractType
|
|||
* Product Image helper instance
|
||||
*
|
||||
* @var \Webkul\Product\Helpers\ProductImage
|
||||
*/
|
||||
*/
|
||||
protected $productImageHelper;
|
||||
|
||||
/**
|
||||
|
|
@ -99,6 +98,13 @@ abstract class AbstractType
|
|||
*/
|
||||
protected $canBeMovedFromWishlistToCart = true;
|
||||
|
||||
/**
|
||||
* Products of this type can be copied in the admin backend?
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
protected $canBeCopied = true;
|
||||
|
||||
/**
|
||||
* Has child products aka variants
|
||||
*
|
||||
|
|
@ -152,7 +158,16 @@ abstract class AbstractType
|
|||
}
|
||||
|
||||
/**
|
||||
* @param array $data
|
||||
* Is the administrator able to copy products of this type in the admin backend?
|
||||
*/
|
||||
public function canBeCopied(): bool
|
||||
{
|
||||
return $this->canBeCopied;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $data
|
||||
*
|
||||
* @return \Webkul\Product\Contracts\Product
|
||||
*/
|
||||
public function create(array $data)
|
||||
|
|
@ -162,8 +177,8 @@ abstract class AbstractType
|
|||
|
||||
/**
|
||||
* @param array $data
|
||||
* @param int $id
|
||||
* @param string $attribute
|
||||
* @param int $id
|
||||
* @param string $attribute
|
||||
* @return \Webkul\Product\Contracts\Product
|
||||
*/
|
||||
public function update(array $data, $id, $attribute = "id")
|
||||
|
|
@ -175,7 +190,7 @@ abstract class AbstractType
|
|||
foreach ($product->attribute_family->custom_attributes as $attribute) {
|
||||
$route = request()->route() ? request()->route()->getName() : "";
|
||||
|
||||
if ($attribute->type == 'boolean' && $route != 'admin.catalog.products.massupdate') {
|
||||
if ($attribute->type === 'boolean' && $route !== 'admin.catalog.products.massupdate') {
|
||||
$data[$attribute->code] = isset($data[$attribute->code]) && $data[$attribute->code] ? 1 : 0;
|
||||
}
|
||||
|
||||
|
|
@ -197,8 +212,8 @@ abstract class AbstractType
|
|||
|
||||
if ($attribute->type == 'image' || $attribute->type == 'file') {
|
||||
$data[$attribute->code] = gettype($data[$attribute->code]) == 'object'
|
||||
? request()->file($attribute->code)->store('product/' . $product->id)
|
||||
: NULL;
|
||||
? request()->file($attribute->code)->store('product/' . $product->id)
|
||||
: NULL;
|
||||
}
|
||||
|
||||
$attributeValue = $this->attributeValueRepository->findOneWhere([
|
||||
|
|
@ -219,7 +234,7 @@ abstract class AbstractType
|
|||
} else {
|
||||
$this->attributeValueRepository->update([
|
||||
ProductAttributeValue::$attributeTypeFields[$attribute->type] => $data[$attribute->code]
|
||||
], $attributeValue->id
|
||||
], $attributeValue->id
|
||||
);
|
||||
|
||||
if ($attribute->type == 'image' || $attribute->type == 'file') {
|
||||
|
|
@ -230,8 +245,8 @@ abstract class AbstractType
|
|||
|
||||
$route = request()->route() ? request()->route()->getName() : "";
|
||||
|
||||
if ($route != 'admin.catalog.products.massupdate') {
|
||||
if (! isset($data['categories'])) {
|
||||
if ($route !== 'admin.catalog.products.massupdate') {
|
||||
if (! isset($data['categories'])) {
|
||||
$data['categories'] = [];
|
||||
}
|
||||
|
||||
|
|
@ -376,9 +391,9 @@ abstract class AbstractType
|
|||
$total = 0;
|
||||
|
||||
$channelInventorySourceIds = core()->getCurrentChannel()
|
||||
->inventory_sources()
|
||||
->where('status', 1)
|
||||
->pluck('id');
|
||||
->inventory_sources()
|
||||
->where('status', 1)
|
||||
->pluck('id');
|
||||
|
||||
foreach ($this->product->inventories as $inventory) {
|
||||
if (is_numeric($index = $channelInventorySourceIds->search($inventory->inventory_source_id))) {
|
||||
|
|
@ -387,8 +402,8 @@ abstract class AbstractType
|
|||
}
|
||||
|
||||
$orderedInventory = $this->product->ordered_inventories()
|
||||
->where('channel_id', core()->getCurrentChannel()->id)
|
||||
->first();
|
||||
->where('channel_id', core()->getCurrentChannel()->id)
|
||||
->first();
|
||||
|
||||
if ($orderedInventory) {
|
||||
$total -= $orderedInventory->qty;
|
||||
|
|
@ -539,8 +554,10 @@ abstract class AbstractType
|
|||
if ($haveSpecialPrice) {
|
||||
$this->product->special_price = min($this->product->special_price, $customerGroupPrice);
|
||||
} else {
|
||||
$haveSpecialPrice = true;
|
||||
$this->product->special_price = $customerGroupPrice;
|
||||
if ($customerGroupPrice != $this->product->price) {
|
||||
$haveSpecialPrice = true;
|
||||
$this->product->special_price = $customerGroupPrice;
|
||||
}
|
||||
}
|
||||
|
||||
return $haveSpecialPrice;
|
||||
|
|
@ -571,8 +588,8 @@ abstract class AbstractType
|
|||
|
||||
$customerGroupPrices = $product->customer_group_prices()->where(function ($query) use ($customerGroupId) {
|
||||
$query->where('customer_group_id', $customerGroupId)
|
||||
->orWhereNull('customer_group_id');
|
||||
}
|
||||
->orWhereNull('customer_group_id');
|
||||
}
|
||||
)->get();
|
||||
|
||||
if (! $customerGroupPrices->count()) {
|
||||
|
|
|
|||
|
|
@ -0,0 +1,26 @@
|
|||
{
|
||||
"name": "bagisto/laravel-rule",
|
||||
"license": "MIT",
|
||||
"authors": [
|
||||
{
|
||||
"name": "Jitendra Singh",
|
||||
"email": "jitendra@webkul.com"
|
||||
}
|
||||
],
|
||||
"require": {
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Webkul\\Rule\\": "src/"
|
||||
}
|
||||
},
|
||||
"extra": {
|
||||
"laravel": {
|
||||
"providers": [
|
||||
"Webkul\\Rule\\Providers\\RuleServiceProvider"
|
||||
],
|
||||
"aliases": {}
|
||||
}
|
||||
},
|
||||
"minimum-stability": "dev"
|
||||
}
|
||||
|
|
@ -254,7 +254,7 @@ class InvoiceRepository extends Repository
|
|||
return $invoice;
|
||||
}
|
||||
|
||||
/**
|
||||
/*
|
||||
* @param \Webkul\Sales\Contracts\Invoice $invoice
|
||||
* @return void
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -0,0 +1,11 @@
|
|||
; DO NOT EDIT (unless you know what you are doing)
|
||||
;
|
||||
; This subdirectory is a git "subrepo", and this file is maintained by the
|
||||
; git-subrepo command. See https://github.com/git-commands/git-subrepo#readme
|
||||
;
|
||||
[subrepo]
|
||||
remote = git@github.com:bagistobrasil/core-shop.git
|
||||
branch = master
|
||||
commit =
|
||||
method = merge
|
||||
cmdver = 0.4.1
|
||||
File diff suppressed because one or more lines are too long
|
|
@ -1,4 +1,4 @@
|
|||
{
|
||||
"/js/shop.js": "/js/shop.js?id=d64fdfe9e3fe3e4b9ee4",
|
||||
"/css/shop.css": "/css/shop.css?id=72d87fe2508fdcd9f397"
|
||||
"/css/shop.css": "/css/shop.css?id=8ef1aa65dda3180b66ee"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@ return [
|
|||
'sort' => 4,
|
||||
], [
|
||||
'key' => 'account.compare',
|
||||
'name' => 'velocity::app.customer.compare.text',
|
||||
'name' => 'shop::app.customer.compare.text',
|
||||
'route' =>'velocity.customer.product.compare',
|
||||
'sort' => 5,
|
||||
], [
|
||||
|
|
|
|||
|
|
@ -4286,10 +4286,6 @@ section.review {
|
|||
}
|
||||
}
|
||||
|
||||
.checkbox {
|
||||
margin: 10px 0px 5px 5px;
|
||||
}
|
||||
|
||||
.radio {
|
||||
margin: 10px 0px 5px 5px;
|
||||
|
||||
|
|
@ -4304,11 +4300,22 @@ section.review {
|
|||
}
|
||||
}
|
||||
|
||||
.radio-container .checkmark {
|
||||
top: 2px;
|
||||
left: 4px;
|
||||
}
|
||||
|
||||
.mt-5 {
|
||||
margin-top: 5px;
|
||||
margin-right: 28px;
|
||||
}
|
||||
|
||||
@media only screen and (max-width: 770px) {
|
||||
.checkout-process .col-main {
|
||||
padding-left: 0px;
|
||||
}
|
||||
}
|
||||
|
||||
//checkout process page end here
|
||||
|
||||
//customer page start here
|
||||
|
|
|
|||
|
|
@ -176,6 +176,11 @@ return [
|
|||
'dashboard' => 'الملف الشخصي',
|
||||
'menu' => 'القائمة',
|
||||
|
||||
'general' => [
|
||||
'no' => 'لا',
|
||||
'yes' => 'نعم',
|
||||
],
|
||||
|
||||
'profile' => [
|
||||
'index' => [
|
||||
'page-title' => 'الملف الشخصي',
|
||||
|
|
|
|||
|
|
@ -176,6 +176,11 @@ return [
|
|||
'dashboard' => 'Profil bearbeiten',
|
||||
'menu' => 'Menu',
|
||||
|
||||
'general' => [
|
||||
'no' => 'Nein',
|
||||
'yes' => 'Ja',
|
||||
],
|
||||
|
||||
'profile' => [
|
||||
'index' => [
|
||||
'page-title' => 'Profil',
|
||||
|
|
|
|||
|
|
@ -176,6 +176,11 @@ return [
|
|||
'dashboard' => 'Edit Profile',
|
||||
'menu' => 'Menu',
|
||||
|
||||
'general' => [
|
||||
'no' => 'No',
|
||||
'yes' => 'Yes',
|
||||
],
|
||||
|
||||
'profile' => [
|
||||
'index' => [
|
||||
'page-title' => 'Profile',
|
||||
|
|
|
|||
|
|
@ -173,6 +173,11 @@ return [
|
|||
'dashboard' => 'Cliente - Editar perfil',
|
||||
'menu' => 'Menu',
|
||||
|
||||
'general' => [
|
||||
'no' => 'No',
|
||||
'yes' => 'si',
|
||||
],
|
||||
|
||||
'profile' => [
|
||||
'index' => [
|
||||
'page-title' => 'Cliente - Perfil',
|
||||
|
|
|
|||
|
|
@ -176,6 +176,11 @@ return [
|
|||
'dashboard' => 'مشتری - ویرایش نمایه',
|
||||
'menu' => 'فهرست',
|
||||
|
||||
'general' => [
|
||||
'no' => 'نه',
|
||||
'yes' => 'آره',
|
||||
],
|
||||
|
||||
'profile' => [
|
||||
'index' => [
|
||||
'page-title' => 'مشتری - پروفایل',
|
||||
|
|
|
|||
|
|
@ -174,6 +174,11 @@ return [
|
|||
'dashboard' => 'Modifica Profilo',
|
||||
'menu' => 'Menu',
|
||||
|
||||
'general' => [
|
||||
'no' => 'No',
|
||||
'yes' => 'sì',
|
||||
],
|
||||
|
||||
'profile' => [
|
||||
'index' => [
|
||||
'page-title' => 'Profilo',
|
||||
|
|
|
|||
|
|
@ -173,6 +173,11 @@ return [
|
|||
'dashboard' => 'プロフィールを編集',
|
||||
'menu' => 'メニュー',
|
||||
|
||||
'general' => [
|
||||
'no' => '番号',
|
||||
'yes' => 'はい',
|
||||
],
|
||||
|
||||
'profile' => [
|
||||
'index' => [
|
||||
'page-title' => 'プロフィール',
|
||||
|
|
|
|||
|
|
@ -181,6 +181,11 @@ return [
|
|||
'dashboard' => 'Edit Profile',
|
||||
'menu' => 'Menu',
|
||||
|
||||
'general' => [
|
||||
'no' => 'Nee',
|
||||
'yes' => 'Ja',
|
||||
],
|
||||
|
||||
'profile' => [
|
||||
'index' => [
|
||||
'page-title' => 'Profiel',
|
||||
|
|
|
|||
|
|
@ -174,6 +174,11 @@ return [
|
|||
'dashboard' => 'Edytuj profil',
|
||||
'menu' => 'Menu',
|
||||
|
||||
'general' => [
|
||||
'no' => 'Nie',
|
||||
'yes' => 'tak',
|
||||
],
|
||||
|
||||
'profile' => [
|
||||
'index' => [
|
||||
'page-title' => 'Profil',
|
||||
|
|
|
|||
|
|
@ -174,6 +174,11 @@ return [
|
|||
'dashboard' => 'Cliente - Perfil',
|
||||
'menu' => 'Menu',
|
||||
|
||||
'general' => [
|
||||
'no' => 'Não',
|
||||
'yes' => 'sim',
|
||||
],
|
||||
|
||||
'profile' => [
|
||||
'index' => [
|
||||
'page-title' => 'Cliente - Perfil',
|
||||
|
|
|
|||
|
|
@ -173,6 +173,11 @@ return [
|
|||
'dashboard' => 'Profil Düzenle',
|
||||
'menu' => 'Menü',
|
||||
|
||||
'general' => [
|
||||
'no' => 'Hayır',
|
||||
'yes' => 'Evet',
|
||||
],
|
||||
|
||||
'profile' => [
|
||||
'index' => [
|
||||
'page-title' => 'Profil',
|
||||
|
|
|
|||
|
|
@ -16,13 +16,11 @@
|
|||
<div class="line-one">
|
||||
<label class="radio-container">
|
||||
<input v-validate="'required'" type="radio" id="{{ $payment['method'] }}" name="payment[method]" value="{{ $payment['method'] }}" v-model="payment.method" @change="methodSelected()" data-vv-as=""{{ __('shop::app.checkout.onepage.payment-method') }}"">
|
||||
|
||||
<span class="checkmark"></span>
|
||||
|
||||
<span class="payment-method method-label">
|
||||
<b>{{ $payment['method_title'] }}</b>
|
||||
</span>
|
||||
</label>
|
||||
<span class="payment-method method-label">
|
||||
<b>{{ $payment['method_title'] }}</b>
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div class="line-two mt-5">
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
@include('shop::guest.compare.compare-products')
|
||||
|
||||
@section('page_title')
|
||||
{{ __('velocity::app.customer.compare.compare_similar_items') }}
|
||||
{{ __('shop::app.customer.compare.compare_similar_items') }}
|
||||
@endsection
|
||||
|
||||
@section('content-wrapper')
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@
|
|||
|
||||
|
||||
@if ($order->canCancel())
|
||||
<a href="{{ route('customer.orders.cancel', $order->id) }}" class="btn btn-lg btn-primary" v-alert:message="'{{ __('shop::app.customer.account.order.view.cancel-confirm-msg') }}'">
|
||||
<a href="{{ route('customer.orders.cancel', $order->id) }}" class="btn btn-lg btn-primary" v-alert:message="'{{ __('shop::app.customer.account.order.view.cancel-confirm-msg') }}'" style="float: right;">
|
||||
{{ __('shop::app.customer.account.order.view.cancel-btn-title') }}
|
||||
</a>
|
||||
@endif
|
||||
|
|
|
|||
|
|
@ -1,13 +1,17 @@
|
|||
@php
|
||||
$attributeRepository = app('\Webkul\Attribute\Repositories\AttributeRepository');
|
||||
$comparableAttributes = $attributeRepository->findByField('is_comparable', 1);
|
||||
$attributeRepository = app('\Webkul\Attribute\Repositories\AttributeFamilyRepository');
|
||||
$comparableAttributes = $attributeRepository->getComparableAttributesBelongsToFamily();
|
||||
|
||||
$locale = request()->get('locale') ?: app()->getLocale();
|
||||
|
||||
$attributeOptionTranslations = DB::table('attribute_option_translations')->where('locale', $locale)->get()->toJson();
|
||||
@endphp
|
||||
|
||||
@push('scripts')
|
||||
<script type="text/x-template" id="compare-product-template">
|
||||
<section class="comparison-component">
|
||||
<h1>
|
||||
{{ __('velocity::app.customer.compare.compare_similar_items') }}
|
||||
{{ __('shop::app.customer.compare.compare_similar_items') }}
|
||||
</h1>
|
||||
|
||||
<button
|
||||
|
|
@ -25,13 +29,13 @@
|
|||
$comparableAttributes = $comparableAttributes->toArray();
|
||||
|
||||
array_splice($comparableAttributes, 1, 0, [[
|
||||
'code' => 'image',
|
||||
'admin_name' => 'Product Image'
|
||||
'code' => 'product_image',
|
||||
'admin_name' => __('velocity::app.customer.compare.product_image'),
|
||||
]]);
|
||||
|
||||
array_splice($comparableAttributes, 2, 0, [[
|
||||
'code' => 'addToCartHtml',
|
||||
'admin_name' => 'Actions'
|
||||
'admin_name' => __('velocity::app.customer.compare.actions'),
|
||||
]]);
|
||||
@endphp
|
||||
|
||||
|
|
@ -49,7 +53,7 @@
|
|||
</a>
|
||||
@break
|
||||
|
||||
@case('image')
|
||||
@case('product_image')
|
||||
<a :href="`${baseUrl}/${product.url_key}`" class="unset">
|
||||
<img
|
||||
class="image-wrapper"
|
||||
|
|
@ -91,12 +95,25 @@
|
|||
: '{{ __('velocity::app.shop.general.no') }}'"
|
||||
></span>
|
||||
@break;
|
||||
@case('file')
|
||||
<a v-if="product.product['{{ $attribute['code'] }}']" :href="`${baseUrl}/storage/${product.product['{{ $attribute['code'] }}']}`">
|
||||
<span v-text="product.product['{{ $attribute['code'] }}'].substr(product.product['{{ $attribute['code'] }}'].lastIndexOf('/') + 1)" class="fs16"></span>
|
||||
<i class='icon sort-down-icon download'></i>
|
||||
|
||||
@case('checkbox')
|
||||
<span v-if="product.product['{{ $attribute['code'] }}']" v-html="getAttributeOptions(product['{{ $attribute['code'] }}'] ? product : product.product['{{ $attribute['code'] }}'] ? product.product : null, '{{ $attribute['code'] }}', 'multiple')" class="fs16"></span>
|
||||
<span v-else class="fs16">__</span>
|
||||
@break;
|
||||
|
||||
@case('select')
|
||||
<span v-if="product.product['{{ $attribute['code'] }}']" v-html="getAttributeOptions(product['{{ $attribute['code'] }}'] ? product : product.product['{{ $attribute['code'] }}'] ? product.product : null, '{{ $attribute['code'] }}', 'single')" class="fs16"></span>
|
||||
<span v-else class="fs16">__</span>
|
||||
@break;
|
||||
|
||||
@case ('file')
|
||||
@case ('image')
|
||||
<a :href="`${baseUrl}/${product.url_key}`" class="unset">
|
||||
<img
|
||||
class="image-wrapper"
|
||||
:src="'storage/' + product.product['{{ $attribute['code'] }}']"
|
||||
:onerror="`this.src='${baseUrl}/vendor/webkul/ui/assets/images/product/large-product-placeholder.png'`" />
|
||||
</a>
|
||||
<a v-else class="fs16">__</span>
|
||||
@break;
|
||||
@default
|
||||
<span v-html="product['{{ $attribute['code'] }}'] ? product['{{ $attribute['code'] }}'] : product.product['{{ $attribute['code'] }}'] ? product.product['{{ $attribute['code'] }}'] : '__'" class="fs16"></span>
|
||||
|
|
@ -105,14 +122,14 @@
|
|||
|
||||
@break
|
||||
|
||||
@endswitch
|
||||
@endswitch
|
||||
</td>
|
||||
</tr>
|
||||
@endforeach
|
||||
</template>
|
||||
|
||||
<span v-else-if="isProductListLoaded && products.length == 0">
|
||||
{{ __('velocity::app.customer.compare.empty-text') }}
|
||||
{{ __('shop::app.customer.compare.empty-text') }}
|
||||
</span>
|
||||
</table>
|
||||
|
||||
|
|
@ -129,6 +146,7 @@
|
|||
'products': [],
|
||||
'isProductListLoaded': false,
|
||||
'baseUrl': "{{ url()->to('/') }}",
|
||||
'attributeOptions': JSON.parse(@json($attributeOptionTranslations)),
|
||||
'isCustomer': '{{ auth()->guard('customer')->user() ? "true" : "false" }}' == "true",
|
||||
}
|
||||
},
|
||||
|
|
@ -170,7 +188,7 @@
|
|||
})
|
||||
.catch(error => {
|
||||
this.isProductListLoaded = true;
|
||||
console.log("{{ __('velocity::app.error.something_went_wrong') }}");
|
||||
console.log("{{ __('shop::app.common.error') }}");
|
||||
});
|
||||
} else {
|
||||
this.isProductListLoaded = true;
|
||||
|
|
@ -193,7 +211,7 @@
|
|||
this.$root.addFlashMessages();
|
||||
})
|
||||
.catch(error => {
|
||||
console.log("{{ __('velocity::app.error.something_went_wrong') }}");
|
||||
console.log("{{ __('shop::app.common.error') }}");
|
||||
});
|
||||
} else {
|
||||
let existingItems = this.getStorageValue('compared_product');
|
||||
|
|
@ -201,17 +219,19 @@
|
|||
if (productId == "all") {
|
||||
updatedItems = [];
|
||||
this.$set(this, 'products', []);
|
||||
window.flashMessages = [{'type': 'alert-success', 'message': '{{ __('velocity::app.customer.compare.removed-all') }}' }];
|
||||
window.flashMessages = [{'type': 'alert-success', 'message': '{{ __('shop::app.customer.compare.removed-all') }}' }];
|
||||
} else {
|
||||
updatedItems = existingItems.filter(item => item != productId);
|
||||
this.$set(this, 'products', this.products.filter(product => product.id != productId));
|
||||
window.flashMessages = [{'type': 'alert-success', 'message': '{{ __('velocity::app.customer.compare.removed') }}' }];
|
||||
window.flashMessages = [{'type': 'alert-success', 'message': '{{ __('shop::app.customer.compare.removed') }}' }];
|
||||
}
|
||||
|
||||
this.setStorageValue('compared_product', updatedItems);
|
||||
|
||||
this.$root.addFlashMessages();
|
||||
}
|
||||
|
||||
this.updateCompareCount();
|
||||
},
|
||||
|
||||
'getDynamicHTML': function (input) {
|
||||
|
|
@ -258,6 +278,64 @@
|
|||
|
||||
return true;
|
||||
},
|
||||
|
||||
'getAttributeOptions': function (productDetails, attributeValues, type) {
|
||||
var attributeOptions = '__';
|
||||
|
||||
if (productDetails && attributeValues) {
|
||||
var attributeItems;
|
||||
|
||||
if (type == "multiple") {
|
||||
attributeItems = productDetails[attributeValues].split(',');
|
||||
} else if (type == "single") {
|
||||
attributeItems = productDetails[attributeValues];
|
||||
}
|
||||
|
||||
attributeOptions = this.attributeOptions.filter(option => {
|
||||
if (type == "multiple") {
|
||||
if (attributeItems.indexOf(option.attribute_option_id.toString()) > -1) {
|
||||
return true;
|
||||
}
|
||||
} else if (type == "single") {
|
||||
if (attributeItems == option.attribute_option_id.toString()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
});
|
||||
|
||||
attributeOptions = attributeOptions.map(option => {
|
||||
return option.label;
|
||||
});
|
||||
|
||||
attributeOptions = attributeOptions.join(', ');
|
||||
}
|
||||
|
||||
return attributeOptions;
|
||||
},
|
||||
|
||||
'updateCompareCount': function () {
|
||||
if (this.isCustomer == "true" || this.isCustomer == true) {
|
||||
this.$http.get(`${this.baseUrl}/items-count`)
|
||||
.then(response => {
|
||||
$('#compare-items-count').html(response.data.compareProductsCount);
|
||||
})
|
||||
.catch(exception => {
|
||||
window.flashMessages = [{
|
||||
'type': `alert-error`,
|
||||
'message': "{{ __('shop::app.common.error') }}"
|
||||
}];
|
||||
|
||||
this.$root.addFlashMessages();
|
||||
});
|
||||
} else {
|
||||
let comparedItems = JSON.parse(localStorage.getItem('compared_product'));
|
||||
comparedItemsCount = comparedItems ? comparedItems.length : 0;
|
||||
|
||||
$('#compare-items-count').html(comparedItemsCount);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
@include('shop::guest.compare.compare-products')
|
||||
|
||||
@section('page_title')
|
||||
{{ __('velocity::app.customer.compare.compare_similar_items') }}
|
||||
{{ __('shop::app.customer.compare.compare_similar_items') }}
|
||||
@endsection
|
||||
|
||||
@section('content-wrapper')
|
||||
|
|
|
|||
|
|
@ -55,7 +55,7 @@
|
|||
{!! view_render_event('bagisto.shop.layout.header.comppare-item.before') !!}
|
||||
|
||||
@php
|
||||
$showCompare = core()->getConfigData('general.content.shop.compare_option') == "1" ? true : false
|
||||
$showCompare = core()->getConfigData('general.content.shop.compare_option') == "1" ? true : false
|
||||
@endphp
|
||||
|
||||
@if ($showCompare)
|
||||
|
|
@ -70,8 +70,8 @@
|
|||
@endguest
|
||||
style="color: #242424;"
|
||||
>
|
||||
<span class="name">{{ __('velocity::app.customer.compare.text') }}</span>
|
||||
|
||||
<span class="name">{{ __('shop::app.customer.compare.text') }}</span>
|
||||
(<span id="compare-items-count"></span>)
|
||||
</a>
|
||||
</li>
|
||||
@endif
|
||||
|
|
@ -202,7 +202,7 @@
|
|||
<button style="background: none; border: none; padding: 0px;">
|
||||
<i class="icon icon-search"></i>
|
||||
</button>
|
||||
|
||||
|
||||
<image-search-component></image-search-component>
|
||||
|
||||
<input type="search" name="term" class="search">
|
||||
|
|
@ -297,7 +297,7 @@
|
|||
localStorage.searched_image_url = self.uploaded_image_url;
|
||||
|
||||
queryString = localStorage.searched_terms = analysedResult.join('_');
|
||||
|
||||
|
||||
self.$root.hideLoader();
|
||||
|
||||
window.location.href = "{{ route('shop.search.index') }}" + '?term=' + queryString + '&image-search=1';
|
||||
|
|
@ -336,6 +336,23 @@
|
|||
toggleDropdown(e);
|
||||
});
|
||||
|
||||
@auth('customer')
|
||||
@php
|
||||
$compareCount = app('Webkul\Velocity\Repositories\VelocityCustomerCompareProductRepository')
|
||||
->count([
|
||||
'customer_id' => auth()->guard('customer')->user()->id,
|
||||
]);
|
||||
@endphp
|
||||
|
||||
let comparedItems = JSON.parse(localStorage.getItem('compared_product'));
|
||||
$('#compare-items-count').html({{ $compareCount }});
|
||||
@endauth
|
||||
|
||||
@guest('customer')
|
||||
let comparedItems = JSON.parse(localStorage.getItem('compared_product'));
|
||||
$('#compare-items-count').html(comparedItems ? comparedItems.length : 0);
|
||||
@endguest
|
||||
|
||||
function toggleDropdown(e) {
|
||||
var currentElement = $(e.currentTarget);
|
||||
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@
|
|||
|
||||
template: '#compare-component-template',
|
||||
|
||||
data: function () {
|
||||
data: function () {
|
||||
return {
|
||||
'baseUrl': "{{ url()->to('/') }}",
|
||||
'customer': '{{ auth()->guard('customer')->user() ? "true" : "false" }}' == "true",
|
||||
|
|
@ -37,12 +37,12 @@
|
|||
'type': `alert-${response.data.status}`,
|
||||
'message': response.data.message
|
||||
}];
|
||||
|
||||
|
||||
this.$root.addFlashMessages()
|
||||
}).catch(error => {
|
||||
window.flashMessages = [{
|
||||
'type': `alert-danger`,
|
||||
'message': "{{ __('velocity::app.error.something_went_wrong') }}"
|
||||
'message': "{{ __('shop::app.common.error') }}"
|
||||
}];
|
||||
|
||||
this.$root.addFlashMessages()
|
||||
|
|
@ -59,14 +59,14 @@
|
|||
|
||||
window.flashMessages = [{
|
||||
'type': `alert-success`,
|
||||
'message': "{{ __('velocity::app.customer.compare.added') }}"
|
||||
'message': "{{ __('shop::app.customer.compare.added') }}"
|
||||
}];
|
||||
|
||||
this.$root.addFlashMessages()
|
||||
} else {
|
||||
window.flashMessages = [{
|
||||
'type': `alert-success`,
|
||||
'message': "{{ __('velocity::app.customer.compare.already_added') }}"
|
||||
'message': "{{ __('shop::app.customer.compare.already_added') }}"
|
||||
}];
|
||||
|
||||
this.$root.addFlashMessages()
|
||||
|
|
@ -76,12 +76,14 @@
|
|||
|
||||
window.flashMessages = [{
|
||||
'type': `alert-success`,
|
||||
'message': "{{ __('velocity::app.customer.compare.added') }}"
|
||||
'message': "{{ __('shop::app.customer.compare.added') }}"
|
||||
}];
|
||||
|
||||
this.$root.addFlashMessages()
|
||||
}
|
||||
}
|
||||
|
||||
this.updateCompareCount();
|
||||
},
|
||||
|
||||
'getStorageValue': function (key) {
|
||||
|
|
@ -99,6 +101,28 @@
|
|||
|
||||
return true;
|
||||
},
|
||||
|
||||
'updateCompareCount': function () {
|
||||
if (this.customer == "true" || this.customer == true) {
|
||||
this.$http.get(`${this.baseUrl}/items-count`)
|
||||
.then(response => {
|
||||
$('#compare-items-count').html(response.data.compareProductsCount);
|
||||
})
|
||||
.catch(exception => {
|
||||
window.flashMessages = [{
|
||||
'type': `alert-error`,
|
||||
'message': "{{ __('shop::app.common.error') }}"
|
||||
}];
|
||||
|
||||
this.$root.addFlashMessages();
|
||||
});
|
||||
} else {
|
||||
let comparedItems = JSON.parse(localStorage.getItem('compared_product'));
|
||||
comparedItemsCount = comparedItems ? comparedItems.length : 0;
|
||||
|
||||
$('#compare-items-count').html(comparedItemsCount);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,26 @@
|
|||
{
|
||||
"name": "bagisto/laravel-social-login",
|
||||
"description": "Shipping Package for Shipping Method",
|
||||
"license": "MIT",
|
||||
"authors": [
|
||||
{
|
||||
"name": "rahulshukla-webkul",
|
||||
"email": "rahulshukla.symfony517@webkul.com"
|
||||
}
|
||||
],
|
||||
"require": {},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Webkul\\SocialLogin\\": "src/"
|
||||
}
|
||||
},
|
||||
"extra": {
|
||||
"laravel": {
|
||||
"providers": [
|
||||
"Webkul\\SocialLogin\\Providers\\SocialLoginServiceProvider"
|
||||
],
|
||||
"aliases": {}
|
||||
}
|
||||
},
|
||||
"minimum-stability": "dev"
|
||||
}
|
||||
|
|
@ -16,7 +16,7 @@
|
|||
"extra": {
|
||||
"laravel": {
|
||||
"providers": [
|
||||
"Webkul\\Theme\\ThemeServiceProvider"
|
||||
"Webkul\\Theme\\Providers\\ThemeServiceProvider"
|
||||
],
|
||||
"aliases": {}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ namespace Webkul\Theme;
|
|||
|
||||
use Webkul\Theme\Facades\Themes;
|
||||
use Illuminate\Support\Arr;
|
||||
use Illuminate\Support\Str;
|
||||
use Illuminate\View\FileViewFinder;
|
||||
|
||||
class ThemeViewFinder extends FileViewFinder
|
||||
|
|
@ -19,7 +20,7 @@ class ThemeViewFinder extends FileViewFinder
|
|||
// Extract the $view and the $namespace parts
|
||||
list($namespace, $view) = $this->parseNamespaceSegments($name);
|
||||
|
||||
if ($namespace != 'admin') {
|
||||
if (! Str::contains(request()->route()->uri, 'admin/')) {
|
||||
$paths = $this->addThemeNamespacePaths($namespace);
|
||||
|
||||
try {
|
||||
|
|
@ -34,7 +35,23 @@ class ThemeViewFinder extends FileViewFinder
|
|||
return $this->findInPaths($view, $paths);
|
||||
}
|
||||
} else {
|
||||
return $this->findInPaths($view, $this->hints[$namespace]);
|
||||
$themes = app('themes');
|
||||
|
||||
$themes->set(config('themes.admin-default'));
|
||||
|
||||
$paths = $this->addThemeNamespacePaths($namespace);
|
||||
|
||||
try {
|
||||
return $this->findInPaths($view, $paths);
|
||||
} catch(\Exception $e) {
|
||||
if ($namespace != 'admin') {
|
||||
if (strpos($view, 'admin.') !== false) {
|
||||
$view = str_replace('admin.', 'admin.' . Themes::current()->code . '.', $view);
|
||||
}
|
||||
}
|
||||
|
||||
return $this->findInPaths($view, $paths);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -84,19 +101,6 @@ class ThemeViewFinder extends FileViewFinder
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the string contents of the view.
|
||||
*
|
||||
* @param callable|null $callback
|
||||
* @return array|string
|
||||
*
|
||||
* @throws \Throwable
|
||||
*/
|
||||
public function render(callable $callback = null)
|
||||
{
|
||||
dd(111);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the array of paths where the views are being searched.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@
|
|||
namespace Webkul\Theme;
|
||||
|
||||
use Illuminate\Support\Facades\Config;
|
||||
use Illuminate\Support\Str;
|
||||
use Webkul\Theme\Theme;
|
||||
|
||||
class Themes
|
||||
|
|
@ -42,9 +43,15 @@ class Themes
|
|||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$this->laravelViewsPath = Config::get('view.paths');
|
||||
$routeURI = request()->route()->uri;
|
||||
|
||||
$this->defaultThemeCode = Config::get('themes.default', null);
|
||||
if (Str::contains(request()->route()->uri, 'admin/')) {
|
||||
$this->defaultThemeCode = Config::get('themes.admin-default', null);
|
||||
} else {
|
||||
$this->defaultThemeCode = Config::get('themes.default', null);
|
||||
}
|
||||
|
||||
$this->laravelViewsPath = Config::get('view.paths');
|
||||
|
||||
$this->loadThemes();
|
||||
}
|
||||
|
|
@ -59,6 +66,32 @@ class Themes
|
|||
return $this->themes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return list of registered themes
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getChannelThemes()
|
||||
{
|
||||
$themes = config('themes.themes', []);
|
||||
$channelThemes = [];
|
||||
|
||||
foreach ($themes as $code => $data) {
|
||||
$channelThemes[] = new Theme(
|
||||
$code,
|
||||
isset($data['name']) ? $data['name'] : '',
|
||||
isset($data['assets_path']) ? $data['assets_path'] : '',
|
||||
isset($data['views_path']) ? $data['views_path'] : ''
|
||||
);
|
||||
|
||||
if (isset($data['parent']) && $data['parent']) {
|
||||
$parentThemes[$code] = $data['parent'];
|
||||
}
|
||||
}
|
||||
|
||||
return $channelThemes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if specified exists
|
||||
*
|
||||
|
|
@ -85,7 +118,11 @@ class Themes
|
|||
{
|
||||
$parentThemes = [];
|
||||
|
||||
$themes = config('themes.themes', []);
|
||||
if (Str::contains(request()->route()->uri, 'admin/')) {
|
||||
$themes = config('themes.admin-themes', []);
|
||||
} else {
|
||||
$themes = config('themes.themes', []);
|
||||
}
|
||||
|
||||
foreach ($themes as $code => $data) {
|
||||
$this->themes[] = new Theme(
|
||||
|
|
@ -140,6 +177,7 @@ class Themes
|
|||
Config::set('view.paths', $paths);
|
||||
|
||||
$themeViewFinder = app('view.finder');
|
||||
|
||||
$themeViewFinder->setPaths($paths);
|
||||
|
||||
return $theme;
|
||||
|
|
|
|||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"/js/velocity.js": "/js/velocity.js?id=25493b80bfd55a858726",
|
||||
"/js/velocity.js": "/js/velocity.js?id=1cccc6e984773916257d",
|
||||
"/css/velocity-admin.css": "/css/velocity-admin.css?id=612d35e452446366eef7",
|
||||
"/css/velocity.css": "/css/velocity.css?id=21237e38e6fdd0b9cd2b"
|
||||
"/css/velocity.css": "/css/velocity.css?id=72cf9eb7824c25e1dad8"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -385,7 +385,7 @@ class Helper extends Review
|
|||
|
||||
$productMetaDetails = [];
|
||||
$productMetaDetails['slug'] = $product->url_key;
|
||||
$productMetaDetails['image'] = $formattedProduct['image'];
|
||||
$productMetaDetails['product_image'] = $formattedProduct['image'];
|
||||
$productMetaDetails['priceHTML'] = $formattedProduct['priceHTML'];
|
||||
$productMetaDetails['new'] = $formattedProduct['new'];
|
||||
$productMetaDetails['addToCartHtml'] = $formattedProduct['addToCartHtml'];
|
||||
|
|
|
|||
|
|
@ -93,7 +93,6 @@ class Controller extends BaseController
|
|||
* @param \Webkul\Category\Repositories\CategoryRepository $categoryRepository
|
||||
* @param \Webkul\Velocity\Repositories\Product\ProductRepository $velocityProductRepository
|
||||
* @param \Webkul\Velocity\Repositories\VelocityCustomerCompareProductRepository $compareProductsRepository
|
||||
* @param \Webkul\Velocity\Repositories\VelocityCustomerCompareProductRepository $compareProductsRepository
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
<template>
|
||||
<div class="col-12 lg-card-container list-card product-card row" v-if="list">
|
||||
<div class="product-image" style="margin: auto;">
|
||||
<div class="product-image">
|
||||
<a :title="product.name" :href="`${baseUrl}/${product.slug}`">
|
||||
<img
|
||||
:src="product.image"
|
||||
|
|
|
|||
|
|
@ -1686,6 +1686,7 @@
|
|||
|
||||
&.new {
|
||||
background-color: $theme-color;
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -480,7 +480,6 @@
|
|||
|
||||
> div {
|
||||
display: table-cell;
|
||||
vertical-align: middle;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,197 +1,199 @@
|
|||
<?php
|
||||
|
||||
return [
|
||||
'admin' => [
|
||||
'admin' => [
|
||||
'system' => [
|
||||
'velocity' => [
|
||||
'general' => 'General',
|
||||
'category' => 'Category',
|
||||
'settings' => 'Settings',
|
||||
'extension_name' => 'Velocity Theme',
|
||||
'error-module-inactive' => 'Warning: Velocity theme status is inactive',
|
||||
'general' => '一般的な',
|
||||
'category' => 'カテゴリー',
|
||||
'settings' => '設定',
|
||||
'extension_name' => '速度のテーマ',
|
||||
'error-module-inactive' => '警告:Velocityテーマのステータスは非アクティブです',
|
||||
],
|
||||
|
||||
'settings' => [
|
||||
'channels'=> [
|
||||
'subscription_bar' => 'Subscription bar content'
|
||||
'channels' => [
|
||||
'subscription_bar' => 'サブスクリプションバーのコンテンツ'
|
||||
],
|
||||
],
|
||||
|
||||
'general' => [
|
||||
'status' => 'Status',
|
||||
'active' => 'Active',
|
||||
'inactive' => 'Inactive',
|
||||
'general' => [
|
||||
'status' => '状態',
|
||||
'active' => 'アクティブ',
|
||||
'inactive' => '非活性',
|
||||
],
|
||||
'category' => [
|
||||
'all' => 'All',
|
||||
'left' => 'Left',
|
||||
'right' => 'Right',
|
||||
'active' => 'Active',
|
||||
'custom' => 'Custom',
|
||||
'inactive' => 'Inactive',
|
||||
'image-alignment' => 'Image Alignment',
|
||||
'icon-status' => 'Category Icon Status',
|
||||
'image-status' => 'Category Image Status',
|
||||
'sub-category-show' => 'Show Sub Category',
|
||||
'image-height' => 'Image\'s Height [in Pixel]',
|
||||
'image-width' => 'Image\'s Width [in Pixel]',
|
||||
'show-tooltip' => 'Show Category\'s Tooltip',
|
||||
'num-sub-category' => 'Number Of Sub Category',
|
||||
'all' => 'すべて',
|
||||
'left' => '左',
|
||||
'right' => '正しい',
|
||||
'active' => 'アクティブ',
|
||||
'custom' => 'カスタム',
|
||||
'inactive' => '非活性',
|
||||
'image-alignment' => '画像の配置',
|
||||
'icon-status' => 'カテゴリアイコンステータス',
|
||||
'image-status' => 'カテゴリー画像ステータス',
|
||||
'sub-category-show' => 'サブカテゴリーを表示',
|
||||
'image-height' => '画像の高さ(ピクセル単位)',
|
||||
'image-width' => '画像の幅[ピクセル単位]',
|
||||
'show-tooltip' => 'カテゴリのツールチップを表示',
|
||||
'num-sub-category' => 'サブカテゴリーの数',
|
||||
]
|
||||
],
|
||||
|
||||
'layouts' => [
|
||||
'velocity' => 'Velocity',
|
||||
'cms-pages' => 'CMS Pages',
|
||||
'meta-data' => 'Meta Data',
|
||||
'category-menu' => 'Category Menu',
|
||||
'header-content' => 'Header Content',
|
||||
'velocity' => '速度',
|
||||
'cms-pages' => 'CMSページ',
|
||||
'meta-data' => 'メタデータ',
|
||||
'category-menu' => 'カテゴリーメニュー',
|
||||
'header-content' => 'ヘッダーコンテンツ',
|
||||
],
|
||||
|
||||
'contents' => [
|
||||
'self' => 'Self',
|
||||
'active' => 'Active',
|
||||
'new-tab' => 'New Tab',
|
||||
'inactive' => 'Inactive',
|
||||
'title' => 'Content List',
|
||||
'select' => '-- Select --',
|
||||
'add-title' => 'Add Content',
|
||||
'btn-add-content' => 'Add Content',
|
||||
'save-btn-title' => 'Save Content',
|
||||
'autocomplete' => '[Autocomplete]',
|
||||
'no-result-found' => 'No record found.',
|
||||
'search-hint' => 'Search product here...',
|
||||
'mass-delete-success' => 'Selected content deleted successfully.',
|
||||
'tab' => [
|
||||
'page' => 'Page Setting',
|
||||
'content' => 'Content Setting',
|
||||
'meta_content' => 'Meta Data',
|
||||
'self' => '自己',
|
||||
'active' => 'アクティブ',
|
||||
'new-tab' => '新しいタブ',
|
||||
'inactive' => '非活性',
|
||||
'title' => 'コンテンツリスト',
|
||||
'select' => '- 選択する -',
|
||||
'add-title' => 'コンテンツを追加',
|
||||
'btn-add-content' => 'コンテンツを追加',
|
||||
'save-btn-title' => 'コンテンツを保存',
|
||||
'autocomplete' => '[オートコンプリート]',
|
||||
'no-result-found' => 'レコードが見つかりません。',
|
||||
'search-hint' => 'ここで製品を検索...',
|
||||
'mass-delete-success' => '選択したコンテンツは正常に削除されました。',
|
||||
'tab' => [
|
||||
'page' => 'ページ設定',
|
||||
'content' => 'コンテンツ設定',
|
||||
'meta_content' => 'メタデータ',
|
||||
],
|
||||
'page' => [
|
||||
'title' => 'Title',
|
||||
'status' => 'Status',
|
||||
'position' => 'Position',
|
||||
'page' => [
|
||||
'title' => '題名',
|
||||
'status' => '状態',
|
||||
'position' => 'ポジション',
|
||||
],
|
||||
'content' => [
|
||||
'content-type' => 'Content Type',
|
||||
'custom-title' => 'Custom Title',
|
||||
'category-slug' => 'Category Slug',
|
||||
'link-target' => 'Page Link Target',
|
||||
'custom-product' => 'Store Products',
|
||||
'custom-heading' => 'Custom Heading',
|
||||
'catalog-type' => 'Product Catalog Type',
|
||||
'static-description' => 'Content Description',
|
||||
'page-link' => 'Page Link [e.g. http://example.com/../../]',
|
||||
'content' => [
|
||||
'content-type' => 'コンテンツタイプ',
|
||||
'custom-title' => 'カスタムタイトル',
|
||||
'category-slug' => 'カテゴリースラッグ',
|
||||
'link-target' => 'ページリンクターゲット',
|
||||
'custom-product' => 'ストア製品',
|
||||
'custom-heading' => 'カスタム見出し',
|
||||
'catalog-type' => '製品カタログのタイプ',
|
||||
'static-description' => 'コンテンツの説明',
|
||||
'page-link' => 'ページリンク[例: http://example.com/../../]',
|
||||
],
|
||||
'datagrid' => [
|
||||
'id' => 'Id',
|
||||
'title' => 'Title',
|
||||
'status' => 'Status',
|
||||
'position' => 'Position',
|
||||
'content-type' => 'Content Type',
|
||||
'datagrid' => [
|
||||
'id' => 'Id',
|
||||
'title' => '題名',
|
||||
'status' => '状態',
|
||||
'position' => 'ポジション',
|
||||
'content-type' => 'コンテンツタイプ',
|
||||
]
|
||||
],
|
||||
|
||||
'meta-data' => [
|
||||
'footer' => 'Footer',
|
||||
'title' => 'Velocity meta data',
|
||||
'activate-slider' => 'Activate Slider',
|
||||
'home-page-content' => 'Home Page Content',
|
||||
'footer-left-content' => 'Footer Left Content',
|
||||
'subscription-content' => 'Subscription bar Content',
|
||||
'sidebar-categories' => 'Sidebar Categories',
|
||||
'header_content_count' => 'Header Content Count',
|
||||
'footer-left-raw-content' => '<p>We love to craft softwares and solve the real world problems with the binaries. We are highly committed to our goals. We invest our resources to create world class easy to use softwares and applications for the enterprise business with the top notch, on the edge technology expertise.</p>',
|
||||
'slider-path' => 'Slider Path',
|
||||
'category-logo' => 'Category logo',
|
||||
'product-policy' => 'Product Policy',
|
||||
'update-meta-data' => 'Update Meta Data',
|
||||
'product-view-image' => 'Product View Image',
|
||||
'advertisement-two' => 'Advertisement Two Images',
|
||||
'advertisement-one' => 'Advertisement One Images',
|
||||
'footer-middle-content' => 'Footer Middle Content',
|
||||
'advertisement-four' => 'Advertisement Four Images',
|
||||
'advertisement-three' => 'Advertisement Three Images',
|
||||
'images' => 'Images',
|
||||
'general' => 'General',
|
||||
'add-image-btn-title' => 'Add Image'
|
||||
'footer' => 'フッター',
|
||||
'title' => '速度メタデータ',
|
||||
'activate-slider' => 'スライダーをアクティブにする',
|
||||
'home-page-content' => 'ホームページコンテンツ',
|
||||
'footer-left-content' => 'フッター左コンテンツ',
|
||||
'subscription-content' => 'サブスクリプションバーのコンテンツ',
|
||||
'sidebar-categories' => 'サイドバーのカテゴリ',
|
||||
'header_content_count' => 'ヘッダーコンテンツ数',
|
||||
'footer-left-raw-content' => '<p>私たちはソフトウェアを作成し、バイナリで現実世界の問題を解決するのが大好きです。私達は私達の目標に非常にコミットしています。私たちはリソースを投資して、最先端のテクノロジーの専門知識を活用し、一流のエンタープライズビジネス向けの使いやすいソフトウェアとアプリケーションを作成します。</p>',
|
||||
'slider-path' => 'スライダーパス',
|
||||
'category-logo' => 'カテゴリーロゴ',
|
||||
'product-policy' => '製品ポリシー',
|
||||
'update-meta-data' => 'メタデータを更新',
|
||||
'product-view-image' => '製品ビュー画像',
|
||||
'advertisement-two' => '広告2つの画像',
|
||||
'advertisement-one' => '広告1つの画像',
|
||||
'footer-middle-content' => 'フッターミドルコンテンツ',
|
||||
'advertisement-four' => '広告4つの画像',
|
||||
'advertisement-three' => '広告3つの画像',
|
||||
'images' => '画像',
|
||||
'general' => '一般的な',
|
||||
'add-image-btn-title' => '画像を追加'
|
||||
],
|
||||
|
||||
'category' => [
|
||||
'save-btn-title' => 'Save Menu',
|
||||
'title' => 'Category Menu List',
|
||||
'add-title' => 'Add Menu Content',
|
||||
'edit-title' => 'Edit Menu Content',
|
||||
'btn-add-category' => 'Add Category Content',
|
||||
'datagrid' => [
|
||||
'category-id' => 'Category Id',
|
||||
'category-name' => 'Category Name',
|
||||
'category-icon' => 'Category Icon',
|
||||
'category-status' => 'Status',
|
||||
'save-btn-title' => '保存メニュー',
|
||||
'title' => 'カテゴリーメニュー一覧',
|
||||
'add-title' => 'メニューコンテンツを追加',
|
||||
'edit-title' => 'メニューコンテンツの編集',
|
||||
'btn-add-category' => 'カテゴリコンテンツを追加',
|
||||
'datagrid' => [
|
||||
'category-id' => 'カテゴリID',
|
||||
'category-name' => '種別名',
|
||||
'category-icon' => 'カテゴリーアイコン',
|
||||
'category-status' => '状態',
|
||||
],
|
||||
'tab' => [
|
||||
'general' => 'General',
|
||||
'tab' => [
|
||||
'general' => '一般的な',
|
||||
],
|
||||
'status' => 'Status',
|
||||
'active' => 'Active',
|
||||
'inactive' => 'Inactive',
|
||||
'select' => '-- Select --',
|
||||
'icon-class' => 'Icon Class',
|
||||
'select-category' => 'Choose Category',
|
||||
'tooltip-content' => 'Tooltip Content',
|
||||
'mass-delete-success' => 'Selected categories menu deleted successfully.',
|
||||
'status' => '状態',
|
||||
'active' => 'アクティブ',
|
||||
'inactive' => '非活性',
|
||||
'select' => '- 選択する -',
|
||||
'icon-class' => 'アイコンクラス',
|
||||
'select-category' => 'カテゴリーを選択',
|
||||
'tooltip-content' => 'ツールチップの内容',
|
||||
'mass-delete-success' => '選択したカテゴリメニューを削除しました。',
|
||||
],
|
||||
|
||||
'general' => [
|
||||
'locale_logo' => 'Locale Logo',
|
||||
'locale_logo' => 'ロケールロゴ',
|
||||
],
|
||||
],
|
||||
|
||||
'home' => [
|
||||
'view-all' => 'View All',
|
||||
'add-to-cart' => 'Add To Cart',
|
||||
'hot-categories' => 'Hot Categories',
|
||||
'payment-methods' => 'Payment Methods',
|
||||
'customer-reviews' => 'Customer Reviews',
|
||||
'shipping-methods' => 'Shipping Methods',
|
||||
'popular-categories' => 'Popular Categories',
|
||||
'home' => [
|
||||
'view-all' => 'すべてを見る',
|
||||
'add-to-cart' => 'カートに追加',
|
||||
'hot-categories' => '人気のカテゴリ',
|
||||
'payment-methods' => 'お支払い方法',
|
||||
'customer-reviews' => 'カスタマーレビュー',
|
||||
'shipping-methods' => '輸送方法',
|
||||
'popular-categories' => '人気のカテゴリー',
|
||||
],
|
||||
|
||||
'header' => [
|
||||
'cart' => 'Cart',
|
||||
'cart' => 'Cart',
|
||||
'guest' => 'Guest',
|
||||
'logout' => 'Logout',
|
||||
'title' => 'Account',
|
||||
'account' => 'Account',
|
||||
'profile' => 'Profile',
|
||||
'wishlist' => 'Wishlist',
|
||||
'all-categories' => 'All Categories',
|
||||
'search-text' => 'Search products here',
|
||||
'welcome-message' => 'Welcome, :customer_name',
|
||||
'dropdown-text' => 'Manage Cart, Orders & Wishlist',
|
||||
'header' => [
|
||||
'cart' => 'カート',
|
||||
'guest' => 'ゲスト',
|
||||
'logout' => 'ログアウト',
|
||||
'title' => 'アカウント',
|
||||
'account' => 'アカウント',
|
||||
'profile' => 'プロフィール',
|
||||
'wishlist' => 'ウィッシュリスト',
|
||||
'all-categories' => 'すべてのカテゴリ',
|
||||
'search-text' => 'ここで製品を検索',
|
||||
'welcome-message' => 'ようこそ、:customer_name',
|
||||
'dropdown-text' => 'カート、注文、ウィッシュリストを管理する',
|
||||
],
|
||||
|
||||
'menu-navbar' => [
|
||||
'text-more' => 'More',
|
||||
'text-category' => 'Shop by Category',
|
||||
'menu-navbar' => [
|
||||
'text-more' => 'もっと',
|
||||
'text-category' => 'カテゴリーで選ぶ',
|
||||
],
|
||||
|
||||
'minicart' => [
|
||||
'cart' => 'Cart',
|
||||
'view-cart' => 'View Cart',
|
||||
'minicart' => [
|
||||
'cart' => 'カート',
|
||||
'view-cart' => 'カート',
|
||||
],
|
||||
|
||||
'checkout' => [
|
||||
'qty' => 'Qty',
|
||||
'checkout' => 'Checkout',
|
||||
'checkout' => [
|
||||
'qty' => '数量',
|
||||
'checkout' => 'チェックアウト',
|
||||
'cart' => [
|
||||
'view-cart' => 'View Cart',
|
||||
'cart-summary' => 'Cart Summary',
|
||||
'view-cart' => 'かごの中身を見る',
|
||||
'cart-summary' => 'カートの概要',
|
||||
],
|
||||
'qty' => 'Qty',
|
||||
'items' => 'Items',
|
||||
'subtotal' => 'Subtotal',
|
||||
'sub-total' => 'Sub Total',
|
||||
'proceed' => 'Proceed to checkout',
|
||||
'qty' => '数量',
|
||||
'items' => 'アイテム',
|
||||
'subtotal' => '小計',
|
||||
'sub-total' => '小計',
|
||||
'proceed' => 'チェックアウトに進む',
|
||||
],
|
||||
|
||||
'customer' => [
|
||||
'customer' => [
|
||||
'compare' => [
|
||||
'text' => '比較する',
|
||||
'compare_similar_items' => '類似アイテムを比較する',
|
||||
|
|
@ -200,85 +202,84 @@ return [
|
|||
'already_added' => 'アイテムは比較リストに既に追加されています',
|
||||
'removed' => '比較リストからアイテムを削除しました',
|
||||
'empty-text' => "比較リストにアイテムがありません",
|
||||
'product_image' => 'Product Image',
|
||||
'actions' => 'Actions',
|
||||
'product_image' => '商品画像',
|
||||
'actions' => '行動',
|
||||
],
|
||||
'login-form' => [
|
||||
'sign-up' => 'Sign up',
|
||||
'new-customer' => 'New Customer',
|
||||
'customer-login' => 'Customer Login',
|
||||
'registered-user' => 'Registered User',
|
||||
'your-email-address' => 'Your email address',
|
||||
'form-login-text' => 'If you have an account, sign in with your email address.',
|
||||
'sign-up' => 'サインアップ',
|
||||
'new-customer' => '新規のお客様',
|
||||
'customer-login' => 'お客様ログイン',
|
||||
'registered-user' => '登録ユーザー',
|
||||
'your-email-address' => 'メールアドレス',
|
||||
'form-login-text' => 'アカウントをお持ちの場合は、メールアドレスでログインしてください。',
|
||||
],
|
||||
'signup-form' => [
|
||||
'login' => 'Login',
|
||||
'become-user' => 'Become User',
|
||||
'user-registration' => 'User Registration',
|
||||
'form-sginup-text' => 'If you are new to our store, we glad to have you as member.',
|
||||
'login' => 'ログインする',
|
||||
'become-user' => 'ユーザーになる',
|
||||
'user-registration' => 'ユーザー登録',
|
||||
'form-sginup-text' => 'あなたが私たちの店に初めている場合は、メンバーとして喜んでいます。',
|
||||
],
|
||||
'forget-password' => [
|
||||
'login' => 'Login',
|
||||
'forgot-password' => 'Forgot Password',
|
||||
'recover-password' => 'Recover Password',
|
||||
'recover-password-text' => 'If you forgot your password, recover it by entering your email address.',
|
||||
'login' => 'ログインする',
|
||||
'forgot-password' => 'パスワードをお忘れですか',
|
||||
'recover-password' => 'パスワードを回復',
|
||||
'recover-password-text' => 'パスワードを忘れた場合は、メールアドレスを入力してパスワードを回復してください。',
|
||||
]
|
||||
],
|
||||
|
||||
'error' => [
|
||||
'go-to-home' => 'Go to home',
|
||||
'page-lost-short' => 'Page lost content',
|
||||
'something_went_wrong' => 'something went wrong',
|
||||
'page-lost-description' => "The page you're looking for isn't available. Try to search again or use the Go Back button below.",
|
||||
'error' => [
|
||||
'go-to-home' => '家に帰る',
|
||||
'page-lost-short' => 'ページが失われたコンテンツ',
|
||||
'something_went_wrong' => '問題が発生しました',
|
||||
'page-lost-description' => "お探しのページはご利用いただけません。もう一度検索するか、下の[戻る]ボタンを使用してください。",
|
||||
],
|
||||
|
||||
'products' => [
|
||||
'text' => 'Products',
|
||||
'details' => 'Details',
|
||||
'reviews-title' => 'Reviews',
|
||||
'reviewed' => 'Reviewed',
|
||||
'review-by' => 'Review by',
|
||||
'quick-view' => 'Quick View',
|
||||
'not-available' => 'Not Available',
|
||||
'submit-review' => 'Submit Review',
|
||||
'ratings' => ':totalRatings Ratings',
|
||||
'reviews-count' => ':totalReviews Reviews',
|
||||
'customer-rating' => 'Customer Rating',
|
||||
'more-infomation' => 'More Information',
|
||||
'view-all-reviews' => 'View All Reviews',
|
||||
'write-your-review' => 'Write Your Review',
|
||||
'short-description' => 'Short Descriptions',
|
||||
'recently-viewed' => 'Recently Viewed Products',
|
||||
'be-first-review' => 'Be the first to write a review',
|
||||
'products' => [
|
||||
'text' => '製品',
|
||||
'details' => '細部',
|
||||
'reviews-title' => 'レビュー',
|
||||
'reviewed' => '審査',
|
||||
'review-by' => 'によるレビュー',
|
||||
'quick-view' => 'クイックビュー',
|
||||
'not-available' => '利用不可',
|
||||
'submit-review' => 'レビュー送信',
|
||||
'ratings' => ':totalRatings 評価',
|
||||
'reviews-count' => ':totalReviews レビュー',
|
||||
'customer-rating' => 'お客様の評価',
|
||||
'more-infomation' => '詳しくは',
|
||||
'view-all-reviews' => 'すべてのレビューを表示',
|
||||
'write-your-review' => 'レビューを書く',
|
||||
'short-description' => '短い説明',
|
||||
'recently-viewed' => '最近見た製品',
|
||||
'be-first-review' => '最初のレビューを書く',
|
||||
],
|
||||
|
||||
'shop' => [
|
||||
'shop' => [
|
||||
'gender' => [
|
||||
'male' => 'Male',
|
||||
'other' => 'Other',
|
||||
'female' => 'Female',
|
||||
'male' => '男性',
|
||||
'other' => 'その他の',
|
||||
'female' => '女性',
|
||||
],
|
||||
'general' => [
|
||||
'no' => 'No',
|
||||
'yes' => 'Yes',
|
||||
'view' => 'View',
|
||||
'filter' => 'Filter',
|
||||
'orders' => 'Orders',
|
||||
'update' => 'Update',
|
||||
'reviews' => 'Reviews',
|
||||
'currencies' => 'Currencies',
|
||||
'addresses' => 'Addresses',
|
||||
'top-brands' => 'Top Brands',
|
||||
'new-password' => 'New password',
|
||||
'downloadables' => 'Downloadable Products',
|
||||
'confirm-new-password' => 'Confirm new password',
|
||||
'enter-current-password' => 'Enter your current password',
|
||||
|
||||
'no' => '番号',
|
||||
'yes' => 'はい',
|
||||
'view' => '見る',
|
||||
'filter' => 'フィルタ',
|
||||
'orders' => '注文',
|
||||
'update' => '更新',
|
||||
'reviews' => 'レビュー',
|
||||
'currencies' => '通貨',
|
||||
'addresses' => '住所',
|
||||
'top-brands' => 'トップブランド',
|
||||
'new-password' => '新しいパスワード',
|
||||
'downloadables' => 'ダウンロード可能な製品',
|
||||
'confirm-new-password' => '新しいパスワードを確認',
|
||||
'enter-current-password' => '現在のパスワードを入力してください',
|
||||
'alert' => [
|
||||
'info' => 'Info',
|
||||
'error' => 'Error',
|
||||
'success' => 'Success',
|
||||
'warning' => 'Warning',
|
||||
'info' => '情報',
|
||||
'error' => 'エラー',
|
||||
'success' => '成功',
|
||||
'warning' => '警告',
|
||||
],
|
||||
],
|
||||
'wishlist' => [
|
||||
|
|
@ -287,13 +288,11 @@ return [
|
|||
]
|
||||
],
|
||||
|
||||
'responsive' => [
|
||||
'responsive' => [
|
||||
'header' => [
|
||||
'done' => 'Done',
|
||||
'languages' => 'Languages',
|
||||
'greeting' => 'Welcome, :customer !',
|
||||
'done' => 'できた',
|
||||
'languages' => '言語',
|
||||
'greeting' => 'ようこそ、:customer !',
|
||||
]
|
||||
],
|
||||
]
|
||||
|
||||
?>
|
||||
];
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@
|
|||
{{ __('velocity::app.responsive.header.greeting', ['customer' => auth()->guard('customer')->user()->first_name]) }}
|
||||
</a>
|
||||
@endauth
|
||||
|
||||
|
||||
<i
|
||||
@click="closeDrawer()"
|
||||
class="material-icons pull-right text-dark">
|
||||
|
|
@ -175,6 +175,16 @@
|
|||
</a>
|
||||
@endguest
|
||||
</li>
|
||||
|
||||
<li>
|
||||
@guest('customer')
|
||||
<a
|
||||
class="unset"
|
||||
href="{{ route('customer.register.index') }}">
|
||||
<span>{{ __('shop::app.header.sign-up') }}</span>
|
||||
</a>
|
||||
@endguest
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
|
|
@ -493,7 +503,7 @@
|
|||
|
||||
toggleMetaInfo: function (metaKey) {
|
||||
this.rootCategories = ! this.rootCategories;
|
||||
|
||||
|
||||
this[metaKey] = !this[metaKey];
|
||||
},
|
||||
|
||||
|
|
@ -532,7 +542,7 @@
|
|||
console.log(this.__('error.something_went_wrong'));
|
||||
});
|
||||
},
|
||||
|
||||
|
||||
formatCategories: function (categories) {
|
||||
let slicedCategories = categories;
|
||||
let categoryCount = this.categoryCount ? this.categoryCount : 9;
|
||||
|
|
|
|||
|
|
@ -84,17 +84,16 @@
|
|||
@endpush
|
||||
|
||||
@if ($addresses->isEmpty())
|
||||
<style>
|
||||
<style>
|
||||
a#add-address-button {
|
||||
position: absolute;
|
||||
margin-top: 92px;
|
||||
}
|
||||
|
||||
a#add-address-button {
|
||||
position: absolute;
|
||||
margin-top: 92px;
|
||||
}
|
||||
|
||||
.address-button {
|
||||
position: absolute;
|
||||
margin-top: 92px;
|
||||
}
|
||||
|
||||
</style>
|
||||
.address-button {
|
||||
position: absolute;
|
||||
z-index: 1 !important;
|
||||
margin-top: 110px !important;
|
||||
}
|
||||
</style>
|
||||
@endif
|
||||
|
|
|
|||
|
|
@ -1,6 +1,10 @@
|
|||
@php
|
||||
$attributeRepository = app('\Webkul\Attribute\Repositories\AttributeRepository');
|
||||
$comparableAttributes = $attributeRepository->findByField('is_comparable', 1);
|
||||
$attributeRepository = app('\Webkul\Attribute\Repositories\AttributeFamilyRepository');
|
||||
$comparableAttributes = $attributeRepository->getComparableAttributesBelongsToFamily();
|
||||
|
||||
$locale = request()->get('locale') ?: app()->getLocale();
|
||||
|
||||
$attributeOptionTranslations = DB::table('attribute_option_translations')->where('locale', $locale)->get()->toJson();
|
||||
@endphp
|
||||
|
||||
@push('css')
|
||||
|
|
@ -39,13 +43,13 @@
|
|||
$comparableAttributes = $comparableAttributes->toArray();
|
||||
|
||||
array_splice($comparableAttributes, 1, 0, [[
|
||||
'code' => 'image',
|
||||
'admin_name' => __('velocity::app.customer.compare.product_image')
|
||||
'code' => 'product_image',
|
||||
'admin_name' => __('velocity::app.customer.compare.product_image'),
|
||||
]]);
|
||||
|
||||
array_splice($comparableAttributes, 2, 0, [[
|
||||
'code' => 'addToCartHtml',
|
||||
'admin_name' => __('velocity::app.customer.compare.actions')
|
||||
'admin_name' => __('velocity::app.customer.compare.actions'),
|
||||
]]);
|
||||
@endphp
|
||||
|
||||
|
|
@ -63,7 +67,7 @@
|
|||
</a>
|
||||
@break
|
||||
|
||||
@case('image')
|
||||
@case('product_image')
|
||||
<a :href="`${$root.baseUrl}/${product.url_key}`" class="unset">
|
||||
<img
|
||||
class="image-wrapper"
|
||||
|
|
@ -111,13 +115,28 @@
|
|||
: '{{ __('velocity::app.shop.general.no') }}'"
|
||||
></span>
|
||||
@break;
|
||||
@case('file')
|
||||
<a v-if="product.product['{{ $attribute['code'] }}']" :href="`${$root.baseUrl}/storage/${product.product['{{ $attribute['code'] }}']}`">
|
||||
<span v-text="product.product['{{ $attribute['code'] }}'].substr(product.product['{{ $attribute['code'] }}'].lastIndexOf('/') + 1)" class="fs16"></span>
|
||||
<i class='material-icons'>arrow_downward</i>
|
||||
</a>
|
||||
<a v-else class="fs16">__</span>
|
||||
|
||||
@case('checkbox')
|
||||
<span v-if="product.product['{{ $attribute['code'] }}']" v-html="getAttributeOptions(product['{{ $attribute['code'] }}'] ? product : product.product['{{ $attribute['code'] }}'] ? product.product : null, '{{ $attribute['code'] }}', 'multiple')" class="fs16"></span>
|
||||
<span v-else class="fs16">__</span>
|
||||
@break;
|
||||
|
||||
@case('select')
|
||||
<span v-if="product.product['{{ $attribute['code'] }}']" v-html="getAttributeOptions(product['{{ $attribute['code'] }}'] ? product : product.product['{{ $attribute['code'] }}'] ? product.product : null, '{{ $attribute['code'] }}', 'single')" class="fs16"></span>
|
||||
<span v-else class="fs16">__</span>
|
||||
@break;
|
||||
|
||||
@case ('file')
|
||||
@case ('image')
|
||||
<a :href="`${$root.baseUrl}/${product.url_key}`" class="unset">
|
||||
<img
|
||||
class="image-wrapper"
|
||||
onload="window.updateHeight ? window.updateHeight() : ''"
|
||||
:src="'storage/' + product.product['{{ $attribute['code'] }}']"
|
||||
:onerror="`this.src='${$root.baseUrl}/vendor/webkul/ui/assets/images/product/large-product-placeholder.png'`" />
|
||||
</a>
|
||||
@break;
|
||||
|
||||
@default
|
||||
<span v-html="product['{{ $attribute['code'] }}'] ? product['{{ $attribute['code'] }}'] : product.product['{{ $attribute['code'] }}'] ? product.product['{{ $attribute['code'] }}'] : '__'" class="fs16"></span>
|
||||
@break;
|
||||
|
|
@ -148,6 +167,7 @@
|
|||
return {
|
||||
'products': [],
|
||||
'isProductListLoaded': false,
|
||||
'attributeOptions': JSON.parse(@json($attributeOptionTranslations)),
|
||||
'isCustomer': '{{ auth()->guard('customer')->user() ? "true" : "false" }}' == "true",
|
||||
}
|
||||
},
|
||||
|
|
@ -218,6 +238,7 @@
|
|||
if (productId == "all") {
|
||||
updatedItems = [];
|
||||
this.$set(this, 'products', []);
|
||||
|
||||
window.showAlert(
|
||||
`alert-success`,
|
||||
this.__('shop.general.alert.success'),
|
||||
|
|
@ -226,6 +247,7 @@
|
|||
} else {
|
||||
updatedItems = existingItems.filter(item => item != productId);
|
||||
this.$set(this, 'products', this.products.filter(product => product.id != productId));
|
||||
|
||||
window.showAlert(
|
||||
`alert-success`,
|
||||
this.__('shop.general.alert.success'),
|
||||
|
|
@ -238,6 +260,42 @@
|
|||
|
||||
this.$root.headerItemsCount++;
|
||||
},
|
||||
|
||||
'getAttributeOptions': function (productDetails, attributeValues, type) {
|
||||
var attributeOptions = '__';
|
||||
|
||||
if (productDetails && attributeValues) {
|
||||
var attributeItems;
|
||||
|
||||
if (type == "multiple") {
|
||||
attributeItems = productDetails[attributeValues].split(',');
|
||||
} else if (type == "single") {
|
||||
attributeItems = productDetails[attributeValues];
|
||||
}
|
||||
|
||||
attributeOptions = this.attributeOptions.filter(option => {
|
||||
if (type == "multiple") {
|
||||
if (attributeItems.indexOf(option.attribute_option_id.toString()) > -1) {
|
||||
return true;
|
||||
}
|
||||
} else if (type == "single") {
|
||||
if (attributeItems == option.attribute_option_id.toString()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
});
|
||||
|
||||
attributeOptions = attributeOptions.map(option => {
|
||||
return option.label;
|
||||
});
|
||||
|
||||
attributeOptions = attributeOptions.join(', ');
|
||||
}
|
||||
|
||||
return attributeOptions;
|
||||
}
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@
|
|||
navigation-enabled="hide"
|
||||
pagination-enabled="hide"
|
||||
id="upsell-products-carousel"
|
||||
:slides-count="{{ sizeof($products) }}">
|
||||
:slides-count="{{ $product->cross_sells()->count() }}">
|
||||
|
||||
@foreach($products as $product)
|
||||
@foreach ($product->cross_sells()->paginate(2) as $index => $crossSellProduct)
|
||||
|
|
@ -40,7 +40,7 @@
|
|||
|
||||
<div class="carousel-products vc-small-screen">
|
||||
<carousel-component
|
||||
:slides-count="{{ sizeof($products) }}"
|
||||
:slides-count="{{ $product->cross_sells()->count() }}"
|
||||
slides-per-page="2"
|
||||
id="upsell-products-carousel"
|
||||
navigation-enabled="hide"
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
<?php
|
||||
|
||||
use Codeception\Actor;
|
||||
use Webkul\User\Models\Admin;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
|
|
@ -22,7 +23,7 @@ use Illuminate\Routing\RouteCollection;
|
|||
*
|
||||
* @SuppressWarnings(PHPMD)
|
||||
*/
|
||||
class FunctionalTester extends \Codeception\Actor
|
||||
class FunctionalTester extends Actor
|
||||
{
|
||||
use _generated\FunctionalTesterActions;
|
||||
|
||||
|
|
@ -47,7 +48,7 @@ class FunctionalTester extends \Codeception\Actor
|
|||
}
|
||||
|
||||
if (! $admin) {
|
||||
throw new \Exception(
|
||||
throw new Exception(
|
||||
'Admin user not found in database. Please ensure Seeders are executed');
|
||||
}
|
||||
|
||||
|
|
@ -85,12 +86,17 @@ class FunctionalTester extends \Codeception\Actor
|
|||
|
||||
/**
|
||||
* @param string $name
|
||||
* @param array $params
|
||||
* @param bool $routeCheck set this to false if the action is doing a redirection
|
||||
*/
|
||||
public function amOnAdminRoute(string $name, array $params = [])
|
||||
public function amOnAdminRoute(string $name, array $params = [], bool $routeCheck = true)
|
||||
{
|
||||
$I = $this;
|
||||
$I->amOnRoute($name, $params);
|
||||
$I->seeCurrentRouteIs($name);
|
||||
|
||||
if ($routeCheck) {
|
||||
$I->seeCurrentRouteIs($name);
|
||||
}
|
||||
|
||||
/** @var RouteCollection $routes */
|
||||
$routes = Route::getRoutes();
|
||||
|
|
|
|||
|
|
@ -0,0 +1,134 @@
|
|||
<?php
|
||||
|
||||
namespace Tests\Functional\Product;
|
||||
|
||||
use FunctionalTester;
|
||||
use Webkul\Product\Models\Product;
|
||||
use Webkul\Product\Models\ProductFlat;
|
||||
use Webkul\Core\Helpers\Laravel5Helper;
|
||||
use Webkul\Product\Models\ProductInventory;
|
||||
use Webkul\Product\Models\ProductAttributeValue;
|
||||
|
||||
class ProductCopyCest
|
||||
{
|
||||
|
||||
public function _before(FunctionalTester $I)
|
||||
{
|
||||
$I->loginAsAdmin();
|
||||
}
|
||||
|
||||
public function testSkipAttributes(FunctionalTester $I)
|
||||
{
|
||||
config(['products.skipAttributesOnCopy' => ['name', 'inventories']]);
|
||||
|
||||
$original = $I->haveProduct(Laravel5Helper::SIMPLE_PRODUCT, [
|
||||
'productInventory' => [
|
||||
'qty' => 10,
|
||||
],
|
||||
'attributeValues' => [
|
||||
'name' => 'Original',
|
||||
],
|
||||
]);
|
||||
|
||||
$I->amOnAdminRoute('admin.catalog.products.copy', ['id' => $original->id], false);
|
||||
|
||||
// test attribute is skipped:
|
||||
$attr = $I->dontSeeRecord(ProductAttributeValue::class, [
|
||||
'attribute_id' => 2, // name
|
||||
'product_id' => $original->id + 1,
|
||||
]);
|
||||
|
||||
// test relation is skipped:
|
||||
$I->dontSeeRecord(ProductInventory::class, [
|
||||
'product_id' => $original->id + 1,
|
||||
'qty' => 10,
|
||||
]);
|
||||
}
|
||||
|
||||
public function testBlockProductCopy(FunctionalTester $I)
|
||||
{
|
||||
$original = $I->haveProduct(Laravel5Helper::BOOKING_EVENT_PRODUCT, []);
|
||||
|
||||
$I->amOnAdminRoute('admin.catalog.products.copy', ['id' => $original->id], false);
|
||||
|
||||
$I->seeInSource('Products of type booking can not be copied');
|
||||
}
|
||||
|
||||
public function testProductCopy(FunctionalTester $I)
|
||||
{
|
||||
// set this config value to true to make it testable. It defaults to false.
|
||||
config(['products.linkProductsOnCopy' => true]);
|
||||
|
||||
$originalName = $I->fake()->name;
|
||||
|
||||
$original = $I->haveProduct(Laravel5Helper::SIMPLE_PRODUCT, [
|
||||
'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,
|
||||
]);
|
||||
|
||||
$attr = $I->grabRecord(ProductAttributeValue::class, [
|
||||
'attribute_id' => 2,
|
||||
'product_id' => $copiedProduct->id,
|
||||
]);
|
||||
$I->assertStringStartsWith('Copy of ' . $originalName, $attr->text_value);
|
||||
|
||||
// url_key
|
||||
$attr = $I->grabRecord(ProductAttributeValue::class, [
|
||||
'attribute_id' => 3,
|
||||
'product_id' => $copiedProduct->id,
|
||||
]);
|
||||
$I->assertStringStartsWith('copy-of-' . $original->url_key, $attr->text_value);
|
||||
|
||||
// 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('product_relations', [
|
||||
'parent_id' => $original->id,
|
||||
'child_id' => $copiedProduct->id,
|
||||
]);
|
||||
|
||||
$flat = $I->grabRecord(ProductFlat::class, [
|
||||
'product_id' => $copiedProduct->id,
|
||||
]);
|
||||
$I->assertStringStartsWith('Copy of ' . $originalName, $flat->name);
|
||||
|
||||
$I->assertCount($count + 1, Product::all());
|
||||
|
||||
$I->seeResponseCodeIsSuccessful();
|
||||
}
|
||||
}
|
||||
|
|
@ -243,21 +243,21 @@ class CartRuleCest
|
|||
protected function getCartWithCouponScenarios(): array
|
||||
{
|
||||
return [
|
||||
[
|
||||
'name' => 'check cart coupon',
|
||||
'productSequence' => [
|
||||
self::PRODUCT_NOT_FREE,
|
||||
self::PRODUCT_NOT_FREE_REDUCED_TAX,
|
||||
self::PRODUCT_NOT_FREE,
|
||||
],
|
||||
'withCoupon' => true,
|
||||
'couponScenario' => [
|
||||
'scenario' => self::COUPON_FIXED_CART,
|
||||
'products' => [
|
||||
],
|
||||
],
|
||||
'checkOrder' => true,
|
||||
],
|
||||
// [
|
||||
// 'name' => 'check cart coupon',
|
||||
// 'productSequence' => [
|
||||
// self::PRODUCT_NOT_FREE,
|
||||
// self::PRODUCT_NOT_FREE_REDUCED_TAX,
|
||||
// self::PRODUCT_NOT_FREE,
|
||||
// ],
|
||||
// 'withCoupon' => true,
|
||||
// 'couponScenario' => [
|
||||
// 'scenario' => self::COUPON_FIXED_CART,
|
||||
// 'products' => [
|
||||
// ],
|
||||
// ],
|
||||
// 'checkOrder' => true,
|
||||
// ],
|
||||
// ohne coupon
|
||||
[
|
||||
'name' => 'PRODUCT_FREE no coupon',
|
||||
|
|
@ -306,23 +306,23 @@ class CartRuleCest
|
|||
],
|
||||
'checkOrder' => false,
|
||||
],
|
||||
[
|
||||
'name' => 'check fix coupon applied to two products',
|
||||
'productSequence' => [
|
||||
self::PRODUCT_NOT_FREE,
|
||||
self::PRODUCT_NOT_FREE_REDUCED_TAX,
|
||||
self::PRODUCT_NOT_FREE,
|
||||
],
|
||||
'withCoupon' => true,
|
||||
'couponScenario' => [
|
||||
'scenario' => self::COUPON_FIXED,
|
||||
'products' => [
|
||||
self::PRODUCT_NOT_FREE,
|
||||
self::PRODUCT_NOT_FREE_REDUCED_TAX,
|
||||
],
|
||||
],
|
||||
'checkOrder' => true,
|
||||
],
|
||||
// [
|
||||
// 'name' => 'check fix coupon applied to two products',
|
||||
// 'productSequence' => [
|
||||
// self::PRODUCT_NOT_FREE,
|
||||
// self::PRODUCT_NOT_FREE_REDUCED_TAX,
|
||||
// self::PRODUCT_NOT_FREE,
|
||||
// ],
|
||||
// 'withCoupon' => true,
|
||||
// 'couponScenario' => [
|
||||
// 'scenario' => self::COUPON_FIXED,
|
||||
// 'products' => [
|
||||
// self::PRODUCT_NOT_FREE,
|
||||
// self::PRODUCT_NOT_FREE_REDUCED_TAX,
|
||||
// ],
|
||||
// ],
|
||||
// 'checkOrder' => true,
|
||||
// ],
|
||||
// prozenturaler Coupon für ein Produkt (Warenkorb wird nicht 0)
|
||||
[
|
||||
'name' => 'PRODUCT_NOT_FREE percentage coupon',
|
||||
|
|
@ -354,23 +354,23 @@ class CartRuleCest
|
|||
],
|
||||
'checkOrder' => false,
|
||||
],
|
||||
[
|
||||
'name' => 'check percentage coupon applied to two products',
|
||||
'productSequence' => [
|
||||
self::PRODUCT_NOT_FREE,
|
||||
self::PRODUCT_NOT_FREE_REDUCED_TAX,
|
||||
self::PRODUCT_NOT_FREE,
|
||||
],
|
||||
'withCoupon' => true,
|
||||
'couponScenario' => [
|
||||
'scenario' => self::COUPON_PERCENTAGE,
|
||||
'products' => [
|
||||
self::PRODUCT_NOT_FREE,
|
||||
self::PRODUCT_NOT_FREE_REDUCED_TAX,
|
||||
],
|
||||
],
|
||||
'checkOrder' => true,
|
||||
],
|
||||
// [
|
||||
// 'name' => 'check percentage coupon applied to two products',
|
||||
// 'productSequence' => [
|
||||
// self::PRODUCT_NOT_FREE,
|
||||
// self::PRODUCT_NOT_FREE_REDUCED_TAX,
|
||||
// self::PRODUCT_NOT_FREE,
|
||||
// ],
|
||||
// 'withCoupon' => true,
|
||||
// 'couponScenario' => [
|
||||
// 'scenario' => self::COUPON_PERCENTAGE,
|
||||
// 'products' => [
|
||||
// self::PRODUCT_NOT_FREE,
|
||||
// self::PRODUCT_NOT_FREE_REDUCED_TAX,
|
||||
// ],
|
||||
// ],
|
||||
// 'checkOrder' => true,
|
||||
// ],
|
||||
// fixer Coupon für ein Produkt (Warenkorb wird 0)
|
||||
[
|
||||
'name' => 'PRODUCT_NON_SUB_NOT_FREE fix coupon to zero',
|
||||
|
|
@ -402,23 +402,23 @@ class CartRuleCest
|
|||
],
|
||||
'checkOrder' => false,
|
||||
],
|
||||
[
|
||||
'name' => 'check fix coupon to zero applied to two products',
|
||||
'productSequence' => [
|
||||
self::PRODUCT_NOT_FREE,
|
||||
self::PRODUCT_NOT_FREE_REDUCED_TAX,
|
||||
self::PRODUCT_NOT_FREE,
|
||||
],
|
||||
'withCoupon' => true,
|
||||
'couponScenario' => [
|
||||
'scenario' => self::COUPON_FIXED_FULL,
|
||||
'products' => [
|
||||
self::PRODUCT_NOT_FREE,
|
||||
self::PRODUCT_NOT_FREE_REDUCED_TAX,
|
||||
],
|
||||
],
|
||||
'checkOrder' => true,
|
||||
],
|
||||
// [
|
||||
// 'name' => 'check fix coupon to zero applied to two products',
|
||||
// 'productSequence' => [
|
||||
// self::PRODUCT_NOT_FREE,
|
||||
// self::PRODUCT_NOT_FREE_REDUCED_TAX,
|
||||
// self::PRODUCT_NOT_FREE,
|
||||
// ],
|
||||
// 'withCoupon' => true,
|
||||
// 'couponScenario' => [
|
||||
// 'scenario' => self::COUPON_FIXED_FULL,
|
||||
// 'products' => [
|
||||
// self::PRODUCT_NOT_FREE,
|
||||
// self::PRODUCT_NOT_FREE_REDUCED_TAX,
|
||||
// ],
|
||||
// ],
|
||||
// 'checkOrder' => true,
|
||||
// ],
|
||||
// prozenturaler Coupon für ein Produkt (Warenkorb wird 0)
|
||||
[
|
||||
'name' => 'PRODUCT_NOT_FREE percentage coupon to zero',
|
||||
|
|
@ -450,23 +450,23 @@ class CartRuleCest
|
|||
],
|
||||
'checkOrder' => false,
|
||||
],
|
||||
[
|
||||
'name' => 'check percentage coupon to zero applied to two products',
|
||||
'productSequence' => [
|
||||
self::PRODUCT_NOT_FREE,
|
||||
self::PRODUCT_NOT_FREE_REDUCED_TAX,
|
||||
self::PRODUCT_NOT_FREE,
|
||||
],
|
||||
'withCoupon' => true,
|
||||
'couponScenario' => [
|
||||
'scenario' => self::COUPON_PERCENTAGE_FULL,
|
||||
'products' => [
|
||||
self::PRODUCT_NOT_FREE,
|
||||
self::PRODUCT_NOT_FREE_REDUCED_TAX,
|
||||
],
|
||||
],
|
||||
'checkOrder' => true,
|
||||
],
|
||||
// [
|
||||
// 'name' => 'check percentage coupon to zero applied to two products',
|
||||
// 'productSequence' => [
|
||||
// self::PRODUCT_NOT_FREE,
|
||||
// self::PRODUCT_NOT_FREE_REDUCED_TAX,
|
||||
// self::PRODUCT_NOT_FREE,
|
||||
// ],
|
||||
// 'withCoupon' => true,
|
||||
// 'couponScenario' => [
|
||||
// 'scenario' => self::COUPON_PERCENTAGE_FULL,
|
||||
// 'products' => [
|
||||
// self::PRODUCT_NOT_FREE,
|
||||
// self::PRODUCT_NOT_FREE_REDUCED_TAX,
|
||||
// ],
|
||||
// ],
|
||||
// 'checkOrder' => true,
|
||||
// ],
|
||||
];
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -57,7 +57,12 @@ class CartModelCest
|
|||
$I->assertTrue(Cart::getCart()->hasProductsWithQuantityBox());
|
||||
|
||||
$I->wantTo('check function with cart, that contains a product with QuantityBox() == true');
|
||||
Cart::removeItem($cartItemIdOfProductWithoutQuantityBox);
|
||||
// Cart::removeItem($cartItemIdOfProductWithoutQuantityBox);
|
||||
Cart::addProduct($this->productWithQuantityBox->id, [
|
||||
'_token' => session('_token'),
|
||||
'product_id' => $this->productWithQuantityBox->id,
|
||||
'quantity' => 1,
|
||||
]);
|
||||
$I->assertTrue(Cart::getCart()->hasProductsWithQuantityBox());
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue