resolved conflicts

This commit is contained in:
mohd asif 2020-03-19 18:07:25 +05:30
commit a1124fc7b6
81 changed files with 1383 additions and 711 deletions

View File

@ -58,4 +58,4 @@ Below is an example of a valid Bagisto doc block. Note that the @param attribute
protected function registerFacades($loader, $concrete = null, $shared = false)
{
//
}
}

View File

@ -21,7 +21,7 @@
"barryvdh/laravel-dompdf": "0.8.5",
"doctrine/dbal": "2.9.2",
"fideloper/proxy": "^4.0",
"flynsarmy/db-blade-compiler": "*",
"flynsarmy/db-blade-compiler": "^5.5",
"guzzlehttp/guzzle": "~6.0",
"intervention/image": "^2.4",
"intervention/imagecache": "^2.3",
@ -33,21 +33,20 @@
"maatwebsite/excel": "3.1.18",
"nwidart/laravel-modules": "^3.2",
"prettus/l5-repository": "^2.6",
"tymon/jwt-auth": "^1.0.0",
"barryvdh/laravel-debugbar": "^3.1",
"fzaninotto/faker": "^1.4"
"tymon/jwt-auth": "^1.0.0"
},
"require-dev": {
"codeception/codeception": "^4.0",
"codeception/codeception": "4.1.1",
"codeception/module-asserts": "^1.1",
"codeception/module-filesystem": "^1.0",
"codeception/module-laravel5": "^1.0",
"filp/whoops": "^2.0",
"laravel/dusk": "^5.7.0",
"mockery/mockery": "^1.0",
"nunomaduro/collision": "^2.0",
"phpunit/phpunit": "^7.0"
"phpunit/phpunit": "^7.0",
"barryvdh/laravel-debugbar": "^3.1",
"fzaninotto/faker": "^1.4"
},
"replace": {

599
composer.lock generated
View File

@ -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": "2e158f9cd141beb41f6bc0dd7ee82767",
"content-hash": "dca322023597f38ef7991bc9d9bdc50f",
"packages": [
{
"name": "astrotomic/laravel-translatable",
@ -71,74 +71,6 @@
],
"time": "2020-03-03T10:43:26+00:00"
},
{
"name": "barryvdh/laravel-debugbar",
"version": "v3.2.9",
"source": {
"type": "git",
"url": "https://github.com/barryvdh/laravel-debugbar.git",
"reference": "42d5da5379a7860093f8e4032167e4cb5ebec180"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/barryvdh/laravel-debugbar/zipball/42d5da5379a7860093f8e4032167e4cb5ebec180",
"reference": "42d5da5379a7860093f8e4032167e4cb5ebec180",
"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-02-25T20:42:23+00:00"
},
{
"name": "barryvdh/laravel-dompdf",
"version": "v0.8.5",
@ -887,56 +819,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.2",
@ -1457,33 +1339,33 @@
},
{
"name": "konekt/concord",
"version": "1.4.0",
"version": "1.5.0",
"source": {
"type": "git",
"url": "https://github.com/artkonekt/concord.git",
"reference": "3d13628d45253e1fafe3567729338545a10da047"
"reference": "2d9f7080c35636c0c7b94bb614d1e50942088061"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/artkonekt/concord/zipball/3d13628d45253e1fafe3567729338545a10da047",
"reference": "3d13628d45253e1fafe3567729338545a10da047",
"url": "https://api.github.com/repos/artkonekt/concord/zipball/2d9f7080c35636c0c7b94bb614d1e50942088061",
"reference": "2d9f7080c35636c0c7b94bb614d1e50942088061",
"shasum": ""
},
"require": {
"illuminate/console": "~5.5|~6.0",
"illuminate/support": "~5.5|~6.0",
"illuminate/console": "~5.5|~6.0|~7.0",
"illuminate/support": "~5.5|~6.0|~7.0",
"konekt/enum": "~2.1",
"konekt/enum-eloquent": "^1.3.1",
"php": "^7.1.3"
"php": "^7.2"
},
"require-dev": {
"orchestra/testbench": "^3.4.2|~4.9",
"phpunit/phpunit": "6.0 - 7.5|~8.0"
"orchestra/testbench": "~3.5|~4.0|~5.0",
"phpunit/phpunit": "6.0 - 7.5|~8.0|~9.0"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.4-dev"
"dev-master": "1.5-dev"
},
"laravel": {
"providers": [
@ -1514,7 +1396,7 @@
}
],
"description": "Concord is a Laravel Extension for building modular Laravel Applications",
"time": "2019-11-17T10:30:36+00:00"
"time": "2020-03-13T16:50:52+00:00"
},
{
"name": "konekt/enum",
@ -2021,16 +1903,16 @@
},
{
"name": "league/flysystem",
"version": "1.0.63",
"version": "1.0.65",
"source": {
"type": "git",
"url": "https://github.com/thephpleague/flysystem.git",
"reference": "8132daec326565036bc8e8d1876f77ec183a7bd6"
"reference": "8f17b3ba67097aafb8318cd5c553b1acf7c891c8"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/thephpleague/flysystem/zipball/8132daec326565036bc8e8d1876f77ec183a7bd6",
"reference": "8132daec326565036bc8e8d1876f77ec183a7bd6",
"url": "https://api.github.com/repos/thephpleague/flysystem/zipball/8f17b3ba67097aafb8318cd5c553b1acf7c891c8",
"reference": "8f17b3ba67097aafb8318cd5c553b1acf7c891c8",
"shasum": ""
},
"require": {
@ -2042,7 +1924,7 @@
},
"require-dev": {
"phpspec/phpspec": "^3.4",
"phpunit/phpunit": "^5.7.10"
"phpunit/phpunit": "^5.7.26"
},
"suggest": {
"ext-fileinfo": "Required for MimeType",
@ -2101,7 +1983,7 @@
"sftp",
"storage"
],
"time": "2020-01-04T16:30:31+00:00"
"time": "2020-03-08T18:53:20+00:00"
},
{
"name": "maatwebsite/excel",
@ -2172,30 +2054,30 @@
},
{
"name": "markbaker/complex",
"version": "1.4.7",
"version": "1.4.8",
"source": {
"type": "git",
"url": "https://github.com/MarkBaker/PHPComplex.git",
"reference": "1ea674a8308baf547cbcbd30c5fcd6d301b7c000"
"reference": "8eaa40cceec7bf0518187530b2e63871be661b72"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/MarkBaker/PHPComplex/zipball/1ea674a8308baf547cbcbd30c5fcd6d301b7c000",
"reference": "1ea674a8308baf547cbcbd30c5fcd6d301b7c000",
"url": "https://api.github.com/repos/MarkBaker/PHPComplex/zipball/8eaa40cceec7bf0518187530b2e63871be661b72",
"reference": "8eaa40cceec7bf0518187530b2e63871be661b72",
"shasum": ""
},
"require": {
"php": "^5.6.0|^7.0.0"
},
"require-dev": {
"dealerdirect/phpcodesniffer-composer-installer": "^0.4.3",
"phpcompatibility/php-compatibility": "^8.0",
"dealerdirect/phpcodesniffer-composer-installer": "^0.5.0",
"phpcompatibility/php-compatibility": "^9.0",
"phpdocumentor/phpdocumentor": "2.*",
"phploc/phploc": "2.*",
"phpmd/phpmd": "2.*",
"phpunit/phpunit": "^4.8.35|^5.4.0",
"sebastian/phpcpd": "2.*",
"squizlabs/php_codesniffer": "^3.3.0"
"squizlabs/php_codesniffer": "^3.4.0"
},
"type": "library",
"autoload": {
@ -2263,7 +2145,7 @@
"complex",
"mathematics"
],
"time": "2018-10-13T23:28:42+00:00"
"time": "2020-03-11T20:15:49+00:00"
},
{
"name": "markbaker/matrix",
@ -2334,67 +2216,6 @@
],
"time": "2019-10-06T11:29:25+00:00"
},
{
"name": "maximebf/debugbar",
"version": "v1.16.1",
"source": {
"type": "git",
"url": "https://github.com/maximebf/php-debugbar.git",
"reference": "58998b818c6567fac01e35b8a4b70c1a64530556"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/maximebf/php-debugbar/zipball/58998b818c6567fac01e35b8a4b70c1a64530556",
"reference": "58998b818c6567fac01e35b8a4b70c1a64530556",
"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": "2019-11-24T09:46:11+00:00"
},
{
"name": "monolog/monolog",
"version": "2.0.2",
@ -3064,26 +2885,27 @@
},
{
"name": "prettus/l5-repository",
"version": "2.6.41",
"version": "2.6.42",
"source": {
"type": "git",
"url": "https://github.com/andersao/l5-repository.git",
"reference": "363904bd1d01325223197d3de1ea3f6fc9da2a06"
"reference": "24c473c08ab46759a2ebe8bb1ec6de1d7c9e9d1e"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/andersao/l5-repository/zipball/363904bd1d01325223197d3de1ea3f6fc9da2a06",
"reference": "363904bd1d01325223197d3de1ea3f6fc9da2a06",
"url": "https://api.github.com/repos/andersao/l5-repository/zipball/24c473c08ab46759a2ebe8bb1ec6de1d7c9e9d1e",
"reference": "24c473c08ab46759a2ebe8bb1ec6de1d7c9e9d1e",
"shasum": ""
},
"require": {
"illuminate/config": "~5.0|~6.0",
"illuminate/console": "~5.0|~6.0",
"illuminate/database": "~5.0|~6.0",
"illuminate/filesystem": "~5.0|~6.0",
"illuminate/http": "~5.0|~6.0",
"illuminate/pagination": "~5.0|~6.0",
"illuminate/support": "~5.0|~6.0",
"illuminate/config": "~5.0|~6.0|~7.0",
"illuminate/console": "~5.0|~6.0|~7.0",
"illuminate/database": "~5.0|~6.0|~7.0",
"illuminate/filesystem": "~5.0|~6.0|~7.0",
"illuminate/http": "~5.0|~6.0|~7.0",
"illuminate/pagination": "~5.0|~6.0|~7.0",
"illuminate/support": "~5.0|~6.0|~7.0",
"illuminate/validation": "~5.0|~6.0|~7.0",
"prettus/laravel-validation": "~1.1|~1.2"
},
"suggest": {
@ -3125,25 +2947,25 @@
"model",
"repository"
],
"time": "2020-02-05T06:48:26+00:00"
"time": "2020-03-14T18:53:21+00:00"
},
{
"name": "prettus/laravel-validation",
"version": "1.2.0",
"version": "1.2.2",
"source": {
"type": "git",
"url": "https://github.com/andersao/laravel-validator.git",
"reference": "5ffa053baae31d11fa34da013b940d85c99ba253"
"reference": "3d43037c2f497df3f8fbf3d8c16954a83c72e530"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/andersao/laravel-validator/zipball/5ffa053baae31d11fa34da013b940d85c99ba253",
"reference": "5ffa053baae31d11fa34da013b940d85c99ba253",
"url": "https://api.github.com/repos/andersao/laravel-validator/zipball/3d43037c2f497df3f8fbf3d8c16954a83c72e530",
"reference": "3d43037c2f497df3f8fbf3d8c16954a83c72e530",
"shasum": ""
},
"require": {
"illuminate/support": "~5.4|^6.0",
"illuminate/validation": "~5.4|^6.0",
"illuminate/support": "~5.4|^6.0|^7.0",
"illuminate/validation": "~5.4|^6.0|^7.0",
"php": ">=5.4.0"
},
"type": "library",
@ -3168,7 +2990,7 @@
"service",
"validation"
],
"time": "2019-09-11T12:19:42+00:00"
"time": "2020-03-14T19:28:36+00:00"
},
{
"name": "psr/container",
@ -4043,16 +3865,16 @@
},
{
"name": "symfony/finder",
"version": "v4.4.3",
"version": "v4.4.5",
"source": {
"type": "git",
"url": "https://github.com/symfony/finder.git",
"reference": "3a50be43515590faf812fbd7708200aabc327ec3"
"reference": "ea69c129aed9fdeca781d4b77eb20b62cf5d5357"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/finder/zipball/3a50be43515590faf812fbd7708200aabc327ec3",
"reference": "3a50be43515590faf812fbd7708200aabc327ec3",
"url": "https://api.github.com/repos/symfony/finder/zipball/ea69c129aed9fdeca781d4b77eb20b62cf5d5357",
"reference": "ea69c129aed9fdeca781d4b77eb20b62cf5d5357",
"shasum": ""
},
"require": {
@ -4088,7 +3910,7 @@
],
"description": "Symfony Finder Component",
"homepage": "https://symfony.com",
"time": "2020-01-04T13:00:46+00:00"
"time": "2020-02-14T07:42:58+00:00"
},
{
"name": "symfony/http-foundation",
@ -5273,16 +5095,16 @@
},
{
"name": "vlucas/phpdotenv",
"version": "v3.6.0",
"version": "v3.6.1",
"source": {
"type": "git",
"url": "https://github.com/vlucas/phpdotenv.git",
"reference": "1bdf24f065975594f6a117f0f1f6cabf1333b156"
"reference": "8f7961f7b9deb3b432452c18093cf16f88205902"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/vlucas/phpdotenv/zipball/1bdf24f065975594f6a117f0f1f6cabf1333b156",
"reference": "1bdf24f065975594f6a117f0f1f6cabf1333b156",
"url": "https://api.github.com/repos/vlucas/phpdotenv/zipball/8f7961f7b9deb3b432452c18093cf16f88205902",
"reference": "8f7961f7b9deb3b432452c18093cf16f88205902",
"shasum": ""
},
"require": {
@ -5291,8 +5113,12 @@
"symfony/polyfill-ctype": "^1.9"
},
"require-dev": {
"ext-filter": "*",
"phpunit/phpunit": "^4.8.35 || ^5.0 || ^6.0 || ^7.0"
},
"suggest": {
"ext-filter": "Required to use the boolean validator."
},
"type": "library",
"extra": {
"branch-alias": {
@ -5326,10 +5152,78 @@
"env",
"environment"
],
"time": "2019-09-10T21:37:39+00:00"
"time": "2020-03-12T13:44:00+00:00"
}
],
"packages-dev": [
{
"name": "barryvdh/laravel-debugbar",
"version": "v3.2.9",
"source": {
"type": "git",
"url": "https://github.com/barryvdh/laravel-debugbar.git",
"reference": "42d5da5379a7860093f8e4032167e4cb5ebec180"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/barryvdh/laravel-debugbar/zipball/42d5da5379a7860093f8e4032167e4cb5ebec180",
"reference": "42d5da5379a7860093f8e4032167e4cb5ebec180",
"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-02-25T20:42:23+00:00"
},
{
"name": "behat/gherkin",
"version": "v4.6.1",
@ -5916,6 +5810,56 @@
],
"time": "2020-01-15T10:00:00+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",
@ -5965,53 +5909,41 @@
"time": "2016-01-20T08:20:44+00:00"
},
{
"name": "laravel/dusk",
"version": "v5.9.2",
"name": "maximebf/debugbar",
"version": "v1.16.1",
"source": {
"type": "git",
"url": "https://github.com/laravel/dusk.git",
"reference": "7abf5a7152863f8597a43d640cce3adb6cd8ab3f"
"url": "https://github.com/maximebf/php-debugbar.git",
"reference": "58998b818c6567fac01e35b8a4b70c1a64530556"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/laravel/dusk/zipball/7abf5a7152863f8597a43d640cce3adb6cd8ab3f",
"reference": "7abf5a7152863f8597a43d640cce3adb6cd8ab3f",
"url": "https://api.github.com/repos/maximebf/php-debugbar/zipball/58998b818c6567fac01e35b8a4b70c1a64530556",
"reference": "58998b818c6567fac01e35b8a4b70c1a64530556",
"shasum": ""
},
"require": {
"ext-json": "*",
"ext-zip": "*",
"illuminate/console": "~5.7.0|~5.8.0|^6.0|^7.0",
"illuminate/support": "~5.7.0|~5.8.0|^6.0|^7.0",
"nesbot/carbon": "^1.20|^2.0",
"php": ">=7.1.0",
"php-webdriver/webdriver": "^1.8.1",
"symfony/console": "^4.0|^5.0",
"symfony/finder": "^4.0|^5.0",
"symfony/process": "^4.0|^5.0",
"vlucas/phpdotenv": "^2.2|^3.0|^4.0"
"php": "^7.1",
"psr/log": "^1.0",
"symfony/var-dumper": "^2.6|^3|^4|^5"
},
"require-dev": {
"mockery/mockery": "^1.0",
"phpunit/phpunit": "^7.5|^8.0"
"phpunit/phpunit": "^5"
},
"suggest": {
"ext-pcntl": "Used to gracefully terminate Dusk when tests are running."
"kriswallsmith/assetic": "The best way to manage assets",
"monolog/monolog": "Log using Monolog",
"predis/predis": "Redis storage"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "5.0-dev"
},
"laravel": {
"providers": [
"Laravel\\Dusk\\DuskServiceProvider"
]
"dev-master": "1.16-dev"
}
},
"autoload": {
"psr-4": {
"Laravel\\Dusk\\": "src/"
"DebugBar\\": "src/DebugBar/"
}
},
"notification-url": "https://packagist.org/downloads/",
@ -6020,82 +5952,22 @@
],
"authors": [
{
"name": "Taylor Otwell",
"email": "taylor@laravel.com"
}
],
"description": "Laravel Dusk provides simple end-to-end testing and browser automation.",
"keywords": [
"laravel",
"testing",
"webdriver"
],
"time": "2020-02-18T19:13:12+00:00"
},
{
"name": "league/commonmark-ext-table",
"version": "v2.1.0",
"source": {
"type": "git",
"url": "https://github.com/thephpleague/commonmark-ext-table.git",
"reference": "3228888ea69636e855efcf6636ff8e6316933fe7"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/thephpleague/commonmark-ext-table/zipball/3228888ea69636e855efcf6636ff8e6316933fe7",
"reference": "3228888ea69636e855efcf6636ff8e6316933fe7",
"shasum": ""
},
"require": {
"league/commonmark": "~0.19.3|^1.0",
"php": "^7.1"
},
"require-dev": {
"friendsofphp/php-cs-fixer": "^2.14",
"phpstan/phpstan": "~0.11",
"phpunit/phpunit": "^7.0|^8.0",
"symfony/var-dumper": "^4.0",
"vimeo/psalm": "^3.0"
},
"type": "commonmark-extension",
"extra": {
"branch-alias": {
"dev-master": "2.2-dev"
}
},
"autoload": {
"psr-4": {
"League\\CommonMark\\Ext\\Table\\": "src"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Martin Hasoň",
"email": "martin.hason@gmail.com"
"name": "Maxime Bouroumeau-Fuseau",
"email": "maxime.bouroumeau@gmail.com",
"homepage": "http://maximebf.com"
},
{
"name": "Webuni s.r.o.",
"homepage": "https://www.webuni.cz"
},
{
"name": "Colin O'Dell",
"email": "colinodell@gmail.com",
"homepage": "https://www.colinodell.com"
"name": "Barry vd. Heuvel",
"email": "barryvdh@gmail.com"
}
],
"description": "Table extension for league/commonmark",
"homepage": "https://github.com/thephpleague/commonmark-ext-table",
"description": "Debug bar in the browser for php application",
"homepage": "https://github.com/maximebf/php-debugbar",
"keywords": [
"commonmark",
"extension",
"markdown",
"table"
"debug",
"debugbar"
],
"time": "2019-09-26T13:28:33+00:00"
"time": "2019-11-24T09:46:11+00:00"
},
{
"name": "mockery/mockery",
@ -6376,71 +6248,6 @@
"description": "Library for handling version information and constraints",
"time": "2018-07-08T19:19:57+00:00"
},
{
"name": "php-webdriver/webdriver",
"version": "1.8.2",
"source": {
"type": "git",
"url": "https://github.com/php-webdriver/php-webdriver.git",
"reference": "3308a70be084d6d7fd1ee5787b4c2e6eb4b70aab"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/php-webdriver/php-webdriver/zipball/3308a70be084d6d7fd1ee5787b4c2e6eb4b70aab",
"reference": "3308a70be084d6d7fd1ee5787b4c2e6eb4b70aab",
"shasum": ""
},
"require": {
"ext-curl": "*",
"ext-json": "*",
"ext-zip": "*",
"php": "^5.6 || ~7.0",
"symfony/polyfill-mbstring": "^1.12",
"symfony/process": "^2.8 || ^3.1 || ^4.0 || ^5.0"
},
"require-dev": {
"friendsofphp/php-cs-fixer": "^2.0",
"jakub-onderka/php-parallel-lint": "^1.0",
"php-coveralls/php-coveralls": "^2.0",
"php-mock/php-mock-phpunit": "^1.1",
"phpunit/phpunit": "^5.7",
"sebastian/environment": "^1.3.4 || ^2.0 || ^3.0",
"sminnee/phpunit-mock-objects": "^3.4",
"squizlabs/php_codesniffer": "^3.5",
"symfony/var-dumper": "^3.3 || ^4.0 || ^5.0"
},
"suggest": {
"ext-SimpleXML": "For Firefox profile creation"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.8.x-dev"
}
},
"autoload": {
"psr-4": {
"Facebook\\WebDriver\\": "lib/"
},
"files": [
"lib/Exception/TimeoutException.php"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"description": "A PHP client for Selenium WebDriver. Previously facebook/webdriver.",
"homepage": "https://github.com/php-webdriver/php-webdriver",
"keywords": [
"Chromedriver",
"geckodriver",
"php",
"selenium",
"webdriver"
],
"time": "2020-03-04T14:40:12+00:00"
},
{
"name": "phpdocumentor/reflection-common",
"version": "2.0.0",

View File

@ -49,10 +49,10 @@ class Cart extends JsonResource
'formated_tax_total' => core()->formatPrice($this->tax_total, $this->cart_currency_code),
'base_tax_total' => $this->base_tax_total,
'formated_base_tax_total' => core()->formatBasePrice($this->base_tax_total),
'discount' => $this->discount,
'formated_discount' => core()->formatPrice($this->discount, $this->cart_currency_code),
'base_discount' => $this->base_discount,
'formated_base_discount' => core()->formatBasePrice($this->base_discount),
'discount' => $this->discount_amount,
'formated_discount' => core()->formatPrice($this->discount_amount, $this->cart_currency_code),
'base_discount' => $this->base_discount_amount,
'formated_base_discount' => core()->formatBasePrice($this->base_discount_amount),
'checkout_method' => $this->checkout_method,
'is_guest' => $this->is_guest,
'is_active' => $this->is_active,
@ -93,4 +93,4 @@ class Cart extends JsonResource
return $result;
}
}
}

View File

@ -11,7 +11,8 @@ class Order extends JsonResource
/**
* Transform the resource into an array.
*
* @param \Illuminate\Http\Request
* @param \Illuminate\Http\Request
*
* @return array
*/
public function toArray($request)
@ -103,7 +104,7 @@ class Order extends JsonResource
'items' => OrderItem::collection($this->items),
'invoices' => Invoice::collection($this->invoices),
'shipments' => Shipment::collection($this->shipments),
'created_at' => $this->created_at
'created_at' => $this->created_at,
];
}
}

View File

@ -30,6 +30,37 @@ return [
'channel_based' => true,
],
],
], [
'key' => 'general.general.email_settings',
'name' => 'admin::app.admin.system.email-settings',
'sort' => 1,
'fields' => [
[
'name' => 'sender_name',
'title' => 'admin::app.admin.system.email-sender-name',
'type' => 'text',
'validation' => 'required|max:50',
'channel_based' => true,
], [
'name' => 'shop_email_from',
'title' => 'admin::app.admin.system.shop-email-from',
'type' => 'text',
'validation' => 'required|email',
'channel_based' => true,
], [
'name' => 'admin_name',
'title' => 'admin::app.admin.system.admin-name',
'type' => 'text',
'validation' => 'required|max:50',
'channel_based' => true,
], [
'name' => 'admin_email',
'title' => 'admin::app.admin.system.admin-email',
'type' => 'text',
'validation' => 'required|email',
'channel_based' => true,
],
],
], [
'key' => 'general.content',
'name' => 'admin::app.admin.system.content',

View File

@ -13,7 +13,6 @@ use Webkul\Admin\Mail\NewRefundNotification;
class Order
{
/**
* Send new order Mail to the customer and admin
*
@ -24,11 +23,13 @@ class Order
{
try {
$configKey = 'emails.general.notifications.emails.general.notifications.new-order';
if (core()->getConfigData($configKey)) {
Mail::queue(new NewOrderNotification($order));
}
$configKey = 'emails.general.notifications.emails.general.notifications.new-admin';
if (core()->getConfigData($configKey)) {
Mail::queue(new NewAdminNotification($order));
}
@ -51,6 +52,7 @@ class Order
}
$configKey = 'emails.general.notifications.emails.general.notifications.new-invoice';
if (core()->getConfigData($configKey)) {
Mail::queue(new NewInvoiceNotification($invoice));
}
@ -69,6 +71,7 @@ class Order
{
try {
$configKey = 'emails.general.notifications.emails.general.notifications.new-refund';
if (core()->getConfigData($configKey)) {
Mail::queue(new NewRefundNotification($refund));
}
@ -80,7 +83,7 @@ class Order
/**
* Send new shipment mail to the customer
*
* @param \Webkul\Sales\Contracts\Shipment $refund
* @param \Webkul\Sales\Contracts\Shipment $shipment
* @return void
*/
public function sendNewShipmentMail($shipment)
@ -91,11 +94,13 @@ class Order
}
$configKey = 'emails.general.notifications.emails.general.notifications.new-shipment';
if (core()->getConfigData($configKey)) {
Mail::queue(new NewShipmentNotification($shipment));
}
$configKey = 'emails.general.notifications.emails.general.notifications.new-inventory-source';
if (core()->getConfigData($configKey)) {
Mail::queue(new NewInventorySourceNotification($shipment));
}

View File

@ -27,7 +27,8 @@ class CancelOrderNotification extends Mailable
public function build()
{
return $this->to($this->order->customer_email, $this->order->customer_full_name)
return $this->from(core()->getSenderEmailDetails()['email'], core()->getSenderEmailDetails()['name'])
->to($this->order->customer_email, $this->order->customer_full_name)
->subject(trans('shop::app.mail.order.cancel.subject'))
->view('shop::emails.sales.order-cancel');
}

View File

@ -36,7 +36,8 @@ class NewAdminNotification extends Mailable
*/
public function build()
{
return $this->to(config('mail.admin.address'))
return $this->from(core()->getSenderEmailDetails()['email'], core()->getSenderEmailDetails()['name'])
->to(core()->getAdminEmailDetails()['email'])
->subject(trans('shop::app.mail.order.subject'))
->view('shop::emails.sales.new-admin-order');
}

View File

@ -49,7 +49,8 @@ class NewCustomerNotification extends Mailable
*/
public function build()
{
return $this->to($this->customer->email)
return $this->from(core()->getSenderEmailDetails()['email'], core()->getSenderEmailDetails()['name'])
->to($this->customer->email)
->subject(trans('shop::app.mail.customer.new.subject'))
->view('shop::emails.customer.new-customer')->with(['customer' => $this->customer, 'password' => $this->password]);
}

View File

@ -40,7 +40,8 @@ class NewInventorySourceNotification extends Mailable
$inventory = $this->shipment->inventory_source;
return $this->to($inventory->contact_email, $inventory->name)
return $this->from(core()->getSenderEmailDetails()['email'], core()->getSenderEmailDetails()['name'])
->to($inventory->contact_email, $inventory->name)
->subject(trans('shop::app.mail.shipment.subject', ['order_id' => $order->increment_id]))
->view('shop::emails.sales.new-inventorysource-shipment');
}

View File

@ -38,7 +38,8 @@ class NewInvoiceNotification extends Mailable
{
$order = $this->invoice->order;
return $this->to($order->customer_email, $order->customer_full_name)
return $this->from(core()->getSenderEmailDetails()['email'], core()->getSenderEmailDetails()['name'])
->to($order->customer_email, $order->customer_full_name)
->subject(trans('shop::app.mail.invoice.subject', ['order_id' => $order->increment_id]))
->view('shop::emails.sales.new-invoice');
}

View File

@ -36,7 +36,8 @@ class NewOrderNotification extends Mailable
*/
public function build()
{
return $this->to($this->order->customer_email, $this->order->customer_full_name)
return $this->from(core()->getSenderEmailDetails()['email'], core()->getSenderEmailDetails()['name'])
->to($this->order->customer_email, $this->order->customer_full_name)
->subject(trans('shop::app.mail.order.subject'))
->view('shop::emails.sales.new-order');
}

View File

@ -38,7 +38,8 @@ class NewRefundNotification extends Mailable
{
$order = $this->refund->order;
return $this->to($order->customer_email, $order->customer_full_name)
return $this->from(core()->getSenderEmailDetails()['email'], core()->getSenderEmailDetails()['name'])
->to($order->customer_email, $order->customer_full_name)
->subject(trans('shop::app.mail.refund.subject', ['order_id' => $order->increment_id]))
->view('shop::emails.sales.new-refund');
}

View File

@ -38,7 +38,8 @@ class NewShipmentNotification extends Mailable
{
$order = $this->shipment->order;
return $this->to($order->customer_email, $order->customer_full_name)
return $this->from(core()->getSenderEmailDetails()['email'], core()->getSenderEmailDetails()['name'])
->to($order->customer_email, $order->customer_full_name)
->subject(trans('shop::app.mail.shipment.subject', ['order_id' => $order->increment_id]))
->view('shop::emails.sales.new-shipment');
}

View File

@ -1301,7 +1301,9 @@ return [
'default' => 'إفتراضي',
'sandbox' => 'صندوق الرمل',
'all-channels' => 'الكل',
'all-locales' => 'الكل'
'all-locales' => 'الكل',
'invoice-slip-design' => 'Invoice Slip Design',
'logo' => 'logo'
]
]
];

View File

@ -1286,6 +1286,11 @@ return [
'footer-toggle' => 'Toggle footer',
'locale-options' => 'Unit Options',
'weight-unit' => 'Weight Unit',
'email-settings' => 'Email Settings',
'email-sender-name' => 'Email Sender Name',
'shop-email-from' => 'Shop Email Address [For sending emails]',
'admin-name' => 'Admin Name',
'admin-email' => 'Admin Email',
'admin-page-limit' => 'Default Items Per Page (Admin)',
'design' => 'Design',
'admin-logo' => 'Admin Logo',
@ -1301,7 +1306,9 @@ return [
'default' => 'Default',
'sandbox' => 'Sandbox',
'all-channels' => 'All',
'all-locales' => 'All'
]
'all-locales' => 'All',
'invoice-slip-design' => 'Invoice Slip Design',
'logo' => 'logo'
]
]
];

View File

@ -1287,6 +1287,11 @@ return [
'locale-options' => 'گزینه های واحد',
'weight-unit' => 'واحد وزن',
'admin-page-limit' => 'موارد پیش فرض در هر صفحه (مدیر)',
'email-settings' => 'Email Settings',
'email-sender-name' => 'Email Sender Name',
'shop-email-from' => 'Shop Email Address [For sending emails]',
'admin-name' => 'Admin Name',
'admin-email' => 'Admin Email',
'design' => 'طراحی',
'admin-logo' => 'لوگو مدیر',
'logo-image' => 'تصویر لوگو',
@ -1301,7 +1306,10 @@ return [
'default' => 'پیش فرض',
'sandbox' => 'Sandbox',
'all-channels' => 'همه',
'all-locales' => 'همه'
'all-locales' => 'همه',
'sandbox' => 'Sandbox',
'invoice-slip-design' => 'Invoice Slip Design',
'logo' => 'logo'
]
]
];

View File

@ -1286,6 +1286,11 @@ return [
'footer-toggle' => 'Voettekst in- / uitschakelen',
'locale-options' => 'Eenheid opties',
'weight-unit' => 'Gewichtseenheid',
'email-settings' => 'Email Settings',
'email-sender-name' => 'Email Sender Name',
'shop-email-from' => 'Shop Email Address [For sending emails]',
'admin-name' => 'Admin Name',
'admin-email' => 'Admin Email',
'admin-page-limit' => 'Standaarditems per pagina (Admin)',
'design' => 'Ontwerp',
'admin-logo' => 'Admin Logo',
@ -1301,7 +1306,9 @@ return [
'default' => 'Standaard',
'sandbox' => 'Sandbox',
'all-channels' => 'Alles',
'all-locales' => 'Alles'
'all-locales' => 'Alles',
'invoice-slip-design' => 'Invoice Slip Design',
'logo' => 'logo'
]
]
];

View File

@ -1288,6 +1288,12 @@ return [
'weight-unit' => 'Unidade de peso',
'admin-page-limit' => 'Itens padrão por página (administrador)',
'design' => 'Projeto',
'email-settings' => 'Email Settings',
'email-sender-name' => 'Email Sender Name',
'shop-email-from' => 'Shop Email Address [For sending emails]',
'admin-name' => 'Admin Name',
'admin-email' => 'Admin Email',
'design' => 'Design',
'admin-logo' => 'Admin Logo',
'logo-image' => 'Logo Imagem',
'credit-max' => 'Máximo de crédito do cliente',
@ -1301,7 +1307,10 @@ return [
'default' => 'Padrão',
'sandbox' => 'Sandbox',
'all-channels' => 'Todos',
'all-locales' => 'Todos'
'all-locales' => 'Todos',
'sandbox' => 'Sandbox',
'invoice-slip-design' => 'Invoice Slip Design',
'logo' => 'logo'
]
]
];

View File

@ -75,12 +75,28 @@
font-weight: 600;
}
.logo {
height: 70px;
width: 70px;
}
</style>
</head>
<body style="background-image: none;background-color: #fff;">
<div class="container">
<div class="header">
<div class="image">
<img class="logo" src="{{ Storage::url(core()->getConfigData('sales.orderSettings.invoice_slip_design.logo')) }}"/>
</div>
<div class="address">
<p>
<b> {{ core()->getConfigData('sales.orderSettings.invoice_slip_design.address') }} </b>
</p>
</div>
</div>
<div class="invoice-summary">
<div class="row">

View File

@ -3,6 +3,7 @@
namespace Webkul\BookingProduct\Helpers;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Arr;
use Carbon\Carbon;
use Webkul\BookingProduct\Repositories\BookingProductRepository;
use Webkul\BookingProduct\Repositories\BookingProductDefaultSlotRepository;
@ -269,6 +270,13 @@ class Booking
? $bookingProductSlot->slots
: ($bookingProductSlot->slots[$requestedDate->format('w')] ?? []);
if ($requestedDate < $currentTime
|| $requestedDate < $availableFrom
|| $requestedDate > $availableTo
) {
return [];
}
$slots = [];
foreach ($timeDurations as $timeDuration) {
@ -332,7 +340,7 @@ class Booking
{
$bookingProduct = $this->bookingProductRepository->findOneByField('product_id', $cartItem['product_id']);
if ($bookingProduct->qty - $this->getBookedQuantity($cartItem) < $cartItem['quantity']) {
if ($bookingProduct->qty - $this->getBookedQuantity($cartItem) < $cartItem['quantity'] || $this->isSlotExpired($cartItem)) {
return false;
}
@ -354,6 +362,25 @@ class Booking
return true;
}
/**
* @param \Webkul\Ceckout\Contracts\CartItem|array $cartItem
* @return bool
*/
public function isSlotExpired($cartItem)
{
$bookingProduct = $this->bookingProductRepository->findOneByField('product_id', $cartItem['product_id']);
$typeHelper = app($this->typeHelpers[$bookingProduct->type]);
$slots = $typeHelper->getSlotsByDate($bookingProduct, $cartItem['additional']['booking']['date']);
$filtered = Arr::where($slots, function ($slot, $key) use ($cartItem) {
return $slot['timestamp'] == $cartItem['additional']['booking']['slot'];
});
return count($filtered) ? false : true;
}
/**
* @param array $data
* @return int
@ -501,7 +528,7 @@ class Booking
* Validate cart item product price
*
* @param \Webkul\Checkout\Contracts\CartItem $item
* @return float
* @return void
*/
public function validateCartItem($item)
{

View File

@ -4,6 +4,7 @@ namespace Webkul\BookingProduct\Helpers;
use Illuminate\Support\Facades\DB;
use Carbon\Carbon;
use Webkul\Checkout\Facades\Cart;
class RentalSlot extends Booking
{
@ -38,6 +39,13 @@ class RentalSlot extends Booking
? $bookingProductSlot->slots
: $bookingProductSlot->slots[$requestedDate->format('w')];
if ($requestedDate < $currentTime
|| $requestedDate < $availableFrom
|| $requestedDate > $availableTo
) {
return [];
}
$slots = [];
foreach ($timeDurations as $index => $timeDuration) {
@ -126,6 +134,33 @@ class RentalSlot extends Booking
return ! is_null($result->total_qty_booked) ? $result->total_qty_booked : 0;
}
/**
* @param \Webkul\Ceckout\Contracts\CartItem|array $cartItem
* @return bool
*/
public function isSlotExpired($cartItem)
{
$bookingProduct = $this->bookingProductRepository->findOneByField('product_id', $cartItem['product_id']);
$typeHelper = app($this->typeHelpers[$bookingProduct->type]);
$timeIntervals = $typeHelper->getSlotsByDate($bookingProduct, $cartItem['additional']['booking']['date']);
$isExpired = true;
foreach ($timeIntervals as $timeInterval) {
foreach ($timeInterval['slots'] as $slot) {
if ($slot['from_timestamp'] == $cartItem['additional']['booking']['slot']['from']
&& $slot['to_timestamp'] == $cartItem['additional']['booking']['slot']['to']
) {
$isExpired = false;
}
}
}
return $isExpired;
}
/**
* Add booking additional prices to cart item
*
@ -162,7 +197,7 @@ class RentalSlot extends Booking
* Validate cart item product price
*
* @param \Webkul\Checkout\Contracts\CartItem $item
* @return float
* @return void|null
*/
public function validateCartItem($item)
{
@ -173,11 +208,27 @@ class RentalSlot extends Booking
$rentingType = $item->additional['booking']['renting_type'] ?? $bookingProduct->rental_slot->renting_type;
if ($rentingType == 'daily') {
if (! isset($item->additional['booking']['date_from'])
|| ! isset($item->additional['booking']['date_to'])
) {
Cart::removeItem($item->id);
return true;
}
$from = Carbon::createFromTimeString($item->additional['booking']['date_from'] . " 00:00:00");
$to = Carbon::createFromTimeString($item->additional['booking']['date_to'] . " 24:00:00");
$price += $item->product->getTypeInstance()->getFinalPrice() + $bookingProduct->rental_slot->daily_price * $to->diffInDays($from);
$price += $bookingProduct->rental_slot->daily_price * $to->diffInDays($from);
} else {
if (! isset($item->additional['booking']['slot']['from'])
|| ! isset($item->additional['booking']['slot']['to'])
) {
Cart::removeItem($item->id);
return true;
}
$from = Carbon::createFromTimestamp($item->additional['booking']['slot']['from']);
$to = Carbon::createFromTimestamp($item->additional['booking']['slot']['to']);

View File

@ -209,7 +209,13 @@ class Booking extends Virtual
return false;
}
return $options1['booking'] == $options2['booking'];
if (isset($options1['booking']) && isset($options2['booking'])) {
return $options1['booking'] === $options2['booking'];
} elseif (! isset($options1['booking'])) {
return false;
} elseif (! isset($options2['booking'])) {
return false;
}
}
/**
@ -237,6 +243,6 @@ class Booking extends Virtual
return;
}
app($this->bookingHelper->getTypeHepler($bookingProduct->type))->validateCartItem($item);
return app($this->bookingHelper->getTypeHepler($bookingProduct->type))->validateCartItem($item);
}
}

View File

@ -2,6 +2,7 @@
namespace Webkul\Checkout;
use Webkul\Checkout\Models\CartAddress;
use Webkul\Checkout\Repositories\CartRepository;
use Webkul\Checkout\Repositories\CartItemRepository;
use Webkul\Checkout\Repositories\CartAddressRepository;
@ -141,7 +142,7 @@ class Cart
if (is_string($cartProducts)) {
$this->collectTotals();
if (! count($cart->all_items) > 0) {
if (count($cart->all_items) <= 0) {
session()->forget('cart');
}
@ -298,7 +299,7 @@ class Cart
* Remove the item from the cart
*
* @param int $itemId
* @return bool
* @return boolean
*/
public function removeItem($itemId)
{
@ -340,6 +341,7 @@ class Cart
$guestCart = session()->get('cart');
//when the logged in customer is not having any of the cart instance previously and are active.
if (! $cart) {
$this->cartRepository->update([
'customer_id' => $this->getCurrentCustomer()->user()->id,
@ -358,7 +360,11 @@ class Cart
$found = false;
foreach ($cart->items as $cartItem) {
if (! $cartItem->product->getTypeInstance()->compareOptions($cartItem->additional, $guestCartItem->additional)) {
if (! $cartItem
->product
->getTypeInstance()
->compareOptions($cartItem->additional, $guestCartItem->additional)
) {
continue;
}
@ -458,7 +464,7 @@ class Cart
if ($cart->haveStockableItems()) {
$data['shipping_address'] = $cart->shipping_address->toArray();
$data['selected_shipping_rate'] = $cart->selected_shipping_rate->toArray();
$data['selected_shipping_rate'] = $cart->selected_shipping_rate ? $cart->selected_shipping_rate->toArray() : 0.0;
}
$data['payment'] = $cart->payment->toArray();
@ -471,110 +477,25 @@ class Cart
/**
* Save customer address
*
* @param array $data
* @return bool
* @param array $data
*
* @return void is the cart valid
*/
public function saveCustomerAddress($data)
public function saveCustomerAddress($data): bool
{
if (! $cart = $this->getCart()) {
return false;
}
$billingAddress = $data['billing'];
$billingAddress['cart_id'] = $cart->id;
$billingAddressData = $this->gatherBillingAddress($data, $cart);
if (isset($data['billing']['address_id']) && $data['billing']['address_id']) {
$address = $this->customerAddressRepository->findOneWhere(['id' => $data['billing']['address_id']])->toArray();
$shippingAddressData = $this->gatherShippingAddress($data, $cart);
$billingAddress['first_name'] = $this->getCurrentCustomer()->user()->first_name;
$billingAddress['last_name'] = $this->getCurrentCustomer()->user()->last_name;
$billingAddress['email'] = $this->getCurrentCustomer()->user()->email;
$billingAddress['address1'] = $address['address1'];
$billingAddress['country'] = $address['country'];
$billingAddress['state'] = $address['state'];
$billingAddress['city'] = $address['city'];
$billingAddress['postcode'] = $address['postcode'];
$billingAddress['phone'] = $address['phone'];
}
$this->saveAddressesWhenRequested($data, $billingAddressData, $shippingAddressData);
if (isset($data['billing']['save_as_address']) && $data['billing']['save_as_address']) {
$billingAddress['customer_id'] = $this->getCurrentCustomer()->user()->id;
$this->linkAddresses($cart, $billingAddressData, $shippingAddressData);
$this->customerAddressRepository->create($billingAddress);
}
if ($cart->haveStockableItems()) {
$shippingAddress = $data['shipping'];
$shippingAddress['cart_id'] = $cart->id;
if (isset($data['shipping']['address_id']) && $data['shipping']['address_id']) {
$address = $this->customerAddressRepository->findOneWhere(['id' => $data['shipping']['address_id']])->toArray();
$shippingAddress['first_name'] = $this->getCurrentCustomer()->user()->first_name;
$shippingAddress['last_name'] = $this->getCurrentCustomer()->user()->last_name;
$shippingAddress['email'] = $this->getCurrentCustomer()->user()->email;
$shippingAddress['address1'] = $address['address1'];
$shippingAddress['country'] = $address['country'];
$shippingAddress['state'] = $address['state'];
$shippingAddress['city'] = $address['city'];
$shippingAddress['postcode'] = $address['postcode'];
$shippingAddress['phone'] = $address['phone'];
}
if (isset($data['shipping']['save_as_address']) && $data['shipping']['save_as_address']) {
$shippingAddress['customer_id'] = $this->getCurrentCustomer()->user()->id;
$this->customerAddressRepository->create($shippingAddress);
}
}
if ($billingAddressModel = $cart->billing_address) {
$this->cartAddressRepository->update($billingAddress, $billingAddressModel->id);
if ($cart->haveStockableItems()) {
if ($shippingAddressModel = $cart->shipping_address) {
if (isset($billingAddress['use_for_shipping']) && $billingAddress['use_for_shipping']) {
$this->cartAddressRepository->update($billingAddress, $shippingAddressModel->id);
} else {
$this->cartAddressRepository->update($shippingAddress, $shippingAddressModel->id);
}
} else {
if (isset($billingAddress['use_for_shipping']) && $billingAddress['use_for_shipping']) {
$this->cartAddressRepository->create(
array_merge($billingAddress, ['address_type' => 'shipping'])
);
} else {
$this->cartAddressRepository->create(
array_merge($shippingAddress, ['address_type' => 'shipping'])
);
}
}
}
} else {
$this->cartAddressRepository->create(array_merge($billingAddress, ['address_type' => 'billing']));
if ($cart->haveStockableItems()) {
if (isset($billingAddress['use_for_shipping']) && $billingAddress['use_for_shipping']) {
$this->cartAddressRepository->create(
array_merge($billingAddress, ['address_type' => 'shipping'])
);
} else {
$this->cartAddressRepository->create(
array_merge($shippingAddress, ['address_type' => 'shipping'])
);
}
}
}
if ($this->getCurrentCustomer()->check()) {
$cart->customer_email = $this->getCurrentCustomer()->user()->email;
$cart->customer_first_name = $this->getCurrentCustomer()->user()->first_name;
$cart->customer_last_name = $this->getCurrentCustomer()->user()->last_name;
} else {
$cart->customer_email = $cart->billing_address->email;
$cart->customer_first_name = $cart->billing_address->first_name;
$cart->customer_last_name = $cart->billing_address->last_name;
}
$this->assignCustomerFields($cart);
$cart->save();
@ -589,7 +510,7 @@ class Cart
* @param string $shippingMethodCode
* @return bool
*/
public function saveShippingMethod($shippingMethodCode)
public function saveShippingMethod($shippingMethodCode): bool
{
if (! $cart = $this->getCart()) {
return false;
@ -646,6 +567,7 @@ class Cart
Event::dispatch('checkout.cart.collect.totals.before', $cart);
$this->calculateItemsTax();
$cart->refresh();
$cart->grand_total = $cart->base_grand_total = 0;
$cart->sub_total = $cart->base_sub_total = 0;
@ -706,7 +628,11 @@ class Cart
return false;
} else {
foreach ($cart->items as $item) {
$item->product->getTypeInstance()->validateCartItem($item);
$response = $item->product->getTypeInstance()->validateCartItem($item);
if ($response) {
return;
}
$price = ! is_null($item->custom_price) ? $item->custom_price : $item->base_price;
@ -732,6 +658,8 @@ class Cart
if (! $cart = $this->getCart()) {
return;
}
Event::dispatch('checkout.cart.calculate.items.tax.before', $cart);
foreach ($cart->items()->get() as $item) {
$taxCategory = $this->taxCategoryRepository->find($item->product->tax_category_id);
@ -748,7 +676,7 @@ class Cart
if ($address === null && auth()->guard('customer')->check()) {
$address = auth()->guard('customer')->user()->addresses()
->where('default_address',1)->first();
->where('default_address', 1)->first();
}
if ($address === null) {
@ -787,7 +715,7 @@ class Cart
$haveTaxRate = true;
}
}
if ($haveTaxRate) {
$item->tax_percent = $rate->tax_rate;
$item->tax_amount = ($item->total * $rate->tax_rate) / 100;
@ -800,6 +728,7 @@ class Cart
$item->save();
}
Event::dispatch('checkout.cart.calculate.items.tax.after', $cart);
}
/**
@ -926,6 +855,7 @@ class Cart
'shipping_discount_amount' => $data['selected_shipping_rate']['discount_amount'],
'base_shipping_discount_amount' => $data['selected_shipping_rate']['base_discount_amount'],
]);
}
foreach ($data['items'] as $item) {
@ -1005,7 +935,8 @@ class Cart
}
/**
* Function to move a already added product to wishlist will run only on customer authentication.
* Function to move a already added product to wishlist will run only on customer
* authentication.
*
* @param int $itemId
* @return bool
@ -1039,7 +970,7 @@ class Cart
}
}
if (!$found) {
if (! $found) {
$this->wishlistRepository->create([
'channel_id' => $cart->channel_id,
'customer_id' => $this->getCurrentCustomer()->user()->id,
@ -1091,4 +1022,200 @@ class Cart
return $this;
}
/**
* Transfer the user profile information into the cart/into the order.
*
* When logged in as guest or the customer profile is not complete, we use the
* billing address to fill the order customer_ data.
*
* @param \Webkul\Checkout\Models\Cart $cart
*/
private function assignCustomerFields(\Webkul\Checkout\Models\Cart $cart): void
{
if ($this->getCurrentCustomer()->check()
&& ($user = $this->getCurrentCustomer()->user())
&& $this->profileIsComplete($user)
) {
$cart->customer_email = $user->email;
$cart->customer_first_name = $user->first_name;
$cart->customer_last_name = $user->last_name;
} else {
$cart->customer_email = $cart->billing_address->email;
$cart->customer_first_name = $cart->billing_address->first_name;
$cart->customer_last_name = $cart->billing_address->last_name;
}
}
/**
* @param $user
*
* @return bool
*/
private function profileIsComplete($user): bool
{
return $user->email && $user->first_name && $user->last_name;
}
/**
* @return array
*/
private function fillCustomerAttributes(): array
{
$attributes = [];
$user = $this->getCurrentCustomer()->user();
if ($user) {
$attributes['first_name'] = $user->first_name;
$attributes['last_name'] = $user->last_name;
$attributes['email'] = $user->email;
$attributes['customer_id'] = $user->id;
}
return $attributes;
}
/**
* @return array
*/
private function fillAddressAttributes(array $addressAttributes): array
{
$attributes = [];
$cartAddress = new CartAddress();
foreach ($cartAddress->getFillable() as $attribute) {
if (isset($addressAttributes[$attribute])) {
$attributes[$attribute] = $addressAttributes[$attribute];
}
}
return $attributes;
}
/**
* @param array $data
* @param array $billingAddress
* @param array $shippingAddress
*/
private function saveAddressesWhenRequested(
array $data,
array $billingAddress,
array $shippingAddress
): void
{
if (isset($data['billing']['save_as_address']) && $data['billing']['save_as_address']) {
$this->customerAddressRepository->create($billingAddress);
}
if (isset($data['shipping']['save_as_address']) && $data['shipping']['save_as_address']) {
$this->customerAddressRepository->create($shippingAddress);
}
}
/**
* @param $data
* @param $cart
*
* @return array
*/
private function gatherBillingAddress($data, \Webkul\Checkout\Models\Cart $cart): array
{
$customerAddress = [];
if (isset($data['billing']['address_id']) && $data['billing']['address_id']) {
$customerAddress = $this
->customerAddressRepository
->findOneWhere(['id' => $data['billing']['address_id']])
->toArray();
}
$billingAddress = array_merge(
$customerAddress,
$data['billing'],
['cart_id' => $cart->id],
$this->fillCustomerAttributes(),
$this->fillAddressAttributes($data['billing'])
);
return $billingAddress;
}
/**
* @param $data
* @param \Webkul\Checkout\Cart|null $cart
*
* @return array
*/
private function gatherShippingAddress($data, \Webkul\Checkout\Models\Cart $cart): array
{
$customerAddress = [];
if (isset($data['shipping']['address_id']) && $data['shipping']['address_id']) {
$customerAddress = $this
->customerAddressRepository
->findOneWhere(['id' => $data['shipping']['address_id']])
->toArray();
}
$shippingAddress = array_merge(
$customerAddress,
$data['shipping'],
['cart_id' => $cart->id],
$this->fillCustomerAttributes(),
$this->fillAddressAttributes($data['shipping'])
);
return $shippingAddress;
}
/**
* @param \Webkul\Checkout\Cart|null $cart
* @param array $billingAddressData
* @param array $shippingAddressData
*
* @throws \Prettus\Validator\Exceptions\ValidatorException
*/
private function linkAddresses(
\Webkul\Checkout\Models\Cart $cart,
array $billingAddressData,
array $shippingAddressData
): void
{
$billingAddressModel = $cart->billing_address;
if ($billingAddressModel) {
$this->cartAddressRepository->update($billingAddressData, $billingAddressModel->id);
if ($cart->haveStockableItems()) {
$shippingAddressModel = $cart->shipping_address;
if ($shippingAddressModel) {
if (isset($billingAddressData['use_for_shipping']) && $billingAddressData['use_for_shipping']) {
$this->cartAddressRepository->update($billingAddressData, $shippingAddressModel->id);
} else {
$this->cartAddressRepository->update($shippingAddressData, $shippingAddressModel->id);
}
} else {
if (isset($billingAddressData['use_for_shipping']) && $billingAddressData['use_for_shipping']) {
$this->cartAddressRepository->create(array_merge($billingAddressData,
['address_type' => 'shipping']));
} else {
$this->cartAddressRepository->create(array_merge($shippingAddressData,
['address_type' => 'shipping']));
}
}
}
} else {
$this->cartAddressRepository->create(array_merge($billingAddressData, ['address_type' => 'billing']));
if ($cart->haveStockableItems()) {
if (isset($billingAddressData['use_for_shipping']) && $billingAddressData['use_for_shipping']) {
$this->cartAddressRepository->create(array_merge($billingAddressData, ['address_type' => 'shipping']));
} else {
$this->cartAddressRepository->create(array_merge($shippingAddressData, ['address_type' => 'shipping']));
}
}
}
}
}

View File

@ -23,6 +23,7 @@ class CartAddress extends Model implements CartAddressContract
'phone',
'address_type',
'cart_id',
'customer_id',
];
/**

View File

@ -4,12 +4,18 @@ namespace Webkul\Checkout\Repositories;
use Webkul\Core\Eloquent\Repository;
/**
* Cart Address Repository
*
* @author Prashant Singh <prashant.singh852@webkul.com>
* @copyright 2018 Webkul Software Pvt Ltd (http://www.webkul.com)
*/
class CartAddressRepository extends Repository
{
/**
* Specify Model class name
*
* @return Mixed
* @return string
*/
function model()
{

View File

@ -8,7 +8,6 @@
}
],
"require": {
"propaganistas/laravel-intl": "^2.0"
},
"autoload": {
"psr-4": {

View File

@ -1047,4 +1047,38 @@ class Core
{
return str_replace('.', '_', (string)$taxRate);
}
/**
* Get Shop email sender details
*
* @return array
*/
public function getSenderEmailDetails()
{
$sender_name = core()->getConfigData('general.general.email_settings.sender_name') ? core()->getConfigData('general.general.email_settings.sender_name') : config('mail.from.name');
$sender_email = core()->getConfigData('general.general.email_settings.shop_email_from') ? core()->getConfigData('general.general.email_settings.shop_email_from') : config('mail.from.address');
return [
'name' => $sender_name,
'email' => $sender_email,
];
}
/**
* Get Admin email details
*
* @return array
*/
public function getAdminEmailDetails()
{
$admin_name = core()->getConfigData('general.general.email_settings.admin_name') ? core()->getConfigData('general.general.email_settings.admin_name') : config('mail.admin.name');
$admin_email = core()->getConfigData('general.general.email_settings.admin_email') ? core()->getConfigData('general.general.email_settings.admin_email') : config('mail.admin.address');
return [
'name' => $admin_name,
'email' => $admin_email,
];
}
}

View File

@ -14,15 +14,17 @@ class CurrencyTableSeeder extends Seeder
DB::table('currencies')->delete();
DB::table('currencies')->insert([
[
'id' => 1,
'code' => 'USD',
'name' => 'US Dollar',
'symbol' => '$',
], [
'id' => 2,
'code' => 'EUR',
'name' => 'Euro',
'symbol' => '€',
]
);
]);
}
}

View File

@ -14,6 +14,7 @@ class LocalesTableSeeder extends Seeder
DB::table('locales')->delete();
DB::table('locales')->insert([
[
'id' => 1,
'code' => 'en',
'name' => 'English',
@ -22,6 +23,6 @@ class LocalesTableSeeder extends Seeder
'code' => 'fr',
'name' => 'French',
]
);
]);
}
}

View File

@ -6,9 +6,14 @@ namespace Webkul\Core\Helpers;
// all public methods declared in helper class will be available in $I
use Codeception\Module\Laravel5;
use Webkul\Checkout\Models\Cart;
use Webkul\Customer\Models\Customer;
use Webkul\Checkout\Models\CartItem;
use Illuminate\Support\Facades\Event;
use Webkul\Product\Models\Product;
use Webkul\Checkout\Models\CartAddress;
use Webkul\Product\Models\ProductInventory;
use Webkul\Customer\Models\CustomerAddress;
use Webkul\Product\Models\ProductAttributeValue;
use Webkul\Product\Models\ProductDownloadableLink;
use Webkul\Product\Models\ProductDownloadableLinkTranslation;
@ -22,7 +27,8 @@ class Laravel5Helper extends Laravel5
/**
* Returns field name of given attribute.
*
* @param string $attribute
* @param string $attribute
*
* @return string|null
* @part ORM
*/
@ -57,7 +63,7 @@ class Laravel5Helper extends Laravel5
'brand' => 'text_value',
'guest_checkout' => 'boolean_value',
];
if (! array_key_exists($attribute, $attributes)) {
return null;
}
@ -65,16 +71,119 @@ class Laravel5Helper extends Laravel5
return $attributes[$attribute];
}
/**
* Generate a cart for the customer. Usually this is necessary to prepare the database
* before testing the checkout.
*
* @param array $options pass some options to configure some of the properties of the cart
*
* @return array the generated mocks as array
*
* @throws \Exception
*/
public function prepareCart(array $options = []): array
{
$faker = \Faker\Factory::create();
$I = $this;
$product = $I->haveProduct(self::SIMPLE_PRODUCT, $options['productOptions'] ?? []);
if (isset($options['customer'])) {
$customer = $options['customer'];
} else {
$customer = $I->have(Customer::class);
}
$I->have(CustomerAddress::class, [
'customer_id' => $customer->id,
'default_address' => 1,
'first_name' => $customer->first_name,
'last_name' => $customer->last_name,
'company_name' => $faker->company,
]);
if (isset($options['payment_method'])
&& $options['payment_method'] === 'free_of_charge') {
$grand_total = '0.0000';
$base_grand_total = '0.0000';
} else {
$grand_total = (string)$faker->numberBetween(1, 666);
$base_grand_total = $grand_total;
}
$cart = $I->have(Cart::class, [
'customer_id' => $customer->id,
'customer_first_name' => $customer->first_name,
'customer_last_name' => $customer->last_name,
'customer_email' => $customer->email,
'is_active' => 1,
'channel_id' => 1,
'grand_total' => $grand_total,
'base_grand_total' => $base_grand_total,
]);
$cartAddress = $I->have(CartAddress::class, ['cart_id' => $cart->id]);
if (isset($options['product_type'])) {
$type = $options['product_type'];
} else {
$type = 'simple';
}
$totalQtyOrdered = 0;
$cartItems = [];
$generatedCartItems = rand(3, 10);
for ($i = 2; $i <= $generatedCartItems; $i++) {
$quantity = random_int(1, 10);
$cartItem = $I->have(CartItem::class, [
'type' => $type,
'quantity' => $quantity,
'cart_id' => $cart->id,
'product_id' => $product->id,
]);
$totalQtyOrdered += $quantity;
$cartItems[] = $cartItem;
}
// actually set the cart to the user's session
// when in an functional test:
$stub = new \StdClass();
$stub->id = $cart->id;
$I->setSession(['cart' => $stub]);
return [
'cart' => $cart,
'product' => $product,
'customer' => $customer,
'cartAddress' => $cartAddress,
'cartItems' => $cartItems,
'totalQtyOrdered' => $totalQtyOrdered,
];
}
/**
* Helper function to generate products for testing
*
* @param int $productType
* @param array $configs
* @param array $productStates
* @param int $productType
* @param array $configs
* @param array $productStates
*
* @return \Webkul\Product\Models\Product
* @part ORM
*/
public function haveProduct(int $productType, array $configs = [], array $productStates = []): Product
public function haveProduct(
int $productType,
array $configs = [],
array $productStates = []
): Product
{
$I = $this;
@ -86,7 +195,7 @@ class Laravel5Helper extends Laravel5
case self::VIRTUAL_PRODUCT:
$product = $I->haveVirtualProduct($configs, $productStates);
break;
case self::SIMPLE_PRODUCT:
@ -102,11 +211,36 @@ class Laravel5Helper extends Laravel5
}
/**
* @param array $configs
* @param array $productStates
* @return \Webkul\Product\Contracts\Product
* Set all session with the given key and value in the array.
*
* @param array $keyValue
*/
private function haveSimpleProduct(array $configs = [], array $productStates = []): Product
public function setSession(array $keyValue)
{
session($keyValue);
}
/**
* Flush the session data and regenerate the ID
* A logged in user will be logged off.
*
*/
public function invalidateSession()
{
session()->invalidate();
}
/**
* @param array $configs
* @param array $productStates
*
* @return \Webkul\Product\Models\Product
*/
private function haveSimpleProduct(
array $configs = [],
array $productStates = []
): Product
{
$I = $this;
@ -125,8 +259,9 @@ class Laravel5Helper extends Laravel5
}
/**
* @param array $configs
* @param array $productStates
* @param array $configs
* @param array $productStates
*
* @return \Webkul\Product\Contracts\Product
*/
private function haveVirtualProduct(array $configs = [], array $productStates = []): Product
@ -148,8 +283,9 @@ class Laravel5Helper extends Laravel5
}
/**
* @param array $configs
* @param array $productStates
* @param array $configs
* @param array $productStates
*
* @return \Webkul\Product\Contracts\Product
*/
private function haveDownloadableProduct(array $configs = [], array $productStates = []): Product
@ -182,8 +318,9 @@ class Laravel5Helper extends Laravel5
}
/**
* @param int $productId
* @param array $inventoryConfig
* @param int $productId
* @param array $inventoryConfig
*
* @return void
*/
private function createInventory(int $productId, array $inventoryConfig = []): void
@ -193,11 +330,14 @@ class Laravel5Helper extends Laravel5
$I->have(ProductInventory::class, array_merge($inventoryConfig, [
'product_id' => $productId,
'inventory_source_id' => 1,
'qty' => random_int(100, 666),
]));
}
/**
* @param int $productId
* @param int $productId
*
* @return void
*/
private function createDownloadableLink(int $productId): void
@ -214,14 +354,15 @@ class Laravel5Helper extends Laravel5
}
/**
* @param int $productId
* @param array $attributeValues
* @param int $productId
* @param array $attributeValues
*
* @return void
*/
private function createAttributeValues(int $productId, array $attributeValues = []): void
{
$I = $this;
$productAttributeValues = [
'sku',
'url_key',
@ -254,7 +395,7 @@ class Laravel5Helper extends Laravel5
$data = [$fieldName => $attributeValues[$attribute]];
}
}
$I->have(ProductAttributeValue::class, $data, $attribute);
}
}

View File

@ -8,13 +8,12 @@ use Webkul\Customer\Models\Customer;
$factory->define(Customer::class, function (Faker $faker) {
$now = date("Y-m-d H:i:s");
$gender = array_rand(['male', 'female', 'other']);
$password = $faker->password;
return [
'first_name' => $faker->firstName($gender),
'first_name' => $faker->firstName(),
'last_name' => $faker->lastName,
'gender' => ucfirst($gender),
'gender' => array_random(['male', 'female', 'other']),
'email' => $faker->email,
'status' => 1,
'password' => Hash::make($password),
@ -22,7 +21,7 @@ $factory->define(Customer::class, function (Faker $faker) {
'is_verified' => 1,
'created_at' => $now,
'updated_at' => $now,
'notes' => json_encode(array('plain_password' => $password)),
'notes' => json_encode(['plain_password' => $password]),
];
});

View File

@ -34,8 +34,9 @@ class RegistrationEmail extends Mailable
*/
public function build()
{
return $this->to($this->data['email'])
->subject(trans('shop::app.mail.customer.registration.customer-registration'))
->view('shop::emails.customer.registration')->with('data', $this->data);
return $this->from(core()->getSenderEmailDetails()['email'], core()->getSenderEmailDetails()['name'])
->to($this->data['email'])
->subject(trans('shop::app.mail.customer.registration.customer-registration'))
->view('shop::emails.customer.registration')->with('data', $this->data);
}
}

View File

@ -34,13 +34,14 @@ class VerificationEmail extends Mailable
*/
public function build()
{
return $this->to($this->verificationData['email'])
->subject(trans('shop::app.mail.customer.verification.subject'))
->view('shop::emails.customer.verification-email')
->with('data', [
'email' => $this->verificationData['email'],
'token' => $this->verificationData['token'],
]
);
return $this->from(core()->getSenderEmailDetails()['email'], core()->getSenderEmailDetails()['name'])
->to($this->verificationData['email'])
->subject(trans('shop::app.mail.customer.verification.subject'))
->view('shop::emails.customer.verification-email')
->with('data', [
'email' => $this->verificationData['email'],
'token' => $this->verificationData['token'],
]
);
}
}

View File

@ -21,10 +21,11 @@ class CustomerResetPassword extends ResetPassword
}
return (new MailMessage)
->from(core()->getSenderEmailDetails()['email'], core()->getSenderEmailDetails()['name'])
->subject(__('shop::app.mail.forget-password.subject') )
->view('shop::emails.customer.forget-password', [
'user_name' => $notifiable->name,
'token' => $this->token,
'user_name' => $notifiable->name,
'token' => $this->token,
]
);
}

View File

@ -496,8 +496,14 @@ class Bundle extends AbstractType
return false;
}
return $options1['bundle_options'] == $options2['bundle_options']
&& $options1['bundle_option_qty'] == $this->getOptionQuantities($options2);
if (isset($options1['bundle_options']) && isset($options2['bundle_options'])) {
return $options1['bundle_options'] == $options2['bundle_options']
&& $options1['bundle_option_qty'] == $this->getOptionQuantities($options2);
} elseif (! isset($options1['bundle_options'])) {
return false;
} elseif (! isset($options2['bundle_options'])) {
return false;
}
}
/**

View File

@ -460,7 +460,13 @@ class Configurable extends AbstractType
return false;
}
return $options1['selected_configurable_option'] === $options2['selected_configurable_option'];
if (isset($options1['selected_configurable_option']) && isset($options2['selected_configurable_option'])) {
return $options1['selected_configurable_option'] === $options2['selected_configurable_option'];
} elseif (! isset($options1['selected_configurable_option'])) {
return false;
} elseif (! isset($options2['selected_configurable_option'])) {
return false;
}
}
/**

View File

@ -188,7 +188,13 @@ class Downloadable extends AbstractType
return false;
}
return $options1['links'] == $options2['links'];
if (isset($options1['links']) && isset($options2['links'])) {
return $options1['links'] === $options2['links'];
} elseif (! isset($options1['links'])) {
return false;
} elseif (! isset($options2['links'])) {
return false;
}
}
/**

View File

@ -35,5 +35,24 @@ return [
'locale_based' => true,
],
]
], [
'key' => 'sales.orderSettings.invoice_slip_design',
'name' => 'admin::app.admin.system.invoice-slip-design',
'sort' => 1,
'fields' => [
[
'name' => 'logo',
'title' => 'admin::app.admin.system.logo',
'type' => 'image',
'validation' => 'mimes:jpeg,bmp,png,jpg',
'channel_based' => true,
],
[
'name' => 'address',
'title' => 'admin::app.admin.system.address',
'type' => 'textarea',
'channel_based' => true,
]
]
]
];

View File

@ -0,0 +1,31 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class FixOrderColumns extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::table('order', function (Blueprint $table) {
$table->removeColumn('customer_company_name');
$table->removeColumn('customer_vat_id');
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
//
}
}

View File

@ -2,6 +2,7 @@
namespace Webkul\Sales\Models;
use Webkul\Checkout\Models\CartProxy;
use Illuminate\Database\Eloquent\Model;
use Webkul\Sales\Contracts\Order as OrderContract;
@ -61,6 +62,15 @@ class Order extends Model implements OrderContract
return $this->grand_total - $this->grand_total_invoiced;
}
/**
* Get the associated cart that was used to create this order.
*/
public function cart()
{
return $this->belongsTo(CartProxy::modelClass());
}
/**
* Get the order items record associated with the order.
*/

View File

@ -3,6 +3,7 @@
namespace Webkul\Sales\Models;
use Illuminate\Database\Eloquent\Model;
use Webkul\Customer\Models\Customer;
use Webkul\Sales\Contracts\OrderAddress as OrderAddressContract;
class OrderAddress extends Model implements OrderAddressContract

View File

@ -135,7 +135,7 @@ class OrderItem extends Model implements OrderItemContract
}
/**
* Get the order record associated with the order item.
* Get the product record associated with the order item.
*/
public function product()
{

View File

@ -2,16 +2,21 @@
namespace Webkul\Sales\Repositories;
use Illuminate\Container\Container as App;
use Webkul\Core\Eloquent\Repository;
use Webkul\Sales\Contracts\OrderAddress;
/**
* Order Address Repository
*
* @author Jitendra Singh <jitendra@webkul.com>
* @copyright 2018 Webkul Software Pvt Ltd (http://www.webkul.com)
*/
class OrderAddressRepository extends Repository
{
/**
* Specify Model class name
*
* @return Mixed
* @return string
*/
function model()

View File

@ -49,8 +49,8 @@ class RefundItemRepository extends Repository
if ($orderItem->parent) {
$shippedQty = $orderItem->qty_ordered
? ($orderItem->qty_ordered / $orderItem->parent->qty_ordered) * $shipmentItem->qty
: $orderItem->parent->qty_ordered;
? ($orderItem->qty_ordered / $orderItem->parent->qty_ordered) * $shipmentItem->qty
: $orderItem->parent->qty_ordered;
} else {
$shippedQty = $shipmentItem->qty;
}
@ -69,7 +69,9 @@ class RefundItemRepository extends Repository
$quantity -= $totalShippedQtyToRefund;
}
} elseif ($orderItem->getTypeInstance()->showQuantityBox()) {
} elseif (! $orderItem->getTypeInstance()->isStockable()
&& $orderItem->getTypeInstance()->showQuantityBox()
) {
$inventory = $orderItem->product->inventories()
// ->where('vendor_id', $data['vendor_id'])
->whereIn('inventory_source_id', $orderItem->order->channel->inventory_sources()->pluck('id'))

View File

@ -70,6 +70,7 @@ class CartController extends Controller
if ($this->onWarningAddingToCart($result)) {
session()->flash('warning', $result['warning']);
return redirect()->back();
}
@ -82,6 +83,7 @@ class CartController extends Controller
if (request()->get('is_buy_now')) {
Event::dispatch('shop.item.buy-now', $id);
return redirect()->route('shop.checkout.onepage.index');
}
}
@ -205,10 +207,11 @@ class CartController extends Controller
/**
* Returns true, if result of adding product to cart is an array and contains a key "warning"
*
* @param array $result
* @return bool
* @param array $result
* @return boolean
*/
private function onWarningAddingToCart($result): bool {
private function onWarningAddingToCart($result): bool
{
return is_array($result) && isset($result['warning']);
}
}

View File

@ -52,12 +52,14 @@ class OnepageController extends Controller
*/
public function index()
{
if (! auth()->guard('customer')->check() && ! core()->getConfigData('catalog.products.guest-checkout.allow-guest-checkout')) {
if (! auth()->guard('customer')->check()
&& ! core()->getConfigData('catalog.products.guest-checkout.allow-guest-checkout')) {
return redirect()->route('customer.session.index');
}
if (Cart::hasError())
if (Cart::hasError()) {
return redirect()->route('shop.checkout.cart.index');
}
$cart = Cart::getCart();

View File

@ -30,14 +30,14 @@ class SubscriptionEmail extends Mailable
*/
public function build()
{
return $this->to($this->subscriptionData['email'])
->subject(trans('shop::app.mail.customer.subscription.subject'))
->view('shop::emails.customer.subscription-email')
->with('data', [
'content' => 'You Are Subscribed',
'token' => $this->subscriptionData['token'],
]
);
return $this->from(core()->getSenderEmailDetails()['email'], core()->getSenderEmailDetails()['name'])
->to($this->subscriptionData['email'])
->subject(trans('shop::app.mail.customer.subscription.subject'))
->view('shop::emails.customer.subscription-email')
->with('data', [
'content' => 'You Are Subscribed',
'token' => $this->subscriptionData['token'],
]
);
}
}

View File

@ -79,12 +79,28 @@
font-weight: 600;
}
.logo {
height: 70px;
width: 70px;
}
</style>
</head>
<body style="background-image: none;background-color: #fff;">
<div class="container">
<div class="header">
<div class="image">
<img class="logo" src="{{ Storage::url(core()->getConfigData('sales.orderSettings.invoice_slip_design.logo')) }}"/>
</div>
<div class="address">
<p>
<b> {{ core()->getConfigData('sales.orderSettings.invoice_slip_design.address') }} </b>
</p>
</div>
</div>
<div class="invoice-summary">
<div class="row">

View File

@ -161,6 +161,10 @@
props: ['index', 'attribute', 'appliedFilterValues'],
data: function() {
let maxPrice = '{{ core()->convertPrice($productFlatRepository->getCategoryProductMaximumPrice($category)) }}';
maxPrice = (parseInt(maxPrice) !== 0) ? parseInt(maxPrice) : 500;
return {
appliedFilters: [],
@ -171,7 +175,7 @@
0,
0
],
max: {{ core()->convertPrice($productFlatRepository->getCategoryProductMaximumPrice($category)) ?? 0 }},
max: maxPrice,
processStyle: {
"backgroundColor": "#FF6472"
},

View File

@ -1,4 +1,4 @@
<?php
<?php
namespace Webkul\Theme;
@ -18,7 +18,7 @@ class ThemeViewFinder extends FileViewFinder
{
// Extract the $view and the $namespace parts
list($namespace, $view) = $this->parseNamespaceSegments($name);
if ($namespace != 'admin') {
$paths = $this->addThemeNamespacePaths($namespace);
@ -64,14 +64,14 @@ class ThemeViewFinder extends FileViewFinder
/**
* Override replaceNamespace() to add path for custom error pages "resources/themes/theme_name/views/errors/..."
*
* @param string $namespace
* @param string $namespace
* @param string|array $hints
* @return void
*/
public function replaceNamespace($namespace, $hints)
{
$this->hints[$namespace] = (array) $hints;
// Overide Error Pages
if ($namespace == 'errors' || $namespace == 'mails') {
$searchPaths = array_diff($this->paths, Themes::getLaravelViewPaths());

View File

@ -20,6 +20,7 @@ class AdminResetPassword extends ResetPassword
}
return (new MailMessage)
->from(core()->getSenderEmailDetails()['email'], core()->getSenderEmailDetails()['name'])
->view('shop::emails.admin.forget-password', [
'user_name' => $notifiable->name,
'token' => $this->token,

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -1,5 +1,5 @@
{
"/js/velocity.js": "/js/velocity.js?id=6435683a6664cfe72d05",
"/js/velocity.js": "/js/velocity.js?id=2ae4efd13e4e5a1b4055",
"/css/velocity-admin.css": "/css/velocity-admin.css?id=612d35e452446366eef7",
"/css/velocity.css": "/css/velocity.css?id=93ab8f3d857e4367cf0d"
"/css/velocity.css": "/css/velocity.css?id=3b5f1d7a695ef3820846"
}

View File

@ -15,10 +15,10 @@ use Webkul\Velocity\Repositories\VelocityMetadataRepository;
class Helper extends Review
{
/**
* productModel object
*
* @var \Webkul\Product\Contracts\Product
*/
* productModel object
*
* @var \Webkul\Product\Contracts\Product
*/
protected $productModel;
/**
@ -42,7 +42,7 @@ class Helper extends Review
*/
protected $productFlatRepository;
/**
/**
* productModel object
*
* @var \Webkul\Attribute\Repositories\AttributeOptionRepository
@ -66,11 +66,12 @@ class Helper extends Review
/**
* Create a helper instamce
*
* @param \Webkul\Product\Contracts\Product $productModel
* @param \Webkul\Velocity\Repositories\OrderBrandsRepository $orderBrands
* @param \Webkul\Attribute\Repositories\AttributeOptionRepository $attributeOptionRepository
* @param \Webkul\Product\Repositories\ProductReviewRepository $productReviewRepository
* @param \Webkul\Velocity\Repositories\VelocityMetadataRepository $velocityMetadataRepository
* @param \Webkul\Product\Contracts\Product $productModel
* @param \Webkul\Velocity\Repositories\OrderBrandsRepository $orderBrands
* @param \Webkul\Attribute\Repositories\AttributeOptionRepository $attributeOptionRepository
* @param \Webkul\Product\Repositories\ProductReviewRepository $productReviewRepository
* @param \Webkul\Velocity\Repositories\VelocityMetadataRepository $velocityMetadataRepository
*
* @return void
*/
public function __construct(
@ -89,7 +90,7 @@ class Helper extends Review
$this->productRepository = $productRepository;
$this->productFlatRepository = $productFlatRepository;
$this->orderBrandsRepository = $orderBrandsRepository;
$this->productReviewRepository = $productReviewRepository;
@ -98,7 +99,8 @@ class Helper extends Review
}
/**
* @param \Webkul\Sales\Contracts\Order
* @param \Webkul\Sales\Contracts\Order $order
*
* @return void
*/
public function topBrand($order)
@ -109,8 +111,8 @@ class Helper extends Review
$products[] = $orderItem->product;
$this->orderBrandsRepository->create([
'order_id' => $orderItem->order_id,
'order_item_id' => $orderItem->id,
'order_id' => $orderItem->order_id,
'product_id' => $orderItem->product_id,
'brand' => $products[$key]->brand,
]);
@ -172,6 +174,7 @@ class Helper extends Review
* Returns the count rating of the product
*
* @param \Webkul\Product\Contracts\Product $product
*
* @return int
*/
public function getCountRating($product)
@ -229,10 +232,11 @@ class Helper extends Review
*/
public function getShopRecentReviews($reviewCount = 4)
{
$reviews = $this->productReviewRepository->getModel()
->orderBy('id', 'desc')
->where('status', 'approved')
->take($reviewCount)->get();
$reviews = $this->productReviewRepository
->getModel()
->orderBy('id', 'desc')
->where('status', 'approved')
->take($reviewCount)->get();
return $reviews;
}
@ -267,8 +271,8 @@ class Helper extends Review
'images' => $images,
'itemId' => $item->id,
'name' => $item->name,
'url_key' => $product->url_key,
'quantity' => $item->quantity,
'url_key' => $product->url_key,
'baseTotal' => core()->currency($item->base_total),
];
}
@ -278,7 +282,7 @@ class Helper extends Review
* @param bool $list
* @return array
*/
public function formatProduct($product, $list = false)
public function formatProduct($product, $list = false, $metaInformation = [])
{
$reviewHelper = app('Webkul\Product\Helpers\Review');
$productImageHelper = app('Webkul\Product\Helpers\ProductImage');
@ -317,6 +321,12 @@ class Helper extends Review
'showCompare' => true,
'product' => $product,
'addWishlistClass' => ! (isset($list) && $list) ? '' : '',
'btnText' => (isset($metaInformation['btnText']) && $metaInformation['btnText'])
? $metaInformation['btnText']
: null,
'moveToCart' => (isset($metaInformation['moveToCart']) && $metaInformation['moveToCart'])
? $metaInformation['moveToCart']
: null,
'addToCartBtnClass' => ! (isset($list) && $list) ? 'small-padding' : '',
])->render(),
];
@ -330,7 +340,7 @@ class Helper extends Review
*
* @return array
*/
public function fetchProductCollection($items, $separator='&')
public function fetchProductCollection($items, $moveToCart = false, $separator='&')
{
$productCollection = [];
$productIds = explode($separator, $items);
@ -343,7 +353,10 @@ class Helper extends Review
$product = $this->productRepository->findOneWhere(['id' => $productFlat->product_id]);
if ($product) {
$formattedProduct = $this->formatProduct($productFlat);
$formattedProduct = $this->formatProduct($productFlat, false, [
'moveToCart' => $moveToCart,
'btnText' => $moveToCart ? trans('shop::app.customer.account.wishlist.move-to-cart') : null,
]);
$productMetaDetails = [];
$productMetaDetails['slug'] = $product->url_key;

View File

@ -27,7 +27,7 @@ class ShopController extends Controller
if ($product) {
$productReviewHelper = app('Webkul\Product\Helpers\Review');
$galleryImages = $this->productImageHelper->getProductBaseImage($product);
$response = [
@ -92,7 +92,7 @@ class ShopController extends Controller
$productDetails = [];
$productDetails = array_merge($productDetails, $this->velocityHelper->formatProduct($product));
array_push($customizedProducts, $productDetails);
}
@ -217,7 +217,9 @@ class ShopController extends Controller
{
// for product details
if ($items = request()->get('items')) {
$productCollection = $this->velocityHelper->fetchProductCollection($items);
$moveToCart = request()->get('moveToCart');
$productCollection = $this->velocityHelper->fetchProductCollection($items, $moveToCart);
$response = [
'status' => 'success',

View File

@ -20,8 +20,10 @@
'isEnable',
'csrfToken',
'productId',
'moveToCart',
'showCartIcon',
'addClassToBtn',
'productFlatId',
],
data: function () {
@ -47,6 +49,15 @@
if (response.data.status == 'success') {
this.$root.miniCartKey++;
if (this.moveToCart == "true") {
let existingItems = this.getStorageValue('wishlist_product');
let updatedItems = existingItems.filter(item => item != this.productFlatId);
this.$root.headerItemsCount++;
this.setStorageValue('wishlist_product', updatedItems);
}
window.showAlert(`alert-success`, this.__('shop.general.alert.success'), response.data.message);
} else {
window.showAlert(`alert-${response.data.status}`, response.data.label ? response.data.label : this.__('shop.general.alert.error'), response.data.message);
@ -59,7 +70,7 @@
.catch(error => {
console.log(this.__('error.something_went_wrong'));
})
}
},
}
}
</script>

View File

@ -87,8 +87,6 @@
return {
'addToCart': 0,
'addToCartHtml': '',
'message' : "Hello there",
'showTestClass': 'sdfsdf',
}
},
}

View File

@ -96,6 +96,8 @@
mounted: function () {
$('.compare-icon').click(this.closeQuickView);
$('.wishlist-icon').click(this.closeQuickView);
$('.add-to-cart-btn').click(() => setTimeout(this.closeQuickView, 0));
},
methods: {

View File

@ -37,6 +37,10 @@
</script>
<style>
.shimmer-card-container {
width: 100%;
}
.shimmer-card {
margin: 0px 10px 50px 10px;
padding: 30px 40px;

View File

@ -702,7 +702,7 @@
.wishlist-icon {
margin: 0;
display: inline-block;
display: inline;
}
}
@ -2272,6 +2272,9 @@
.compare-products {
// overflow-x: scroll;
// padding-bottom: 30px;
.col,
.col-2 {
padding-left: 0;
@ -2311,6 +2314,12 @@
span {
font-size: 24px !important
}
.price-from {
span:nth-child(2) {
font-size: 20px !important;
}
}
}
.material-icons {

View File

@ -106,6 +106,9 @@ header #search-form > *:focus {
position: relative;
}
.align-vertical-super {
vertical-align: super;
}
.align-vertical-top {
vertical-align: top;
}
@ -715,6 +718,10 @@ body::after {
}
}
}
.description-text {
word-break: break-word;
}
}
.container {

View File

@ -174,6 +174,25 @@
.quantity {
width: unset;
}
.form-group {
label {
display: block;
}
.radio {
margin-right: 10px;
input[type=radio] {
margin-left: 0;
position: static;
}
.radio-view {
display: none;
}
}
}
}
.thumb-list {

View File

@ -75,7 +75,7 @@
alt="{{ $product->name }}">
</a>
<div class="product-details-content col-6">
<div class="product-details-content col-7 pr0">
<div class="row item-title no-margin">
<a
href="{{ route('shop.productOrCategory.index', $product->url_key) }}"
@ -103,23 +103,17 @@
@include ('shop::products.price', ['product' => $product])
</div>
@php
$moveToWishlist = trans('shop::app.checkout.cart.move-to-wishlist');
@endphp
<div class="no-padding col-12 cursor-pointer fs16">
@auth('customer')
@if ($item->parent_id != 'null' ||$item->parent_id != null)
<a
class="unset"
href="{{ route('shop.movetowishlist', $item->id) }}"
onclick="removeLink('{{ __('shop::app.checkout.cart.cart-remove-action') }}')">
<wishlist-component
active="false"
add-class="align-vertical-top">
</wishlist-component>
<span class="align-vertical-top">
{{ __('shop::app.checkout.cart.move-to-wishlist') }}
</span>
</a>
@include('shop::products.wishlist', [
'route' => route('shop.movetowishlist', $item->id),
'text' => "<span class='align-vertical-super'>$moveToWishlist</span>"
])
@else
<a
class="unset"
@ -138,6 +132,13 @@
@endif
@endauth
@guest('customer')
@include('shop::products.wishlist')
<span class="align-vertical-top">
{{ __('shop::app.checkout.cart.move-to-wishlist') }}
</span>
@endguest
<a
class="unset
@auth('customer')
@ -153,7 +154,7 @@
</div>
</div>
<div class="product-quantity col-3 no-padding">
<div class="product-quantity col-2 no-padding">
<quantity-changer
:control-name="'qty[{{$item->id}}]'"
quantity="{{ $item->quantity }}">

View File

@ -31,7 +31,9 @@
{!! view_render_event('bagisto.shop.customers.account.compare.view.before') !!}
<div class="row compare-products col-12 ml0">
<template v-if="products.length > 0">
<shimmer-component v-if="!isProductListLoaded && !isMobile()"></shimmer-component>
<template v-else-if="isProductListLoaded && products.length > 0">
@php
$comparableAttributes = $comparableAttributes->toArray();
@ -105,7 +107,7 @@
@endforeach
</template>
<span v-if="isProductListLoaded && products.length == 0">
<span v-else-if="isProductListLoaded && products.length == 0">
@{{ __('customer.compare.empty-text') }}
</span>
</div>
@ -157,6 +159,7 @@
this.products = response.data.products;
})
.catch(error => {
this.isProductListLoaded = true;
console.log(this.__('error.something_went_wrong'));
});
} else {

View File

@ -36,7 +36,9 @@
{!! view_render_event('bagisto.shop.customers.account.guest-customer.view.before') !!}
<div class="row products-collection col-12 ml0">
<template v-if="products.length > 0">
<shimmer-component v-if="!isProductListLoaded && !isMobile()"></shimmer-component>
<template v-else-if="isProductListLoaded && products.length > 0">
<carousel-component
slides-per-page="6"
navigation-enabled="hide"
@ -53,7 +55,7 @@
</carousel-component>
</template>
<span v-else>{{ __('customer::app.wishlist.empty') }}</span>
<span v-else-if="isProductListLoaded">{{ __('customer::app.wishlist.empty') }}</span>
</div>
{!! view_render_event('bagisto.shop.customers.account.guest-customer.view.after') !!}
@ -89,17 +91,19 @@
if (items != "") {
this.$http
.get(`${this.$root.baseUrl}/detailed-products`, {
params: { items }
params: { moveToCart: true, items }
})
.then(response => {
this.isProductListLoaded = true;
this.products = response.data.products;
})
.catch(error => {
this.isProductListLoaded = true;
console.log(this.__('error.something_went_wrong'));
});
} else {
this.isProductListLoaded = true;
}
},
'removeProduct': function (productId) {

View File

@ -59,8 +59,7 @@
{!! view_render_event('bagisto.shop.home.content.before') !!}
@if ($velocityMetaData)
{{-- {!! DbView::make($velocityMetaData)->field('home_page_content')->render() !!} --}}
@include('shop::home.featured-products')
{!! DbView::make($velocityMetaData)->field('home_page_content')->render() !!}
@else
@include('shop::home.advertisements.advertisement-four')
@include('shop::home.featured-products')

View File

@ -2,18 +2,18 @@
<div class="mx-0 no-padding">
@if (isset($showCompare) && $showCompare)
<compare-component
@auth('customer')
customer="true"
@endif
<compare-component
@auth('customer')
customer="true"
@endif
@guest('customer')
customer="false"
@endif
@guest('customer')
customer="false"
@endif
slug="{{ $product->url_key }}"
product-id="{{ $product->id }}"
></compare-component>
slug="{{ $product->url_key }}"
product-id="{{ $product->id }}"
></compare-component>
@endif
@if (! (isset($showWishlist) && !$showWishlist))
@ -33,7 +33,7 @@
<i class="material-icons text-down-3">shopping_cart</i>
@endif
<span class="fs14 fw6 text-uppercase text-up-4">
<span type="submit" class="fs14 fw6 text-uppercase text-up-4">
{{ __('shop::app.products.add-to-cart') }}
</span>
</button>
@ -64,7 +64,9 @@
<add-to-cart
form="true"
csrf-token='{{ csrf_token() }}'
product-flat-id="{{ $product->id }}"
product-id="{{ $product->product_id }}"
move-to-cart="{{ $moveToCart ?? false }}"
add-class-to-btn="{{ $addToCartBtnClass ?? '' }}"
is-enable={{ ! $product->isSaleable() ? 'false' : 'true' }}
show-cart-icon={{ !(isset($showCartIcon) && !$showCartIcon) }}

View File

@ -183,7 +183,7 @@
data: function() {
let maxPrice = '{{ core()->convertPrice($productFlatRepository->getCategoryProductMaximumPrice($category)) }}';
maxPrice = (maxPrice !== '') ? parseInt(maxPrice) : 0;
maxPrice = (parseInt(maxPrice) !== 0) ? parseInt(maxPrice) : 500;
return {
active: false,

View File

@ -177,7 +177,12 @@
<script type='text/javascript' src='https://unpkg.com/spritespin@4.1.0/release/spritespin.js'></script>
<script type="text/x-template" id="product-view-template">
<form method="POST" id="product-form" action="{{ route('cart.add', $product->product_id) }}" @click="onSubmit($event)">
<form
method="POST"
id="product-form"
@click="onSubmit($event)"
action="{{ route('cart.add', $product->product_id) }}">
<input type="hidden" name="is_buy_now" v-model="is_buy_now">
<slot v-if="slot"></slot>
@ -189,11 +194,11 @@
</form>
</script>
<script type="text/javascript">
<script>
Vue.component('product-view', {
inject: ['$validator'],
template: '#product-view-template',
data: function() {
data: function () {
return {
slot: true,
is_buy_now: 0,
@ -205,6 +210,7 @@
let currentProductId = '{{ $product->url_key }}';
let existingViewed = window.localStorage.getItem('recentlyViewed');
if (! existingViewed) {
existingViewed = [];
} else {
@ -234,15 +240,15 @@
},
methods: {
onSubmit: function(e) {
if (e.target.getAttribute('type') != 'submit')
onSubmit: function(event) {
if (event.target.getAttribute('type') != 'submit')
return;
e.preventDefault();
event.preventDefault();
this.$validator.validateAll().then(result => {
if (result) {
this.is_buy_now = e.target.classList.contains('buynow') ? 1 : 0;
this.is_buy_now = event.target.classList.contains('buynow') ? 1 : 0;
setTimeout(function() {
document.getElementById('product-form').submit();
@ -287,7 +293,6 @@
]
});
}, 0);
}
}
});

View File

@ -8,7 +8,9 @@
<a
class="unset wishlist-icon {{ $addWishlistClass ?? '' }} text-right"
@if (! $isWished)
@if(isset($route))
href="{{ $route }}"
@elseif (! $isWished)
href="{{ route('customer.wishlist.add', $product->product_id) }}"
title="{{ __('velocity::app.shop.wishlist.add-wishlist-text') }}"
@elseif (isset($itemId) && $itemId)
@ -17,6 +19,10 @@
@endif>
<wishlist-component active="{{ !$isWished }}" is-customer="true"></wishlist-component>
@if (isset($text))
{!! $text !!}
@endif
</a>
@endauth

View File

@ -21,6 +21,7 @@
<select name="mail_encryption" class="control">
<option value="ssl">SSL</option>
<option value="tls">TLS</option>
<option value="">None</option>
</select>
</div>

View File

@ -27,6 +27,9 @@ $data = array();
if (empty($_POST['mail_username']))
$errors['mail_username'] = 'Please enter your email address or username.';
if (preg_match('/\s/', $_POST['mail_username']))
$errors['mail_username'] = 'There should be no space in Username.';
if (empty($_POST['mail_password']))
$errors['mail_password'] = 'Please enter the password for this email address.';

View File

@ -52,13 +52,12 @@
@slot('subcopy')
@lang(
"If youre having trouble clicking the \":actionText\" button, copy and paste the URL below\n".
'into your web browser: [:displayableActionUrl](:actionURL)',
'into your web browser: [:actionURL](:actionURL)',
[
'actionText' => $actionText,
'actionURL' => $actionUrl,
'displayableActionUrl' => $displayableActionUrl,
]
)
@endslot
@endisset
@endcomponent
@endcomponent

View File

@ -6,6 +6,10 @@ use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Route;
use Webkul\User\Models\Admin;
use Webkul\Customer\Models\Customer;
use Webkul\Customer\Models\CustomerAddress;
use Webkul\Checkout\Models\Cart;
use Webkul\Checkout\Models\CartItem;
use Webkul\Checkout\Models\CartAddress;
/**
* Inherited Methods
@ -104,18 +108,24 @@ class FunctionalTester extends \Codeception\Actor
* // TODO: change method as soon as there is a method to set core config data
*
* @param $data array containing 'code => value' pairs
*
* @return void
*/
public function setConfigData($data): void {
public function setConfigData($data): void
{
foreach ($data as $key => $value) {
if (DB::table('core_config')->where('code', '=', $key)->exists()) {
DB::table('core_config')->where('code', '=', $key)->update(['value' => $value]);
DB::table('core_config')
->where('code', '=', $key)
->update(['value' => $value]);
} else {
DB::table('core_config')->insert([
'code' => $key,
'value' => $value,
'created_at' => date('Y-m-d H:i:s'),
'updated_at' => date('Y-m-d H:i:s')
'code' => $key,
'value' => $value,
'channel_code' => null,
'locale_code' => null,
'created_at' => date('Y-m-d H:i:s'),
'updated_at' => date('Y-m-d H:i:s'),
]);
}
}

View File

@ -1,4 +1,5 @@
<?php
namespace Helper;
// here you can define custom actions
@ -6,5 +7,21 @@ namespace Helper;
class Functional extends \Codeception\Module
{
/**
* Apply the given theme by setting the value to the default (or given) channel.
*
* @param string $theme
*/
public function applyTheme(string $theme, string $channel = 'default'): void
{
$channel = Channel::where('code', $channel)->first();
if (! $channel) {
throw new \Exception(
"Given theme '$theme' could not applied because channel '$channel' could not be fetched from database"
);
}
$channel->update(['theme' => $theme]);
}
}

View File

@ -74,8 +74,9 @@ class AttributeFamilyCest
private function fillForm(FunctionalTester $I): array
{
$testData = [
'code' => $I->fake()->word,
'name' => $I->fake()->word,
// code needs to match to: '/^[a-zA-Z]+[a-zA-Z0-9_]+$/'
'code' => $I->fake()->word . strtr($I->fake()->uuid, ['-' => '_']),
'name' => $I->fake()->sentence,
];
$I->fillField('code', $testData['code']);

View File

@ -0,0 +1,147 @@
<?php
namespace Tests\Functional\Checkout\Cart;
use Faker\Factory;
use FunctionalTester;
use Cart;
use Webkul\Sales\Models\Order;
use Webkul\Sales\Models\OrderAddress;
use Webkul\Sales\Models\OrderPayment;
use Webkul\Checkout\Models\CartAddress;
use Webkul\Checkout\Models\CartPayment;
use Webkul\Customer\Models\Customer;
use Webkul\Core\Models\Channel;
/**
* Class OrderCest
*
* @package Tests\Functional\Checkout\Cart
*/
class OrderCest
{
/**
* @param \FunctionalTester $I
*/
public function testCheckoutAsCustomer(FunctionalTester $I)
{
$customer = $I->loginAsCustomer();
$faker = Factory::create();
$addressData = [
'city' => $faker->city,
'company_name' => $faker->company,
'country' => $faker->countryCode,
'email' => $faker->email,
'first_name' => $faker->firstName,
'last_name' => $faker->lastName,
'phone' => $faker->phoneNumber,
'postcode' => $faker->postcode,
'state' => $faker->state,
];
$mocks = $I->prepareCart([
'customer' => $customer,
]);
// assert that checkout can be reached and generate csrf token.
$I->amOnRoute('shop.checkout.onepage.index');
// simulate the entering of the address(es):
$I->sendAjaxPostRequest(route('shop.checkout.save-address'), [
'_token' => csrf_token(),
'billing' => array_merge($addressData, [
'address1' => ['900 Nobel Parkway'],
'save_as_address' => true,
'use_for_shipping' => true,
]),
'shipping' => array_merge($addressData, [
'address1' => ['900 Nobel Parkway'],
'save_as_address' => true,
'use_for_shipping' => true,
]),
]);
$I->seeResponseCodeIsSuccessful();
$I->seeRecord(CartAddress::class, array_merge($addressData, [
'address_type' => 'shipping',
'cart_id' => $mocks['cart']->id,
'customer_id' => $mocks['customer']->id,
]));
$I->seeRecord(CartAddress::class, array_merge($addressData, [
'address_type' => 'billing',
'cart_id' => $mocks['cart']->id,
'customer_id' => $mocks['customer']->id,
]));
$I->sendAjaxPostRequest(route('shop.checkout.save-shipping'), [
'_token' => csrf_token(),
'shipping_method' => 'free_free',
]);
$I->seeResponseCodeIsSuccessful();
$I->sendAjaxPostRequest(route('shop.checkout.save-payment'), [
'_token' => csrf_token(),
'payment' => [
'method' => 'cashondelivery',
],
]);
$I->seeResponseCodeIsSuccessful();
$I->seeRecord(CartPayment::class, [
'method' => 'cashondelivery',
'method_title' => null,
'cart_id' => $mocks['cart']->id,
]);
// simulate click on the 'place order' button at the last step:
$I->sendAjaxPostRequest(route('shop.checkout.save-order'),
['_token' => csrf_token()]
);
$I->seeResponseCodeIsSuccessful();
$order = $I->grabRecord(Order::class, [
'status' => 'pending',
'channel_name' => 'Default',
'is_guest' => 0,
'customer_first_name' => $customer->first_name,
'customer_last_name' => $customer->last_name,
'customer_email' => $customer->email,
'shipping_method' => 'free_free',
'shipping_title' => 'Free Shipping - Free Shipping',
'shipping_description' => 'Free Shipping',
'customer_type' => Customer::class,
'channel_id' => 1,
'channel_type' => Channel::class,
'cart_id' => $mocks['cart']->id,
'customer_id' => $customer->id,
'total_item_count' => count($mocks['cartItems']),
'total_qty_ordered' => $mocks['totalQtyOrdered'],
]);
$I->seeRecord(OrderAddress::class, array_merge($addressData, [
'order_id' => $order->id,
'address_type' => 'shipping',
'customer_id' => $mocks['customer']->id,
]));
$I->seeRecord(OrderAddress::class, array_merge($addressData, [
'order_id' => $order->id,
'address_type' => 'billing',
'customer_id' => $mocks['customer']->id,
]));
$I->seeRecord(OrderPayment::class, [
'method' => 'cashondelivery',
'method_title' => null,
'order_id' => $order->id,
]);
}
}

View File

@ -26,19 +26,19 @@ class CartTaxesCest
$tax1 = $I->have(TaxRate::class, [
'country' => $this->country,
]);
$taxCategorie1 = $I->have(TaxCategory::class);
$taxCategory1 = $I->have(TaxCategory::class);
$I->have(TaxMap::class, [
'tax_rate_id' => $tax1->id,
'tax_category_id' => $taxCategorie1->id,
'tax_category_id' => $taxCategory1->id,
]);
$tax2 = $I->have(TaxRate::class, [
'country' => $this->country,
]);
$taxCategorie2 = $I->have(TaxCategory::class);
$taxCategory2 = $I->have(TaxCategory::class);
$I->have(TaxMap::class, [
'tax_rate_id' => $tax2->id,
'tax_category_id' => $taxCategorie2->id,
'tax_category_id' => $taxCategory2->id,
]);
$config1 = [
@ -46,7 +46,7 @@ class CartTaxesCest
'attributeValues' => [
'status' => true,
'new' => 1,
'tax_category_id' => $taxCategorie1->id,
'tax_category_id' => $taxCategory1->id,
],
];
$product1 = $I->haveProduct(Laravel5Helper::SIMPLE_PRODUCT, $config1);
@ -56,7 +56,7 @@ class CartTaxesCest
'attributeValues' => [
'status' => true,
'new' => 1,
'tax_category_id' => $taxCategorie2->id,
'tax_category_id' => $taxCategory2->id,
],
];
$product2 = $I->haveProduct(Laravel5Helper::SIMPLE_PRODUCT, $config2);
@ -158,15 +158,15 @@ class CartTaxesCest
'tax_rate' => $I->fake()->randomFloat(2, 3, 8),
]);
$taxCategorie1 = $I->have(TaxCategory::class);
$taxCategory1 = $I->have(TaxCategory::class);
$I->have(TaxMap::class, [
'tax_rate_id' => $tax11->id,
'tax_category_id' => $taxCategorie1->id,
'tax_category_id' => $taxCategory1->id,
]);
$I->have(TaxMap::class, [
'tax_rate_id' => $tax12->id,
'tax_category_id' => $taxCategorie1->id,
'tax_category_id' => $taxCategory1->id,
]);
$tax21 = $I->have(TaxRate::class, [
@ -186,15 +186,15 @@ class CartTaxesCest
'tax_rate' => $I->fake()->randomFloat(2, 14, 25),
]);
$taxCategorie2 = $I->have(TaxCategory::class);
$taxCategory2 = $I->have(TaxCategory::class);
$I->have(TaxMap::class, [
'tax_rate_id' => $tax21->id,
'tax_category_id' => $taxCategorie2->id,
'tax_category_id' => $taxCategory2->id,
]);
$I->have(TaxMap::class, [
'tax_rate_id' => $tax22->id,
'tax_category_id' => $taxCategorie2->id,
'tax_category_id' => $taxCategory2->id,
]);
$config1 = [
@ -202,7 +202,7 @@ class CartTaxesCest
'attributeValues' => [
'status' => true,
'new' => 1,
'tax_category_id' => $taxCategorie1->id,
'tax_category_id' => $taxCategory1->id,
],
];
$product1 = $I->haveProduct(Laravel5Helper::SIMPLE_PRODUCT, $config1);
@ -212,7 +212,7 @@ class CartTaxesCest
'attributeValues' => [
'status' => true,
'new' => 1,
'tax_category_id' => $taxCategorie2->id,
'tax_category_id' => $taxCategory2->id,
],
];
$product2 = $I->haveProduct(Laravel5Helper::SIMPLE_PRODUCT, $config2);